p5-CryptX contains a vendored copy of libtomcrypt. It uses "-msse4.1 -maes" to enable AES-NI support. The problem is that these flags are used for *all* source files. This may cause SIGILL on CPUs without SSE4.1.
I think the best solution is for CryptX to use "-msse4.1 -maes" only for aesni.c. Unfortunately this requires several changes to the libtomcrypt source. I'm trying to get these changes accepted upstream. Is this suitable to put in ports? Index: Makefile =================================================================== RCS file: /cvs/ports/security/p5-CryptX/Makefile,v diff -p -u -r1.12 Makefile --- Makefile 26 Dec 2023 20:56:24 -0000 1.12 +++ Makefile 12 Apr 2024 12:51:05 -0000 @@ -2,6 +2,7 @@ COMMENT = cryptographic toolkit for Perl DISTNAME = CryptX-0.080 CPAN_AUTHOR = MIK +REVISION = 1 CATEGORIES = security Index: patches/patch-Makefile_PL =================================================================== RCS file: patches/patch-Makefile_PL diff -N patches/patch-Makefile_PL --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-Makefile_PL 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,33 @@ +Index: Makefile.PL +--- Makefile.PL.orig ++++ Makefile.PL +@@ -3,7 +3,7 @@ use warnings; + use ExtUtils::MakeMaker; + use Config; + +-my (@EUMM_INC_LIB, $myarflags, $mycflags); ++my (@EUMM_INC_LIB, $myarflags, $mycflags, $mycflags_aes_ni); + + if ($ENV{CRYPTX_CFLAGS} || $ENV{CRYPTX_LDFLAGS}) { + # EXPERIMENTAL: use system libraries libtomcrypt + libtommath +@@ -38,7 +38,10 @@ else { + $ver1 ||= $1 if $Config{gccversion} =~ /^([0-9]+)\./; # gccversion='10.2.0' + $ver1 ||= $1 if $Config{gccversion} =~ /LLVM ([0-9]+)\./i; # gccversion='Apple LLVM 14.0.0 (clang-1400.0.29.202)' + $ver1 ||= $1 if $Config{gccversion} =~ /Clang ([0-9]+)\./i; # gccversion='FreeBSD Clang 13.0.0 (g...@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a303)' or 'OpenBSD Clang 13.0.0' +- $mycflags .= " -msse4.1 -maes" if $ver1 > 4; # supported since gcc-4.4 ++ if ($ver1 > 4) { ++ $mycflags .= " -DLTC_AES_NI"; ++ $mycflags_aes_ni .= " -msse4.1 -maes"; # supported since gcc-4.4 ++ } + } + + #FIX: this is particularly useful for Debian https://github.com/DCIT/perl-CryptX/pull/39 +@@ -117,7 +120,7 @@ sub MY::postamble { + + my $extra_targets = qq{ + \$(MYEXTLIB): src/Makefile +- cd src && \$(MAKE) ARFLAGS="$myarflags" RANLIB="\$(RANLIB)" AR="\$(AR)" CC="\$(CC)" LIB_EXT=\$(LIB_EXT) OBJ_EXT=\$(OBJ_EXT) CFLAGS="$mycflags" ++ cd src && \$(MAKE) ARFLAGS="$myarflags" RANLIB="\$(RANLIB)" AR="\$(AR)" CC="\$(CC)" LIB_EXT=\$(LIB_EXT) OBJ_EXT=\$(OBJ_EXT) CFLAGS="$mycflags" CFLAGS_AES_NI="$mycflags_aes_ni" + }; + + $extra_targets = qq{ Index: patches/patch-src_Makefile =================================================================== RCS file: patches/patch-src_Makefile diff -N patches/patch-src_Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_Makefile 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,10 @@ +Index: src/Makefile +--- src/Makefile.orig ++++ src/Makefile +@@ -195,3 +195,6 @@ clean: + + .c$(OBJ_EXT): + $(CC) -Iltm -Iltc/headers -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC $(CFLAGS) -DARGTYPE=4 -c $< -o $@ ++ ++ltc/ciphers/aes/aesni.o: ltc/ciphers/aes/aesni.c ++ $(CC) -Iltm -Iltc/headers -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC $(CFLAGS) $(CFLAGS_AES_NI) -DARGTYPE=4 -c ltc/ciphers/aes/aesni.c -o ltc/ciphers/aes/aesni.o Index: patches/patch-src_ltc_ciphers_aes_aes_desc_c =================================================================== RCS file: patches/patch-src_ltc_ciphers_aes_aes_desc_c diff -N patches/patch-src_ltc_ciphers_aes_aes_desc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_ciphers_aes_aes_desc_c 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,57 @@ +Index: src/ltc/ciphers/aes/aes_desc.c +--- src/ltc/ciphers/aes/aes_desc.c.orig ++++ src/ltc/ciphers/aes/aes_desc.c +@@ -48,7 +48,7 @@ const struct ltc_cipher_descriptor aes_enc_desc = + #endif + + /* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */ +-#if defined(LTC_HAS_AES_NI) ++#if defined(LTC_AES_NI) + static LTC_INLINE int s_aesni_is_supported(void) + { + static int initialized = 0, is_supported = 0; +@@ -56,7 +56,7 @@ static LTC_INLINE int s_aesni_is_supported(void) + if (initialized == 0) { + int a, b, c, d; + +- /* Look for CPUID.1.0.ECX[25] ++ /* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI) + * EAX = 1, ECX = 0 + */ + a = 1; +@@ -67,7 +67,7 @@ static LTC_INLINE int s_aesni_is_supported(void) + :"a"(a), "c"(c) + ); + +- is_supported = ((c >> 25) & 1); ++ is_supported = ((c >> 19) & 1) && ((c >> 25) & 1); + initialized = 1; + } + +@@ -92,7 +92,7 @@ int aesni_is_supported(void) + */ + int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) + { +-#ifdef LTC_HAS_AES_NI ++#ifdef LTC_AES_NI + if (s_aesni_is_supported()) { + return aesni_setup(key, keylen, num_rounds, skey); + } +@@ -110,7 +110,7 @@ int AES_SETUP(const unsigned char *key, int keylen, in + */ + int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey) + { +-#ifdef LTC_HAS_AES_NI ++#ifdef LTC_AES_NI + if (s_aesni_is_supported()) { + return aesni_ecb_encrypt(pt, ct, skey); + } +@@ -128,7 +128,7 @@ int AES_ENC(const unsigned char *pt, unsigned char *ct + */ + int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey) + { +-#ifdef LTC_HAS_AES_NI ++#ifdef LTC_AES_NI + if (s_aesni_is_supported()) { + return aesni_ecb_decrypt(ct, pt, skey); + } Index: patches/patch-src_ltc_ciphers_aes_aesni_c =================================================================== RCS file: patches/patch-src_ltc_ciphers_aes_aesni_c diff -N patches/patch-src_ltc_ciphers_aes_aesni_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_ciphers_aes_aesni_c 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,12 @@ +Index: src/ltc/ciphers/aes/aesni.c +--- src/ltc/ciphers/aes/aesni.c.orig ++++ src/ltc/ciphers/aes/aesni.c +@@ -9,7 +9,7 @@ + + #include "tomcrypt_private.h" + +-#if defined(LTC_HAS_AES_NI) ++#if defined(LTC_AES_NI) + + const struct ltc_cipher_descriptor aesni_desc = + { Index: patches/patch-src_ltc_headers_tomcrypt_cfg_h =================================================================== RCS file: patches/patch-src_ltc_headers_tomcrypt_cfg_h diff -N patches/patch-src_ltc_headers_tomcrypt_cfg_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_headers_tomcrypt_cfg_h 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,15 @@ +Index: src/ltc/headers/tomcrypt_cfg.h +--- src/ltc/headers/tomcrypt_cfg.h.orig ++++ src/ltc/headers/tomcrypt_cfg.h +@@ -91,11 +91,6 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, cons + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD + #define LTC_FAST +- #if defined(__SSE4_1__) +- #if __SSE4_1__ == 1 +- #define LTC_AMD64_SSE4_1 +- #endif +- #endif + #endif + + /* detect PPC32 */ Index: patches/patch-src_ltc_headers_tomcrypt_cipher_h =================================================================== RCS file: patches/patch-src_ltc_headers_tomcrypt_cipher_h diff -N patches/patch-src_ltc_headers_tomcrypt_cipher_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_headers_tomcrypt_cipher_h 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,12 @@ +Index: src/ltc/headers/tomcrypt_cipher.h +--- src/ltc/headers/tomcrypt_cipher.h.orig ++++ src/ltc/headers/tomcrypt_cipher.h +@@ -718,7 +718,7 @@ extern const struct ltc_cipher_descriptor rijndael_des + extern const struct ltc_cipher_descriptor rijndael_enc_desc; + #endif + +-#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1) ++#if defined(LTC_AES_NI) + int aesni_is_supported(void); + int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); + int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey); Index: patches/patch-src_ltc_headers_tomcrypt_custom_h =================================================================== RCS file: patches/patch-src_ltc_headers_tomcrypt_custom_h diff -N patches/patch-src_ltc_headers_tomcrypt_custom_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_headers_tomcrypt_custom_h 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,11 @@ +Index: src/ltc/headers/tomcrypt_custom.h +--- src/ltc/headers/tomcrypt_custom.h.orig ++++ src/ltc/headers/tomcrypt_custom.h +@@ -179,7 +179,6 @@ + #define LTC_RC6 + #define LTC_SAFERP + #define LTC_RIJNDAEL +-#define LTC_AES_NI + #define LTC_XTEA + /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ Index: patches/patch-src_ltc_headers_tomcrypt_private_h =================================================================== RCS file: patches/patch-src_ltc_headers_tomcrypt_private_h diff -N patches/patch-src_ltc_headers_tomcrypt_private_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_headers_tomcrypt_private_h 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,14 @@ +Index: src/ltc/headers/tomcrypt_private.h +--- src/ltc/headers/tomcrypt_private.h.orig ++++ src/ltc/headers/tomcrypt_private.h +@@ -77,10 +77,6 @@ typedef struct + + /* tomcrypt_cipher.h */ + +-#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1) +-#define LTC_HAS_AES_NI +-#endif +- + void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey); + int blowfish_expand(const unsigned char *key, int keylen, + const unsigned char *data, int datalen, Index: patches/patch-src_ltc_misc_crypt_crypt_c =================================================================== RCS file: patches/patch-src_ltc_misc_crypt_crypt_c diff -N patches/patch-src_ltc_misc_crypt_crypt_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ltc_misc_crypt_crypt_c 12 Apr 2024 12:51:05 -0000 @@ -0,0 +1,12 @@ +Index: src/ltc/misc/crypt/crypt.c +--- src/ltc/misc/crypt/crypt.c.orig ++++ src/ltc/misc/crypt/crypt.c +@@ -416,7 +416,7 @@ const char *crypt_build_settings = + #if defined(LTC_ADLER32) + " ADLER32 " + #endif +-#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1) ++#if defined(LTC_AES_NI) + " AES-NI " + #endif + #if defined(LTC_BASE64)