Skip to content

Commit d0908de

Browse files
committed
fixed #218 - fixed padding calculation, AES-GCM rekey and hmac-sha2-256(-etm) MAC
1 parent c0f3458 commit d0908de

File tree

3 files changed

+14
-31
lines changed

3 files changed

+14
-31
lines changed

russh/src/cipher/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl<C: StreamCipher + KeySizeUser + IvSizeUser> super::OpeningKey for OpeningKe
129129
return Err(Error::PacketAuth);
130130
}
131131
}
132-
Ok(ciphertext_in_plaintext_out)
132+
Ok(&ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..])
133133
}
134134
}
135135

russh/src/cipher/gcm.rs

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
// http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD
1717

1818
use aes_gcm::{AeadCore, AeadInPlace, Aes256Gcm, KeyInit, KeySizeUser};
19-
use byteorder::{BigEndian, ByteOrder};
2019
use digest::typenum::Unsigned;
2120
use generic_array::GenericArray;
2221
use rand::RngCore;
@@ -84,27 +83,13 @@ pub struct SealingKey {
8483
cipher: Aes256Gcm,
8584
}
8685

87-
const GCM_COUNTER_OFFSET: u64 = 3;
88-
89-
fn make_nonce(
90-
nonce: &GenericArray<u8, NonceSize>,
91-
sequence_number: u32,
92-
) -> GenericArray<u8, NonceSize> {
93-
let mut new_nonce = GenericArray::<u8, NonceSize>::default();
94-
new_nonce.clone_from_slice(nonce);
95-
// Increment the nonce
96-
let i0 = new_nonce.len() - 8;
97-
98-
#[allow(clippy::indexing_slicing)] // length checked
99-
let ctr = BigEndian::read_u64(&new_nonce[i0..]);
100-
101-
// GCM requires the counter to start from 1
102-
#[allow(clippy::indexing_slicing)] // length checked
103-
BigEndian::write_u64(
104-
&mut new_nonce[i0..],
105-
ctr + sequence_number as u64 - GCM_COUNTER_OFFSET,
106-
);
107-
new_nonce
86+
fn inc_nonce(nonce: &mut GenericArray<u8, NonceSize>) {
87+
let mut carry = 1;
88+
for i in (0..nonce.len()).rev() {
89+
let n = nonce[i] as u16 + carry;
90+
nonce[i] = n as u8;
91+
carry = n >> 8;
92+
}
10893
}
10994

11095
impl super::OpeningKey for OpeningKey {
@@ -137,22 +122,21 @@ impl super::OpeningKey for OpeningKey {
137122
#[allow(clippy::indexing_slicing)] // length checked
138123
buffer.copy_from_slice(&ciphertext_in_plaintext_out[super::PACKET_LENGTH_LEN..]);
139124

140-
let nonce = make_nonce(&self.nonce, sequence_number);
141-
142125
let mut tag_buf = GenericArray::<u8, TagSize>::default();
143126
tag_buf.clone_from_slice(tag);
144127

145128
#[allow(clippy::indexing_slicing)]
146129
self.cipher
147130
.decrypt_in_place_detached(
148-
&nonce,
131+
&self.nonce,
149132
&packet_length,
150133
&mut ciphertext_in_plaintext_out[super::PACKET_LENGTH_LEN..],
151134
&tag_buf,
152135
)
153136
.map_err(|_| Error::DecryptionError)?;
154137

155-
Ok(ciphertext_in_plaintext_out)
138+
inc_nonce(&mut self.nonce);
139+
Ok(&ciphertext_in_plaintext_out[super::PACKET_LENGTH_LEN..])
156140
}
157141
}
158142

@@ -191,18 +175,17 @@ impl super::SealingKey for SealingKey {
191175
#[allow(clippy::indexing_slicing)] // length checked
192176
packet_length.clone_from_slice(&plaintext_in_ciphertext_out[..super::PACKET_LENGTH_LEN]);
193177

194-
let nonce = make_nonce(&self.nonce, sequence_number);
195-
196178
#[allow(clippy::indexing_slicing, clippy::unwrap_used)]
197179
let tag_out = self
198180
.cipher
199181
.encrypt_in_place_detached(
200-
&nonce,
182+
&self.nonce,
201183
&packet_length,
202184
&mut plaintext_in_ciphertext_out[super::PACKET_LENGTH_LEN..],
203185
)
204186
.unwrap();
205187

188+
inc_nonce(&mut self.nonce);
206189
tag.clone_from_slice(&tag_out)
207190
}
208191
}

russh/src/mac/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static _HMAC_SHA512: CryptoMacAlgorithm<Hmac<Sha512>, U64> =
7676
CryptoMacAlgorithm(PhantomData, PhantomData);
7777
static _HMAC_SHA1_ETM: CryptoEtmMacAlgorithm<Hmac<Sha1>, U64> =
7878
CryptoEtmMacAlgorithm(PhantomData, PhantomData);
79-
static _HMAC_SHA256_ETM: CryptoEtmMacAlgorithm<Hmac<Sha256>, U64> =
79+
static _HMAC_SHA256_ETM: CryptoEtmMacAlgorithm<Hmac<Sha256>, U32> =
8080
CryptoEtmMacAlgorithm(PhantomData, PhantomData);
8181
static _HMAC_SHA512_ETM: CryptoEtmMacAlgorithm<Hmac<Sha512>, U64> =
8282
CryptoEtmMacAlgorithm(PhantomData, PhantomData);

0 commit comments

Comments
 (0)