thrussh 0.40.5

A client and server SSH library.
Documentation
pub enum MacKey {
    None,
    HmacSha256(hmac_sha256::Key),
}

impl MacKey {
    pub fn len(&self) -> usize {
        match self {
            MacKey::None => 0,
            MacKey::HmacSha256(_) => ssh_libsodium::hmac256::BYTES,
        }
    }

    pub fn authenticate(&self, number: u32, b: &[u8], out: &mut [u8]) {
        match self {
            MacKey::None => {}
            MacKey::HmacSha256(k) => hmac_sha256::authenticate(k, number, b, out),
        }
    }

    pub fn verify(&self, number: u32, b: &[u8], out: &[u8]) -> bool {
        match self {
            MacKey::None => true,
            MacKey::HmacSha256(k) => hmac_sha256::verify(k, number, b, out),
        }
    }
}

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Name(pub &'static str);
impl AsRef<str> for Name {
    fn as_ref(&self) -> &str {
        self.0
    }
}

pub struct Mac {
    pub _name: Name,
    pub key_len: usize,
    pub make_key: fn(key: &[u8]) -> MacKey,
}

pub mod hmac_sha256 {
    use byteorder::{BigEndian, ByteOrder};
    pub const NAME: super::Name = super::Name("hmac-sha2-256");
    pub struct Key([u8; ssh_libsodium::hmac256::KEY_BYTES]);
    pub const MAC: super::Mac = super::Mac {
        _name: NAME,
        key_len: 32,
        make_key,
    };

    fn make_key(b: &[u8]) -> super::MacKey {
        let mut k = Key([0; ssh_libsodium::hmac256::KEY_BYTES]);
        k.0.clone_from_slice(b);
        super::MacKey::HmacSha256(k)
    }

    pub fn authenticate(k: &Key, number: u32, b: &[u8], out: &mut [u8]) {
        let mut s = ssh_libsodium::hmac256::init_state(&k.0);
        let mut n = [0; 4];
        BigEndian::write_u32(&mut n, number);
        ssh_libsodium::hmac256::update(&mut s, &n);
        ssh_libsodium::hmac256::update(&mut s, b);
        ssh_libsodium::hmac256::finalize(&mut s, out);
    }

    pub fn verify(k: &Key, number: u32, b: &[u8], h: &[u8]) -> bool {
        let mut s = ssh_libsodium::hmac256::init_state(&k.0);
        let mut n = [0; 4];
        BigEndian::write_u32(&mut n, number);
        ssh_libsodium::hmac256::update(&mut s, &n);
        ssh_libsodium::hmac256::update(&mut s, b);
        let mut out = [0; ssh_libsodium::hmac256::BYTES];
        ssh_libsodium::hmac256::finalize(&mut s, &mut out);
        debug!("out {:?} h {:?}", out, h);
        ssh_libsodium::memcmp(&out, h)
    }
}