Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 90 additions & 117 deletions deoxys/src/modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ where
let mut tag = Tag::default();
let mut checksum = Checksum::default();
let mut tweak = Tweak::default();
let buffer_len = buffer.len();

// Associated Data
<Self as DeoxysModeInternal<B>>::compute_ad_tag(
Expand All @@ -111,82 +110,68 @@ where
tweak[8] = nonce[7] << 4;

// Message authentication and encryption
if !buffer.is_empty() {
tweak[0] = (tweak[0] & 0xf) | TWEAK_M;

let (data_blocks, tail) = buffer.into_chunks();
let data_blocks_len = data_blocks.len();
tweak[0] = (tweak[0] & 0xf) | TWEAK_M;

for (index, data) in data_blocks.into_iter().enumerate() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
let (data_blocks, mut tail) = buffer.into_chunks();
let mut data_blocks_len = data_blocks.len();

for (c, d) in checksum.iter_mut().zip(data.get_in().iter()) {
*c ^= d;
}
for (index, data) in data_blocks.into_iter().enumerate() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

B::encrypt_inout(data, &tweak, subkeys);
for (c, d) in checksum.iter_mut().zip(data.get_in().iter()) {
*c ^= d;
}

let mut data = tail;
let index = data_blocks_len;
if !data.is_empty() {
// Last block, incomplete

// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

// Last block checksum
tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST;

let mut block = Block::default();
block[0..data.len()].copy_from_slice(data.get_in());

block[data.len()] = 0x80;

for (c, d) in checksum.iter_mut().zip(block.iter()) {
*c ^= d;
}

block.fill(0);

// Last block encryption
B::encrypt_inout((&mut block).into(), &tweak, subkeys);
B::encrypt_inout(data, &tweak, subkeys);
}

data.xor_in2out((block[..data.len()]).into());
// Process incomplete last block
if !tail.is_empty() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(data_blocks_len as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

// Tag computing.
tweak[0] = (tweak[0] & 0xf) | TWEAK_CHKSUM;
// Last block checksum
tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST;

let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&((index + 1) as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
let mut block = Block::default();
block[..tail.len()].copy_from_slice(tail.get_in());

B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);
block[tail.len()] = 0x80;

for (t, c) in tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}
for (c, d) in checksum.iter_mut().zip(block.iter()) {
*c ^= d;
}
}

if buffer_len % 16 == 0 {
// Tag computing without last block
tweak[0] = (tweak[0] & 0xf) | TWEAK_TAG;
block.fill(0);

let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&((buffer_len / 16) as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
// Last block encryption
B::encrypt_inout((&mut block).into(), &tweak, subkeys);

B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);
tail.xor_in2out((block[..tail.len()]).into());

for (t, c) in tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}
data_blocks_len += 1;
};

// Tag computing.
let t = if tail.is_empty() {
TWEAK_TAG
} else {
TWEAK_CHKSUM
};
tweak[0] = (tweak[0] & 0xf) | t;
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(data_blocks_len as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);
for (t, c) in tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}

tag
Expand All @@ -202,7 +187,6 @@ where
let mut computed_tag = Tag::default();
let mut checksum = Checksum::default();
let mut tweak = Tweak::default();
let buffer_len = buffer.len();

// Associated Data
<Self as DeoxysModeInternal<B>>::compute_ad_tag(
Expand All @@ -221,78 +205,67 @@ where
tweak[8] = nonce[7] << 4;

// Message authentication and encryption
if !buffer.is_empty() {
tweak[0] = (tweak[0] & 0xf) | TWEAK_M;

let (data_blocks, tail) = buffer.into_chunks();
let data_blocks_len = data_blocks.len();

for (index, mut data) in data_blocks.into_iter().enumerate() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

B::decrypt_inout(data.reborrow(), tweak.as_ref(), subkeys);

for (c, d) in checksum.iter_mut().zip(data.get_out().iter()) {
*c ^= d;
}
}
tweak[0] = (tweak[0] & 0xf) | TWEAK_M;

let mut data = tail;
let index = data_blocks_len;
if !data.is_empty() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
let (data_blocks, mut tail) = buffer.into_chunks();
let mut data_blocks_len = data_blocks.len();

// Last block checksum
tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST;
for (index, mut data) in data_blocks.into_iter().enumerate() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(index as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

let mut block = Block::default();
B::encrypt_inout((&mut block).into(), tweak.as_ref(), subkeys);
B::decrypt_inout(data.reborrow(), tweak.as_ref(), subkeys);

data.xor_in2out((block[..data.len()]).into());
for (c, d) in checksum.iter_mut().zip(data.get_out().iter()) {
*c ^= d;
}
}

block.fill(0);
// Process incomplete last block
if !tail.is_empty() {
// Copy block number
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(data_blocks_len as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

block[0..data.len()].copy_from_slice(data.get_out());
block[data.len()] = 0x80;
// Last block checksum
tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST;

for (c, d) in checksum.iter_mut().zip(block.iter()) {
*c ^= d;
}
let mut block = Block::default();
B::encrypt_inout((&mut block).into(), tweak.as_ref(), subkeys);

// Tag computing.
tweak[0] = (tweak[0] & 0xf) | TWEAK_CHKSUM;
tail.xor_in2out((block[..tail.len()]).into());

let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&((index + 1) as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
block.fill(0);

B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);
block[..tail.len()].copy_from_slice(tail.get_out());
block[tail.len()] = 0x80;

for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}
for (c, d) in checksum.iter_mut().zip(block.iter()) {
*c ^= d;
}
}

if buffer_len % 16 == 0 {
// Tag computing without last block
tweak[0] = (tweak[0] & 0xf) | TWEAK_TAG;
data_blocks_len += 1;
}

let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&((buffer_len / 16) as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;
// Tag computing.
let t = if tail.is_empty() {
TWEAK_TAG
} else {
TWEAK_CHKSUM
};
tweak[0] = (tweak[0] & 0xf) | t;
let tmp = tweak[8] & 0xf0;
tweak[8..].copy_from_slice(&(data_blocks_len as u64).to_be_bytes());
tweak[8] = (tweak[8] & 0xf) | tmp;

B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);
B::encrypt_inout((&mut checksum).into(), tweak.as_ref(), subkeys);

for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}
for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) {
*t ^= c;
}

if tag.ct_eq(&computed_tag).into() {
Expand Down