Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #431
Browse files Browse the repository at this point in the history
1256a6f Build: fix ARMv7/8 builds. Fixes #384, refs #285 (anonimal)
  • Loading branch information
anonimal committed Nov 7, 2016
2 parents 9c159ec + 1256a6f commit 4f03407
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 24 deletions.
63 changes: 39 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,42 +26,57 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()

# Compiler flags customization (by vendor)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -maes")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening
# for OpenWRT.
# Multiple definitions of __stack_chk_fail (libssp & libc)
set(CMAKE_CXX_FLAGS_MINSIZEREL
"${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
# -flto is added from above
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections")
### TODO(unassigned): improve detection and use-case
# Minimal processor detection (needed for ARM build)
set(CPU "${CMAKE_SYSTEM_PROCESSOR}")
string(SUBSTRING "${CPU}" 0 3 PARSE_ARM)
if (CPU STREQUAL "aarch64" OR PARSE_ARM STREQUAL "arm")
set(ARM TRUE)
endif()

# Check for c++14 support
# Detect minimum compiler version
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
message(FATAL_ERROR "GCC 4.9.3 or higher is required")
endif()
set(GNU TRUE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
message(FATAL_ERROR "Clang 3.5 or higher is required")
endif()
set(Clang TRUE) # TODO(unassigned): make use of this
endif()

# Check for C++14 support (minimum version compilers guarantee this)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++1y" CXX14_SUPPORTED)
if(CXX14_SUPPORTED)
add_definitions("-std=c++1y")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
elseif(NOT MSVC)
message(FATAL_ERROR "C++14 standard not supported by compiler. See building instructions.")
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
message(FATAL_ERROR "GCC 4.9.3 or higher is required")
### TODO(unassigned): review, cleanup, improve
# Compiler flags (by vendor)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch")
if(NOT ARM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic")
# TODO: The following is incompatible with static build and enabled hardening
# for OpenWRT.
# Multiple definitions of __stack_chk_fail (libssp & libc)
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections")
# -flto is added from above
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections")
if(WITH_HARDENING)
add_definitions("-D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fstack-protector-strong -fPIE --param ssp-buffer-size=4 -z relro -z now")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
message(FATAL_ERROR "Clang 3.5 or higher is required")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fPIE --param ssp-buffer-size=4")
if(GNU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -z relro -z now")
endif()
endif()
endif()

Expand Down
20 changes: 20 additions & 0 deletions src/core/crypto/impl/cryptopp/aes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace core {
/// TODO(unassigned): if we switch libraries, we should move AES-NI elsewhere.
/// TODO(unassigned): ARM support? MSVC x86-64 support?
bool HasAESNI() {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
unsigned int eax, ecx; // We only need ECX
const unsigned int flag = (1 << 25); // ECX bit 25 for AES-NI
LogPrint(eLogDebug, "Crypto: checking for AES-NI...");
Expand All @@ -59,6 +60,7 @@ bool HasAESNI() {
LogPrint(eLogDebug, "Crypto: AES-NI is available!");
return true;
}
#endif
LogPrint(eLogDebug, "Crypto: AES-NI is not available. Using library.");
return false;
}
Expand All @@ -81,6 +83,7 @@ class ECBCryptoAESNI {
}

protected:
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
void ExpandKey(
const AESKey& key) {
__asm__(
Expand Down Expand Up @@ -116,6 +119,7 @@ class ECBCryptoAESNI {
: [key]"r"((const std::uint8_t *)key), [sched]"r"(GetKeySchedule()) // Input
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory"); // Clobbered
}
#endif

private:
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
Expand All @@ -141,7 +145,9 @@ class ECBEncryption::ECBEncryptionImpl : public ECBCryptoAESNI {
void SetKey(
const AESKey& key) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
ExpandKey(key);
#endif
} else {
try {
m_Encryption.SetKey(key, 32);
Expand All @@ -156,13 +162,15 @@ class ECBEncryption::ECBEncryptionImpl : public ECBCryptoAESNI {
const CipherBlock* in,
CipherBlock* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
:
: [sched]"r"(GetKeySchedule()), [in]"r"(in), [out]"r"(out)
: "%xmm0", "memory");
#endif
} else {
try {
m_Encryption.ProcessData(out->buf, in->buf, 16);
Expand Down Expand Up @@ -218,6 +226,7 @@ class ECBDecryption::ECBDecryptionImpl : public ECBCryptoAESNI {
void SetKey(
const AESKey& key) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
ExpandKey(key); // expand encryption key first
// then invert it using aesimc
__asm__(
Expand All @@ -237,6 +246,7 @@ class ECBDecryption::ECBDecryptionImpl : public ECBCryptoAESNI {
:
: [shed]"r"(GetKeySchedule())
: "%xmm0", "memory");
#endif
} else {
try {
m_Decryption.SetKey(key, 32);
Expand All @@ -251,13 +261,15 @@ class ECBDecryption::ECBDecryptionImpl : public ECBCryptoAESNI {
const CipherBlock* in,
CipherBlock* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
:
: [sched]"r"(GetKeySchedule()), [in]"r"(in), [out]"r"(out)
: "%xmm0", "memory");
#endif
} else {
try {
m_Decryption.ProcessData(out->buf, in->buf, 16);
Expand Down Expand Up @@ -330,6 +342,7 @@ class CBCEncryption::CBCEncryptionImpl {
const CipherBlock* in,
CipherBlock* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
Expand All @@ -348,6 +361,7 @@ class CBCEncryption::CBCEncryptionImpl {
[sched]"r"(m_ECBEncryption.GetKeySchedule()),
[in]"r"(in), [out]"r"(out), [num]"r"(num_blocks)
: "%xmm0", "%xmm1", "cc", "memory");
#endif
} else {
for (int i = 0; i < num_blocks; i++) {
m_LastBlock ^= in[i];
Expand All @@ -374,6 +388,7 @@ class CBCEncryption::CBCEncryptionImpl {
const std::uint8_t* in,
std::uint8_t* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
Expand All @@ -386,6 +401,7 @@ class CBCEncryption::CBCEncryptionImpl {
[sched]"r"(m_ECBEncryption.GetKeySchedule()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory");
#endif
} else {
Encrypt(
1,
Expand Down Expand Up @@ -478,6 +494,7 @@ class CBCDecryption::CBCDecryptionImpl {
const CipherBlock* in,
CipherBlock* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
Expand All @@ -496,6 +513,7 @@ class CBCDecryption::CBCDecryptionImpl {
: [iv]"r"(&m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(num_blocks)
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory");
#endif
} else {
for (int i = 0; i < num_blocks; i++) {
CipherBlock tmp = in[i];
Expand Down Expand Up @@ -523,6 +541,7 @@ class CBCDecryption::CBCDecryptionImpl {
const std::uint8_t* in,
std::uint8_t* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
Expand All @@ -534,6 +553,7 @@ class CBCDecryption::CBCDecryptionImpl {
: [iv]"r"(&m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory");
#endif
} else {
Decrypt(
1,
Expand Down
4 changes: 4 additions & 0 deletions src/core/crypto/impl/cryptopp/tunnel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class TunnelEncryption::TunnelEncryptionImpl {
const std::uint8_t* in,
std::uint8_t* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
// encrypt IV
"movups (%[in]), %%xmm0 \n"
Expand All @@ -88,6 +89,7 @@ class TunnelEncryption::TunnelEncryptionImpl {
[sched_l]"r"(m_ECBLayerEncryption.GetKeySchedule()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "cc", "memory");
#endif
} else {
m_IVEncryption.Encrypt( // iv
(const CipherBlock *)in,
Expand Down Expand Up @@ -148,6 +150,7 @@ class TunnelDecryption::TunnelDecryptionImpl {
const std::uint8_t* in,
std::uint8_t* out) {
if (UsingAESNI()) {
#if defined(__x86_64__) || defined(_M_X64) // TODO(unassigned): hack until we implement ARM AES-NI
__asm__(
// decrypt IV
"movups (%[in]), %%xmm0 \n"
Expand All @@ -173,6 +176,7 @@ class TunnelDecryption::TunnelDecryptionImpl {
[sched_l]"r"(m_ECBLayerDecryption.GetKeySchedule()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory");
#endif
} else {
m_IVDecryption.Decrypt(
(const CipherBlock *)in,
Expand Down

0 comments on commit 4f03407

Please sign in to comment.