Repository: randombit/botan
Pull request #3291 (2023-02-15 23:18:20)

Remove various function-like macros
Not all of them yet, future PR


Patch:
diff --git a/src/lib/block/aes/aes_ni/aes_ni.cpp b/src/lib/block/aes/aes_ni/aes_ni.cpp
index ea4285403..27b28a272 100644
--- a/src/lib/block/aes/aes_ni/aes_ni.cpp
+++ b/src/lib/block/aes/aes_ni/aes_ni.cpp
@@ -14,9 +14,12 @@ namespace Botan {
 
 namespace {
 
-BOTAN_FUNC_ISA("ssse3")
-__m128i aes_128_key_expansion(__m128i key, __m128i key_with_rcon)
+template<uint8_t RC>
+BOTAN_FUNC_ISA("ssse3,aes")
+inline __m128i
+aes_128_key_expansion(__m128i key, __m128i key_getting_rcon)
    {
+   __m128i key_with_rcon = _mm_aeskeygenassist_si128(key_getting_rcon, RC);
    key_with_rcon = _mm_shuffle_epi32(key_with_rcon, _MM_SHUFFLE(3,3,3,3));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
@@ -26,7 +29,7 @@ __m128i aes_128_key_expansion(__m128i key, __m128i key_with_rcon)
 
 BOTAN_FUNC_ISA("ssse3")
 void aes_192_key_expansion(__m128i* K1, __m128i* K2, __m128i key2_with_rcon,
-                           uint32_t out[], bool last)
+                           secure_vector<uint32_t>& out, size_t offset)
    {
    __m128i key1 = *K1;
    __m128i key2 = *K2;
@@ -38,17 +41,17 @@ void aes_192_key_expansion(__m128i* K1, __m128i* K2, __m128i key2_with_rcon,
    key1 = _mm_xor_si128(key1, key2_with_rcon);
 
    *K1 = key1;
-   _mm_storeu_si128(reinterpret_cast<__m128i*>(out), key1);
+   _mm_storeu_si128(reinterpret_cast<__m128i*>(&out[offset]), key1);
 
-   if(last)
+   if(offset == 48) // last key
       return;
 
    key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4));
    key2 = _mm_xor_si128(key2, _mm_shuffle_epi32(key1, _MM_SHUFFLE(3,3,3,3)));
 
    *K2 = key2;
-   out[4] = _mm_cvtsi128_si32(key2);
-   out[5] = _mm_cvtsi128_si32(_mm_srli_si128(key2, 4));
+   out[offset + 4] = _mm_cvtsi128_si32(key2);
+   out[offset + 5] = _mm_cvtsi128_si32(_mm_srli_si128(key2, 4));
    }
 
 /*
@@ -284,20 +287,17 @@ void AES_128::aesni_key_schedule(const uint8_t key[], size_t /*length*/)
    m_EK.resize(44);
    m_DK.resize(44);
 
-   #define AES_128_key_exp(K, RCON) \
-      aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON))
-
    const __m128i K0  = _mm_loadu_si128(reinterpret_cast<const __m128i*>(key));
-   const __m128i K1  = AES_128_key_exp(K0, 0x01);
-   const __m128i K2  = AES_128_key_exp(K1, 0x02);
-   const __m128i K3  = AES_128_key_exp(K2, 0x04);
-   const __m128i K4  = AES_128_key_exp(K3, 0x08);
-   const __m128i K5  = AES_128_key_exp(K4, 0x10);
-   const __m128i K6  = AES_128_key_exp(K5, 0x20);
-   const __m128i K7  = AES_128_key_exp(K6, 0x40);
-   const __m128i K8  = AES_128_key_exp(K7, 0x80);
-   const __m128i K9  = AES_128_key_exp(K8, 0x1B);
-   const __m128i K10 = AES_128_key_exp(K9, 0x36);
+   const __m128i K1  = aes_128_key_expansion<0x01>(K0, K0);
+   const __m128i K2  = aes_128_key_expansion<0x02>(K1, K1);
+   const __m128i K3  = aes_128_key_expansion<0x04>(K2, K2);
+   const __m128i K4  = aes_128_key_expansion<0x08>(K3, K3);
+   const __m128i K5  = aes_128_key_expansion<0x10>(K4, K4);
+   const __m128i K6  = aes_128_key_expansion<0x20>(K5, K5);
+   const __m128i K7  = aes_128_key_expansion<0x40>(K6, K6);
+   const __m128i K8  = aes_128_key_expansion<0x80>(K7, K7);
+   const __m128i K9  = aes_128_key_expansion<0x1B>(K8, K8);
+   const __m128i K10 = aes_128_key_expansion<0x36>(K9, K9);
 
    __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data());
    _mm_storeu_si128(EK_mm     , K0);
