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