Align macro based and inline LTC_FAST functions.

This commit is contained in:
Steffen Jaeckel 2026-07-31 11:55:11 +02:00 committed by Karel Miko
parent 6bc4dd9b7b
commit 4a964ea017
5 changed files with 64 additions and 29 deletions

View file

@ -44,13 +44,19 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
#endif
/* some compilers do not like "inline" (or maybe "static inline"), namely: HP cc, IBM xlc */
#if !defined(LTC_NO_INLINE)
#if defined(__GNUC__) || defined(__xlc__)
#define LTC_INLINE __inline__
#elif defined(_MSC_VER) || defined(__HP_cc)
#define LTC_INLINE __inline
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define LTC_INLINE inline
#else
#endif
#endif
#if !defined(LTC_INLINE)
#if !defined(LTC_NO_INLINE)
#define LTC_NO_INLINE
#endif
#define LTC_INLINE
#endif
@ -272,29 +278,6 @@ typedef unsigned long ltc_mp_digit;
#else
typedef ulong32 LTC_FAST_TYPE;
#endif
#define LTC_FAST_XOR3(dst, src1, src2) \
do { \
LTC_FAST_TYPE fast_src1, fast_src2, fast_dst; \
XMEMCPY(&fast_src1, (src1), sizeof(LTC_FAST_TYPE)); \
XMEMCPY(&fast_src2, (src2), sizeof(LTC_FAST_TYPE)); \
fast_dst = fast_src1 ^ fast_src2; \
XMEMCPY((dst), &fast_dst, sizeof(LTC_FAST_TYPE)); \
}while (0)
#define LTC_FAST_XOR2(dst, src) LTC_FAST_XOR3((dst), (dst), (src))
#define LTC_FAST_MASK(dst, src, mask) \
do { \
LTC_FAST_TYPE fast_src, fast_mask, fast_dst; \
XMEMCPY(&fast_src, (src), sizeof(LTC_FAST_TYPE)); \
fast_mask = ((LTC_FAST_TYPE)(mask)); \
fast_dst = fast_src & fast_mask; \
XMEMCPY((dst), &fast_dst, sizeof(LTC_FAST_TYPE)); \
}while (0)
#define LTC_FAST_STORE(dst, src) \
do { \
LTC_FAST_TYPE fast_tmp; \
XMEMCPY(&fast_tmp, (src), sizeof(LTC_FAST_TYPE)); \
XMEMCPY((dst), &fast_tmp, sizeof(LTC_FAST_TYPE)); \
}while (0)
#endif
#if !defined(ENDIAN_NEUTRAL) && (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))

View file

