feat: add zeroize and rename next to update
This commit is contained in:
@@ -7,5 +7,8 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = { version = "0.8.3", features = ["zeroize"] }
|
aes = { version = "0.8.3", features = ["zeroize"] }
|
||||||
aes-gcm = { version = "0.10.2", features = ["zeroize"] }
|
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
zeroize = { version = "1.6.0", features = ["zeroize_derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
aes-gcm = { version = "0.10.2", features = ["zeroize"] }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use aes::{Aes128, Aes192, Aes256};
|
use aes::{Aes128, Aes192, Aes256};
|
||||||
use aes::cipher::{Block, BlockEncrypt, KeyInit};
|
use aes::cipher::{Block, BlockEncrypt, KeyInit};
|
||||||
use aes::cipher::generic_array::GenericArray;
|
use aes::cipher::generic_array::GenericArray;
|
||||||
|
use zeroize::ZeroizeOnDrop;
|
||||||
|
|
||||||
use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128};
|
use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128};
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ macro_rules! define_aes_gcm_stream_decryptor_impl {
|
|||||||
$key_size:tt
|
$key_size:tt
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
|
#[derive(ZeroizeOnDrop)]
|
||||||
pub struct $module {
|
pub struct $module {
|
||||||
crypto: $aesn,
|
crypto: $aesn,
|
||||||
message_buffer: Vec<u8>,
|
message_buffer: Vec<u8>,
|
||||||
@@ -55,7 +57,7 @@ impl $module {
|
|||||||
self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]);
|
self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, bytes: &[u8]) -> Vec<u8> {
|
pub fn update(&mut self, bytes: &[u8]) -> Vec<u8> {
|
||||||
self.message_buffer.extend_from_slice(bytes);
|
self.message_buffer.extend_from_slice(bytes);
|
||||||
let message_buffer_slice = self.message_buffer.as_slice();
|
let message_buffer_slice = self.message_buffer.as_slice();
|
||||||
let message_buffer_len = message_buffer_slice.len();
|
let message_buffer_len = message_buffer_slice.len();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use aes::{Aes128, Aes192, Aes256};
|
use aes::{Aes128, Aes192, Aes256};
|
||||||
use aes::cipher::{Block, BlockEncrypt, KeyInit};
|
use aes::cipher::{Block, BlockEncrypt, KeyInit};
|
||||||
use aes::cipher::generic_array::GenericArray;
|
use aes::cipher::generic_array::GenericArray;
|
||||||
|
use zeroize::ZeroizeOnDrop;
|
||||||
|
|
||||||
use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128};
|
use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128};
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ macro_rules! define_aes_gcm_stream_encryptor_impl {
|
|||||||
$key_size:tt
|
$key_size:tt
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
|
#[derive(ZeroizeOnDrop)]
|
||||||
pub struct $module {
|
pub struct $module {
|
||||||
crypto: $aesn,
|
crypto: $aesn,
|
||||||
message_buffer: Vec<u8>,
|
message_buffer: Vec<u8>,
|
||||||
@@ -55,7 +57,7 @@ impl $module {
|
|||||||
self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]);
|
self.integrality_buffer.extend_from_slice(&vec![0x00; v / 8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, bytes: &[u8]) -> Vec<u8> {
|
pub fn update(&mut self, bytes: &[u8]) -> Vec<u8> {
|
||||||
self.message_buffer.extend_from_slice(bytes);
|
self.message_buffer.extend_from_slice(bytes);
|
||||||
let message_buffer_slice = self.message_buffer.as_slice();
|
let message_buffer_slice = self.message_buffer.as_slice();
|
||||||
let message_buffer_len = message_buffer_slice.len();
|
let message_buffer_len = message_buffer_slice.len();
|
||||||
|
|||||||
112
src/lib.rs
112
src/lib.rs
@@ -54,7 +54,7 @@ fn test128() {
|
|||||||
if !aad.is_empty() {
|
if !aad.is_empty() {
|
||||||
encryptor.init_adata(aad);
|
encryptor.init_adata(aad);
|
||||||
}
|
}
|
||||||
ciphertext.extend_from_slice(&encryptor.next(plaintext));
|
ciphertext.extend_from_slice(&encryptor.update(plaintext));
|
||||||
let (last_block, tag) = encryptor.finalize();
|
let (last_block, tag) = encryptor.finalize();
|
||||||
ciphertext.extend_from_slice(&last_block);
|
ciphertext.extend_from_slice(&last_block);
|
||||||
ciphertext.extend_from_slice(&tag);
|
ciphertext.extend_from_slice(&tag);
|
||||||
@@ -64,7 +64,7 @@ fn test128() {
|
|||||||
if !aad.is_empty() {
|
if !aad.is_empty() {
|
||||||
decryptor.init_adata(aad);
|
decryptor.init_adata(aad);
|
||||||
}
|
}
|
||||||
let mut plaintext1 = decryptor.next(ciphertext.as_slice());
|
let mut plaintext1 = decryptor.update(ciphertext.as_slice());
|
||||||
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
||||||
plaintext1.extend_from_slice(&plaintext2);
|
plaintext1.extend_from_slice(&plaintext2);
|
||||||
assert_eq!(plaintext, plaintext1.as_slice());
|
assert_eq!(plaintext, plaintext1.as_slice());
|
||||||
@@ -88,6 +88,67 @@ fn test128() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test192() {
|
||||||
|
let knp = vec![
|
||||||
|
([0; 24], [0; 12], &[] as &[u8], b"Hello World!" as &[u8]),
|
||||||
|
([0; 24], [0; 12], &[1; 16], b"Hello World!" as &[u8]),
|
||||||
|
([0; 24], [0; 12], &[1; 17], b"Hello World!" as &[u8]),
|
||||||
|
([0; 24], [0; 12], &[1; 32], b"Hello World!" as &[u8]),
|
||||||
|
([0; 24], [0; 12], &[1; 64], b"Hello World!" as &[u8]),
|
||||||
|
([0; 24], [0; 12], &[1, 2, 3], b"Hello World!" as &[u8]),
|
||||||
|
([1; 24], [0; 12], &[], b"Hello World!"),
|
||||||
|
([0; 24], [1; 12], &[], b"Hello World!"),
|
||||||
|
([1; 24], [1; 12], &[], b"Hello World ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!"),
|
||||||
|
([1; 24], [1; 12], &[0; 129], b"Hello World ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!"),
|
||||||
|
([0xff; 24], [0; 12], &[], b"Hello World!"),
|
||||||
|
([0; 24], [0xff; 12], &[], b"Hello World!"),
|
||||||
|
([0xff; 24], [0xff; 12], &[], b"Hello World ~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~!"),
|
||||||
|
([0xff; 24], [0xff; 12], &[11, 22, 33], b"Hello World ~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
|
||||||
|
~~~~~~~~~!"),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (key, nonce, aad, plaintext) in knp {
|
||||||
|
// encrypt
|
||||||
|
let mut ciphertext = vec![];
|
||||||
|
let mut encryptor = Aes192GcmStreamEncryptor::new(key.clone(), &nonce);
|
||||||
|
if !aad.is_empty() {
|
||||||
|
encryptor.init_adata(aad);
|
||||||
|
}
|
||||||
|
ciphertext.extend_from_slice(&encryptor.update(plaintext));
|
||||||
|
let (last_block, tag) = encryptor.finalize();
|
||||||
|
ciphertext.extend_from_slice(&last_block);
|
||||||
|
ciphertext.extend_from_slice(&tag);
|
||||||
|
|
||||||
|
// decrypt 1
|
||||||
|
let mut decryptor = Aes192GcmStreamDecryptor::new(key.clone(), &nonce);
|
||||||
|
if !aad.is_empty() {
|
||||||
|
decryptor.init_adata(aad);
|
||||||
|
}
|
||||||
|
let mut plaintext1 = decryptor.update(ciphertext.as_slice());
|
||||||
|
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
||||||
|
plaintext1.extend_from_slice(&plaintext2);
|
||||||
|
assert_eq!(plaintext, plaintext1.as_slice());
|
||||||
|
|
||||||
|
// ops, aes_gcm not supports AES192 bit keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test256() {
|
fn test256() {
|
||||||
use aes_gcm::{aead::{Aead, Nonce, Payload}, Aes256Gcm, KeyInit};
|
use aes_gcm::{aead::{Aead, Nonce, Payload}, Aes256Gcm, KeyInit};
|
||||||
@@ -132,7 +193,7 @@ fn test256() {
|
|||||||
if !aad.is_empty() {
|
if !aad.is_empty() {
|
||||||
encryptor.init_adata(aad);
|
encryptor.init_adata(aad);
|
||||||
}
|
}
|
||||||
ciphertext.extend_from_slice(&encryptor.next(plaintext));
|
ciphertext.extend_from_slice(&encryptor.update(plaintext));
|
||||||
let (last_block, tag) = encryptor.finalize();
|
let (last_block, tag) = encryptor.finalize();
|
||||||
ciphertext.extend_from_slice(&last_block);
|
ciphertext.extend_from_slice(&last_block);
|
||||||
ciphertext.extend_from_slice(&tag);
|
ciphertext.extend_from_slice(&tag);
|
||||||
@@ -142,7 +203,7 @@ fn test256() {
|
|||||||
if !aad.is_empty() {
|
if !aad.is_empty() {
|
||||||
decryptor.init_adata(aad);
|
decryptor.init_adata(aad);
|
||||||
}
|
}
|
||||||
let mut plaintext1 = decryptor.next(ciphertext.as_slice());
|
let mut plaintext1 = decryptor.update(ciphertext.as_slice());
|
||||||
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
||||||
plaintext1.extend_from_slice(&plaintext2);
|
plaintext1.extend_from_slice(&plaintext2);
|
||||||
assert_eq!(plaintext, plaintext1.as_slice());
|
assert_eq!(plaintext, plaintext1.as_slice());
|
||||||
@@ -164,4 +225,45 @@ fn test256() {
|
|||||||
};
|
};
|
||||||
assert_eq!(plaintext, decrypted_plaintext.as_slice());
|
assert_eq!(plaintext, decrypted_plaintext.as_slice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test256_stream() {
|
||||||
|
use aes_gcm::{aead::{Aead, Nonce}, Aes256Gcm, KeyInit};
|
||||||
|
let key = [0u8; 32];
|
||||||
|
let nonce = [0; 12];
|
||||||
|
|
||||||
|
let mut plaintext = vec![];
|
||||||
|
// encrypt
|
||||||
|
let mut ciphertext = vec![];
|
||||||
|
let mut encryptor = Aes256GcmStreamEncryptor::new(key.clone(), &nonce);
|
||||||
|
for i in 0..1024 {
|
||||||
|
plaintext.extend_from_slice(&[(i % 128) as u8]);
|
||||||
|
ciphertext.extend_from_slice(&encryptor.update(&[(i % 128) as u8]));
|
||||||
|
}
|
||||||
|
let (last_block, tag) = encryptor.finalize();
|
||||||
|
ciphertext.extend_from_slice(&last_block);
|
||||||
|
ciphertext.extend_from_slice(&tag);
|
||||||
|
|
||||||
|
|
||||||
|
// decrypt 1
|
||||||
|
let mut decryptor = Aes256GcmStreamDecryptor::new(key.clone(), &nonce);
|
||||||
|
let mut plaintext1 = vec![];
|
||||||
|
for i in 0..ciphertext.len() {
|
||||||
|
plaintext1.extend_from_slice(decryptor.update(
|
||||||
|
&[ciphertext.as_slice()[i]]).as_slice());
|
||||||
|
}
|
||||||
|
let plaintext2 = decryptor.finalize().expect("decryptor decrypt");
|
||||||
|
plaintext1.extend_from_slice(&plaintext2);
|
||||||
|
assert_eq!(plaintext, plaintext1.as_slice());
|
||||||
|
|
||||||
|
// decrypt 2
|
||||||
|
let cipher = Aes256Gcm::new_from_slice(&key).expect("new from key slice");
|
||||||
|
let mut decrypt_nonce = Nonce::<Aes256Gcm>::default();
|
||||||
|
let m: &mut [u8] = decrypt_nonce.as_mut();
|
||||||
|
for i in 0..m.len() {
|
||||||
|
m[i] = nonce[i];
|
||||||
|
}
|
||||||
|
let decrypted_plaintext = cipher.decrypt(&decrypt_nonce, ciphertext.as_slice()).expect("decrypt1");
|
||||||
|
assert_eq!(plaintext, decrypted_plaintext.as_slice());
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ pub(crate) fn gmul_128(x: u128, y: u128) -> u128 {
|
|||||||
|
|
||||||
pub(crate) fn ghash(key: u128, messages: &[u128]) -> u128 {
|
pub(crate) fn ghash(key: u128, messages: &[u128]) -> u128 {
|
||||||
let mut y = 0u128;
|
let mut y = 0u128;
|
||||||
for i in 0..messages.len() {
|
for message in messages {
|
||||||
let yi = gmul_128(y ^ messages[i], key);
|
let yi = gmul_128(y ^ message, key);
|
||||||
y = yi;
|
y = yi;
|
||||||
}
|
}
|
||||||
y
|
y
|
||||||
@@ -54,9 +54,7 @@ pub(crate) fn msb_s(s: usize, bytes: &[u8]) -> Vec<u8> {
|
|||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
let n = s / 8;
|
let n = s / 8;
|
||||||
let remain = s % 8;
|
let remain = s % 8;
|
||||||
for i in 0..n {
|
result.extend_from_slice(&bytes[0..n]);
|
||||||
result.push(bytes[i]);
|
|
||||||
}
|
|
||||||
if remain > 0 {
|
if remain > 0 {
|
||||||
result.push(bytes[n] >> (8 - remain));
|
result.push(bytes[n] >> (8 - remain));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user