Skip to content
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: 1 addition & 0 deletions .github/workflows/belt-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release
- run: cargo test --release --all-features
1 change: 1 addition & 0 deletions .github/workflows/cbc-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release
- run: cargo test --release --all-features
1 change: 1 addition & 0 deletions .github/workflows/cmac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release
- run: cargo test --release --all-features
2 changes: 1 addition & 1 deletion .github/workflows/hmac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release --features reset
- run: cargo test --release
- run: cargo test --release --all-features
1 change: 1 addition & 0 deletions .github/workflows/pmac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release
- run: cargo test --release --all-features
1 change: 1 addition & 0 deletions .github/workflows/retail-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ jobs:
toolchain: ${{ matrix.rust }}
- run: cargo test --release --no-default-features
- run: cargo test --release
- run: cargo test --release --all-features
28 changes: 12 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ members = [

[profile.dev]
opt-level = 2

[patch.crates-io]
# https://github.com/RustCrypto/traits/pull/1787
# https://github.com/RustCrypto/traits/pull/1799
digest = { git = "https://github.com/RustCrypto/traits" }
crypto-common = { git = "https://github.com/RustCrypto/traits" }

# https://github.com/RustCrypto/hashes/pull/678
streebog = { git = "https://github.com/RustCrypto/hashes" }
sha1 = { git = "https://github.com/RustCrypto/hashes" }
sha2 = { git = "https://github.com/RustCrypto/hashes" }
md-5 = { git = "https://github.com/RustCrypto/hashes" }
13 changes: 13 additions & 0 deletions belt-mac/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.2.0 (UNRELEASED)
### Changed
- Edition changed to 2024 and MSRV bumped to 1.85
- Relax MSRV policy and allow MSRV bumps in patch releases
- Update to `digest` v0.11
- Update to `cipher` v0.5
- Replace type aliases with newtypes ([#186])

### Removed
- `std` crate feature ([#186])

[#186]: https://github.com/RustCrypto/MACs/pull/186

## 0.1.0 (2023-04-03)
Initial Release
4 changes: 1 addition & 3 deletions belt-mac/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ digest = { version = "=0.11.0-pre.10", features = ["dev"] }
hex-literal = "1"

[features]
std = ["digest/std"]
zeroize = ["cipher/zeroize"]
zeroize = ["cipher/zeroize", "digest/zeroize"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
3 changes: 1 addition & 2 deletions belt-mac/benches/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#![feature(test)]
extern crate test;

use belt_block::BeltBlock;
use belt_mac::{BeltMac, KeyInit};
use test::Bencher;

digest::bench_update!(
BeltMac::<BeltBlock>::new(&Default::default());
BeltMac::new(&Default::default());
belt_mac_10 10;
belt_mac_100 100;
belt_mac_1000 1000;
Expand Down
184 changes: 184 additions & 0 deletions belt-mac/src/block_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
use belt_block::BeltBlock;
use cipher::{BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt};
use core::fmt;
use digest::{
MacMarker, Output, OutputSizeUser, Reset,
array::{Array, ArraySize},
block_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, Lazy,
UpdateCore,
},
crypto_common::{BlockSizes, InnerInit, InnerUser},
};

#[cfg(feature = "zeroize")]
use digest::zeroize::{Zeroize, ZeroizeOnDrop};

/// Generic core BeltMac instance, which operates over blocks.
#[derive(Clone)]
pub struct BeltMacCore<C = BeltBlock>
where
C: BlockCipherEncrypt + Clone,
{
cipher: C,
state: Block<C>,
r: Block<C>,
}

impl<C> BlockSizeUser for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
type BlockSize = C::BlockSize;
}

impl<C> OutputSizeUser for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
type OutputSize = C::BlockSize;
}

impl<C> InnerUser for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
type Inner = C;
}

impl<C> MacMarker for BeltMacCore<C> where C: BlockCipherEncrypt + Clone {}

impl<C> InnerInit for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
#[inline]
fn inner_init(cipher: C) -> Self {
let state = Default::default();
let mut r = Default::default();
cipher.encrypt_block(&mut r);
Self { cipher, state, r }
}
}

impl<C> BufferKindUser for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
type BufferKind = Lazy;
}

impl<C> UpdateCore for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
struct Closure<'a, N: BlockSizes> {
state: &'a mut Block<Self>,
blocks: &'a [Block<Self>],
}

impl<N: BlockSizes> BlockSizeUser for Closure<'_, N> {
type BlockSize = N;
}

impl<N: BlockSizes> BlockCipherEncClosure for Closure<'_, N> {
#[inline(always)]
fn call<B: BlockCipherEncBackend<BlockSize = Self::BlockSize>>(self, backend: &B) {
for block in self.blocks {
xor(self.state, block);
backend.encrypt_block((self.state).into());
}
}
}

let Self { cipher, state, .. } = self;
cipher.encrypt_with_backend(Closure { state, blocks })
}
}

impl<C> Reset for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
#[inline(always)]
fn reset(&mut self) {
self.state = Default::default();
}
}

impl<C> FixedOutputCore for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
#[inline]
fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
let pos = buffer.get_pos();
let mut buf = buffer.pad_with_zeros();

let cipher = &mut self.cipher;
let r = &self.r;
let bs = r.len();
let mut new_r = Block::<C>::default();
if pos == bs {
// phi1
let (h1, h2) = new_r.split_at_mut(bs - 4);
h1.copy_from_slice(&r[4..]);
for i in 0..4 {
h2[i] = r[i] ^ r[4 + i];
}
} else {
buf[pos] = 0x80;
// phi2
let (h1, h2) = new_r.split_at_mut(4);
for i in 0..4 {
h1[i] = r[i] ^ r[bs - 4 + i];
}
h2.copy_from_slice(&r[..bs - 4]);
}

let mut state = self.state.clone();
xor(&mut state, &buf);
xor(&mut state, &new_r);
cipher.encrypt_block_b2b(&state, out);
}
}

impl<C> AlgorithmName for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BeltMac")
}
}

impl<C> fmt::Debug for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BeltMacCore { ... }")
}
}

#[cfg(feature = "zeroize")]
impl<C> Drop for BeltMacCore<C>
where
C: BlockCipherEncrypt + Clone,
{
fn drop(&mut self) {
self.state.zeroize();
}
}

#[cfg(feature = "zeroize")]
impl<C> ZeroizeOnDrop for BeltMacCore<C> where C: BlockCipherEncrypt + Clone + ZeroizeOnDrop {}

#[inline(always)]
fn xor<N: ArraySize>(buf: &mut Array<u8, N>, data: &Array<u8, N>) {
for i in 0..N::USIZE {
buf[i] ^= data[i];
}
}
Loading