packages feed

ppad-hmac-drbg 0.3.1 → 0.3.2

raw patch · 5 files changed

+58/−11 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,6 +1,11 @@ # Changelog -- 0.3.1 (2026-02-01)+- 0.3.2 (2026-11-14)+  * 'new' and 'reseed' combine their seed material in a pinned buffer+    that is zeroed after use, rather than concatenating it into+    ordinary heap bytestrings that could outlive 'wipe'.++- 0.3.1 (2026-02-04)   * Adds SPECIALIZE pragmas for IO and ST to improve the generated Core.  - 0.3.0 (2026-02-01)
lib/Crypto/DRBG/HMAC/Internal.hs view
@@ -1,4 +1,5 @@ {-# OPTIONS_HADDOCK hide #-}+{-# LANGUAGE BangPatterns #-}  -- | -- Module: Crypto.DRBG.HMAC.Internal@@ -12,9 +13,18 @@     Error(..)   , _RESEED_COUNTER   , _MAX_BYTES+  , _with_concat   ) where -import Data.Word (Word64)+import Control.Monad.Primitive (PrimMonad)+import qualified Control.Monad.Primitive as Prim (unsafeIOToPrim)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BI+import qualified Data.ByteString.Unsafe as BU+import Data.Word (Word8, Word64)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Marshal.Utils (copyBytes, fillBytes)+import Foreign.Ptr (Ptr, castPtr, plusPtr)  -- | A DRBG error. data Error =@@ -31,3 +41,29 @@ _MAX_BYTES :: Word64 _MAX_BYTES = 0x10000 {-# INLINE _MAX_BYTES #-}++-- | Run an action on the concatenation of the given strings, held in a+--   pinned buffer that is zeroed once the action completes, so that+--   (secret) seed material leaves no copy of the library's making+--   behind. The action must not retain its argument.+_with_concat+  :: PrimMonad m+  => [BS.ByteString]+  -> (BS.ByteString -> m a)+  -> m a+_with_concat bss act = do+  let !n = sum (fmap BS.length bss)+  fp <- Prim.unsafeIOToPrim $ do+    fp <- BI.mallocByteString n+    withForeignPtr fp $ \dst -> copy_all dst bss+    pure fp+  !r <- act (BI.BS fp n)+  Prim.unsafeIOToPrim $ withForeignPtr fp $ \p -> fillBytes p 0 n+  pure r+  where+    copy_all :: Ptr Word8 -> [BS.ByteString] -> IO ()+    copy_all _ [] = pure ()+    copy_all dst (b@(BI.PS _ _ l) : bs) = do+      BU.unsafeUseAsCString b $ \src -> copyBytes dst (castPtr src) l+      copy_all (dst `plusPtr` l) bs+{-# INLINE _with_concat #-}
lib/Crypto/DRBG/HMAC/SHA256.hs view
@@ -29,7 +29,8 @@   , _read_k   ) where -import Crypto.DRBG.HMAC.Internal (Error(..), _RESEED_COUNTER, _MAX_BYTES)+import Crypto.DRBG.HMAC.Internal+  (Error(..), _RESEED_COUNTER, _MAX_BYTES, _with_concat) import qualified Crypto.Hash.SHA256 as SHA256 import Crypto.Hash.SHA256.Internal (Registers(..)) import qualified Crypto.Hash.SHA256.Internal as SHA256 (cat)@@ -87,7 +88,7 @@   PA.setPrimArray drbg 02 08 (0x00000000 :: Word32) -- init k   PA.setPrimArray drbg 10 08 (0x01010101 :: Word32) -- init v   PA.setPrimArray drbg 18 16 (0x00000000 :: Word32) -- scratch-  update drbg (entropy <> nonce <> ps)+  _with_concat [entropy, nonce, ps] (update drbg)   pure $! DRBG drbg {-# INLINABLE new #-} {-# SPECIALIZE new@@ -118,7 +119,7 @@   -> BS.ByteString   -> m () reseed (DRBG drbg) entr addl = do-  update drbg (entr <> addl)+  _with_concat [entr, addl] (update drbg)   init_counter drbg {-# INLINE reseed #-} @@ -184,7 +185,9 @@ -- | Wipe the state of a DRBG. -- --   You should call this when you're finished with a DRBG to ensure that its---   state is wiped from memory.+--   state is wiped from memory. A wiped DRBG must not be used afterwards:+--   its state is reset to the publicly known initial one, so it would+--   produce predictable output. -- --   >>> drbg <- new mempty mempty mempty --   >>> Right bytes <- gen drbg addl_bytes 16
lib/Crypto/DRBG/HMAC/SHA512.hs view
@@ -29,7 +29,8 @@   , _read_k   ) where -import Crypto.DRBG.HMAC.Internal (Error(..), _RESEED_COUNTER, _MAX_BYTES)+import Crypto.DRBG.HMAC.Internal+  (Error(..), _RESEED_COUNTER, _MAX_BYTES, _with_concat) import qualified Crypto.Hash.SHA512 as SHA512 import Crypto.Hash.SHA512.Internal (Registers(..)) import qualified Crypto.Hash.SHA512.Internal as SHA512 (cat)@@ -87,7 +88,7 @@   PA.setPrimArray drbg 01 08 (0x0000000000000000 :: Word64) -- init k   PA.setPrimArray drbg 09 08 (0x0101010101010101 :: Word64) -- init v   PA.setPrimArray drbg 17 16 (0x0000000000000000 :: Word64) -- scratch-  update drbg (entropy <> nonce <> ps)+  _with_concat [entropy, nonce, ps] (update drbg)   pure $! DRBG drbg {-# INLINABLE new #-} {-# SPECIALIZE new@@ -118,7 +119,7 @@   -> BS.ByteString   -> m () reseed (DRBG drbg) entr addl = do-  update drbg (entr <> addl)+  _with_concat [entr, addl] (update drbg)   init_counter drbg {-# INLINE reseed #-} @@ -184,7 +185,9 @@ -- | Wipe the state of a DRBG. -- --   You should call this when you're finished with a DRBG to ensure that its---   state is wiped from memory.+--   state is wiped from memory. A wiped DRBG must not be used afterwards:+--   its state is reset to the publicly known initial one, so it would+--   produce predictable output. -- --   >>> drbg <- new mempty mempty mempty --   >>> Right bytes <- gen drbg addl_bytes 16
ppad-hmac-drbg.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               ppad-hmac-drbg-version:            0.3.1+version:            0.3.2 synopsis:           HMAC-based deterministic random bit generator license:            MIT license-file:       LICENSE