Skip to content

Commit

Permalink
Restrict usage of assembly code to little endian for ARM & AAarch64.
Browse files Browse the repository at this point in the history
We have this in cpu/arm.rs to force the build to fail for big-endian
ARM/AArch64 targets:

```
const _ASSUMED_ENDIANNESS: () = assert!(cfg!(target_endian = "little"));
```

As a step towards removing that restriction, change the `cfg` logic for
ARM and Aarch64 to take the endianness into consideration.

Also, don't try to assembly any assembly language sources if the target
isn't little endian.
  • Loading branch information
briansmith committed Jan 12, 2025
1 parent 7476129 commit ed4f33e
Show file tree
Hide file tree
Showing 28 changed files with 282 additions and 124 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ cfg-if = { version = "1.0.0", default-features = false }
getrandom = { version = "0.2.10" }
untrusted = { version = "0.9" }

[target.'cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86",target_arch = "x86_64"))'.dependencies]
[target.'cfg(any(all(target_arch = "aarch64", target_endian = "little"), all(target_arch = "arm", target_endian = "little"), target_arch = "x86",target_arch = "x86_64"))'.dependencies]
spin = { version = "0.9.8", default-features = false, features = ["once"] }

[target.'cfg(all(any(target_arch = "aarch64", target_arch = "arm"), any(target_os = "android", target_os = "linux")))'.dependencies]
[target.'cfg(all(any(all(target_arch = "aarch64", target_endian = "little"), all(target_arch = "arm", target_endian = "little")), any(target_os = "android", target_os = "linux")))'.dependencies]
libc = { version = "0.2.148", default-features = false }

[target.'cfg(all(target_arch = "aarch64", target_vendor = "apple", any(target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "visionos", target_os = "watchos")))'.dependencies]
[target.'cfg(all(all(target_arch = "aarch64", target_endian = "little"), target_vendor = "apple", any(target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "visionos", target_os = "watchos")))'.dependencies]
libc = { version = "0.2.155", default-features = false }