@@ -491,21 +491,14 @@ void AES_192::aesni_key_schedule(const uint8_t key[], size_t /*length*/)
 
    load_le(m_EK.data(), key, 6);
 
-   #define AES_192_key_exp(RCON, EK_OFF)                         \
-     aes_192_key_expansion(&K0, &K1,                             \
-                           _mm_aeskeygenassist_si128(K1, RCON),  \
-                           &m_EK[EK_OFF], EK_OFF == 48)
-
-   AES_192_key_exp(0x01, 6);
-   AES_192_key_exp(0x02, 12);
-   AES_192_key_exp(0x04, 18);
-   AES_192_key_exp(0x08, 24);
-   AES_192_key_exp(0x10, 30);
-   AES_192_key_exp(0x20, 36);
-   AES_192_key_exp(0x40, 42);
-   AES_192_key_exp(0x80, 48);
-
-   #undef AES_192_key_exp
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x01), m_EK, 6);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x02), m_EK, 12);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x04), m_EK, 18);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x08), m_EK, 24);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x10), m_EK, 30);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x20), m_EK, 36);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x40), m_EK, 42);
+   aes_192_key_expansion(&K0, &K1, _mm_aeskeygenassist_si128(K1, 0x80), m_EK, 48);
 
    // Now generate decryption keys
    const __m128i* EK_mm = reinterpret_cast<const __m128i*>(m_EK.data());
@@ -698,25 +691,25 @@ void AES_256::aesni_key_schedule(const uint8_t key[], size_t /*length*/)
    const __m128i K0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(key));
    const __m128i K1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(key + 16));
 
-   const __m128i K2 = aes_128_key_expansion(K0, _mm_aeskeygenassist_si128(K1, 0x01));
+   const __m128i K2 = aes_128_key_expansion<0x01>(K0, K1);
    const __m128i K3 = aes_256_key_expansion(K1, K2);
 
-   const __m128i K4 = aes_128_key_expansion(K2, _mm_aeskeygenassist_si128(K3, 0x02));
+   const __m128i K4 = aes_128_key_expansion<0x02>(K2, K3);
    const __m128i K5 = aes_256_key_expansion(K3, K4);
 
-   const __m128i K6 = aes_128_key_expansion(K4, _mm_aeskeygenassist_si128(K5, 0x04));
+   const __m128i K6 = aes_128_key_expansion<0x04>(K4, K5);
    const __m128i K7 = aes_256_key_expansion(K5, K6);
 
-   const __m128i K8 = aes_128_key_expansion(K6, _mm_aeskeygenassist_si128(K7, 0x08));
+   const __m128i K8 = aes_128_key_expansion<0x08>(K6, K7);
    const __m128i K9 = aes_256_key_expansion(K7, K8);
 
-   const __m128i K10 = aes_128_key_expansion(K8, _mm_aeskeygenassist_si128(K9, 0x10));
+   const __m128i K10 = aes_128_key_expansion<0x10>(K8, K9);
    const __m128i K11 = aes_256_key_expansion(K9, K10);
 
-   const __m128i K12 = aes_128_key_expansion(K10, _mm_aeskeygenassist_si128(K11, 0x20));
+   const __m128i K12 = aes_128_key_expansion<0x20>(K10, K11);
    const __m128i K13 = aes_256_key_expansion(K11, K12);
 
-   const __m128i K14 = aes_128_key_expansion(K12, _mm_aeskeygenassist_si128(K13, 0x40));
+   const __m128i K14 = aes_128_key_expansion<0x40>(K12, K13);
 
    __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data());
    _mm_storeu_si128(EK_mm     , K0);
