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