diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb857754..b28ca0b9b 100644 --- a/CMakeLists.txt +++ b/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) diff --git a/demos/gcm-file/gcm_filehandle.c b/demos/gcm-file/gcm_filehandle.c index 11c55a62b..6065f966d 100644 --- a/demos/gcm-file/gcm_filehandle.c +++ b/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) { diff --git a/makefile_include.mk b/makefile_include.mk index f933b36b6..f76798c41 100644 --- a/makefile_include.mk +++ b/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 diff --git a/src/ciphers/aes/aes.c b/src/ciphers/aes/aes.c index 0f46b748a..3a5d0dbb8 100644 --- a/src/ciphers/aes/aes.c +++ b/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; diff --git a/src/ciphers/aes/aesni.c b/src/ciphers/aes/aesni.c index 6f98779ec..113aaf676 100644 --- a/src/ciphers/aes/aesni.c +++ b/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; diff --git a/src/encauth/ccm/ccm_memory.c b/src/encauth/ccm/ccm_memory.c index fdb5172e0..45951ff93 100644 --- a/src/encauth/ccm/ccm_memory.c +++ b/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; } diff --git a/src/encauth/gcm/gcm_memory.c b/src/encauth/gcm/gcm_memory.c index 4da5d5423..6de0b3092 100644 --- a/src/encauth/gcm/gcm_memory.c +++ b/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) { diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index 35af30083..3d90d03cc 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/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 diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index aba28a271..8b6f8781f 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/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 diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 8575c1cc8..129f0245f 100644 --- a/src/headers/tomcrypt_custom.h +++ b/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 */ diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index c8f4a3227..f6738f697 100644 --- a/src/headers/tomcrypt_mac.h +++ b/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); diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index aa251e2ac..041bdd639 100644 --- a/src/headers/tomcrypt_private.h +++ b/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.