Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1424663 - vectorized ChaCha20 from HACL* for SSSE3 and ARM NEON, …
…r=ttaubert

Summary:
This adds the vectorized ChaCha20 implementation from HACL* to NSS and replaces the old vectorized code.
Note that this is not used on Android as we currently have no way of testing this for Android or use it on Android for Firefox.

Reviewers: ttaubert

Reviewed By: ttaubert

Bug #: 1424663

Differential Revision: https://phabricator.services.mozilla.com/D467

--HG--
extra : rebase_source : 715ec95c1f5377f86a0f183e7250f8495743b579
extra : histedit_source : 4d998bcb0c41fb703182455eaf5acf1b2e53a2e0%2C16cfd6e35aaab7cb0f1d9487d6ca0d392b04c1b3
  • Loading branch information
franziskuskiefer committed Feb 19, 2018
1 parent c88eaef commit 3fa042f
Show file tree
Hide file tree
Showing 20 changed files with 1,136 additions and 413 deletions.
2 changes: 1 addition & 1 deletion automation/taskcluster/docker-hacl/Dockerfile
Expand Up @@ -9,7 +9,7 @@ ENV haclrepo https://github.com/mitls/hacl-star.git

# Define versions of dependencies
ENV opamv 4.04.2
ENV haclversion dcd48329d535727dbde93877b124c5ec4a7a2b20
ENV haclversion 104de0fbc83939a5e76012d64e3db2b3c0524bd1

# Install required packages and set versions
ADD setup.sh /tmp/setup.sh
Expand Down
24 changes: 22 additions & 2 deletions automation/taskcluster/graph/src/extend.js
Expand Up @@ -77,7 +77,8 @@ queue.filter(task => {
}
}

if (task.tests == "fips" && task.platform == "mac") {
if (task.tests == "fips" &&
(task.platform == "mac" || task.platform == "aarch64")) {
return false;
}

Expand All @@ -93,7 +94,7 @@ queue.filter(task => {
}
}

// Don't run additional hardware tests on ARM (we don't have anything there).
// Don't run all additional hardware tests on ARM.
if (task.group == "Cipher" && task.platform == "aarch64" && task.env &&
(task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_HW_AES == "1"
|| task.env.NSS_DISABLE_AVX == "1")) {
Expand Down Expand Up @@ -271,6 +272,18 @@ export default async function main() {
}, aarch64_base)
);

await scheduleLinux("Linux AArch64 (debug, make)",
merge({
env: {USE_64: "1"},
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
],
collection: "make",
}, aarch64_base)
);

await scheduleMac("Mac (opt)", {collection: "opt"}, "--opt");
await scheduleMac("Mac (debug)", {collection: "debug"});
}
Expand Down Expand Up @@ -899,6 +912,13 @@ function scheduleTests(task_build, task_cert, test_base) {
name: "Cipher tests", symbol: "NoAVX", tests: "cipher",
env: {NSS_DISABLE_AVX: "1"}, group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "Cipher tests", symbol: "NoSSSE3|NEON", tests: "cipher",
env: {
NSS_DISABLE_ARM_NEON: "1",
NSS_DISABLE_SSSE3: "1"
}, group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "EC tests", symbol: "EC", tests: "ec"
}));
Expand Down
13 changes: 3 additions & 10 deletions lib/freebl/Makefile
Expand Up @@ -519,23 +519,16 @@ ifndef NSS_DISABLE_CHACHAPOLY
else
EXTRA_SRCS += poly1305.c
endif

ifneq (1,$(CC_IS_GCC))
EXTRA_SRCS += chacha20.c
VERIFIED_SRCS += Hacl_Chacha20.c
else
EXTRA_SRCS += chacha20_vec.c
endif
else
ifeq ($(CPU_ARCH),aarch64)
EXTRA_SRCS += Hacl_Poly1305_64.c
else
EXTRA_SRCS += poly1305.c
endif

EXTRA_SRCS += chacha20.c
VERIFIED_SRCS += Hacl_Chacha20.c
endif # x86_64

VERIFIED_SRCS += Hacl_Chacha20.c
VERIFIED_SRCS += Hacl_Chacha20_Vec128.c
endif # NSS_DISABLE_CHACHAPOLY

ifeq (,$(filter-out i386 x386 x86 x86_64 aarch64,$(CPU_ARCH)))
Expand Down
6 changes: 6 additions & 0 deletions lib/freebl/blapii.h
Expand Up @@ -80,5 +80,11 @@ SECStatus generate_prime(mp_int *prime, int primeLen);
PRBool aesni_support();
PRBool clmul_support();
PRBool avx_support();
PRBool ssse3_support();
PRBool arm_neon_support();
PRBool arm_aes_support();
PRBool arm_pmull_support();
PRBool arm_sha1_support();
PRBool arm_sha2_support();

#endif /* _BLAPII_H_ */
138 changes: 138 additions & 0 deletions lib/freebl/blinit.c
Expand Up @@ -23,6 +23,12 @@ static PRCallOnceType coFreeblInit;
static PRBool aesni_support_ = PR_FALSE;
static PRBool clmul_support_ = PR_FALSE;
static PRBool avx_support_ = PR_FALSE;
static PRBool ssse3_support_ = PR_FALSE;
static PRBool arm_neon_support_ = PR_FALSE;
static PRBool arm_aes_support_ = PR_FALSE;
static PRBool arm_sha1_support_ = PR_FALSE;
static PRBool arm_sha2_support_ = PR_FALSE;
static PRBool arm_pmull_support_ = PR_FALSE;

