src.bluetooth_sig.types.ead

Type definitions for BLE Encrypted Advertising Data (EAD).

This module defines data structures for Encrypted Advertising Data per Bluetooth Core Spec Supplement Section 1.23.

EAD Format:

[Randomizer (5 bytes)][Encrypted Payload (variable)][MIC (4 bytes)]

The Randomizer provides uniqueness for each advertisement. The MIC (Message Integrity Check) is a 4-byte authentication tag produced by AES-CCM encryption.

Cryptographic parameters per Bluetooth Core Spec Supplement:
  • Session Key: 16-byte AES-128 key

  • IV: 8-byte initialization vector

  • Nonce: 13 bytes (Randomizer + Device Address + Padding)

  • MIC: 4-byte authentication tag

Attributes

Classes

Name

Description

EADDecryptResult

Result of an EAD decryption attempt.

EADError

Error types for EAD decryption failures.

EADKeyMaterial

Key material for BLE Encrypted Advertising Data (EAD).

EncryptedAdvertisingData

Parsed BLE Encrypted Advertising Data structure.

Module Contents

class src.bluetooth_sig.types.ead.EADDecryptResult

Bases: msgspec.Struct

Result of an EAD decryption attempt.

Provides structured feedback on decryption success or failure, including specific error types for appropriate handling.

success

Whether decryption succeeded

plaintext

Decrypted data if successful, None otherwise

error

Human-readable error message if failed

error_type

Structured error type for programmatic handling

Example - successful decryption:
>>> result = EADDecryptResult(success=True, plaintext=b"sensor_data")
>>> if result.success:
...     process_data(result.plaintext)
Example - failed decryption:
>>> result = EADDecryptResult(
...     success=False,
...     plaintext=None,
...     error="MIC verification failed",
...     error_type=EADError.INVALID_KEY,
... )
>>> if result.error_type == EADError.INVALID_KEY:
...     request_new_key()
error: str | None = None
error_type: EADError | None = None
plaintext: bytes | None = None
success: bool
class src.bluetooth_sig.types.ead.EADError(*args, **kwds)

Bases: enum.Enum

Error types for EAD decryption failures.

INVALID_KEY

Decryption failed due to incorrect key (MIC mismatch)

REPLAY_DETECTED

Advertisement counter indicates replay attack

CORRUPTED_DATA

Data format invalid or too short

NO_KEY_AVAILABLE

No encryption key configured for this device

INSUFFICIENT_DATA

EAD payload too short to contain required fields

CORRUPTED_DATA
INSUFFICIENT_DATA
INVALID_KEY
NO_KEY_AVAILABLE
REPLAY_DETECTED
class src.bluetooth_sig.types.ead.EADKeyMaterial

Bases: msgspec.Struct

Key material for BLE Encrypted Advertising Data (EAD).

Per Bluetooth Core Spec Supplement Section 1.23, EAD encryption requires a 16-byte session key and 8-byte initialization vector.

Validation is performed at construction time - invalid key sizes will raise ValueError.

session_key

16-byte AES-128 session key for encryption/decryption

iv

8-byte initialization vector (combined with randomizer for nonce)

Example

>>> key_material = EADKeyMaterial(
...     session_key=bytes.fromhex("0123456789abcdef0123456789abcdef"),
...     iv=bytes.fromhex("0102030405060708"),
... )
Raises:

ValueError – If session_key is not 16 bytes or iv is not 8 bytes

iv: bytes
session_key: bytes
class src.bluetooth_sig.types.ead.EncryptedAdvertisingData

Bases: msgspec.Struct

Parsed BLE Encrypted Advertising Data structure.

Represents the three components of an EAD advertisement as defined in Bluetooth Core Spec Supplement Section 1.23.

randomizer

5-byte randomizer for nonce construction

encrypted_payload

Variable-length encrypted data

mic

4-byte Message Integrity Check (authentication tag)

Example

>>> raw = bytes.fromhex("0102030405aabbccdd11223344")
>>> ead = EncryptedAdvertisingData.from_bytes(raw)
>>> print(ead.randomizer.hex())
'0102030405'
>>> print(ead.mic.hex())
'11223344'
classmethod from_bytes(data: bytes) typing_extensions.Self

Parse raw EAD bytes into structured components.

Parameters:

data – Raw EAD advertisement data (minimum 9 bytes: 5-byte randomizer + at least 0-byte payload + 4-byte MIC)

Returns:

Parsed EncryptedAdvertisingData structure

Raises:

ValueError – If data is shorter than minimum EAD size (9 bytes)

Example

>>> raw = bytes.fromhex("0102030405aabbccdd11223344")
>>> ead = EncryptedAdvertisingData.from_bytes(raw)
>>> len(ead.encrypted_payload)
4
encrypted_payload: bytes
mic: bytes
randomizer: bytes
src.bluetooth_sig.types.ead.EAD_ADDRESS_SIZE: int = 6
src.bluetooth_sig.types.ead.EAD_IV_SIZE: int = 8
src.bluetooth_sig.types.ead.EAD_MIC_SIZE: int = 4
src.bluetooth_sig.types.ead.EAD_MIN_SIZE: int = 9
src.bluetooth_sig.types.ead.EAD_NONCE_SIZE: int = 13
src.bluetooth_sig.types.ead.EAD_RANDOMIZER_SIZE: int = 5
src.bluetooth_sig.types.ead.EAD_SESSION_KEY_SIZE: int = 16