Skip to content

Commit d300cd1

Browse files
committed
AEAD: Reduce punning of architecture-specific implementations.
Replace the punning with separate implementations so that code coverage can measure them better. The punning is avoided at construction of the key objects, but not necessarily everywhere else; this is good enough for us to see that each implementation is selected during coverage testing, while still minimizing duplication.
1 parent b6cb15f commit d300cd1

File tree

5 files changed

+94
-51
lines changed

5 files changed

+94
-51
lines changed

src/aead/aes/hw.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,6 @@
2020

2121
use super::{Block, Counter, EncryptBlock, EncryptCtr32, Iv, KeyBytes, Overlapping, AES_KEY};
2222
use crate::{cpu, error};
23-
use cfg_if::cfg_if;
24-
25-
cfg_if! {
26-
if #[cfg(all(target_arch = "aarch64", target_endian = "little"))] {
27-
pub(in super::super) type RequiredCpuFeatures = cpu::aarch64::Aes;
28-
pub(in super::super) type OptionalCpuFeatures = ();
29-
} else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
30-
use cpu::intel::{Aes, Avx, Ssse3};
31-
// Some functions seem to have been written to require only SSE/SSE2
32-
// but there seem to be no SSSE3-less CPUs with AES-NI, and we don't
33-
// have feature detection for SSE2.
34-
pub(in super::super) type RequiredCpuFeatures = (Aes, Ssse3);
35-
pub(in super::super) type OptionalCpuFeatures = Avx;
36-
}
37-
}
3823

