Index | Thread | Search

From:
Tim van der Molen <tim@kariliq.nl>
Subject:
security/p5-CryptX: fix SIGILL on CPUs without SSE4.1
To:
ports@openbsd.org
Date:
Fri, 12 Apr 2024 14:57:35 +0200

Download raw body.

Thread
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 (git@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)