Skip to content

Commit 7c8c10f

Browse files
committed
Use rc.* crate prereleases
This notably includes `dsa` and `rsa` upgrades which migrate to `crypto-bigint`, allowing us to drop `num-bigint-dig` as a dependency
1 parent 21dacb7 commit 7c8c10f

24 files changed

Lines changed: 475 additions & 355 deletions

File tree

Cargo.lock

Lines changed: 173 additions & 197 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ssh-cipher/Cargo.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ edition = "2024"
1919
rust-version = "1.85"
2020

2121
[dependencies]
22-
cipher = "=0.5.0-pre.6"
22+
cipher = "0.5.0-rc.0"
2323
encoding = { package = "ssh-encoding", version = "=0.3.0-pre.1", path = "../ssh-encoding" }
2424

2525
# optional dependencies
26-
aead = { version = "0.6.0-rc.0", optional = true, default-features = false }
27-
aes = { version = "=0.9.0-pre.1", optional = true, default-features = false }
28-
aes-gcm = { version = "=0.11.0-pre.1", optional = true, default-features = false, features = ["aes"] }
29-
cbc = { version = "=0.2.0-pre.1", optional = true }
30-
ctr = { version = "=0.10.0-pre.1", optional = true, default-features = false }
31-
chacha20 = { version = "=0.10.0-pre.1", optional = true, default-features = false, features = ["cipher", "legacy"] }
32-
des = { version = "=0.9.0-pre.1", optional = true, default-features = false }
33-
poly1305 = { version = "0.9.0-rc.0", optional = true, default-features = false }
26+
aead = { version = "0.6.0-rc.1", optional = true, default-features = false }
27+
aes = { version = "0.9.0-rc.0", optional = true, default-features = false }
28+
aes-gcm = { version = "0.11.0-rc.0", optional = true, default-features = false, features = ["aes"] }
29+
cbc = { version = "0.2.0-rc.0", optional = true }
30+
ctr = { version = "0.10.0-rc.0", optional = true, default-features = false }
31+
chacha20 = { version = "0.10.0-rc.0", optional = true, default-features = false, features = ["cipher", "legacy"] }
32+
des = { version = "0.9.0-rc.0", optional = true, default-features = false }
33+
poly1305 = { version = "0.9.0-rc.1", optional = true, default-features = false }
3434
subtle = { version = "2", optional = true, default-features = false }
3535
zeroize = { version = "1", optional = true, default-features = false }
3636

ssh-cipher/src/chacha20poly1305.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pub use chacha20::ChaCha20Legacy as ChaCha20;
44

