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

Reduce amount of unsafe #540

Merged
merged 6 commits into from
Jan 10, 2024
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
1 change: 0 additions & 1 deletion belt-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ pub fn belt_compress(x1: [u32; 4], x2: [u32; 4], x34: [u32; 8]) -> ([u32; 4], [u

#[inline(always)]
fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
// TODO: use array zip on stabilization and MSRV bump
[a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
}

Expand Down
2 changes: 1 addition & 1 deletion blake2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern crate std;

pub use digest::{self, Digest};

use core::{convert::TryInto, fmt, marker::PhantomData, ops::Div};
use core::{fmt, marker::PhantomData, ops::Div};
use digest::{
array::{Array, ArraySize},
block_buffer::{Lazy, LazyBuffer},
Expand Down
2 changes: 1 addition & 1 deletion gost94/src/gost94_core.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(clippy::many_single_char_names)]
use core::{convert::TryInto, fmt};
use core::fmt;
use digest::{
block_buffer::Eager,
core_api::{
Expand Down
1 change: 0 additions & 1 deletion groestl/src/compress1024.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::needless_range_loop)]
use crate::table::TABLE;
use core::{convert::TryInto, u64};

pub(crate) const COLS: usize = 16;
const ROUNDS: u64 = 14;
Expand Down
1 change: 0 additions & 1 deletion groestl/src/compress512.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::needless_range_loop)]
use crate::table::TABLE;
use core::{convert::TryInto, u64};

