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 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 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
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
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
2 changes: 1 addition & 1 deletion sha2/src/sha512/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ unsafe fn rounds_0_63_avx2(

for i in 1..5 {
for j in 0..8 {
let t = _mm_loadu_si128(K64.as_ptr().add(k64x4_idx) as *const u64 as *const _);
let t = _mm_loadu_si128(K64.as_ptr().add(k64x4_idx).cast());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh huh, neat

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's one of relatively old (introduced in 1.38) goodies which is really nice.

let y = sha512_update_x_avx2(x, _mm256_set_m128i(t, t));

{
Expand Down
1 change: 0 additions & 1 deletion sha3/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::convert::TryInto;
#[cfg(feature = "zeroize")]
use zeroize::{Zeroize, ZeroizeOnDrop};

Expand Down
2 changes: 1 addition & 1 deletion sha3/tests/turboshake.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::{convert::TryInto, fmt::Debug};
use core::fmt::Debug;
use digest::ExtendableOutput;

pub(crate) fn turbo_shake_test<D, F>(
Expand Down
2 changes: 1 addition & 1 deletion shabal/src/core_api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::consts;
use core::{convert::TryInto, fmt, mem, num::Wrapping};
use core::{fmt, mem, num::Wrapping};
use digest::{
array::Array,
block_buffer::Eager,
Expand Down
1 change: 0 additions & 1 deletion sm3/src/compress.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(clippy::many_single_char_names, clippy::too_many_arguments)]
use crate::{consts::T32, Block, Sm3Core};
use core::convert::TryInto;

#[inline(always)]
fn ff1(x: u32, y: u32, z: u32) -> u32 {
Expand Down
2 changes: 1 addition & 1 deletion streebog/src/core_api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::{convert::TryInto, fmt};
use core::fmt;
use digest::{
block_buffer::Eager,
consts::U64,
Expand Down
1 change: 0 additions & 1 deletion tiger/src/compress.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::tables::{T1, T2, T3, T4};
use super::State;
use core::convert::TryInto;

#[inline(always)]
fn round(a: &mut u64, b: &mut u64, c: &mut u64, x: &u64, mul: u8) {
Expand Down
7 changes: 2 additions & 5 deletions whirlpool/src/compress.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use crate::BLOCK_SIZE;
use core::convert::TryInto;

#[path = "consts.rs"]
mod consts;
use consts::*;

fn compress_block(state: &mut [u64; 8], b: &[u8; BLOCK_SIZE]) {
fn compress_block(state: &mut [u64; 8], b: &[u8; 64]) {
let mut k = [0u64; 8];
let mut block = [0u64; 8];
let mut s = [0u64; 8];
Expand Down Expand Up @@ -53,7 +50,7 @@ fn compress_block(state: &mut [u64; 8], b: &[u8; BLOCK_SIZE]) {
}
}

pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; BLOCK_SIZE]]) {
pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; 64]]) {
for block in blocks {
compress_block(state, block);
}
Expand Down
21 changes: 7 additions & 14 deletions whirlpool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
)]
#![deny(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms)]

pub use digest::{self, Digest};
Expand All @@ -18,12 +19,13 @@ use compress::compress;

use core::fmt;
use digest::{
array::ArrayOps,
block_buffer::Eager,
core_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
OutputSizeUser, Reset, UpdateCore,
},
typenum::{Unsigned, U64},
typenum::U64,
HashMarker, Output,
};

Expand Down Expand Up @@ -51,9 +53,10 @@ impl OutputSizeUser for WhirlpoolCore {
impl UpdateCore for WhirlpoolCore {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
let block_bits = 8 * BLOCK_SIZE as u64;
let block_bits = 8 * Self::block_size() as u64;
self.update_len(block_bits * (blocks.len() as u64));
compress(&mut self.state, convert(blocks));
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress(&mut self.state, blocks);
}
}

Expand All @@ -70,7 +73,7 @@ impl FixedOutputCore for WhirlpoolCore {

let mut state = self.state;
buffer.digest_pad(0x80, &buf, |block| {
compress(&mut state, convert(core::slice::from_ref(block)));
compress(&mut state, core::slice::from_ref(&block.0));
});

for (chunk, v) in out.chunks_exact_mut(8).zip(state.iter()) {
Expand Down Expand Up @@ -129,13 +132,3 @@ fn adc(a: &mut u64, b: u64, carry: &mut u64) {
*a = ret as u64;
*carry = (ret >> 64) as u64;
}

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

#[inline(always)]
fn convert(blocks: &[Block<WhirlpoolCore>]) -> &[[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()) }
}