Documentation
¶
Overview ¶
Package crypto implements a **FIPS 140-3 compliant KEM-DEM envelope encryption scheme** suitable for multi-gigabyte streams using ECDH P-256 and AES-256-GCM. This design is Go 1.24+ FIPS compatible (GOFIPS140=v1.0.0) and depends only on standard library crypto packages.
────────────────────────── Design summary ─────────────────────────────
⚙ KEM (Key-Encapsulation Mechanism)
• ECDH P-256 + AES-256-GCM for DEK wrapping
• Output: variable-size encrypted DEK (48-byte DEK + 16-byte GCM tag + ephemeral pubkey)
• Provides forward secrecy for each blob
⚙ DEM (Data-Encapsulation Mechanism)
• AES-256-GCM 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 ECDSA P-256 key-pair per customer
• Public key used directly for ECDH operations
• Private key stored in cloud secret store and fetched at boot
File layout
┌─────────────────────────────────────────────────────────────────────────┐
│ uint16 wrappedLen │ 125B wrapped DEK │ 12B base nonce │ frames... │
└─────────────────────────────────────────────────────────────────────────┘
▲ ▲
│ └─ AES-256-GCM frames
└─ ECDH + AES-GCM wrapped DEK
Security properties
• Confidentiality & integrity: AES-256-GCM per frame
• Header authentication: first frame includes header as associated data
• Forward-secrecy per object: new ephemeral ECDH key each encryption
• Key rotation: requires re-wrapping only the ~139-byte header
• FIPS 140-3 compliant: uses only approved algorithms
Typical workflow
────────────────
Publisher:
1) generate DEK, encrypt stream → dst
2) ephemeral ECDH + AES-GCM wrap DEK with fleet public key
3) write header {len, wrapped DEK, nonce} - ~139 bytes total
4) first frame includes header as associated data for authentication
Machine node:
1) read header, unwrap DEK with fleet private key via ECDH
2) stream-decrypt frames on the fly (first frame verifies header)
Public API ──────────
EncryptFIPSKEMDEMStream(pub *ecdsa.PublicKey, r io.Reader, w io.Writer) DecryptFIPSKEMDEMStream(priv *ecdsa.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.
Index ¶
- Constants
- Variables
- func DecryptBytes(encryptedData []byte, key string) ([]byte, error)
- func DecryptFIPSKEMDEMStream(priv *ecdsa.PrivateKey, src io.Reader, dst io.Writer) (int64, error)
- func DecryptStream(reader io.Reader, writer io.WriteCloser, key string) error
- func EncryptBytes(data []byte, key string) ([]byte, error)
- func EncryptFIPSKEMDEMStream(pub *ecdsa.PublicKey, src io.Reader, dst io.Writer) (int64, error)
- func EncryptStream(reader io.Reader, writer io.WriteCloser, key string) error
- func PrepareHTTPRequestForStreaming(key *ecdsa.PrivateKey, req *http.Request) error
- func SignHTTPRequest(key *ecdsa.PrivateKey, req *http.Request, body []byte) error
- func VerifyHTTPRequest(key *ecdsa.PublicKey, req *http.Request, body []byte, ...) error
- func VerifyHTTPRequestSignatureWithBody(key *ecdsa.PublicKey, req *http.Request, bodyReader io.Reader, ...) error
- func VerifyHTTPRequestStreaming(key *ecdsa.PublicKey, req *http.Request, bodyReader io.Reader, ...) error
Constants ¶
const ( HeaderSignature = "Signature" HeaderSignatureAlg = "X-Signature-Alg" HeaderSignatureKeyID = "X-Signature-KeyID" HeaderSignatureTimestamp = "X-Signature-Timestamp" HeaderSignatureNonce = "X-Signature-Nonce" SignatureAlgorithmECDSA = "ecdsa-sha256" SignatureECDSAKeyIDPrefix = "k1-ecdsa-" )
const MaxChunkSize = 10 * 1024 * 1024 // 10 MiB
MaxChunkSize is the maximum allowed ciphertext chunk length (bytes).
Variables ¶
var ErrChunkSizeTooLarge = errors.New("chunk size too large")
ErrChunkSizeTooLarge is returned when a chunk size exceeds the maximum allowed size.
var (
ErrSignatureComputationTimeout = errors.New("signature computation timeout")
)
Predefined errors for better error handling and testing
Functions ¶
func DecryptBytes ¶ added in v1.0.81
DecryptBytes decrypts a byte array and returns the decrypted bytes. For better performance with large data or when you have readers/writers available, use DecryptStream instead.
func DecryptFIPSKEMDEMStream ¶ added in v1.0.74
DecryptFIPSKEMDEMStream reverses EncryptFIPSKEMDEMStream using FIPS-approved algorithms.
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 EncryptBytes ¶ added in v1.0.81
EncryptBytes encrypts a byte array and returns the encrypted bytes. For better performance with large data or when you have readers/writers available, use EncryptStream instead.
func EncryptFIPSKEMDEMStream ¶ added in v1.0.74
EncryptFIPSKEMDEMStream copies src → dst using FIPS-approved algorithms, 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]
func PrepareHTTPRequestForStreaming ¶ added in v1.0.85
func PrepareHTTPRequestForStreaming(key *ecdsa.PrivateKey, req *http.Request) error
PrepareHTTPRequestForStreaming sets up a request for streaming signature.
func SignHTTPRequest ¶ added in v1.0.73
SignHTTPRequest signs an HTTP request with the given private key and body and sets the signature headers in the request.
func VerifyHTTPRequest ¶ added in v1.0.73
func VerifyHTTPRequest(key *ecdsa.PublicKey, req *http.Request, body []byte, checkNonce func(string) error) error
VerifyHTTPRequest verifies a request and body against the provided HTTP signature headers to ensure that the request is valid and the body matches the signature.
func VerifyHTTPRequestSignatureWithBody ¶ added in v1.0.86
func VerifyHTTPRequestSignatureWithBody(key *ecdsa.PublicKey, req *http.Request, bodyReader io.Reader, timestamp time.Time, nonce string, checkNonce func(string) error) error
VerifyHTTPRequestSignatureWithBody verifies a request and body against the provided HTTP signature headers to ensure that the request is valid and the body matches the signature.
func VerifyHTTPRequestStreaming ¶ added in v1.0.85
func VerifyHTTPRequestStreaming(key *ecdsa.PublicKey, req *http.Request, bodyReader io.Reader, checkNonce func(string) error) error
VerifyHTTPRequestStreaming verifies a request and body against the provided HTTP signature headers to ensure that the request is valid and the body matches the signature.
Types ¶
This section is empty.