pub(crate) const COLS: usize = 8;
const ROUNDS: u64 = 10;
Expand Down
2 changes: 1 addition & 1 deletion jh/benches/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ macro_rules! mach_bench {
input: *const [u8; 64],
) {
for _ in 0..160 {
jh::f8_impl(m, state, input as *const _);
jh::f8_impl(m, state, input.cast());
}
}
b.iter(|| unsafe { runner(m, &mut state, &input) });
Expand Down
2 changes: 1 addition & 1 deletion jh/src/compressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ union X2Bytes<M: Machine> {
#[doc(hidden)]
pub fn f8_impl<M: Machine>(mach: M, state: &mut [vec128_storage; 8], data: *const u8) {
#[allow(clippy::cast_ptr_alignment)]
let data = data as *const M::u128x1;
let data: *const M::u128x1 = data.cast();
let mut y = X8::<M>(
mach.unpack(state[0]),
mach.unpack(state[1]),
Expand Down
2 changes: 1 addition & 1 deletion md4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

pub use digest::{self, Digest};

use core::{convert::TryInto, fmt, num::Wrapping as W};
use core::{fmt, num::Wrapping as W};
#[cfg(feature = "oid")]
use digest::const_oid::{AssociatedOid, ObjectIdentifier};
use digest::{
Expand Down
1 change: 0 additions & 1 deletion md5/src/compress/soft.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::many_single_char_names, clippy::unreadable_literal)]
use crate::consts::RC;
use core::convert::TryInto;

#[inline(always)]
fn op_f(w: u32, x: u32, y: u32, z: u32, m: u32, c: u32, s: u32) -> u32 {
Expand Down
18 changes: 4 additions & 14 deletions md5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use core::{fmt, slice::from_ref};
#[cfg(feature = "oid")]
use digest::const_oid::{AssociatedOid, ObjectIdentifier};
use digest::{
array::ArrayOps,
block_buffer::Eager,
core_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
Expand Down Expand Up @@ -49,7 +50,8 @@ impl UpdateCore for Md5Core {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len = self.block_len.wrapping_add(blocks.len() as u64);
compress::compress(&mut self.state, convert(blocks))
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress::compress(&mut self.state, blocks)
}
}

Expand All @@ -62,9 +64,7 @@ impl FixedOutputCore for Md5Core {
.wrapping_add(buffer.get_pos() as u64)
.wrapping_mul(8);
let mut s = self.state;
buffer.len64_padding_le(bit_len, |b| {
compress::compress(&mut s, convert(from_ref(b)))
});
buffer.len64_padding_le(bit_len, |b| compress::compress(&mut s, from_ref(&b.0)));
for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) {
chunk.copy_from_slice(&v.to_le_bytes());
}
Expand Down Expand Up @@ -108,13 +108,3 @@ impl AssociatedOid for Md5Core {

/// MD5 hasher state.
pub type Md5 = CoreWrapper<Md5Core>;

const BLOCK_SIZE: usize = <Md5Core as BlockSizeUser>::BlockSize::USIZE;

#[inline(always)]
fn convert(blocks: &[Block<Md5Core>]) -> &[[u8; BLOCK_SIZE]] {
// SAFETY: Array<u8, U64> and [u8; 64] have
// exactly the same memory layout
let p = blocks.as_ptr() as *const [u8; BLOCK_SIZE];
unsafe { core::slice::from_raw_parts(p, blocks.len()) }
}
2 changes: 0 additions & 2 deletions ripemd/src/c128.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::convert::TryInto;

pub const DIGEST_BUF_LEN: usize = 4;
pub const WORK_BUF_LEN: usize = 16;

Expand Down
2 changes: 0 additions & 2 deletions ripemd/src/c160.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::convert::TryInto;

pub const DIGEST_BUF_LEN: usize = 5;
pub const WORK_BUF_LEN: usize = 16;

Expand Down
2 changes: 1 addition & 1 deletion ripemd/src/c256.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::{convert::TryInto, mem::swap};
use core::mem::swap;

pub const DIGEST_BUF_LEN: usize = 8;
pub const HALF_DIGEST_BUF_LEN: usize = DIGEST_BUF_LEN / 2;
Expand Down
2 changes: 1 addition & 1 deletion ripemd/src/c320.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::{convert::TryInto, mem::swap};
use core::mem::swap;

pub const HALF_DIGEST_BUF_LEN: usize = 5;
pub const DIGEST_BUF_LEN: usize = 10;
Expand Down
11 changes: 2 additions & 9 deletions sha1/src/compress.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{Block, BlockSizeUser, Sha1Core};
use digest::typenum::Unsigned;
use crate::BLOCK_SIZE;

cfg_if::cfg_if! {
if #[cfg(feature = "force-soft")] {
Expand Down Expand Up @@ -27,14 +26,8 @@ cfg_if::cfg_if! {
}
}

const BLOCK_SIZE: usize = <Sha1Core as BlockSizeUser>::BlockSize::USIZE;

/// SHA-1 compression function
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
pub fn compress(state: &mut [u32; 5], blocks: &[Block<Sha1Core>]) {
// SAFETY: Array<u8, U64> and [u8; 64] have
// exactly the same memory layout
let blocks: &[[u8; BLOCK_SIZE]] =
unsafe { &*(blocks as *const _ as *const [[u8; BLOCK_SIZE]]) };
pub fn compress(state: &mut [u32; 5], blocks: &[[u8; BLOCK_SIZE]]) {
compress_inner(state, blocks);
}
1 change: 0 additions & 1 deletion sha1/src/compress/soft.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::many_single_char_names)]
use super::BLOCK_SIZE;
use core::convert::TryInto;

const K: [u32; 4] = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];

Expand Down
18 changes: 5 additions & 13 deletions sha1/src/compress/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,12 @@ unsafe fn digest_blocks(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
#[allow(non_snake_case)]
let MASK: __m128i = _mm_set_epi64x(0x0001_0203_0405_0607, 0x0809_0A0B_0C0D_0E0F);

let mut state_abcd = _mm_set_epi32(
state[0] as i32,
state[1] as i32,
state[2] as i32,
state[3] as i32,
);
let mut state_abcd = _mm_loadu_si128(state.as_ptr().cast());
state_abcd = _mm_shuffle_epi32(state_abcd, 0b00011011);
let mut state_e = _mm_set_epi32(state[4] as i32, 0, 0, 0);

for block in blocks {
// SAFETY: we use only unaligned loads with this pointer
#[allow(clippy::cast_ptr_alignment)]
let block_ptr = block.as_ptr() as *const __m128i;
let block_ptr: *const __m128i = block.as_ptr().cast();

let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(0)), MASK);
let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(1)), MASK);
Expand Down Expand Up @@ -90,10 +84,8 @@ unsafe fn digest_blocks(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
state_e = _mm_sha1nexte_epu32(h1, state_e);
}

state[0] = _mm_extract_epi32(state_abcd, 3) as u32;
state[1] = _mm_extract_epi32(state_abcd, 2) as u32;
state[2] = _mm_extract_epi32(state_abcd, 1) as u32;
state[3] = _mm_extract_epi32(state_abcd, 0) as u32;
state_abcd = _mm_shuffle_epi32(state_abcd, 0b00011011);
_mm_storeu_si128(state.as_mut_ptr().cast(), state_abcd);
state[4] = _mm_extract_epi32(state_e, 3) as u32;
}

Expand Down
5 changes: 4 additions & 1 deletion sha1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use core::{fmt, slice::from_ref};
#[cfg(feature = "oid")]
use digest::const_oid::{AssociatedOid, ObjectIdentifier};
use digest::{
array::ArrayOps,
block_buffer::Eager,
core_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
Expand All @@ -30,6 +31,7 @@ pub use compress::compress;
use compress::compress;

const STATE_LEN: usize = 5;
const BLOCK_SIZE: usize = <Sha1Core as BlockSizeUser>::BlockSize::USIZE;

/// Core SHA-1 hasher state.
#[derive(Clone)]
Expand All @@ -56,6 +58,7 @@ impl UpdateCore for Sha1Core {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u64;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress(&mut self.h, blocks);
}
}
Expand All @@ -67,7 +70,7 @@ impl FixedOutputCore for Sha1Core {
let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);

