Adding support for MACs and AES in CTR mode
Dependencies
- [2]
5EV2X6V4Version bump/nix shell - [3]
WX7UY5KKAdding support for aes256-gcm - [4]
SKTE2HF6Version 0.37 - [5]
Y67GNDVBuse tokio::process::Command for proxy commands - [6]
XEKZBXNIFixing a bug with tokio::select - [7]
G3FNNIIULimiting the amount of messages that can be buffered while rekeying to two channel windows - [8]
VYDCQWSFVersion 0.30.6 - [9]
UT24SM2FVersion bump - [10]
7FRJYUI6Reboot because of a bad change - [11]
CQSPFH4HVersion 0.30.4 - [12]
2VTUKRLJVersion - [13]
32GIIFWRFixing strict mode - [14]
PDTFLA4YVersion 0.30.7 - [15]
ASD7JVBEDo not read past the size of the buffer (after Tokio 0.3) - [16]
7Y2ROIVZVersion bump - [17]
D6H7OWTTFixing the terrapin attack mitigation - [18]
DJT33BQEVersion bump - [19]
CWHVPLXNVersion bump - [20]
P5SAD7JFVersion bump (+ formatting) - [21]
E2SB74SVVersion 0.30.3 - [22]
EUHO3DAZSend a SSH_MSG_EXT_INFO with server-sig-algs when the client indicates they support extensions by sending ext-info-c. This allows modern clients that don't do ssh-rsa anymore because of sha1 to still use RSA keys with sha2. - [23]
VJIXIN4TFixing CVE-2023-48795 - [24]
2WEO7OZLVersion updates: getting rid of anyhow + moving to Tokio 1.0 - [25]
WXZWQLGLCorrect negotiation without OpenSSL - [26]
BRDS7STAAdding method `send_channel_msg` to client::Session, to make it easier to write handlers - [27]
662ZS5JFVersion 0.33.2 - [28]
SMUTYV2CFixing warnings - [29]
OQZGSEWMBuffering non-kex packets received after issuing a KEXINIT - [30]
MCS77Y4VMaking OpenSSL optional - [31]
Q323RFJSVersion bump - [32]
R5J3MB56Client newkeys was not always resetting the sequence counter - [33]
XCNFFN6ZThrussh-keys, version 0.19.3 - [34]
EZTTZ6OWFixing terrapin, again - [35]
OBHPOIUHModernising the API with async traits - [36]
MFMCIUMJFixing authentication with RSA - [37]
634OYCNMTokio 0.3 - [38]
NHOSLQGGThrussh: making OpenSSL optional - [39]
ORSEEVB5Version bump - [40]
UHAEQPZUSupport ecdsa-sha2-nistp256 keys for authentication - [41]
TFYJ3P2AVersion 0.30.8/0.19.4, and solving conflicts - [42]
BWU5BDAHThrussh-keys 0.19.5 - [43]
6TIVIM7MVersion of thrussh-keys - [44]
2Q3SZY2CVersion bump - [45]
FT67GGO4Version bump (Pijul and Thrussh) - [46]
ELRPPXSGFixing conflicts - [47]
AWVLXGAWRemoving anyhows on Windows
Change contents
- edit in thrussh-libsodium/src/lib.rs at line 9
}pub fn memcmp(a: &[u8], b: &[u8]) -> bool {unsafe {sodium_memcmp(a.as_ptr() as *const libc::c_void,b.as_ptr() as *const libc::c_void,a.len().min(b.len()),) == 0} - edit in thrussh-libsodium/src/lib.rs at line 51
}}}pub mod hmac256 {pub const KEY_BYTES: usize = libsodium_sys::crypto_auth_hmacsha256_KEYBYTES as usize;pub const BYTES: usize = libsodium_sys::crypto_auth_hmacsha256_BYTES as usize;pub fn init_state(key: &[u8; KEY_BYTES]) -> libsodium_sys::crypto_auth_hmacsha256_state {unsafe {let mut state = std::mem::zeroed();libsodium_sys::crypto_auth_hmacsha256_init(&mut state, key.as_ptr(), KEY_BYTES);state}}pub fn update(s: &mut libsodium_sys::crypto_auth_hmacsha256_state, msg: &[u8]) {unsafe {libsodium_sys::crypto_auth_hmacsha256_update(s, msg.as_ptr(), msg.len() as u64); - edit in thrussh-libsodium/src/lib.rs at line 72
pub fn finalize(s: &mut libsodium_sys::crypto_auth_hmacsha256_state, out: &mut [u8]) {assert_eq!(out.len(), BYTES);unsafe {libsodium_sys::crypto_auth_hmacsha256_final(s, out.as_mut_ptr());}} - replacement in thrussh-libsodium/Cargo.toml at line 3
version = "0.2.2"version = "0.4.0" - replacement in thrussh-keys/Cargo.toml at line 3
version = "0.23.1"version = "0.23.2" - replacement in thrussh-keys/Cargo.toml at line 37
cryptovec = "0.7.0"cryptovec = "0.7.1" - replacement in thrussh-keys/Cargo.toml at line 49
thrussh-libsodium = "0.2"thrussh-libsodium = "0.4" - replacement in thrussh/src/session.rs at line 18
use crate::{auth, cipher, kex, msg, negotiation};use crate::{auth, cipher, kex, mac, msg, negotiation}; - replacement in thrussh/src/session.rs at line 34
pub mac: Option<&'static str>,pub mac: mac::Name, - replacement in thrussh/src/session.rs at line 485
let c = self.kex.compute_keys(&session_id, &hash, self.names.cipher, is_server)?;let c = self.kex.compute_keys(&session_id,&hash,self.names.cipher,self.names.mac,is_server,)?; - replacement in thrussh/src/negotiation.rs at line 15
use crate::{Error, cipher, kex, msg};use crate::{Error, cipher, kex, mac, msg}; - replacement in thrussh/src/negotiation.rs at line 30
pub mac: Option<&'static str>,pub mac: mac::Name, - replacement in thrussh/src/negotiation.rs at line 51
pub mac: &'static [&'static str],pub mac: &'static [mac::Name], - replacement in thrussh/src/negotiation.rs at line 75
mac: &["none"],mac: &[mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 89
mac: &["none"],mac: &[mac::hmac_sha256::NAME, mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 99
mac: &["none"],mac: &[mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 109
mac: &["none"],mac: &[mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 119
mac: &["none"],mac: &[mac::hmac_sha256::NAME, mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 129
mac: &["none"],mac: &[mac::hmac_sha256::NAME, mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 139
mac: &["none"],mac: &[mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 149
mac: &["none"],mac: &[mac::Name("none")], - replacement in thrussh/src/negotiation.rs at line 262
let mac = Self::select(pref.mac, r.read_string()?);let mac = mac.and_then(|(_, x)| Some(x));let mac_string = r.read_string()?;let mac = Self::select(pref.mac, mac_string);if mac.is_none() {debug!("Could not find common mac, other side only supports {:?}, we only support {:?}",from_utf8(mac_string),pref.mac);return Err(Error::NoCommonMac.into());}let mac = mac.unwrap().1; - file addition: mac[5.165404]
- file addition: mod.rs[0.2412]
pub enum MacKey {None,HmacSha256(hmac_sha256::Key),}impl MacKey {pub fn len(&self) -> usize {match self {MacKey::None => 0,MacKey::HmacSha256(_) => thrussh_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; thrussh_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; thrussh_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 = thrussh_libsodium::hmac256::init_state(&k.0);let mut n = [0; 4];BigEndian::write_u32(&mut n, number);thrussh_libsodium::hmac256::update(&mut s, &n);thrussh_libsodium::hmac256::update(&mut s, b);thrussh_libsodium::hmac256::finalize(&mut s, out);}pub fn verify(k: &Key, number: u32, b: &[u8], h: &[u8]) -> bool {let mut s = thrussh_libsodium::hmac256::init_state(&k.0);let mut n = [0; 4];BigEndian::write_u32(&mut n, number);thrussh_libsodium::hmac256::update(&mut s, &n);thrussh_libsodium::hmac256::update(&mut s, b);let mut out = [0; thrussh_libsodium::hmac256::BYTES];thrussh_libsodium::hmac256::finalize(&mut s, &mut out);thrussh_libsodium::memcmp(&out, h)}} - edit in thrussh/src/lib.rs at line 268
pub mod mac; - replacement in thrussh/src/lib.rs at line 322
#[error("No common key cipher")]#[error("No common cipher")] - edit in thrussh/src/lib.rs at line 325
/// No common mac.#[error("No common mac")]NoCommonMac, - edit in thrussh/src/lib.rs at line 365
/// The remote provided a wrong MAC.#[error("Wrong message authentication code")]WrongMAC, - replacement in thrussh/src/kex.rs at line 15
use crate::{cipher, key, msg};use crate::{cipher, key, mac, msg}; - edit in thrussh/src/kex.rs at line 57
static MAC_BUF: RefCell<CryptoVec> = RefCell::new(CryptoVec::new()); - edit in thrussh/src/kex.rs at line 164
mac: mac::Name, - edit in thrussh/src/kex.rs at line 171
#[cfg(feature = "openssl")]super::cipher::aes256_ctr::NAME => &super::cipher::aes256_ctr::CIPHER, - edit in thrussh/src/kex.rs at line 176
let mac = match mac {super::mac::hmac_sha256::NAME => Some(&super::mac::hmac_sha256::MAC),super::mac::Name("none") => None,_ => unreachable!(),}; - replacement in thrussh/src/kex.rs at line 186
let compute_key = |c, key: &mut CryptoVec, len| -> Result<(), crate::Error> {let mut buffer = buffer.borrow_mut();buffer.clear();key.clear();MAC_BUF.with(|mac_buf| {let compute_key =|c, key: &mut CryptoVec, len| -> Result<(), crate::Error> {let mut buffer = buffer.borrow_mut();buffer.clear();key.clear();if let Some(ref shared) = self.shared_secret {buffer.extend_ssh_mpint(&shared.0);}buffer.extend(exchange_hash.as_ref());buffer.push(c);buffer.extend(session_id.as_ref());let hash = {use sha2::Digest;let mut hasher = sha2::Sha256::new();hasher.update(&buffer[..]);hasher.finalize()};key.extend(hash.as_ref()); - replacement in thrussh/src/kex.rs at line 208
if let Some(ref shared) = self.shared_secret {buffer.extend_ssh_mpint(&shared.0);}while key.len() < len {// extend.buffer.clear();if let Some(ref shared) = self.shared_secret {buffer.extend_ssh_mpint(&shared.0);}buffer.extend(exchange_hash.as_ref());buffer.extend(key);let hash = {use sha2::Digest;let mut hasher = sha2::Sha256::new();hasher.update(&buffer[..]);hasher.finalize()};key.extend(&hash.as_ref());}key.resize(len);Ok(())}; - replacement in thrussh/src/kex.rs at line 228[3.952]→[5.313624:313687](∅→∅),[5.313624]→[5.313624:313687](∅→∅),[5.313687]→[3.953:1053](∅→∅),[3.1053]→[5.313731:313768](∅→∅),[5.313731]→[5.313731:313768](∅→∅),[5.313768]→[5.1662:1876](∅→∅)
buffer.extend(exchange_hash.as_ref());buffer.push(c);buffer.extend(session_id.as_ref());let hash = {use sha2::Digest;let mut hasher = sha2::Sha256::new();hasher.update(&buffer[..]);hasher.finalize()let (local_to_remote,local_to_remote_iv,local_to_remote_mac,remote_to_local,remote_to_local_iv,remote_to_local_mac,) = if is_server {(b'D', b'B', b'F', b'C', b'A', b'E')} else {(b'C', b'A', b'E', b'D', b'B', b'F') - edit in thrussh/src/kex.rs at line 240
key.extend(hash.as_ref()); - replacement in thrussh/src/kex.rs at line 241
while key.len() < len {// extend.buffer.clear();if let Some(ref shared) = self.shared_secret {buffer.extend_ssh_mpint(&shared.0);}buffer.extend(exchange_hash.as_ref());buffer.extend(key);let hash = {use sha2::Digest;let mut hasher = sha2::Sha256::new();hasher.update(&buffer[..]);hasher.finalize()};key.extend(&hash.as_ref());let mut key = key.borrow_mut();compute_key(local_to_remote, &mut key, cipher.key_len)?;let mut iv = iv.borrow_mut();if cipher.iv_len > 0 {compute_key(local_to_remote_iv, &mut iv, cipher.iv_len)?; - edit in thrussh/src/kex.rs at line 247
key.resize(len);Ok(())}; - replacement in thrussh/src/kex.rs at line 248
let (local_to_remote, local_to_remote_iv, remote_to_local, remote_to_local_iv) =if is_server {(b'D', b'B', b'C', b'A')let local_to_remote_mac = if let Some(mac) = mac {let mut mac_buf = mac_buf.borrow_mut();compute_key(local_to_remote_mac, &mut mac_buf, mac.key_len)?;(mac.make_key)(&mac_buf) - replacement in thrussh/src/kex.rs at line 253
(b'C', b'A', b'D', b'B')mac::MacKey::None - replacement in thrussh/src/kex.rs at line 256
let mut key = key.borrow_mut();compute_key(local_to_remote, &mut key, cipher.key_len)?;let mut iv = iv.borrow_mut();if cipher.iv_len > 0 {compute_key(local_to_remote_iv, &mut iv, cipher.iv_len)?;}let local_to_remote = (cipher.make_sealing_cipher)(&key, &iv);let local_to_remote =(cipher.make_sealing_cipher)(&key, &iv, local_to_remote_mac); - replacement in thrussh/src/kex.rs at line 259
compute_key(remote_to_local, &mut key, cipher.key_len)?;if cipher.iv_len > 0 {compute_key(remote_to_local_iv, &mut iv, cipher.iv_len)?;}let remote_to_local = (cipher.make_opening_cipher)(&key, &iv);compute_key(remote_to_local, &mut key, cipher.key_len)?;if cipher.iv_len > 0 {compute_key(remote_to_local_iv, &mut iv, cipher.iv_len)?;}let remote_to_local_mac = if let Some(mac) = mac {let mut mac_buf = mac_buf.borrow_mut();compute_key(remote_to_local_mac, &mut mac_buf, mac.key_len)?;(mac.make_key)(&mac_buf)} else {mac::MacKey::None};let remote_to_local =(cipher.make_opening_cipher)(&key, &iv, remote_to_local_mac); - replacement in thrussh/src/kex.rs at line 273
Ok(super::cipher::CipherPair {local_to_remote: local_to_remote,remote_to_local: remote_to_local,Ok(super::cipher::CipherPair {local_to_remote: local_to_remote,remote_to_local: remote_to_local,}) - edit in thrussh/src/cipher/mod.rs at line 16
use crate::mac; - edit in thrussh/src/cipher/mod.rs at line 21
#[cfg(feature = "openssl")]pub mod aes256_ctr; - replacement in thrussh/src/cipher/mod.rs at line 32
pub make_opening_cipher: fn(key: &[u8], iv: &[u8]) -> OpeningCipher,pub make_sealing_cipher: fn(key: &[u8], iv: &[u8]) -> SealingCipher,pub make_opening_cipher: fn(key: &[u8], iv: &[u8], mac: mac::MacKey) -> OpeningCipher,pub make_sealing_cipher: fn(key: &[u8], iv: &[u8], mac: mac::MacKey) -> SealingCipher, - edit in thrussh/src/cipher/mod.rs at line 41
#[cfg(feature = "openssl")]Aes256Ctr(aes256_ctr::Key), - edit in thrussh/src/cipher/mod.rs at line 52
#[cfg(feature = "openssl")]OpeningCipher::Aes256Ctr(ref key) => key, - edit in thrussh/src/cipher/mod.rs at line 63
#[cfg(feature = "openssl")]Aes256Ctr(aes256_ctr::Key), - edit in thrussh/src/cipher/mod.rs at line 74
#[cfg(feature = "openssl")]SealingCipher::Aes256Ctr(ref key) => key, - replacement in thrussh/src/cipher/mod.rs at line 113
tag: &[u8],tag: usize, - replacement in thrussh/src/cipher/mod.rs at line 124
fn seal(&self, seqn: u32, plaintext_in_ciphertext_out: &mut [u8], tag_out: &mut [u8]);fn seal(&self, seqn: u32, plaintext_in_ciphertext_out: &mut [u8], plaintext_len: usize); - replacement in thrussh/src/cipher/mod.rs at line 154
let (ciphertext, tag) = buffer.buffer.split_at_mut(ciphertext_len);let plaintext = key.open(seqn, ciphertext, tag)?;let plaintext = key.open(seqn, &mut buffer.buffer, ciphertext_len)?; - replacement in thrussh/src/cipher/mod.rs at line 200
let (plaintext, tag) =buffer.buffer[offset..].split_at_mut(PACKET_LENGTH_LEN + packet_length);let plaintext = &mut buffer.buffer[offset..]; - replacement in thrussh/src/cipher/mod.rs at line 202
key.seal(buffer.seqn.0, plaintext, tag);key.seal(buffer.seqn.0, plaintext, PACKET_LENGTH_LEN + packet_length); - replacement in thrussh/src/cipher/clear.rs at line 34
tag: &[u8],tag: usize, - replacement in thrussh/src/cipher/clear.rs at line 36
debug_assert_eq!(tag.len(), 0); // self.tag_len());debug_assert_eq!(tag, ciphertext_in_plaintext_out.len()); // self.tag_len()); - replacement in thrussh/src/cipher/clear.rs at line 67
fn seal(&self, _seqn: u32, _plaintext_in_ciphertext_out: &mut [u8], tag_out: &mut [u8]) {debug_assert_eq!(tag_out.len(), self.tag_len());fn seal(&self, _seqn: u32, plaintext_in_ciphertext_out: &mut [u8], tag_out: usize) {debug_assert_eq!(tag_out, plaintext_in_ciphertext_out.len()); - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 43
fn make_sealing_cipher(k: &[u8], _: &[u8]) -> super::SealingCipher {fn make_sealing_cipher(k: &[u8], _: &[u8], _: crate::mac::MacKey) -> super::SealingCipher { - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 51
fn make_opening_cipher(k: &[u8], _: &[u8]) -> super::OpeningCipher {fn make_opening_cipher(k: &[u8], _: &[u8], _: crate::mac::MacKey) -> super::OpeningCipher { - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 85
tag: &[u8],tag: usize, - edit in thrussh/src/cipher/chacha20poly1305.rs at line 87
let (ciphertext_in_plaintext_out, tag) = ciphertext_in_plaintext_out.split_at_mut(tag); - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 135
fn seal(&self,sequence_number: u32,plaintext_in_ciphertext_out: &mut [u8],tag_out: &mut [u8],) {fn seal(&self, sequence_number: u32, plaintext_in_ciphertext_out: &mut [u8], tag_out: usize) {let (payload, tag_out) = plaintext_in_ciphertext_out.split_at_mut(tag_out); - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 139
let (a, b) = plaintext_in_ciphertext_out.split_at_mut(4);let (a, b) = payload.split_at_mut(4); - replacement in thrussh/src/cipher/chacha20poly1305.rs at line 147
let tag = poly1305_auth(plaintext_in_ciphertext_out, &poly_key);let tag = poly1305_auth(payload, &poly_key); - replacement in thrussh/src/cipher/aes256_gcm.rs at line 38
fn make_sealing_cipher(k: &[u8], i: &[u8]) -> super::SealingCipher {fn make_sealing_cipher(k: &[u8], i: &[u8], _: crate::mac::MacKey) -> super::SealingCipher { - replacement in thrussh/src/cipher/aes256_gcm.rs at line 51
fn make_opening_cipher(k: &[u8], i: &[u8]) -> super::OpeningCipher {fn make_opening_cipher(k: &[u8], i: &[u8], _: crate::mac::MacKey) -> super::OpeningCipher { - replacement in thrussh/src/cipher/aes256_gcm.rs at line 81
tag: &[u8],tag: usize, - edit in thrussh/src/cipher/aes256_gcm.rs at line 83
let (payload, tag) = payload.split_at_mut(tag); - replacement in thrussh/src/cipher/aes256_gcm.rs at line 127
fn seal(&self, _sequence_number: u32, payload: &mut [u8], tag_out: &mut [u8]) {fn seal(&self, _sequence_number: u32, payload: &mut [u8], tag_out: usize) {let (payload, tag_out) = payload.split_at_mut(tag_out); - replacement in thrussh/src/cipher/aes256_gcm.rs at line 159
pub fn crypt_aead(fn crypt_aead( - file addition: aes256_ctr.rs[5.409076]
use openssl::symm::{Cipher, Crypter};use rand::Rng;use std::sync::Mutex;pub const NAME: super::Name = super::Name("aes256-ctr");pub struct Key {mac: crate::mac::MacKey,crypter: Mutex<Crypter>,buf: Mutex<cryptovec::CryptoVec>,}pub static CIPHER: super::Cipher = super::Cipher {_name: NAME,key_len: 32,iv_len: 16,make_sealing_cipher,make_opening_cipher,};fn make_sealing_cipher(k: &[u8], iv: &[u8], mac: crate::mac::MacKey) -> super::SealingCipher {super::SealingCipher::Aes256Ctr(Key {crypter: Mutex::new(openssl::symm::Crypter::new(Cipher::aes_256_ctr(),openssl::symm::Mode::Encrypt,&k,Some(&iv),).unwrap(),),mac,buf: Mutex::new(cryptovec::CryptoVec::new()),})}fn make_opening_cipher(k: &[u8], iv: &[u8], mac: crate::mac::MacKey) -> super::OpeningCipher {super::OpeningCipher::Aes256Ctr(Key {crypter: Mutex::new(openssl::symm::Crypter::new(Cipher::aes_256_ctr(),openssl::symm::Mode::Encrypt,&k,Some(&iv),).unwrap(),),mac,buf: Mutex::new(cryptovec::CryptoVec::new()),})}impl super::SealingKey for Key {fn padding_length(&self, payload: &[u8]) -> usize {let encrypted_len = payload.len() + 5;let padding = 16 - (encrypted_len % 16);let min_padding = if padding < 4 { padding + 16 } else { padding };let mut rng = rand::rng();(rng.random::<u8>() & 0xe0) as usize + min_padding}fn fill_padding(&self, padding_out: &mut [u8]) {openssl::rand::rand_bytes(padding_out).unwrap()}fn tag_len(&self) -> usize {self.mac.len()}/// Append an encrypted packet with contents `packet_content` at/// the end of `buffer`.fn seal(&self, sequence_number: u32, payload_tag: &mut [u8], tag_out: usize) {let (payload, tag) = payload_tag.split_at_mut(tag_out);self.mac.authenticate(sequence_number, &payload[..], tag);let mut out = self.buf.lock().unwrap();out.resize(payload.len());let mut crypter = self.crypter.lock().unwrap();let count = crypter.update(&payload, &mut out).unwrap();crypter.finalize(&mut out[count..]).unwrap();payload.clone_from_slice(&out);}}impl super::OpeningKey for Key {fn decrypt_packet_length(&self,_sequence_number: u32,encrypted_packet_length: [u8; 4],) -> [u8; 4] {let mut out = [0; 4];let mut crypter = self.crypter.lock().unwrap();let count = crypter.update(&encrypted_packet_length, &mut out).unwrap();crypter.finalize(&mut out[count..]).unwrap();out}fn tag_len(&self) -> usize {self.mac.len()}fn open<'a>(&self,sequence_number: u32,payload: &'a mut [u8],tag: usize,) -> Result<&'a [u8], crate::Error> {let (payload, tag) = payload.split_at_mut(tag);let mut out = self.buf.lock().unwrap();out.resize(payload.len());let mut c = self.crypter.lock().unwrap();let count = c.update(&payload, &mut out).unwrap();c.finalize(&mut out[count..]).unwrap();if !self.mac.verify(sequence_number, &out, tag) {return Err(crate::Error::WrongMAC);}payload.clone_from_slice(&out);Ok(payload)}} - replacement in thrussh/Cargo.toml at line 5
version = "0.37.0"version = "0.38.0" - edit in thrussh/Cargo.toml at line 19
"src/mac/mod.rs", - edit in thrussh/Cargo.toml at line 27
"src/cipher/aes256_ctr.rs", - replacement in thrussh/Cargo.toml at line 53
thrussh-keys = { version = "0.23.1", path = "../thrussh-keys" }thrussh-keys = { version = "0.23.2", path = "../thrussh-keys" } - replacement in thrussh/Cargo.toml at line 55
thrussh-libsodium = "0.2"cryptovec = "0.7.0"thrussh-libsodium = "0.4"cryptovec = "0.7.1" - replacement in cryptovec/src/lib.rs at line 301
let s = s.to_be();let x: [u8; 4] = unsafe { std::mem::transmute(s) };let x: [u8; 4] = s.to_be_bytes(); - replacement in cryptovec/Cargo.toml at line 4
version = "0.7.0"version = "0.7.1"