diff --git a/src/lib/block/serpent/serpent_avx2/serpent_avx2.cpp b/src/lib/block/serpent/serpent_avx2/serpent_avx2.cpp
index 9be3be572..da1c6ba49 100644
--- a/src/lib/block/serpent/serpent_avx2/serpent_avx2.cpp
+++ b/src/lib/block/serpent/serpent_avx2/serpent_avx2.cpp
@@ -10,7 +10,7 @@
 
 namespace Botan {
 
-#if defined(__GNUG__)
+#if defined(__GNUG__) && !defined(__clang__)
 
 // These macros are redundant with the versions in serpent_sbox.h
 // but unfortunately removing them seems to trigger a bug in GCC
diff --git a/src/lib/block/sm4/sm4.cpp b/src/lib/block/sm4/sm4.cpp
index a59eb1263..f1023c617 100644
--- a/src/lib/block/sm4/sm4.cpp
+++ b/src/lib/block/sm4/sm4.cpp
@@ -118,41 +118,59 @@ inline uint32_t SM4_Tp(uint32_t b)
    return t ^ rotl<13>(t) ^ rotl<23>(t);
    }
 
-#define SM4_E_RNDS(R, F) do {                      \
-   B0 ^= F(B1 ^ B2 ^ B3 ^ m_RK[4*R+0]);            \
-   B1 ^= F(B2 ^ B3 ^ B0 ^ m_RK[4*R+1]);            \
-   B2 ^= F(B3 ^ B0 ^ B1 ^ m_RK[4*R+2]);            \
-   B3 ^= F(B0 ^ B1 ^ B2 ^ m_RK[4*R+3]);            \
-   } while(0)
-
-#define SM4_Ex2_RNDS(R, F) do {                    \
-   B0 ^= F(B1 ^ B2 ^ B3 ^ m_RK[4*R+0]);            \
-   C0 ^= F(C1 ^ C2 ^ C3 ^ m_RK[4*R+0]);            \
-   B1 ^= F(B2 ^ B3 ^ B0 ^ m_RK[4*R+1]);            \
-   C1 ^= F(C2 ^ C3 ^ C0 ^ m_RK[4*R+1]);            \
-   B2 ^= F(B3 ^ B0 ^ B1 ^ m_RK[4*R+2]);            \
-   C2 ^= F(C3 ^ C0 ^ C1 ^ m_RK[4*R+2]);            \
-   B3 ^= F(B0 ^ B1 ^ B2 ^ m_RK[4*R+3]);            \
-   C3 ^= F(C0 ^ C1 ^ C2 ^ m_RK[4*R+3]);            \
-} while(0)
-
-#define SM4_D_RNDS(R, F) do {                      \
-   B0 ^= F(B1 ^ B2 ^ B3 ^ m_RK[4*R+3]);            \
-   B1 ^= F(B2 ^ B3 ^ B0 ^ m_RK[4*R+2]);            \
-   B2 ^= F(B3 ^ B0 ^ B1 ^ m_RK[4*R+1]);            \
-   B3 ^= F(B0 ^ B1 ^ B2 ^ m_RK[4*R+0]);            \
-   } while(0)
-
-#define SM4_Dx2_RNDS(R, F) do {                    \
-   B0 ^= F(B1 ^ B2 ^ B3 ^ m_RK[4*R+3]);            \
-   C0 ^= F(C1 ^ C2 ^ C3 ^ m_RK[4*R+3]);            \
-   B1 ^= F(B2 ^ B3 ^ B0 ^ m_RK[4*R+2]);            \
-   C1 ^= F(C2 ^ C3 ^ C0 ^ m_RK[4*R+2]);            \
-   B2 ^= F(B3 ^ B0 ^ B1 ^ m_RK[4*R+1]);            \
-   C2 ^= F(C3 ^ C0 ^ C1 ^ m_RK[4*R+1]);            \
-   B3 ^= F(B0 ^ B1 ^ B2 ^ m_RK[4*R+0]);            \
-   C3 ^= F(C0 ^ C1 ^ C2 ^ m_RK[4*R+0]);            \
-} while(0)
+template<size_t R, typename F>
+BOTAN_FORCE_INLINE
+void SM4_E(uint32_t& B0, uint32_t& B1, uint32_t& B2, uint32_t& B3,
+           const secure_vector<uint32_t>& RK, F& f)
+   {
+   B0 ^= f(B1 ^ B2 ^ B3 ^ RK[4*R+0]);
+   B1 ^= f(B2 ^ B3 ^ B0 ^ RK[4*R+1]);
+   B2 ^= f(B3 ^ B0 ^ B1 ^ RK[4*R+2]);
+   B3 ^= f(B0 ^ B1 ^ B2 ^ RK[4*R+3]);
+   }
+
+template<size_t R, typename F>
+BOTAN_FORCE_INLINE
+void SM4_E(uint32_t& B0, uint32_t& B1, uint32_t& B2, uint32_t& B3,
+           uint32_t& C0, uint32_t& C1, uint32_t& C2, uint32_t& C3,
+           const secure_vector<uint32_t>& RK, F& f)
+   {
+   B0 ^= f(B1 ^ B2 ^ B3 ^ RK[4*R+0]);
+   C0 ^= f(C1 ^ C2 ^ C3 ^ RK[4*R+0]);
+   B1 ^= f(B2 ^ B3 ^ B0 ^ RK[4*R+1]);
+   C1 ^= f(C2 ^ C3 ^ C0 ^ RK[4*R+1]);
+   B2 ^= f(B3 ^ B0 ^ B1 ^ RK[4*R+2]);
+   C2 ^= f(C3 ^ C0 ^ C1 ^ RK[4*R+2]);
+   B3 ^= f(B0 ^ B1 ^ B2 ^ RK[4*R+3]);
+   C3 ^= f(C0 ^ C1 ^ C2 ^ RK[4*R+3]);
+   }
+
+template<size_t R, typename F>
+BOTAN_FORCE_INLINE
+void SM4_D(uint32_t& B0, uint32_t& B1, uint32_t& B2, uint32_t& B3,
+           const secure_vector<uint32_t>& RK, F& f)
+   {
+   B0 ^= f(B1 ^ B2 ^ B3 ^ RK[4*R+3]);
+   B1 ^= f(B2 ^ B3 ^ B0 ^ RK[4*R+2]);
+   B2 ^= f(B3 ^ B0 ^ B1 ^ RK[4*R+1]);
+   B3 ^= f(B0 ^ B1 ^ B2 ^ RK[4*R+0]);
+   }
+
+template<size_t R, typename F>
+BOTAN_FORCE_INLINE
+void SM4_D(uint32_t& B0, uint32_t& B1, uint32_t& B2, uint32_t& B3,
+           uint32_t& C0, uint32_t& C1, uint32_t& C2, uint32_t& C3,
+           const secure_vector<uint32_t>& RK, F& f)
+   {
+   B0 ^= f(B1 ^ B2 ^ B3 ^ RK[4*R+3]);
+   C0 ^= f(C1 ^ C2 ^ C3 ^ RK[4*R+3]);
+   B1 ^= f(B2 ^ B3 ^ B0 ^ RK[4*R+2]);
+   C1 ^= f(C2 ^ C3 ^ C0 ^ RK[4*R+2]);
+   B2 ^= f(B3 ^ B0 ^ B1 ^ RK[4*R+1]);
+   C2 ^= f(C3 ^ C0 ^ C1 ^ RK[4*R+1]);
+   B3 ^= f(B0 ^ B1 ^ B2 ^ RK[4*R+0]);
+   C3 ^= f(C0 ^ C1 ^ C2 ^ RK[4*R+0]);
+   }
 
 }
 
