Browse Source

Merge pull request #633 from libtom/some-fixes

Fix AES-NI and other minor stuff
Steffen Jaeckel 2 years ago
parent
commit
91b7bbe4c1

+ 12 - 0
CMakeLists.txt

@@ -24,6 +24,9 @@ include(CheckIPOSupported)
 include(CMakePackageConfigHelpers)
 # for potential builds against gnump
 include(FindPkgConfig)
+# for potential builds with MSVC
+include(CMakePushCheckState)
+include(CheckSymbolExists)
 # default is "No tests"
 option(BUILD_TESTING "" OFF)
 include(CTest)
@@ -297,6 +300,15 @@ else()
     set(DISTRO_PACK_PATH ${CMAKE_SYSTEM_NAME}/)
 endif()
 
+# make sure untagged versions get a different package name
+execute_process(COMMAND git describe --exact-match --tags ERROR_QUIET RESULT_VARIABLE REPO_HAS_TAG)
+if(REPO_HAS_TAG EQUAL 0)
+    set(PACKAGE_NAME_SUFFIX "")
+else()
+    set(PACKAGE_NAME_SUFFIX "-git")
+    message(STATUS "Use -git suffix")
+endif()
+
 # default CPack generators
 set(CPACK_GENERATOR TGZ STGZ)
 

+ 1 - 3
demos/gcm-file/gcm_filehandle.c

