# DDR-0015: Fixed Initialization Vector for E27 AES-CBC Encryption

Status: Accepted  
Date: 2025-12-22  
Related ADRs: ADR-0003 (Crypto and Presentation Separation), ADR-0007 (E27 Layering)

## Context

The E27 protocol uses AES-128-CBC encryption for:
- schema-0 encrypted presentation-layer messages
- encrypted `api_link` responses (temporary key)
- encrypted `hello` response fields (`sk`, `shm`) using the link key

Unlike many modern protocols, E27 does not negotiate or transmit a per-message IV.
Instead, the IV is fixed and implicitly known by both client and panel implementations.
This behavior is confirmed by the vendor documentation and validated against a working
Node-RED reference implementation.

## Decision

The E27 implementation will use a fixed, constant initialization vector (IV) for all
AES-128-CBC encryption and decryption operations.

The IV is defined as:

- 16 bytes with incremental values from `0x00` to `0x0F`
- Represented in Python as:

  `API_LINK_IV = bytes(range(16))`

Rules:
- The IV is immutable and shared across all protocol phases:
  - api_link response decryption (temporary key)
  - hello session material decryption (link key)
  - normal schema-0 message encryption/decryption (session key)
- No endianness swapping is applied to the IV.
- The IV is never transmitted on the wire.

## Rationale

- Matches the behavior of the official E27 implementation
- Required for successful interoperability with real panels
- Eliminates IV negotiation complexity
- Keeps crypto behavior deterministic and debuggable
- Aligns with documented and observed protocol semantics

## Consequences

- AES-CBC encryption is deterministic for identical plaintext and keys
- This design does not provide semantic security against replay or ciphertext analysis,
  but reflects the constraints of the E27 protocol and cannot be altered client-side
- The IV must be defined in a single canonical location to prevent divergence
- All encryption/decryption helpers must consistently use this IV
