diff --git a/ChangeLog b/ChangeLog
index 43faf02aba0d0211d7aad16388d12406eea58c6f..998a650afa74037e8bcedb5053e5eea704929e81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2022-08-31  Niels Möller  <nisse@lysator.liu.se>
+
+	* bswap-internal.h (nettle_bswap64, nettle_bswap32)
+	(bswap64_if_le): New header file, new inline functions/macros.
+	* gcm.c (gcm_hash_sizes): Use bswap64_if_le, and bswap-internal.h,
+	replacing local definition of bswap_if_le.
+	* nist-keywrap.c (nist_keywrap16): Likewise.
+	* blowfish-bcrypt.c (swap32): Renamed function, to...
+	(bswap32_if_le): ...new name, rewritten to use nettle_bswap32.
+	Update call sites.
+	* Makefile.in (DISTFILES): Add bswap-internal.h.
+
 2022-08-18  Niels Möller  <nisse@lysator.liu.se>
 
 	* Makefile.in (HEADERS): Add sm4.h.
diff --git a/Makefile.in b/Makefile.in
index 021ed8c85e04fd1d3449a999ecd5ef2127e3e710..ca1466b788fe8f391f826e7411d71716c266b68d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -259,7 +259,8 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
 	INSTALL NEWS ChangeLog \
 	nettle.pc.in hogweed.pc.in \
 	desdata.stamp $(des_headers) descore.README \
-	aes-internal.h block-internal.h blowfish-internal.h camellia-internal.h \
+	aes-internal.h block-internal.h blowfish-internal.h bswap-internal.h \
+	camellia-internal.h \
 	ghash-internal.h gost28147-internal.h poly1305-internal.h \
 	serpent-internal.h cast128_sboxes.h desinfo.h desCode.h \
 	ripemd160-internal.h md-internal.h sha2-internal.h \
diff --git a/blowfish-bcrypt.c b/blowfish-bcrypt.c
index 800d14688e704ad667d795bb238c76726f38202b..08b1e32e6e2f6fde11e85e56c4cc6e0a1beedbaf 100644
--- a/blowfish-bcrypt.c
+++ b/blowfish-bcrypt.c
@@ -42,7 +42,7 @@
 #include "blowfish.h"
 #include "blowfish-internal.h"
 #include "base64.h"
-
+#include "bswap-internal.h"
 #include "macros.h"
 
 #define CRYPTPLEN 7
@@ -149,19 +149,16 @@ static uint32_t magic_w[6] = {
   0x64657253, 0x63727944, 0x6F756274
 };
 
-/* conflicts with OpenBSD's swap32 macro */
-#undef swap32
-
-static void swap32(uint32_t *x, int count)
+#if WORDS_BIGENDIAN
+#define bswap32_if_le(x, n)
+#else
+static void bswap32_if_le (uint32_t *x, unsigned n)
 {
-#if !WORDS_BIGENDIAN
-  do {
-    uint32_t tmp = *x;
-    tmp = (tmp << 16) | (tmp >> 16);
-    *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
-  } while (--count);
-#endif
+  unsigned i;
+  for (i = 0; i < n; i++)
+    x[i] = nettle_bswap32 (x[i]);
 }
