diff --git a/src/eea3/stream_cipher.rs b/src/eea3/stream_cipher.rs index 7441b68..ce92483 100644 --- a/src/eea3/stream_cipher.rs +++ b/src/eea3/stream_cipher.rs @@ -1,6 +1,6 @@ use super::Eea3Keystream; -use crate::internal::stream_cipher::xor_to_vec; +use crate::internal::stream_cipher::xor_inplace; /// 128-EEA3 stream cipher /// ([EEA3-EIA3-specification](https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2019/05/EEA3_EIA3_specification_v1_8.pdf)) @@ -9,32 +9,25 @@ pub type Eea3StreamCipher = cipher::StreamCipherCoreWrapper; /// 128-EEA3: 3GPP confidentiality algorithm /// ([EEA3-EIA3-specification](https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2019/05/EEA3_EIA3_specification_v1_8.pdf)) /// -/// Input: -/// - count: 32bit counter -/// - bearer: 5bit carrier layer identification -/// - direction: 1bit transmission direction identification -/// - ck: 128bit confidentiality key -/// - length: 32bit bit length of plaintext information stream -/// - ibs: input bitstream -/// -/// Output: -/// - [`Vec`]: encrypted bit stream -/// -/// # Panics -/// + Panics if `length` is greater than the length of `ibs` times 8. -/// + Panics if `length` is greater than `usize::MAX`. -#[must_use] -pub fn eea3_encrypt( +/// ## Input +/// | name | size | description | +/// | --------- | -------- | ------------------------------------- | +/// | count | 32 bits | counter | +/// | bearer | 5 bits | carrier layer identification | +/// | direction | 1 bit | transmission direction identification | +/// | ck | 128 bits | confidentiality key | +/// | data | - | the bitstream | +/// | bitlen | - | bit length of the bitstream | +pub fn eea3_xor_inplace( count: u32, bearer: u8, direction: u8, ck: &[u8; 16], - length: u32, - ibs: &[u8], -) -> Vec { - let bitlen = usize::try_from(length).expect("bit length overflow"); + data: &mut [u8], + bitlen: usize, +) { let mut eea3 = Eea3Keystream::new(count, bearer, direction, ck); - xor_to_vec(&mut eea3, ibs, bitlen) + xor_inplace(&mut eea3, data, bitlen); } #[cfg(test)] @@ -217,8 +210,16 @@ mod tests { #[test] fn examples() { for x in ALL_EXAMPLES { - let obs = eea3_encrypt(x.count, x.bearer, x.direction, &x.ck, x.length, x.ibs); - assert_eq!(obs, x.obs); + let mut data = x.ibs.to_vec(); + eea3_xor_inplace( + x.count, + x.bearer, + x.direction, + &x.ck, + &mut data, + x.length as usize, + ); + assert_eq!(data, x.obs); } } @@ -226,6 +227,8 @@ mod tests { #[test] fn invalid_input() { let x = &EXAMPLE1; - let _ = eea3_encrypt(x.count, x.bearer, x.direction, &x.ck, x.length * 2, x.ibs); + let mut data = x.ibs.to_vec(); + let bitlen = x.length as usize * 2; + eea3_xor_inplace(x.count, x.bearer, x.direction, &x.ck, &mut data, bitlen); } } diff --git a/src/internal/stream_cipher.rs b/src/internal/stream_cipher.rs index 9ccb11f..503694a 100644 --- a/src/internal/stream_cipher.rs +++ b/src/internal/stream_cipher.rs @@ -28,9 +28,3 @@ pub fn xor_inplace(zuc: &mut impl Keystream, data: &mut [u8], bitlen data[i] = 0; } } - -pub fn xor_to_vec(zuc: &mut impl Keystream, ibs: &[u8], bitlen: usize) -> Vec { - let mut res = ibs.to_vec(); - xor_inplace(zuc, &mut res, bitlen); - res -} diff --git a/src/lib.rs b/src/lib.rs index 6a27727..aeec62c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,7 @@ pub mod zuc128 { pub use self::keystream::Zuc128Keystream; pub use self::mac::Zuc128Mac; - pub use self::stream_cipher::{zuc128_xor_encrypt, Zuc128StreamCipher}; + pub use self::stream_cipher::{zuc128_xor_inplace, Zuc128StreamCipher}; } pub mod zuc256 { @@ -60,7 +60,7 @@ pub mod eea3 { mod stream_cipher; pub use self::keystream::Eea3Keystream; - pub use self::stream_cipher::{eea3_encrypt, Eea3StreamCipher}; + pub use self::stream_cipher::{eea3_xor_inplace, Eea3StreamCipher}; } pub mod eia3 { diff --git a/src/zuc128/stream_cipher.rs b/src/zuc128/stream_cipher.rs index f85e983..e82c808 100644 --- a/src/zuc128/stream_cipher.rs +++ b/src/zuc128/stream_cipher.rs @@ -1,29 +1,22 @@ use super::Zuc128Keystream; -use crate::internal::stream_cipher::xor_to_vec; +use crate::internal::stream_cipher::xor_inplace; /// ZUC128 stream cipher /// ([GB/T 33133.1-2016](https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=8C41A3AEECCA52B5C0011C8010CF0715)) pub type Zuc128StreamCipher = cipher::StreamCipherCoreWrapper; -/// ZUC128 xor encryption algorithm +/// ZUC128 confidentiality algorithm /// ([GB/T 33133.2-2021](https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=5D3CBA3ADEC7989344BD1E63006EF2B3)) /// -/// Input: -/// - `ck`: 128bit confidentiality key -/// - `iv`: 128bit initial vector -/// - `length`: 32bit bit length of plaintext information stream -/// - `ibs`: input bitstream -/// -/// Output: -/// - [`Vec`]: encrypted bit stream -/// -/// # Panics -/// + Panics if `length` is greater than the length of `ibs` times 8. -/// + Panics if `length` is greater than `usize::MAX`. -#[must_use] -pub fn zuc128_xor_encrypt(ck: &[u8; 16], iv: &[u8; 16], length: u32, ibs: &[u8]) -> Vec { - let bitlen = usize::try_from(length).expect("bit length overflow"); +/// ## Input +/// | name | size | description | +/// | ------ | -------- | --------------------------- | +/// | ck | 128 bits | confidentiality key | +/// | iv | 128 bits | initial vector | +/// | data | - | the bitstream | +/// | bitlen | - | bit length of the bitstream | +pub fn zuc128_xor_inplace(ck: &[u8; 16], iv: &[u8; 16], data: &mut [u8], bitlen: usize) { let mut zuc = Zuc128Keystream::new(ck, iv); - xor_to_vec(&mut zuc, ibs, bitlen) + xor_inplace(&mut zuc, data, bitlen); }