@@ -98,9 +98,7 @@ int gcm_filehandle(      int           cipher,
     * but again it's only for SSE2 anyways, so who cares?
     */
 #ifdef LTC_GCM_TABLES_SSE2
-   if ((unsigned long)gcm & 15) {
-      gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
-   }
+    gcm = LTC_ALIGN_BUF(gcm, 16);
 #endif
 
     if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {

+ 9 - 9
makefile_include.mk

@@ -13,16 +13,16 @@ ifndef CROSS_COMPILE
   CROSS_COMPILE:=
 endif
 
-# We only need to go through this dance of determining the right compiler if we're using
-# cross compilation, otherwise $(CC) is fine as-is.
+H := \#
+ifeq (CLANG,$(shell printf "$(H)ifdef __clang__\nCLANG\n$(H)endif\n" | $(CC) -E - | grep CLANG))
+  CC_IS_CLANG := 1
+else
+  CC_IS_CLANG := 0
+endif # Clang
+
 ifneq (,$(CROSS_COMPILE))
 ifeq ($(origin CC),default)
-CSTR := "\#ifdef __clang__\nCLANG\n\#endif\n"
-ifeq ($(PLATFORM),FreeBSD)
-  # XXX: FreeBSD needs extra escaping for some reason
-  CSTR := $$$(CSTR)
-endif
-ifneq (,$(shell echo $(CSTR) | $(CC) -E - | grep CLANG))
+ifeq ($(CC_IS_CLANG), 1)
   CC := $(CROSS_COMPILE)clang
 else
   CC := $(CROSS_COMPILE)gcc
@@ -124,7 +124,7 @@ LTC_CFLAGS += -Os -DLTC_SMALL_CODE
 endif # LTC_SMALL
 
 
-ifneq ($(findstring clang,$(CC)),)
+ifeq ($(CC_IS_CLANG), 1)
 LTC_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header
 LTC_CFLAGS += -Wno-missing-field-initializers -Wno-missing-braces -Wno-incomplete-setjmp-declaration -Wno-cast-align
 LTC_CFLAGS += -Wno-declaration-after-statement

+ 5 - 1
src/ciphers/aes/aes.c

@@ -96,7 +96,7 @@ static ulong32 setup_mix2(ulong32 temp)
 int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
 {
     int i;
-    ulong32 temp, *rk;
+    ulong32 temp, *rk, *K;
 #ifndef ENCRYPT_ONLY
     ulong32 *rrk;
 #endif
@@ -112,6 +112,10 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
     }
 
     skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
+    K = LTC_ALIGN_BUF(skey->rijndael.K, 16);
+    skey->rijndael.eK = K;
+    K += 60;
+    skey->rijndael.dK = K;
 
     /* setup the forward key */
     i                 = 0;

+ 5 - 1
src/ciphers/aes/aesni.c

@@ -46,7 +46,7 @@ int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
 {
    int i;
    __m128i temp;
-   ulong32 *rk;
+   ulong32 *rk, *K;
    ulong32 *rrk;
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(skey != NULL);
@@ -60,6 +60,10 @@ int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
    }
 
    skey->rijndael.Nr = keylen / 4 + 6;
+   K = LTC_ALIGN_BUF(skey->rijndael.K, 16);
+   skey->rijndael.eK = K;
+   K += 60;
+   skey->rijndael.dK = K;
 
    /* setup the forward key */
    i = 0;

+ 3 - 0
src/encauth/ccm/ccm_memory.c

@@ -161,6 +161,9 @@ int ccm_memory(int cipher,
        PAD[x++] = 0;
    }
    for (; y < L; y++) {
+       if (x >= sizeof(PAD)) {
+          return CRYPT_INVALID_ARG;
+       }
        PAD[x++] = (unsigned char)((len >> 24) & 255);
        len <<= 8;
    }

+ 1 - 3
src/encauth/gcm/gcm_memory.c

@@ -70,9 +70,7 @@ int gcm_memory(      int           cipher,
     * but again it's only for SSE2 anyways, so who cares?
     */
 #ifdef LTC_GCM_TABLES_SSE2
-   if ((unsigned long)gcm & 15) {
-      gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
-   }
+    gcm = LTC_ALIGN_BUF(gcm, 16);
 #endif
 
     if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {

+ 1 - 1
src/headers/tomcrypt_cfg.h

@@ -209,7 +209,7 @@ LTC_EXPORT int   LTC_CALL XSTRCMP(const char *s1, const char *s2);
    typedef unsigned __int64 ulong64;
    typedef __int64 long64;
 #else
-   #define CONST64(n) n ## ULL
+   #define CONST64(n) n ## uLL
    typedef unsigned long long ulong64;
    typedef long long long64;
 #endif

+ 38 - 37
src/headers/tomcrypt_cipher.h

@@ -35,8 +35,9 @@ struct saferp_key {
 
 #ifdef LTC_RIJNDAEL
 struct rijndael_key {
-   ulong32 eK[60] LTC_ALIGN(16);
-   ulong32 dK[60] LTC_ALIGN(16);
+   unsigned char K[(60 + 60 + 4) * sizeof(ulong32)];
+   ulong32 *eK;
+   ulong32 *dK;
    int Nr;
 };
 #endif
@@ -128,24 +129,24 @@ struct khazad_key {
 
 #ifdef LTC_ANUBIS
 struct anubis_key {
-   int keyBits;
-   int R;
    ulong32 roundKeyEnc[18 + 1][4];
    ulong32 roundKeyDec[18 + 1][4];
+   int keyBits;
+   int R;
 };
 #endif
 
 #ifdef LTC_MULTI2
 struct multi2_key {
-    int N;
     ulong32 uk[8];
+    int N;
 };
 #endif
 
 #ifdef LTC_CAMELLIA
 struct camellia_key {
-    int R;
     ulong64 kw[4], k[24], kl[6];
+    int R;
 };
 #endif
 
@@ -246,60 +247,60 @@ typedef union Symmetric_key {
 #ifdef LTC_ECB_MODE
 /** A block cipher ECB structure */
 typedef struct {
+   /** The scheduled key */
+   symmetric_key       key;
    /** The index of the cipher chosen */
    int                 cipher,
    /** The block size of the given cipher */
                        blocklen;
-   /** The scheduled key */
-   symmetric_key       key;
 } symmetric_ECB;
 #endif
 
 #ifdef LTC_CFB_MODE
 /** A block cipher CFB structure */
 typedef struct {
-   /** The index of the cipher chosen */
-   int                 cipher,
-   /** The block size of the given cipher */
-                       blocklen,
-   /** The padding offset */
-                       padlen;
    /** The current IV */
    unsigned char       IV[MAXBLOCKSIZE],
    /** The pad used to encrypt/decrypt */
                        pad[MAXBLOCKSIZE];
    /** The scheduled key */
    symmetric_key       key;
+   /** The index of the cipher chosen */
+   int                 cipher,
+   /** The block size of the given cipher */
+                       blocklen,
+   /** The padding offset */
+                       padlen;
 } symmetric_CFB;
 #endif
 
 #ifdef LTC_OFB_MODE
 /** A block cipher OFB structure */
 typedef struct {
+   /** The current IV */
+   unsigned char       IV[MAXBLOCKSIZE];
+   /** The scheduled key */
+   symmetric_key       key;
    /** The index of the cipher chosen */
    int                 cipher,
    /** The block size of the given cipher */
                        blocklen,
    /** The padding offset */
                        padlen;
-   /** The current IV */
-   unsigned char       IV[MAXBLOCKSIZE];
-   /** The scheduled key */
-   symmetric_key       key;
 } symmetric_OFB;
 #endif
 
 #ifdef LTC_CBC_MODE
 /** A block cipher CBC structure */
 typedef struct {
-   /** The index of the cipher chosen */
-   int                 cipher,
-   /** The block size of the given cipher */
-                       blocklen;
    /** The current IV */
    unsigned char       IV[MAXBLOCKSIZE];
    /** The scheduled key */
    symmetric_key       key;
+   /** The index of the cipher chosen */
+   int                 cipher,
+   /** The block size of the given cipher */
+                       blocklen;
 } symmetric_CBC;
 #endif
 
@@ -307,6 +308,13 @@ typedef struct {
 #ifdef LTC_CTR_MODE
 /** A block cipher CTR structure */
 typedef struct {
+   /** The counter */
+   unsigned char       ctr[MAXBLOCKSIZE];
+   /** The pad used to encrypt/decrypt */
+   unsigned char       pad[MAXBLOCKSIZE];
+   /** The scheduled key */
+   symmetric_key       key;
+
    /** The index of the cipher chosen */
    int                 cipher,
    /** The block size of the given cipher */
@@ -317,13 +325,6 @@ typedef struct {
                        mode,
    /** counter width */
                        ctrlen;
-
-   /** The counter */
-   unsigned char       ctr[MAXBLOCKSIZE];
-   /** The pad used to encrypt/decrypt */
-   unsigned char       pad[MAXBLOCKSIZE] LTC_ALIGN(16);
-   /** The scheduled key */
-   symmetric_key       key;
 } symmetric_CTR;
 #endif
 
@@ -331,9 +332,6 @@ typedef struct {
 #ifdef LTC_LRW_MODE
 /** A LRW structure */
 typedef struct {
-    /** The index of the cipher chosen (must be a 128-bit block cipher) */
-    int               cipher;
-
     /** The current IV */
     unsigned char     IV[16],
 
@@ -350,25 +348,28 @@ typedef struct {
     /** The pre-computed multiplication table */
     unsigned char     PC[16][256][16];
 #endif
+
+    /** The index of the cipher chosen (must be a 128-bit block cipher) */
+    int               cipher;
 } symmetric_LRW;
 #endif
 
 #ifdef LTC_F8_MODE
 /** A block cipher F8 structure */
 typedef struct {
+   /** The current IV */
+   unsigned char       IV[MAXBLOCKSIZE],
+                       MIV[MAXBLOCKSIZE];
+   /** The scheduled key */
+   symmetric_key       key;
    /** The index of the cipher chosen */
    int                 cipher,
    /** The block size of the given cipher */
                        blocklen,
    /** The padding offset */
                        padlen;
-   /** The current IV */
-   unsigned char       IV[MAXBLOCKSIZE],
-                       MIV[MAXBLOCKSIZE];
    /** Current block count */
    ulong32             blockcnt;
-   /** The scheduled key */
-   symmetric_key       key;
 } symmetric_F8;
 #endif
 

+ 3 - 1
src/headers/tomcrypt_custom.h

@@ -179,7 +179,9 @@
 #define LTC_RC6
 #define LTC_SAFERP
 #define LTC_RIJNDAEL
-#define LTC_AES_NI
+#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 */

+ 14 - 15
src/headers/tomcrypt_mac.h

@@ -358,10 +358,10 @@ typedef struct {
    unsigned char     aSum_current[MAXBLOCKSIZE],    /* AAD related helper variable */
                      aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
                      adata_buffer[MAXBLOCKSIZE];    /* AAD buffer */
-   int               adata_buffer_bytes;            /* bytes in AAD buffer */
-   unsigned long     ablock_index;                  /* index # for current adata (AAD) block */
 
    symmetric_key     key;                     /* scheduled key for cipher */
+   int               adata_buffer_bytes;            /* bytes in AAD buffer */
+   unsigned long     ablock_index;                  /* index # for current adata (AAD) block */
    unsigned long     block_index;             /* index # for current data block */
    int               cipher,                  /* cipher idx */
                      tag_len,                 /* length of tag */
@@ -407,7 +407,12 @@ int ocb3_test(void);
 #define CCM_DECRYPT LTC_DECRYPT
 
 typedef struct {
+   unsigned char       PAD[16],              /* flags | Nonce N | l(m) */
+                       ctr[16],
+                       CTRPAD[16];
+
    symmetric_key       K;
+
    int                 cipher,               /* which cipher */
                        taglen,               /* length of the tag (encoded in M value) */
                        x;                    /* index in PAD */
@@ -419,10 +424,7 @@ typedef struct {
                        current_aadlen,       /* length of the currently provided add */
                        noncelen;             /* length of the nonce */
 
-   unsigned char       PAD[16],              /* flags | Nonce N | l(m) */
-                       ctr[16],
-                       CTRPAD[16],
-                       CTRlen;
+   unsigned char       CTRlen;
 } ccm_state;
 
 int ccm_init(ccm_state *ccm, int cipher,
@@ -478,13 +480,18 @@ extern const unsigned char gcm_shift_table[];
 #define LTC_GCM_MODE_TEXT  2
 
 typedef struct {
-   symmetric_key       K;
    unsigned char       H[16],        /* multiplier */
                        X[16],        /* accumulator */
                        Y[16],        /* counter */
                        Y_0[16],      /* initial counter */
                        buf[16];      /* buffer for stuff */
 
+#ifdef LTC_GCM_TABLES
+   unsigned char       PC[16][256][16];  /* 16 tables of 8x128 */
+#endif
+
+   symmetric_key       K;
+
    int                 cipher,       /* which cipher */
                        ivmode,       /* Which mode is the IV in? */
                        mode,         /* mode the GCM code is in */
@@ -492,14 +499,6 @@ typedef struct {
 
    ulong64             totlen,       /* 64-bit counter used for IV and AAD */
                        pttotlen;     /* 64-bit counter for the PT */
-
-#ifdef LTC_GCM_TABLES
-   unsigned char       PC[16][256][16]  /* 16 tables of 8x128 */
-#ifdef LTC_GCM_TABLES_SSE2
-LTC_ALIGN(16)
-#endif
-;
-#endif
 } gcm_state;
 
 void gcm_mult_h(const gcm_state *gcm, unsigned char *I);

+ 21 - 0
src/headers/tomcrypt_private.h

@@ -6,9 +6,30 @@
 /*
  * Internal Macros
  */
+/* Static assertion */
+#define LTC_STATIC_ASSERT(msg, cond) typedef char ltc_static_assert_##msg[(cond) ? 1 : -1];
 
 #define LTC_PAD_MASK       (0xF000U)
 
+#if defined(ENDIAN_64BITWORD)
+   #define CONSTPTR(n) CONST64(n)
+#else
+   #define CONSTPTR(n) n ## uL
+#endif
+
+LTC_STATIC_ASSERT(correct_CONSTPTR_size, sizeof(CONSTPTR(1)) == sizeof(void*))
+
+/* Poor-man's `uintptr_t` since we can't use stdint.h
+ * c.f. https://github.com/DCIT/perl-CryptX/issues/95#issuecomment-1745280962 */
+typedef size_t ltc_uintptr;
+
+LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*))
+
+/* Aligns a `unsigned char` buffer `buf` to `n` bytes and returns that aligned address.
+ * Make sure that the buffer that is passed is huge enough.
+ */
+#define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1)))))
+
 /* `NULL` as defined by the standard is not guaranteed to be of a pointer
  * type. In order to make sure that in vararg API's a pointer type is used,
  * define our own version and use that one internally.