Skip to content

Commit

Permalink
Propagate errors arisin mostly from internal updates of states
Browse files Browse the repository at this point in the history
  • Loading branch information
brycx committed Dec 29, 2018
1 parent 78d33fc commit 878ffb7
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 55 deletions.
24 changes: 10 additions & 14 deletions src/hazardous/aead/chacha20poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,17 @@ fn process_authentication(

let mut padding_max = [0u8; 16];

poly1305_state.update(ad).unwrap();
poly1305_state.update(&padding_max[..padding(ad)]).unwrap();
poly1305_state.update(&buf[..buf_in_len]).unwrap();
poly1305_state
.update(&padding_max[..padding(&buf[..buf_in_len])])
.unwrap();
poly1305_state.update(ad)?;
poly1305_state.update(&padding_max[..padding(ad)])?;
poly1305_state.update(&buf[..buf_in_len])?;
poly1305_state.update(&padding_max[..padding(&buf[..buf_in_len])])?;

// Using the 16 bytes from padding template to store length information
LittleEndian::write_u64(&mut padding_max[..8], ad.len() as u64);
LittleEndian::write_u64(&mut padding_max[8..16], buf_in_len as u64);

poly1305_state.update(&padding_max[..8]).unwrap();
poly1305_state.update(&padding_max[8..16]).unwrap();
poly1305_state.update(&padding_max[..8])?;
poly1305_state.update(&padding_max[8..16])?;

Ok(())
}
Expand Down Expand Up @@ -196,9 +194,8 @@ pub fn seal(
)?;
let mut poly1305_state = poly1305::init(&poly1305_key);

process_authentication(&mut poly1305_state, &optional_ad, &dst_out, plaintext.len()).unwrap();
dst_out[plaintext.len()..]
.copy_from_slice(&poly1305_state.finalize().unwrap().unprotected_as_bytes());
process_authentication(&mut poly1305_state, &optional_ad, &dst_out, plaintext.len())?;
dst_out[plaintext.len()..].copy_from_slice(&poly1305_state.finalize()?.unprotected_as_bytes());

Ok(())
}
Expand Down Expand Up @@ -233,11 +230,10 @@ pub fn open(
&optional_ad,
ciphertext_with_tag,
ciphertext_len,
)
.unwrap();
)?;

util::secure_cmp(
&poly1305_state.finalize().unwrap().unprotected_as_bytes(),
&poly1305_state.finalize()?.unprotected_as_bytes(),
&ciphertext_with_tag[ciphertext_len..],
)?;

Expand Down
8 changes: 4 additions & 4 deletions src/hazardous/aead/xchacha20poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ pub fn seal(
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let subkey: SecretKey =
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?).unwrap();
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?)?;
let mut prefixed_nonce = [0u8; IETF_CHACHA_NONCESIZE];
prefixed_nonce[4..IETF_CHACHA_NONCESIZE].copy_from_slice(&nonce.as_bytes()[16..24]);

chacha20poly1305::seal(
&subkey,
&IETFNonce::from_slice(&prefixed_nonce).unwrap(),
&IETFNonce::from_slice(&prefixed_nonce)?,
plaintext,
ad,
dst_out,
Expand All @@ -132,13 +132,13 @@ pub fn open(
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let subkey: SecretKey =
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?).unwrap();
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?)?;
let mut prefixed_nonce = [0u8; 12];
prefixed_nonce[4..12].copy_from_slice(&nonce.as_bytes()[16..24]);

