Skip to content

Commit f90867b

Browse files
committed
docs(stack-encrypt): state the Kms and Aead outcomes of a wrong blob context
ZeroKMS refuses a wrong context's descriptor before the AEAD runs, so it surfaces as Error::Kms; only a key source that ignores descriptors reaches Error::Aead. Say so in the blob module docs and the changelog, as the crate docs do, and limit the authentic-ciphertext claim to OpenedType and Blob.
1 parent f806561 commit f90867b

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

‎packages/stack-encrypt/CHANGELOG.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5252
any key is requested), and after the leaf authenticated, `blob_not_a_blob`,
5353
`blob_unsupported_version` (a later storage version: upgrade the reader),
5454
`blob_malformed` and `blob_mismatch` (a well-formed blob of another shape or
55-
type). Every decrypt-side `Blob` error means the ciphertext was authentic;
56-
tampering and a wrong context are still `Aead`, and a blob opened as a
57-
scalar or a scalar as a blob is `OpenedType`. No message or payload names a
55+
type). Every decrypt-side `Blob` error means the ciphertext was authentic.
56+
Tampering is still `Aead`; a wrong context is refused by ZeroKMS before
57+
the AEAD runs and surfaces as `Kms` (only a key source that ignores
58+
descriptors, such as `FakeDataKeySource`, lets it reach the AEAD as
59+
`Aead`); and a blob opened as a scalar or a scalar as a blob is
60+
`OpenedType`. No message or payload names a
5861
value; a mismatch's payload names the declared field.
5962
- **`Zeroizing<T>` as the opt-in drop-guarded result** of the scalar API:
6063
`OpaqueDecode` is implemented for `Zeroizing<P>` of any decodable `P`, so

‎packages/stack-encrypt/src/blob.rs‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,15 @@
148148
//!
149149
//! Decryption **authenticates before it decodes**. The leaf opens first,
150150
//! under its key and context; only then does the profile's reader see the
151-
//! bytes. So the errors tell three things apart:
152-
//!
153-
//! - [`Error::Aead`]: the leaf did not open. Wrong key, wrong context, or
154-
//! altered bytes; the blob was never looked at.
151+
//! bytes. A context other than the one the blob was sealed under is
152+
//! normally refused before that: ZeroKMS binds each data key to its
153+
//! context's descriptor and denies the retrieve, so it surfaces as
154+
//! [`Error::Kms`] and nothing is decrypted. Past key retrieval, the errors
155+
//! tell three things apart:
156+
//!
157+
//! - [`Error::Aead`]: the leaf did not open. Altered bytes, the wrong key,
158+
//! or a wrong context under a key source that ignores descriptors
159+
//! (`FakeDataKeySource`, in tests); the blob was never looked at.
155160
//! - [`Error::OpenedType`]: the leaf opened but is not a bytes leaf: it was
156161
//! sealed as a `String` or an integer, say, not as a blob.
157162
//! - [`Error::Blob`]: the leaf opened as bytes and they are not a blob this
@@ -160,9 +165,10 @@
160165
//! of version 1 ([`BlobError::Malformed`]), or a well-formed blob that is
161166
//! not a `T` ([`BlobError::Mismatch`]).
162167
//!
163-
//! All three are refusals of an authentic ciphertext, so an `Error::Blob`
164-
//! never says the data was tampered with; it says the data was written as
165-
//! something else. The whole blob is validated before `T`'s `Deserialize`
168+
//! [`Error::OpenedType`] and [`Error::Blob`] are refusals of an authentic
169+
//! ciphertext, so neither says the data was tampered with; each says the
170+
//! data was written as something else. Only [`Error::Aead`] (or
171+
//! [`Error::Kms`]) leaves the ciphertext's authenticity unestablished. The whole blob is validated before `T`'s `Deserialize`
166172
//! sees any of it: every length is checked against the end of the blob, so
167173
//! a forged length allocates nothing, and a `Deserialize` impl never builds
168174
//! part of a value from a malformed blob. No refusal names a value or a map
@@ -238,6 +244,7 @@
238244
//! with its marker; both readers read either form).
239245
//!
240246
//! [`Error::Aead`]: crate::Error::Aead
247+
//! [`Error::Kms`]: crate::Error::Kms
241248
//! [`Error::OpenedType`]: crate::Error::OpenedType
242249
//! [`Error::Blob`]: crate::Error::Blob
243250
//! [`KeysetCipher::encrypt`]: crate::KeysetCipher::encrypt

0 commit comments

Comments
 (0)