deadbolt-crypto 0.1.1

Cryptography wrapper for deadbolt
Documentation
extern crate argon2;
extern crate hmac;
extern crate secrecy;
extern crate sha2;

use argon2::{Argon2, Params, Version};
use hkdf::Hkdf as HkdfWrapper;
use hmac::{digest::MacError, Hmac as HmacWrapper, Mac};
use secrecy::{ExposeSecret, Secret};
use sha2::{Digest, Sha256};

pub struct Hash {}

impl Hash {
    pub fn sha256(message: &Vec<u8>) -> Vec<u8> {
        let mut hasher = Sha256::new();
        hasher.update(message);
        hasher.finalize().to_vec()
    }
}

pub struct PasswordHash {}

impl PasswordHash {
    pub fn argon2(
        algorithm: argon2::Algorithm,
        params: argon2::Params,
        password: Secret<String>,
        salt: &[u8],
    ) -> Secret<Vec<u8>> {
        let mut key_material: [u8; 32] = [0u8; 32];
        Argon2::new(algorithm, Version::default(), params)
            .hash_password_into(password.expose_secret().as_bytes(), salt, &mut key_material)
            .unwrap();

        Secret::new(key_material.to_vec())
    }

    pub fn argon2d(
        password: Secret<String>,
        salt: &[u8],
        iterations: u8,
        threads: u8,
        memory: u32,
    ) -> Secret<Vec<u8>> {
        let params: argon2::Params =
            argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
                .expect("cannot build argon2 params");

        PasswordHash::argon2(argon2::Algorithm::Argon2d, params, password, salt)
    }

    pub fn argon2id(
        password: Secret<String>,
        salt: &[u8],
        iterations: u8,
        threads: u8,
        memory: u32,
    ) -> Secret<Vec<u8>> {
        let params: argon2::Params =
            argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
                .expect("cannot build argon2 params");

        PasswordHash::argon2(argon2::Algorithm::Argon2id, params, password, salt)
    }
}

pub struct Hkdf {}

impl Hkdf {
    pub fn expand(input_key_material: Secret<Vec<u8>>) -> Secret<Vec<u8>> {
        let mut okm: [u8; 64] = [0u8; 64];
        let info = vec![0xde, 0xad, 0xb0, 0x1d];
        let hk = HkdfWrapper::<Sha256>::from_prk(input_key_material.expose_secret())
            .expect("PRK should be large enough");
        hk.expand(&info, &mut okm).unwrap();

        Secret::new(okm.to_vec())
    }
}

pub struct Hmac {
    mac: HmacWrapper<Sha256>,
}

impl Hmac {
    pub fn new(secret: &Secret<Vec<u8>>) -> Hmac {
        type HmacSha256 = HmacWrapper<Sha256>;
        Hmac {
            mac: HmacSha256::new_from_slice(secret.expose_secret()).unwrap(),
        }
    }

    pub fn update(&mut self, message: &[u8]) {
        self.mac.update(message);
    }

    pub fn finalize(&mut self) -> Vec<u8> {
        let result = self.mac.clone();
        result.finalize().into_bytes().to_vec()
    }

    pub fn verify(&mut self, expected: &[u8]) -> Result<(), MacError> {
        let result = self.mac.clone();
        result.verify_slice(expected)
    }
}