chacha20poly1305::open(
&subkey,
&IETFNonce::from_slice(&prefixed_nonce).unwrap(),
&IETFNonce::from_slice(&prefixed_nonce)?,
ciphertext_with_tag,
ad,
dst_out,
Expand Down
4 changes: 2 additions & 2 deletions src/hazardous/hash/blake2b.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
//! - `update()` is called after `finalize()` without a `reset()` in between.
//! - `reset()` is called with `Some(secret_key)` but the struct was initialized
//! with `None`.
//! - `reset()` is called with `None` as `secret_key` but the struct was initialized
//! with `Some(secret_key)`.
//! - `reset()` is called with `None` as `secret_key` but the struct was
//! initialized with `Some(secret_key)`.
//!
//! # Security:
//! - The secret key should always be generated using a CSPRNG.
Expand Down
8 changes: 4 additions & 4 deletions src/hazardous/kdf/hkdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ pub fn expand(
for (idx, hlen_block) in dst_out.chunks_mut(HLEN).enumerate() {
let block_len = hlen_block.len();

hmac.update(optional_info).unwrap();
hmac.update(&[idx as u8 + 1_u8]).unwrap();
hlen_block.copy_from_slice(&hmac.finalize().unwrap().unprotected_as_bytes()[..block_len]);
hmac.update(optional_info)?;
hmac.update(&[idx as u8 + 1_u8])?;
hlen_block.copy_from_slice(&hmac.finalize()?.unprotected_as_bytes()[..block_len]);

// Check if it's the last iteration, if yes don't process anything
if block_len < HLEN || (block_len * (idx + 1) == okm_len) {
break;
} else {
hmac.reset();
hmac.update(&hlen_block).unwrap();
hmac.update(&hlen_block)?;
}
}

Expand Down
17 changes: 10 additions & 7 deletions src/hazardous/kdf/pbkdf2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,27 +91,29 @@ fn function_f(
dk_block: &mut [u8],
block_len: usize,
hmac: &mut hmac::Hmac,
) {
) -> Result<(), UnknownCryptoError> {
let mut u_step: HLenArray = [0u8; 64];
// First 4 bytes used for index BE conversion
BigEndian::write_u32(&mut u_step[..4], index);
hmac.update(salt).unwrap();
hmac.update(&u_step[..4]).unwrap();
hmac.update(salt)?;
hmac.update(&u_step[..4])?;

u_step.copy_from_slice(&hmac.finalize().unwrap().unprotected_as_bytes());
u_step.copy_from_slice(&hmac.finalize()?.unprotected_as_bytes());
dk_block.copy_from_slice(&u_step[..block_len]);

if iterations > 1 {
for _ in 1..iterations {
hmac.reset();
hmac.update(&u_step).unwrap();
u_step.copy_from_slice(&hmac.finalize().unwrap().unprotected_as_bytes());
hmac.update(&u_step)?;
u_step.copy_from_slice(&hmac.finalize()?.unprotected_as_bytes());
dk_block
.iter_mut()
.zip(u_step.iter())
.for_each(|(a, b)| *a ^= b);
}
}

Ok(())
}

#[must_use]
Expand Down Expand Up @@ -143,11 +145,12 @@ pub fn derive_key(
function_f(
salt,
iterations,
// .unwrap() cannot panic since block_idx.is_some() == true
block_idx.unwrap(),
dk_block,
block_len,
&mut hmac,
);
)?;
hmac.reset();
} else {
return Err(UnknownCryptoError);
Expand Down
12 changes: 6 additions & 6 deletions src/hazardous/mac/poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,12 @@ impl Poly1305 {
}

let tmp = self.buffer;
self.process_block(&tmp).unwrap();
self.process_block(&tmp)?;
self.leftover = 0;
}

while bytes.len() >= POLY1305_BLOCKSIZE {
self.process_block(&bytes[0..POLY1305_BLOCKSIZE]).unwrap();
self.process_block(&bytes[0..POLY1305_BLOCKSIZE])?;
// Reduce by slice
bytes = &bytes[POLY1305_BLOCKSIZE..];
}
Expand Down Expand Up @@ -367,13 +367,13 @@ impl Poly1305 {
*buf_itm = 0u8;
}

self.process_block(&local_buffer).unwrap();
self.process_block(&local_buffer)?;
}
// Get tag
self.process_end_of_stream();
LittleEndian::write_u32_into(&self.a[0..4], &mut local_buffer);

Ok(Tag::from_slice(&local_buffer).unwrap())
Ok(Tag::from_slice(&local_buffer)?)
}
}

