Remove chacha dependency from poly1305.
The new chacha20_poly1305_openssh -> chacha20_poly1305 here is not ideal either, but better than poly1305 -> chacha.
This commit is contained in:
parent
e363572b76
commit
34e5a5b93a
@ -76,8 +76,12 @@ fn aead_poly1305(
|
||||
chacha20_key: &chacha::Key, counter: &chacha::Counter, ad: &[u8], ciphertext: &[u8],
|
||||
) -> Tag {
|
||||
debug_assert_eq!(counter[0], 0);
|
||||
let key = poly1305::Key::derive_using_chacha(chacha20_key, counter);
|
||||
let mut ctx = poly1305::Context::from_key(key);
|
||||
|
||||
let mut ctx = {
|
||||
let key = derive_poly1305_key(chacha20_key, counter);
|
||||
poly1305::Context::from_key(key)
|
||||
};
|
||||
|
||||
poly1305_update_padded_16(&mut ctx, ad);
|
||||
poly1305_update_padded_16(&mut ctx, ciphertext);
|
||||
let lengths = [
|
||||
@ -97,6 +101,15 @@ fn poly1305_update_padded_16(ctx: &mut poly1305::Context, data: &[u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Also used by chacha20_poly1305_openssh.
|
||||
pub(super) fn derive_poly1305_key(
|
||||
chacha_key: &chacha::Key, counter: &chacha::Counter,
|
||||
) -> poly1305::Key {
|
||||
let mut bytes = [0u8; poly1305::KEY_LEN];
|
||||
chacha::chacha20_xor_in_place(chacha_key, counter, &mut bytes);
|
||||
poly1305::Key::from(bytes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
@ -29,7 +29,7 @@
|
||||
//! http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD
|
||||
//! [RFC 4253]: https://tools.ietf.org/html/rfc4253
|
||||
|
||||
use super::{poly1305, Tag, TAG_LEN};
|
||||
use super::{chacha20_poly1305::derive_poly1305_key, poly1305, Tag, TAG_LEN};
|
||||
use crate::{chacha, error};
|
||||
|
||||
/// A key for sealing packets.
|
||||
@ -69,7 +69,7 @@ impl SealingKey {
|
||||
}
|
||||
|
||||
counter[0] = 0;
|
||||
let poly_key = poly1305::Key::derive_using_chacha(&self.key.k_2, &counter);
|
||||
let poly_key = derive_poly1305_key(&self.key.k_2, &counter);
|
||||
let Tag(tag) = poly1305::sign(poly_key, plaintext_in_ciphertext_out);
|
||||
tag_out.copy_from_slice(&tag);
|
||||
}
|
||||
@ -118,7 +118,7 @@ impl OpeningKey {
|
||||
// We must verify the tag before decrypting so that
|
||||
// `ciphertext_in_plaintext_out` is unmodified if verification fails.
|
||||
// This is beyond what we guarantee.
|
||||
let poly_key = poly1305::Key::derive_using_chacha(&self.key.k_2, &counter);
|
||||
let poly_key = derive_poly1305_key(&self.key.k_2, &counter);
|
||||
poly1305::verify(poly_key, ciphertext_in_plaintext_out, tag)?;
|
||||
|
||||
let plaintext_in_ciphertext_out = &mut ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..];
|
||||
|
@ -16,21 +16,14 @@
|
||||
// TODO: enforce maximum input length.
|
||||
|
||||
use super::{Tag, TAG_LEN};
|
||||
use crate::{bssl, c, chacha, constant_time, error, polyfill};
|
||||
use crate::{bssl, c, constant_time, error, polyfill};
|
||||
use core;
|
||||
|
||||
/// A Poly1305 key.
|
||||
pub struct Key([u8; KEY_LEN]);
|
||||
|
||||
impl Key {
|
||||
pub fn derive_using_chacha(chacha20_key: &chacha::Key, counter: &chacha::Counter) -> Self {
|
||||
let mut bytes = [0u8; KEY_LEN];
|
||||
chacha::chacha20_xor_in_place(chacha20_key, counter, &mut bytes);
|
||||
Key(bytes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn from_test_vector(bytes: &[u8; KEY_LEN]) -> Self { Key(*bytes) }
|
||||
impl From<[u8; KEY_LEN]> for Key {
|
||||
fn from(value: [u8; 32]) -> Self { Key(value) }
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
@ -251,25 +244,25 @@ mod tests {
|
||||
|
||||
// Test single-shot operation.
|
||||
{
|
||||
let key = Key::from_test_vector(&key);
|
||||
let key = Key::from(key.clone());
|
||||
let mut ctx = Context::from_key(key);
|
||||
ctx.update(&input);
|
||||
let Tag(actual_mac) = ctx.finish();
|
||||
assert_eq!(expected_mac, &actual_mac);
|
||||
}
|
||||
{
|
||||
let key = Key::from_test_vector(&key);
|
||||
let key = Key::from(key.clone());
|
||||
let Tag(actual_mac) = sign(key, &input);
|
||||
assert_eq!(expected_mac, &actual_mac);
|
||||
}
|
||||
{
|
||||
let key = Key::from_test_vector(&key);
|
||||
let key = Key::from(key.clone());
|
||||
assert_eq!(Ok(()), verify(key, &input, &expected_mac));
|
||||
}
|
||||
|
||||
// Test streaming byte-by-byte.
|
||||
{
|
||||
let key = Key::from_test_vector(&key);
|
||||
let key = Key::from(key.clone());
|
||||
let mut ctx = Context::from_key(key);
|
||||
for chunk in input.chunks(1) {
|
||||
ctx.update(chunk);
|
||||
@ -290,7 +283,7 @@ mod tests {
|
||||
fn test_poly1305_simd(
|
||||
excess: usize, key: &[u8; KEY_LEN], input: &[u8], expected_mac: &[u8; TAG_LEN],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let key = Key::from_test_vector(&key);
|
||||
let key = Key::from(key.clone());
|
||||
let mut ctx = Context::from_key(key);
|
||||
|
||||
// Some implementations begin in non-SIMD mode and upgrade on demand.
|
||||
|
Loading…
x
Reference in New Issue
Block a user