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, ¶m->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, ¶m->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, ¶m->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 *)¶m->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 }