lib_q_core/aead_semantic.rs
1//! Layer B semantic outcomes for AEAD decryption.
2//!
3//! See workspace ADR `docs/adr/003-aead-decrypt-layers.md` for Layer A/B/C definitions and
4//! threat-model boundaries. This module is gated on the **`alloc`** feature.
5
6extern crate alloc;
7
8use alloc::vec::Vec;
9use core::fmt;
10
11use zeroize::Zeroizing;
12
13use crate::Result;
14use crate::traits::{
15 Aead,
16 AeadKey,
17 Nonce,
18};
19
20/// Semantic result of an AEAD decrypt after parseable inputs were accepted.
21///
22/// This type is a closed `enum`: downstream crates cannot add variants. Use exhaustive
23/// `match` (or `if let`) to branch; do not reduce verification to a secret-derived `bool`
24/// without an explicit, reviewed threat model.
25///
26/// # Examples
27///
28/// ```rust
29/// use lib_q_core::{
30/// AeadDecryptSemantic,
31/// DecryptSemanticOutcome,
32/// AeadKey,
33/// Nonce,
34/// };
35/// # fn demo<T: AeadDecryptSemantic>(aead: &T, key: &AeadKey, nonce: &Nonce, ct: &[u8]) -> lib_q_core::Result<()> {
36/// match aead.decrypt_semantic(key, nonce, ct, None)? {
37/// DecryptSemanticOutcome::Success(pt) => {
38/// let _ = pt.len();
39/// }
40/// DecryptSemanticOutcome::AuthenticationFailed => {}
41/// }
42/// # Ok(())
43/// # }
44/// ```
45#[derive(PartialEq, Eq)]
46pub enum DecryptSemanticOutcome {
47 /// Verified plaintext; buffer is zeroized on drop.
48 Success(Zeroizing<Vec<u8>>),
49 /// Integrity failure after the algorithm’s decrypt/verify schedule. No plaintext.
50 AuthenticationFailed,
51}
52
53impl fmt::Debug for DecryptSemanticOutcome {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::Success(_) => f.write_str("Success(<redacted>)"),
57 Self::AuthenticationFailed => f.write_str("AuthenticationFailed"),
58 }
59 }
60}
61
62/// AEAD implementations that expose a semantic decrypt API (Layer B).
63///
64/// Implementors must also implement [`Aead`]. Operational errors (invalid sizes, keys,
65/// nonces, configuration) are returned as [`Err`]. Only post-decrypt authentication
66/// failure is reported as [`DecryptSemanticOutcome::AuthenticationFailed`] inside [`Ok`].
67///
68/// This trait is separate from [`Aead`] so `dyn AeadOperations` and other object-safe
69/// surfaces can remain `Result`-only ([`crate::api::AeadOperations`]) without forcing every
70/// backend to expose semantic decrypt.
71pub trait AeadDecryptSemantic: Aead {
72 /// Decrypt and classify the outcome without overloading `Result` for auth failure.
73 fn decrypt_semantic(
74 &self,
75 key: &AeadKey,
76 nonce: &Nonce,
77 ciphertext: &[u8],
78 associated_data: Option<&[u8]>,
79 ) -> Result<DecryptSemanticOutcome>;
80}