# Module: binary_split ## Purpose Handles the encrypted Docker image archive workflow: downloading a key fragment from the API, decrypting an AES-256-CBC encrypted archive, loading it into Docker, and verifying expected images are present. ## Public Interface ### Functions | Function | Signature | Description | |------------------------|------------------------------------------------------------------------|----------------------------------------------------------| | `download_key_fragment`| `(resource_api_url: str, token: str) -> bytes` | GET request to `/binary-split/key-fragment` with Bearer auth | | `decrypt_archive` | `(encrypted_path: str, key_fragment: bytes, output_path: str) -> None` | AES-256-CBC stream decrypt with SHA-256 derived key; PKCS7 removed in-pipeline via unpadder | | `docker_load` | `(tar_path: str) -> None` | Runs `docker load -i ` subprocess | | `check_images_loaded` | `(version: str) -> bool` | Checks all `API_SERVICES` images exist for given version tag | ### Module-level Constants | Name | Value | |---------------|--------------------------------------------------------------------------------------------| | API_SERVICES | List of 7 Docker image names: `azaion/annotations`, `azaion/flights`, `azaion/detections`, `azaion/gps-denied-onboard`, `azaion/gps-denied-desktop`, `azaion/autopilot`, `azaion/ai-training` | ## Internal Logic ### `decrypt_archive` 1. Derives AES key: `SHA-256(key_fragment)` → 32-byte key 2. Reads first 16 bytes as IV from encrypted file 3. Streams ciphertext in 64KB chunks through AES-256-CBC decryptor 4. Feeds decrypted chunks through `padding.PKCS7(128).unpadder()`; writes unpadded bytes to the output file (`finalize` on decryptor and unpadder at end) ### `check_images_loaded` Iterates all 7 service image names, runs `docker image inspect :` for each. Returns `False` on first missing image. ## Dependencies - **Internal**: none (leaf module) - **External**: `hashlib`, `subprocess` (stdlib), `requests` (2.32.4), `cryptography` (44.0.2) ## Consumers - `main` — `_run_unlock()` calls all four functions; `unlock()` endpoint calls `check_images_loaded()` ## Data Models None. ## Configuration No env vars consumed directly. `API_SERVICES` list is hardcoded. ## External Integrations - **REST API**: GET `{resource_api_url}/binary-split/key-fragment` — downloads encryption key fragment - **Docker CLI**: `docker load` and `docker image inspect` via subprocess - **File system**: reads encrypted `.enc` archive, writes decrypted `.tar` archive ## Security - Key derivation: SHA-256 hash of server-provided key fragment - Encryption: AES-256-CBC with PKCS7 padding - The key fragment is ephemeral — downloaded per unlock operation ## Tests No tests found.