Skip to content

Commit

Permalink
Bluetooth: Host: Add Encrypted Advertising Data
Browse files Browse the repository at this point in the history
Create a new Bluetooth library and add Encrypted Advertising Data to it.

Encrypted Advertising Data is a new feature from the Bluetooth Core
Specification 5.4. It provides a way to communicate encrypted data in
advertising, scan response and EIR packets. To do that it introduce a
new advertising data type called `Encrypted Advertising Data`. Also, it
introduce a new characteristic called `Encrypted Data Key Material`,
this provides a way to share the key material.

The library add two main functions `bt_ead_encrypt` and
`bt_ead_decrypt`.

Two helper functions are added to `bluetooth.h`. `bt_data_get_len` and
`bt_data_serialize`, the first one allow the user to get the total size
of a set of `bt_data` structures; the second one generate a spec
compliant bytes array from a `bt_data` structure. The last one is useful
because `bt_ead_encrypt` take as input those kind of bytes array.

Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
  • Loading branch information
theob-pro authored and jhedberg committed Mar 21, 2023
1 parent 6437234 commit a693b9b
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 0 deletions.
28 changes: 28 additions & 0 deletions include/zephyr/bluetooth/bluetooth.h
Expand Up @@ -388,6 +388,34 @@ struct bt_data {
BT_DATA(_type, ((uint8_t []) { _bytes }), \
sizeof((uint8_t []) { _bytes }))

/**
* @brief Get the total size (in bytes) of a given set of @ref bt_data
* structures.
*
* @param[in] data Array of @ref bt_data structures.
* @param[in] data_count Number of @ref bt_data structures in @p data.
*
* @return Size of the concatenated data, built from the @ref bt_data structure
* set.
*/
size_t bt_data_get_len(const struct bt_data data[], size_t data_count);

/**
* @brief Serialize a @ref bt_data struct into an advertising structure (a flat
* byte array).
*
* The data are formatted according to the Bluetooth Core Specification v. 5.4,
* vol. 3, part C, 11.
*
* @param[in] input Single @ref bt_data structure to read from.
* @param[out] output Buffer large enough to store the advertising structure in
* @p input. The size of it must be at least the size of the
* `input->data_len + 2` (for the type and the length).
*
* @return Number of bytes written in @p output.
*/
size_t bt_data_serialize(const struct bt_data *input, uint8_t *output);

/** Advertising options */
enum {
/** Convenience value when no options are specified. */
Expand Down
92 changes: 92 additions & 0 deletions include/zephyr/bluetooth/ead.h
@@ -0,0 +1,92 @@
/* Copyright (c) 2023 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/

#include <stddef.h>
#include <stdint.h>

#include <zephyr/kernel.h>

#include <zephyr/bluetooth/bluetooth.h>

/** Randomizer size in bytes */
#define BT_EAD_RANDOMIZER_SIZE 5
/** Key size in bytes */
#define BT_EAD_KEY_SIZE 16
/** Initialisation Vector size in bytes */
#define BT_EAD_IV_SIZE 8
/** MIC size in bytes */
#define BT_EAD_MIC_SIZE 4

/** Get the size (in bytes) of the encrypted advertising data for a given
* payload size in bytes.
*/
#define BT_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size) \
((payload_size) + BT_EAD_RANDOMIZER_SIZE + BT_EAD_MIC_SIZE)

/** Get the size (in bytes) of the decrypted payload for a given payload size in
* bytes.
*/
#define BT_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_payload_size) \
((encrypted_payload_size) - (BT_EAD_RANDOMIZER_SIZE + BT_EAD_MIC_SIZE))

/**
* @brief Encrypt and authenticate the given advertising data.
*
* The resulting data in @p encrypted_payload will look like that:
* - Randomizer is added in the @ref BT_EAD_RANDOMIZER_SIZE first bytes;
* - Encrypted payload is added ( @p payload_size bytes);
* - MIC is added in the last @ref BT_EAD_MIC_SIZE bytes.
*
* @attention The function must be called each time the RPA is updated or the
* data are modified.
*
* @note The term `advertising structure` is used to describe the advertising
* data with the advertising type and the length of those two.
*
* @param[in] session_key Key of @ref BT_EAD_KEY_SIZE bytes used for the
* encryption.
* @param[in] iv Initialisation Vector used to generate the nonce. It must be
* changed each time the Session Key changes.
* @param[in] payload Advertising Data to encrypt. Can be multiple advertising
* structures that are concatenated.
* @param[in] payload_size Size of the Advertising Data to encrypt.
* @param[out] encrypted_payload Encrypted Ad Data including the Randomizer and
* the MIC. Size must be at least @ref BT_EAD_RANDOMIZER_SIZE + @p
* payload_size + @ref BT_EAD_MIC_SIZE. Use @ref
* BT_EAD_ENCRYPTED_PAYLOAD_SIZE to get the right size.
*
* @retval 0 Data have been correctly encrypted and authenticated.
* @retval -EIO Error occurred during the encryption or the authentication.
* @retval -EINVAL One of the argument is a NULL pointer.
* @retval -ECANCELED Error occurred during the random number generation.
*/
int bt_ead_encrypt(const uint8_t session_key[BT_EAD_KEY_SIZE], const uint8_t iv[BT_EAD_IV_SIZE],
const uint8_t *payload, size_t payload_size, uint8_t *encrypted_payload);

/**
* @brief Decrypt and authenticate the given encrypted advertising data.
*
* @note The term `advertising structure` is used to describe the advertising
* data with the advertising type and the length of those two.
*
* @param[in] session_key Key of 16 bytes used for the encryption.
* @param[in] iv Initialisation Vector used to generate the `nonce`.
* @param[in] encrypted_payload Encrypted Advertising Data received. This
* should only contain the advertising data from the received
* advertising structure, not the length nor the type.
* @param[in] encrypted_payload_size Size of the received advertising data in
* bytes. Should be equal to the length field of the received
* advertising structure, minus the size of the type (1 byte).
* @param[out] payload Decrypted advertising payload. Use @ref
* BT_EAD_DECRYPTED_PAYLOAD_SIZE to get the right size.
*
* @retval 0 Data have been correctly decrypted and authenticated.
* @retval -EIO Error occurred during the decryption or the authentication.
* @retval -EINVAL One of the argument is a NULL pointer or @p
* encrypted_payload_size is less than @ref
* BT_EAD_RANDOMIZER_SIZE + @ref BT_EAD_MIC_SIZE.
*/
int bt_ead_decrypt(const uint8_t session_key[BT_EAD_KEY_SIZE], const uint8_t iv[BT_EAD_IV_SIZE],
const uint8_t *encrypted_payload, size_t encrypted_payload_size,
uint8_t *payload);
1 change: 1 addition & 0 deletions include/zephyr/bluetooth/gap.h
Expand Up @@ -70,6 +70,7 @@ extern "C" {
#define BT_DATA_CSIS_RSI 0x2e /* CSIS Random Set ID type */
#define BT_DATA_ADV_INT_LONG 0x2f /* Advertising Interval long */
#define BT_DATA_BROADCAST_NAME 0x30 /* Broadcast Name */
#define BT_DATA_ENCRYPTED_AD_DATA 0x31 /* Encrypted Advertising Data */
#define BT_DATA_3D_INFO 0x3D /* 3D Information Data */

#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/CMakeLists.txt
Expand Up @@ -17,3 +17,5 @@ if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
endif()

zephyr_include_directories(${ZEPHYR_BASE}/subsys/bluetooth)

add_subdirectory(lib)
1 change: 1 addition & 0 deletions subsys/bluetooth/Kconfig
Expand Up @@ -187,6 +187,7 @@ rsource "host/Kconfig"
rsource "controller/Kconfig"
rsource "shell/Kconfig"
rsource "crypto/Kconfig"
rsource "lib/Kconfig"

endif # BT_HCI

Expand Down
3 changes: 3 additions & 0 deletions subsys/bluetooth/lib/CMakeLists.txt
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_sources_ifdef(CONFIG_BT_EAD ead.c)
14 changes: 14 additions & 0 deletions subsys/bluetooth/lib/Kconfig
@@ -0,0 +1,14 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

config BT_EAD
bool "Encrypted Advertising Data [EXPERIMENTAL]"
select EXPERIMENTAL
select BT_HOST_CCM
help
Enable the Encrypted Advertising Data library

parent-module = BT
module = BT_EAD
module-str = "Bluetooth Encrypted Advertising Data"
source "subsys/logging/Kconfig.template.log_config_inherit"

0 comments on commit a693b9b

Please sign in to comment.