1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "gap_internal.h"
17 #include "gap_task_internal.h"
18 
19 #include <securec.h>
20 
21 #include "allocator.h"
22 #include "log.h"
23 
24 #include "smp/smp.h"
25 
26 typedef struct {
27     uint16_t handle;
28     uint8_t pairMethod;
29     uint8_t *displayValue;
30 } GapLeAuthenticationRequestParam;
31 
32 typedef struct {
33     uint16_t handle;
34     uint8_t status;
35     SMP_PairResult result;
36 } GapLePairResultParam;
37 
38 typedef struct {
39     uint16_t handle;
40     SMP_PairParam param;
41 } GapLeRemotePairRequestParam;
42 
43 typedef struct {
44     uint16_t handle;
45     SMP_PairParam param;
46 } GapLeRemotePairResponseParam;
47 
48 typedef struct {
49     uint16_t handle;
50     uint8_t authReq;
51 } GapLeRemoteSecurityRequestParam;
52 
53 typedef struct {
54     uint16_t handle;
55     uint64_t random;
56     uint16_t ediv;
57 } GapLeLongTermKeyRequestParam;
58 
59 typedef struct {
60     uint8_t status;
61     uint8_t *sign;
62 } GapLeGenerateSignatureResultParam;
63 
64 typedef struct {
65     uint8_t status;
66     uint8_t *addr;
67 } GapGenerateRPAResultParam;
68 
69 typedef struct {
70     uint8_t status;
71     bool result;
72     uint8_t addr[BT_ADDRESS_SIZE];
73     uint8_t irk[GAP_IRK_SIZE];
74 } GapResolveRPAResultParam;
75 
GapLeAuthenticationRequestTask(void * ctx)76 static void GapLeAuthenticationRequestTask(void *ctx)
77 {
78     GapLeAuthenticationRequestParam *param = ctx;
79     GapLeAuthenticationRequest(param->handle, param->pairMethod, param->displayValue);
80 }
81 
GapFreeLeAuthenticationRequest(void * ctx)82 static void GapFreeLeAuthenticationRequest(void *ctx)
83 {
84     GapLeAuthenticationRequestParam *param = ctx;
85 
86     if (param->displayValue != NULL) {
87         MEM_MALLOC.free(param->displayValue);
88     }
89 }
90 
GapAllocLeAuthenticationRequestValue(uint8_t pairMethod,const uint8_t * displayValue)91 static uint8_t *GapAllocLeAuthenticationRequestValue(uint8_t pairMethod, const uint8_t *displayValue)
92 {
93     uint8_t valueLength;
94     uint8_t *value = NULL;
95 
96     switch (pairMethod) {
97         case SMP_PAIR_METHOD_PASSKEY_DISPLAY:
98         case SMP_PAIR_METHOD_NUMERIC_COMPARISON:
99             valueLength = sizeof(uint32_t);
100             break;
101         case SMP_PAIR_METHOD_OOB_LEGACY:
102             valueLength = GAP_OOB_DATA_SIZE;
103             break;
104         case SMP_PAIR_METHOD_OOB_SC_BOTH_SIDE_SEND_RECV:
105         case SMP_PAIR_METHOD_OOB_SC_LOCAL_SEND_PEER_RECV:
106         case SMP_PAIR_METHOD_OOB_SC_LOCAL_RECV_PEER_SEND:
107             valueLength = BT_ADDRESS_SIZE + GAP_OOB_DATA_CONFIRM_SIZE + GAP_OOB_DATA_RANDOM_SIZE;
108             break;
109         case SMP_PAIR_METHOD_JUST_WORK:
110         case SMP_PAIR_METHOD_PASSKEY_ENTRY:
111         default:
112             return NULL;
113     }
114 
115     value = MEM_MALLOC.alloc(valueLength);
116     if (value != NULL) {
117         (void)memcpy_s(value, valueLength, displayValue, valueLength);
118     }
119 
120     return value;
121 }
122 
GapRecvLeAuthenticationRequest(uint16_t handle,uint8_t pairMethod,const uint8_t * displayValue)123 static void GapRecvLeAuthenticationRequest(uint16_t handle, uint8_t pairMethod, const uint8_t *displayValue)
124 {
125     LOG_INFO("%{public}s: handle:0x%04x pairMethod:%hhu", __FUNCTION__, handle, pairMethod);
126     GapLeAuthenticationRequestParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeAuthenticationRequestParam));
127     if (smParam == NULL) {
128         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
129         return;
130     }
131 
132     smParam->handle = handle;
133     smParam->pairMethod = pairMethod;
134     smParam->displayValue = GapAllocLeAuthenticationRequestValue(pairMethod, displayValue);
135     if (smParam->displayValue == NULL && displayValue != NULL) {
136         MEM_MALLOC.free(smParam);
137         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
138         return;
139     }
140 
141     int ret = GapRunTaskUnBlockProcess(GapLeAuthenticationRequestTask, smParam, GapFreeLeAuthenticationRequest);
142     if (ret != BT_SUCCESS) {
143         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
144     }
145 }
146 
GapLePairResultTask(void * ctx)147 static void GapLePairResultTask(void *ctx)
148 {
149     GapLePairResultParam *param = ctx;
150     GapLePairResult(param->handle, param->status, &param->result);
151 }
152 
GapRecvLePairResult(uint16_t handle,uint8_t status,const SMP_PairResult * result)153 static void GapRecvLePairResult(uint16_t handle, uint8_t status, const SMP_PairResult *result)
154 {
155     LOG_INFO("%{public}s: handle:0x%04x status:%hhu", __FUNCTION__, handle, status);
156     if (result != NULL) {
157         LOG_INFO("pairType:%hhu bondedFlag:%hhu authFlag:0x%02x encKeySize:%hhu localKeyDist:0x%02x peerKeyDist:0x%02x",
158             result->pairType,
159             result->bondedFlag,
160             result->authFlag,
161             result->encKeySize,
162             result->localKeyDist,
163             result->peerKeyDist);
164     } else {
165         return;
166     }
167 
168     GapLePairResultParam *smParam = MEM_MALLOC.alloc(sizeof(GapLePairResultParam));
169     if (smParam == NULL) {
170         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
171         return;
172     }
173 
174     smParam->handle = handle;
175     smParam->status = status;
176     smParam->result = *result;
177 
178     int ret = GapRunTaskUnBlockProcess(GapLePairResultTask, smParam, NULL);
179     if (ret != BT_SUCCESS) {
180         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
181     }
182 }
183 
GapLeRemotePairRequestTask(void * ctx)184 static void GapLeRemotePairRequestTask(void *ctx)
185 {
186     GapLeRemotePairRequestParam *param = ctx;
187     GapLeRemotePairRequest(param->handle, &param->param);
188 }
189 
GapRecvLeRemotePairRequest(uint16_t handle,const SMP_PairParam * param)190 static void GapRecvLeRemotePairRequest(uint16_t handle, const SMP_PairParam *param)
191 {
192     LOG_INFO("%{public}s: handle:0x%04x ioCapability:%hhu authReq:0x%02x initKeyDist:0x%02x respKeyDist:0x%02x",
193         __FUNCTION__,
194         handle,
195         param->ioCapability,
196         param->authReq,
197         param->initKeyDist,
198         param->respKeyDist);
199     GapLeRemotePairRequestParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeRemotePairRequestParam));
200     if (smParam == NULL) {
201         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
202         return;
203     }
204 
205     smParam->handle = handle;
206     smParam->param = *param;
207 
208     int ret = GapRunTaskUnBlockProcess(GapLeRemotePairRequestTask, smParam, NULL);
209     if (ret != BT_SUCCESS) {
210         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
211     }
212 }
213 
GapLeRemotePairResponseTask(void * ctx)214 static void GapLeRemotePairResponseTask(void *ctx)
215 {
216     GapLeRemotePairRequestParam *param = ctx;
217     GapLeRemotePairResponse(param->handle, &param->param);
218 }
219 
GapRecvLeRemotePairResponse(uint16_t handle,const SMP_PairParam * param)220 static void GapRecvLeRemotePairResponse(uint16_t handle, const SMP_PairParam *param)
221 {
222     LOG_INFO("%{public}s: handle:0x%04x ioCapability:%hhu authReq:0x%02x initKeyDist:0x%02x respKeyDist:0x%02x",
223         __FUNCTION__,
224         handle,
225         param->ioCapability,
226         param->authReq,
227         param->initKeyDist,
228         param->respKeyDist);
229     GapLeRemotePairResponseParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeRemotePairResponseParam));
230     if (smParam == NULL) {
231         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
232         return;
233     }
234 
235     smParam->handle = handle;
236     smParam->param = *param;
237 
238     int ret = GapRunTaskUnBlockProcess(GapLeRemotePairResponseTask, smParam, NULL);
239     if (ret != BT_SUCCESS) {
240         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
241     }
242 }
243 
GapLeRemoteSecurityRequestTask(void * ctx)244 static void GapLeRemoteSecurityRequestTask(void *ctx)
245 {
246     GapLeRemoteSecurityRequestParam *param = ctx;
247     GapLeRemoteSecurityRequest(param->handle, param->authReq);
248 }
249 
GapRecvLeRemoteSecurityRequest(uint16_t handle,uint8_t authReq)250 static void GapRecvLeRemoteSecurityRequest(uint16_t handle, uint8_t authReq)
251 {
252     LOG_INFO("%{public}s: handle:0x%04x authReq:0x%02x", __FUNCTION__, handle, authReq);
253     GapLeRemoteSecurityRequestParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeRemoteSecurityRequestParam));
254     if (smParam == NULL) {
255         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
256         return;
257     }
258 
259     smParam->handle = handle;
260     smParam->authReq = authReq;
261 
262     int ret = GapRunTaskUnBlockProcess(GapLeRemoteSecurityRequestTask, smParam, NULL);
263     if (ret != BT_SUCCESS) {
264         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
265     }
266 }
267 
GapLeLongTermKeyRequestTask(void * ctx)268 static void GapLeLongTermKeyRequestTask(void *ctx)
269 {
270     GapLeLongTermKeyRequestParam *param = ctx;
271     GapLeLongTermKeyRequest(param->handle, (uint8_t *)&param->random, param->ediv);
272 }
273 
GapRecvLeLongTermKeyRequest(uint16_t handle,const uint8_t * random,uint16_t ediv)274 static void GapRecvLeLongTermKeyRequest(uint16_t handle, const uint8_t *random, uint16_t ediv)
275 {
276     LOG_INFO("%{public}s: handle:0x%04x", __FUNCTION__, handle);
277     GapLeLongTermKeyRequestParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeLongTermKeyRequestParam));
278     if (smParam == NULL) {
279         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
280         return;
281     }
282 
283     smParam->handle = handle;
284     smParam->random = *(uint64_t *)random;
285     smParam->ediv = ediv;
286 
287     int ret = GapRunTaskUnBlockProcess(GapLeLongTermKeyRequestTask, smParam, NULL);
288     if (ret != BT_SUCCESS) {
289         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
290     }
291 }
292 
GapLeGenerateSignatureResultTask(void * ctx)293 static void GapLeGenerateSignatureResultTask(void *ctx)
294 {
295     GapLeGenerateSignatureResultParam *param = ctx;
296     GapLeGenerateSignatureResult(param->status, param->sign);
297 }
298 
GapFreeLeGenerateSignatureResult(void * ctx)299 static void GapFreeLeGenerateSignatureResult(void *ctx)
300 {
301     GapLeGenerateSignatureResultParam *param = ctx;
302 
303     MEM_MALLOC.free(param->sign);
304 }
305 
GapRecvLeGenerateSignatureResult(uint8_t status,const uint8_t * sign)306 static void GapRecvLeGenerateSignatureResult(uint8_t status, const uint8_t *sign)
307 {
308     LOG_INFO("%{public}s: status:%hhu", __FUNCTION__, status);
309     GapLeGenerateSignatureResultParam *smParam = MEM_MALLOC.alloc(sizeof(GapLeGenerateSignatureResultParam));
310     if (smParam == NULL) {
311         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
312         return;
313     }
314 
315     smParam->status = status;
316     if (status == SMP_GENERATE_SIGN_STATUS_SUCCESS) {
317         smParam->sign = MEM_MALLOC.alloc(GAP_SIGNATURE_SIZE);
318         if (smParam->sign == NULL) {
319             MEM_MALLOC.free(smParam);
320             LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
321             return;
322         }
323 
324         (void)memcpy_s(smParam->sign, GAP_SIGNATURE_SIZE, sign, GAP_SIGNATURE_SIZE);
325     } else {
326         smParam->sign = NULL;
327     }
328 
329     int ret = GapRunTaskUnBlockProcess(GapLeGenerateSignatureResultTask, smParam, GapFreeLeGenerateSignatureResult);
330     if (ret != BT_SUCCESS) {
331         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
332     }
333 }
334 
GapGenerateRPAResultTask(void * ctx)335 static void GapGenerateRPAResultTask(void *ctx)
336 {
337     GapGenerateRPAResultParam *param = ctx;
338     GapGenerateRPAResult(param->status, param->addr);
339 }
340 
GapFreeGenerateRPAResult(void * ctx)341 static void GapFreeGenerateRPAResult(void *ctx)
342 {
343     GapGenerateRPAResultParam *param = ctx;
344 
345     MEM_MALLOC.free(param->addr);
346 }
347 
GapRecvGenerateRPAResult(uint8_t status,const uint8_t * addr)348 static void GapRecvGenerateRPAResult(uint8_t status, const uint8_t *addr)
349 {
350     LOG_INFO("%{public}s: status:%hhu", __FUNCTION__, status);
351     GapGenerateRPAResultParam *smParam = MEM_MALLOC.alloc(sizeof(GapGenerateRPAResultParam));
352     if (smParam == NULL) {
353         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
354         return;
355     }
356 
357     smParam->status = status;
358     if (status == SMP_GENERATE_RPA_STATUS_SUCCESS) {
359         smParam->addr = MEM_MALLOC.alloc(BT_ADDRESS_SIZE);
360         if (smParam->addr == NULL) {
361             MEM_MALLOC.free(smParam);
362             LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
363             return;
364         }
365 
366         (void)memcpy_s(smParam->addr, BT_ADDRESS_SIZE, addr, BT_ADDRESS_SIZE);
367     } else {
368         smParam->addr = NULL;
369     }
370 
371     int ret = GapRunTaskUnBlockProcess(GapGenerateRPAResultTask, smParam, GapFreeGenerateRPAResult);
372     if (ret != BT_SUCCESS) {
373         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
374     }
375 }
376 
GapResolveRPAResultTask(void * ctx)377 static void GapResolveRPAResultTask(void *ctx)
378 {
379     GapResolveRPAResultParam *param = ctx;
380     GapResolveRPAResult(param->status, param->result, param->addr, param->irk);
381 }
382 
GapRecvResolveRPAResult(uint8_t status,bool result,const uint8_t * addr,const uint8_t * irk)383 static void GapRecvResolveRPAResult(uint8_t status, bool result, const uint8_t *addr, const uint8_t *irk)
384 {
385     LOG_INFO("%{public}s: status:%hhu result:%{public}d", __FUNCTION__, status, result);
386     GapResolveRPAResultParam *smParam = MEM_MALLOC.alloc(sizeof(GapResolveRPAResultParam));
387     if (smParam == NULL) {
388         LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__);
389         return;
390     }
391 
392     smParam->status = status;
393     smParam->result = result;
394     (void)memcpy_s(smParam->addr, BT_ADDRESS_SIZE, addr, BT_ADDRESS_SIZE);
395     (void)memcpy_s(smParam->irk, GAP_IRK_SIZE, irk, GAP_IRK_SIZE);
396 
397     int ret = GapRunTaskUnBlockProcess(GapResolveRPAResultTask, smParam, NULL);
398     if (ret != BT_SUCCESS) {
399         LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret);
400     }
401 }
402 
403 static SMP_Callback_t g_smCallback = {
404     .SMP_CallbackAuthenticationRequest = GapRecvLeAuthenticationRequest,
405     .SMP_CallbackPairResult = GapRecvLePairResult,
406     .SMP_CallbackRemotePairRequest = GapRecvLeRemotePairRequest,
407     .SMP_CallbackRemotePairResponse = GapRecvLeRemotePairResponse,
408     .SMP_CallbackRemoteSecurityRequest = GapRecvLeRemoteSecurityRequest,
409     .SMP_CallbackLongTermKeyRequest = GapRecvLeLongTermKeyRequest,
410     .SMP_CallbackGenerateSignatureResult = GapRecvLeGenerateSignatureResult,
411     .SMP_CallbackGenerateRPAResult = GapRecvGenerateRPAResult,
412     .SMP_CallbackResolveRPAResult = GapRecvResolveRPAResult,
413 };
414 
GapRegisterSmCallbacks(void)415 void GapRegisterSmCallbacks(void)
416 {
417     SMP_RegisterCallback(&g_smCallback);
418 }
419 
GapDeregisterSmCallbacks(void)420 void GapDeregisterSmCallbacks(void)
421 {
422     SMP_UnregisterCallback();
423 }