@ -47,7 +47,8 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*)
#define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#ifdef LTC_FAST
#if defined(LTC_FAST)
#if !defined(LTC_NO_INLINE)
/* The LTC_FAST helpers operate on byte buffers that are not guaranteed to be aligned for LTC_FAST_TYPE.
Use memcpy for loads/stores to avoid undefined behavior from unaligned or aliasing-unsafe typed-pointer dereferences.
On GCC/Clang prefer __builtin_memcpy: it is guaranteed to be inlined for constant sizes regardless of any
@ -73,6 +74,15 @@ static LTC_INLINE void LTC_FAST_STORE(void *p, LTC_FAST_TYPE v)
#endif
}
static LTC_INLINE void LTC_FAST_STOREP(void *dst, void *src)
{
#if defined(__GNUC__)
__builtin_memcpy(dst, src, sizeof(LTC_FAST_TYPE));
#else
XMEMCPY(dst, src, sizeof(LTC_FAST_TYPE));
#endif
}
static LTC_INLINE void LTC_FAST_XOR2(void *dst, const void *src)
{
LTC_FAST_STORE(dst, LTC_FAST_LOAD(dst) ^ LTC_FAST_LOAD(src));
@ -82,7 +92,44 @@ static LTC_INLINE void LTC_FAST_XOR3(void *dst, const void *src1, const void *sr
{
LTC_FAST_STORE(dst, LTC_FAST_LOAD(src1) ^ LTC_FAST_LOAD(src2));
}
#endif
static LTC_INLINE void LTC_FAST_MASK(void *dst, const void *src, LTC_FAST_TYPE mask)
{
LTC_FAST_STORE(dst, LTC_FAST_LOAD(src) & mask);
}
#else
#define LTC_FAST_LOAD(src) \
({ \
LTC_FAST_TYPE LTC_TMPVAR(fast_tmp); \
XMEMCPY(&LTC_TMPVAR(fast_tmp), (src), sizeof(LTC_FAST_TYPE)); \
LTC_TMPVAR(fast_tmp); \
})
#define LTC_FAST_STORE(dst, v) \
do { \
XMEMCPY((dst), &(v), sizeof(v)); \
} while (0)
#define LTC_FAST_STOREP(dst, src) \
do { \
XMEMCPY((dst), (src), sizeof(LTC_FAST_TYPE)); \
} while (0)
#define LTC_FAST_XOR3(dst, src1, src2) \
do { \
LTC_FAST_TYPE LTC_TMPVAR(fast_src1), LTC_TMPVAR(fast_src2), LTC_TMPVAR(fast_dst); \
XMEMCPY(&LTC_TMPVAR(fast_src1), (src1), sizeof(LTC_FAST_TYPE)); \
XMEMCPY(&LTC_TMPVAR(fast_src2), (src2), sizeof(LTC_FAST_TYPE)); \
LTC_TMPVAR(fast_dst) = LTC_TMPVAR(fast_src1) ^ LTC_TMPVAR(fast_src2); \
XMEMCPY((dst), &LTC_TMPVAR(fast_dst), sizeof(LTC_FAST_TYPE)); \
} while (0)
#define LTC_FAST_XOR2(dst, src) LTC_FAST_XOR3((dst), (dst), (src))
#define LTC_FAST_MASK(dst, src, mask) \
do { \
LTC_FAST_TYPE LTC_TMPVAR(fast_src), LTC_TMPVAR(fast_dst); \
XMEMCPY(&LTC_TMPVAR(fast_src), (src), sizeof(LTC_FAST_TYPE)); \
LTC_TMPVAR(fast_dst) = LTC_TMPVAR(fast_src) & (mask); \
XMEMCPY((dst), &LTC_TMPVAR(fast_dst), sizeof(LTC_FAST_TYPE)); \
} while (0)
#endif /* if !defined(LTC_NO_INLINE) */
#endif /* #if defined(LTC_FAST) */
/*
* Internal Enums

View file

@ -584,6 +584,11 @@ const char *crypt_build_settings =
#if defined(LTC_NO_FAST)
" LTC_NO_FAST "
#endif
#if defined(LTC_NO_INLINE)
" LTC_NO_INLINE "
#else
" " NAME_VALUE(LTC_INLINE) " "
#endif
#if defined(LTC_NO_BSWAP)
" LTC_NO_BSWAP "
#endif

View file

@ -63,8 +63,8 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
#if defined(LTC_FAST)
for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
LTC_FAST_XOR3(&tmpy, (unsigned char *)cbc->IV + x, (unsigned char *)tmp + x);
LTC_FAST_STORE((unsigned char *)cbc->IV + x, (unsigned char *)ct + x);
LTC_FAST_STORE((unsigned char *)pt + x, &tmpy);
LTC_FAST_STOREP((unsigned char *)cbc->IV + x, (unsigned char *)ct + x);
LTC_FAST_STOREP((unsigned char *)pt + x, &tmpy);
}
#else
for (x = 0; x < cbc->ecb.blocklen; x++) {

View file

@ -67,7 +67,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
/* store IV [ciphertext] for a future block */
#if defined(LTC_FAST)
for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
LTC_FAST_STORE((unsigned char *)cbc->IV + x, (unsigned char *)ct + x);
LTC_FAST_STOREP((unsigned char *)cbc->IV + x, (unsigned char *)ct + x);
}
#else
for (x = 0; x < cbc->ecb.blocklen; x++) {