@@ -180,14 +198,14 @@ void SM4::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
       uint32_t C2 = load_be<uint32_t>(in, 6);
       uint32_t C3 = load_be<uint32_t>(in, 7);
 
-      SM4_Ex2_RNDS(0, SM4_T_slow);
-      SM4_Ex2_RNDS(1, SM4_T);
-      SM4_Ex2_RNDS(2, SM4_T);
-      SM4_Ex2_RNDS(3, SM4_T);
-      SM4_Ex2_RNDS(4, SM4_T);
-      SM4_Ex2_RNDS(5, SM4_T);
-      SM4_Ex2_RNDS(6, SM4_T);
-      SM4_Ex2_RNDS(7, SM4_T_slow);
+      SM4_E<0>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T_slow);
+      SM4_E<1>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<2>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<3>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<4>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<5>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<6>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_E<7>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T_slow);
 
       store_be(out, B3, B2, B1, B0, C3, C2, C1, C0);
 
@@ -203,14 +221,14 @@ void SM4::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
       uint32_t B2 = load_be<uint32_t>(in, 2);
       uint32_t B3 = load_be<uint32_t>(in, 3);
 
-      SM4_E_RNDS(0, SM4_T_slow);
-      SM4_E_RNDS(1, SM4_T);
-      SM4_E_RNDS(2, SM4_T);
-      SM4_E_RNDS(3, SM4_T);
-      SM4_E_RNDS(4, SM4_T);
-      SM4_E_RNDS(5, SM4_T);
-      SM4_E_RNDS(6, SM4_T);
-      SM4_E_RNDS(7, SM4_T_slow);
+      SM4_E<0>(B0, B1, B2, B3, m_RK, SM4_T_slow);
+      SM4_E<1>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<2>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<3>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<4>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<5>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<6>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_E<7>(B0, B1, B2, B3, m_RK, SM4_T_slow);
 
       store_be(out, B3, B2, B1, B0);
 