Expand All @@ -398,9 +398,9 @@ pub fn init(one_time_key: &OneTimeKey) -> Poly1305 {
/// One-shot function for generating a Poly1305 tag of `data`.
pub fn poly1305(one_time_key: &OneTimeKey, data: &[u8]) -> Result<Tag, UnknownCryptoError> {
let mut poly_1305_state = init(one_time_key);
poly_1305_state.update(data).unwrap();
poly_1305_state.update(data)?;

Ok(poly_1305_state.finalize().unwrap())
Ok(poly_1305_state.finalize()?)
}

#[must_use]
Expand Down
6 changes: 3 additions & 3 deletions src/hazardous/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

//! ### **Caution**:
//! Usage of the `hazardous` module is __**only intended for advanced users**__.
//! `hazardous` contains implementations with a much higher degree of control. It
//! is also much easier to misuse those implementations. Only use `hazardous` if
//! absolutely necessary.
//! `hazardous` contains implementations with a much higher degree of control.
//! It is also much easier to misuse those implementations. Only use `hazardous`
//! if absolutely necessary.
/// AEADs (Authenticated Encryption with Associated Data).
pub mod aead;
Expand Down
23 changes: 10 additions & 13 deletions src/hazardous/stream/chacha20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ impl InternalState {

// Only set block counter if not HChaCha
if self.is_ietf {
// .unwrap() cannot panic here since the above two
// checks make sure block_count.is_some() == true
// if this branch it hit
self.state[12] = block_count.unwrap();
}

Expand Down Expand Up @@ -315,15 +318,13 @@ pub fn encrypt(
let block_counter = initial_counter.checked_add(counter as u32);
if block_counter.is_some() {
keystream_state = chacha_state
.process_block(Some(block_counter.unwrap()))
.unwrap();
// .unwrap() cannot panic here since block_counter.is_some() == true
.process_block(Some(block_counter.unwrap()))?;
} else {
return Err(UnknownCryptoError);
}

chacha_state
.serialize_block(&keystream_state, &mut keystream_block)
.unwrap();
chacha_state.serialize_block(&keystream_state, &mut keystream_block)?;

for (idx, itm) in plaintext_block.iter().enumerate() {
// `ciphertext_block` and `plaintext_block` have the same length
Expand Down Expand Up @@ -366,11 +367,9 @@ pub fn keystream_block(
chacha_state.init_state(secret_key, &nonce.as_bytes())?;

let mut keystream_block = [0u8; CHACHA_BLOCKSIZE];
let mut keystream_state: ChaChaState = chacha_state.process_block(Some(counter)).unwrap();
let mut keystream_state: ChaChaState = chacha_state.process_block(Some(counter))?;

chacha_state
.serialize_block(&keystream_state, &mut keystream_block)
.unwrap();
chacha_state.serialize_block(&keystream_state, &mut keystream_block)?;

keystream_state.clear();

Expand All @@ -390,11 +389,9 @@ pub fn hchacha20(
};
chacha_state.init_state(secret_key, nonce)?;

let mut keystream_state = chacha_state.process_block(None).unwrap();
let mut keystream_state = chacha_state.process_block(None)?;
let mut keystream_block: [u8; HCHACHA_OUTSIZE] = [0u8; HCHACHA_OUTSIZE];
chacha_state
.serialize_block(&keystream_state, &mut keystream_block)
.unwrap();
chacha_state.serialize_block(&keystream_state, &mut keystream_block)?;

keystream_state.clear();

Expand Down
4 changes: 2 additions & 2 deletions src/hazardous/stream/xchacha20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ pub fn encrypt(
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let subkey: SecretKey =
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?).unwrap();
SecretKey::from_slice(&chacha20::hchacha20(secret_key, &nonce.as_bytes()[0..16])?)?;
let mut prefixed_nonce = [0u8; IETF_CHACHA_NONCESIZE];
prefixed_nonce[4..IETF_CHACHA_NONCESIZE].copy_from_slice(&nonce.as_bytes()[16..24]);

chacha20::encrypt(
&subkey,
&IETFNonce::from_slice(&prefixed_nonce).unwrap(),
&IETFNonce::from_slice(&prefixed_nonce)?,
initial_counter,
plaintext,
dst_out,
Expand Down

0 comments on commit 878ffb7

Please sign in to comment.