libcrux/hpke/
errors.rs

1//! # HPKE Errors
2//!
3//! The high-level, public HPKE APIs specified in this document are all fallible.
4//! These include the Setup functions and all encryption context functions.
5//! For example, `Decap()` can fail if the encapsulated key `enc` is invalid,
6//! and `Open()` may fail if ciphertext decryption fails. The explicit errors
7//! generated throughout this specification, along with the conditions that
8//! lead to each error, are as follows:
9//!
10//! - `ValidationError`: KEM input or output validation failure.
11//! - `DeserializeError`: Public or private key deserialization failure.
12//! - `EncapError`: `Encap()` failure.
13//! - `DecapError`: `Decap()` failure.
14//! - `OpenError`: Context AEAD `Open()` failure.
15//! - `MessageLimitReachedError`: Context AEAD sequence number overflow.
16//! - `DeriveKeyPairError`: Key pair derivation failure.
17//!
18//! Implicit errors may also occur. As an example, certain classes of failures,
19//! e.g., malformed recipient public keys, may not yield explicit errors.
20//! For example, for the DHKEM variant described in this specification,
21//! the `Encap()` algorithm fails when given an invalid recipient public key.
22//! However, other KEM algorithms may not have an efficient algorithm for verifying
23//! the validity of public keys. As a result, an equivalent error may not manifest
24//! until AEAD decryption at the recipient. As another example, DHKEM's `AuthDecap()`
25//! function will produce invalid output if given the wrong sender public key.
26//! This error is not detectable until subsequent AEAD decryption.
27//!
28//! The errors in this document are meant as a guide for implementors. They are not
29//! an exhaustive list of all the errors an implementation might emit. For example,
30//! future KEMs might have internal failure cases, or an implementation might run
31//! out of memory.
32//!
33//! How these errors are expressed in an API or handled by applications is an
34//! implementation-specific detail. For example, some implementations may abort or
35//! panic upon a `DeriveKeyPairError` failure given that it only occurs with
36//! negligible probability, whereas other implementations may retry the failed
37//! DeriveKeyPair operation.
38//! As another example, some implementations of the DHKEM specified in this document
39//! may choose to transform `ValidationError` from `DH()` into an `EncapError` or
40//! `DecapError` from `Encap()` or `Decap()`, respectively, whereas others may choose
41//! to raise `ValidationError` unmodified.
42//!
43//! Applications using HPKE APIs should not assume that the errors here are complete,
44//! nor should they assume certain classes of errors will always manifest the same way
45//! for all ciphersuites. For example, the DHKEM specified in this document will emit
46//! a `DeserializationError` or `ValidationError` if a KEM public key is invalid. However,
47//! a new KEM might not have an efficient algorithm for determining whether or not a
48//! public key is valid. In this case, an invalid public key might instead yield an
49//! `OpenError` when trying to decrypt a ciphertext.
50//!
51//! ## Exceptions
52//! The exceptions raised in the HPKE RFC are modelled as errors here as well:
53//!
54//! - `InconsistentPskInputs`: PSK inputs are inconsistent.
55//! - `UnnecessaryPsk`: PSK input provided when not needed.
56//! - `MissingPsk`: Missing required PSK input.
57//!
58//! ## hacspec Extensions
59//! In order to implement HPKE a number of additional errors are added here:
60//!
61//! - `UnsupportedAlgorithm`: An algorithm is not supported by the implementation
62//! - `InvalidParameters`: Parameters to an algorithm are inconsistent or wrong.
63//! - `CryptoError`: An opaque error happened in a crypto operation outside of this code.
64
65/// Explicit errors generated throughout this specification.
66#[derive(Debug, Copy, Clone, PartialEq)]
67pub enum HpkeError {
68    /// KEM input or output validation failure.
69    ValidationError,
70    /// Public or private key deserialization failure.
71    DeserializeError,
72    /// `Encap()` failure.
73    EncapError,
74    /// `Decap()` failure.
75    DecapError,
76    /// Context AEAD `Open()` failure.
77    OpenError,
78    /// Context AEAD sequence number overflow.
79    MessageLimitReachedError,
80    /// Key pair derivation failure.
81    DeriveKeyPairError,
82
83    /// PSK inputs are inconsistent.
84    InconsistentPskInputs,
85    /// PSK input provided when not needed.
86    UnnecessaryPsk,
87    /// Missing required PSK input.
88    MissingPsk,
89
90    /// An algorithm is not supported by the implementation.
91    UnsupportedAlgorithm,
92    /// Parameters to an algorithm are inconsistent or wrong.
93    InvalidParameters,
94    /// An opaque error happened in a crypto operation outside of this code.
95    CryptoError,
96}
97
98/// A [`Result`] type that returns a [`Bytes`] or an [`HpkeError`].
99pub type HpkeBytesResult = Result<Vec<u8>, HpkeError>;
100
101impl From<crate::aead::Error> for HpkeError {
102    fn from(value: crate::aead::Error) -> Self {
103        match value {
104            crate::aead::Error::UnsupportedAlgorithm => Self::UnsupportedAlgorithm,
105            crate::aead::Error::EncryptionError => Self::EncapError,
106            crate::aead::Error::DecryptionFailed => Self::DecapError,
107            crate::aead::Error::InvalidKey
108            | crate::aead::Error::InvalidIv
109            | crate::aead::Error::InvalidTag => Self::InvalidParameters,
110        }
111    }
112}