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 #ifndef SMP_H
17 #define SMP_H
18 
19 #include <stdbool.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 
24 #include "btstack.h"
25 #include "securec.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 // true:  Pairing using hardware AES-128 encryption algorithm
32 // false: Pairing using software AES-128 encryption algorithm
33 #define SMP_USING_HW_AES128_PAIR (false)
34 
35 // true:  Generating Signature using hardware AES-128 encryption algorithm
36 // false: Generating Signature using software AES-128 encryption algorithm
37 #define SMP_USING_HW_AES128_SIGN (false)
38 
39 // true:  Generating/Resolving RPA using hardware AES-128 encryption algorithm
40 // false: Generating/Resolving RPA using software AES-128 encryption algorithm
41 #define SMP_USING_HW_AES128_RPA (false)
42 
43 #define SMP_PAIR_STATUS_SUCCESS 0x00
44 #define SMP_PAIR_STATUS_FAILED 0x01
45 
46 #define SMP_ENCRYPT_STATUS_SUCCESS 0x00
47 #define SMP_ENCRYPT_STATUS_FAILED 0x01
48 
49 #define SMP_GENERATE_SIGN_STATUS_SUCCESS 0x00
50 #define SMP_GENERATE_SIGN_STATUS_FAILED 0x01
51 
52 #define SMP_GENERATE_RPA_STATUS_SUCCESS 0x00
53 #define SMP_GENERATE_RPA_STATUS_FAILED 0x01
54 
55 #define SMP_RESOLVE_RPA_STATUS_SUCCESS 0x00
56 #define SMP_RESOLVE_RPA_STATUS_FAILED 0x01
57 
58 #define SMP_RESOLVE_RPA_RESULT_YES 0x01
59 #define SMP_RESOLVE_RPA_RESULT_NO 0x00
60 
61 #define SMP_GENERATE_SC_OOB_DATA_SUCCESS 0x00
62 #define SMP_GENERATE_SC_OOB_DATA_FAILED 0x01
63 
64 #define SMP_SUCCESS BT_SUCCESS                    /// < SMP error code success
65 #define SMP_ERR_NOT_ENABLE BT_BAD_STATUS           /// < SMP error code module not initialize
66 #define SMP_ERR_INVAL_PARAM BT_BAD_PARAM           /// < SMP error code invalid parameter
67 #define SMP_ERR_INVAL_STATE BT_BAD_STATUS          /// < SMP error code invalid state
68 #define SMP_ERR_REPEATED BT_ALREADY                /// < SMP error code repeated action
69 #define SMP_ERR_OUT_OF_RES BT_NO_MEMORY            /// < SMP error code out of resource
70 #define SMP_ERR_REMOTE_ACTION BT_OPERATION_FAILED  /// < SMP error code communication failed
71 
72 #define SMP_PAIR_METHOD_JUST_WORK 0x00
73 // Data Type: uint32_t
74 #define SMP_PAIR_METHOD_PASSKEY_DISPLAY 0x02
75 // Data Type: uint32_t
76 #define SMP_PAIR_METHOD_PASSKEY_ENTRY 0x03
77 // Data Type: uint32_t
78 #define SMP_PAIR_METHOD_NUMERIC_COMPARISON 0x04
79 #define SMP_PAIR_METHOD_OOB_LEGACY 0x05                   // Data Type: uint8_t array (16 bytes)
80 #define SMP_PAIR_METHOD_OOB_SC_BOTH_SIDE_SEND_RECV 0x06   // Data Type: uint8_t array (38 bytes)
81 #define SMP_PAIR_METHOD_OOB_SC_LOCAL_SEND_PEER_RECV 0x07  // Data Type: uint8_t array (38 bytes)
82 #define SMP_PAIR_METHOD_OOB_SC_LOCAL_RECV_PEER_SEND 0x08  // Data Type: uint8_t array (38 bytes)
83 
84 #define SMP_BONDED_FLAG_NO 0x00
85 #define SMP_BONDED_FLAG_YES 0x01
86 
87 #define SMP_AUTH_FLAG_NO 0x00
88 #define SMP_AUTH_FLAG_YES 0x01
89 
90 #define SMP_PAIR_TYPE_LEGACY 0x00
91 #define SMP_PAIR_TYPE_SECURE_CONNECTION 0x01
92 
93 #define SMP_PAIR_FAILED_NO_FAILED 0x00
94 #define SMP_PAIR_FAILED_PASSKEY_ENTRY 0x01
95 #define SMP_PAIR_FAILED_OOB_NOT_AVAILABLE 0x02
96 #define SMP_PAIR_FAILED_AUTH_REQ 0x03
97 #define SMP_PAIR_FAILED_CONFIRM_VALUE 0x04
98 #define SMP_PAIR_FAILED_PAIRING_NOT_SUPPORTED 0x05
99 #define SMP_PAIR_FAILED_ENC_KEY_SIZE 0x06
100 #define SMP_PAIR_FAILED_ENC_CMD_NOT_SUPPORTED 0x07
101 #define SMP_PAIR_FAILED_UNSPECIFIED_REASION 0x08
102 #define SMP_PAIR_FAILED_REPAETED_ATTEMPTS 0x09
103 #define SMP_PAIR_FAILED_INVALID_PARAM 0x0A
104 #define SMP_PAIR_FAILED_DHKEY_CHECK 0x0B
105 #define SMP_PAIR_FAILED_NUMERIC_COMPARISON 0x0C
106 #define SMP_PAIR_FAILED_BREDR_PAIRING_IN_PROGRESS 0x0D
107 #define SMP_PAIR_FAILED_KEY_GENERATION_NOT_ALLOWED 0x0E
108 
109 #define SMP_IO_DISPLAY_ONLY 0x00
110 #define SMP_IO_DISPLAY_YES_NO 0x01
111 #define SMP_IO_KEYBOARD_ONLY 0x02
112 #define SMP_IO_NO_INPUT_NO_OUTPUT 0x03
113 #define SMP_IO_KEYBOARD_DISPLAY 0x04
114 
115 #define SMP_AUTH_REQ_NO_BONDING 0x00
116 #define SMP_AUTH_REQ_BONDING 0x01
117 #define SMP_AUTH_REQ_BIT_MITM 0x04
118 #define SMP_AUTH_REQ_BIT_SC 0x08
119 #define SMP_AUTH_REQ_BIT_KEYPRESS 0x10
120 #define SMP_AUTH_REQ_BIT_CT2 0x20
121 
122 #define SMP_KEY_DIST_BIT_ENC_KEY 0x01
123 #define SMP_KEY_DIST_BIT_ID_KEY 0x02
124 #define SMP_KEY_DIST_BIT_SIGN_KEY 0x04
125 
126 #define SMP_IRK_LEN 0x10
127 #define SMP_CSRK_LEN 0x10
128 #define SMP_RAND_NUM_LEN 0x08
129 #define SMP_LTK_LEN 0x10
130 
131 /**
132  * @brief Pair param structure.
133  */
134 typedef struct {
135     uint8_t ioCapability;
136     uint8_t oobDataFlag;
137     uint8_t authReq;
138     uint8_t maxEncKeySize;
139     uint8_t initKeyDist;
140     uint8_t respKeyDist;
141 } SMP_PairParam;
142 
143 /**
144  * @brief Pair result structure.
145  */
146 typedef struct {
147     uint8_t pairType;
148     uint8_t bondedFlag;
149     uint8_t authFlag;
150     uint8_t encKeySize;
151     uint8_t localKeyDist;
152     uint8_t peerKeyDist;
153     uint8_t localLTK[SMP_LTK_LEN];
154     uint16_t localEdiv;
155     uint8_t localRandom[SMP_RAND_NUM_LEN];
156     uint8_t peerLTK[SMP_LTK_LEN];
157     uint16_t peerEdiv;
158     uint8_t peerRandom[SMP_RAND_NUM_LEN];
159     uint8_t localIRK[SMP_IRK_LEN];
160     BtAddr localIdentAddr;
161     uint8_t peerIRK[SMP_IRK_LEN];
162     BtAddr peerIdentAddr;
163     uint8_t localCSRK[SMP_CSRK_LEN];
164     uint8_t peerCSRK[SMP_CSRK_LEN];
165 } SMP_PairResult;
166 
167 /**
168  * @brief Security manager callback structure.
169  */
170 typedef struct {
171     void (*SMP_CallbackAuthenticationRequest)(uint16_t handle, uint8_t pairMethod, const uint8_t *displayValue);
172     void (*SMP_CallbackPairResult)(uint16_t handle, uint8_t status, const SMP_PairResult *result);
173     void (*SMP_CallbackRemotePairRequest)(uint16_t handle, const SMP_PairParam *param);
174     void (*SMP_CallbackRemotePairResponse)(uint16_t handle, const SMP_PairParam *param);
175     void (*SMP_CallbackRemoteSecurityRequest)(uint16_t handle, uint8_t authReq);
176     void (*SMP_CallbackLongTermKeyRequest)(uint16_t handle, const uint8_t *random, uint16_t ediv);
177     void (*SMP_CallbackEncryptionComplete)(uint16_t handle, uint8_t status);
178     void (*SMP_CallbackGenerateSignatureResult)(uint8_t status, const uint8_t *sign);
179     void (*SMP_CallbackGenerateRPAResult)(uint8_t status, const uint8_t *addr);
180     void (*SMP_CallbackResolveRPAResult)(uint8_t status, bool result, const uint8_t *addr, const uint8_t *irk);
181     void (*SMP_CallbackGenerateScOobDataResult)(uint8_t status, const uint8_t *random, const uint8_t *confirm);
182 } SMP_Callback_t;
183 
184 /**
185  * @brief Set local IRk.
186  *
187  * @param irk Local IRK.
188  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
189  */
190 int SMP_SetIRK(const uint8_t *irk);
191 
192 /**
193  * @brief Set Local Identity Address.
194  *
195  * @param addr Local Identity Address.
196  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
197  */
198 int SMP_SetIdentAddr(const BtAddr *addr);
199 
200 /**
201  * @brief Resolve resolvable private address.
202  *
203  * @param addr Resolvable private address.
204  * @param irk Saved irk.
205  * @return Returns <b>SMP_RESOLVE_RPA_RESULT_YES</b> if the operation is successful;
206  *                                           returns others if the operation fails.
207  */
208 int SMP_ResolveRPA(const uint8_t *addr, const uint8_t *irk);
209 
210 /**
211  * @brief Resolve resolvable private address.
212  *
213  * @param addr Resolvable private address.
214  * @param irk Saved irk.
215  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
216  */
217 int SMP_AsyncResolveRPA(const uint8_t *addr, const uint8_t *irk);
218 
219 /**
220  * @brief Generate resolvable private address.
221  *
222  * @param irk Local irk.
223  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
224  */
225 int SMP_GenerateRPA(const uint8_t *irk);
226 
227 /**
228  * @brief Set Secure Connection Only mode.
229  *
230  * @param mode Whether it is Secure Connection Only mode.
231  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
232  */
233 int SMP_SetSecureConnOnlyMode(bool mode);
234 
235 /**
236  * @brief Send a Security Request to the remote device.
237  *
238  * @param handle ACL Connection Handle.
239  * @param authReq Authentication Requirements Flags.
240  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
241  */
242 int SMP_SendSecurityRequestToRemote(uint16_t handle, uint8_t authReq);
243 
244 /**
245  * @brief Generate signature.
246  *
247  * @param csrk Connection Signature Resolving Key.
248  * @param counter Signature counter .
249  * @param data Data that needs to be signed.
250  * @param dataLen Data length.
251  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
252  */
253 int SMP_GenerateSignature(const uint8_t *csrk, uint32_t counter, const uint8_t *data, uint16_t dataLen);
254 
255 /**
256  * @brief Start Encryption.
257  *
258  * @param handle ACL Connection Handle.
259  * @param random Saved peer random.
260  * @param ediv Saved peer ediv.
261  * @param key Saved peer long term key.
262  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
263  */
264 int SMP_StartEncryption(uint16_t handle, const uint8_t *random, uint16_t ediv, const uint8_t *key);
265 
266 /**
267  * @brief Proactively start pairing.
268  *
269  * @param handle ACL Connection Handle.
270  * @param localAddr Local addr.
271  * @param peerAddr Peer addr.
272  * @param param Paired param.
273  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
274  */
275 int SMP_StartPair(uint16_t handle, const BtAddr *localAddr, const BtAddr *peerAddr, const SMP_PairParam *param);
276 
277 /**
278  * @brief Reply authentication request.
279  *
280  * @param handle ACL Connection Handle.
281  * @param accept Accept or reject.
282  * @param rejectReason Reject Reason.
283  * @param pairMethod Paired method.
284  * @param entryValue Authentication value.
285  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
286  */
287 int SMP_AuthenticationRequestReply(
288     uint16_t handle, bool accept, uint8_t rejectReason, uint8_t pairMethod, const uint8_t *entryValue);
289 
290 /**
291  * @brief Reply to peer pairing request.
292  *
293  * @param handle ACL Connection Handle.
294  * @param rejectReason Reject Reason.
295  * @param localAddr Local addr.
296  * @param peerAddr Peer addr.
297  * @param param Paired param.
298  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
299  */
300 int SMP_RemotePairRequestReply(
301     uint16_t handle, uint8_t rejectReason, const BtAddr *localAddr, const BtAddr *peerAddr, const SMP_PairParam *param);
302 
303 /**
304  * @brief Reply to peer pairing response.
305  *
306  * @param handle ACL Connection Handle.
307  * @param accept Accept or reject.
308  * @param rejectReason Reject Reason.
309  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
310  */
311 int SMP_RemotePairResponseReply(uint16_t handle, bool accept, uint8_t rejectReason);
312 
313 /**
314  * @brief Reply peer security request.
315  *
316  * @param handle ACL Connection Handle.
317  * @param accept Accept or reject.
318  * @param rejectReason Reject reason.
319  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
320  */
321 int SMP_RemoteSecurityRequestReply(uint16_t handle, bool accept, uint8_t rejectReason);
322 
323 /**
324  * @brief Reply to remote encryption request.
325  *
326  * @param handle ACL Connection Handle.
327  * @param accept Accept or reject.
328  * @param key Local long term key.
329  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
330  */
331 int SMP_LongTermKeyRequestReply(uint16_t handle, bool accept, const uint8_t *key);
332 
333 /**
334  * @brief Proactively cancel pairing.
335  *
336  * @param handle ACL Connection Handle.
337  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
338  */
339 int SMP_CancelPair(uint16_t handle);
340 
341 /**
342  * @brief Register callback functions.
343  *
344  * @param cb Point to <b>SMP_Callback_t</b> struct, the struct must be available before calling to
345  *                  <b>SMP_UnregisterCallback</b>.
346  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
347  */
348 int SMP_RegisterCallback(const SMP_Callback_t *cb);
349 
350 /**
351  * @brief Unregister callback functions.
352  *
353  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
354  */
355 int SMP_UnregisterCallback();
356 
357 /**
358  * @brief Generate out of band data.
359  *
360  * @return Returns <b>BT_SUCCESS</b> if the operation is successful; returns others if the operation fails.
361  */
362 int SMP_GenerateScOobData();
363 
364 #ifdef __cplusplus
365 }
366 #endif
367 
368 #endif