#ifdef NSS_X86_OR_X64
/*
Expand Down Expand Up @@ -62,6 +68,7 @@ check_xcr0_ymm()
#define ECX_XSAVE (1 << 26)
#define ECX_OSXSAVE (1 << 27)
#define ECX_AVX (1 << 28)
#define ECX_SSSE3 (1 << 9)
#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX)

void
Expand All @@ -71,16 +78,115 @@ CheckX86CPUSupport()
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL");
char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX");
char *disable_ssse3 = PR_GetEnvSecure("NSS_DISABLE_SSSE3");
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL);
clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL);
/* For AVX we check AVX, OSXSAVE, and XSAVE
* as well as XMM and YMM state. */
avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() &&
disable_avx == NULL;
ssse3_support_ = (PRBool)((ecx & ECX_SSSE3) != 0 &&
disable_ssse3 == NULL);
}
#endif /* NSS_X86_OR_X64 */

#if (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__)
#if defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)
#include <sys/auxv.h>
extern unsigned long getauxval(unsigned long type) __attribute__((weak));
#else
static unsigned long (*getauxval)(unsigned long) = NULL;
#define AT_HWCAP2
#define AT_HWCAP
#endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/
#endif /* (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__) */

#if defined(__aarch64__) && !defined(__ANDROID__)
// Defines from hwcap.h in Linux kernel - ARM64
#define HWCAP_AES (1 << 3)
#define HWCAP_PMULL (1 << 4)
#define HWCAP_SHA1 (1 << 5)
#define HWCAP_SHA2 (1 << 6)

void
CheckARMSupport()
{
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
if (getauxval) {
long hwcaps = getauxval(AT_HWCAP);
arm_aes_support_ = hwcaps & HWCAP_AES && disable_hw_aes == NULL;
arm_pmull_support_ = hwcaps & HWCAP_PMULL;
arm_sha1_support_ = hwcaps & HWCAP_SHA1;
arm_sha2_support_ = hwcaps & HWCAP_SHA2;
}
/* aarch64 must support NEON. */
arm_neon_support_ = disable_arm_neon == NULL;
}
#endif /* defined(__aarch64__) && !defined(__ANDROID__) */

#if defined(__arm__) && !defined(__ANDROID__)
// Defines from hwcap.h in Linux kernel - ARM
/*
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
*/
#define HWCAP_NEON (1 << 12)

/*
* HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2
*/
#define HWCAP2_AES (1 << 0)
#define HWCAP2_PMULL (1 << 1)
#define HWCAP2_SHA1 (1 << 2)
#define HWCAP2_SHA2 (1 << 3)

void
CheckARMSupport()
{
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
if (getauxval) {
long hwcaps = getauxval(AT_HWCAP2);
arm_aes_support_ = hwcaps & HWCAP2_AES && disable_hw_aes == NULL;
arm_pmull_support_ = hwcaps & HWCAP2_PMULL;
arm_sha1_support_ = hwcaps & HWCAP2_SHA1;
arm_sha2_support_ = hwcaps & HWCAP2_SHA2;
arm_neon_support_ = hwcaps & HWCAP_NEON && disable_arm_neon == NULL;
}
}
#endif /* defined(__arm__) && !defined(__ANDROID__) */

// Enable when Firefox can use it.
// #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__))
// #include <cpu-features.h>
// void
// CheckARMSupport()
// {
// char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
// char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
// AndroidCpuFamily family = android_getCpuFamily();
// uint64_t features = android_getCpuFeatures();
// if (family == ANDROID_CPU_FAMILY_ARM64) {
// arm_aes_support_ = features & ANDROID_CPU_ARM64_FEATURE_AES &&
// disable_hw_aes == NULL;
// arm_pmull_support_ = features & ANDROID_CPU_ARM64_FEATURE_PMULL;
// arm_sha1_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA1;
// arm_sha2_support_ = features & ANDROID_CPU_ARM64_FEATURE_SHA2;
// arm_neon_support_ = disable_arm_neon == NULL;
// }
// if (family == ANDROID_CPU_FAMILY_ARM) {
// arm_aes_support_ = features & ANDROID_CPU_ARM_FEATURE_AES &&
// disable_hw_aes == NULL;
// arm_pmull_support_ = features & ANDROID_CPU_ARM_FEATURE_PMULL;
// arm_sha1_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA1;
// arm_sha2_support_ = features & ANDROID_CPU_ARM_FEATURE_SHA2;
// arm_neon_support_ = hwcaps & ANDROID_CPU_ARM_FEATURE_NEON &&
// disable_arm_neon == NULL;
// }
// }
// #endif /* defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__)) */

PRBool
aesni_support()
{
Expand All @@ -96,12 +202,44 @@ avx_support()
{
return avx_support_;
}
PRBool
ssse3_support()
{
return ssse3_support_;
}
PRBool
arm_neon_support()
{
return arm_neon_support_;
}
PRBool
arm_aes_support()
{
return arm_aes_support_;
}
PRBool
arm_pmull_support()
{
return arm_pmull_support_;
}
PRBool
arm_sha1_support()
{
return arm_sha1_support_;
}
PRBool
arm_sha2_support()
{
return arm_sha2_support_;
}

static PRStatus
FreeblInit(void)
{
#ifdef NSS_X86_OR_X64
CheckX86CPUSupport();
#elif (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__)
CheckARMSupport();
#endif
return PR_SUCCESS;
}
Expand Down
19 changes: 0 additions & 19 deletions lib/freebl/chacha20.c

This file was deleted.

26 changes: 0 additions & 26 deletions lib/freebl/chacha20.h

This file was deleted.

0 comments on commit 3fa042f

Please sign in to comment.