coolssh 1.2.0

SSH 2.0 Client
Documentation
use sha2::{Sha256, Digest};

#[derive(Clone)]
pub struct Hmac {
    ih: Sha256,
    output_xor: [u8; 64],
}

fn xor(mut array: [u8; 64], byte: u8) -> [u8; 64] {
    for b in array.iter_mut() {
        *b ^= byte;
    }

    array
}

impl Hmac {
    pub fn new(key: impl AsRef<[u8]>) -> Self {
        let key = key.as_ref();

        let stack_array: [u8; 32];
        let key = if key.len() > 64 {
            let mut hashed_key = Sha256::new();
            hashed_key.update(key);
            stack_array = hashed_key.finalize().into();
            &stack_array
        } else {
            key
        };

        let mut padded = [0; 64];
        padded[..key.len()].copy_from_slice(key);

        let input_xor = xor(padded, 0x36);
        let output_xor = xor(padded, 0x5C);

        let mut ih = Sha256::new();
        ih.update(&input_xor);
        Self { ih, output_xor }
    }

    pub fn update(&mut self, input: impl AsRef<[u8]>) {
        self.ih.update(input);
    }

    pub fn finalize(self) -> [u8; 32] {
        let mut oh = Sha256::new();
        oh.update(&self.output_xor);
        oh.update(self.ih.finalize());
        oh.finalize().into()
    }
}