let mut h = self.h;
buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(&b.0)));
for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) {
chunk.copy_from_slice(&v.to_be_bytes());
}
Expand Down
7 changes: 5 additions & 2 deletions sha2/src/core_api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{consts, sha256::compress256, sha512::compress512};
use core::{fmt, slice::from_ref};
use digest::{
array::ArrayOps,
block_buffer::Eager,
core_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, OutputSizeUser, TruncSide,
Expand Down Expand Up @@ -34,6 +35,7 @@ impl UpdateCore for Sha256VarCore {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u64;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress256(&mut self.state, blocks);
}
}
Expand All @@ -60,7 +62,7 @@ impl VariableOutputCore for Sha256VarCore {
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
let bs = Self::BlockSize::U64;
let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(b)));
buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(&b.0)));

for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) {
chunk.copy_from_slice(&v.to_be_bytes());
Expand Down Expand Up @@ -106,6 +108,7 @@ impl UpdateCore for Sha512VarCore {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u128;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress512(&mut self.state, blocks);
}
}
Expand Down Expand Up @@ -134,7 +137,7 @@ impl VariableOutputCore for Sha512VarCore {
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
let bs = Self::BlockSize::U64 as u128;
let bit_len = 8 * (buffer.get_pos() as u128 + bs * self.block_len);
buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, from_ref(b)));
buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, from_ref(&b.0)));

for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) {
chunk.copy_from_slice(&v.to_be_bytes());
Expand Down
8 changes: 1 addition & 7 deletions sha2/src/sha256.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use digest::{array::Array, typenum::U64};

cfg_if::cfg_if! {
if #[cfg(feature = "force-soft")] {
mod soft;
Expand Down Expand Up @@ -31,10 +29,6 @@ cfg_if::cfg_if! {
/// This is a low-level "hazmat" API which provides direct access to the core
/// functionality of SHA-256.
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
pub fn compress256(state: &mut [u32; 8], blocks: &[Array<u8, U64>]) {
// SAFETY: Array<u8, U64> and [u8; 64] have
// exactly the same memory layout
let p = blocks.as_ptr() as *const [u8; 64];
let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) };
pub fn compress256(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
compress(state, blocks)
}
1 change: 0 additions & 1 deletion sha2/src/sha256/soft.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::many_single_char_names)]
use crate::consts::BLOCK_LEN;
use core::convert::TryInto;

#[inline(always)]
fn shr(v: [u32; 4], o: u32) -> [u32; 4] {
Expand Down
14 changes: 7 additions & 7 deletions sha2/src/sha256/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
0x0405_0607_0001_0203u64 as i64,
);

let state_ptr = state.as_ptr() as *const __m128i;
let state_ptr: *const __m128i = state.as_ptr().cast();
let dcba = _mm_loadu_si128(state_ptr.add(0));
let efgh = _mm_loadu_si128(state_ptr.add(1));

Expand All @@ -59,11 +59,11 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
let abef_save = abef;
let cdgh_save = cdgh;

let data_ptr = block.as_ptr() as *const __m128i;
let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(0)), MASK);
let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(1)), MASK);
let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(2)), MASK);
let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(3)), MASK);
let block_ptr: *const __m128i = block.as_ptr().cast();
let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(0)), MASK);
let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(1)), MASK);
let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(2)), MASK);
let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(3)), MASK);
let mut w4;

rounds4!(abef, cdgh, w0, 0);
Expand Down Expand Up @@ -92,7 +92,7 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
let dcba = _mm_blend_epi16(feba, dchg, 0xF0);
let hgef = _mm_alignr_epi8(dchg, feba, 8);

let state_ptr_mut = state.as_mut_ptr() as *mut __m128i;
let state_ptr_mut: *mut __m128i = state.as_mut_ptr().cast();
_mm_storeu_si128(state_ptr_mut.add(0), dcba);
_mm_storeu_si128(state_ptr_mut.add(1), hgef);
}
Expand Down
8 changes: 1 addition & 7 deletions sha2/src/sha512.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use digest::{array::Array, typenum::U128};

cfg_if::cfg_if! {
if #[cfg(feature = "force-soft")] {
mod soft;
Expand Down Expand Up @@ -33,10 +31,6 @@ cfg_if::cfg_if! {
/// This is a low-level "hazmat" API which provides direct access to the core
/// functionality of SHA-512.
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
pub fn compress512(state: &mut [u64; 8], blocks: &[Array<u8, U128>]) {
// SAFETY: Array<u8, U64> and [u8; 64] have
// exactly the same memory layout
let p = blocks.as_ptr() as *const [u8; 128];
let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) };
pub fn compress512(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
compress(state, blocks)
}
1 change: 0 additions & 1 deletion sha2/src/sha512/soft.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::many_single_char_names)]
use crate::consts::{BLOCK_LEN, K64X2};
use core::convert::TryInto;

fn add(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
[a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])]
Expand Down
Loading
Loading