From d9a6dc39641062b0911eb14658a4f62226979cb5 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 18 May 2024 12:31:31 -0700 Subject: [PATCH] Bump MSRV to 1.64. * Use core::ffi::{c_int, c_uint} and remove our polyfills, eliminating libc as a dev-dependency. * Somplify CI configuration for symbol prefixing since 1.64.0 has llvm-tools-preview. * Use `core::ffi::CStr` in aarch64-apple-* feature detection. --- .github/workflows/ci.yml | 18 ++++++------------ Cargo.toml | 5 +---- src/aead/aes.rs | 12 ++++++++---- src/bssl.rs | 11 ++++++----- src/c.rs | 33 --------------------------------- src/constant_time.rs | 3 ++- src/cpu/arm/darwin.rs | 6 +++--- src/ec/curve25519/ops.rs | 6 +++--- src/ec/curve25519/x25519.rs | 5 +++-- src/polyfill/cstr.rs | 37 ++++++------------------------------- 10 files changed, 38 insertions(+), 98 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2591dde1c..f412e8b945 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,7 +169,7 @@ jobs: rust_channel: - stable # Keep in sync with Cargo.toml and similar `rust_channel` sections. - - 1.63.0 # MSRV + - 1.64.0 # MSRV # TODO: Move these to a daily/pre-release job. # - nightly # - beta @@ -305,12 +305,10 @@ jobs: # Check that all the needed symbol renaming was done. # TODO: Do this check on Windows too. - - if: ${{ (matrix.target != 'aarch64-apple-ios' || matrix.rust_channel != '1.63.0') && - !contains(matrix.host_os, 'windows') }} + - if: ${{ !contains(matrix.host_os, 'windows') }} run: rustup toolchain install --component=llvm-tools-preview ${{ matrix.rust_channel }} - - if: ${{ (matrix.target != 'aarch64-apple-ios' || matrix.rust_channel != '1.63.0') && - !contains(matrix.host_os, 'windows') }} + - if: ${{ !contains(matrix.host_os, 'windows') }} run: mk/check-symbol-prefixes.sh +${{ matrix.rust_channel }} --target=${{ matrix.target }} test-bench: @@ -387,7 +385,7 @@ jobs: - stable - nightly # Keep in sync with Cargo.toml and similar `rust_channel` sections. - - 1.63.0 # MSRV + - 1.64.0 # MSRV include: - target: aarch64-unknown-linux-musl @@ -435,12 +433,9 @@ jobs: # Check that all the needed symbol renaming was done. # TODO: Do this check on Windows too. - - if: ${{ (matrix.target != 'aarch64-apple-ios' || matrix.rust_channel != '1.63.0') && - !contains(matrix.host_os, 'windows') }} - run: rustup toolchain install --component=llvm-tools-preview ${{ matrix.rust_channel }} + - run: rustup toolchain install --component=llvm-tools-preview ${{ matrix.rust_channel }} - - if: ${{ (matrix.target != 'aarch64-apple-ios' || matrix.rust_channel != '1.63.0') && - !contains(matrix.host_os, 'windows') }} + - if: ${{ !contains(matrix.host_os, 'windows') }} run: mk/check-symbol-prefixes.sh +${{ matrix.rust_channel }} --target=${{ matrix.target }} # The wasm32-unknown-unknown targets have a different set of feature sets and @@ -498,7 +493,6 @@ jobs: ${{ matrix.webdriver }} mk/cargo.sh +${{ matrix.rust_channel }} test -vv --target=${{ matrix.target }} ${{ matrix.features }} ${{ matrix.mode }} # Check that all the needed symbol renaming was done. - # TODO: Do this check on Windows too. - run: rustup toolchain install --component=llvm-tools-preview ${{ matrix.rust_channel }} - run: mk/check-symbol-prefixes.sh +${{ matrix.rust_channel }} --target=${{ matrix.target }} diff --git a/Cargo.toml b/Cargo.toml index e48704833e..211e21c0e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/briansmith/ring" # Keep in sync with .github/workflows/ci.yml ("MSRV") and see the MSRV note # in cpu/arm.rs -rust-version = "1.63.0" +rust-version = "1.64.0" # Keep in sync with `links` below. version = "0.17.8" @@ -171,9 +171,6 @@ windows-sys = { version = "0.52", features = ["Win32_Foundation", "Win32_System_ [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies] wasm-bindgen-test = { version = "0.3.37", default-features = false } -[target.'cfg(any(unix, windows, target_os = "wasi"))'.dev-dependencies] -libc = { version = "0.2.148", default-features = false } - [build-dependencies] cc = { version = "1.0.83", default-features = false } diff --git a/src/aead/aes.rs b/src/aead/aes.rs index 15802da29d..717dc94c47 100644 --- a/src/aead/aes.rs +++ b/src/aead/aes.rs @@ -18,7 +18,11 @@ use crate::{ c, constant_time, cpu, error, polyfill::{self, slice}, }; -use core::{num::NonZeroUsize, ops::RangeFrom}; +use core::{ + ffi::{c_int, c_uint}, + num::NonZeroUsize, + ops::RangeFrom, +}; #[derive(Clone)] pub(super) struct Key { @@ -38,7 +42,7 @@ pub(super) struct Key { macro_rules! set_encrypt_key { ( $name:ident, $key_bytes:expr, $key:expr, $cpu_features:expr ) => {{ prefixed_extern! { - fn $name(user_key: *const u8, bits: BitLength, key: *mut AES_KEY) -> c::int; + fn $name(user_key: *const u8, bits: BitLength, key: *mut AES_KEY) -> c_int; } set_encrypt_key($name, $key_bytes, $key, $cpu_features) }}; @@ -46,7 +50,7 @@ macro_rules! set_encrypt_key { #[inline] unsafe fn set_encrypt_key( - f: unsafe extern "C" fn(*const u8, BitLength, *mut AES_KEY) -> c::int, + f: unsafe extern "C" fn(*const u8, BitLength, *mut AES_KEY) -> c_int, bytes: KeyBytes<'_>, key: &mut AES_KEY, _cpu_features: cpu::Features, @@ -363,7 +367,7 @@ impl Key { #[derive(Clone)] pub(super) struct AES_KEY { pub rd_key: [u32; 4 * (MAX_ROUNDS + 1)], - pub rounds: c::uint, + pub rounds: c_uint, } // Keep this in sync with `AES_MAXNR` in aes.h. diff --git a/src/bssl.rs b/src/bssl.rs index 8ce769da21..7e80c24ad0 100644 --- a/src/bssl.rs +++ b/src/bssl.rs @@ -12,7 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -use crate::{c, error}; +use crate::error; +use core::ffi::c_int; /// An `int` returned from a foreign function containing **1** if the function /// was successful or **0** if an error occurred. This is the convention used by @@ -20,7 +21,7 @@ use crate::{c, error}; #[derive(Clone, Copy, Debug)] #[must_use] #[repr(transparent)] -pub struct Result(c::int); +pub struct Result(c_int); impl From for core::result::Result<(), error::Unspecified> { fn from(ret: Result) -> Self { @@ -37,12 +38,12 @@ impl From for core::result::Result<(), error::Unspecified> { #[cfg(test)] mod tests { mod result { - use crate::{bssl, c}; - use core::mem; + use crate::bssl; + use core::{ffi::c_int, mem}; #[test] fn size_and_alignment() { - type Underlying = c::int; + type Underlying = c_int; assert_eq!(mem::size_of::(), mem::size_of::()); assert_eq!( mem::align_of::(), diff --git a/src/c.rs b/src/c.rs index 6f4ef07004..f4c49250d4 100644 --- a/src/c.rs +++ b/src/c.rs @@ -19,41 +19,8 @@ //! are all uniformly defined on the platforms we care about. This will //! probably change if/when we support 16-bit platforms or platforms where //! `usize` and `uintptr_t` are different sizes. -//! -//! TODO(MSRV-1.64): Use `core::ffi::{c_int, c_uint}`, remove the libc -//! compatibility testing, and remove the libc dev-dependency. - -// Keep in sync with the checks in base.h that verify these assumptions. - -#![allow(dead_code)] use core::num::NonZeroUsize; -pub(crate) type int = i32; -pub(crate) type uint = u32; pub(crate) type size_t = usize; pub(crate) type NonZero_size_t = NonZeroUsize; - -#[cfg(all(test, any(unix, windows)))] -mod tests { - use crate::c; - - #[test] - fn test_libc_compatible() { - { - let x: c::int = 1; - let _x: libc::c_int = x; - } - - { - let x: c::uint = 1; - let _x: libc::c_uint = x; - } - - { - let x: c::size_t = 1; - let _x: libc::size_t = x; - let _x: usize = x; - } - } -} diff --git a/src/constant_time.rs b/src/constant_time.rs index dd18463b5e..a1a739a579 100644 --- a/src/constant_time.rs +++ b/src/constant_time.rs @@ -15,6 +15,7 @@ //! Constant-time operations. use crate::{c, error}; +use core::ffi::c_int; /// Returns `Ok(())` if `a == b` and `Err(error::Unspecified)` otherwise. /// The comparison of `a` and `b` is done in constant time with respect to the @@ -32,7 +33,7 @@ pub fn verify_slices_are_equal(a: &[u8], b: &[u8]) -> Result<(), error::Unspecif } prefixed_extern! { - fn CRYPTO_memcmp(a: *const u8, b: *const u8, len: c::size_t) -> c::int; + fn CRYPTO_memcmp(a: *const u8, b: *const u8, len: c::size_t) -> c_int; } pub(crate) fn xor(mut a: [u8; N], b: [u8; N]) -> [u8; N] { diff --git a/src/cpu/arm/darwin.rs b/src/cpu/arm/darwin.rs index 667fb472c2..0a05f38cba 100644 --- a/src/cpu/arm/darwin.rs +++ b/src/cpu/arm/darwin.rs @@ -14,6 +14,7 @@ use super::{AES, ARMCAP_STATIC, NEON, PMULL, SHA256, SHA512}; use crate::polyfill::cstr; +use core::ffi::{c_int, c_void, CStr}; // ``` // $ rustc +1.61.0 --print cfg --target=aarch64-apple-ios | grep -E "neon|aes|sha|pmull" @@ -51,10 +52,9 @@ const _AARCH64_APPLE_DARWIN_TARGETS_EXPECTED_FEATURES: () = assert!(ARMCAP_STATIC == MIN_STATIC_FEATURES); pub fn detect_features() -> u32 { - fn detect_feature(name: cstr::Ref) -> bool { + fn detect_feature(name: &CStr) -> bool { use crate::polyfill; use core::mem; - use libc::{c_int, c_void}; let mut value: c_int = 0; let mut len = mem::size_of_val(&value); @@ -80,7 +80,7 @@ pub fn detect_features() -> u32 { let mut features = 0; // TODO(MSRV 1.77): Use c"..." literal. - const SHA512_NAME: cstr::Ref = + const SHA512_NAME: &CStr = cstr::unwrap_const_from_bytes_with_nul(b"hw.optional.armv8_2_sha512\0"); if detect_feature(SHA512_NAME) { features |= SHA512.mask; diff --git a/src/ec/curve25519/ops.rs b/src/ec/curve25519/ops.rs index 5fd83372c0..d2bee42812 100644 --- a/src/ec/curve25519/ops.rs +++ b/src/ec/curve25519/ops.rs @@ -17,10 +17,10 @@ pub use super::scalar::{MaskedScalar, Scalar, SCALAR_LEN}; use crate::{ - bssl, c, cpu, error, + bssl, cpu, error, limb::{Limb, LIMB_BITS}, }; -use core::marker::PhantomData; +use core::{ffi::c_int, marker::PhantomData}; // Elem` is `fe` in curve25519/internal.h. // Elem is `fe_loose` in curve25519/internal.h. @@ -82,7 +82,7 @@ impl ExtPoint { t: Elem::zero(), }; prefixed_extern! { - fn x25519_ge_scalarmult_base(h: &mut ExtPoint, a: &Scalar, has_fe25519_adx: c::int); + fn x25519_ge_scalarmult_base(h: &mut ExtPoint, a: &Scalar, has_fe25519_adx: c_int); } unsafe { x25519_ge_scalarmult_base(&mut r, scalar, has_fe25519_adx(cpu).into()); diff --git a/src/ec/curve25519/x25519.rs b/src/ec/curve25519/x25519.rs index fdfaa4c555..e00cacbc8d 100644 --- a/src/ec/curve25519/x25519.rs +++ b/src/ec/curve25519/x25519.rs @@ -15,7 +15,8 @@ //! X25519 Key agreement. use super::{ops, scalar::SCALAR_LEN}; -use crate::{agreement, c, constant_time, cpu, ec, error, rand}; +use crate::{agreement, constant_time, cpu, ec, error, rand}; +use core::ffi; static CURVE25519: ec::Curve = ec::Curve { public_key_len: PUBLIC_KEY_LEN, @@ -79,7 +80,7 @@ fn x25519_public_from_private( fn x25519_public_from_private_generic_masked( public_key_out: &mut PublicKey, private_key: &PrivateKey, - use_adx: c::int, + use_adx: ffi::c_int, ); } unsafe { diff --git a/src/polyfill/cstr.rs b/src/polyfill/cstr.rs index 74c0176fdb..5a4a718091 100644 --- a/src/polyfill/cstr.rs +++ b/src/polyfill/cstr.rs @@ -12,38 +12,14 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -//! Work around lack of `core::ffi::CStr` prior to Rust 1.64, and the lack of -//! `const fn` support for `CStr` in later versions. +//! Work around lack of `const fn` support for `CStr`. #![cfg(all(target_arch = "aarch64", target_vendor = "apple"))] -// TODO(MSRV 1.64): Use `core::ffi::c_char`. -use libc::c_char; +use core::ffi::CStr; -// TODO(MSRV 1.64): Replace with `&core::ffi::CStr`. -pub struct Ref(&'static [u8]); - -impl Ref { - #[inline(always)] - pub fn as_ptr(&self) -> *const c_char { - const _SAME_ALIGNMENT: () = - assert!(core::mem::align_of::() == core::mem::align_of::()); - const _SAME_SIZE: () = - assert!(core::mem::size_of::() == core::mem::size_of::()); - - // It is safe to cast a `*const u8` to a `const c_char` as they are the - // same size and alignment. - self.0.as_ptr().cast() - } - - // SAFETY: Same as `CStr::from_bytes_with_nul_unchecked`. - const unsafe fn from_bytes_with_nul_unchecked(value: &'static [u8]) -> Self { - Self(value) - } -} - -pub const fn unwrap_const_from_bytes_with_nul(value: &'static [u8]) -> Ref { - // XXX: We cannot use `unwrap_const` since `Ref`/`CStr` is not `Copy`. +pub const fn unwrap_const_from_bytes_with_nul(value: &'static [u8]) -> &'static CStr { + // XXX: We cannot use `unwrap_const` since `CStr` is not `Copy`. match const_from_bytes_with_nul(value) { Some(r) => r, None => panic!("const_from_bytes_with_nul failed"), @@ -52,7 +28,7 @@ pub const fn unwrap_const_from_bytes_with_nul(value: &'static [u8]) -> Ref { // TODO(MSRV 1.72): Replace with `CStr::from_bytes_with_nul`. #[inline(always)] -const fn const_from_bytes_with_nul(value: &'static [u8]) -> Option { +const fn const_from_bytes_with_nul(value: &'static [u8]) -> Option<&'static CStr> { const fn const_contains(mut value: &[u8], needle: &u8) -> bool { while let [head, tail @ ..] = value { if *head == *needle { @@ -69,8 +45,7 @@ const fn const_from_bytes_with_nul(value: &'static [u8]) -> Option { // SAFETY: // * `value` is nul-terminated according to the slice pattern. // * `value` doesn't contain any interior null, by the guard. - // TODO(MSRV 1.64): Use `CStr::from_bytes_with_nul_unchecked` - Some(unsafe { Ref::from_bytes_with_nul_unchecked(value) }) + Some(unsafe { CStr::from_bytes_with_nul_unchecked(value) }) } _ => None, }