1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <stddef.h>
6 #include <stdint.h>
7 
8 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_EAD_H_
9 #define ZEPHYR_INCLUDE_BLUETOOTH_EAD_H_
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/bluetooth/bluetooth.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * @brief Encrypted Advertising Data (EAD)
20  * @defgroup bt_ead Encrypted Advertising Data (EAD)
21  * @ingroup bluetooth
22  * @{
23  */
24 
25 /** Randomizer size in bytes */
26 #define BT_EAD_RANDOMIZER_SIZE 5
27 /** Key size in bytes */
28 #define BT_EAD_KEY_SIZE	       16
29 /** Initialisation Vector size in bytes */
30 #define BT_EAD_IV_SIZE	       8
31 /** MIC size in bytes */
32 #define BT_EAD_MIC_SIZE	       4
33 
34 /** Get the size (in bytes) of the encrypted advertising data for a given
35  *  payload size in bytes.
36  */
37 #define BT_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size)                                                \
38 	((payload_size) + BT_EAD_RANDOMIZER_SIZE + BT_EAD_MIC_SIZE)
39 
40 /** Get the size (in bytes) of the decrypted payload for a given payload size in
41  *  bytes.
42  */
43 #define BT_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_payload_size)                                      \
44 	((encrypted_payload_size) - (BT_EAD_RANDOMIZER_SIZE + BT_EAD_MIC_SIZE))
45 
46 /**
47  * @brief Encrypt and authenticate the given advertising data.
48  *
49  * The resulting data in @p encrypted_payload will look like that:
50  * - Randomizer is added in the @ref BT_EAD_RANDOMIZER_SIZE first bytes;
51  * - Encrypted payload is added ( @p payload_size bytes);
52  * - MIC is added in the last @ref BT_EAD_MIC_SIZE bytes.
53  *
54  * @attention The function must be called each time the RPA is updated or the
55  * data are modified.
56  *
57  * @note The term `advertising structure` is used to describe the advertising
58  *       data with the advertising type and the length of those two.
59  *
60  * @param[in]  session_key Key of @ref BT_EAD_KEY_SIZE bytes used for the
61  *             encryption.
62  * @param[in]  iv Initialisation Vector used to generate the nonce. It must be
63  *             changed each time the Session Key changes.
64  * @param[in]  payload Advertising Data to encrypt. Can be multiple advertising
65  *             structures that are concatenated.
66  * @param[in]  payload_size Size of the Advertising Data to encrypt.
67  * @param[out] encrypted_payload Encrypted Ad Data including the Randomizer and
68  *             the MIC. Size must be at least @ref BT_EAD_RANDOMIZER_SIZE + @p
69  *             payload_size + @ref BT_EAD_MIC_SIZE. Use @ref
70  *             BT_EAD_ENCRYPTED_PAYLOAD_SIZE to get the right size.
71  *
72  * @retval 0 Data have been correctly encrypted and authenticated.
73  * @retval -EIO Error occurred during the encryption or the authentication.
74  * @retval -EINVAL One of the argument is a NULL pointer.
75  * @retval -ECANCELED Error occurred during the random number generation.
76  */
77 int bt_ead_encrypt(const uint8_t session_key[BT_EAD_KEY_SIZE], const uint8_t iv[BT_EAD_IV_SIZE],
78 		   const uint8_t *payload, size_t payload_size, uint8_t *encrypted_payload);
79 
80 /**
81  * @brief Decrypt and authenticate the given encrypted advertising data.
82  *
83  * @note The term `advertising structure` is used to describe the advertising
84  *       data with the advertising type and the length of those two.
85  *
86  * @param[in]  session_key Key of 16 bytes used for the encryption.
87  * @param[in]  iv Initialisation Vector used to generate the `nonce`.
88  * @param[in]  encrypted_payload Encrypted Advertising Data received. This
89  *             should only contain the advertising data from the received
90  *             advertising structure, not the length nor the type.
91  * @param[in]  encrypted_payload_size Size of the received advertising data in
92  *             bytes. Should be equal to the length field of the received
93  *             advertising structure, minus the size of the type (1 byte).
94  * @param[out] payload Decrypted advertising payload. Use @ref
95  *             BT_EAD_DECRYPTED_PAYLOAD_SIZE to get the right size.
96  *
97  * @retval 0 Data have been correctly decrypted and authenticated.
98  * @retval -EIO Error occurred during the decryption or the authentication.
99  * @retval -EINVAL One of the argument is a NULL pointer or @p
100  *                 encrypted_payload_size is less than @ref
101  *                 BT_EAD_RANDOMIZER_SIZE + @ref BT_EAD_MIC_SIZE.
102  */
103 int bt_ead_decrypt(const uint8_t session_key[BT_EAD_KEY_SIZE], const uint8_t iv[BT_EAD_IV_SIZE],
104 		   const uint8_t *encrypted_payload, size_t encrypted_payload_size,
105 		   uint8_t *payload);
106 
107 /**
108  * @}
109  */
110 
111 #ifdef __cplusplus
112 }
113 #endif
114 
115 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_EAD_H_ */
116