Skip to content

Commit

Permalink
poly1305: Use MacResult for representing tags
Browse files Browse the repository at this point in the history
This outsources constant time comparisons to `MacResult`, so downstream
crates don't need to rely on additional crates to perform them beyond
what `MacResult` is already using.
  • Loading branch information
tarcieri committed Aug 19, 2019
1 parent 26c8c12 commit 98cf577
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
1 change: 1 addition & 0 deletions poly1305/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ readme = "README.md"

[dependencies]
byteorder = { version = "1", default-features = false }
crypto-mac = "0.7"
zeroize = { version = "0.9", optional = true, default-features = false }

[dev-dependencies]
Expand Down
20 changes: 13 additions & 7 deletions poly1305/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@

// TODO: replace with `u32::{from_le_bytes, to_le_bytes}` in libcore (1.32+)
extern crate byteorder;
extern crate crypto_mac;

#[cfg(feature = "zeroize")]
extern crate zeroize;

use byteorder::{ByteOrder, LE};
use core::cmp::min;
use crypto_mac::generic_array::{typenum::U16, GenericArray};
use crypto_mac::MacResult;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

Expand All @@ -33,6 +36,9 @@ pub const KEY_SIZE: usize = 32;
/// Size of the blocks Poly1305 acts upon
pub const BLOCK_SIZE: usize = 16;

/// Poly1305 authentication tags
pub type Tag = MacResult<U16>;

/// The Poly1305 universal hash function.
///
/// Note that Poly1305 is not a traditional MAC and is single-use only
Expand Down Expand Up @@ -135,7 +141,7 @@ impl Poly1305 {
}

/// Get the hashed output
pub fn result(mut self) -> [u8; BLOCK_SIZE] {
pub fn result(mut self) -> Tag {
if self.leftover > 0 {
self.buffer[self.leftover] = 1;

Expand Down Expand Up @@ -227,13 +233,13 @@ impl Poly1305 {
f = u64::from(h3) + u64::from(self.pad[3]) + (f >> 32);
h3 = f as u32;

let mut output = [0u8; BLOCK_SIZE];
LE::write_u32(&mut output[0..4], h0);
LE::write_u32(&mut output[4..8], h1);
LE::write_u32(&mut output[8..12], h2);
LE::write_u32(&mut output[12..16], h3);
let mut tag = GenericArray::default();
LE::write_u32(&mut tag[0..4], h0);
LE::write_u32(&mut tag[4..8], h1);
LE::write_u32(&mut tag[8..12], h2);
LE::write_u32(&mut tag[12..16], h3);

output
MacResult::new(tag)
}

/// Compute a single block of Poly1305 using the internal buffer
Expand Down
36 changes: 20 additions & 16 deletions poly1305/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ fn test_nacl_vector() {
0xd9,
];

assert_eq!(&Poly1305::new(&key).chain(&msg).result(), &expected[..]);
let result1 = Poly1305::new(&key).chain(&msg).result();
assert_eq!(&expected[..], result1.code().as_slice());

let result = Poly1305::new(&key)
let result2 = Poly1305::new(&key)
.chain(&msg[0..32])
.chain(&msg[32..96])
.chain(&msg[96..112])
Expand All @@ -44,7 +45,7 @@ fn test_nacl_vector() {
.chain(&msg[130..131])
.result();

assert_eq!(&result, &expected[..]);
assert_eq!(&expected[..], result2.code().as_slice());
}

#[test]
Expand All @@ -65,10 +66,9 @@ fn donna_self_test() {
0x00,
];

assert_eq!(
&Poly1305::new(&wrap_key).chain(&wrap_msg).result(),
&wrap_mac[..]
);
let result = Poly1305::new(&wrap_key).chain(&wrap_msg).result();

assert_eq!(&wrap_mac[..], result.code().as_slice());

let total_key = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xff,
Expand All @@ -88,31 +88,35 @@ fn donna_self_test() {
key.copy_from_slice(&repeat(i as u8).take(KEY_SIZE).collect::<Vec<_>>());

let msg: Vec<u8> = repeat(i as u8).take(256).collect();
tpoly.input(&Poly1305::new(&key).chain(&msg[..i]).result());
let tag = Poly1305::new(&key).chain(&msg[..i]).result();
tpoly.input(tag.code().as_slice());
}

assert_eq!(&tpoly.result(), &total_mac[..]);
assert_eq!(&total_mac[..], tpoly.result().code().as_slice());
}

#[test]
fn test_tls_vectors() {
// from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
let key = b"this is 32-byte key for Poly1305";
let msg = [0u8; 32];
let expected = [

let msg1 = [0u8; 32];
let expected1 = [
0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03,
0x07,
];

assert_eq!(&Poly1305::new(&key).chain(&msg).result(), &expected[..]);
let result1 = Poly1305::new(&key).chain(&msg1).result();
assert_eq!(&expected1[..], result1.code().as_slice());

let msg = b"Hello world!";
let expected = [
let msg2 = b"Hello world!";
let expected2 = [
0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2,
0xf0,
];

assert_eq!(&Poly1305::new(&key).chain(&msg[..]).result(), &expected[..]);
let result2 = Poly1305::new(&key).chain(&msg2[..]).result();
assert_eq!(&expected2[..], result2.code().as_slice());
}

#[test]
Expand All @@ -135,5 +139,5 @@ fn padded_input() {

let mut poly = Poly1305::new(&key);
poly.input_padded(&msg);
assert_eq!(&expected[..], poly.result());
assert_eq!(&expected[..], poly.result().code().as_slice());
}

0 comments on commit 98cf577

Please sign in to comment.