[target.'cfg(all(target_arch = "aarch64", target_os = "windows"))'.dependencies]
[target.'cfg(all(all(target_arch = "aarch64", target_endian = "little"), target_os = "windows"))'.dependencies]
windows-sys = { version = "0.52", features = ["Win32_Foundation", "Win32_System_Threading"] }

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies]
Expand Down
12 changes: 9 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ fn ring_build_rs_main(c_root_dir: &Path, core_name_and_version: &str) {
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
let endian = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap();
let is_little_endian = endian == "little";

let is_git = fs::metadata(c_root_dir.join(".git")).is_ok();

Expand All @@ -321,9 +323,13 @@ fn ring_build_rs_main(c_root_dir: &Path, core_name_and_version: &str) {
force_warnings_into_errors,
};

let asm_target = ASM_TARGETS.iter().find(|asm_target| {
asm_target.arch == target.arch && asm_target.oss.contains(&target.os.as_ref())
});
let asm_target = if is_little_endian {
ASM_TARGETS.iter().find(|asm_target| {
asm_target.arch == target.arch && asm_target.oss.contains(&target.os.as_ref())
})
} else {
None
};

// If `.git` exists then assume this is the "local hacking" case where
// we want to make it easy to build *ring* using `cargo build`/`cargo test`
Expand Down
32 changes: 22 additions & 10 deletions src/aead/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub type Overlapping<'o> = overlapping::Overlapping<'o, u8>;
pub type OverlappingPartialBlock<'o> = overlapping::PartialBlock<'o, u8, BLOCK_LEN>;

cfg_if! {
if #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] {
if #[cfg(any(all(target_arch = "aarch64", target_endian = "little"), target_arch = "x86_64"))] {
pub(super) use ffi::AES_KEY;
} else {
use ffi::AES_KEY;
Expand All @@ -45,12 +45,16 @@ cfg_if! {

#[derive(Clone)]
pub(super) enum Key {
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
Hw(hw::Key),

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]
Expand All @@ -65,14 +69,18 @@ impl Key {
bytes: KeyBytes<'_>,
cpu_features: cpu::Features,
) -> Result<Self, error::Unspecified> {
#[cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]
if let Some(hw_features) = cpu_features.get_feature() {
return Ok(Self::Hw(hw::Key::new(bytes, hw_features)?));
}

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
Expand All @@ -88,12 +96,16 @@ impl Key {
#[inline]
fn encrypt_block(&self, a: Block) -> Block {
match self {
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
Key::Hw(inner) => inner.encrypt_block(a),

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]
Expand Down
2 changes: 1 addition & 1 deletion src/aead/aes/bs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#![cfg(target_arch = "arm")]
#![cfg(all(target_arch = "arm", target_endian = "little"))]

use super::{Counter, Overlapping, AES_KEY};

Expand Down
2 changes: 1 addition & 1 deletion src/aead/aes/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl AES_KEY {
}
}

#[cfg(target_arch = "arm")]
#[cfg(all(target_arch = "arm", target_endian = "little"))]
impl AES_KEY {
pub(super) unsafe fn derive(
f: for<'a> unsafe extern "C" fn(*mut AES_KEY, &'a AES_KEY),
Expand Down
13 changes: 10 additions & 3 deletions src/aead/aes/hw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#![cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))]
#![cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]

use super::{Block, Counter, EncryptBlock, EncryptCtr32, Iv, KeyBytes, Overlapping, AES_KEY};
use crate::{cpu, error};

#[cfg(target_arch = "aarch64")]
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
pub(in super::super) type RequiredCpuFeatures = cpu::arm::Aes;

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Expand All @@ -37,7 +41,10 @@ impl Key {
Ok(Self { inner })
}

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64"
))]
#[must_use]
pub(in super::super) fn inner_less_safe(&self) -> &AES_KEY {
&self.inner
Expand Down
22 changes: 16 additions & 6 deletions src/aead/aes/vp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#![cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]

use super::{Block, Counter, EncryptBlock, EncryptCtr32, Iv, KeyBytes, Overlapping, AES_KEY};
use crate::{cpu, error};

#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little")
))]
type RequiredCpuFeatures = cpu::arm::Neon;

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Expand All @@ -43,7 +46,11 @@ impl Key {
}
}

#[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86_64"
))]
impl EncryptBlock for Key {
fn encrypt_block(&self, block: Block) -> Block {
super::encrypt_block_using_encrypt_iv_xor_block(self, block)
Expand All @@ -54,14 +61,17 @@ impl EncryptBlock for Key {
}
}

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64"
))]
impl EncryptCtr32 for Key {
fn ctr32_encrypt_within(&self, in_out: Overlapping<'_>, ctr: &mut Counter) {
unsafe { ctr32_encrypt_blocks!(vpaes_ctr32_encrypt_blocks, in_out, &self.inner, ctr) }
}
}

#[cfg(target_arch = "arm")]
#[cfg(all(target_arch = "arm", target_endian = "little"))]
impl EncryptCtr32 for Key {
fn ctr32_encrypt_within(&self, in_out: Overlapping<'_>, ctr: &mut Counter) {
use super::{super::overlapping::IndexError, bs, BLOCK_LEN};
Expand Down
68 changes: 50 additions & 18 deletions src/aead/aes_gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use core::ops::RangeFrom;
use aes::EncryptCtr32 as _;

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]
Expand All @@ -53,10 +53,17 @@ enum DynKey {
#[cfg(target_arch = "x86_64")]
AesHwClMulAvxMovbe(Combo<aes::hw::Key, gcm::clmulavxmovbe::Key>),

#[cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
))]
AesHwClMul(Combo<aes::hw::Key, gcm::clmul::Key>),

#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little")
))]
Simd(Combo<aes::vp::Key, gcm::neon::Key>),

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Expand All @@ -75,15 +82,22 @@ impl DynKey {
return Ok(Self::AesHwClMulAvxMovbe(Combo { aes_key, gcm_key }));
}

