Repository navigation
v0.0.26
Padded streams get their own domain
Padded streams are now domain-separated from plain ones, and the padded sealer
enforces the declared size before it writes any padding. Padded blobs sealed
by v0.0.24 or v0.0.25 no longer open. Everything else is untouched.
Breaking
Both padded helpers prepend a fixed domain tag to the caller's AAD, so a padded
stream and a plain one can no longer be opened as each other. A padded blob from
v0.0.24 or v0.0.25 fails as ErrStreamAuth.
Unaffected: SealStream/SealFile blobs, single-shot tokens
(SealString, SealBytes, SealInt64), and wrapped master keys. Only
SealPaddedStream/SealPaddedFile output changed.
Migration: open with v0.0.25 and re-seal with v0.0.26. No signature changed,
so the only edit is the version in go.mod.
The bytes on disk are still identically shaped, so a file continues not to
advertise whether it is padded. The price is diagnosis: a plain stream opened as
padded now fails as ErrStreamAuth, indistinguishable from a wrong key. Retry
with OpenStream over a fresh reader, which succeeds only in the unpadded case.
Changed
- A wrong
sizenow costs a header instead of a Padmé bucket. The padded
sealer wrapssrcand enforces the declared length at the payload boundary,
before any padding is generated. A caller declaring 1 TiB and sending one byte
previously had ~16 GiB of zeros written before the end-of-stream check
noticed; it now costs the 37-byte header. That is what makessizesafe to
take from an untrusted peer, such as an upload that states its own length. - The opener's drain is bounded. The expected padding is computed from
PaddedSizeup front and drained withio.CopyNplus a one-byte end probe,
so a frame declaring a small payload inside a huge stream is rejected after a
couple of chunks rather than after the whole file. ErrNotPaddedandErrSourceSizeare now umbrellas and carry no cause of
their own; their messages changed accordingly.errors.Isagainst either
still matches.
Added
-
New errors, each wrapping the umbrella it belongs to:
ErrNoPaddingFrameandErrPaddingMalformedunderErrNotPadded;
ErrSourceIrregular,ErrSourceShortandErrSourceLongunder
ErrSourceSize. A caller that must tell "retry the upload" from "reject it"
can now branch on the direction. -
Deferred padding, demonstrated. An HTML multipart upload states no length,
soSealPaddedStreamcannot run on the request path. Section 11 of the
envelope example seals the upload unpadded, then recovers the length from the
sealed size and re-seals it padded in a second pass. -
An HTTP upload server in the example, behind
-serve, for pushing a real
file through the streaming and padding APIs by hand:go run ./_example/envelope -serve 127.0.0.1:8080 go run ./_example/envelope -serve 127.0.0.1:8080 -max 0 -dir /tmp/enc It caps uploads at 1 GiB and stores ciphertext in a temp dir; -max 0 -dir lifts both, which is what a multi-gigabyte test needs.
Compatibility
- Requires Go 1.25+. The only external dependency is golang.org/x/crypto.
- No exported signature changed.
- The wire formats are unchanged: single-shot 0x01, stream 0x81, padding
frame 0x01 inside the sealed plaintext. What changed is the AAD a padded
stream authenticates, which is never stored.
Full Changelog: v0.0.25...v0.0.26