55
use crate::Tag;
66
use aead::{
7-
AeadCore, Error, KeyInit, KeySizeUser, Result,
8-
array::typenum::{U0, U8, U16, U32},
7+
AeadCore, Error, KeyInit, KeySizeUser, Result, TagPosition,
8+
array::typenum::{U8, U16, U32},
99
};
1010
use cipher::{KeyIvInit, StreamCipher, StreamCipherSeek};
1111
use poly1305::Poly1305;
@@ -49,7 +49,7 @@ impl KeyInit for ChaCha20Poly1305 {
4949
impl AeadCore for ChaCha20Poly1305 {
5050
type NonceSize = U8;
5151
type TagSize = U16;
52-
type CiphertextOverhead = U0;
52+
const TAG_POSITION: TagPosition = TagPosition::Postfix;
5353
}
5454

5555
impl ChaCha20Poly1305 {

ssh-cipher/src/decryptor.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use des::TdesEde3;
1313
use aes::{Aes128, Aes192, Aes256};
1414

1515
#[cfg(any(feature = "aes-cbc", feature = "tdes"))]
16-
use cipher::{Block, BlockCipher, BlockCipherDecrypt, BlockModeDecrypt};
16+
use cipher::{
17+
Block,
18+
block::{BlockCipherDecrypt, BlockModeDecrypt},
19+
};
1720

1821
/// Stateful decryptor object for unauthenticated SSH symmetric ciphers.
1922
///
@@ -137,7 +140,7 @@ impl Decryptor {
137140
#[cfg(any(feature = "aes-cbc", feature = "tdes"))]
138141
fn cbc_decrypt<C>(decryptor: &mut cbc::Decryptor<C>, buffer: &mut [u8]) -> Result<()>
139142
where
140-
C: BlockCipher + BlockCipherDecrypt,
143+
C: BlockCipherDecrypt,
141144
{
142145
let (blocks, remaining) = Block::<C>::slice_as_chunks_mut(buffer);
143146

ssh-cipher/src/encryptor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! Stateful encryptor object.
22
33
use crate::{Cipher, Error, Result};
4-
use cipher::{Block, BlockCipher, BlockCipherEncrypt, KeyIvInit};
4+
use cipher::{Block, BlockCipherEncrypt, KeyIvInit};
55

66
#[cfg(feature = "aes-ctr")]
77
use {
88
crate::Ctr128BE,
9-
cipher::{StreamCipherCore, array::sizes::U16},
9+
cipher::{BlockSizeUser, StreamCipherCore, array::sizes::U16},
1010
};
1111

1212
#[cfg(feature = "tdes")]
@@ -16,7 +16,7 @@ use des::TdesEde3;
1616
use aes::{Aes128, Aes192, Aes256};
1717

1818
#[cfg(any(feature = "aes-cbc", feature = "tdes"))]
19-
use cipher::BlockModeEncrypt;
19+
use cipher::block::BlockModeEncrypt;
2020

2121
/// Stateful encryptor object for unauthenticated SSH symmetric ciphers.
2222
///
@@ -122,7 +122,7 @@ impl Encryptor {
122122
#[cfg(any(feature = "aes-cbc", feature = "tdes"))]
123123
fn cbc_encrypt<C>(encryptor: &mut cbc::Encryptor<C>, buffer: &mut [u8]) -> Result<()>
124124
where
125-
C: BlockCipher + BlockCipherEncrypt,
125+
C: BlockCipherEncrypt,
126126
{
127127
let (blocks, remaining) = Block::<C>::slice_as_chunks_mut(buffer);
128128

@@ -139,7 +139,7 @@ where
139139
#[cfg(feature = "aes-ctr")]
140140
pub(crate) fn ctr_encrypt<C>(encryptor: &mut Ctr128BE<C>, buffer: &mut [u8]) -> Result<()>
141141
where
142-
C: BlockCipher<BlockSize = U16> + BlockCipherEncrypt,
142+
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
143143
{
144144
let (blocks, remaining) = Block::<C>::slice_as_chunks_mut(buffer);
145145

ssh-cipher/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use encoding::{Label, LabelError};
4545

4646
#[cfg(feature = "aes-gcm")]
4747
use {
48-
aead::{AeadInPlace, array::typenum::U12},
48+
aead::{AeadInOut, array::typenum::U12},
4949
aes_gcm::{Aes128Gcm, Aes256Gcm},
5050
};
5151

@@ -236,7 +236,7 @@ impl Cipher {
236236
let nonce = iv.try_into().map_err(|_| Error::IvSize)?;
237237
let tag = tag.ok_or(Error::TagSize)?;
238238
cipher
239-
.decrypt_in_place_detached(nonce, &[], buffer, &tag)
239+
.decrypt_inout_detached(nonce, &[], buffer.into(), &tag)
240240
.map_err(|_| Error::Crypto)?;
241241

242242
Ok(())
@@ -247,7 +247,7 @@ impl Cipher {
247247
let nonce = iv.try_into().map_err(|_| Error::IvSize)?;
248248
let tag = tag.ok_or(Error::TagSize)?;
249249
cipher
250-
.decrypt_in_place_detached(nonce, &[], buffer, &tag)
250+
.decrypt_inout_detached(nonce, &[], buffer.into(), &tag)
251251
.map_err(|_| Error::Crypto)?;
252252

253253
Ok(())
@@ -300,7 +300,7 @@ impl Cipher {
300300
let cipher = Aes128Gcm::new_from_slice(key).map_err(|_| Error::KeySize)?;
301301
let nonce = iv.try_into().map_err(|_| Error::IvSize)?;
302302
let tag = cipher
303-
.encrypt_in_place_detached(nonce, &[], buffer)
303+
.encrypt_inout_detached(nonce, &[], buffer.into())
304304
.map_err(|_| Error::Crypto)?;
305305

306306
Ok(Some(tag))
@@ -310,7 +310,7 @@ impl Cipher {
310310
let cipher = Aes256Gcm::new_from_slice(key).map_err(|_| Error::KeySize)?;
311311
let nonce = iv.try_into().map_err(|_| Error::IvSize)?;
312312
let tag = cipher
313-
.encrypt_in_place_detached(nonce, &[], buffer)
313+
.encrypt_inout_detached(nonce, &[], buffer.into())
314314
.map_err(|_| Error::Crypto)?;
315315

316316
Ok(Some(tag))

ssh-encoding/Cargo.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ rust-version = "1.85"
1717

1818
[dependencies]
1919
base64ct = { version = "1.7", optional = true }
20+
bigint = { package = "crypto-bigint", version = "=0.7.0-pre.4", optional = true, default-features = false, features = ["alloc"] }
2021
bytes = { version = "1", optional = true, default-features = false }
21-
digest = { version = "=0.11.0-pre.9", optional = true, default-features = false }
22-
pem-rfc7468 = { version = "1.0.0-rc.2", optional = true }
22+
digest = { version = "0.11.0-rc.0", optional = true, default-features = false }
23+
pem-rfc7468 = { version = "1.0.0-rc.3", optional = true }
2324
ssh-derive = { version = "0.0.1-alpha", optional = true, path = "../ssh-derive" }
2425
subtle = { version = "2", optional = true, default-features = false }
2526
zeroize = { version = "1", optional = true, default-features = false }
2627

27-
# TODO(tarcieri): migrate to `crypto-bigint`
28-
bigint = { package = "num-bigint-dig", version = "0.8", optional = true, default-features = false }
29-
3028
[dev-dependencies]
3129
hex-literal = "1"
3230

ssh-encoding/src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ impl From<base64ct::InvalidLengthError> for Error {
119119
}
120120
}
121121

122+
#[cfg(feature = "bigint")]
123+
impl From<bigint::DecodeError> for Error {
124+
fn from(_: bigint::DecodeError) -> Error {
125+
Error::MpintEncoding
126+
}
127+
}
128+
122129
#[cfg(feature = "pem")]
123130
impl From<pem_rfc7468::Error> for Error {
124131
fn from(err: pem_rfc7468::Error) -> Error {

ssh-encoding/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ pub use crate::mpint::Mpint;
242242
#[cfg(feature = "base64")]
243243
pub use crate::{base64::Base64Reader, base64::Base64Writer};
244244

245+
#[cfg(feature = "bigint")]
246+
pub use bigint;
247+
245248
#[cfg(feature = "bytes")]
246249
pub use bytes;
247250

@@ -258,3 +261,14 @@ pub use ssh_derive::{Decode, Encode};
258261

259262
#[cfg(all(doc, feature = "alloc"))]
260263
use alloc::vec::Vec;
264+
265+
#[cfg(feature = "bigint")]
266+
pub use bigint::BoxedUint as Uint;
267+
268+
/// Non-zero [`Uint`].
269+
#[cfg(feature = "bigint")]
270+
pub type NonZeroUint = bigint::NonZero<Uint>;
271+
272+
/// Odd [`Uint`].
273+
#[cfg(feature = "bigint")]
274+
pub type OddUint = bigint::Odd<Uint>;

ssh-encoding/src/mpint.rs

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use crate::{CheckedSum, Decode, Encode, Error, Reader, Result, Writer};
44
use alloc::{boxed::Box, vec::Vec};
55
use core::fmt;
66

7+
#[cfg(feature = "bigint")]
8+
use crate::{NonZeroUint, OddUint, Uint};
9+
710
#[cfg(feature = "subtle")]
811
use subtle::{Choice, ConstantTimeEq};
912

@@ -205,45 +208,125 @@ impl fmt::UpperHex for Mpint {
205208
}
206209

207210
#[cfg(feature = "bigint")]
208-
impl TryFrom<bigint::BigUint> for Mpint {
211+
impl TryFrom<NonZeroUint> for Mpint {
209212
type Error = Error;
210213

211-
fn try_from(uint: bigint::BigUint) -> Result<Mpint> {
214+
fn try_from(uint: NonZeroUint) -> Result<Mpint> {
212215
Mpint::try_from(&uint)
213216
}
214217
}
215218

216219
#[cfg(feature = "bigint")]
217-
impl TryFrom<&bigint::BigUint> for Mpint {
220+
impl TryFrom<&NonZeroUint> for Mpint {
221+
type Error = Error;
222+
223+
fn try_from(uint: &NonZeroUint) -> Result<Mpint> {
224+
Self::try_from(uint.as_ref())
225+
}
226+
}
227+
228+
#[cfg(feature = "bigint")]
229+
impl TryFrom<OddUint> for Mpint {
218230
type Error = Error;
219231

220-
fn try_from(uint: &bigint::BigUint) -> Result<Mpint> {
221-
let bytes = Zeroizing::new(uint.to_bytes_be());
222-
Mpint::from_positive_bytes(bytes.as_slice())
232+
fn try_from(uint: OddUint) -> Result<Mpint> {
233+
Mpint::try_from(&uint)
223234
}
224235
}
225236

226237
#[cfg(feature = "bigint")]
227-
impl TryFrom<Mpint> for bigint::BigUint {
238+
impl TryFrom<&OddUint> for Mpint {
228239
type Error = Error;
229240

230-
fn try_from(mpint: Mpint) -> Result<bigint::BigUint> {
231-
bigint::BigUint::try_from(&mpint)
241+
fn try_from(uint: &OddUint) -> Result<Mpint> {
242+
Self::try_from(uint.as_ref())
232243
}
233244
}
234245

235246
#[cfg(feature = "bigint")]
236-
impl TryFrom<&Mpint> for bigint::BigUint {
247+
impl TryFrom<Uint> for Mpint {
237248
type Error = Error;
238249

239-
fn try_from(mpint: &Mpint) -> Result<bigint::BigUint> {
240-
mpint
241-
.as_positive_bytes()
242-
.map(bigint::BigUint::from_bytes_be)
250+
fn try_from(uint: Uint) -> Result<Mpint> {
251+
Mpint::try_from(&uint)
252+
}
253+
}
254+
255+
#[cfg(feature = "bigint")]
256+
impl TryFrom<&Uint> for Mpint {
257+
type Error = Error;
258+
259+
fn try_from(uint: &Uint) -> Result<Mpint> {
260+
let bytes = Zeroizing::new(uint.to_be_bytes());
261+
Mpint::from_positive_bytes(&bytes)
262+
}
263+
}
264+
265+
#[cfg(feature = "bigint")]
266+
impl TryFrom<Mpint> for NonZeroUint {
267+
type Error = Error;
268+
269+
fn try_from(mpint: Mpint) -> Result<NonZeroUint> {
270+
NonZeroUint::try_from(&mpint)
271+
}
272+
}
273+
274+
#[cfg(feature = "bigint")]
275+
impl TryFrom<&Mpint> for NonZeroUint {
276+
type Error = Error;
277+
278+
fn try_from(mpint: &Mpint) -> Result<NonZeroUint> {
279+
let uint = Uint::try_from(mpint)?;
280+
NonZeroUint::new(uint)
281+
.into_option()
243282
.ok_or(Error::MpintEncoding)
244283
}
245284
}
246285

286+
#[cfg(feature = "bigint")]
287+
impl TryFrom<Mpint> for OddUint {
288+
type Error = Error;
289+
290+
fn try_from(mpint: Mpint) -> Result<OddUint> {
291+
OddUint::try_from(&mpint)
292+
}
293+
}
294+
295+
#[cfg(feature = "bigint")]
296+
impl TryFrom<&Mpint> for OddUint {
297+
type Error = Error;
298+
299+
fn try_from(mpint: &Mpint) -> Result<OddUint> {
300+
let uint = Uint::try_from(mpint)?;
301+
OddUint::new(uint).into_option().ok_or(Error::MpintEncoding)
302+
}
303+
}
304+
305+
#[cfg(feature = "bigint")]
306+
impl TryFrom<Mpint> for Uint {
307+
type Error = Error;
308+
309+
fn try_from(mpint: Mpint) -> Result<Uint> {
310+
Uint::try_from(&mpint)
311+
}
312+
}
313+
314+
#[cfg(feature = "bigint")]
315+
impl TryFrom<&Mpint> for Uint {
316+
type Error = Error;
317+
318+
fn try_from(mpint: &Mpint) -> Result<Uint> {
319+
let bytes = mpint.as_positive_bytes().ok_or(Error::MpintEncoding)?;
320+
let bits_precision = bytes
321+
.len()
322+
.checked_mul(8)
323+
.and_then(|n| u32::try_from(n).ok())
324+
.ok_or(Error::MpintEncoding)?;
325+
326+
Ok(Uint::from_be_slice(bytes, bits_precision)?)
327+
}
328+
}
329+
247330
#[cfg(test)]
248331
mod tests {
249332
use super::Mpint;

0 commit comments

Comments
 (0)