Encrypted Advertising Data: Design Receiver Key Selection and Freshness Checks
Accept encrypted advertising through three separate gates: select authorized candidate key material, authenticate and parse the protected payload, then apply the product’s freshness policy. Successful decryption does not tell the receiver that an old authentic advertisement represents the broadcaster’s current state.
Applicability: Core Supplement v12 Encrypted Data format, Bluetooth Core 6.1 GAP key-material procedure and Zephyr v4.2.0 EAD APIs. These are explicit reference versions. The receiver policy and replay fixtures are proposed designs, not an executed security evaluation. Pairing and bond-store management are outside this article.

1. Separate key possession from packet freshness
The Supplement’s Encrypted Data structure contains a randomizer, encrypted payload and MIC. The protected payload is a sequence of AD structures. Its outer format does not provide a universal application sender identifier, key-version field or monotonically increasing freshness counter.
The randomizer is part of nonce construction, not an application sequence number. Replaying the same authentic ciphertext preserves its cryptographic validity under the same key material. Therefore infer freshness only from a separately designed, authenticated application contract and retained receiver state.
If several devices share one symmetric key, successful authentication establishes membership in that key-holding group, not unique proof of which member transmitted the packet. Choose per-device or group material deliberately and reflect that distinction in authorization.
2. Maintain a bounded authorized key registry
Associate each installed key-and-IV pair with its authorized service or sender scope, local generation, activation rule and retirement rule. Do not log key bytes. The Core 6.1 GAP procedure uses the Encrypted Data Key Material characteristic; its read access requires authentication and authorization.
Perform candidate selection from a previously established relationship or service context. A visible routing hint may reduce lookup work, but remains untrusted until the protected content confirms the intended scope. It must not authorize installing a new key, expanding a candidate list or resetting freshness state.
Bound both candidate count and work per received report. A hypothetical rotation policy might allow current and previous material for one service during a controlled transition. That is a product policy, not a standard two-key limit. Do not try every retained key indefinitely on arbitrary nearby traffic.
Evaluate privacy before adding a stable visible key identifier. A convenient lookup field can also become a tracking identifier. Keep authenticated sender identity inside the protected application structure when the product’s discovery design permits it.
3. Validate lengths before decrypting
The Zephyr v4.2.0 API expects only the Encrypted Data AD value, excluding its Length and Type bytes. The value contains five randomizer bytes and four MIC bytes in addition to the encrypted payload. Reject shorter values before computing the decoded size.
BT_EAD_DECRYPTED_PAYLOAD_SIZE is subtraction, not input validation. Applying it to an unchecked unsigned length below nine can underflow. Check the outer AD boundary, the minimum overhead, a product maximum and destination capacity before calling the decryptor.
Decrypt into temporary storage. Publish no plaintext until bt_ead_decrypt returns success, and discard the temporary result on any failure. Authentication success is followed by inner AD-length validation and required-schema checks; it is not permission to cast arbitrary bytes directly to a product structure.
The exact implementation permits a nine-byte value to reach decryption while warning that it contains no encrypted data. The product parser must still reject an empty payload when its schema requires an AD structure. API acceptance and application validity are separate boundaries.
4. Put replay semantics inside authenticated content
A proposed application AD structure can contain format version, sender scope, key epoch, monotonic sequence and the actual state record. Define each field’s encoding and maximum size. Verify the authenticated epoch against the candidate key record, rather than trusting an unauthenticated hint.
For a latest-state telemetry service, a simple policy accepts only a sequence greater than the stored high-water mark within the same authorized epoch. Duplicates may update a reception diagnostic but must not retrigger an operation or refresh the state’s semantic age.
A hypothetical receiver that has accepted epoch 7, sequence 105 should reject replayed sequence 104 and duplicate 105, while accepting valid 106. This fixture assumes a nonwrapping sequence domain and trustworthy retained state. Define a controlled epoch transition before counter exhaustion; do not let wrap silently reset the comparison.
Sequence ordering alone does not bound absolute age. A first-seen but old packet can be newer than the receiver’s stored mark. Where age matters, require an authenticated timestamp with a trustworthy clock policy, or refresh state through an authenticated interaction before enabling the dependent action.
After receiver state loss, treat freshness as unknown. After broadcaster reset, do not reuse a sequence epoch unless its continuity is safely retained. An arbitrary reboot marker is not automatically a trusted new epoch; authorize the transition through the product’s key or synchronization lifecycle.
5. Rotate key material without reopening history
The Supplement requires a changed randomizer when payload or random device address changes, and a changed IV when the session key changes. Zephyr’s encrypt API documents re-encryption when data or the RPA changes. Coordinate those operations with the broadcaster’s advertising update path.
Keep replay state separate for each accepted key epoch during overlap. Retire old material according to a bounded policy and reject it afterward. A receiver that misses rotation needs an authorized resynchronization path; unlimited acceptance of old keys is not a recovery design.
Audit diagnostic configuration too. The tagged EAD implementation contains a debug hexdump of the output buffer before checking the cryptographic return. Disable sensitive payload logging in production and do not assume a failed authentication leaves no bytes available to accidental logging.
6. Test the complete admission decision
- Reject short, oversized and malformed outer AD values before decryption.
- Try wrong keys and modified ciphertext/MIC; verify no plaintext reaches consumers.
- Authenticate malformed or empty inner content; verify schema rejection.
- Replay accepted and older sequences; verify no duplicate state transition.
- Rotate material with one receiver offline; verify bounded overlap and explicit recovery.
- Reboot each side independently; verify lost continuity becomes unknown rather than fresh.
- Change an RPA without changing application state; verify the encryption update path runs.
Record rejection category, nonsecret key generation, schema version and freshness decision. Avoid retaining private payloads unnecessarily. Acceptance requires correct cryptography, meaningful authenticated content and a defensible freshness result, each visible as its own gate.