Skip to content

Commit

Permalink
Add ARMv8.4 cpu feature detection support (GH weidai11#685) (weidai11…
Browse files Browse the repository at this point in the history
…#687)

This PR adds ARMv8.4 cpu feature detection support. Previously we only needed ARMv8.1 and things were much easier. For example, ARMv8.1 `__ARM_FEATURE_CRYPTO` meant PMULL, AES, SHA-1 and SHA-256 were available. ARMv8.4 `__ARM_FEATURE_CRYPTO` means PMULL, AES, SHA-1, SHA-256, SHA-512, SHA-3, SM3 and SM4 are  available. 

We still use the same pattern as before. We make something available based on compiler version and/or preprocessor macros. But this time around we had to tighten things up a bit to ensure ARMv8.4 did not cross-pollinate down into ARMv8.1.

ARMv8.4 is largely untested at the moment. There is no hardware in the field and CI lacks QEMU with the relevant patches/support. We will probably have to revisit some of this stuff in the future.

Since this update applies to ARM gadgets we took the time to expand Android and iOS testing on Travis. Travis now tests more platforms, and includes Autotools and CMake builds, too.
  • Loading branch information
noloader authored Jul 15, 2018
1 parent 2600f6d commit 4e3a1ea
Show file tree
Hide file tree
Showing 20 changed files with 264 additions and 142 deletions.
44 changes: 39 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,16 @@ matrix:
include:
- os: linux
env:
- BUILD_MODE=android
- PLATFORM=armeabi
- BUILD_MODE=autotools
- os: linux
env:
- BUILD_MODE=cmake
- os: osx
env:
- BUILD_MODE=autotools
- os: osx
env:
- BUILD_MODE=cmake
- os: linux
env:
- BUILD_MODE=android
Expand Down Expand Up @@ -85,6 +93,10 @@ matrix:
env:
- BUILD_MODE=ios
- PLATFORM=iPhoneOS
- os: osx
env:
- BUILD_MODE=ios
- PLATFORM=Arm64
- os: osx
env:
- BUILD_MODE=ios
Expand All @@ -103,21 +115,43 @@ matrix:
env:
- BUILD_MODE=ios
- PLATFORM=WatchOS
- os: linux
env:
- BUILD_MODE=android
- PLATFORM=armeabi
- os: linux
env:
- BUILD_MODE=android
- PLATFORM=mipsel
- os: linux
env:
- BUILD_MODE=android
- PLATFORM=mipsel64

before_install:
- |
if [[ "$BUILD_MODE" == "android" ]]; then
# https://github.com/travis-ci/travis-ci/issues/9037
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A145
TestScripts/install-android.sh
fi
script:
- |
if [[ "$BUILD_MODE" == "ios" ]]; then
cp ./TestScripts/setenv-ios.sh .
TestScripts/cryptest-ios.sh
cp ./TestScripts/cryptest-ios.sh .
./cryptest-ios.sh
elif [[ "$BUILD_MODE" == "android" ]]; then
cp ./TestScripts/setenv-android.sh .
TestScripts/cryptest-android.sh
cp ./TestScripts/setenv-android-gcc.sh .
cp ./TestScripts/cryptest-android.sh .
./cryptest-android.sh
elif [[ "$BUILD_MODE" == "autotools" ]]; then
cp ./TestScripts/cryptest-autotools.sh .
./cryptest-autotools.sh
elif [[ "$BUILD_MODE" == "cmake" ]]; then
cp ./TestScripts/cryptest-cmake.sh .
./cryptest-cmake.sh
elif [[ "$BUILD_MODE" == "debug" ]]; then
CXXFLAGS="-DDEBUG -g2 -O1" make -j "$BUILD_JOBS"
./cryptest.exe v
Expand Down
4 changes: 3 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,14 @@ ifeq ($(IS_NEON),1)
HAVE_NEON = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon -dM -E - 2>/dev/null | $(GREP) -i -c -E '\<__ARM_NEON\>')
ifeq ($(HAVE_NEON),1)
NEON_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
AES_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
CRC_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
GCM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
BLAKE2_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
CHAM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
LEA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SHA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMECK_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMON_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SPECK_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
Expand Down
22 changes: 18 additions & 4 deletions GNUmakefile-cross
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ endif

IS_i686 := $(shell echo "$HOSTX" | $(EGREP) -v 64 | $(EGREP) -i -c 'i.86')
IS_x86_64 := $(shell echo "$HOSTX" | $(EGREP) -i -c 'x86_64|amd64')
IS_ARM := $(shell echo "$HOSTX" | $(EGREP) -i -c 'arm')
IS_ARM32 := $(shell echo "$(HOSTX)" | $(EGREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMv8 := $(shell echo "$HOSTX" | $(EGREP) -i -c 'aarch32|aarch64')

CLANG_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "clang")
GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -v -E '(llvm|clang)' | $(EGREP) -i -c -E '(gcc|g\+\+)')
CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -i -c -E '(llvm|clang)')

IS_IOS ?= 0
IS_ANDROID ?= 0
Expand Down Expand Up @@ -321,16 +322,25 @@ endif

# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
SRCS := cryptlib.cpp cpu.cpp integer.cpp $(filter-out cryptlib.cpp cpu.cpp integer.cpp pch.cpp simple.cpp winpipes.cpp cryptlib_bds.cpp,$(sort $(wildcard *.cpp)))

# For Makefile.am; resource.h is Windows
INCL := $(filter-out resource.h,$(sort $(wildcard *.h)))

# Cryptogams AES for ARMv4 and above. We couple to ARMv7.
# Disable Thumb via -marm due to unaligned byte buffers.
ifeq ($(IS_ARM32),1)
CRYPTOGAMS_AES_ARCH = -march=armv7-a -marm
SRCS += aes-armv4.S
endif

# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
OBJS := $(SRCS:.cpp=.o)
OBJS := $(OBJS:.S=.o)

# List test.cpp first to tame C++ static initialization problems.
TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp
TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp dlltest.cpp fipsalgt.cpp
TESTINCL := bench.h factory.h validate.h

# Test objects
TESTOBJS := $(TESTSRCS:.cpp=.o)
LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS))

Expand Down Expand Up @@ -494,6 +504,10 @@ endif # Dependencies
cpu-features.o: cpu-features.h cpu-features.c
$(CXX) $(strip $(CXXFLAGS) -fpermissive -c) cpu-features.c

# Cryptogams ARM asm implementation. CRYPTOGAMS_AES_ARCH includes -marm.
aes-armv4.o : aes-armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_AES_ARCH) -c) $<

# SSE4.2 or NEON available
aria-simd.o : aria-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(ARIA_FLAG) -c) $<
Expand Down
1 change: 1 addition & 0 deletions Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,4 @@ June 2015 - Changing of the guard. Wei Dai turned the library over to the
still provides guidance when we have questions.

Originally written by Wei Dai, maintained by the Crypto++ Project

8 changes: 5 additions & 3 deletions TestScripts/cryptest-android.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ else
PLATFORMS=(${PLATFORM})
fi
RUNTIMES=(gnu-static gnu-shared stlport-static stlport-shared) #llvm-static llvm-shared

for platform in ${PLATFORMS[@]}
do
for runtime in ${RUNTIMES[@]}
Expand All @@ -30,14 +31,15 @@ do
# Test if we can set the environment for the platform
./setenv-android-gcc.sh "$platform" "$runtime"

if [ "$?" -eq "0" ]; then
if [ "$?" -eq "0" ];
then
echo
echo "Building for $platform using $runtime..."
echo

# run in subshell to not keep any env vars
(
. ./setenv-android-gcc.sh "$platform" "$runtime" > /dev/null 2>&1
source ./setenv-android-gcc.sh "$platform" "$runtime" > /dev/null 2>&1
make -f GNUmakefile-cross static dynamic cryptest.exe
if [ "$?" -eq "0" ]; then
echo "$platform:$runtime ==> SUCCESS" >> /tmp/build.log
Expand All @@ -48,7 +50,7 @@ do
)
else
echo
echo "$platform with $runtime not supported by Android"
echo "There were problems testing $platform with $runtime"
echo "$platform:$runtime ==> FAILURE" >> /tmp/build.log
touch /tmp/build.failed
fi
Expand Down
2 changes: 1 addition & 1 deletion TestScripts/cryptest-ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# ====================================================================

if [ -z "${PLATFORM-}" ]; then
PLATFORMS=(iPhoneOS iPhoneSimulator WatchOS WatchSimulator AppleTVOS AppleTVSimulator)
PLATFORMS=(iPhoneOS iPhoneSimulator Arm64 WatchOS WatchSimulator AppleTVOS AppleTVSimulator)
else
PLATFORMS=(${PLATFORM})
fi
Expand Down
4 changes: 2 additions & 2 deletions TestScripts/setenv-android-gcc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ case "$THE_ARCH" in
TOOLCHAIN_NAME="i686-linux-android"
AOSP_ABI="x86"
AOSP_ARCH="arch-x86"
AOSP_FLAGS="-mtune=intel -mssse3 -mfpmath=sse -DCRYPTOPP_DISABLE_SSE4 -funwind-tables -fexceptions -frtti"
AOSP_FLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
;;
x86_64|x64)
TOOLCHAIN_ARCH="x86_64"
TOOLCHAIN_NAME="x86_64-linux-android"
AOSP_ABI="x86_64"
AOSP_ARCH="arch-x86_64"
AOSP_FLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -DCRYPTOPP_DISABLE_CLMUL -DCRYPTOPP_DISABLE_AESNI -DCRYPTOPP_DISABLE_SHANI -funwind-tables -fexceptions -frtti"
AOSP_FLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
;;
*)
echo "ERROR: Unknown architecture $1"
Expand Down
4 changes: 2 additions & 2 deletions TestScripts/setenv-android-old.sh
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,14 @@ case "$THE_ARCH" in
TOOLCHAIN_NAME="i686-linux-android"
AOSP_ABI="x86"
AOSP_ARCH="arch-x86"
AOSP_FLAGS="-mtune=intel -mssse3 -mfpmath=sse -DCRYPTOPP_DISABLE_SSE4 -DCRYPTOPP_DISABLE_CLMUL -DCRYPTOPP_DISABLE_AES -DCRYPTOPP_DISABLE_SHA -funwind-tables -fexceptions -frtti"
AOSP_FLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
;;
x86_64|x64)
TOOLCHAIN_ARCH="x86_64"
TOOLCHAIN_NAME="x86_64-linux-android"
AOSP_ABI="x86_64"
AOSP_ARCH="arch-x86_64"
AOSP_FLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -DCRYPTOPP_DISABLE_CLMUL -DCRYPTOPP_DISABLE_AES -DCRYPTOPP_DISABLE_SHA -funwind-tables -fexceptions -frtti"
AOSP_FLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
;;
*)
echo "ERROR: Unknown architecture $1"
Expand Down
5 changes: 5 additions & 0 deletions adv-simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
# include <arm_neon.h>
#endif

#if defined(CRYPTOPP_ARM_ACLE_AVAILABLE)
# include <stdint.h>
# include <arm_acle.h>
#endif

#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
# include <emmintrin.h>
# include <pmmintrin.h>
Expand Down
Loading

0 comments on commit 4e3a1ea

Please sign in to comment.