Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

poly1305 internals: Remove the I-U-F logic in poly1305.c. #2272

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
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
39 changes: 1 addition & 38 deletions crypto/poly1305/poly1305.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ struct poly1305_state_st {
uint32_t r0, r1, r2, r3, r4;
uint32_t s1, s2, s3, s4;
uint32_t h0, h1, h2, h3, h4;
uint8_t buf[16];
size_t buf_used;
uint8_t key[16];
};

Expand Down Expand Up @@ -179,7 +177,6 @@ void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) {
state->h3 = 0;
state->h4 = 0;

state->buf_used = 0;
OPENSSL_memcpy(state->key, key + 16, sizeof(state->key));
}

Expand All @@ -192,48 +189,14 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
return;
}

if (state->buf_used) {
size_t todo = 16 - state->buf_used;
if (todo > in_len) {
todo = in_len;
}
for (size_t i = 0; i < todo; i++) {
state->buf[state->buf_used + i] = in[i];
}
state->buf_used += todo;
in_len -= todo;
in += todo;

if (state->buf_used == 16) {
poly1305_update(state, state->buf, 16);
state->buf_used = 0;
}
}

if (in_len >= 16) {
size_t todo = in_len & ~0xf;
poly1305_update(state, in, todo);
in += todo;
in_len &= 0xf;
}

if (in_len) {
for (size_t i = 0; i < in_len; i++) {
state->buf[i] = in[i];
}
state->buf_used = in_len;
}
poly1305_update(state, in, in_len);
}

void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) {
struct poly1305_state_st *state = poly1305_aligned_state(statep);
uint32_t g0, g1, g2, g3, g4;
uint32_t b, nb;

if (state->buf_used) {
poly1305_update(state, state->buf, state->buf_used);
}

b = state->h0 >> 26;
state->h0 = state->h0 & 0x3ffffff;
state->h1 += b;
Expand Down
20 changes: 9 additions & 11 deletions src/aead/chacha20_poly1305/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use crate::{
cpu,
error::InputTooLongError,
polyfill::{u64_from_usize, usize_from_u64_saturated},
polyfill::{slice, sliceutil, u64_from_usize, usize_from_u64_saturated},
};
use cfg_if::cfg_if;

Expand Down Expand Up @@ -147,23 +147,21 @@
Ok((counter, poly1305_key))
}

fn finish(mut auth: poly1305::Context, aad_len: usize, in_out_len: usize) -> Tag {
fn finish(auth: poly1305::Context, aad_len: usize, in_out_len: usize) -> Tag {

Check warning on line 150 in src/aead/chacha20_poly1305/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/chacha20_poly1305/mod.rs#L150

Added line #L150 was not covered by tests
let mut block = [0u8; poly1305::BLOCK_LEN];
let (alen, clen) = block.split_at_mut(poly1305::BLOCK_LEN / 2);
alen.copy_from_slice(&u64::to_le_bytes(u64_from_usize(aad_len)));
clen.copy_from_slice(&u64::to_le_bytes(u64_from_usize(in_out_len)));
auth.update(&block);
auth.finish()
auth.finish(&block)

Check warning on line 155 in src/aead/chacha20_poly1305/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/chacha20_poly1305/mod.rs#L155

Added line #L155 was not covered by tests
}

#[inline]
fn poly1305_update_padded_16(ctx: &mut poly1305::Context, input: &[u8]) {
if !input.is_empty() {
ctx.update(input);
let remainder_len = input.len() % poly1305::BLOCK_LEN;
if remainder_len != 0 {
const ZEROES: [u8; poly1305::BLOCK_LEN] = [0; poly1305::BLOCK_LEN];
ctx.update(&ZEROES[..(poly1305::BLOCK_LEN - remainder_len)])
}
let (whole, remainder) = slice::as_chunks(input);
ctx.update(whole);

Check warning on line 161 in src/aead/chacha20_poly1305/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/chacha20_poly1305/mod.rs#L160-L161

Added lines #L160 - L161 were not covered by tests
if !remainder.is_empty() {
let mut block = [0u8; poly1305::BLOCK_LEN];
sliceutil::overwrite_at_start(&mut block, remainder);
ctx.update_block(block);

Check warning on line 165 in src/aead/chacha20_poly1305/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/chacha20_poly1305/mod.rs#L163-L165

Added lines #L163 - L165 were not covered by tests
}
}
26 changes: 17 additions & 9 deletions src/aead/poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
// TODO: enforce maximum input length.

use super::{Tag, TAG_LEN};
use crate::cpu;
#[cfg(all(target_arch = "arm", target_endian = "little"))]
use crate::cpu::GetFeature as _;
use crate::{cpu, polyfill::slice};
use core::array;

mod ffi_arm_neon;
mod ffi_fallback;
Expand Down Expand Up @@ -62,16 +63,24 @@
ffi_fallback::State::new_context(key)
}

#[inline(always)]
pub fn update(&mut self, input: &[u8]) {
pub fn update_block(&mut self, input: [u8; BLOCK_LEN]) {
self.update(array::from_ref(&input))
}

Check warning on line 68 in src/aead/poly1305.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/poly1305.rs#L66-L68

Added lines #L66 - L68 were not covered by tests

pub fn update(&mut self, input: &[[u8; BLOCK_LEN]]) {
self.update_internal(slice::flatten(input));
}

Check warning on line 72 in src/aead/poly1305.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/poly1305.rs#L70-L72

Added lines #L70 - L72 were not covered by tests

fn update_internal(&mut self, input: &[u8]) {
match self {
#[cfg(all(target_arch = "arm", target_endian = "little"))]
Self::ArmNeon(state) => state.update(input),
Self::Fallback(state) => state.update(input),
Self::ArmNeon(state) => state.update_internal(input),
Self::Fallback(state) => state.update_internal(input),
}
}

pub(super) fn finish(self) -> Tag {
pub(super) fn finish(mut self, input: &[u8]) -> Tag {
self.update_internal(input);
match self {
#[cfg(all(target_arch = "arm", target_endian = "little"))]
Self::ArmNeon(state) => state.finish(),
Expand All @@ -85,9 +94,8 @@
/// This is used by chacha20_poly1305_openssh and the standalone
/// poly1305 test vectors.
pub(super) fn sign(key: Key, input: &[u8], cpu_features: cpu::Features) -> Tag {
let mut ctx = Context::from_key(key, cpu_features);
ctx.update(input);
ctx.finish()
let ctx = Context::from_key(key, cpu_features);
ctx.finish(input)
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/aead/poly1305/ffi_arm_neon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl State {
super::Context::ArmNeon(r)
}

pub(super) fn update(&mut self, input: &[u8]) {
pub(super) fn update_internal(&mut self, input: &[u8]) {
prefixed_extern! {
fn CRYPTO_poly1305_update_neon(
state: &mut poly1305_state,
Expand Down
4 changes: 3 additions & 1 deletion src/aead/poly1305/ffi_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ impl State {
super::Context::Fallback(r)
}

pub(super) fn update(&mut self, input: &[u8]) {
// `input.len % BLOCK_LEN == 0` must be true for every call except the
// final one.
pub(super) fn update_internal(&mut self, input: &[u8]) {
prefixed_extern! {
fn CRYPTO_poly1305_update(
state: &mut poly1305_state,
Expand Down