+#endif
 
 static void set_xkey(size_t lenkey, const uint8_t *key,
                      bf_key expanded, bf_key initial,
@@ -343,7 +340,7 @@ static int ibcrypt(uint8_t *dst,
   else if (lenscheme < HASHOFFSET)
     return 0;
   memcpy(psalt, data.binary.salt, BLOWFISH_BCRYPT_BINSALT_SIZE);
-  swap32(data.binary.salt, 4);
+  bswap32_if_le (data.binary.salt, 4);
 
   if (log2rounds < minlog2rounds || log2rounds > 31)
     return 0;
@@ -448,7 +445,7 @@ static int ibcrypt(uint8_t *dst,
   dst = (uint8_t*)
         encode_radix64((char*) dst, BLOWFISH_BCRYPT_BINSALT_SIZE, psalt) - 1;
 
-  swap32(data.binary.output, 6);
+  bswap32_if_le (data.binary.output, 6);
 /* This has to be bug-compatible with the original implementation, so
    only encode 23 of the 24 bytes. */
   encode_radix64((char*) dst, 23, (uint8_t *) data.binary.output);
diff --git a/bswap-internal.h b/bswap-internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9606f1dfcae8b48c069f4b27e4a6c4396afe7d0
--- /dev/null
+++ b/bswap-internal.h
@@ -0,0 +1,71 @@
+/* bswap-internal.h
+
+   Copyright (C) 2022 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NETTLE_BSWAP_INTERNAL_H_INCLUDED
+#define NETTLE_BSWAP_INTERNAL_H_INCLUDED
+
+#include "nettle-types.h"
+
+/* Note that these definitions depend config.h, which should be
+   included first. */
+
+#if HAVE_BUILTIN_BSWAP64
+#define nettle_bswap64 __builtin_bswap64
+/* Assume bswap32 is also available. */
+#define nettle_bswap32 __builtin_bswap32
+#else
+static inline uint64_t
+nettle_bswap64 (uint64_t x)
+{
+  x = (x >> 32) | (x << 32);
+  x = ((x >> 16) & UINT64_C (0xffff0000ffff))
+    | ((x & UINT64_C (0xffff0000ffff)) << 16);
+  x = ((x >> 8) & UINT64_C (0xff00ff00ff00ff))
+    | ((x & UINT64_C (0xff00ff00ff00ff)) << 8);
+  return x;
+}
+
+static inline uint32_t
+nettle_bswap32 (uint32_t x)
+{
+  x = (x << 16) | (x >> 16);
+  x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);
+  return x;
+}
+#endif
+
+#if WORDS_BIGENDIAN
+#define bswap64_if_le(x) (x)
+#else
+#define bswap64_if_le nettle_bswap64
+#endif
+
+#endif /* NETTLE_BSWAP_INTERNAL_H_INCLUDED */
diff --git a/gcm.c b/gcm.c
index 5de8abb21570e2c400ff525fcd0d7225501e550c..1e015b9db2837f56d8f8c43601c938dcfcc23f37 100644
--- a/gcm.c
+++ b/gcm.c
@@ -55,25 +55,7 @@
 #include "macros.h"
 #include "ctr-internal.h"
 #include "block-internal.h"
-
-/* FIXME: Duplicated in nist-keywrap.c */
-#if WORDS_BIGENDIAN
-#define bswap_if_le(x) (x)
-#elif HAVE_BUILTIN_BSWAP64
-#define bswap_if_le(x) (__builtin_bswap64 (x))
-#else
-static uint64_t
-bswap_if_le (uint64_t x)
-{
-  x = ((x >> 32) & UINT64_C (0xffffffff))
-    | ((x & UINT64_C (0xffffffff)) << 32);
-  x = ((x >> 16) & UINT64_C (0xffff0000ffff))
-    | ((x & UINT64_C (0xffff0000ffff)) << 16);
-  x = ((x >> 8) & UINT64_C (0xff00ff00ff00ff))
-    | ((x & UINT64_C (0xff00ff00ff00ff)) << 8);
-  return x;
-}
-#endif
+#include "bswap-internal.h"
 
 /* Initialization of GCM.
  * @ctx: The context of GCM
@@ -115,8 +97,8 @@ gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x,
   data_size *= 8;
   auth_size *= 8;
 
-  buffer.u64[0] = bswap_if_le (auth_size);
-  buffer.u64[1] = bswap_if_le (data_size);
+  buffer.u64[0] = bswap64_if_le (auth_size);
+  buffer.u64[1] = bswap64_if_le (data_size);
 
   _ghash_update (key, x, 1, buffer.b);
 }
diff --git a/nist-keywrap.c b/nist-keywrap.c
index 8fdd9335e44f3ac521ac0dab745a5a9cf9e0c0f2..2aca84235042b658530712610e78c1c7e78cda9e 100644
--- a/nist-keywrap.c
+++ b/nist-keywrap.c
@@ -44,24 +44,7 @@
 #include "nist-keywrap.h"
 #include "memops.h"
 #include "macros.h"
-
-#if WORDS_BIGENDIAN
-#define bswap_if_le(x) (x)
-#elif HAVE_BUILTIN_BSWAP64
-#define bswap_if_le(x) (__builtin_bswap64 (x))
-#else
-static uint64_t
-bswap_if_le (uint64_t x)
-{
-  x = ((x >> 32) & UINT64_C (0xffffffff))
-    | ((x & UINT64_C (0xffffffff)) << 32);
-  x = ((x >> 16) & UINT64_C (0xffff0000ffff))
-    | ((x & UINT64_C (0xffff0000ffff)) << 16);
-  x = ((x >> 8) & UINT64_C (0xff00ff00ff00ff))
-    | ((x & UINT64_C (0xff00ff00ff00ff)) << 8);
-  return x;
-}
-#endif
+#include "bswap-internal.h"
 
 void
 nist_keywrap16 (const void *ctx, nettle_cipher_func *encrypt,
@@ -94,7 +77,7 @@ nist_keywrap16 (const void *ctx, nettle_cipher_func *encrypt,
 	  encrypt (ctx, 16, B.b, I.b);
 
 	  /* A = MSB(64, B) ^ t where t = (n*j)+i */
-	  A.u64 = B.u64[0] ^ bswap_if_le ((n * j) + (i + 1));
+	  A.u64 = B.u64[0] ^ bswap64_if_le ((n * j) + (i + 1));
 
 	  /* R[i] = LSB(64, B) */
 	  memcpy (R + (i * 8), B.b + 8, 8);
@@ -129,7 +112,7 @@ nist_keyunwrap16 (const void *ctx, nettle_cipher_func *decrypt,
       for (i = n - 1; i >= 0; i--)
 	{
 	  /* B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i */
-	  I.u64[0] = A.u64 ^ bswap_if_le ((n * j) + (i + 1));
+	  I.u64[0] = A.u64 ^ bswap64_if_le ((n * j) + (i + 1));
 	  memcpy (I.b + 8, R + (i * 8), 8);
 	  decrypt (ctx, 16, B.b, I.b);