Skip to main content

keepass/crypt/
mod.rs

1#[cfg(feature = "challenge_response")]
2use hybrid_array::typenum::U20;
3use hybrid_array::{
4    typenum::{U32, U64},
5    Array as GenericArray,
6};
7
8use cipher::{InvalidLength, KeyInit};
9use hmac::{Hmac, Mac};
10#[cfg(feature = "challenge_response")]
11use sha1::Sha1;
12use sha2::{Digest, Sha256, Sha512};
13use thiserror::Error;
14
15pub(crate) mod ciphers;
16pub(crate) mod kdf;
17
18pub(crate) fn calculate_hmac(elements: &[&[u8]], key: &[u8]) -> Result<GenericArray<u8, U32>, InvalidLength> {
19    type HmacSha256 = Hmac<Sha256>;
20    let mut mac = HmacSha256::new_from_slice(key)?;
21
22    for element in elements {
23        mac.update(element);
24    }
25
26    let result = mac.finalize();
27    Ok(result.into_bytes())
28}
29
30#[cfg(feature = "challenge_response")]
31pub(crate) fn calculate_hmac_sha1(
32    elements: &[&[u8]],
33    key: &[u8],
34) -> Result<GenericArray<u8, U20>, InvalidLength> {
35    type HmacSha1 = Hmac<Sha1>;
36    let mut mac = HmacSha1::new_from_slice(key)?;
37
38    for element in elements {
39        mac.update(element);
40    }
41
42    let result = mac.finalize();
43    Ok(result.into_bytes())
44}
45
46pub(crate) fn calculate_sha256(elements: &[&[u8]]) -> GenericArray<u8, U32> {
47    let mut digest = Sha256::new();
48
49    for element in elements {
50        digest.update(element);
51    }
52
53    digest.finalize()
54}
55
56pub(crate) fn calculate_sha512(elements: &[&[u8]]) -> GenericArray<u8, U64> {
57    let mut digest = Sha512::new();
58
59    for element in elements {
60        digest.update(element);
61    }
62
63    digest.finalize()
64}
65
66/// Errors that can occur during cryptographic operations
67#[derive(Error, Debug)]
68#[non_exhaustive]
69pub enum CryptographyError {
70    /// An invalid key length was provided
71    #[error(transparent)]
72    InvalidLength(#[from] InvalidLength),
73
74    /// Data has invalid padding
75    #[error(transparent)]
76    InvalidPadding(#[from] cipher::block_padding::Error),
77
78    /// Errors related to the Argon2 key derivation function
79    #[error(transparent)]
80    Argon2(#[from] argon2::Error),
81}