From 72bd86a6be3b73dc257c26150cf605494b2fa42c Mon Sep 17 00:00:00 2001 From: brycx Date: Sat, 26 Jan 2019 21:13:52 +0100 Subject: [PATCH] Bugfix: Fix panic when passing an out parameter to seal() that is longer than the minimum required length. Fixing this required to explicitly defining the length when copying the slice to append to authentication tag to the ciphertext --- src/hazardous/aead/chacha20poly1305.rs | 32 ++++++++++++++++++++++++- src/hazardous/aead/xchacha20poly1305.rs | 30 +++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/hazardous/aead/chacha20poly1305.rs b/src/hazardous/aead/chacha20poly1305.rs index 737d9829..2e0f8653 100644 --- a/src/hazardous/aead/chacha20poly1305.rs +++ b/src/hazardous/aead/chacha20poly1305.rs @@ -195,7 +195,7 @@ pub fn seal( let mut poly1305_state = poly1305::init(&poly1305_key); process_authentication(&mut poly1305_state, &optional_ad, &dst_out, plaintext.len())?; - dst_out[plaintext.len()..].copy_from_slice(&poly1305_state.finalize()?.unprotected_as_bytes()); + dst_out[plaintext.len()..(plaintext.len() + POLY1305_BLOCKSIZE)].copy_from_slice(&poly1305_state.finalize()?.unprotected_as_bytes()); Ok(()) } @@ -456,3 +456,33 @@ fn rfc_8439_test_poly1305_key_gen_3() { expected.as_ref() ); } + +#[test] +fn regression_detect_bigger_than_slice_bug() { + + let pt = [0x5B; 79]; + + let mut dst_out_ct = vec![0u8; pt.len() + (POLY1305_BLOCKSIZE * 2)]; + + seal( + &SecretKey::from_slice(&[0u8; 32]).unwrap(), + &Nonce::from_slice(&[0u8; 12]).unwrap(), + &pt[..], + None, + &mut dst_out_ct, + ).unwrap(); + + // Verify that using a slice that is bigger than produces the exact same + // output as using a slice that is the exact required length + let mut dst_out_ct_2 = vec![0u8; pt.len() + POLY1305_BLOCKSIZE]; + + seal( + &SecretKey::from_slice(&[0u8; 32]).unwrap(), + &Nonce::from_slice(&[0u8; 12]).unwrap(), + &pt[..], + None, + &mut dst_out_ct_2, + ).unwrap(); + + assert!(dst_out_ct[..dst_out_ct_2.len()] == dst_out_ct_2[..]); +} \ No newline at end of file diff --git a/src/hazardous/aead/xchacha20poly1305.rs b/src/hazardous/aead/xchacha20poly1305.rs index c46b9522..9d41b723 100644 --- a/src/hazardous/aead/xchacha20poly1305.rs +++ b/src/hazardous/aead/xchacha20poly1305.rs @@ -171,3 +171,33 @@ fn test_modified_tag_error() { ) .is_err()); } + +#[test] +fn regression_detect_bigger_than_slice_bug() { + + let pt = [0x5B; 79]; + + let mut dst_out_ct = vec![0u8; pt.len() + (16 * 2)]; + + seal( + &SecretKey::from_slice(&[0u8; 32]).unwrap(), + &Nonce::from_slice(&[0u8; 24]).unwrap(), + &pt[..], + None, + &mut dst_out_ct, + ).unwrap(); + + // Verify that using a slice that is bigger than produces the exact same + // output as using a slice that is the exact required length + let mut dst_out_ct_2 = vec![0u8; pt.len() + 16]; + + seal( + &SecretKey::from_slice(&[0u8; 32]).unwrap(), + &Nonce::from_slice(&[0u8; 24]).unwrap(), + &pt[..], + None, + &mut dst_out_ct_2, + ).unwrap(); + + assert!(dst_out_ct[..dst_out_ct_2.len()] == dst_out_ct_2[..]); +} \ No newline at end of file