packages feed

libsodium 1.0.18.0 → 1.0.18.1

raw patch · 4 files changed

+152/−13 lines, 4 files

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+# Version 1.0.18.1++* Improve support for opaque C structs (`Storable`, `Ptr`, allocation).++ # Version 1.0.18.0  * Initial version.
lib/Libsodium.chs view
@@ -1,10 +1,13 @@+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-}+{-# OPTIONS_GHC -Wno-missing-signatures #-}  #include <sodium.h> @@ -334,19 +337,39 @@     --     -- $types   , Crypto_aead_aes256gcm_state+  , crypto_aead_aes256gcm_state'ptr+  , crypto_aead_aes256gcm_state'malloc   , Crypto_auth_hmacsha256_state+  , crypto_auth_hmacsha256_state'ptr+  , crypto_auth_hmacsha256_state'malloc+  , Crypto_auth_hmacsha512256_state   , Crypto_auth_hmacsha512_state+  , crypto_auth_hmacsha512_state'ptr+  , crypto_auth_hmacsha512_state'malloc   , Crypto_generichash_blake2b_state+  , crypto_generichash_blake2b_state'ptr+  , crypto_generichash_blake2b_state'malloc+  , Crypto_generichash_state   , Crypto_hash_sha256_state+  , crypto_hash_sha256_state'ptr+  , crypto_hash_sha256_state'malloc   , Crypto_hash_sha512_state+  , crypto_hash_sha512_state'ptr+  , crypto_hash_sha512_state'malloc   , Crypto_onetimeauth_poly1305_state+  , crypto_onetimeauth_poly1305_state'ptr+  , crypto_onetimeauth_poly1305_state'malloc+  , Crypto_onetimeauth_state   , Crypto_secretstream_xchacha20poly1305_state+  , crypto_secretstream_xchacha20poly1305_state'ptr+  , crypto_secretstream_xchacha20poly1305_state'malloc   , Crypto_sign_ed25519ph_state-  , Crypto_auth_hmacsha512256_state-  , Crypto_generichash_state-  , Crypto_onetimeauth_state+  , crypto_sign_ed25519ph_state'ptr+  , crypto_sign_ed25519ph_state'malloc   , Crypto_sign_state   , Randombytes_implementation+  , randombytes_implementation'ptr+  , randombytes_implementation'malloc   -- * Constants   --   -- $constants@@ -354,9 +377,12 @@   ) --}   where +import Data.Coerce import Data.Proxy import Data.Word import Foreign.C+import Foreign.ForeignPtr+import Foreign.Marshal.Array (copyArray) import Foreign.Ptr import Foreign.Storable import GHC.TypeLits@@ -782,15 +808,33 @@ -------------------------------------------------------------------------------- -- $types ----- These are types used by some of the functions in--- "Libsodium". They are exported as opaque types.+-- These are types used by some of the functions in "Libsodium".+-- They are exported as opaque types having a particular size and+-- alignment described by their 'Storable' instance. ----- Use 'Storable' if you need to allocate values of these types.--newtype Crypto_aead_aes256gcm_state = Crypto_aead_aes256gcm_state-  (Opaque 16 {# sizeof crypto_aead_aes256gcm_state #})+-- Use the @/xxx/'malloc@ functions to allocate values of type @Xxx@. These+-- will be freed from memory as soon as they become unused.+--+-- Use the @/xxx/'ptr@ function to obtain a+-- @'Ptr' Xxx@ suitable for passing to functions.+newtype Crypto_aead_aes256gcm_state+  = Crypto_aead_aes256gcm_state+    (Opaque 16 {# sizeof crypto_aead_aes256gcm_state #})   deriving newtype (Storable) +crypto_aead_aes256gcm_state'malloc+  :: IO Crypto_aead_aes256gcm_state+crypto_aead_aes256gcm_state'malloc =+  fmap Crypto_aead_aes256gcm_state opaque'malloc++crypto_aead_aes256gcm_state'ptr+  :: Crypto_aead_aes256gcm_state+  -> (Ptr Crypto_aead_aes256gcm_state -> IO x)+  -> IO x+crypto_aead_aes256gcm_state'ptr = opaque'ptr+       @Crypto_aead_aes256gcm_state++--- type Crypto_sign_state = Crypto_sign_ed25519ph_state  newtype Crypto_sign_ed25519ph_state = Crypto_sign_ed25519ph_state@@ -798,34 +842,58 @@           {# sizeof crypto_sign_ed25519ph_state #})   deriving newtype (Storable) +crypto_sign_ed25519ph_state'ptr = opaque'ptr @Crypto_sign_ed25519ph_state+crypto_sign_ed25519ph_state'malloc = fmap Crypto_sign_ed25519ph_state opaque'malloc++--- newtype Crypto_secretstream_xchacha20poly1305_state   = Crypto_secretstream_xchacha20poly1305_state   (Opaque {# alignof crypto_secretstream_xchacha20poly1305_state #}           {# sizeof crypto_secretstream_xchacha20poly1305_state #})   deriving newtype (Storable) +crypto_secretstream_xchacha20poly1305_state'ptr = opaque'ptr @Crypto_secretstream_xchacha20poly1305_state+crypto_secretstream_xchacha20poly1305_state'malloc = fmap Crypto_secretstream_xchacha20poly1305_state opaque'malloc++--- type Crypto_onetimeauth_state = Crypto_onetimeauth_poly1305_state  newtype Crypto_onetimeauth_poly1305_state = Crypto_onetimeauth_poly1305_state   (Opaque 16 {# sizeof crypto_onetimeauth_poly1305_state #})   deriving newtype (Storable) +crypto_onetimeauth_poly1305_state'ptr = opaque'ptr @Crypto_onetimeauth_poly1305_state+crypto_onetimeauth_poly1305_state'malloc = fmap Crypto_onetimeauth_poly1305_state opaque'malloc++--- type Crypto_generichash_state = Crypto_generichash_blake2b_state  newtype Crypto_generichash_blake2b_state = Crypto_generichash_blake2b_state   (Opaque 64 {# sizeof crypto_generichash_blake2b_state #})   deriving newtype (Storable) +crypto_generichash_blake2b_state'ptr = opaque'ptr @Crypto_generichash_blake2b_state+crypto_generichash_blake2b_state'malloc = fmap Crypto_generichash_blake2b_state opaque'malloc++--- newtype Crypto_hash_sha256_state = Crypto_hash_sha256_state   (Opaque {# alignof crypto_hash_sha256_state #}           {# sizeof crypto_hash_sha256_state #})   deriving newtype (Storable) +crypto_hash_sha256_state'ptr = opaque'ptr @Crypto_hash_sha256_state+crypto_hash_sha256_state'malloc = fmap Crypto_hash_sha256_state opaque'malloc++--- newtype Crypto_hash_sha512_state = Crypto_hash_sha512_state   (Opaque {# alignof crypto_hash_sha512_state #}           {# sizeof crypto_hash_sha512_state #})   deriving newtype (Storable) +crypto_hash_sha512_state'ptr = opaque'ptr @Crypto_hash_sha512_state+crypto_hash_sha512_state'malloc = fmap Crypto_hash_sha512_state opaque'malloc++--- type Crypto_auth_hmacsha512256_state = Crypto_auth_hmacsha512_state  newtype Crypto_auth_hmacsha512_state = Crypto_auth_hmacsha512_state@@ -833,25 +901,54 @@           {# sizeof crypto_auth_hmacsha512_state #})   deriving newtype (Storable) +crypto_auth_hmacsha512_state'ptr = opaque'ptr @Crypto_auth_hmacsha512_state+crypto_auth_hmacsha512_state'malloc = fmap Crypto_auth_hmacsha512_state opaque'malloc++--- newtype Crypto_auth_hmacsha256_state = Crypto_auth_hmacsha256_state   (Opaque {# alignof crypto_auth_hmacsha256_state #}           {# sizeof crypto_auth_hmacsha256_state #})   deriving newtype (Storable) +crypto_auth_hmacsha256_state'ptr = opaque'ptr @Crypto_auth_hmacsha256_state+crypto_auth_hmacsha256_state'malloc = fmap Crypto_auth_hmacsha256_state opaque'malloc++--- newtype Randombytes_implementation = Randombytes_implementation   (Opaque {# alignof randombytes_implementation #}           {# sizeof randombytes_implementation #})   deriving newtype (Storable) +randombytes_implementation'ptr = opaque'ptr @Randombytes_implementation+randombytes_implementation'malloc = fmap Randombytes_implementation opaque'malloc+ -------------------------------------------------------------------------------- -newtype Opaque (alignment :: Nat) (size :: Nat) = Opaque (Ptr ())+newtype Opaque (alignment :: Nat) (size :: Nat)+  = Opaque (ForeignPtr (Opaque alignment size))  instance forall a s. (KnownNat a, KnownNat s) => Storable (Opaque a s) where   alignment _ = fromIntegral (natVal (Proxy :: Proxy a))   sizeOf _ = fromIntegral (natVal (Proxy :: Proxy s))-  peek z = Opaque <$> peek (castPtr z)-  poke z (Opaque a) = poke (castPtr z) a+  peek ps = do+    fpd <- mallocForeignPtr+    withForeignPtr fpd $ \pd -> copyArray pd ps 1+    pure $ Opaque fpd+  poke pd (Opaque fps) =+    withForeignPtr fps $ \ps -> copyArray pd ps 1++opaque'malloc :: (KnownNat a, KnownNat s) => IO (Opaque a s)+opaque'malloc = fmap Opaque mallocForeignPtr++opaque'ptr+  :: forall o a s x+  .  Coercible o (Opaque a s)+  => o+  -> (Ptr o -> IO x)+  -> IO x+opaque'ptr o g =+  let Opaque fp = coerce o :: Opaque a s+  in withForeignPtr fp (g . castPtr)  -------------------------------------------------------------------------------- -- $constants
libsodium.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: libsodium-version: 1.0.18.0+version: 1.0.18.1 license: ISC license-file: LICENSE extra-source-files: README.md CHANGELOG.md
test/Main.chs view
@@ -1,3 +1,5 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ScopedTypeVariables #-} #include <sodium.h>  module Main (main) where@@ -6,6 +8,8 @@ import Control.Monad.IO.Class import Foreign.C.String import Foreign.C.Types+import Foreign.ForeignPtr+import Foreign.Storable import qualified Test.Tasty as Tasty import qualified Test.Tasty.Runners as Tasty import Test.Tasty (TestTree, testGroup)@@ -68,6 +72,39 @@   [ tt_core   , tt_constants   , tt_randombytes+  , tt_storable+  ]++tt_storable :: TestTree+tt_storable = testGroup "Storable"+  [ testCase "alloc" $ do+      _ :: ForeignPtr L.Crypto_hash_sha256_state <- mallocForeignPtr+      pure ()++  , testCase "peek" $ do+      -- Allocate s1 and fill with random bytes+      s1 <- L.crypto_hash_sha256_state'malloc+      L.crypto_hash_sha256_state'ptr s1 $ \p1 -> do+        L.randombytes_buf p1 (fromIntegral (sizeOf s1))+        -- Allocate s2 by peeking from s1+        s2 <- peek p1+        L.crypto_hash_sha256_state'ptr s2 $ \p2 -> do+          -- Compare s1 and s2+          x <- L.sodium_memcmp p1 p2 (fromIntegral (sizeOf s1))+          0 @=? x++  , testCase "poke" $ do+      -- Allocate s1 and fill with random bytes+      s1 <- L.crypto_hash_sha256_state'malloc+      L.crypto_hash_sha256_state'ptr s1 $ \p1 -> do+        L.randombytes_buf p1 (fromIntegral (sizeOf s1))+        -- Allocate s2 and poke s1 into it+        s2 <- L.crypto_hash_sha256_state'malloc+        L.crypto_hash_sha256_state'ptr s2 $ \p2 -> do+          poke p2 s1+          -- Compare s1 and s2+          x <- L.sodium_memcmp p1 p2 (fromIntegral (sizeOf s1))+          0 @=? x   ]  tt_core :: TestTree