Skip to content

Commit f26bb48

Browse files
authored
polyval: use ManuallyDrop unions; MSRV 1.49+ (#113)
Using `ManuallyDrop` for the fields of `union`s (allowing them to be non-Copy types) was stabilized in Rust 1.49.
1 parent e75d01f commit f26bb48

10 files changed

Lines changed: 104 additions & 83 deletions

File tree

.github/workflows/ghash.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
strategy:
2626
matrix:
2727
rust:
28-
- 1.41.0 # MSRV
28+
- 1.49.0 # MSRV
2929
- stable
3030
target:
3131
- thumbv7em-none-eabi
@@ -54,7 +54,7 @@ jobs:
5454
strategy:
5555
matrix:
5656
rust:
57-
- 1.41.0 # MSRV
57+
- 1.49.0 # MSRV
5858
- stable
5959
steps:
6060
- uses: actions/checkout@v1

.github/workflows/polyval.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
strategy:
2626
matrix:
2727
rust:
28-
- 1.41.0 # MSRV
28+
- 1.49.0 # MSRV
2929
- stable
3030
target:
3131
- thumbv7em-none-eabi
@@ -52,15 +52,15 @@ jobs:
5252
include:
5353
# 32-bit Linux
5454
- target: i686-unknown-linux-gnu
55-
rust: 1.41.0 # MSRV
55+
rust: 1.49.0 # MSRV
5656
deps: sudo apt update && sudo apt install gcc-multilib
5757
- target: i686-unknown-linux-gnu
5858
rust: stable
5959
deps: sudo apt update && sudo apt install gcc-multilib
6060

6161
# 64-bit Linux
6262
- target: x86_64-unknown-linux-gnu
63-
rust: 1.41.0 # MSRV
63+
rust: 1.49.0 # MSRV
6464
- target: x86_64-unknown-linux-gnu
6565
rust: stable
6666
steps:
@@ -89,15 +89,15 @@ jobs:
8989
include:
9090
# 32-bit Linux
9191
- target: i686-unknown-linux-gnu
92-
rust: 1.41.0 # MSRV
92+
rust: 1.49.0 # MSRV
9393
deps: sudo apt update && sudo apt install gcc-multilib
9494
- target: i686-unknown-linux-gnu
9595
rust: stable
9696
deps: sudo apt update && sudo apt install gcc-multilib
9797

9898
# 64-bit Linux
9999
- target: x86_64-unknown-linux-gnu
100-
rust: 1.41.0 # MSRV
100+
rust: 1.49.0 # MSRV
101101
- target: x86_64-unknown-linux-gnu
102102
rust: stable
103103
steps:
@@ -125,15 +125,15 @@ jobs:
125125
include:
126126
# 32-bit Linux
127127
- target: i686-unknown-linux-gnu
128-
rust: 1.41.0 # MSRV
128+
rust: 1.49.0 # MSRV
129129
deps: sudo apt update && sudo apt install gcc-multilib
130130
- target: i686-unknown-linux-gnu
131131
rust: stable
132132
deps: sudo apt update && sudo apt install gcc-multilib
133133

134134
# 64-bit Linux
135135
- target: x86_64-unknown-linux-gnu
136-
rust: 1.41.0 # MSRV
136+
rust: 1.49.0 # MSRV
137137
- target: x86_64-unknown-linux-gnu
138138
rust: stable
139139
steps:
@@ -159,13 +159,13 @@ jobs:
159159
include:
160160
# ARM64
161161
- target: aarch64-unknown-linux-gnu
162-
rust: 1.41.0 # MSRV
162+
rust: 1.49.0 # MSRV
163163
- target: aarch64-unknown-linux-gnu
164164
rust: stable
165165

166166
# PPC32
167167
- target: powerpc-unknown-linux-gnu
168-
rust: 1.41.0 # MSRV
168+
rust: 1.49.0 # MSRV
169169
- target: powerpc-unknown-linux-gnu
170170
rust: stable
171171

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ghash/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ghash"
3-
version = "0.3.1"
3+
version = "0.4.0-pre"
44
authors = ["RustCrypto Developers"]
55
license = "Apache-2.0 OR MIT"
66
description = """
@@ -16,7 +16,7 @@ edition = "2018"
1616

1717
[dependencies]
1818
opaque-debug = "0.3"
19-
polyval = { version = "0.4.4", features = ["mulx"], path = "../polyval" }
19+
polyval = { version = "=0.5.0-pre", features = ["mulx"], path = "../polyval" }
2020
zeroize = { version = "1", optional = true, default-features = false }
2121

2222
[dev-dependencies]

polyval/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "polyval"
3-
version = "0.4.5"
3+
version = "0.5.0-pre"
44
authors = ["RustCrypto Developers"]
55
license = "Apache-2.0 OR MIT"
66
description = """
@@ -17,7 +17,7 @@ edition = "2018"
1717
[dependencies]
1818
opaque-debug = "0.3"
1919
universal-hash = { version = "0.4", default-features = false }
20-
zeroize = { version = "1", optional = true, default-features = false }
20+
zeroize = { version = "1.2", optional = true, default-features = false }
2121

2222
[target.'cfg(any(target_arch = "x86_64", target_arch = "x86"))'.dependencies]
2323
cpuid-bool = "0.2"

polyval/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ dual licensed as above, without any additional terms or conditions.
5252
[docs-image]: https://docs.rs/polyval/badge.svg
5353
[docs-link]: https://docs.rs/polyval/
5454
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
55-
[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
55+
[rustc-image]: https://img.shields.io/badge/rustc-1.49+-blue.svg
5656
[build-image]: https://github.com/RustCrypto/universal-hashes/workflows/polyval/badge.svg?branch=master&event=push
5757
[build-link]: https://github.com/RustCrypto/universal-hashes/actions?query=workflow%3Apolyval
5858

polyval/src/backend/autodetect.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! to the "soft" backend when it's unavailable.
33
44
use crate::{backend, Block, Key};
5+
use core::mem::ManuallyDrop;
56
use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash};
67

78
cpuid_bool::new!(clmul_cpuid, "pclmulqdq", "sse4.1");
@@ -13,8 +14,8 @@ pub struct Polyval {
1314
}
1415

1516
union Inner {
16-
clmul: backend::clmul::Polyval,
17-
soft: backend::soft::Polyval,
17+
clmul: ManuallyDrop<backend::clmul::Polyval>,
18+
soft: ManuallyDrop<backend::soft::Polyval>,
1819
}
1920

2021
impl NewUniversalHash for Polyval {
@@ -26,11 +27,11 @@ impl NewUniversalHash for Polyval {
2627

2728
let inner = if clmul_present {
2829
Inner {
29-
clmul: backend::clmul::Polyval::new(h),
30+
clmul: ManuallyDrop::new(backend::clmul::Polyval::new(h)),
3031
}
3132
} else {
3233
Inner {
33-
soft: backend::soft::Polyval::new(h),
34+
soft: ManuallyDrop::new(backend::soft::Polyval::new(h)),
3435
}
3536
};
3637

@@ -45,27 +46,35 @@ impl UniversalHash for Polyval {
4546
#[inline]
4647
fn update(&mut self, x: &Block) {
4748
if self.token.get() {
48-
unsafe { self.inner.clmul.update(x) }
49+
unsafe { (*self.inner.clmul).update(x) }
4950
} else {
50-
unsafe { self.inner.soft.update(x) }
51+
unsafe { (*self.inner.soft).update(x) }
5152
}
5253
}
5354

5455
/// Reset internal state
5556
fn reset(&mut self) {
5657
if self.token.get() {
57-
unsafe { self.inner.clmul.reset() }
58+
unsafe { (*self.inner.clmul).reset() }
5859
} else {
59-
unsafe { self.inner.soft.reset() }
60+
unsafe { (*self.inner.soft).reset() }
6061
}
6162
}
6263

6364
/// Get POLYVAL result (i.e. computed `S` field element)
6465
fn finalize(self) -> Output<Self> {
6566
let output_bytes = if self.token.get() {
66-
unsafe { self.inner.clmul.finalize().into_bytes() }
67+
unsafe {
68+
ManuallyDrop::into_inner(self.inner.clmul)
69+
.finalize()
70+
.into_bytes()
71+
}
6772
} else {
68-
unsafe { self.inner.soft.finalize().into_bytes() }
73+
unsafe {
74+
ManuallyDrop::into_inner(self.inner.soft)
75+
.finalize()
76+
.into_bytes()
77+
}
6978
};
7079

7180
Output::new(output_bytes)
@@ -75,12 +84,14 @@ impl UniversalHash for Polyval {
7584
impl Clone for Polyval {
7685
fn clone(&self) -> Self {
7786
let inner = if self.token.get() {
87+
let clmul = unsafe { (*self.inner.clmul).clone() };
7888
Inner {
79-
clmul: unsafe { self.inner.clmul.clone() },
89+
clmul: ManuallyDrop::new(clmul),
8090
}
8191
} else {
92+
let soft = unsafe { (*self.inner.soft).clone() };
8293
Inner {
83-
soft: unsafe { self.inner.soft.clone() },
94+
soft: ManuallyDrop::new(soft),
8495
}
8596
};
8697

@@ -90,13 +101,3 @@ impl Clone for Polyval {
90101
}
91102
}
92103
}
93-
94-
#[cfg(feature = "zeroize")]
95-
impl Drop for Polyval {
96-
fn drop(&mut self) {
97-
use zeroize::Zeroize;
98-
const SIZE: usize = core::mem::size_of::<Polyval>();
99-
let state = unsafe { &mut *(self as *mut Polyval as *mut [u8; SIZE]) };
100-
state.zeroize();
101-
}
102-
}

polyval/src/backend/clmul.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ use core::arch::x86_64::*;
1313

1414
/// **POLYVAL**: GHASH-like universal hash over GF(2^128).
1515
#[derive(Clone)]
16-
#[cfg_attr(
17-
all(
18-
any(target_arch = "x86", target_arch = "x86_64"),
19-
not(feature = "force-soft")
20-
),
21-
derive(Copy)
22-
)] // TODO(tarcieri): switch to ManuallyDrop on MSRV 1.49+
2316
pub struct Polyval {
2417
h: __m128i,
2518
y: __m128i,
@@ -127,6 +120,15 @@ impl Polyval {
127120
}
128121
}
129122

123+
#[cfg(feature = "zeroize")]
124+
impl Drop for Polyval {
125+
fn drop(&mut self) {
126+
use zeroize::Zeroize;
127+
self.h.zeroize();
128+
self.y.zeroize();
129+
}
130+
}
131+
130132
#[inline(always)]
131133
unsafe fn xor4(e1: __m128i, e2: __m128i, e3: __m128i, e4: __m128i) -> __m128i {
132134
_mm_xor_si128(_mm_xor_si128(e1, e2), _mm_xor_si128(e3, e4))

polyval/src/backend/soft32.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
//! In other words, if we bit-reverse (over 32 bits) the operands, then we
2626
//! bit-reverse (over 64 bits) the result.
2727
28-
// TODO(tarcieri): fix zeroize when we switch to ManuallyDrop on MSRV 1.49+
29-
3028
use crate::{Block, Key};
3129
use core::{
3230
convert::TryInto,
@@ -35,23 +33,17 @@ use core::{
3533
};
3634
use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash};
3735

36+
#[cfg(feature = "zeroize")]
37+
use zeroize::Zeroize;
38+
3839
/// **POLYVAL**: GHASH-like universal hash over GF(2^128).
39-
#[allow(non_snake_case)]
4040
#[derive(Clone)]
41-
#[repr(align(16))]
42-
#[cfg_attr(
43-
all(
44-
any(target_arch = "x86", target_arch = "x86_64"),
45-
not(feature = "force-soft")
46-
),
47-
derive(Copy)
48-
)] // TODO(tarcieri): switch to ManuallyDrop on MSRV 1.49+
4941
pub struct Polyval {
5042
/// GF(2^128) field element input blocks are multiplied by
51-
H: U32x4,
43+
h: U32x4,
5244

5345
/// Field element representing the computed universal hash
54-
S: U32x4,
46+
s: U32x4,
5547
}
5648

5749
impl NewUniversalHash for Polyval {
@@ -60,8 +52,8 @@ impl NewUniversalHash for Polyval {
6052
/// Initialize POLYVAL with the given `H` field element
6153
fn new(h: &Key) -> Self {
6254
Self {
63-
H: h.into(),
64-
S: U32x4::default(),
55+
h: h.into(),
56+
s: U32x4::default(),
6557
}
6658
}
6759
}
@@ -72,12 +64,12 @@ impl UniversalHash for Polyval {
7264
/// Input a field element `X` to be authenticated
7365
fn update(&mut self, x: &Block) {
7466
let x = U32x4::from(x);
75-
self.S = (self.S + x) * self.H;
67+
self.s = (self.s + x) * self.h;
7668
}
7769

7870
/// Reset internal state
7971
fn reset(&mut self) {
80-
self.S = U32x4::default();
72+
self.s = U32x4::default();
8173
}
8274

8375
/// Get POLYVAL result (i.e. computed `S` field element)
@@ -86,7 +78,7 @@ impl UniversalHash for Polyval {
8678

8779
for (chunk, i) in block
8880
.chunks_mut(4)
89-
.zip(&[self.S.0, self.S.1, self.S.2, self.S.3])
81+
.zip(&[self.s.0, self.s.1, self.s.2, self.s.3])
9082
{
9183
chunk.copy_from_slice(&i.to_le_bytes());
9284
}
@@ -95,6 +87,14 @@ impl UniversalHash for Polyval {
9587
}
9688
}
9789

90+
#[cfg(feature = "zeroize")]
91+
impl Drop for Polyval {
92+
fn drop(&mut self) {
93+
self.h.zeroize();
94+
self.s.zeroize();
95+
}
96+
}
97+
9898
/// 4 x `u32` values
9999
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
100100
struct U32x4(u32, u32, u32, u32);
@@ -233,6 +233,16 @@ impl Mul for U32x4 {
233233
}
234234
}
235235

236+
#[cfg(feature = "zeroize")]
237+
impl Zeroize for U32x4 {
238+
fn zeroize(&mut self) {
239+
self.0.zeroize();
240+
self.1.zeroize();
241+
self.2.zeroize();
242+
self.3.zeroize();
243+
}
244+
}
245+
236246
/// Multiplication in GF(2)[X], truncated to the low 32-bits, with “holes”
237247
/// (sequences of zeroes) to avoid carry spilling.
238248
///

0 commit comments

Comments
 (0)