cardano-crypto-class-2.1.1.0: Type classes abstracting over cryptography primitives for Cardano
Safe HaskellSafe-Inferred
LanguageHaskell2010

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

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) #

zeroMem :: Ptr a -> CSize -> m () #

copyMem :: Ptr a -> Ptr a -> CSize -> m () #

Instances

Instances details
MonadSodium IO # 
Instance details

Defined in Cardano.Crypto.MonadSodium.Class

Re-exported types

data MLockedForeignPtr a #

Foreign pointer to securely allocated memory.

data MLockedSizedBytes (n :: Nat) #

A block of raw memory of a known size, protected with mlock().

Instances

Instances details
(MonadSodium m, MonadST m, KnownNat n) => MEq m (MLockedSizedBytes n) # 
Instance details

Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal

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.

Instance details

Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal

NFData (MLockedSizedBytes n) # 
Instance details

Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal

Methods

rnf :: MLockedSizedBytes n -> () Source #

NoThunks (MLockedSizedBytes n) # 
Instance details

Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal

Monadic Eq and Ord

class MEq m a where #

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.

Methods

equalsM :: a -> a -> m Bool #

Instances

Instances details
(MonadST m, MonadSodium m) => MEq m (SignKeyDSIGNM Ed25519DSIGNM) # 
Instance details

Defined in Cardano.Crypto.DSIGN.Ed25519ML

(Monad m, MEq m (SignKeyDSIGNM d)) => MEq m (SignKeyKES (SimpleKES d t)) # 
Instance details

Defined in Cardano.Crypto.KES.Simple

Methods

equalsM :: SignKeyKES (SimpleKES d t) -> SignKeyKES (SimpleKES d t) -> m Bool #

(MonadSodium m, MonadST m, KnownNat n) => MEq m (MLockedSizedBytes n) # 
Instance details

Defined in Cardano.Crypto.Libsodium.MLockedBytes.Internal

(Applicative m, Eq a) => MEq m (PureMEq a) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: PureMEq a -> PureMEq a -> m Bool #

(MonadSodium m, MonadST m, KnownNat n) => MEq m (MLockedSeed n) # 
Instance details

Defined in Cardano.Crypto.MLockedSeed

Methods

equalsM :: MLockedSeed n -> MLockedSeed n -> m Bool #

(Applicative m, MEq m a) => MEq m (Maybe a) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: Maybe a -> Maybe a -> m Bool #

(Applicative m, MEq m a, MEq m b) => MEq m (Either a b) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: Either a b -> Either a b -> m Bool #

(Applicative m, MEq m a, MEq m b) => MEq m (a, b) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: (a, b) -> (a, b) -> m Bool #

(Applicative m, MEq m a, MEq m b, MEq m c) => MEq m (a, b, c) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: (a, b, c) -> (a, b, c) -> m Bool #

(Applicative m, MEq m a, MEq m b, MEq m c, MEq m d) => MEq m (a, b, c, d) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: (a, b, c, d) -> (a, b, c, d) -> m Bool #

nequalsM :: (Functor m, MEq m a) => a -> a -> m Bool #

(==!) :: MEq m a => a -> a -> m Bool infix 4 #

Infix version of equalsM

(!=!) :: (Functor m, MEq m a) => a -> a -> m Bool infix 4 #

Infix version of nequalsM

newtype PureMEq a #

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 

Instances

Instances details
(Applicative m, Eq a) => MEq m (PureMEq a) # 
Instance details

Defined in Cardano.Crypto.MEqOrd

Methods

equalsM :: PureMEq a -> PureMEq a -> m Bool #

Memory management

mlockedAllocaSized :: forall m n b. (MonadSodium m, MonadThrow m, KnownNat n) => (SizedPtr n -> m b) -> m b #

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.

Hashing

class HashAlgorithm h => SodiumHashAlgorithm h where #

Methods

naclDigestPtr #

Arguments

:: proxy h 
-> Ptr a

input

-> Int

input length

-> IO (MLockedSizedBytes (SizeHash h)) 

Instances

Instances details
SodiumHashAlgorithm Blake2b_256 # 
Instance details

Defined in Cardano.Crypto.Libsodium.Hash.Class

SodiumHashAlgorithm SHA256 # 
Instance details

Defined in Cardano.Crypto.Libsodium.Hash.Class

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)) #