@@ -243,14 +261,14 @@ void SM4::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
       uint32_t C2 = load_be<uint32_t>(in, 6);
       uint32_t C3 = load_be<uint32_t>(in, 7);
 
-      SM4_Dx2_RNDS(7, SM4_T_slow);
-      SM4_Dx2_RNDS(6, SM4_T);
-      SM4_Dx2_RNDS(5, SM4_T);
-      SM4_Dx2_RNDS(4, SM4_T);
-      SM4_Dx2_RNDS(3, SM4_T);
-      SM4_Dx2_RNDS(2, SM4_T);
-      SM4_Dx2_RNDS(1, SM4_T);
-      SM4_Dx2_RNDS(0, SM4_T_slow);
+      SM4_D<7>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T_slow);
+      SM4_D<6>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<5>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<4>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<3>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<2>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<1>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T);
+      SM4_D<0>(B0, B1, B2, B3, C0, C1, C2, C3, m_RK, SM4_T_slow);
 
       store_be(out, B3, B2, B1, B0, C3, C2, C1, C0);
 
@@ -266,14 +284,14 @@ void SM4::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
       uint32_t B2 = load_be<uint32_t>(in, 2);
       uint32_t B3 = load_be<uint32_t>(in, 3);
 
-      SM4_D_RNDS(7, SM4_T_slow);
-      SM4_D_RNDS(6, SM4_T);
-      SM4_D_RNDS(5, SM4_T);
-      SM4_D_RNDS(4, SM4_T);
-      SM4_D_RNDS(3, SM4_T);
-      SM4_D_RNDS(2, SM4_T);
-      SM4_D_RNDS(1, SM4_T);
-      SM4_D_RNDS(0, SM4_T_slow);
+      SM4_D<7>(B0, B1, B2, B3, m_RK, SM4_T_slow);
+      SM4_D<6>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<5>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<4>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<3>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<2>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<1>(B0, B1, B2, B3, m_RK, SM4_T);
+      SM4_D<0>(B0, B1, B2, B3, m_RK, SM4_T_slow);
 
       store_be(out, B3, B2, B1, B0);
 
@@ -282,9 +300,6 @@ void SM4::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
       }
    }
 
-#undef SM4_E_RNDS
-#undef SM4_D_RNDS
-
 /*
 * SM4 Key Schedule
 */
diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp
index 0692c2437..931b4285e 100644
--- a/src/lib/hash/sha2_32/sha2_32.cpp
+++ b/src/lib/hash/sha2_32/sha2_32.cpp
@@ -7,6 +7,7 @@
 */
 
 #include <botan/internal/sha2_32.h>
