调整加密
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 aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
|
||||||
|
use anyhow::anyhow;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
|
||||||
use crate::cipher::Finger;
|
use crate::cipher::Finger;
|
||||||
@@ -50,14 +49,14 @@ impl AesCbcCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if net_packet.payload().len() < 16 {
|
||||||
log::error!("数据异常,长度{}小于{}", 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];
|
let mut iv = [0; 16];
|
||||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -75,7 +74,7 @@ impl AesCbcCipher {
|
|||||||
if let Some(finger) = &self.finger {
|
if let Some(finger) = &self.finger {
|
||||||
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body());
|
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body());
|
||||||
if &finger != secret_body.finger() {
|
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 {
|
let rs = match &self.cipher {
|
||||||
@@ -92,10 +91,7 @@ impl AesCbcCipher {
|
|||||||
net_packet.set_data_len(HEAD_LEN + len - 4)?;
|
net_packet.set_data_len(HEAD_LEN + len - 4)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("aes_cbc 解密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("解密失败:{}", e),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// net_packet 必须预留足够长度
|
/// net_packet 必须预留足够长度
|
||||||
@@ -103,7 +99,7 @@ impl AesCbcCipher {
|
|||||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let data_len = net_packet.data_len();
|
let data_len = net_packet.data_len();
|
||||||
let mut iv = [0; 16];
|
let mut iv = [0; 16];
|
||||||
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
iv[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -146,10 +142,7 @@ impl AesCbcCipher {
|
|||||||
net_packet.set_encrypt_flag(true);
|
net_packet.set_encrypt_flag(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("aes_cbc 加密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("加密失败:{}", 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 std::ptr;
|
||||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use openssl_sys::EVP_CIPHER_CTX;
|
use openssl_sys::EVP_CIPHER_CTX;
|
||||||
use std::{io, ptr};
|
|
||||||
|
use crate::cipher::Finger;
|
||||||
|
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||||
|
|
||||||
pub struct AesEcbCipher {
|
pub struct AesEcbCipher {
|
||||||
key: Vec<u8>,
|
key: Vec<u8>,
|
||||||
@@ -100,10 +103,10 @@ impl AesEcbCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if let Some(finger) = &self.finger {
|
||||||
@@ -116,18 +119,18 @@ impl AesEcbCipher {
|
|||||||
nonce_raw[11] = net_packet.source_ttl();
|
nonce_raw[11] = net_packet.source_ttl();
|
||||||
let len = net_packet.payload().len();
|
let len = net_packet.payload().len();
|
||||||
if len < 12 {
|
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 secret_body = &net_packet.payload()[..len - 12];
|
||||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||||
if &finger != &net_packet.payload()[len - 12..] {
|
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())?;
|
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||||
}
|
}
|
||||||
if net_packet.payload().len() < 16 {
|
if net_packet.payload().len() < 16 {
|
||||||
log::error!("数据异常,长度{}小于{}", 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 input = net_packet.payload();
|
||||||
let mut out = [0u8; 1024 * 5];
|
let mut out = [0u8; 1024 * 5];
|
||||||
@@ -147,22 +150,22 @@ impl AesEcbCipher {
|
|||||||
//校验头部
|
//校验头部
|
||||||
let src_net_packet = NetPacket::new(text)?;
|
let src_net_packet = NetPacket::new(text)?;
|
||||||
if src_net_packet.source() != net_packet.source() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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);
|
net_packet.set_encrypt_flag(false);
|
||||||
@@ -175,7 +178,7 @@ impl AesEcbCipher {
|
|||||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let input = net_packet.buffer();
|
let input = net_packet.buffer();
|
||||||
let mut out = [0u8; 1024 * 5];
|
let mut out = [0u8; 1024 * 5];
|
||||||
let mut out_len = 0;
|
let mut out_len = 0;
|
||||||
@@ -191,7 +194,7 @@ impl AesEcbCipher {
|
|||||||
}
|
}
|
||||||
let out_len = out_len as usize;
|
let out_len = out_len as usize;
|
||||||
if out_len == 0 {
|
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];
|
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::cipher::Finger;
|
||||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
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 Aes128EcbEnc = ecb::Encryptor<aes::Aes128>;
|
||||||
type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;
|
type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;
|
||||||
@@ -46,10 +47,10 @@ impl AesEcbCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if let Some(finger) = &self.finger {
|
||||||
@@ -62,18 +63,18 @@ impl AesEcbCipher {
|
|||||||
nonce_raw[11] = net_packet.source_ttl();
|
nonce_raw[11] = net_packet.source_ttl();
|
||||||
let len = net_packet.payload().len();
|
let len = net_packet.payload().len();
|
||||||
if len < 12 {
|
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 secret_body = &net_packet.payload()[..len - 12];
|
||||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||||
if &finger != &net_packet.payload()[len - 12..] {
|
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())?;
|
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||||
}
|
}
|
||||||
if net_packet.payload().len() < 16 {
|
if net_packet.payload().len() < 16 {
|
||||||
log::error!("数据异常,长度{}小于{}", 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 mut out = [0u8; 1024 * 5];
|
||||||
let rs = match self.key {
|
let rs = match self.key {
|
||||||
@@ -87,32 +88,29 @@ impl AesEcbCipher {
|
|||||||
//校验头部
|
//校验头部
|
||||||
let src_net_packet = NetPacket::new(buf)?;
|
let src_net_packet = NetPacket::new(buf)?;
|
||||||
if src_net_packet.source() != net_packet.source() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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_data_len(buf.len())?;
|
||||||
net_packet.set_payload(src_net_packet.payload())?;
|
net_packet.set_payload(src_net_packet.payload())?;
|
||||||
net_packet.set_encrypt_flag(false);
|
net_packet.set_encrypt_flag(false);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("aes_ecb解密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("aes_ecb解密失败:{}", e),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// net_packet 必须预留足够长度
|
/// net_packet 必须预留足够长度
|
||||||
@@ -120,7 +118,7 @@ impl AesEcbCipher {
|
|||||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut out = [0u8; 1024 * 5];
|
let mut out = [0u8; 1024 * 5];
|
||||||
let rs = match self.key {
|
let rs = match self.key {
|
||||||
AesEcbEnum::AES128ECB(key) => Aes128EcbEnc::new(&key.into())
|
AesEcbEnum::AES128ECB(key) => Aes128EcbEnc::new(&key.into())
|
||||||
@@ -152,10 +150,7 @@ impl AesEcbCipher {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("aes_ecb加密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("aes_ecb加密失败:{}", e),
|
|
||||||
)),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
use std::io;
|
|
||||||
|
|
||||||
use aes_gcm::aead::consts::{U12, U16};
|
use aes_gcm::aead::consts::{U12, U16};
|
||||||
use aes_gcm::aead::generic_array::GenericArray;
|
use aes_gcm::aead::generic_array::GenericArray;
|
||||||
use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, Tag};
|
use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, Tag};
|
||||||
|
use anyhow::anyhow;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
|
||||||
use crate::cipher::finger::Finger;
|
use crate::cipher::finger::Finger;
|
||||||
@@ -39,14 +38,14 @@ impl AesGcmCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||||
log::error!("数据异常,长度小于{}", 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];
|
let mut nonce_raw = [0; 12];
|
||||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -62,7 +61,7 @@ impl AesGcmCipher {
|
|||||||
if let Some(finger) = &self.finger {
|
if let Some(finger) = &self.finger {
|
||||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||||
if &finger != secret_body.finger() {
|
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);
|
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(tag);
|
||||||
@@ -75,10 +74,7 @@ impl AesGcmCipher {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Err(e) = rs {
|
if let Err(e) = rs {
|
||||||
return Err(io::Error::new(
|
return Err(anyhow!("解密失败:{}", e));
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("解密失败:{}", e),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
net_packet.set_encrypt_flag(false);
|
net_packet.set_encrypt_flag(false);
|
||||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
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]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if net_packet.reserve() < AES_GCM_ENCRYPTION_RESERVED {
|
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];
|
let mut nonce_raw = [0; 12];
|
||||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -123,10 +119,7 @@ impl AesGcmCipher {
|
|||||||
net_packet.set_encrypt_flag(true);
|
net_packet.set_encrypt_flag(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("加密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("加密失败:{}", 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 rand::RngCore;
|
||||||
use ring::aead;
|
use ring::aead;
|
||||||
use ring::aead::{LessSafeKey, UnboundKey};
|
use ring::aead::{LessSafeKey, UnboundKey};
|
||||||
use std::io;
|
|
||||||
|
|
||||||
|
use crate::cipher::Finger;
|
||||||
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
|
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
|
||||||
use crate::protocol::NetPacket;
|
use crate::protocol::NetPacket;
|
||||||
|
|
||||||
@@ -53,14 +53,14 @@ impl AesGcmCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED {
|
||||||
log::error!("数据异常,长度小于{}", 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];
|
let mut nonce_raw = [0; 12];
|
||||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -74,7 +74,7 @@ impl AesGcmCipher {
|
|||||||
if let Some(finger) = &self.finger {
|
if let Some(finger) = &self.finger {
|
||||||
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body());
|
||||||
if &finger != secret_body.finger() {
|
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 {
|
if let Err(e) = rs {
|
||||||
return Err(io::Error::new(
|
return Err(anyhow!("解密失败:{}", e));
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("解密失败:{}", e),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
net_packet.set_encrypt_flag(false);
|
net_packet.set_encrypt_flag(false);
|
||||||
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?;
|
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]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut nonce_raw = [0; 12];
|
let mut nonce_raw = [0; 12];
|
||||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||||
@@ -128,10 +125,7 @@ impl AesGcmCipher {
|
|||||||
Ok(tag) => {
|
Ok(tag) => {
|
||||||
let tag = tag.as_ref();
|
let tag = tag.as_ref();
|
||||||
if tag.len() != 16 {
|
if tag.len() != 16 {
|
||||||
return Err(io::Error::new(
|
return Err(anyhow!("加密tag长度错误:{}", tag.len()));
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("加密tag长度错误:{}", tag.len()),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
secret_body.set_tag(tag)?;
|
secret_body.set_tag(tag)?;
|
||||||
if let Some(finger) = &self.finger {
|
if let Some(finger) = &self.finger {
|
||||||
@@ -141,10 +135,7 @@ impl AesGcmCipher {
|
|||||||
net_packet.set_encrypt_flag(true);
|
net_packet.set_encrypt_flag(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("加密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("加密失败:{}", 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::fmt::Display;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
#[cfg(cipher)]
|
||||||
|
use sha2::Digest;
|
||||||
|
|
||||||
#[cfg(feature = "aes_cbc")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
use crate::cipher::aes_cbc::AesCbcCipher;
|
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(feature = "aes_ecb")]
|
||||||
#[cfg(any(feature = "openssl-vendored", feature = "openssl"))]
|
use crate::cipher::aes_ecb::AesEcbCipher;
|
||||||
use crate::cipher::openssl_aes_ecb::AesEcbCipher;
|
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
#[cfg(feature = "ring-cipher")]
|
use crate::cipher::aes_gcm::AesGcmCipher;
|
||||||
use crate::cipher::ring_aes_gcm_cipher::AesGcmCipher;
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
use crate::cipher::chacha20::ChaCha20Cipher;
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
use crate::cipher::chacha20_poly1305::ChaCha20Poly1305Cipher;
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
use crate::cipher::sm4_cbc::Sm4CbcCipher;
|
use crate::cipher::sm4_cbc::Sm4CbcCipher;
|
||||||
#[cfg(any(
|
use crate::cipher::xor::XORCipher;
|
||||||
feature = "aes_gcm",
|
#[cfg(cipher)]
|
||||||
feature = "server_encrypt",
|
|
||||||
feature = "aes_cbc",
|
|
||||||
feature = "aes_ecb",
|
|
||||||
feature = "sm4_cbc"
|
|
||||||
))]
|
|
||||||
use crate::cipher::Finger;
|
use crate::cipher::Finger;
|
||||||
use crate::protocol::NetPacket;
|
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)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum CipherModel {
|
pub enum CipherModel {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
AesGcm,
|
AesGcm,
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
Chacha20Poly1305,
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
Chacha20,
|
||||||
#[cfg(feature = "aes_cbc")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
AesCbc,
|
AesCbc,
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
AesEcb,
|
AesEcb,
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
Sm4Cbc,
|
Sm4Cbc,
|
||||||
|
Xor,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,61 +45,55 @@ impl Display for CipherModel {
|
|||||||
let str = match self {
|
let str = match self {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
CipherModel::AesGcm => "aes_gcm".to_string(),
|
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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
CipherModel::AesCbc => "aes_cbc".to_string(),
|
CipherModel::AesCbc => "aes_cbc".to_string(),
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
CipherModel::AesEcb => "aes_ecb".to_string(),
|
CipherModel::AesEcb => "aes_ecb".to_string(),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
CipherModel::Sm4Cbc => "sm4_cbc".to_string(),
|
CipherModel::Sm4Cbc => "sm4_cbc".to_string(),
|
||||||
|
CipherModel::Xor => "xor".to_string(),
|
||||||
CipherModel::None => "none".to_string(),
|
CipherModel::None => "none".to_string(),
|
||||||
};
|
};
|
||||||
write!(f, "{}", str)
|
write!(f, "{}", str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for CipherModel {
|
impl FromStr for CipherModel {
|
||||||
type Err = String;
|
type Err = String;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
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() {
|
match s.to_lowercase().trim() {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
"aes_gcm" => Ok(CipherModel::AesGcm),
|
"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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
"aes_cbc" => Ok(CipherModel::AesCbc),
|
"aes_cbc" => Ok(CipherModel::AesCbc),
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
"aes_ecb" => Ok(CipherModel::AesEcb),
|
"aes_ecb" => Ok(CipherModel::AesEcb),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
"sm4_cbc" => Ok(CipherModel::Sm4Cbc),
|
"sm4_cbc" => Ok(CipherModel::Sm4Cbc),
|
||||||
|
"xor" => Ok(CipherModel::Xor),
|
||||||
_ => {
|
_ => {
|
||||||
let mut enums = String::new();
|
let mut enums = String::new();
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
enums.push_str("/aes_gcm");
|
enums.push_str("/aes_gcm");
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
enums.push_str("/chacha20_poly1305/chacha20");
|
||||||
#[cfg(feature = "aes_cbc")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
enums.push_str("/aes_cbc");
|
enums.push_str("/aes_cbc");
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
enums.push_str("/aes_ecb");
|
enums.push_str("/aes_ecb");
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
enums.push_str("/sm4_cbc");
|
enums.push_str("/sm4_cbc");
|
||||||
let str = if enums.is_empty() {
|
enums.push_str("/xor");
|
||||||
"no encrypt"
|
Err(format!("not match '{}', enum:{}", s, &enums[1..]))
|
||||||
} else {
|
|
||||||
&enums[1..]
|
|
||||||
};
|
|
||||||
Err(format!("not match '{}', enum:{}", s, str))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,49 +103,37 @@ impl FromStr for CipherModel {
|
|||||||
pub enum Cipher {
|
pub enum Cipher {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
AesGcm((AesGcmCipher, Vec<u8>)),
|
AesGcm((AesGcmCipher, Vec<u8>)),
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
Chacha20Poly1305(ChaCha20Poly1305Cipher),
|
||||||
|
#[cfg(feature = "chacha20_poly1305")]
|
||||||
|
Chacha20(ChaCha20Cipher),
|
||||||
#[cfg(feature = "aes_cbc")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
AesCbc(AesCbcCipher),
|
AesCbc(AesCbcCipher),
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
AesEcb(AesEcbCipher),
|
AesEcb(AesEcbCipher),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
Sm4Cbc(Sm4CbcCipher),
|
Sm4Cbc(Sm4CbcCipher),
|
||||||
|
Xor(XORCipher),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cipher {
|
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(
|
pub fn new_password(
|
||||||
model: CipherModel,
|
model: CipherModel,
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
token: Option<String>,
|
token: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let finger = token.map(|token| Finger::new(&token));
|
|
||||||
if let Some(password) = password {
|
if let Some(password) = password {
|
||||||
let mut hasher = sha2::Sha256::new();
|
#[cfg(cipher)]
|
||||||
hasher.update(password.as_bytes());
|
let key: [u8; 32] = {
|
||||||
let key: [u8; 32] = hasher.finalize().into();
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(password.as_bytes());
|
||||||
|
hasher.finalize().into()
|
||||||
|
};
|
||||||
match model {
|
match model {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
CipherModel::AesGcm => {
|
CipherModel::AesGcm => {
|
||||||
|
let finger = token.map(|token| Finger::new(&token));
|
||||||
if password.len() < 8 {
|
if password.len() < 8 {
|
||||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||||
Cipher::AesGcm((aes, key[..16].to_vec()))
|
Cipher::AesGcm((aes, key[..16].to_vec()))
|
||||||
@@ -169,8 +142,21 @@ impl Cipher {
|
|||||||
Cipher::AesGcm((aes, key.to_vec()))
|
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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
CipherModel::AesCbc => {
|
CipherModel::AesCbc => {
|
||||||
|
let finger = token.map(|token| Finger::new(&token));
|
||||||
if password.len() < 8 {
|
if password.len() < 8 {
|
||||||
let aes = AesCbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
let aes = AesCbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||||
Cipher::AesCbc(aes)
|
Cipher::AesCbc(aes)
|
||||||
@@ -181,6 +167,7 @@ impl Cipher {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
CipherModel::AesEcb => {
|
CipherModel::AesEcb => {
|
||||||
|
let finger = token.map(|token| Finger::new(&token));
|
||||||
if password.len() < 8 {
|
if password.len() < 8 {
|
||||||
let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger);
|
let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||||
Cipher::AesEcb(aes)
|
Cipher::AesEcb(aes)
|
||||||
@@ -191,126 +178,97 @@ impl Cipher {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
CipherModel::Sm4Cbc => {
|
CipherModel::Sm4Cbc => {
|
||||||
|
let finger = token.map(|token| Finger::new(&token));
|
||||||
let aes = Sm4CbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
let aes = Sm4CbcCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||||
Cipher::Sm4Cbc(aes)
|
Cipher::Sm4Cbc(aes)
|
||||||
}
|
}
|
||||||
|
CipherModel::Xor => {
|
||||||
|
let _token = token;
|
||||||
|
Cipher::Xor(XORCipher::new_256(crate::cipher::xor::simple_hash(
|
||||||
|
&password,
|
||||||
|
)))
|
||||||
|
}
|
||||||
CipherModel::None => Cipher::None,
|
CipherModel::None => Cipher::None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Cipher::None
|
Cipher::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(feature = "aes_gcm", feature = "server_encrypt")))]
|
||||||
feature = "aes_gcm",
|
pub fn new_key(_key: [u8; 32], _token: String) -> anyhow::Result<Self> {
|
||||||
feature = "server_encrypt",
|
Err(anyhow!("key error"))
|
||||||
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(any(
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
feature = "aes_gcm",
|
pub fn new_key(key: [u8; 32], token: String) -> anyhow::Result<Self> {
|
||||||
feature = "server_encrypt",
|
|
||||||
feature = "aes_cbc",
|
|
||||||
feature = "aes_ecb",
|
|
||||||
feature = "sm4_cbc"
|
|
||||||
))]
|
|
||||||
pub fn new_key(key: [u8; 32], token: String) -> io::Result<Self> {
|
|
||||||
let finger = Some(Finger::new(&token));
|
let finger = Some(Finger::new(&token));
|
||||||
match key.len() {
|
match key.len() {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
|
||||||
16 => {
|
16 => {
|
||||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||||
Ok(Cipher::AesGcm((aes, key[..16].to_vec())))
|
Ok(Cipher::AesGcm((aes, key[..16].to_vec())))
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
|
||||||
32 => {
|
32 => {
|
||||||
let aes = AesGcmCipher::new_256(key, finger);
|
let aes = AesGcmCipher::new_256(key, finger);
|
||||||
Ok(Cipher::AesGcm((aes, key.to_vec())))
|
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]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm.decrypt_ipv4(net_packet),
|
Cipher::AesGcm((aes_gcm, _)) => aes_gcm.decrypt_ipv4(net_packet),
|
||||||
#[cfg(feature = "aes_cbc")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
Cipher::AesCbc(aes_cbc) => aes_cbc.decrypt_ipv4(net_packet),
|
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")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
Cipher::AesEcb(aes_ecb) => aes_ecb.decrypt_ipv4(net_packet),
|
Cipher::AesEcb(aes_ecb) => aes_ecb.decrypt_ipv4(net_packet),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.decrypt_ipv4(net_packet),
|
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.decrypt_ipv4(net_packet),
|
||||||
|
Cipher::Xor(xor) => xor.decrypt_ipv4(net_packet),
|
||||||
Cipher::None => {
|
Cipher::None => {
|
||||||
if net_packet.is_encrypt() {
|
if net_packet.is_encrypt() {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "not key"));
|
return Err(anyhow!("not key"));
|
||||||
}
|
}
|
||||||
Ok(())
|
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]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm.encrypt_ipv4(net_packet),
|
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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
Cipher::AesCbc(aes_cbc) => aes_cbc.encrypt_ipv4(net_packet),
|
Cipher::AesCbc(aes_cbc) => aes_cbc.encrypt_ipv4(net_packet),
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
Cipher::AesEcb(aes_ecb) => aes_ecb.encrypt_ipv4(net_packet),
|
Cipher::AesEcb(aes_ecb) => aes_ecb.encrypt_ipv4(net_packet),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.encrypt_ipv4(net_packet),
|
Cipher::Sm4Cbc(sm4_cbc) => sm4_cbc.encrypt_ipv4(net_packet),
|
||||||
|
Cipher::Xor(xor) => xor.encrypt_ipv4(net_packet),
|
||||||
Cipher::None => Ok(()),
|
Cipher::None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(any(
|
#[cfg(not(cipher))]
|
||||||
feature = "aes_gcm",
|
|
||||||
feature = "server_encrypt",
|
|
||||||
feature = "aes_cbc",
|
|
||||||
feature = "aes_ecb",
|
|
||||||
feature = "sm4_cbc"
|
|
||||||
)))]
|
|
||||||
pub fn check_finger<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn check_finger<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
_net_packet: &NetPacket<B>,
|
_net_packet: &NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(any(
|
#[cfg(cipher)]
|
||||||
feature = "aes_gcm",
|
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> anyhow::Result<()> {
|
||||||
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<()> {
|
|
||||||
match self {
|
match self {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
Cipher::AesGcm((aes_gcm, _)) => aes_gcm
|
Cipher::AesGcm((aes_gcm, _)) => aes_gcm
|
||||||
@@ -318,6 +276,18 @@ impl Cipher {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.check_finger(net_packet))
|
.map(|f| f.check_finger(net_packet))
|
||||||
.unwrap_or(Ok(())),
|
.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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
Cipher::AesCbc(aes_cbc) => aes_cbc
|
Cipher::AesCbc(aes_cbc) => aes_cbc
|
||||||
.finger
|
.finger
|
||||||
@@ -336,6 +306,7 @@ impl Cipher {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.check_finger(net_packet))
|
.map(|f| f.check_finger(net_packet))
|
||||||
.unwrap_or(Ok(())),
|
.unwrap_or(Ok(())),
|
||||||
|
Cipher::Xor(_) => Ok(()),
|
||||||
Cipher::None => Ok(()),
|
Cipher::None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,12 +314,17 @@ impl Cipher {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
|
||||||
Cipher::AesGcm((_, key)) => Some(key),
|
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")]
|
#[cfg(feature = "aes_cbc")]
|
||||||
Cipher::AesCbc(aes_cbc) => Some(aes_cbc.key()),
|
Cipher::AesCbc(aes_cbc) => Some(aes_cbc.key()),
|
||||||
#[cfg(feature = "aes_ecb")]
|
#[cfg(feature = "aes_ecb")]
|
||||||
Cipher::AesEcb(aes_ecb) => Some(aes_ecb.key()),
|
Cipher::AesEcb(aes_ecb) => Some(aes_ecb.key()),
|
||||||
#[cfg(feature = "sm4_cbc")]
|
#[cfg(feature = "sm4_cbc")]
|
||||||
Cipher::Sm4Cbc(sm4_cbc) => Some(sm4_cbc.key()),
|
Cipher::Sm4Cbc(sm4_cbc) => Some(sm4_cbc.key()),
|
||||||
|
Cipher::Xor(xor) => Some(xor.key()),
|
||||||
Cipher::None => None,
|
Cipher::None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
|
||||||
@@ -16,15 +16,15 @@ impl Finger {
|
|||||||
let hash: [u8; 32] = hasher.finalize().into();
|
let hash: [u8; 32] = hasher.finalize().into();
|
||||||
Finger { hash }
|
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() {
|
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();
|
let payload_len = net_packet.payload().len();
|
||||||
if payload_len < 12 {
|
if payload_len < 12 {
|
||||||
log::error!("数据异常,长度小于{}", 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];
|
let mut nonce_raw = [0; 12];
|
||||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
@@ -36,7 +36,7 @@ impl Finger {
|
|||||||
let payload = net_packet.payload();
|
let payload = net_packet.payload();
|
||||||
let finger = self.calculate_finger(&nonce_raw, &payload[..payload_len - 12]);
|
let finger = self.calculate_finger(&nonce_raw, &payload[..payload_len - 12]);
|
||||||
if &finger[..] != &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(())
|
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;
|
mod cipher;
|
||||||
#[cfg(any(
|
#[cfg(cipher)]
|
||||||
feature = "aes_gcm",
|
|
||||||
feature = "server_encrypt",
|
|
||||||
feature = "aes_cbc",
|
|
||||||
feature = "aes_ecb",
|
|
||||||
feature = "sm4_cbc"
|
|
||||||
))]
|
|
||||||
mod finger;
|
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::Cipher;
|
||||||
pub use cipher::CipherModel;
|
pub use cipher::CipherModel;
|
||||||
#[cfg(any(
|
#[cfg(cipher)]
|
||||||
feature = "aes_gcm",
|
|
||||||
feature = "server_encrypt",
|
|
||||||
feature = "aes_cbc",
|
|
||||||
feature = "aes_ecb",
|
|
||||||
feature = "sm4_cbc"
|
|
||||||
))]
|
|
||||||
pub use finger::Finger;
|
pub use finger::Finger;
|
||||||
#[cfg(feature = "server_encrypt")]
|
#[cfg(feature = "server_encrypt")]
|
||||||
mod rsa_cipher;
|
mod rsa_cipher;
|
||||||
#[cfg(feature = "server_encrypt")]
|
#[cfg(feature = "server_encrypt")]
|
||||||
pub use rsa_cipher::RsaCipher;
|
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::cipher::Finger;
|
||||||
use crate::protocol::{NetPacket, HEAD_LEN};
|
use crate::protocol::{NetPacket, HEAD_LEN};
|
||||||
|
use anyhow::anyhow;
|
||||||
use libsm::sm4::cipher_mode::CipherMode;
|
use libsm::sm4::cipher_mode::CipherMode;
|
||||||
use libsm::sm4::Sm4CipherMode;
|
use libsm::sm4::Sm4CipherMode;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use std::io;
|
|
||||||
|
|
||||||
pub struct Sm4CbcCipher {
|
pub struct Sm4CbcCipher {
|
||||||
key: [u8; 16],
|
key: [u8; 16],
|
||||||
@@ -41,10 +41,10 @@ impl Sm4CbcCipher {
|
|||||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !net_packet.is_encrypt() {
|
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 {
|
if let Some(finger) = &self.finger {
|
||||||
@@ -57,12 +57,12 @@ impl Sm4CbcCipher {
|
|||||||
nonce_raw[11] = net_packet.source_ttl();
|
nonce_raw[11] = net_packet.source_ttl();
|
||||||
let len = net_packet.payload().len();
|
let len = net_packet.payload().len();
|
||||||
if len < 12 {
|
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 secret_body = &net_packet.payload()[..len - 12];
|
||||||
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
let finger = finger.calculate_finger(&nonce_raw, secret_body);
|
||||||
if &finger != &net_packet.payload()[len - 12..] {
|
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())?;
|
net_packet.set_data_len(net_packet.data_len() - finger.len())?;
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ impl Sm4CbcCipher {
|
|||||||
let len = payload.len();
|
let len = payload.len();
|
||||||
if len < 16 || len > 1024 * 4 {
|
if len < 16 || len > 1024 * 4 {
|
||||||
log::error!("数据异常,长度{}小于16或大于4096", len);
|
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 mut out = [0u8; 1024 * 4];
|
||||||
let data = &payload[..len - 16];
|
let data = &payload[..len - 16];
|
||||||
@@ -79,32 +79,29 @@ impl Sm4CbcCipher {
|
|||||||
Ok(len) => {
|
Ok(len) => {
|
||||||
let src_net_packet = NetPacket::new(&out[..len])?;
|
let src_net_packet = NetPacket::new(&out[..len])?;
|
||||||
if src_net_packet.source() != net_packet.source() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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_data_len(len)?;
|
||||||
net_packet.set_payload(src_net_packet.payload())?;
|
net_packet.set_payload(src_net_packet.payload())?;
|
||||||
net_packet.set_encrypt_flag(false);
|
net_packet.set_encrypt_flag(false);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("sm4_cbc解密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("sm4_cbc解密失败:{}", e),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// net_packet 必须预留足够长度
|
/// net_packet 必须预留足够长度
|
||||||
@@ -112,7 +109,7 @@ impl Sm4CbcCipher {
|
|||||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
net_packet: &mut NetPacket<B>,
|
net_packet: &mut NetPacket<B>,
|
||||||
) -> io::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut out = [0u8; 1024 * 4];
|
let mut out = [0u8; 1024 * 4];
|
||||||
let mut iv = [0u8; 16];
|
let mut iv = [0u8; 16];
|
||||||
rand::thread_rng().fill_bytes(&mut iv);
|
rand::thread_rng().fill_bytes(&mut iv);
|
||||||
@@ -121,7 +118,7 @@ impl Sm4CbcCipher {
|
|||||||
"数据异常,长度{}大于1024 * 4 - 32",
|
"数据异常,长度{}大于1024 * 4 - 32",
|
||||||
net_packet.buffer().len()
|
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) {
|
match self.cipher.encrypt(net_packet.buffer(), &iv, &mut out) {
|
||||||
Ok(len) => {
|
Ok(len) => {
|
||||||
@@ -146,10 +143,7 @@ impl Sm4CbcCipher {
|
|||||||
net_packet.set_encrypt_flag(true);
|
net_packet.set_encrypt_flag(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(io::Error::new(
|
Err(e) => Err(anyhow!("sm4_cbc加密失败:{}", e)),
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("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