#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
if let (Some(aes), Some(gcm)) = (cpu_features.get_feature(), cpu_features.get_feature()) {
let aes_key = aes::hw::Key::new(key, aes)?;
let gcm_key_value = derive_gcm_key_value(&aes_key);
let gcm_key = gcm::clmul::Key::new(gcm_key_value, gcm);
return Ok(Self::AesHwClMul(Combo { aes_key, gcm_key }));
}

#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little")
))]
if let (Some(aes), Some(gcm)) = (cpu_features.get_feature(), cpu_features.get_feature()) {
let aes_key = aes::vp::Key::new(key, aes)?;
let gcm_key_value = derive_gcm_key_value(&aes_key);
Expand Down Expand Up @@ -171,7 +185,7 @@ pub(super) fn seal(
seal_finish(aes_key, auth, remainder, ctr, tag_iv)
}

#[cfg(target_arch = "aarch64")]
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
DynKey::AesHwClMul(Combo { aes_key, gcm_key }) => {
use crate::bits::BitLength;

Expand Down Expand Up @@ -215,8 +229,8 @@ pub(super) fn seal(
DynKey::AesHwClMul(c) => seal_strided(c, aad, in_out, ctr, tag_iv),

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
Expand All @@ -228,14 +242,20 @@ pub(super) fn seal(

#[cfg_attr(
any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86",
target_arch = "x86_64"
),
inline(never)
)]
#[cfg_attr(any(target_arch = "aarch64", target_arch = "x86_64"), cold)]
#[cfg_attr(
any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64"
),
cold
)]
fn seal_strided<A: aes::EncryptBlock + aes::EncryptCtr32, G: gcm::UpdateBlocks + gcm::Gmult>(
Combo { aes_key, gcm_key }: &Combo<A, G>,
aad: Aad<&[u8]>,
Expand Down Expand Up @@ -285,7 +305,10 @@ pub(super) fn open(
in_out_slice: &mut [u8],
src: RangeFrom<usize>,
) -> Result<Tag, error::Unspecified> {
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
#[cfg(any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64"
))]
let in_out = Overlapping::new(in_out_slice, src.clone()).map_err(error::erase::<IndexError>)?;

let mut ctr = Counter::one(nonce);
Expand Down Expand Up @@ -357,7 +380,7 @@ pub(super) fn open(
open_finish(aes_key, auth, in_out, ctr, tag_iv)
}

#[cfg(target_arch = "aarch64")]
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
DynKey::AesHwClMul(Combo { aes_key, gcm_key }) => {
use crate::bits::BitLength;

Expand Down Expand Up @@ -409,8 +432,8 @@ pub(super) fn open(
DynKey::AesHwClMul(c) => open_strided(c, aad, in_out_slice, src, ctr, tag_iv),

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little"),
target_arch = "x86_64",
target_arch = "x86"
))]
Expand All @@ -423,7 +446,10 @@ pub(super) fn open(
#[cfg_attr(
any(
all(
any(target_arch = "aarch64", target_arch = "arm"),
any(
all(target_arch = "aarch64", target_endian = "little"),
all(target_arch = "arm", target_endian = "little")
),
target_feature = "neon"
),
all(
Expand All @@ -433,7 +459,13 @@ pub(super) fn open(
),
inline(never)
)]
#[cfg_attr(any(target_arch = "aarch64", target_arch = "x86_64"), cold)]
#[cfg_attr(
any(
all(target_arch = "aarch64", target_endian = "little"),
target_arch = "x86_64"
),
cold
)]
fn open_strided<A: aes::EncryptBlock + aes::EncryptCtr32, G: gcm::UpdateBlocks + gcm::Gmult>(
Combo { aes_key, gcm_key }: &Combo<A, G>,
aad: Aad<&[u8]>,
Expand Down
Loading

0 comments on commit ed4f33e

Please sign in to comment.