Browse Source

Merge pull request #644 from tbvdm/aesni

Improve SSE4.1/AES-NI support
Steffen Jaeckel 1 year ago
parent
commit
ce904c86ef

+ 4 - 0
README.md

@@ -150,6 +150,10 @@ If you have `libtommath` in a non-standard location:
 
     make CFLAGS="-DUSE_LTM -DLTM_DESC -I/opt/devel/ltm" EXTRALIBS="/opt/devel/ltm/libtommath.a" all
 
+You want to enable AES-NI support:
+
+    make CFLAGS=-DLTC_AES_NI
+
 ## Installation
 
 There exist several _install_ make-targets which are described in the table above.

+ 6 - 6
src/ciphers/aes/aes_desc.c

@@ -49,7 +49,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;
@@ -57,7 +57,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;
@@ -68,7 +68,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;
    }
 
@@ -93,7 +93,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);
    }
@@ -111,7 +111,7 @@ int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
 */
 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);
    }
@@ -130,7 +130,7 @@ int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *ske
 */
 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);
    }

+ 4 - 1
src/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 =
 {
@@ -42,6 +42,7 @@ static const ulong32 rcon[] = {
     @param skey The key in as scheduled by this function.
     @return CRYPT_OK if successful
  */
+LTC_ATTRIBUTE((__target__("aes,sse4.1")))
 int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
 {
    int i;
@@ -168,6 +169,7 @@ int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
   @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
+LTC_ATTRIBUTE((__target__("aes")))
 #ifdef LTC_CLEAN_STACK
 static int s_aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
 #else
@@ -219,6 +221,7 @@ int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetri
   @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
+LTC_ATTRIBUTE((__target__("aes")))
 #ifdef LTC_CLEAN_STACK
 static int s_aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
 #else

+ 6 - 5
src/headers/tomcrypt_cfg.h

@@ -91,11 +91,6 @@ LTC_EXPORT int   LTC_CALL XSTRCMP(const char *s1, const char *s2);
    #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 */
@@ -337,4 +332,10 @@ typedef unsigned long ltc_mp_digit;
 #  define LTC_DEPRECATED_PRAGMA(s)
 #endif
 
+#if defined(__GNUC__) || defined(__clang__)
+#  define LTC_ATTRIBUTE(x) __attribute__(x)
+#else
+#  define LTC_ATTRIBUTE(x)
+#endif
+
 #endif /* TOMCRYPT_CFG_H */

+ 1 - 1
src/headers/tomcrypt_cipher.h

@@ -736,7 +736,7 @@ extern const struct ltc_cipher_descriptor rijndael_desc;
 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);

+ 0 - 3
src/headers/tomcrypt_custom.h

@@ -182,9 +182,6 @@
 #define LTC_RC6
 #define LTC_SAFERP
 #define LTC_RIJNDAEL
-#ifndef LTC_NO_AES_NI
-   #define LTC_AES_NI
-#endif
 #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 */

+ 0 - 4
src/headers/tomcrypt_private.h

@@ -110,10 +110,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,

+ 1 - 1
src/misc/crypt/crypt.c

@@ -427,7 +427,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)

+ 1 - 1
tests/cipher_hash_test.c

@@ -14,7 +14,7 @@ int cipher_hash_test(void)
    }
 
    /* explicit AES-NI test */
-#if defined(LTC_HAS_AES_NI)
+#if defined(LTC_AES_NI)
    if (aesni_is_supported()) {
       DO(aesni_test());
    }