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#[derive(Error, Debug)]
68#[non_exhaustive]
69pub enum CryptographyError {
70 #[error(transparent)]
72 InvalidLength(#[from] InvalidLength),
73
74 #[error(transparent)]
76 InvalidPadding(#[from] cipher::block_padding::Error),
77
78 #[error(transparent)]
80 Argon2(#[from] argon2::Error),
81}