Safe Haskell | None |
---|---|
Language | Haskell98 |
This module exposes some core types used through out the Raaz library. One of the major goals of the raaz cryptographic library use the type safety of Haskell to catch some common bugs at compile time. As of now we address three kinds of errors
- Timing safe equality:
- We need a consistent way to build timing
safe equality comparisons. The type class
Equality
plays the role ofEq
for us. The comparison result is of typeResult
and notBool
so as to avoid timing attacks due to short-circuting of the AND-operation. Instance for basic word types are given here and users are expected to build theEquality
instances of compound types by combine the results of comparisons using the monoid instance ofResult
. We also give timing safe equality comparisons forVector
types using theeqVector
andoftenCorrectEqVector
functions. Once an instance forEquality
is defined for a cryptographically sensitive data type, we define theEq
for it indirectly using theEquality
instance and the operation===
. - Endianness aware types:
- When serialising data, we need to be
careful about the endianness of the machine. Instance of the
EndianStore
type class correctly stores and loads data from memory, irrespective of the endianness of the machine. We define endian aware variants ofWord32
andWord64
here and expect other cryptographic types to use such endian explicit types in their definition. - Pointer and Length units:
- We have the generic pointer type
Pointer
and distinguish between different length units at the type level. This helps in to avoid a lot of length conversion errors.
- class Equality a where
- (===) :: Equality a => a -> a -> Bool
- data Result
- isSuccessful :: Result -> Bool
- oftenCorrectEqVector :: (Vector v a, Equality a, Vector v Result) => v a -> v a -> Bool
- eqVector :: (Vector v a, Equality a, Vector v Result) => v a -> v a -> Bool
- class Storable w => EndianStore w where
- data LE w
- data BE w
- littleEndian :: w -> LE w
- bigEndian :: w -> BE w
- storeAt :: (EndianStore w, LengthUnit offset) => Pointer -> offset -> w -> IO ()
- storeAtIndex :: EndianStore w => Pointer -> Int -> w -> IO ()
- loadFrom :: (EndianStore w, LengthUnit offset) => Pointer -> offset -> IO w
- loadFromIndex :: EndianStore w => Pointer -> Int -> IO w
- type Pointer = Ptr Align
- class (Num u, Enum u) => LengthUnit u where
- movePtr :: LengthUnit u => Pointer -> u -> Pointer
- newtype BYTES a = BYTES a
- newtype BITS a = BITS a
- data ALIGN
- data Align
- inBits :: LengthUnit u => u -> BITS Word64
- bitsQuotRem :: LengthUnit u => BITS Word64 -> (u, BITS Word64)
- bytesQuotRem :: LengthUnit u => BYTES Int -> (u, BYTES Int)
- bitsQuot :: LengthUnit u => BITS Word64 -> u
- bytesQuot :: LengthUnit u => BYTES Int -> u
- atLeast :: (LengthUnit src, LengthUnit dest) => src -> dest
- atMost :: (LengthUnit src, LengthUnit dest) => src -> dest
- allocaBuffer :: LengthUnit l => l -> (Pointer -> IO b) -> IO b
- allocaSecure :: LengthUnit l => l -> (Pointer -> IO a) -> IO a
- mallocBuffer :: LengthUnit l => l -> IO Pointer
- hFillBuf :: LengthUnit bufSize => Handle -> Pointer -> bufSize -> IO (BYTES Int)
- byteSize :: Storable a => a -> BYTES Int
- memset :: LengthUnit l => Pointer -> Word8 -> l -> IO ()
- memmove :: LengthUnit l => Pointer -> Pointer -> l -> IO ()
- memcpy :: LengthUnit l => Pointer -> Pointer -> l -> IO ()
- data Tuple dim a
- dimension :: (Unbox a, KnownNat dim) => Tuple dim a -> Int
- initial :: (Unbox a, KnownNat dim0, KnownNat dim1) => Tuple dim1 a -> Tuple dim0 a
- unsafeFromList :: (Unbox a, KnownNat dim) => [a] -> Tuple dim a
- class Describable d where
Timing safe equality checking.
class Equality a where Source #
In a cryptographic setting, naive equality checking dangerous. This class is the timing safe way of doing equality checking. The recommended method of defining equality checking for cryptographically sensitive data is as follows.
data SomeSensitiveType = ... instance Equality SomeSensitiveType where eq a b = ... instance Eq SomeSensitiveType where (==) a b = a === b
Equality Word Source # | |
Equality Word8 Source # | |
Equality Word16 Source # | |
Equality Word32 Source # | |
Equality Word64 Source # | |
Equality SHA1 Source # | |
Equality SHA224 Source # | |
Equality SHA256 Source # | |
Equality SHA384 Source # | |
Equality SHA512 Source # | |
Equality a => Equality (BITS a) Source # | |
Equality a => Equality (BYTES a) Source # | |
Equality w => Equality (BE w) Source # | |
Equality w => Equality (LE w) Source # | |
(Unbox a, Equality a) => Equality (Tuple dim a) Source # | |
The result of comparion.
An opaque type that captures the result of a comparison. The monoid instances allows us to combine the results of two equality comparisons in a timing independent manner. We have the following properties.
isSuccessful mempty = True isSuccessful (r `mappend` s) = isSuccessful r && isSuccessful s
isSuccessful :: Result -> Bool Source #
Checks whether a given equality comparison is successful.
Comparing vectors.
oftenCorrectEqVector :: (Vector v a, Equality a, Vector v Result) => v a -> v a -> Bool Source #
Timing independent equality checks for vector of values. Do not
use this to check the equality of two general vectors in a timing
independent manner (use eqVector
instead) because:
- They do not work for vectors of unequal lengths,
- They do not work for empty vectors.
The use case is for defining equality of data types which have fixed size vector quantities in it. Like for example
import Data.Vector.Unboxed newtype Sha1 = Sha1 (Vector (BE Word32)) instance Eq Sha1 where (==) (Sha1 g) (Sha1 h) = oftenCorrectEqVector g h
eqVector :: (Vector v a, Equality a, Vector v Result) => v a -> v a -> Bool Source #
Timing independent equality checks for vectors. If you know that
the vectors are not empty and of equal length, you may use the
slightly faster oftenCorrectEqVector
Endianess aware types.
class Storable w => EndianStore w where Source #
This class is the starting point of an endian agnostic interface
to basic cryptographic data types. Endianness only matters when we
first load the data from the buffer or when we finally write the
data out. Any multi-byte type that are meant to be serialised
should define and instance of this class. The load
and store
should takes care of the appropriate endian conversion.
store :: Pointer -> w -> IO () Source #
Store the given value at the locating pointed by the pointer
load :: Pointer -> IO w Source #
Load the value from the location pointed by the pointer.
EndianStore Word8 Source # | |
EndianStore SHA1 Source # | |
EndianStore SHA224 Source # | |
EndianStore SHA256 Source # | |
EndianStore SHA384 Source # | |
EndianStore SHA512 Source # | |
EndianStore IV Source # | |
EndianStore KEY256 Source # | |
EndianStore KEY192 Source # | |
EndianStore KEY128 Source # | |
EndianStore (BE Word32) Source # | |
EndianStore (BE Word64) Source # | |
EndianStore (LE Word32) Source # | |
EndianStore (LE Word64) Source # | |
EndianStore h => EndianStore (HMAC h) Source # | |
(Unbox a, EndianStore a, KnownNat dim) => EndianStore (Tuple dim a) Source # | |
Endian explicit word types.
Little endian version of the word type w
Unbox w => Vector Vector (LE w) Source # | |
Unbox w => MVector MVector (LE w) Source # | |
Bounded w => Bounded (LE w) Source # | |
Enum w => Enum (LE w) Source # | |
Eq w => Eq (LE w) Source # | |
Integral w => Integral (LE w) Source # | |
Num w => Num (LE w) Source # | |
Ord w => Ord (LE w) Source # | |
Read w => Read (LE w) Source # | |
Real w => Real (LE w) Source # | |
Show w => Show (LE w) Source # | |
Storable w => Storable (LE w) Source # | |
Bits w => Bits (LE w) Source # | |
NFData w => NFData (LE w) Source # | |
Unbox w => Unbox (LE w) Source # | |
Equality w => Equality (LE w) Source # | |
EndianStore (LE Word32) Source # | |
EndianStore (LE Word64) Source # | |
Encodable (LE Word32) Source # | |
Encodable (LE Word64) Source # | |
Random w => Random (LE w) Source # | |
data MVector s (LE w) Source # | |
data Vector (LE w) Source # | |
Big endian version of the word type w
Unbox w => Vector Vector (BE w) Source # | |
Unbox w => MVector MVector (BE w) Source # | |
Bounded w => Bounded (BE w) Source # | |
Enum w => Enum (BE w) Source # | |
Eq w => Eq (BE w) Source # | |
Integral w => Integral (BE w) Source # | |
Num w => Num (BE w) Source # | |
Ord w => Ord (BE w) Source # | |
Read w => Read (BE w) Source # | |
Real w => Real (BE w) Source # | |
Show w => Show (BE w) Source # | |
Storable w => Storable (BE w) Source # | |
Bits w => Bits (BE w) Source # | |
NFData w => NFData (BE w) Source # | |
Unbox w => Unbox (BE w) Source # | |
Equality w => Equality (BE w) Source # | |
EndianStore (BE Word32) Source # | |
EndianStore (BE Word64) Source # | |
Encodable (BE Word32) Source # | |
Encodable (BE Word64) Source # | |
Random w => Random (BE w) Source # | |
data MVector s (BE w) Source # | |
data Vector (BE w) Source # | |
littleEndian :: w -> LE w Source #
Convert to the little endian variant.
Helper functions for endian aware storing and loading.
:: (EndianStore w, LengthUnit offset) | |
=> Pointer | the pointer |
-> offset | the absolute offset in type safe length units. |
-> w | value to store |
-> IO () |
Store the given value at an offset from the crypto pointer. The offset is given in type safe units.
:: EndianStore w | |
=> Pointer | the pointer to the first element of the array |
-> Int | the index of the array |
-> w | the value to store |
-> IO () |
Store the given value as the n
-th element of the array
pointed by the crypto pointer.
:: (EndianStore w, LengthUnit offset) | |
=> Pointer | the pointer |
-> offset | the offset |
-> IO w |
Load from a given offset. The offset is given in type safe units.
:: EndianStore w | |
=> Pointer | the pointer to the first element of the array |
-> Int | the index of the array |
-> IO w |
Load the n
-th value of an array pointed by the crypto pointer.
The pointer type and Length offsets.
The pointer type.
Type safe length units.
class (Num u, Enum u) => LengthUnit u where Source #
In cryptographic settings, we need to measure pointer offsets and buffer sizes in different units. To avoid errors due to unit conversions, we distinguish between different length units at the type level. This type class capturing such types, i.e. types that stand of length units.
LengthUnit ALIGN Source # | |
LengthUnit (BYTES Int) Source # | |
Primitive p => LengthUnit (BLOCKS p) Source # | |
Type safe lengths/offsets in units of bytes.
BYTES a |
IsString Write # | |
Encodable Write Source # | |
Enum a => Enum (BYTES a) Source # | |
Eq a => Eq (BYTES a) Source # | |
Integral a => Integral (BYTES a) Source # | |
Num a => Num (BYTES a) Source # | |
Ord a => Ord (BYTES a) Source # | |
Real a => Real (BYTES a) Source # | |
Show a => Show (BYTES a) Source # | |
Storable a => Storable (BYTES a) Source # | |
Equality a => Equality (BYTES a) Source # | |
LengthUnit (BYTES Int) Source # | |
Encodable a => Encodable (BYTES a) Source # | |
Type safe lengths/offsets in units of bits.
BITS a |
Enum a => Enum (BITS a) Source # | |
Eq a => Eq (BITS a) Source # | |
Integral a => Integral (BITS a) Source # | |
Num a => Num (BITS a) Source # | |
Ord a => Ord (BITS a) Source # | |
Real a => Real (BITS a) Source # | |
Show a => Show (BITS a) Source # | |
Storable a => Storable (BITS a) Source # | |
Equality a => Equality (BITS a) Source # | |
Encodable a => Encodable (BITS a) Source # | |
A type whose only purpose in this universe is to provide alignment safe pointers.
Some length arithmetic
bitsQuotRem :: LengthUnit u => BITS Word64 -> (u, BITS Word64) Source #
Function similar to bytesQuotRem
but works with bits instead.
bytesQuotRem :: LengthUnit u => BYTES Int -> (u, BYTES Int) Source #
A length unit u
is usually a multiple of bytes. The function
bytesQuotRem
is like quotRem
: the value byteQuotRem bytes
is
a tuple (x,r)
, where x
is bytes
expressed in the unit u
with r
being the reminder.
bitsQuot :: LengthUnit u => BITS Word64 -> u Source #
Function similar to bitsQuotRem
but returns only the quotient.
bytesQuot :: LengthUnit u => BYTES Int -> u Source #
Function similar to bytesQuotRem
but returns only the quotient.
atLeast :: (LengthUnit src, LengthUnit dest) => src -> dest Source #
Express length unit src
in terms of length unit dest
rounding
upwards.
atMost :: (LengthUnit src, LengthUnit dest) => src -> dest Source #
Express length unit src
in terms of length unit dest
rounding
downwards.
Helper function that uses generalised length units.
:: LengthUnit l | |
=> l | buffer length |
-> (Pointer -> IO b) | the action to run |
-> IO b |
The expression allocaBuffer l action
allocates a local buffer
of length l
and passes it on to the IO action action
. No
explicit freeing of the memory is required as the memory is
allocated locally and freed once the action finishes. It is better
to use this function than
as it does type safe
scaling. This function also ensure that the allocated buffer is
word aligned.allocaBytes
allocaSecure :: LengthUnit l => l -> (Pointer -> IO a) -> IO a Source #
This function allocates a chunk of "secure" memory of a given
size and runs the action. The memory (1) exists for the duration of
the action (2) will not be swapped during that time and (3) will be
wiped clean and deallocated when the action terminates either
directly or indirectly via errors. While this is mostly secure,
there can be strange situations in multi-threaded application where
the memory is not wiped out. For example if you run a
crypto-sensitive action inside a child thread and the main thread
gets exists, then the child thread is killed (due to the demonic
nature of haskell threads) immediately and might not give it chance
to wipe the memory clean. This is a problem inherent to how the
bracket
combinator works inside a child thread.
TODO: File this insecurity in the wiki.
:: LengthUnit l | |
=> l | buffer length |
-> IO Pointer |
Creates a memory of given size. It is better to use over
as it uses typesafe length.mallocBytes
hFillBuf :: LengthUnit bufSize => Handle -> Pointer -> bufSize -> IO (BYTES Int) Source #
A version of hGetBuf
which works for any type safe length units.
byteSize :: Storable a => a -> BYTES Int Source #
Similar to sizeOf
but returns the length in type safe units.
:: LengthUnit l | |
=> Pointer | Target |
-> Word8 | Value byte to set |
-> l | Number of bytes to set |
-> IO () |
Sets the given number of Bytes to the specified value.
:: LengthUnit l | |
=> Pointer | Dest |
-> Pointer | Src |
-> l | Number of Bytes to copy |
-> IO () |
Move between pointers.
:: LengthUnit l | |
=> Pointer | Dest |
-> Pointer | Src |
-> l | Number of Bytes to copy |
-> IO () |
Copy between pointers.
Tuples with length encoded in their types.
Length encoded tuples
Tuples that encode their length in their types. For tuples, we call the length its dimension
(Unbox a, Equality a) => Eq (Tuple dim a) Source # | Equality checking is timing safe. |
(Show a, Unbox a) => Show (Tuple dim a) Source # | |
(Unbox a, Storable a, KnownNat dim) => Storable (Tuple dim a) Source # | |
(Unbox a, Equality a) => Equality (Tuple dim a) Source # | |
(Unbox a, EndianStore a, KnownNat dim) => EndianStore (Tuple dim a) Source # | |
dimension :: (Unbox a, KnownNat dim) => Tuple dim a -> Int Source #
Function that returns the dimension of the tuple. The dimension
is calculated without inspecting the tuple and hence the term
will evaluate to 5.dimension
(undefined :: Tuple 5 Int)
initial :: (Unbox a, KnownNat dim0, KnownNat dim1) => Tuple dim1 a -> Tuple dim0 a Source #
Computes the initial fragment of a tuple. No length needs to be given as it is infered from the types.
Unsafe operations
unsafeFromList :: (Unbox a, KnownNat dim) => [a] -> Tuple dim a Source #
Construct a tuple out of the list. This function is unsafe and will result in run time error if the list is not of the correct dimension.
class Describable d where Source #
This class captures all types that have some sort of description attached to it.
Describable (SomeHashI h) Source # | |
Describable (SomeCipherI cipher) Source # | |
Describable (HashI h m) Source # | |
Describable (CipherI cipher encMem decMem) Source # | |