Documentation
¶
Overview ¶
Package crypto implements a **KEM-DEM envelope encryption scheme** suitable for multi-gigabyte streams. The design is intentionally simple and “pure Go”: it depends only on `x/crypto` and `filippo.io/edwards25519` (both CGO-free) and compiles to a single static binary.
────────────────────────── Design summary ─────────────────────────────
⚙ KEM (Key-Encapsulation Mechanism)
• X25519 + XSalsa20-Poly1305 via `box.SealAnonymous`
• Output: 80-byte “sealed box” containing a fresh 256-bit DEK
• Provides forward secrecy for each blob
⚙ DEM (Data-Encapsulation Mechanism)
• ChaCha20-Poly1305 (IETF) in ~64 KiB framed chunks (65519 bytes max)
• Nonce = 4-byte random prefix ∥ 8-byte little-endian counter
• First frame authenticates header via associated data (prevents tampering)
• Constant ~64 KiB RAM, O(1) header re-wrap for key rotation
⚙ Fleet key
• Single Ed25519 key-pair per customer
• Public half is converted → X25519 for the KEM
• Private half is stored in a cloud secret store (AWS Secrets
Manager / Google Secret Manager) and fetched at boot
File layout
┌───────────────────────────────────────────────────────────┐
│ uint16 sealedLen │ 80B sealed DEK │ 12B base nonce │ … │
└───────────────────────────────────────────────────────────┘
▲ ▲
│ └─ ChaCha20-Poly1305 frames
└─ X25519 sealed box
Security properties
• Confidentiality & integrity: ChaCha20-Poly1305 per frame
• Header authentication: first frame includes header as associated data
• Forward-secrecy per object: new ephemeral X25519 key each seal
• Key rotation: requires re-wrapping only the 80-byte header
• No CGO / no OpenSSL: entire TCB is Go std-lib + x/crypto
Typical workflow
────────────────
Publisher:
1) generate DEK, encrypt stream → dst
2) sealed = SealAnonymous(DEK, fleetPub)
3) write header {len, sealed, nonce} - 94 bytes total
4) first frame includes header as associated data for authentication
Machine node:
1) read header, unseal DEK with fleet **private** key
2) stream-decrypt frames on the fly (first frame verifies header)
Threat-model notes
• Relay never sees plaintext or DEK
• Deregistering a node revokes access at the transport layer, so
per-node keys are unnecessary in this model.
Public API ──────────
EncryptHybridKEMDEMStream(pub ed25519.PublicKey, r io.Reader, w io.Writer) DecryptHybridKEMDEMStream(priv ed25519.PrivateKey, r io.Reader, w io.Writer)
Both return the number of plaintext bytes processed and ensure that every error path is authenticated-failure-safe (no partial plaintext leaks before MAC verification).
This comment is intentionally verbose so that a security reviewer can evaluate the construction without reading the code first.
Index ¶
- func DecryptHybridKEMDEMStream(priv ed25519.PrivateKey, src io.Reader, dst io.Writer) (int64, error)
- func DecryptStream(reader io.Reader, writer io.WriteCloser, key string) error
- func EncryptHybridKEMDEMStream(pub ed25519.PublicKey, src io.Reader, dst io.Writer) (int64, error)
- func EncryptStream(reader io.Reader, writer io.WriteCloser, key string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecryptHybridKEMDEMStream ¶ added in v1.0.70
func DecryptHybridKEMDEMStream(priv ed25519.PrivateKey, src io.Reader, dst io.Writer) (int64, error)
DecryptHybridKEMDEMStream reverses EncryptHybridKEMDEMStream.
func DecryptStream ¶ added in v1.0.13
DecryptStream decrypts data from a reader (like an HTTP response body) using a chunked approach where each chunk has its own nonce and authentication tag. This is secure for large files and streaming data sources. The format of each chunk is: [4-byte chunk size (little-endian)][nonce][encrypted data][tag]
func EncryptHybridKEMDEMStream ¶ added in v1.0.70
EncryptHybridKEMDEMStream copies src → dst, returns plaintext bytes written.
func EncryptStream ¶ added in v1.0.13
EncryptStream encrypts data from a reader using a chunked approach where each chunk has its own nonce and authentication tag. This is secure for large files and streaming data sources. The format of each chunk is: [4-byte chunk size (little-endian)][nonce][encrypted data][tag]
Types ¶
This section is empty.