调整加密
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
mod rs_aes_cbc;
|
||||
pub use rs_aes_cbc::*;
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::io;
|
||||
|
||||
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
|
||||
use anyhow::anyhow;
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::cipher::Finger;
|
||||
@@ -50,14 +49,14 @@ impl AesCbcCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < 16 {
|
||||
log::error!("数据异常,长度{}小于{}", net_packet.payload().len(), 16);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("aes_cbc data err"));
|
||||
}
|
||||
let mut iv = [0; 16];
|
||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -75,7 +74,7 @@ impl AesCbcCipher {
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("aes_cbc finger err"));
|
||||
}
|
||||
}
|
||||
let rs = match &self.cipher {
|
||||
@@ -92,10 +91,7 @@ impl AesCbcCipher {
|
||||
net_packet.set_data_len(HEAD_LEN + len - 4)?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("解密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("aes_cbc 解密失败:{}", e)),
|
||||
}
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
@@ -103,7 +99,7 @@ impl AesCbcCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
let data_len = net_packet.data_len();
|
||||
let mut iv = [0; 16];
|
||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -146,10 +142,7 @@ impl AesCbcCipher {
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("加密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("aes_cbc 加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
|
||||
mod rs_aes_ecb;
|
||||
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
|
||||
pub use rs_aes_ecb::*;
|
||||
|
||||
#[cfg(any(feature = "openssl-vendored", feature = "openssl"))]
|
||||
mod openssl_aes_ecb;
|
||||
#[cfg(any(feature = "openssl-vendored", feature = "openssl"))]
|
||||
pub use openssl_aes_ecb::*;
|
||||
@@ -1,8 +1,11 @@
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||
use std::ptr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use libc::c_int;
|
||||
use openssl_sys::EVP_CIPHER_CTX;
|
||||
use std::{io, ptr};
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||
|
||||
pub struct AesEcbCipher {
|
||||
key: Vec<u8>,
|
||||
@@ -100,10 +103,10 @@ impl AesEcbCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
|
||||
if let Some(finger) = &self.finger {
|
||||
@@ -116,18 +119,18 @@ impl AesEcbCipher {
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let len = net_packet.payload().len();
|
||||
if len < 12 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data len err"));
|
||||
return Err(anyhow!("data len err"));
|
||||
}
|
||||
let secret_body = &net_packet.payload()[..len - 12];
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||
if &finger != &net_packet.payload()[len - 12..] {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("finger err"));
|
||||
}
|
||||
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||
}
|
||||
if net_packet.payload().len() < 16 {
|
||||
log::error!("数据异常,长度{}小于{}", net_packet.payload().len(), 16);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let input = net_packet.payload();
|
||||
let mut out = [0u8; 1024 * 5];
|
||||
@@ -147,22 +150,22 @@ impl AesEcbCipher {
|
||||
//校验头部
|
||||
let src_net_packet = NetPacket::new(text)?;
|
||||
if src_net_packet.source() != net_packet.source() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.destination() != net_packet.destination() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.protocol() != net_packet.protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.transport_protocol() != net_packet.transport_protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.is_gateway() != net_packet.is_gateway() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.source_ttl() != net_packet.source_ttl() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
}
|
||||
net_packet.set_encrypt_flag(false);
|
||||
@@ -175,7 +178,7 @@ impl AesEcbCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
let input = net_packet.buffer();
|
||||
let mut out = [0u8; 1024 * 5];
|
||||
let mut out_len = 0;
|
||||
@@ -191,7 +194,7 @@ impl AesEcbCipher {
|
||||
}
|
||||
let out_len = out_len as usize;
|
||||
if out_len == 0 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "ciphertext len err"));
|
||||
return Err(anyhow!("ciphertext len err"));
|
||||
}
|
||||
//密文
|
||||
let ciphertext = &out[..out_len];
|
||||
@@ -1,7 +1,8 @@
|
||||
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyInit};
|
||||
use anyhow::anyhow;
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyInit};
|
||||
use std::io;
|
||||
|
||||
type Aes128EcbEnc = ecb::Encryptor<aes::Aes128>;
|
||||
type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;
|
||||
@@ -46,10 +47,10 @@ impl AesEcbCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
|
||||
if let Some(finger) = &self.finger {
|
||||
@@ -62,18 +63,18 @@ impl AesEcbCipher {
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let len = net_packet.payload().len();
|
||||
if len < 12 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "payload len <12"));
|
||||
return Err(anyhow!("payload len <12"));
|
||||
}
|
||||
let secret_body = &net_packet.payload()[..len - 12];
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||
if &finger != &net_packet.payload()[len - 12..] {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("finger err"));
|
||||
}
|
||||
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||
}
|
||||
if net_packet.payload().len() < 16 {
|
||||
log::error!("数据异常,长度{}小于{}", net_packet.payload().len(), 16);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut out = [0u8; 1024 * 5];
|
||||
let rs = match self.key {
|
||||
@@ -87,32 +88,29 @@ impl AesEcbCipher {
|
||||
//校验头部
|
||||
let src_net_packet = NetPacket::new(buf)?;
|
||||
if src_net_packet.source() != net_packet.source() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.destination() != net_packet.destination() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.protocol() != net_packet.protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.transport_protocol() != net_packet.transport_protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.is_gateway() != net_packet.is_gateway() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.source_ttl() != net_packet.source_ttl() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
net_packet.set_data_len(buf.len())?;
|
||||
net_packet.set_payload(src_net_packet.payload())?;
|
||||
net_packet.set_encrypt_flag(false);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("aes_ecb解密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("aes_ecb解密失败:{}", e)),
|
||||
}
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
@@ -120,7 +118,7 @@ impl AesEcbCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
let mut out = [0u8; 1024 * 5];
|
||||
let rs = match self.key {
|
||||
AesEcbEnum::AES128ECB(key) => Aes128EcbEnc::new(&key.into())
|
||||
@@ -152,10 +150,7 @@ impl AesEcbCipher {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("aes_ecb加密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("aes_ecb加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
use std::io;
|
||||
|
||||
use aes_gcm::aead::consts::{U12, U16};
|
||||
use aes_gcm::aead::generic_array::GenericArray;
|
||||
use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, Tag};
|
||||
use anyhow::anyhow;
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::cipher::finger::Finger;
|
||||
@@ -39,14 +38,14 @@ impl AesGcmCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -62,7 +61,7 @@ impl AesGcmCipher {
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("finger err"));
|
||||
}
|
||||
}
|
||||
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(tag);
|
||||
@@ -75,10 +74,7 @@ impl AesGcmCipher {
|
||||
}
|
||||
};
|
||||
if let Err(e) = rs {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("解密失败:{}", e),
|
||||
));
|
||||
return Err(anyhow!("解密失败:{}", e));
|
||||
}
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
||||
@@ -89,9 +85,9 @@ impl AesGcmCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if net_packet.reserve() < AES_GCM_ENCRYPTION_RESERVED {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "too short"));
|
||||
return Err(anyhow!("too short"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -123,10 +119,7 @@ impl AesGcmCipher {
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("加密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
mod ring_aes_gcm_cipher;
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
pub use ring_aes_gcm_cipher::*;
|
||||
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
mod aes_gcm_cipher;
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
pub use aes_gcm_cipher::*;
|
||||
+10
-19
@@ -1,9 +1,9 @@
|
||||
use crate::cipher::Finger;
|
||||
use anyhow::anyhow;
|
||||
use rand::RngCore;
|
||||
use ring::aead;
|
||||
use ring::aead::{LessSafeKey, UnboundKey};
|
||||
use std::io;
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
|
||||
use crate::protocol::NetPacket;
|
||||
|
||||
@@ -53,14 +53,14 @@ impl AesGcmCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -74,7 +74,7 @@ impl AesGcmCipher {
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "ring aes finger err"));
|
||||
return Err(anyhow!("ring aes finger err"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +87,7 @@ impl AesGcmCipher {
|
||||
}
|
||||
};
|
||||
if let Err(e) = rs {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("解密失败:{}", e),
|
||||
));
|
||||
return Err(anyhow!("解密失败:{}", e));
|
||||
}
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
||||
@@ -102,7 +99,7 @@ impl AesGcmCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
@@ -128,10 +125,7 @@ impl AesGcmCipher {
|
||||
Ok(tag) => {
|
||||
let tag = tag.as_ref();
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("加密tag长度错误:{}", tag.len()),
|
||||
));
|
||||
return Err(anyhow!("加密tag长度错误:{}", tag.len()));
|
||||
}
|
||||
secret_body.set_tag(tag)?;
|
||||
if let Some(finger) = &self.finger {
|
||||
@@ -141,10 +135,7 @@ impl AesGcmCipher {
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("加密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
mod rs_chacha20;
|
||||
pub use rs_chacha20::*;
|
||||
@@ -0,0 +1,114 @@
|
||||
use aes::cipher::Iv;
|
||||
use anyhow::anyhow;
|
||||
use chacha20::cipher::{Key, KeyIvInit, StreamCipher};
|
||||
use chacha20::ChaCha20;
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::body::ChaCah20SecretBody;
|
||||
use crate::protocol::NetPacket;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChaCha20Cipher {
|
||||
key: [u8; 32],
|
||||
pub(crate) finger: Option<Finger>,
|
||||
}
|
||||
|
||||
impl ChaCha20Cipher {
|
||||
pub fn new_256(key: [u8; 32], finger: Option<Finger>) -> Self {
|
||||
Self { key, finger }
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaCha20Cipher {
|
||||
pub fn key(&self) -> &[u8] {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaCha20Cipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
let mut iv = [0; 12];
|
||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
iv[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
iv[8] = net_packet.protocol().into();
|
||||
iv[9] = net_packet.transport_protocol();
|
||||
iv[10] = net_packet.is_gateway() as u8;
|
||||
iv[11] = net_packet.source_ttl();
|
||||
|
||||
let mut secret_body =
|
||||
ChaCah20SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(anyhow!("ChaCha20 finger err"));
|
||||
}
|
||||
}
|
||||
|
||||
ChaCha20::new(
|
||||
Key::<ChaCha20>::from_slice(&self.key),
|
||||
Iv::<ChaCha20>::from_slice(&iv),
|
||||
)
|
||||
.apply_keystream(secret_body.en_body_mut());
|
||||
let len = secret_body.en_body().len();
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_payload_len(len)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
let data_len = net_packet.data_len();
|
||||
let mut iv = [0; 12];
|
||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
iv[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
iv[8] = net_packet.protocol().into();
|
||||
iv[9] = net_packet.transport_protocol();
|
||||
iv[10] = net_packet.is_gateway() as u8;
|
||||
iv[11] = net_packet.source_ttl();
|
||||
if let Some(_) = &self.finger {
|
||||
net_packet.set_data_len(data_len + 12)?;
|
||||
}
|
||||
let mut secret_body =
|
||||
ChaCah20SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
ChaCha20::new(
|
||||
Key::<ChaCha20>::from_slice(&self.key),
|
||||
Iv::<ChaCha20>::from_slice(&iv),
|
||||
)
|
||||
.apply_keystream(secret_body.en_body_mut());
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body_mut());
|
||||
let mut secret_body = ChaCah20SecretBody::new(net_packet.payload_mut(), true)?;
|
||||
secret_body.set_finger(&finger)?;
|
||||
}
|
||||
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chacha20() {
|
||||
let d = ChaCha20Cipher::new_256([0; 32], Some(Finger::new("123")));
|
||||
let mut p =
|
||||
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src);
|
||||
|
||||
let d = ChaCha20Cipher::new_256([0; 32], None);
|
||||
let mut p =
|
||||
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
mod ring_chacha20_poly1305;
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
pub use ring_chacha20_poly1305::*;
|
||||
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
mod rs_chacha20_poly1305;
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
pub use rs_chacha20_poly1305::*;
|
||||
@@ -0,0 +1,129 @@
|
||||
use anyhow::anyhow;
|
||||
|
||||
use ring::aead;
|
||||
use ring::aead::{LessSafeKey, UnboundKey};
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
|
||||
use crate::protocol::NetPacket;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChaCha20Poly1305Cipher {
|
||||
key: Vec<u8>,
|
||||
pub(crate) cipher: LessSafeKey,
|
||||
pub(crate) finger: Option<Finger>,
|
||||
}
|
||||
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn new_256(key: [u8; 32], finger: Option<Finger>) -> Self {
|
||||
let cipher = LessSafeKey::new(UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap());
|
||||
Self {
|
||||
key: key.to_vec(),
|
||||
cipher,
|
||||
finger,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn key(&self) -> &[u8] {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(anyhow!("ring CHACHA20_POLY1305 finger err"));
|
||||
}
|
||||
}
|
||||
|
||||
let rs = self
|
||||
.cipher
|
||||
.open_in_place(nonce, aead::Aad::empty(), secret_body.en_body_mut());
|
||||
if let Err(e) = rs {
|
||||
return Err(anyhow!("ring CHACHA20_POLY1305 解密失败:{}", e));
|
||||
}
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
||||
return Ok(());
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
/// data_len是有效载荷的长度
|
||||
/// 返回加密后载荷的长度
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
|
||||
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED;
|
||||
net_packet.set_data_len(data_len)?;
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
let rs = self.cipher.seal_in_place_separate_tag(
|
||||
nonce,
|
||||
aead::Aad::empty(),
|
||||
secret_body.body_mut(),
|
||||
);
|
||||
return match rs {
|
||||
Ok(tag) => {
|
||||
let tag = tag.as_ref();
|
||||
if tag.len() != 16 {
|
||||
return Err(anyhow!("加密tag长度错误:{}", tag.len()));
|
||||
}
|
||||
secret_body.set_tag(tag)?;
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
secret_body.set_finger(&finger)?;
|
||||
}
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(anyhow!("ring CHACHA20_POLY1305 加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ring_chacha20_poly1305() {
|
||||
let d = ChaCha20Poly1305Cipher::new_256([0; 32], Some(Finger::new("123")));
|
||||
let mut p = NetPacket::new_encrypt([0; 73]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src);
|
||||
let d = ChaCha20Poly1305Cipher::new_256([0; 32], None);
|
||||
let mut p = NetPacket::new_encrypt([0; 73]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
use anyhow::anyhow;
|
||||
use chacha20poly1305::aead::{Nonce, Tag};
|
||||
use chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, Key, KeyInit};
|
||||
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
|
||||
use crate::protocol::NetPacket;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChaCha20Poly1305Cipher {
|
||||
key: Vec<u8>,
|
||||
pub(crate) cipher: ChaCha20Poly1305,
|
||||
pub(crate) finger: Option<Finger>,
|
||||
}
|
||||
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn new_256(key: [u8; 32], finger: Option<Finger>) -> Self {
|
||||
let key: &Key = &key.into();
|
||||
let cipher = ChaCha20Poly1305::new(key);
|
||||
Self {
|
||||
key: key.to_vec(),
|
||||
cipher,
|
||||
finger,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn key(&self) -> &[u8] {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
impl ChaCha20Poly1305Cipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(anyhow!("rs CHACHA20_POLY1305 finger err"));
|
||||
}
|
||||
}
|
||||
let nonce: Nonce<ChaCha20Poly1305> = nonce_raw.into();
|
||||
let tag: Tag<ChaCha20Poly1305> =
|
||||
Tag::<ChaCha20Poly1305>::from_slice(secret_body.tag()).clone();
|
||||
if let Err(e) =
|
||||
self.cipher
|
||||
.decrypt_in_place_detached(&nonce, &[], secret_body.body_mut(), &tag)
|
||||
{
|
||||
return Err(anyhow!("rs CHACHA20_POLY1305 decrypt_ipv4 {:?}", e));
|
||||
}
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
||||
Ok(())
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
/// data_len是有效载荷的长度
|
||||
/// 返回加密后载荷的长度
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce = nonce_raw.into();
|
||||
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED;
|
||||
net_packet.set_data_len(data_len)?;
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
|
||||
let rs = self
|
||||
.cipher
|
||||
.encrypt_in_place_detached(&nonce, &[], secret_body.body_mut());
|
||||
return match rs {
|
||||
Ok(tag) => {
|
||||
let tag: &[u8] = tag.as_ref();
|
||||
if tag.len() != 16 {
|
||||
return Err(anyhow!("加密tag长度错误:{}", tag.len(),));
|
||||
}
|
||||
secret_body.set_tag(tag)?;
|
||||
if let Some(finger) = &self.finger {
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||
secret_body.set_finger(&finger)?;
|
||||
}
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(anyhow!("rs CHACHA20_POLY1305 加密失败:{}", e)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rs_chacha20_poly1305() {
|
||||
let d = ChaCha20Poly1305Cipher::new_256([0; 32], Some(Finger::new("123")));
|
||||
let mut p = NetPacket::new_encrypt([0; 73]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src);
|
||||
}
|
||||
+108
-132
@@ -1,51 +1,42 @@
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
|
||||
use crate::cipher::aes_ecb::AesEcbCipher;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
#[cfg(cipher)]
|
||||
use sha2::Digest;
|
||||
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
use crate::cipher::aes_cbc::AesCbcCipher;
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
use crate::cipher::aes_gcm_cipher::AesGcmCipher;
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
#[cfg(any(feature = "openssl-vendored", feature = "openssl"))]
|
||||
use crate::cipher::openssl_aes_ecb::AesEcbCipher;
|
||||
use crate::cipher::aes_ecb::AesEcbCipher;
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
use crate::cipher::ring_aes_gcm_cipher::AesGcmCipher;
|
||||
use crate::cipher::aes_gcm::AesGcmCipher;
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
use crate::cipher::chacha20::ChaCha20Cipher;
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
use crate::cipher::chacha20_poly1305::ChaCha20Poly1305Cipher;
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
use crate::cipher::sm4_cbc::Sm4CbcCipher;
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
use crate::cipher::xor::XORCipher;
|
||||
#[cfg(cipher)]
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::NetPacket;
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
use sha2::Digest;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum CipherModel {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
AesGcm,
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Chacha20Poly1305,
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Chacha20,
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
AesCbc,
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
AesEcb,
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
Sm4Cbc,
|
||||
Xor,
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -54,61 +45,55 @@ impl Display for CipherModel {
|
||||
let str = match self {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
CipherModel::AesGcm => "aes_gcm".to_string(),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
CipherModel::Chacha20Poly1305 => "chacha20_poly1305".to_string(),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
CipherModel::Chacha20 => "chacha20".to_string(),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
CipherModel::AesCbc => "aes_cbc".to_string(),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
CipherModel::AesEcb => "aes_ecb".to_string(),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
CipherModel::Sm4Cbc => "sm4_cbc".to_string(),
|
||||
CipherModel::Xor => "xor".to_string(),
|
||||
CipherModel::None => "none".to_string(),
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CipherModel {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
#[cfg(not(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
)))]
|
||||
return Err(format!("not match '{}', no encrypt", s));
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
match s.to_lowercase().trim() {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
"aes_gcm" => Ok(CipherModel::AesGcm),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
"chacha20_poly1305" => Ok(CipherModel::Chacha20Poly1305),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
"chacha20" => Ok(CipherModel::Chacha20),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
"aes_cbc" => Ok(CipherModel::AesCbc),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
"aes_ecb" => Ok(CipherModel::AesEcb),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
"sm4_cbc" => Ok(CipherModel::Sm4Cbc),
|
||||
"xor" => Ok(CipherModel::Xor),
|
||||
_ => {
|
||||
let mut enums = String::new();
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
enums.push_str("/aes_gcm");
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
enums.push_str("/chacha20_poly1305/chacha20");
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
enums.push_str("/aes_cbc");
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
enums.push_str("/aes_ecb");
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
enums.push_str("/sm4_cbc");
|
||||
let str = if enums.is_empty() {
|
||||
"no encrypt"
|
||||
} else {
|
||||
&enums[1..]
|
||||
};
|
||||
Err(format!("not match '{}', enum:{}", s, str))
|
||||
enums.push_str("/xor");
|
||||
Err(format!("not match '{}', enum:{}", s, &enums[1..]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,49 +103,37 @@ impl FromStr for CipherModel {
|
||||
pub enum Cipher {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
AesGcm((AesGcmCipher, Vec<u8>)),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Chacha20Poly1305(ChaCha20Poly1305Cipher),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Chacha20(ChaCha20Cipher),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
AesCbc(AesCbcCipher),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
AesEcb(AesEcbCipher),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
Sm4Cbc(Sm4CbcCipher),
|
||||
Xor(XORCipher),
|
||||
None,
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
#[cfg(not(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
)))]
|
||||
pub fn new_password(
|
||||
_model: CipherModel,
|
||||
_password: Option<String>,
|
||||
_token: Option<String>,
|
||||
) -> Self {
|
||||
Cipher::None
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
pub fn new_password(
|
||||
model: CipherModel,
|
||||
password: Option<String>,
|
||||
token: Option<String>,
|
||||
) -> Self {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
if let Some(password) = password {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
#[cfg(cipher)]
|
||||
let key: [u8; 32] = {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
hasher.finalize().into()
|
||||
};
|
||||
match model {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
CipherModel::AesGcm => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
if password.len() < 8 {
|
||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Cipher::AesGcm((aes, key[..16].to_vec()))
|
||||
@@ -169,8 +142,21 @@ impl Cipher {
|
||||
Cipher::AesGcm((aes, key.to_vec()))
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
CipherModel::Chacha20Poly1305 => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
let chacha = ChaCha20Poly1305Cipher::new_256(key, finger);
|
||||
Cipher::Chacha20Poly1305(chacha)
|
||||
}
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
CipherModel::Chacha20 => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
let chacha = ChaCha20Cipher::new_256(key, finger);
|
||||
Cipher::Chacha20(chacha)
|
||||
}
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
CipherModel::AesCbc => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
if password.len() < 8 {
|
||||
let aes = AesCbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Cipher::AesCbc(aes)
|
||||
@@ -181,6 +167,7 @@ impl Cipher {
|
||||
}
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
CipherModel::AesEcb => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
if password.len() < 8 {
|
||||
let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Cipher::AesEcb(aes)
|
||||
@@ -191,126 +178,97 @@ impl Cipher {
|
||||
}
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
CipherModel::Sm4Cbc => {
|
||||
let finger = token.map(|token| Finger::new(&token));
|
||||
let aes = Sm4CbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Cipher::Sm4Cbc(aes)
|
||||
}
|
||||
CipherModel::Xor => {
|
||||
let _token = token;
|
||||
Cipher::Xor(XORCipher::new_256(crate::cipher::xor::simple_hash(
|
||||
&password,
|
||||
)))
|
||||
}
|
||||
CipherModel::None => Cipher::None,
|
||||
}
|
||||
} else {
|
||||
Cipher::None
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
)))]
|
||||
pub fn new_key(_key: [u8; 32], _token: String) -> io::Result<Self> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "key error"))
|
||||
#[cfg(not(any(feature = "aes_gcm", feature = "server_encrypt")))]
|
||||
pub fn new_key(_key: [u8; 32], _token: String) -> anyhow::Result<Self> {
|
||||
Err(anyhow!("key error"))
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
pub fn new_key(key: [u8; 32], token: String) -> io::Result<Self> {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
pub fn new_key(key: [u8; 32], token: String) -> anyhow::Result<Self> {
|
||||
let finger = Some(Finger::new(&token));
|
||||
match key.len() {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
16 => {
|
||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Ok(Cipher::AesGcm((aes, key[..16].to_vec())))
|
||||
}
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
32 => {
|
||||
let aes = AesGcmCipher::new_256(key, finger);
|
||||
Ok(Cipher::AesGcm((aes, key.to_vec())))
|
||||
}
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, "key error")),
|
||||
_ => Err(anyhow!("key error")),
|
||||
}
|
||||
}
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
match self {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm.decrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
Cipher::AesCbc(aes_cbc) => aes_cbc.decrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20Poly1305(chacha20poly1305) => chacha20poly1305.decrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20(chacha20) => chacha20.decrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
Cipher::AesEcb(aes_ecb) => aes_ecb.decrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.decrypt_ipv4(net_packet),
|
||||
Cipher::Xor(xor) => xor.decrypt_ipv4(net_packet),
|
||||
Cipher::None => {
|
||||
if net_packet.is_encrypt() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not key"));
|
||||
return Err(anyhow!("not key"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
)))]
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
_net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
match self {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm.encrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20Poly1305(chacha20poly1305) => chacha20poly1305.encrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20(chacha20) => chacha20.encrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
Cipher::AesCbc(aes_cbc) => aes_cbc.encrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
Cipher::AesEcb(aes_ecb) => aes_ecb.encrypt_ipv4(net_packet),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.encrypt_ipv4(net_packet),
|
||||
Cipher::Xor(xor) => xor.encrypt_ipv4(net_packet),
|
||||
Cipher::None => Ok(()),
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
)))]
|
||||
#[cfg(not(cipher))]
|
||||
pub fn check_finger<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
_net_packet: &NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> io::Result<()> {
|
||||
#[cfg(cipher)]
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> anyhow::Result<()> {
|
||||
match self {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm
|
||||
@@ -318,6 +276,18 @@ impl Cipher {
|
||||
.as_ref()
|
||||
.map(|f| f.check_finger(net_packet))
|
||||
.unwrap_or(Ok(())),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20Poly1305(chacha20poly1305) => chacha20poly1305
|
||||
.finger
|
||||
.as_ref()
|
||||
.map(|f| f.check_finger(net_packet))
|
||||
.unwrap_or(Ok(())),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20(chacha20) => chacha20
|
||||
.finger
|
||||
.as_ref()
|
||||
.map(|f| f.check_finger(net_packet))
|
||||
.unwrap_or(Ok(())),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
Cipher::AesCbc(aes_cbc) => aes_cbc
|
||||
.finger
|
||||
@@ -336,6 +306,7 @@ impl Cipher {
|
||||
.as_ref()
|
||||
.map(|f| f.check_finger(net_packet))
|
||||
.unwrap_or(Ok(())),
|
||||
Cipher::Xor(_) => Ok(()),
|
||||
Cipher::None => Ok(()),
|
||||
}
|
||||
}
|
||||
@@ -343,12 +314,17 @@ impl Cipher {
|
||||
match self {
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
Cipher::AesGcm((_, key)) => Some(key),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20Poly1305(chacha20poly1305) => Some(chacha20poly1305.key()),
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
Cipher::Chacha20(chacha20) => Some(chacha20.key()),
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
Cipher::AesCbc(aes_cbc) => Some(aes_cbc.key()),
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
Cipher::AesEcb(aes_ecb) => Some(aes_ecb.key()),
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
Cipher::Sm4Cbc(sm4_cbc) => Some(sm4_cbc.key()),
|
||||
Cipher::Xor(xor) => Some(xor.key()),
|
||||
Cipher::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io;
|
||||
use anyhow::anyhow;
|
||||
|
||||
use sha2::Digest;
|
||||
|
||||
@@ -16,15 +16,15 @@ impl Finger {
|
||||
let hash: [u8; 32] = hasher.finalize().into();
|
||||
Finger { hash }
|
||||
}
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> io::Result<()> {
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
let payload_len = net_packet.payload().len();
|
||||
if payload_len < 12 {
|
||||
log::error!("数据异常,长度小于{}", 12);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
@@ -36,7 +36,7 @@ impl Finger {
|
||||
let payload = net_packet.payload();
|
||||
let finger = self.calculate_finger(&nonce_raw, &payload[..payload_len - 12]);
|
||||
if &finger[..] != &payload[payload_len - 12..] {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("finger err"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+21
-30
@@ -1,40 +1,31 @@
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
mod aes_cbc;
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
|
||||
mod aes_ecb;
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
mod aes_gcm_cipher;
|
||||
mod cipher;
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
#[cfg(cipher)]
|
||||
mod finger;
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
#[cfg(any(feature = "openssl-vendored", feature = "openssl"))]
|
||||
mod openssl_aes_ecb;
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
mod ring_aes_gcm_cipher;
|
||||
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
mod sm4_cbc;
|
||||
pub use cipher::Cipher;
|
||||
pub use cipher::CipherModel;
|
||||
#[cfg(any(
|
||||
feature = "aes_gcm",
|
||||
feature = "server_encrypt",
|
||||
feature = "aes_cbc",
|
||||
feature = "aes_ecb",
|
||||
feature = "sm4_cbc"
|
||||
))]
|
||||
#[cfg(cipher)]
|
||||
pub use finger::Finger;
|
||||
#[cfg(feature = "server_encrypt")]
|
||||
mod rsa_cipher;
|
||||
#[cfg(feature = "server_encrypt")]
|
||||
pub use rsa_cipher::RsaCipher;
|
||||
|
||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||
mod aes_gcm;
|
||||
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
mod chacha20;
|
||||
#[cfg(feature = "chacha20_poly1305")]
|
||||
mod chacha20_poly1305;
|
||||
|
||||
#[cfg(feature = "aes_ecb")]
|
||||
mod aes_ecb;
|
||||
|
||||
#[cfg(feature = "aes_cbc")]
|
||||
mod aes_cbc;
|
||||
|
||||
#[cfg(feature = "sm4_cbc")]
|
||||
mod sm4_cbc;
|
||||
|
||||
mod xor;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
mod rs_sm4_cbc;
|
||||
pub use rs_sm4_cbc::*;
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||
use anyhow::anyhow;
|
||||
use libsm::sm4::cipher_mode::CipherMode;
|
||||
use libsm::sm4::Sm4CipherMode;
|
||||
use rand::RngCore;
|
||||
use std::io;
|
||||
|
||||
pub struct Sm4CbcCipher {
|
||||
key: [u8; 16],
|
||||
@@ -41,10 +41,10 @@ impl Sm4CbcCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
|
||||
if let Some(finger) = &self.finger {
|
||||
@@ -57,12 +57,12 @@ impl Sm4CbcCipher {
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let len = net_packet.payload().len();
|
||||
if len < 12 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "payload len <12"));
|
||||
return Err(anyhow!("payload len <12"));
|
||||
}
|
||||
let secret_body = &net_packet.payload()[..len - 12];
|
||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||
if &finger != &net_packet.payload()[len - 12..] {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
return Err(anyhow!("finger err"));
|
||||
}
|
||||
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ impl Sm4CbcCipher {
|
||||
let len = payload.len();
|
||||
if len < 16 || len > 1024 * 4 {
|
||||
log::error!("数据异常,长度{}小于16或大于4096", len);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
let mut out = [0u8; 1024 * 4];
|
||||
let data = &payload[..len - 16];
|
||||
@@ -79,32 +79,29 @@ impl Sm4CbcCipher {
|
||||
Ok(len) => {
|
||||
let src_net_packet = NetPacket::new(&out[..len])?;
|
||||
if src_net_packet.source() != net_packet.source() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.destination() != net_packet.destination() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.protocol() != net_packet.protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.transport_protocol() != net_packet.transport_protocol() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.is_gateway() != net_packet.is_gateway() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
if src_net_packet.source_ttl() != net_packet.source_ttl() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
net_packet.set_data_len(len)?;
|
||||
net_packet.set_payload(src_net_packet.payload())?;
|
||||
net_packet.set_encrypt_flag(false);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("sm4_cbc解密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("sm4_cbc解密失败:{}", e)),
|
||||
}
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
@@ -112,7 +109,7 @@ impl Sm4CbcCipher {
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> io::Result<()> {
|
||||
) -> anyhow::Result<()> {
|
||||
let mut out = [0u8; 1024 * 4];
|
||||
let mut iv = [0u8; 16];
|
||||
rand::thread_rng().fill_bytes(&mut iv);
|
||||
@@ -121,7 +118,7 @@ impl Sm4CbcCipher {
|
||||
"数据异常,长度{}大于1024 * 4 - 32",
|
||||
net_packet.buffer().len()
|
||||
);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
return Err(anyhow!("data err"));
|
||||
}
|
||||
match self.cipher.encrypt(net_packet.buffer(), &iv, &mut out) {
|
||||
Ok(len) => {
|
||||
@@ -146,10 +143,7 @@ impl Sm4CbcCipher {
|
||||
net_packet.set_encrypt_flag(true);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("sm4_cbc加密失败:{}", e),
|
||||
)),
|
||||
Err(e) => Err(anyhow!("sm4_cbc加密失败:{}", e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
mod xor;
|
||||
pub use xor::*;
|
||||
@@ -0,0 +1,88 @@
|
||||
use anyhow::anyhow;
|
||||
|
||||
use crate::protocol::NetPacket;
|
||||
|
||||
pub fn simple_hash(input: &str) -> [u8; 32] {
|
||||
let mut result = [0u8; 32];
|
||||
let bytes = input.as_bytes();
|
||||
for (index, v) in result.iter_mut().enumerate() {
|
||||
*v = bytes[index % bytes.len()];
|
||||
}
|
||||
|
||||
let mut state = 0u8;
|
||||
|
||||
for (i, &byte) in bytes.iter().enumerate() {
|
||||
let combined = byte.wrapping_add(state).rotate_left((i % 8) as u32);
|
||||
result[i % 32] ^= combined;
|
||||
state = state.wrapping_add(byte).rotate_left(3);
|
||||
}
|
||||
|
||||
for i in 0..32 {
|
||||
result[i] = result[i]
|
||||
.rotate_left((result[(i + 1) % 32] % 8) as u32)
|
||||
.wrapping_add(state);
|
||||
state = state.wrapping_add(result[i]).rotate_left(3);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct XORCipher {
|
||||
key: [u8; 32],
|
||||
}
|
||||
|
||||
impl XORCipher {
|
||||
pub fn new_256(key: [u8; 32]) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
}
|
||||
|
||||
impl XORCipher {
|
||||
pub fn key(&self) -> &[u8] {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
impl XORCipher {
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(anyhow!("not encrypt"));
|
||||
}
|
||||
let key = &self.key;
|
||||
net_packet
|
||||
.payload_mut()
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(i, byte)| *byte = *byte ^ key[i & 31]);
|
||||
net_packet.set_encrypt_flag(false);
|
||||
Ok(())
|
||||
}
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||
&self,
|
||||
net_packet: &mut NetPacket<B>,
|
||||
) -> anyhow::Result<()> {
|
||||
net_packet.set_encrypt_flag(true);
|
||||
let key = &self.key;
|
||||
net_packet
|
||||
.payload_mut()
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(i, byte)| *byte = *byte ^ key[i & 31]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_xor() {
|
||||
let d = XORCipher::new_256(simple_hash("password"));
|
||||
let mut p = NetPacket::new_encrypt([0; 1000]).unwrap();
|
||||
let src = p.buffer().to_vec();
|
||||
d.encrypt_ipv4(&mut p).unwrap();
|
||||
d.decrypt_ipv4(&mut p).unwrap();
|
||||
assert_eq!(p.buffer(), &src)
|
||||
}
|
||||
Reference in New Issue
Block a user