+#include <botan/internal/sha2_32_f.h>
 #include <botan/internal/loadstor.h>
 #include <botan/internal/rotate.h>
 #include <botan/internal/bit_ops.h>
@@ -54,23 +55,6 @@ std::unique_ptr<HashFunction> SHA_256::copy_state() const
    return std::make_unique<SHA_256>(*this);
    }
 
-/*
-* SHA-256 F1 Function
-*
-* Use a macro as many compilers won't inline a function this big,
-* even though it is much faster if inlined.
-*/
-#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) do {   \
-   uint32_t A_rho = rho<2, 13, 22>(A);                                  \
-   uint32_t E_rho = rho<6, 11, 25>(E);                                  \
-   uint32_t M2_sigma = sigma<17, 19, 10>(M2);                           \
-   uint32_t M4_sigma = sigma<7, 18, 3>(M4);                             \
-   H += magic + E_rho + choose(E, F, G) + M1;                           \
-   D += H;                                                              \
-   H += A_rho + majority(A, B, C);                                      \
-   M1 += M2_sigma + M3 + M4_sigma;                                      \
-   } while(0);
-
 /*
 * SHA-224 / SHA-256 compression function
 */
diff --git a/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp b/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp
index 89deb5901..a1fdd8aa8 100644
--- a/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp
+++ b/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp
@@ -5,6 +5,7 @@
 */
 
 #include <botan/internal/sha2_32.h>
+#include <botan/internal/sha2_32_f.h>
 #include <botan/internal/loadstor.h>
 #include <botan/internal/rotate.h>
 #include <botan/internal/bit_ops.h>
@@ -18,18 +19,6 @@ flags, GCC and Clang use the BMI2 instructions without further help.
 
 Likely instruction scheduling could be improved by using inline asm.
 */
-
-#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) do {   \
-   uint32_t A_rho = rho<2, 13, 22>(A);                                  \
-   uint32_t E_rho = rho<6, 11, 25>(E);                                  \
-   uint32_t M2_sigma = sigma<17, 19, 10>(M2);                           \
-   uint32_t M4_sigma = sigma<7, 18, 3>(M4);                             \
-   H += magic + E_rho + choose(E, F, G) + M1;                           \
-   D += H;                                                              \
-   H += A_rho + majority(A, B, C);                                      \
-   M1 += M2_sigma + M3 + M4_sigma;                                      \
-   } while(0);
-
 void SHA_256::compress_digest_x86_bmi2(secure_vector<uint32_t>& digest,
                                        const uint8_t input[],
                                        size_t blocks)
diff --git a/src/lib/hash/sha2_32/sha2_32_f.h b/src/lib/hash/sha2_32/sha2_32_f.h
new file mode 100644
index 000000000..258e978ba
--- /dev/null
+++ b/src/lib/hash/sha2_32/sha2_32_f.h
@@ -0,0 +1,37 @@
+/*
+* (C) 2023 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SHA2_32_F_H_
+#define BOTAN_SHA2_32_F_H_
+
+#include <botan/types.h>
+#include <botan/internal/rotate.h>
+#include <botan/internal/bit_ops.h>
+
+namespace Botan {
+
+/*
+* SHA-256 F1 Function
+*/
+BOTAN_FORCE_INLINE void
+SHA2_32_F(uint32_t A, uint32_t B, uint32_t C, uint32_t& D,
+          uint32_t E, uint32_t F, uint32_t G, uint32_t& H,
+          uint32_t& M1, uint32_t M2, uint32_t M3, uint32_t M4,
+          uint32_t magic)
+   {
+   uint32_t A_rho = rho<2, 13, 22>(A);
+   uint32_t E_rho = rho<6, 11, 25>(E);
+   uint32_t M2_sigma = sigma<17, 19, 10>(M2);
+   uint32_t M4_sigma = sigma<7, 18, 3>(M4);
+   H += magic + E_rho + choose(E, F, G) + M1;
+   D += H;
+   H += A_rho + majority(A, B, C);
+   M1 += M2_sigma + M3 + M4_sigma;                                      \
+   }
+
+}
+
+#endif
diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp
index 32661d60e..3bc41c363 100644
--- a/src/lib/hash/sha2_64/sha2_64.cpp
+++ b/src/lib/hash/sha2_64/sha2_64.cpp
@@ -6,6 +6,7 @@
 */
 
 #include <botan/internal/sha2_64.h>
