diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # Revision history for the hashes package
 
+## 0.3.0.1 -- 2024-08-20
+
+*   Fix building the package on Gentoo.
+
+Internal Changes:
+
+*   Replace the Syd test framework by hspec.
+*   Modernize the FFI interface with OpenSSL.
+
 ## 0.3.0 -- 2024-07-12
 
 Breaking Changes:
diff --git a/cbits/keccak.c b/cbits/keccak.c
--- a/cbits/keccak.c
+++ b/cbits/keccak.c
@@ -100,7 +100,7 @@
 /* Implementation */
 
 #if OPENSSL_VERSION_NUMBER < 0x30200000L
-int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, EVP_MD *md) {
+int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md) {
     int ok = 1;
     CHECKED(EVP_DigestInit_ex(ctx, md, NULL));
     SET_PAD_BYTE;
diff --git a/cbits/keccak.h b/cbits/keccak.h
--- a/cbits/keccak.h
+++ b/cbits/keccak.h
@@ -22,5 +22,5 @@
  */
 
 #if OPENSSL_VERSION_NUMBER < 0x30200000L
-int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, EVP_MD *md);
+int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md);
 #endif
diff --git a/hashes.cabal b/hashes.cabal
--- a/hashes.cabal
+++ b/hashes.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: hashes
-version: 0.3.0
+version: 0.3.0.1
 synopsis: Hash functions
 Description: Efficient implementations of hash functions
 homepage: https://github.com/larskuhtz/hs-hashes
@@ -75,6 +75,12 @@
         Data.Hash.FNV1.Salted
         Data.Hash.Internal.Utils
         Data.Hash.SipHash
+    -- this allows us to #include <opensslv.h> on Gentoo
+    -- from a Haskell file
+    if arch(x86_64)
+        cpp-options: -D__x86_64__
+    if arch(aarch64)
+        cpp-options: -D__aarch64__
     if flag(with-openssl)
         exposed-modules:
             Data.Hash.Blake2
@@ -107,10 +113,10 @@
         -- internal
         , hashes
         -- external
-        , QuickCheck >= 2.13
+        , QuickCheck >=2.13
         , base >=4.11 && <5
         , bytestring >=0.10
-        , sydtest >=0.4
+        , hspec >=2.11
         , vector >=0.12
 
     if flag(with-openssl)
@@ -155,4 +161,3 @@
             , memory >=0.14
             , cryptonite >=0.29
         cpp-options: -DBENCHMARK_CRYPTONITE=1
-
diff --git a/src/Data/Hash/Internal/OpenSSL.hs b/src/Data/Hash/Internal/OpenSSL.hs
--- a/src/Data/Hash/Internal/OpenSSL.hs
+++ b/src/Data/Hash/Internal/OpenSSL.hs
@@ -13,6 +13,10 @@
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
 
