mls_rs_crypto_openssl/
mac.rs1use std::ops::Deref;
6
7use mls_rs_core::crypto::CipherSuite;
8use openssl::{
9 hash::{hash, MessageDigest},
10 pkey::PKey,
11 sign::Signer,
12};
13use thiserror::Error;
14
15#[derive(Debug, Error)]
16pub enum HashError {
17 #[error(transparent)]
18 OpensslError(#[from] openssl::error::ErrorStack),
19 #[error("unsupported cipher suite")]
20 UnsupportedCipherSuite,
21}
22
23#[derive(Clone)]
24pub struct Hash(MessageDigest);
25
26impl Deref for Hash {
27 type Target = MessageDigest;
28
29 fn deref(&self) -> &Self::Target {
30 &self.0
31 }
32}
33
34impl Hash {
35 pub fn new(cipher_suite: CipherSuite) -> Result<Self, HashError> {
36 let md = match cipher_suite {
37 CipherSuite::CURVE25519_AES128
38 | CipherSuite::P256_AES128
39 | CipherSuite::CURVE25519_CHACHA => Ok(MessageDigest::sha256()),
40 CipherSuite::P384_AES256 => Ok(MessageDigest::sha384()),
41 CipherSuite::CURVE448_CHACHA
42 | CipherSuite::CURVE448_AES256
43 | CipherSuite::P521_AES256 => Ok(MessageDigest::sha512()),
44 _ => Err(HashError::UnsupportedCipherSuite),
45 }?;
46
47 Ok(Self(md))
48 }
49
50 pub fn hash(&self, data: &[u8]) -> Result<Vec<u8>, HashError> {
51 Ok(hash(self.0, data)?.to_vec())
52 }
53
54 pub fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, HashError> {
55 let key = PKey::hmac(key)?;
56 let mut signer = Signer::new(self.0, &key)?;
57 Ok(signer.sign_oneshot_to_vec(data)?)
58 }
59}