+#include <botan/internal/sha2_64_f.h>
 #include <botan/internal/loadstor.h>
 #include <botan/internal/rotate.h>
 #include <botan/internal/bit_ops.h>
@@ -44,24 +45,6 @@ std::unique_ptr<HashFunction> SHA_512_256::copy_state() const
    return std::make_unique<SHA_512_256>(*this);
    }
 
-/*
-* SHA-512 F1 Function
-*
-* Use a macro as many compilers won't inline a function this big,
-* even though it is much faster if inlined.
-*/
-#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic)         \
-   do {                                                                  \
-      const uint64_t E_rho = rho<14, 18, 41>(E);                         \
-      const uint64_t A_rho = rho<28, 34, 39>(A);                         \
-      const uint64_t M2_sigma = sigma<19, 61, 6>(M2);                    \
-      const uint64_t M4_sigma = sigma<1, 8, 7>(M4);                      \
-      H += magic + E_rho + choose(E, F, G) + M1;                         \
-      D += H;                                                            \
-      H += A_rho + majority(A, B, C);                                    \
-      M1 += M2_sigma + M3 + M4_sigma;                                    \
-   } while(0);
-
 /*
 * SHA-{384,512} Compression Function
 */
diff --git a/src/lib/hash/sha2_64/sha2_64_bmi2/sha2_64_bmi2.cpp b/src/lib/hash/sha2_64/sha2_64_bmi2/sha2_64_bmi2.cpp
index 472cca9d6..d31846ca4 100644
--- a/src/lib/hash/sha2_64/sha2_64_bmi2/sha2_64_bmi2.cpp
+++ b/src/lib/hash/sha2_64/sha2_64_bmi2/sha2_64_bmi2.cpp
@@ -5,30 +5,13 @@
 */
 
 #include <botan/internal/sha2_64.h>