+#if !MIN_VERSION_base(4,18,0)
+{-# LANGUAGE PatternSynonyms #-}
+#endif
+
 #include <openssl/opensslv.h>
 
 -- |
@@ -98,7 +102,13 @@
 import Data.Void
 import Data.Word
 
-import Foreign.C.String (CString, withCString)
+#if MIN_VERSION_base(4,18,0)
+import Foreign.C.ConstPtr (ConstPtr(..))
+import Foreign.C.String (withCString)
+#else
+import Foreign.C.String(CString, withCString)
+#endif
+import Foreign.C.Types
 import Foreign.ForeignPtr
 import Foreign.Marshal
 import Foreign.Ptr
@@ -141,6 +151,28 @@
 instance Exception OpenSslException
 
 -- -------------------------------------------------------------------------- --
+-- Utils for ConstPtr
+
+#if MIN_VERSION_base(4,18,0)
+type ConstCString = ConstPtr CChar
+#else
+type ConstPtr a = Ptr a
+type ConstCString = CString
+
+pattern ConstPtr :: forall p. p -> p
+pattern ConstPtr a = a
+#endif
+
+withConstCString :: String -> (ConstCString -> IO a) -> IO a
+withConstCString str inner = withCString str $ \cstr -> inner (ConstPtr cstr)
+
+constPtr :: Addr# -> ConstPtr a
+constPtr a = ConstPtr (Ptr a)
+
+nullConstPtr :: ConstPtr a
+nullConstPtr = ConstPtr nullPtr
+
+-- -------------------------------------------------------------------------- --
 -- OpenSSL Message Digest Algorithms
 
 -- | An algorithm implementation from an OpenSSL algorithm provider.
@@ -172,7 +204,7 @@
 -- identifier, and the search criteria.
 --
 foreign import ccall unsafe "openssl/evp.h EVP_MD_fetch"
-    c_evp_md_fetch :: Ptr Void {- nullPtr -} -> CString -> CString -> IO (Ptr a)
+    c_evp_md_fetch :: Ptr Void {- nullPtr -} -> ConstCString -> ConstCString -> IO (Ptr a)
 
 foreign import ccall unsafe "openssl/evp.h &EVP_MD_free"
     c_evp_md_free :: FunPtr (Ptr a -> IO ())
@@ -187,14 +219,14 @@
 --
 fetchAlgorithm :: String -> IO (Algorithm a)
 fetchAlgorithm name = do
-    withCString name $ \namePtr -> mask_ $ do
-        ptr <- c_evp_md_fetch nullPtr namePtr (Ptr "provider=default"#)
+    withConstCString name $ \namePtr -> mask_ $ do
+        ptr <- c_evp_md_fetch nullPtr namePtr (constPtr "provider=default"#)
         when (ptr == nullPtr) $ throw $ OpenSslException $ "fetching algorithm failed: " <> name
         Algorithm <$> newForeignPtr c_evp_md_free ptr
 #else
 
 foreign import ccall unsafe "openssl/evp.h EVP_get_digestbyname"
-    c_EVP_get_digestbyname :: CString -> IO (Ptr a)
+    c_EVP_get_digestbyname :: ConstCString -> IO (ConstPtr a)
 
 -- | Look up the 'Algorithm' with given identifier. This is a less efficient
 -- legacy way to obtain algorithm implementations. The returned algorithms
@@ -205,8 +237,8 @@
 --
 fetchAlgorithm :: String -> IO (Algorithm a)
 fetchAlgorithm name = do
-    withCString name $ \namePtr -> mask_ $ do
-        ptr <- c_EVP_get_digestbyname namePtr
+    withConstCString name $ \namePtr -> mask_ $ do
+        ConstPtr ptr <- c_EVP_get_digestbyname namePtr
         when (ptr == nullPtr) $ throw $ OpenSslException $ "fetching algorithm failed: " <> name
         Algorithm <$> newForeignPtr_ ptr
 #endif
@@ -240,27 +272,27 @@
 #else
 foreign import ccall unsafe "openssl/evp.h EVP_DigestInit_ex"
 #endif
-    c_evp_digest_init :: Ptr ctx -> Ptr alg -> Ptr Void {- nullPtr -} -> IO Bool
+    c_evp_digest_init :: Ptr ctx -> ConstPtr alg -> Ptr Void {- nullPtr -} -> IO CInt
 
 foreign import ccall unsafe "openssl/evp.h EVP_DigestUpdate"
-    c_evp_digest_update :: Ptr ctx -> Ptr d -> Int -> IO Bool
+    c_evp_digest_update :: Ptr ctx -> ConstPtr d -> CSize -> IO CInt
 
 foreign import ccall unsafe "openssl/evp.h EVP_DigestFinal_ex"
-    c_evp_digest_final :: Ptr ctx -> Ptr d -> Ptr Int -> IO Bool
+    c_evp_digest_final :: Ptr ctx -> Ptr CUChar -> Ptr CUInt -> IO CInt
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 foreign import ccall unsafe "openssl/evp.h EVP_MD_CTX_get0_md"
 #else
 foreign import ccall unsafe "openssl/evp.h EVP_MD_CTX_md"
 #endif
-    c_evp_md_ctx_get0_md :: Ptr ctx -> Ptr a
+    c_evp_md_ctx_get0_md :: ConstPtr ctx -> ConstPtr a
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 foreign import ccall unsafe "openssl/evp.h EVP_MD_get_size"
 #else
 foreign import ccall unsafe "openssl/evp.h EVP_MD_size"
 #endif
-    c_evp_md_get_size :: Ptr a -> Int
+    c_evp_md_get_size :: ConstPtr a -> CInt
 
 newCtx :: IO (Ctx a)
 newCtx = mask_ $ do
@@ -277,8 +309,8 @@
     c@(Ctx ctx) <- newCtx
     r <- withForeignPtr ctx $ \ctxPtr ->
         withForeignPtr alg $ \algPtr ->
-            c_evp_digest_init ctxPtr algPtr nullPtr
-    unless r $ throw $ OpenSslException "digest initialization failed"
+            c_evp_digest_init ctxPtr (ConstPtr algPtr) nullPtr
+    when (r == 0) $ throw $ OpenSslException "digest initialization failed"
     return c
 {-# INLINE initCtx #-}
 
@@ -287,27 +319,27 @@
 resetCtx :: Ctx a -> IO ()
 resetCtx (Ctx ctx) = do
     r <- withForeignPtr ctx $ \ptr ->
-        c_evp_digest_init ptr nullPtr nullPtr
-    unless r $ throw $ OpenSslException "digest re-initialization failed"
+        c_evp_digest_init ptr nullConstPtr nullPtr
+    when (r == 0) $ throw $ OpenSslException "digest re-initialization failed"
 {-# INLINE resetCtx #-}
 
 -- | Feed more data into an context.
 --
 updateCtx :: Ctx a -> Ptr Word8 -> Int -> IO ()
 updateCtx (Ctx ctx) d c = withForeignPtr ctx $ \ptr -> do
-    r <- c_evp_digest_update ptr d c
-    unless r $ throw $ OpenSslException "digest update failed"
+    r <- c_evp_digest_update ptr (ConstPtr d) (fromIntegral c)
+    when (r == 0) $ throw $ OpenSslException "digest update failed"
 {-# INLINE updateCtx #-}
 
 -- | Finalize a hash and return the digest.
 --
 finalCtx :: Ctx a -> IO (Digest a)
 finalCtx (Ctx ctx) = withForeignPtr ctx $ \ptr -> do
-    let s = c_evp_md_get_size (c_evp_md_ctx_get0_md ptr)
+    let s = fromIntegral $ c_evp_md_get_size (c_evp_md_ctx_get0_md (ConstPtr ptr))
     allocaBytes s $ \dptr -> do
         r <- c_evp_digest_final ptr dptr nullPtr
-        unless r $ throw $ OpenSslException "digest finalization failed"
-        Digest <$> BS.packCStringLen (dptr, s)
+        when (r == 0) $ throw $ OpenSslException "digest finalization failed"
+        Digest <$> BS.packCStringLen (castPtr dptr, s)
 {-# INLINE finalCtx #-}
 
 -- -------------------------------------------------------------------------- --
@@ -337,16 +369,16 @@
     deriving (Show, IsString) via B16ShortByteString
 
 foreign import ccall unsafe "openssl/evp.h EVP_DigestFinalXOF"
-    c_EVP_DigestFinalXOF :: Ptr ctx -> Ptr d -> Int -> IO Bool
+    c_EVP_DigestFinalXOF :: Ptr ctx -> Ptr CUChar -> CSize -> IO CInt
 
 -- | Finalize an XOF based hash and return the digest.
 --
 xof_finalCtx :: forall n a . KnownNat n => Ctx a -> IO (XOF_Digest n a)
 xof_finalCtx (Ctx ctx) = withForeignPtr ctx $ \ptr -> do
     allocaBytes s $ \dptr -> do
-        r <- c_EVP_DigestFinalXOF ptr dptr s
-        unless r $ throw $ OpenSslException "digest finalization failed"
-        XOF_Digest <$> BS.packCStringLen (dptr, s)
+        r <- c_EVP_DigestFinalXOF ptr dptr (fromIntegral s)
+        when (r == 0) $ throw $ OpenSslException "digest finalization failed"
+        XOF_Digest <$> BS.packCStringLen (castPtr dptr, s)
   where
     s = fromIntegral $ natVal' @n proxy#
 {-# INLINE xof_finalCtx #-}
@@ -368,23 +400,23 @@
     deriving (Show, IsString) via B16ShortByteString
 
 foreign import ccall unsafe "keccak.h keccak_EVP_DigestInit_ex"
-    c_keccak_EVP_DigestInit_ex :: Ptr ctx -> Ptr a -> IO Bool
+    c_keccak_EVP_DigestInit_ex :: Ptr ctx -> ConstPtr a -> IO CInt
 
 legacyKeccak_initCtx :: Algorithm a -> IO (Ctx a)
 legacyKeccak_initCtx (Algorithm alg) = do
     c@(Ctx ctx) <- newCtx
     r <- withForeignPtr ctx $ \ctxPtr ->
         withForeignPtr alg $ \algPtr ->
-            c_keccak_EVP_DigestInit_ex ctxPtr algPtr
-    unless r $ throw $ OpenSslException "digest initialization failed"
+            c_keccak_EVP_DigestInit_ex ctxPtr (ConstPtr algPtr)
+    when (r == 0) $ throw $ OpenSslException "digest initialization failed"
     return c
 {-# INLINE legacyKeccak_initCtx #-}
 
 legacyKeccak_resetCtx :: Ctx a -> IO ()
 legacyKeccak_resetCtx (Ctx ctx) = do
     r <- withForeignPtr ctx $ \ptr ->
-        c_keccak_EVP_DigestInit_ex ptr nullPtr
-    unless r $ throw $ OpenSslException "digest re-initialization failed"
+        c_keccak_EVP_DigestInit_ex ptr nullConstPtr
+    when (r == 0) $ throw $ OpenSslException "digest re-initialization failed"
 {-# INLINE legacyKeccak_resetCtx #-}
 
 instance OpenSslDigest a => Hash (LegacyKeccak_Digest a) where
@@ -641,8 +673,8 @@
 finalizeKeccak256Ptr :: Ctx Keccak256 -> Ptr Word8 -> IO ()
 finalizeKeccak256Ptr (Ctx ctx) dptr =
     withForeignPtr ctx $ \cptr -> do
-        r <- c_evp_digest_final cptr dptr nullPtr
-        unless r $ throw $ OpenSslException "digest finalization failed"
+        r <- c_evp_digest_final cptr (castPtr dptr) nullPtr
+        when (r == 0) $ throw $ OpenSslException "digest finalization failed"
 {-# INLINE finalizeKeccak256Ptr #-}
 
 -- | Low-Level function that writes the final digest directly into the provided
@@ -653,8 +685,8 @@
 finalizeKeccak512Ptr :: Ctx Keccak512 -> Ptr Word8 -> IO ()
 finalizeKeccak512Ptr (Ctx ctx) dptr = do
     withForeignPtr ctx $ \cptr -> do
-        r <- c_evp_digest_final cptr dptr nullPtr
-        unless r $ throw $ OpenSslException "digest finalization failed"
+        r <- c_evp_digest_final cptr (castPtr dptr) nullPtr
+        when (r == 0) $ throw $ OpenSslException "digest finalization failed"
 {-# INLINE finalizeKeccak512Ptr #-}
 
 -- -------------------------------------------------------------------------- --
diff --git a/test/Cryptonite.hs b/test/Cryptonite.hs
--- a/test/Cryptonite.hs
+++ b/test/Cryptonite.hs
@@ -34,8 +34,9 @@
 import qualified Data.ByteString as B
 import Data.Word
 
+import Test.Hspec
+import Test.Hspec.QuickCheck
 import Test.QuickCheck
-import Test.Syd
 
 -- internal modules
 
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -25,13 +25,13 @@
 import qualified Cryptonite
 #endif
 
-import Test.Syd
+import Test.Hspec
 
 main :: IO ()
-main = sydTest tests
+main = hspec tests
 
 tests :: Spec
-tests = do
+tests = parallel $ do
     describe "Test.Data.Hash.FNV1.tests" Test.Data.Hash.FNV1.tests
     describe "Test.Data.Hash.SipHash.tests" Test.Data.Hash.SipHash.tests
     describe "Test.Data.Hash.Class.Pure" Test.Data.Hash.Class.Pure.tests
diff --git a/test/Test/Data/Hash/Class/Pure.hs b/test/Test/Data/Hash/Class/Pure.hs
--- a/test/Test/Data/Hash/Class/Pure.hs
+++ b/test/Test/Data/Hash/Class/Pure.hs
@@ -32,8 +32,9 @@
 import GHC.IO
 import GHC.Word
 
+import Test.Hspec
+import Test.Hspec.QuickCheck
 import Test.QuickCheck
-import Test.Syd
 
 -- internal modules
 
diff --git a/test/Test/Data/Hash/FNV1.hs b/test/Test/Data/Hash/FNV1.hs
--- a/test/Test/Data/Hash/FNV1.hs
+++ b/test/Test/Data/Hash/FNV1.hs
@@ -24,7 +24,7 @@
 
 import System.IO.Unsafe
 
-import Test.Syd
+import Test.Hspec
 
 -- internal modules
 
diff --git a/test/Test/Data/Hash/Keccak.hs b/test/Test/Data/Hash/Keccak.hs
--- a/test/Test/Data/Hash/Keccak.hs
+++ b/test/Test/Data/Hash/Keccak.hs
@@ -22,8 +22,8 @@
 import Data.Coerce
 import Data.String
 
+import Test.Hspec
 import Test.QuickCheck
-import Test.Syd
 
 -- internal modules
 
@@ -97,7 +97,7 @@
     => Coercible a B16ShortByteString
     => B16ShortByteString
     -> a
-    -> TestDefM '[] () ()
+    -> Spec
 succeed a b = do
     it (show a) $ shouldBe (hashShortByteString_ @a $ coerce a) b
 
@@ -109,7 +109,7 @@
     => Coercible a B16ShortByteString
     => B16ShortByteString
     -> a
-    -> TestDefM '[] () ()
+    -> Spec
 failTest a b = do
     it (show a) $ shouldNotBe (hashShortByteString_ @a $ coerce a) b
 
diff --git a/test/Test/Data/Hash/SHA2.hs b/test/Test/Data/Hash/SHA2.hs
--- a/test/Test/Data/Hash/SHA2.hs
+++ b/test/Test/Data/Hash/SHA2.hs
@@ -26,7 +26,7 @@
 import qualified Data.ByteString.Short as BS
 import Data.Coerce
 
-import Test.Syd
+import Test.Hspec
 import Test.Hash.SHA
 
 -- internal modules
diff --git a/test/Test/Data/Hash/SHA3.hs b/test/Test/Data/Hash/SHA3.hs
--- a/test/Test/Data/Hash/SHA3.hs
+++ b/test/Test/Data/Hash/SHA3.hs
@@ -27,7 +27,7 @@
 import qualified Data.ByteString.Short as BS
 import Data.Coerce
 
-import Test.Syd
+import Test.Hspec
 import Test.Hash.SHA3
 
 -- internal modules
@@ -65,7 +65,7 @@
         => Coercible a B16ShortByteString
         => String
         -> a
-        -> TestDefM '[] () ()
+        -> Spec
     go l b = do
         it l $ shouldBe (hashShortByteString_ @a "") b
 
diff --git a/test/Test/Data/Hash/SipHash.hs b/test/Test/Data/Hash/SipHash.hs
--- a/test/Test/Data/Hash/SipHash.hs
+++ b/test/Test/Data/Hash/SipHash.hs
@@ -22,7 +22,7 @@
 
 import System.IO.Unsafe
 
-import Test.Syd
+import Test.Hspec
 
 -- internal modules
 
