Clypeum Crypto Container Binary Format

# Clypeum Crypto Container Binary Format

Reference: Clypeum CryptoContainerService Cryptographic Data Format Specification

## General Structure
Container = Header + Payload (encrypted) + Signature

All multi-byte fields are **big-endian**.

## Container Header

### Version 0x1 (current)
| Offset | Size | Field | Description |
|--------|------|-------|-------------|
| 0 | 4 | File Start Code | `0x53454301` |
| 4 | 4 | Version | `0x00000001` |
| 8 | 4 | Header Length | Bytes |
| 12 | 4 | Payload Length | Bytes (of encrypted payload, includes padding) |
| 16 | 4 | Signature Length | Bytes |
| 20 | 1 | Signature Algorithm | `0x00`=None, `0x01`=Sha256WithRSA (0x100 bytes) |
| 21 | 2 | Crypto Data Type | e.g. `0x0900` for our production container |
| 23 | 1 | Encryption Algorithm | `0x00`=None, `0x01`=AES-256-CBC, `0x02`=RSA-OAEP-SHA256 |
| 24 | 1 | Hash Algorithm | `0x00`=SHA-256, `0x01`=SHA-512, `0x02`=SHA-3-384, `0x03`=SHA-4-512 |
| 25 | 32/64 | Payload Hash | SHA-256=32 bytes, SHA-512=64 bytes (of plaintext payload) |
| 57/89 | 4 | Time-to-Live | POSIX timestamp (30 days from generation) |
| 61/93 | 64 | Crypto Container ID (CID) | Unique identifier |

### Header parsing code
See `crates/kf-dev-station/src/container_parser.rs` — `ParsedContainer::parse()`

## Payload (encrypted)
The payload (header + data) is encrypted first, then hash is computed on the **plaintext** and stored in the container header.

### Decryption order
1. Verify signature (RSA/ECDSA over entire container)
2. Decrypt payload using AES-256-CBC (key derived from seed?)
3. Verify payload hash matches header hash
4. Parse payload

## Payload Header
| Size | Field | Description |
|------|-------|-------------|
| 4 | Payload Start Code | `0x50415901` |
| 4 | CRC32 | Polynomial `0x04C11DB7`, over "Header Version" through end of data |
| 4 | Header Version | Starts at `0x00000002` |
| 4 | Payload Type | See table below |
| 4 | Payload Data Length | Bytes |

### Payload Types
| Value | Description |
|-------|-------------|
| 0x01 | M-format keys (SHE) |
| 0x05 | M-format keys (SHE+) |
| 0x04 | UCB Block TC3XX |

## Signature
- Calculated over entire container (header + encrypted payload + signature itself is the final step)
- Minimum RSA 2048-bit, ECC 256-bit
- Algorithm `0x01` = Sha256WithRSAEncryption, signature length 0x100 (256 bytes)

## Container Type 0x0900
Production key bundle container for our use case. Structure TBD — likely M-format keys or custom format. The Extra JSON sent with the generation request includes transaction metadata, fob UID/SCP03 data.

## Test Containers
- Dummy crypto data but all fields correctly generated and consistent
- Keys have known values, included in clear text
- For our type: `keyBundleType: "dev"`

## Verification Steps (per spec)
1. Verify payload hash (decrypt first, then compare)
2. Verify payload CRC32
3. Authenticate signature

## Current State
- Parser implemented (`container_parser.rs`) — parses header, extracts encrypted payload and signature
- Payload decryption not yet implemented (need to determine AES key derivation from seed)
- Signature verification not yet implemented (need Clypeum public key)

id: a5535547f87f42deaa4af07f34f928f1
parent_id: beb251c3b3f9490285e6cb68942a5145
created_time: 2026-08-12T10:00:09.081Z
updated_time: 2026-08-14T16:59:00.613Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1786528809081
user_created_time: 2026-08-12T10:00:09.081Z
user_updated_time: 2026-08-14T16:59:00.613Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
is_locked: 0
extracted_resource_ids: 
type_: 1