+#include <botan/internal/sha2_64_f.h>
 #include <botan/internal/loadstor.h>
 #include <botan/internal/rotate.h>
 #include <botan/internal/bit_ops.h>
 
 namespace Botan {
 
-/*
-* SHA-512 F1 Function
-*
-* Use a macro as many compilers won't inline a function this big,
-* even though it is much faster if inlined.
-*/
-#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic)         \
-   do {                                                                  \
-      const uint64_t E_rho = rho<14, 18, 41>(E);                         \
-      const uint64_t A_rho = rho<28, 34, 39>(A);                         \
-      const uint64_t M2_sigma = sigma<19, 61, 6>(M2);                    \
-      const uint64_t M4_sigma = sigma<1, 8, 7>(M4);                      \
-      H += magic + E_rho + choose(E, F, G) + M1;                         \
-      D += H;                                                            \
-      H += A_rho + majority(A, B, C);                                    \
-      M1 += M2_sigma + M3 + M4_sigma;                                    \
-   } while(0);
-
 void SHA_512::compress_digest_bmi2(secure_vector<uint64_t>& digest,
                                    const uint8_t input[], size_t blocks)
    {
diff --git a/src/lib/hash/sha2_64/sha2_64_f.h b/src/lib/hash/sha2_64/sha2_64_f.h
new file mode 100644
index 000000000..2ef13aec2
--- /dev/null
+++ b/src/lib/hash/sha2_64/sha2_64_f.h
@@ -0,0 +1,37 @@
+/*
+* (C) 2023 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SHA2_64_F_H_
+#define BOTAN_SHA2_64_F_H_
+
+#include <botan/types.h>
+#include <botan/internal/rotate.h>
+#include <botan/internal/bit_ops.h>
+
+namespace Botan {
+
+/*
+* SHA-512 F1 Function
+*/
+BOTAN_FORCE_INLINE void
+SHA2_64_F(uint64_t A, uint64_t B, uint64_t C, uint64_t& D,
+          uint64_t E, uint64_t F, uint64_t G, uint64_t& H,
+          uint64_t& M1, uint64_t M2, uint64_t M3, uint64_t M4,
+          uint64_t magic)
+   {
+   const uint64_t E_rho = rho<14, 18, 41>(E);
+   const uint64_t A_rho = rho<28, 34, 39>(A);
+   const uint64_t M2_sigma = sigma<19, 61, 6>(M2);
+   const uint64_t M4_sigma = sigma<1, 8, 7>(M4);
+   H += magic + E_rho + choose(E, F, G) + M1;
+   D += H;
+   H += A_rho + majority(A, B, C);
+   M1 += M2_sigma + M3 + M4_sigma;
+   }
+
+}
+
+#endif
diff --git a/src/lib/pubkey/mce/gf2m_small_m.cpp b/src/lib/pubkey/mce/gf2m_small_m.cpp
index f97cb20b0..be68a12cd 100644
--- a/src/lib/pubkey/mce/gf2m_small_m.cpp
+++ b/src/lib/pubkey/mce/gf2m_small_m.cpp
@@ -14,7 +14,7 @@
 
 namespace Botan {
 
-#define MAX_EXT_DEG 16
+const size_t MAX_EXT_DEG = 16;
 
 namespace {
 
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index 449fd9bd3..7abdf2338 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -541,26 +541,28 @@ std::vector<void*> OS::allocate_locked_pages(size_t count)
 
 #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
 
-#if !defined(MAP_ANONYMOUS)
-   #define MAP_ANONYMOUS MAP_ANON
+      int mmap_flags = MAP_PRIVATE;
+
+#if defined(MAP_ANONYMOUS)
+      mmap_flags |= MAP_ANONYMOUS;
+#elif defined(MAP_ANON)
+      mmap_flags |= MAP_ANON;
 #endif
 
-#if !defined(MAP_NOCORE)
 #if defined(MAP_CONCEAL)
-   #define MAP_NOCORE MAP_CONCEAL
-#else
-   #define MAP_NOCORE 0
-#endif
+      mmap_flags |= MAP_CONCEAL;
+#elif defined(MAP_NOCORE)
+      mmap_flags |= MAP_NOCORE;
 #endif
 
-#if !defined(PROT_MAX)
-   #define PROT_MAX(p) 0
+      int mmap_prot = PROT_READ | PROT_WRITE;
+
+#if defined(PROT_MAX)
+      mmap_prot |= PROT_MAX(mmap_prot);
 #endif
-      const int pflags = PROT_READ | PROT_WRITE;
 
       ptr = ::mmap(nullptr, 3*page_size,
-                   pflags | PROT_MAX(pflags),
-                   MAP_ANONYMOUS | MAP_PRIVATE | MAP_NOCORE,
+                   mmap_prot, mmap_flags,
                    /*fd=*/locked_fd, /*offset=*/0);
 
       if(ptr == MAP_FAILED)
diff --git a/src/lib/utils/version.cpp b/src/lib/utils/version.cpp
index 60a5de5ec..72738e79a 100644
--- a/src/lib/utils/version.cpp
+++ b/src/lib/utils/version.cpp
@@ -16,7 +16,9 @@ namespace Botan {
   version they are running against.
 */
 
+// NOLINTNEXTLINE(*-macro-usage)
 #define QUOTE(name) #name
+// NOLINTNEXTLINE(*-macro-usage)
 #define STR(macro) QUOTE(macro)
 
 const char* short_version_cstr()


Test patch:
diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp
index 09b8502ef..22708724a 100644
--- a/src/tests/test_hash.cpp
+++ b/src/tests/test_hash.cpp
@@ -339,7 +339,7 @@ Test::Result hash_truncation_negative_tests()
    auto unobtainable = Botan::HashFunction::create("Truncated(NonExistentHash-256,128)");
    result.confirm("non-existent hashes are not created", unobtainable == nullptr);
    return result;
-   };
+   }
 
 BOTAN_REGISTER_TEST_FN("hash", "hash_truncation", hash_truncation_negative_tests);