| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Cardano.Crypto.MonadSodium
Description
The Libsodium API generalized to fit arbitrary-ish Monads.
The purpose of this module is to provide a drop-in replacement for the plain
Libsodium module, but such that the Monad in which some
essential actions run can be mocked, rather than forcing it to be IO.
It may also be used to provide Libsodium functionality in monad stacks that have IO at the bottom, but decorate certain Libsodium operations with additional effects, e.g. logging mlocked memory access.
Synopsis
- class Monad m => MonadSodium m where
- withMLockedForeignPtr :: forall a b. MLockedForeignPtr a -> (Ptr a -> m b) -> m b
- finalizeMLockedForeignPtr :: forall a. MLockedForeignPtr a -> m ()
- traceMLockedForeignPtr :: (Storable a, Show a) => MLockedForeignPtr a -> m ()
- mlockedMalloc :: CSize -> m (MLockedForeignPtr a)
- zeroMem :: Ptr a -> CSize -> m ()
- copyMem :: Ptr a -> Ptr a -> CSize -> m ()
- data MLockedForeignPtr a
- data MLockedSizedBytes (n :: Nat)
- class MEq m a where
- nequalsM :: (Functor m, MEq m a) => a -> a -> m Bool
- (==!) :: MEq m a => a -> a -> m Bool
- (!=!) :: (Functor m, MEq m a) => a -> a -> m Bool
- newtype PureMEq a = PureMEq a
- mlockedAllocaSized :: forall m n b. (MonadSodium m, MonadThrow m, KnownNat n) => (SizedPtr n -> m b) -> m b
- mlockedAllocForeignPtr :: forall a m. (MonadSodium m, Storable a) => m (MLockedForeignPtr a)
- mlockedAllocForeignPtrBytes :: MonadSodium m => CSize -> CSize -> m (MLockedForeignPtr a)
- mlsbNew :: forall n m. (KnownNat n, MonadSodium m) => m (MLockedSizedBytes n)
- mlsbZero :: forall n m. (KnownNat n, MonadSodium m) => MLockedSizedBytes n -> m ()
- mlsbNewZero :: forall n m. (KnownNat n, MonadSodium m) => m (MLockedSizedBytes n)
- mlsbCopy :: forall n m. (KnownNat n, MonadSodium m) => MLockedSizedBytes n -> m (MLockedSizedBytes n)
- mlsbFinalize :: MonadSodium m => MLockedSizedBytes n -> m ()
- mlsbToByteString :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => MLockedSizedBytes n -> m ByteString
- mlsbAsByteString :: forall n. KnownNat n => MLockedSizedBytes n -> ByteString
- mlsbFromByteString :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => ByteString -> m (MLockedSizedBytes n)
- mlsbFromByteStringCheck :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => ByteString -> m (Maybe (MLockedSizedBytes n))
- mlsbUseAsSizedPtr :: forall n r m. MonadSodium m => MLockedSizedBytes n -> (SizedPtr n -> m r) -> m r
- mlsbUseAsCPtr :: MonadSodium m => MLockedSizedBytes n -> (Ptr Word8 -> m r) -> m r
- mlsbCompare :: forall n m. (MonadSodium m, MonadST m, KnownNat n) => MLockedSizedBytes n -> MLockedSizedBytes n -> m Ordering
- mlsbEq :: forall n m. (MonadSodium m, MonadST m, KnownNat n) => MLockedSizedBytes n -> MLockedSizedBytes n -> m Bool
- class HashAlgorithm h => SodiumHashAlgorithm h where
- naclDigestPtr :: proxy h -> Ptr a -> Int -> IO (MLockedSizedBytes (SizeHash h))
- expandHash :: forall h m proxy. (SodiumHashAlgorithm h, MonadSodium m, MonadST m, MonadThrow m) => proxy h -> MLockedSizedBytes (SizeHash h) -> m (MLockedSizedBytes (SizeHash h), MLockedSizedBytes (SizeHash h))
- digestMLockedStorable :: forall h a proxy. (SodiumHashAlgorithm h, Storable a) => proxy h -> Ptr a -> IO (MLockedSizedBytes (SizeHash h))
- digestMLockedBS :: forall h proxy. SodiumHashAlgorithm h => proxy h -> ByteString -> IO (MLockedSizedBytes (SizeHash h))
MonadSodium class
class Monad m => MonadSodium m where #
Primitive operations on unmanaged mlocked memory.
These are all implemented in IO underneath, but should morally be in ST.
There are two use cases for this:
- Running mlocked-memory operations in a mocking context (e.g. IOSim) for
testing purposes.
- Running mlocked-memory operations directly on some monad stack with IO
at the bottom.
Methods
withMLockedForeignPtr :: forall a b. MLockedForeignPtr a -> (Ptr a -> m b) -> m b #
finalizeMLockedForeignPtr :: forall a. MLockedForeignPtr a -> m () #
traceMLockedForeignPtr :: (Storable a, Show a) => MLockedForeignPtr a -> m () #
Deprecated: Do not use traceMLockedForeignPtr in production
mlockedMalloc :: CSize -> m (MLockedForeignPtr a) #
Instances
| MonadSodium IO # | |
Defined in Cardano.Crypto.MonadSodium.Class Methods withMLockedForeignPtr :: MLockedForeignPtr a -> (Ptr a -> IO b) -> IO b # finalizeMLockedForeignPtr :: MLockedForeignPtr a -> IO () # traceMLockedForeignPtr :: (Storable a, Show a) => MLockedForeignPtr a -> IO () # mlockedMalloc :: CSize -> IO (MLockedForeignPtr a) # | |
Re-exported types
data MLockedForeignPtr a #
Foreign pointer to securely allocated memory.
Instances
| NFData (MLockedForeignPtr a) # | |
Defined in Cardano.Crypto.Libsodium.Memory.Internal Methods rnf :: MLockedForeignPtr a -> () Source # | |
| NoThunks (MLockedForeignPtr a) # | |
Defined in Cardano.Crypto.Libsodium.Memory.Internal | |
data MLockedSizedBytes (n :: Nat) #
A block of raw memory of a known size, protected with mlock().
Instances
| (MonadSodium m, MonadST m, KnownNat n) => MEq m (MLockedSizedBytes n) # | |
Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal Methods equalsM :: MLockedSizedBytes n -> MLockedSizedBytes n -> m Bool # | |
| KnownNat n => Show (MLockedSizedBytes n) # | This instance is unsafe, it will leak secrets from mlocked memory to the Haskell heap. Do not use outside of testing. |
| NFData (MLockedSizedBytes n) # | |
Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal Methods rnf :: MLockedSizedBytes n -> () Source # | |
| NoThunks (MLockedSizedBytes n) # | |
Monadic Eq and Ord
Monadic flavor of Eq, for things that can only be compared in a monadic
context.
This is needed because we cannot have a sound Eq instance on mlocked
memory types.
Instances
Helper newtype, useful for defining MEq in terms of Eq for types that
have sound Eq instances, using DerivingVia. An Applicative context
must be provided for such instances to work, so this will generally require
StandaloneDeriving as well.
Ex.: deriving via PureEq Int instance Applicative m => MEq m Int
Constructors
| PureMEq a |
Memory management
mlockedAllocaSized :: forall m n b. (MonadSodium m, MonadThrow m, KnownNat n) => (SizedPtr n -> m b) -> m b #
mlockedAllocForeignPtr :: forall a m. (MonadSodium m, Storable a) => m (MLockedForeignPtr a) #
mlockedAllocForeignPtrBytes :: MonadSodium m => CSize -> CSize -> m (MLockedForeignPtr a) #
MLockedSizedBytes operations
mlsbNew :: forall n m. (KnownNat n, MonadSodium m) => m (MLockedSizedBytes n) #
Allocate a new MLockedSizedBytes. The caller is responsible for
deallocating it (mlsbFinalize) when done with it. The contents of the
memory block is undefined.
mlsbZero :: forall n m. (KnownNat n, MonadSodium m) => MLockedSizedBytes n -> m () #
Overwrite an existing MLockedSizedBytes with zeroes.
mlsbNewZero :: forall n m. (KnownNat n, MonadSodium m) => m (MLockedSizedBytes n) #
Allocate a new MLockedSizedBytes, and pre-fill it with zeroes.
The caller is responsible for deallocating it (mlsbFinalize) when done
with it. (See also mlsbNew).
mlsbCopy :: forall n m. (KnownNat n, MonadSodium m) => MLockedSizedBytes n -> m (MLockedSizedBytes n) #
Create a deep mlocked copy of an MLockedSizedBytes.
mlsbFinalize :: MonadSodium m => MLockedSizedBytes n -> m () #
Calls finalizeMLockedForeignPtr on underlying pointer.
This function invalidates argument.
mlsbToByteString :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => MLockedSizedBytes n -> m ByteString #
Note: this function will leak mlocked memory to the Haskell heap and should not be used in production code.
mlsbAsByteString :: forall n. KnownNat n => MLockedSizedBytes n -> ByteString #
Note: the resulting ByteString will still refer to secure memory,
but the types don't prevent it from be exposed. Note further that any
subsequent operations (splicing & dicing, copying, conversion,
packing/unpacking, etc.) on the resulting ByteString may create copies
of the mlocked memory on the unprotected GHC heap, and thus leak secrets,
so use this function with extreme care.
mlsbFromByteString :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => ByteString -> m (MLockedSizedBytes n) #
Allocate a new MLockedSizedBytes, and fill it with the contents of a
ByteString. The size of the input is not checked.
Note: since the input ByteString is a plain old Haskell value, it has
already violated the secure-forgetting properties afforded by
MLockedSizedBytes, so this function is useless outside of testing. Use
mlsbNew or mlsbNewZero to create MLockedSizedBytes values, and
manipulate them through withMLSB, mlsbUseAsCPtr, or mlsbUseAsSizedPtr.
(See also mlsbFromByteStringCheck)
mlsbFromByteStringCheck :: forall n m. (KnownNat n, MonadSodium m, MonadST m) => ByteString -> m (Maybe (MLockedSizedBytes n)) #
Allocate a new MLockedSizedBytes, and fill it with the contents of a
ByteString. The size of the input is checked.
Note: since the input ByteString is a plain old Haskell value, it has
already violated the secure-forgetting properties afforded by
MLockedSizedBytes, so this function is useless outside of testing. Use
mlsbNew or mlsbNewZero to create MLockedSizedBytes values, and
manipulate them through withMLSB, mlsbUseAsCPtr, or mlsbUseAsSizedPtr.
(See also mlsbFromByteString)
mlsbUseAsSizedPtr :: forall n r m. MonadSodium m => MLockedSizedBytes n -> (SizedPtr n -> m r) -> m r #
Use an MLockedSizedBytes value as a SizedPtr of the same size. Care
should be taken to never copy the contents of the MLockedSizedBytes value
into managed memory through the sized pointer, because that would violate
the secure-forgetting property of mlocked memory.
mlsbUseAsCPtr :: MonadSodium m => MLockedSizedBytes n -> (Ptr Word8 -> m r) -> m r #
Use an MLockedSizedBytes value as a raw C pointer. Care should be taken
to never copy the contents of the MLockedSizedBytes value into managed
memory through the raw pointer, because that would violate the
secure-forgetting property of mlocked memory.
mlsbCompare :: forall n m. (MonadSodium m, MonadST m, KnownNat n) => MLockedSizedBytes n -> MLockedSizedBytes n -> m Ordering #
compareM on MLockedSizedBytes
mlsbEq :: forall n m. (MonadSodium m, MonadST m, KnownNat n) => MLockedSizedBytes n -> MLockedSizedBytes n -> m Bool #
Hashing
class HashAlgorithm h => SodiumHashAlgorithm h where #
Methods
Arguments
| :: proxy h | |
| -> Ptr a | input |
| -> Int | input length |
| -> IO (MLockedSizedBytes (SizeHash h)) |
Instances
| SodiumHashAlgorithm Blake2b_256 # | |
Defined in Cardano.Crypto.Libsodium.Hash.Class Methods naclDigestPtr :: proxy Blake2b_256 -> Ptr a -> Int -> IO (MLockedSizedBytes (SizeHash Blake2b_256)) # | |
| SodiumHashAlgorithm SHA256 # | |
Defined in Cardano.Crypto.Libsodium.Hash.Class Methods naclDigestPtr :: proxy SHA256 -> Ptr a -> Int -> IO (MLockedSizedBytes (SizeHash SHA256)) # | |
expandHash :: forall h m proxy. (SodiumHashAlgorithm h, MonadSodium m, MonadST m, MonadThrow m) => proxy h -> MLockedSizedBytes (SizeHash h) -> m (MLockedSizedBytes (SizeHash h), MLockedSizedBytes (SizeHash h)) #
digestMLockedStorable :: forall h a proxy. (SodiumHashAlgorithm h, Storable a) => proxy h -> Ptr a -> IO (MLockedSizedBytes (SizeHash h)) #
digestMLockedBS :: forall h proxy. SodiumHashAlgorithm h => proxy h -> ByteString -> IO (MLockedSizedBytes (SizeHash h)) #