Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords = ["Cryptography"]
description = "Shadowsocks Crypto"
repository = "https://github.com/shadowsocks/shadowsocks-crypto"
documentation = "https://docs.rs/shadowsocks-crypto"
rust-version = "1.71"
rust-version = "1.85"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
Expand Down Expand Up @@ -39,10 +39,10 @@ aws-lc = ["dep:aws-lc-rs"]
[dependencies]
cfg-if = { version = "1.0", optional = true }
rand = "0.10"
aes-gcm = { version = "0.10", optional = true }
aes-gcm-siv = { version = "0.11", optional = true }
ccm = { version = "0.5", optional = true }
chacha20poly1305 = { version = "0.10", optional = true }
aes-gcm = { version = "0.11.0-rc.3", optional = true }
aes-gcm-siv = { version = "0.12.0-rc.3", optional = true }
ccm = { version = "0.6.0-rc.3", optional = true }
chacha20poly1305 = { version = "0.11.0-rc.3", optional = true }
ring-compat = { version = "0.8", default-features = false, features = [
"aead",
"alloc",
Expand All @@ -51,16 +51,16 @@ aws-lc-rs = { version = "1.16", optional = true }
md-5 = { version = "0.11", optional = true }
hkdf = { version = "0.13", optional = true }
sha1 = { version = "0.11", optional = true }
blake3 = { version = "1.3", optional = true }
chacha20 = { version = "0.9", features = [], optional = true }
aes = { version = "0.8", optional = true }
ctr = { version = "0.9", optional = true }
bytes = { version = "1.3", optional = true }
camellia = { version = "0.1", optional = true }
sm4 = { version = "0.5", optional = true }
ghash = { version = "0.5", optional = true }
aead = { version = "0.5", optional = true }
subtle = { version = "2.5", optional = true }
blake3 = { version = "1.8", optional = true }
chacha20 = { version = "0.10", features = [], optional = true }
aes = { version = "0.9", optional = true }
ctr = { version = "0.10", optional = true }
bytes = { version = "1.11", optional = true }
camellia = { version = "0.2", optional = true }
sm4 = { version = "0.6", optional = true }
ghash = { version = "0.6", optional = true }
aead = { version = "0.6.0-rc.10", optional = true }
subtle = { version = "2.6", optional = true }

#[target.'cfg(all(unix, any(target_arch = "x86", target_arch = "x86_64")))'.dependencies]
#md-5 = { version = "0.10", features = ["asm"] }
Expand Down
28 changes: 17 additions & 11 deletions src/v1/aeadcipher/aes_ccm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use aes::{Aes128, Aes256};
use ccm::{
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeyInit, KeySizeUser},
aead::{array::typenum::Unsigned, AeadCore, AeadInOut, KeyInit, KeySizeUser},
consts::{U12, U16},
Ccm,
Nonce,
Expand All @@ -27,22 +27,25 @@ impl Aes128Ccm {
}

pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<U12>::try_from(nonce).expect("AES_128_CCM nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_128_CCM encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<U12>::try_from(nonce).expect("AES_128_CCM nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::<U16>::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}

Expand All @@ -66,21 +69,24 @@ impl Aes256Ccm {
}

pub fn encrypt(&mut self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<U12>::try_from(nonce).expect("AES_256_CCM nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_256_CCM encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&mut self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<U12>::try_from(nonce).expect("AES_256_CCM nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::<U16>::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}
43 changes: 25 additions & 18 deletions src/v1/aeadcipher/aes_gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,20 @@ cfg_if! {
}
} else {
use aes_gcm::{
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeySizeUser, KeyInit},
Key,
Nonce,
Tag,
aead::{self, array::typenum::Unsigned, AeadCore, AeadInOut, KeySizeUser, KeyInit},
};
use aes_gcm::{Aes128Gcm as CryptoAes128Gcm, Aes256Gcm as CryptoAes256Gcm};

type Key<A> = aead::Key<A>;
type Nonce<A> = aead::Nonce<A>;
type Tag<A> = aead::Tag<A>;

pub struct Aes128Gcm(Box<CryptoAes128Gcm>);

impl Aes128Gcm {
pub fn new(key: &[u8]) -> Aes128Gcm {
let key = Key::<CryptoAes128Gcm>::from_slice(key);
Aes128Gcm(Box::new(CryptoAes128Gcm::new(key)))
let key = Key::<CryptoAes128Gcm>::try_from(key).expect("AES_128_GCM key");
Aes128Gcm(Box::new(CryptoAes128Gcm::new(&key)))
}

pub fn key_size() -> usize {
Expand All @@ -127,31 +128,34 @@ cfg_if! {
}

pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<CryptoAes128Gcm>::try_from(nonce).expect("AES_128_GCM nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_128_GCM encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<CryptoAes128Gcm>::try_from(nonce).expect("AES_128_GCM nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::<CryptoAes128Gcm>::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}

pub struct Aes256Gcm(Box<CryptoAes256Gcm>);

impl Aes256Gcm {
pub fn new(key: &[u8]) -> Aes256Gcm {
let key = Key::<CryptoAes256Gcm>::from_slice(key);
Aes256Gcm(Box::new(CryptoAes256Gcm::new(key)))
let key = Key::<CryptoAes256Gcm>::try_from(key).expect("AES_256_GCM key");
Aes256Gcm(Box::new(CryptoAes256Gcm::new(&key)))
}

pub fn key_size() -> usize {
Expand All @@ -167,22 +171,25 @@ cfg_if! {
}

pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<CryptoAes256Gcm>::try_from(nonce).expect("AES_256_GCM nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_256_GCM encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::<CryptoAes256Gcm>::try_from(nonce).expect("AES_256_GCM nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::<CryptoAes256Gcm>::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}
}
Expand Down
36 changes: 21 additions & 15 deletions src/v1/aeadcipher/aes_gcm_siv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ cfg_if! {
aead_gcm_siv_cipher!(Aes256GcmSiv, AES_256_GCM_SIV);
} else {
use aes_gcm_siv::{
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeyInit, KeySizeUser},
aead::{array::typenum::Unsigned, AeadCore, AeadInOut, KeyInit, KeySizeUser},
Aes128GcmSiv as CryptoAes128GcmSiv,
Aes256GcmSiv as CryptoAes256GcmSiv,
Key,
Expand All @@ -78,8 +78,8 @@ cfg_if! {

impl Aes128GcmSiv {
pub fn new(key: &[u8]) -> Aes128GcmSiv {
let key = Key::<CryptoAes128GcmSiv>::from_slice(key);
Aes128GcmSiv(CryptoAes128GcmSiv::new(key))
let key = Key::<CryptoAes128GcmSiv>::try_from(key).expect("AES_128_GCM_SIV key");
Aes128GcmSiv(CryptoAes128GcmSiv::new(&key))
}

pub fn key_size() -> usize {
Expand All @@ -95,31 +95,34 @@ cfg_if! {
}

pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("AES_128_GCM_SIV nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_128_GCM_SIV encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("AES_128_GCM_SIV nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}

pub struct Aes256GcmSiv(CryptoAes256GcmSiv);

impl Aes256GcmSiv {
pub fn new(key: &[u8]) -> Aes256GcmSiv {
let key = Key::<CryptoAes256GcmSiv>::from_slice(key);
Aes256GcmSiv(CryptoAes256GcmSiv::new(key))
let key = Key::<CryptoAes256GcmSiv>::try_from(key).expect("AES_256_GCM_SIV key");
Aes256GcmSiv(CryptoAes256GcmSiv::new(&key))
}

pub fn key_size() -> usize {
Expand All @@ -135,22 +138,25 @@ cfg_if! {
}

pub fn encrypt(&mut self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("AES_256_GCM_SIV nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("AES_256_GCM_SIV encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&mut self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("AES_256_GCM_SIV nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/v1/aeadcipher/chacha20_poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ cfg_if! {
} else {
use chacha20poly1305::ChaCha20Poly1305 as CryptoChaCha20Poly1305;
use chacha20poly1305::{
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeySizeUser, KeyInit},
aead::{array::typenum::Unsigned, AeadCore, AeadInOut, KeySizeUser, KeyInit},
Key,
Nonce,
Tag,
Expand All @@ -86,8 +86,8 @@ cfg_if! {

impl ChaCha20Poly1305 {
pub fn new(key: &[u8]) -> ChaCha20Poly1305 {
let key = Key::from_slice(key);
ChaCha20Poly1305(CryptoChaCha20Poly1305::new(key))
let key = Key::try_from(key).expect("CHACHA20_POLY1305 key");
ChaCha20Poly1305(CryptoChaCha20Poly1305::new(&key))
}

pub fn key_size() -> usize {
Expand All @@ -103,22 +103,25 @@ cfg_if! {
}

pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("CHACHA20_POLY1305 nonce");
let (plaintext, out_tag) =
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
let tag = self
.0
.encrypt_in_place_detached(nonce, &[], plaintext)
.encrypt_inout_detached(&nonce, &[], plaintext.into())
.expect("CHACHA20_POLY1305 encrypt");
out_tag.copy_from_slice(tag.as_slice())
}

pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
let nonce = Nonce::from_slice(nonce);
let nonce = Nonce::try_from(nonce).expect("CHACHA20_POLY1305 nonce");
let (ciphertext, in_tag) =
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
let in_tag = Tag::from_slice(in_tag);
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
let in_tag = match Tag::try_from(&*in_tag) {
Ok(t) => t,
Err(_) => return false,
};
self.0.decrypt_inout_detached(&nonce, &[], ciphertext.into(), &in_tag).is_ok()
}
}
}
Expand Down
Loading
Loading