3924
#[derive(Clone)]
4025
pub struct Key {
@@ -45,22 +30,38 @@ impl Key {
4530
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
4631
pub(in super::super) fn new(
4732
bytes: KeyBytes<'_>,
48-
_required_cpu_features: RequiredCpuFeatures,
49-
_optional_cpu_features: Option<OptionalCpuFeatures>,
33+
_required_cpu_features: cpu::aarch64::Aes,
34+
_optional_cpu_features: Option<()>,
5035
) -> Result<Self, error::Unspecified> {
5136
let inner = unsafe { set_encrypt_key!(aes_hw_set_encrypt_key, bytes) }?;
5237
Ok(Self { inner })
5338
}
5439

55-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
40+
#[cfg(target_arch = "x86")]
41+
pub(in super::super) fn new(
42+
bytes: KeyBytes<'_>,
43+
_required_cpu_features: (cpu::intel::Aes, cpu::intel::Ssse3),
44+
optional_cpu_features: Option<cpu::intel::Avx>,
45+
) -> Result<Self, error::Unspecified> {
46+
// Ssse3 is required, but upstream only uses this if there is also Avx;
47+
// presumably the base version is faster on pre-AVX CPUs.
48+
let inner = if let Some(cpu::intel::Avx { .. }) = optional_cpu_features {
49+
unsafe { set_encrypt_key!(aes_hw_set_encrypt_key_alt, bytes) }?
50+
} else {
51+
unsafe { set_encrypt_key!(aes_hw_set_encrypt_key_base, bytes) }?
52+
};
53+
Ok(Self { inner })
54+
}
55+
56+
#[cfg(target_arch = "x86_64")]
5657
pub(in super::super) fn new(
5758
bytes: KeyBytes<'_>,
58-
(Aes { .. }, Ssse3 { .. }): RequiredCpuFeatures,
59-
optional_cpu_features: Option<OptionalCpuFeatures>,
59+
_required_cpu_features: (cpu::intel::Aes, cpu::intel::Ssse3),
60+
optional_cpu_features: Option<cpu::intel::Avx>,
6061
) -> Result<Self, error::Unspecified> {
6162
// Ssse3 is required, but upstream only uses this if there is also Avx;
6263
// presumably the base version is faster on pre-AVX CPUs.
63-
let inner = if let Some(Avx { .. }) = optional_cpu_features {
64+
let inner = if let Some(cpu::intel::Avx { .. }) = optional_cpu_features {
6465
unsafe { set_encrypt_key!(aes_hw_set_encrypt_key_alt, bytes) }?
6566
} else {
6667
unsafe { set_encrypt_key!(aes_hw_set_encrypt_key_base, bytes) }?

src/aead/aes/vp.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,43 @@
2222
use super::{Block, Counter, EncryptBlock, EncryptCtr32, Iv, KeyBytes, Overlapping, AES_KEY};
2323
use crate::{cpu, error};
2424

25-
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
26-
type RequiredCpuFeatures = cpu::aarch64::Neon;
27-
28-
#[cfg(all(target_arch = "arm", target_endian = "little"))]
29-
type RequiredCpuFeatures = cpu::arm::Neon;
30-
31-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
32-
pub(in super::super) type RequiredCpuFeatures = cpu::intel::Ssse3;
33-
3425
#[derive(Clone)]
3526
pub(in super::super) struct Key {
3627
inner: AES_KEY,
3728
}
3829

3930
impl Key {
31+
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
32+
pub(in super::super) fn new(
33+
bytes: KeyBytes<'_>,
34+
_cpu: cpu::aarch64::Neon,
35+
) -> Result<Self, error::Unspecified> {
36+
let inner = unsafe { set_encrypt_key!(vpaes_set_encrypt_key, bytes) }?;
37+
Ok(Self { inner })
38+
}
39+
40+
#[cfg(all(target_arch = "arm", target_endian = "little"))]
41+
pub(in super::super) fn new(
42+
bytes: KeyBytes<'_>,
43+
_cpu: cpu::arm::Neon,
44+
) -> Result<Self, error::Unspecified> {
45+
let inner = unsafe { set_encrypt_key!(vpaes_set_encrypt_key, bytes) }?;
46+
Ok(Self { inner })
47+
}
48+
49+
#[cfg(target_arch = "x86")]
50+
pub(in super::super) fn new(
51+
bytes: KeyBytes<'_>,
52+
_cpu: cpu::intel::Ssse3,
53+
) -> Result<Self, error::Unspecified> {
54+
let inner = unsafe { set_encrypt_key!(vpaes_set_encrypt_key, bytes) }?;
55+
Ok(Self { inner })
56+
}
57+
58+
#[cfg(target_arch = "x86_64")]
4059
pub(in super::super) fn new(
4160
bytes: KeyBytes<'_>,
42-
_cpu: RequiredCpuFeatures,
61+
_cpu: cpu::intel::Ssse3,
4362
) -> Result<Self, error::Unspecified> {
4463
let inner = unsafe { set_encrypt_key!(vpaes_set_encrypt_key, bytes) }?;
4564
Ok(Self { inner })

src/aead/aes_gcm.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,18 @@ impl DynKey {
143143
Ok(Self::Simd(Combo { aes_key, gcm_key }))
144144
}
145145

146-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
146+
#[cfg(target_arch = "x86")]
147147
#[inline(never)]
148-
fn new_ssse3(
149-
key: aes::KeyBytes,
150-
cpu: aes::vp::RequiredCpuFeatures,
151-
) -> Result<Self, error::Unspecified> {
148+
fn new_ssse3(key: aes::KeyBytes, cpu: cpu::intel::Ssse3) -> Result<Self, error::Unspecified> {
149+
let aes_key = aes::vp::Key::new(key, cpu)?;
150+
let gcm_key_value = derive_gcm_key_value(&aes_key);
151+
let gcm_key = gcm::fallback::Key::new(gcm_key_value);
152+
Ok(Self::Simd(Combo { aes_key, gcm_key }))
153+
}
154+
155+
#[cfg(target_arch = "x86_64")]
156+
#[inline(never)]
157+
fn new_ssse3(key: aes::KeyBytes, cpu: cpu::intel::Ssse3) -> Result<Self, error::Unspecified> {
152158
let aes_key = aes::vp::Key::new(key, cpu)?;
153159
let gcm_key_value = derive_gcm_key_value(&aes_key);
154160
let gcm_key = gcm::fallback::Key::new(gcm_key_value);

src/aead/gcm/clmul.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,35 @@ use crate::cpu;
2424
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
2525
use {super::UpdateBlocks, crate::polyfill::slice::AsChunks};
2626

27-
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
28-
pub(in super::super) type RequiredCpuFeatures = cpu::aarch64::PMull;
29-
30-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
31-
pub(in super::super) type RequiredCpuFeatures = (cpu::intel::ClMul, cpu::intel::Ssse3);
32-
3327
#[derive(Clone)]
3428
pub struct Key {
3529
h_table: HTable,
3630
}
3731

3832
impl Key {
39-
#[cfg_attr(target_arch = "x86_64", inline(never))]
40-
pub(in super::super) fn new(value: KeyValue, _cpu: RequiredCpuFeatures) -> Self {
33+
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
34+
pub(in super::super) fn new(value: KeyValue, _cpu: cpu::aarch64::PMull) -> Self {
35+
Self {
36+
h_table: unsafe { htable_new!(gcm_init_clmul, value) },
37+
}
38+
}
39+
40+
#[cfg(target_arch = "x86")]
41+
pub(in super::super) fn new(
42+
value: KeyValue,
43+
_cpu: (cpu::intel::ClMul, cpu::intel::Ssse3),
44+
) -> Self {
45+
Self {
46+
h_table: unsafe { htable_new!(gcm_init_clmul, value) },
47+
}
48+
}
49+
50+
#[cfg(target_arch = "x86_64")]
51+
#[inline(never)]
52+
pub(in super::super) fn new(
53+
value: KeyValue,
54+
_cpu: (cpu::intel::ClMul, cpu::intel::Ssse3),
55+
) -> Self {
4156
Self {
4257
h_table: unsafe { htable_new!(gcm_init_clmul, value) },
4358
}

src/aead/gcm/neon.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,21 @@
2020
use super::{HTable, KeyValue, UpdateBlock, UpdateBlocks, Xi, BLOCK_LEN};
2121
use crate::{cpu, polyfill::slice::AsChunks};
2222

23-
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
24-
pub(in super::super) type RequiredCpuFeatures = cpu::aarch64::Neon;
25-
26-
#[cfg(all(target_arch = "arm", target_endian = "little"))]
27-
pub(in super::super) type RequiredCpuFeatures = cpu::arm::Neon;
28-
2923
#[derive(Clone)]
3024
pub struct Key {
3125
h_table: HTable,
3226
}
3327

3428
impl Key {
35-
pub(in super::super) fn new(value: KeyValue, _cpu: RequiredCpuFeatures) -> Self {
29+
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
30+
pub(in super::super) fn new(value: KeyValue, _cpu: cpu::aarch64::Neon) -> Self {
31+
Self {
32+
h_table: unsafe { htable_new!(gcm_init_neon, value) },
33+
}
34+
}
35+
36+
#[cfg(all(target_arch = "arm", target_endian = "little"))]
37+
pub(in super::super) fn new(value: KeyValue, _cpu: cpu::arm::Neon) -> Self {
3638
Self {
3739
h_table: unsafe { htable_new!(gcm_init_neon, value) },
3840
}

0 commit comments

Comments
 (0)