Skip to main content

argon2/
error.rs

1//! Error type
2
3use core::fmt;
4
5/// Result with argon2's [`Error`] type.
6pub type Result<T> = core::result::Result<T, Error>;
7
8/// Error type.
9#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10pub enum Error {
11    /// Associated data is too long.
12    AdTooLong,
13
14    /// Algorithm identifier invalid.
15    AlgorithmInvalid,
16
17    /// "B64" encoding is invalid.
18    B64Encoding(base64ct::Error),
19
20    /// Key ID is too long.
21    KeyIdTooLong,
22
23    /// Memory cost is too small.
24    MemoryTooLittle,
25
26    /// Memory cost is too large.
27    MemoryTooMuch,
28
29    /// Output is too short.
30    OutputTooShort,
31
32    /// Output is too long.
33    OutputTooLong,
34
35    /// Password is too long.
36    PwdTooLong,
37
38    /// Salt is too short.
39    SaltTooShort,
40
41    /// Salt is too long.
42    SaltTooLong,
43
44    /// Secret is too long.
45    SecretTooLong,
46
47    /// Not enough threads.
48    ThreadsTooFew,
49
50    /// Too many threads.
51    ThreadsTooMany,
52
53    /// Time cost is too small.
54    TimeTooSmall,
55
56    /// Invalid version.
57    VersionInvalid,
58
59    /// Out of memory (heap allocation failure).
60    OutOfMemory,
61}
62
63impl core::error::Error for Error {
64    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
65        match self {
66            Self::B64Encoding(err) => Some(err),
67            _ => None,
68        }
69    }
70}
71
72impl fmt::Display for Error {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        f.write_str(match self {
75            Error::AdTooLong => "associated data is too long",
76            Error::AlgorithmInvalid => "algorithm identifier invalid",
77            Error::B64Encoding(inner) => return write!(f, "B64 encoding invalid: {inner}"),
78            Error::KeyIdTooLong => "key ID is too long",
79            Error::MemoryTooLittle => "memory cost is too small",
80            Error::MemoryTooMuch => "memory cost is too large",
81            Error::OutputTooShort => "output is too short",
82            Error::OutputTooLong => "output is too long",
83            Error::PwdTooLong => "password is too long",
84            Error::SaltTooShort => "salt is too short",
85            Error::SaltTooLong => "salt is too long",
86            Error::SecretTooLong => "secret is too long",
87            Error::ThreadsTooFew => "not enough threads",
88            Error::ThreadsTooMany => "too many threads",
89            Error::TimeTooSmall => "time cost is too small",
90            Error::VersionInvalid => "invalid version",
91            Error::OutOfMemory => "out of memory",
92        })
93    }
94}
95
96impl From<base64ct::Error> for Error {
97    fn from(err: base64ct::Error) -> Error {
98        Error::B64Encoding(err)
99    }
100}
101
102#[cfg(feature = "kdf")]
103impl From<Error> for kdf::Error {
104    fn from(_err: Error) -> kdf::Error {
105        kdf::Error
106    }
107}
108
109#[cfg(feature = "password-hash")]
110impl From<Error> for password_hash::Error {
111    fn from(err: Error) -> password_hash::Error {
112        match err {
113            Error::AdTooLong => password_hash::Error::ParamInvalid { name: "data" },
114            Error::AlgorithmInvalid => password_hash::Error::Algorithm,
115            Error::B64Encoding(_) => password_hash::Error::EncodingInvalid,
116            Error::KeyIdTooLong => password_hash::Error::ParamInvalid { name: "keyid" },
117            Error::MemoryTooLittle | Error::MemoryTooMuch => {
118                password_hash::Error::ParamInvalid { name: "m" }
119            }
120            Error::OutOfMemory => password_hash::Error::OutOfMemory,
121            Error::OutputTooShort | Error::OutputTooLong => password_hash::Error::OutputSize,
122            Error::PwdTooLong => password_hash::Error::PasswordInvalid,
123            Error::SaltTooShort | Error::SaltTooLong => password_hash::Error::SaltInvalid,
124            Error::SecretTooLong => password_hash::Error::ParamsInvalid,
125            Error::ThreadsTooFew | Error::ThreadsTooMany => {
126                password_hash::Error::ParamInvalid { name: "p" }
127            }
128            Error::TimeTooSmall => password_hash::Error::ParamInvalid { name: "t" },
129            Error::VersionInvalid => password_hash::Error::Version,
130        }
131    }
132}