-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A generic interface for cryptographic operations
--   
--   A generic interface for cryptographic operations (hashes, ciphers,
--   randomness). Maintainers of hash and cipher implementations are
--   encouraged to add instances for the classes defined in Crypto.Classes.
--   Crypto users are similarly encouraged to use the interfaces defined in
--   the Classes module. Any concepts or functions of general use to more
--   than one cryptographic algorithm (ex: padding) is within scope of this
--   package.
@package crypto-api
@version 0.11


-- | Type aliases used throughout the crypto-api modules.
module Crypto.Types

-- | Initilization Vectors for BlockCipher implementations (IV k) are used
--   for various modes and guarrenteed to be blockSize bits long. The
--   common ways to obtain an IV are to generate one (<tt>getIV</tt> or
--   <tt>getIVIO</tt>) or to use one provided with the ciphertext (using
--   the <tt>Serialize</tt> instance of IV).
--   
--   <tt>zeroIV</tt> also exists and is of particular use for starting
--   <tt>ctr</tt> mode with a fresh key.
data IV k
IV :: {-# UNPACK #-} !ByteString -> IV k
initializationVector :: IV k -> {-# UNPACK #-} !ByteString

-- | The length of a field (usually a ByteString) in bits
type BitLength = Int

-- | The length fo a field in bytes.
type ByteLength = Int
instance Eq (IV k)
instance Ord (IV k)
instance Show (IV k)


-- | This module is for instantiating cryptographicly strong determinitic
--   random bit generators (DRBGs, aka PRNGs) For the simple use case of
--   using the system random number generator (<a>Random</a>) to seed the
--   DRBG:
--   
--   <pre>
--   g &lt;- newGenIO
--   </pre>
--   
--   Users needing to provide their own entropy can call <a>newGen</a>
--   directly
--   
--   <pre>
--   entropy &lt;- getEntropy nrBytes
--   let generator = newGen entropy
--   </pre>
module Crypto.Random

-- | A class of random bit generators that allows for the possibility of
--   failure, reseeding, providing entropy at the same time as requesting
--   bytes
--   
--   Minimum complete definition: <a>newGen</a>, <a>genSeedLength</a>,
--   <a>genBytes</a>, <a>reseed</a>.
class CryptoRandomGen g where genBytesWithEntropy len entropy g = let res = genBytes len g in case res of { Left err -> Left err Right (bs, g') -> let entropy' = append entropy (replicate (len - length entropy) 0) in Right (zwp' entropy' bs, g') } newGenIO = go 0 where go 1000 = throw $ GenErrorOther $ "The generator instance requested by" ++ "newGenIO never instantiates (1000 tries). " ++ "It must be broken." go i = do { let p = Proxy getTypedGen :: CryptoRandomGen g => Proxy g -> IO (Either GenError g) getTypedGen pr = liftM newGen (getEntropy $ proxy genSeedLength pr); res <- getTypedGen p; case res of { Left _ -> go (i + 1) Right g -> return (g `asProxyTypeOf` p) } }
newGen :: CryptoRandomGen g => ByteString -> Either GenError g
genSeedLength :: CryptoRandomGen g => Tagged g ByteLength
genBytes :: CryptoRandomGen g => ByteLength -> g -> Either GenError (ByteString, g)
genBytesWithEntropy :: CryptoRandomGen g => ByteLength -> ByteString -> g -> Either GenError (ByteString, g)
reseed :: CryptoRandomGen g => ByteString -> g -> Either GenError g
newGenIO :: CryptoRandomGen g => IO g

-- | Generator failures should always return the appropriate GenError. Note
--   <a>GenError</a> in an instance of exception but wether or not an
--   exception is thrown depends on if the selected generator (read: if you
--   don't want execptions from code that uses <a>throw</a> then pass in a
--   generator that never has an error for the used functions)
data GenError

-- | Misc
GenErrorOther :: String -> GenError

-- | Requested more bytes than a single pass can generate (The maximum
--   request is generator dependent)
RequestedTooManyBytes :: GenError

-- | When using <tt>genInteger g (l,h)</tt> and <tt>logBase 2 (h - l) &gt;
--   (maxBound :: Int)</tt>.
RangeInvalid :: GenError

-- | Some generators cease operation after too high a count without a
--   reseed (ex: NIST SP 800-90)
NeedReseed :: GenError

-- | For instantiating new generators (or reseeding)
NotEnoughEntropy :: GenError

-- | This generator can not be instantiated or reseeded with a finite seed
--   (ex: <a>SystemRandom</a>)
NeedsInfiniteSeed :: GenError

-- | While the safety and wisdom of a splitting function depends on the
--   properties of the generator being split, several arguments from
--   informed people indicate such a function is safe for NIST SP 800-90
--   generators. (see libraries@haskell.org discussion around Sept, Oct
--   2010)
splitGen :: CryptoRandomGen g => g -> Either GenError (g, g)

-- | Useful utility to extract the result of a generator operation and
--   translate error results to exceptions.
throwLeft :: Exception e => Either e a -> a

-- | Not that it is technically correct as an instance of
--   <a>CryptoRandomGen</a>, but simply because it's a reasonable
--   engineering choice here is a CryptoRandomGen which streams the system
--   randoms. Take note:
--   
--   <ul>
--   <li>It uses the default definition of <tt>genByteWithEntropy</tt></li>
--   <li><a>newGen</a> will always fail!</li>
--   <li><a>reseed</a> will always fail!</li>
--   <li>the handle to the system random is never closed</li>
--   </ul>
data SystemRandom
instance Typeable GenError
instance Eq GenError
instance Ord GenError
instance Show GenError
instance CryptoRandomGen SystemRandom
instance Exception GenError


-- | This is the heart of the crypto-api package. By making (or having) an
--   instance of Hash, AsymCipher, BlockCipher or StreamCipher you provide
--   (or obtain) access to any infrastructure built on these primitives
--   include block cipher modes of operation, hashing, hmac, signing, etc.
--   These classes allow users to build routines that are agnostic to the
--   algorithm used so changing algorithms is as simple as changing a type
--   signature.
module Crypto.Classes

-- | The Hash class is intended as the generic interface targeted by
--   maintainers of Haskell digest implementations. Using this generic
--   interface, higher level functions such as <a>hash</a> and <a>hash'</a>
--   provide a useful API for comsumers of hash implementations.
--   
--   Any instantiated implementation must handle unaligned data.
--   
--   Minimum complete definition: <a>outputLength</a>, <a>blockLength</a>,
--   <a>initialCtx</a>, <a>updateCtx</a>, and <a>finalize</a>.
class (Serialize d, Eq d, Ord d) => Hash ctx d | d -> ctx, ctx -> d where hash msg = res where res = finalize ctx end ctx = foldl' updateCtx initialCtx blks (blks, end) = makeBlocks msg blockLen blockLen = (blockLength .::. res) `div` 8 hash' msg = res where res = finalize (updateCtx initialCtx top) end (top, end) = splitAt remlen msg remlen = length msg - (length msg `rem` bLen) bLen = blockLength `for` res `div` 8
outputLength :: Hash ctx d => Tagged d BitLength
blockLength :: Hash ctx d => Tagged d BitLength
initialCtx :: Hash ctx d => ctx
updateCtx :: Hash ctx d => ctx -> ByteString -> ctx
finalize :: Hash ctx d => ctx -> ByteString -> d
hash :: (Hash ctx d, Hash ctx d) => ByteString -> d
hash' :: (Hash ctx d, Hash ctx d) => ByteString -> d

-- | Obtain a lazy hash function whose result is the same type as the given
--   digest, which is discarded. If the type is already inferred then
--   consider using the <a>hash</a> function instead.
hashFunc :: Hash c d => d -> (ByteString -> d)

-- | Obtain a strict hash function whose result is the same type as the
--   given digest, which is discarded. If the type is already inferred then
--   consider using the <a>hash'</a> function instead.
hashFunc' :: Hash c d => d -> (ByteString -> d)

-- | The BlockCipher class is intended as the generic interface targeted by
--   maintainers of Haskell cipher implementations. Using this generic
--   interface higher level functions such as <a>cbc</a>, and other
--   functions from Data.Crypto.Modes, provide a useful API for comsumers
--   of cipher implementations.
--   
--   Instances must handle unaligned data
class Serialize k => BlockCipher k where ecb = modeEcb' unEcb = modeUnEcb' cbc = modeCbc' unCbc = modeUnCbc' ctr = modeCtr' incIV unCtr = modeUnCtr' incIV cfb = modeCfb' unCfb = modeUnCfb' ofb = modeOfb' unOfb = modeUnOfb'
blockSize :: BlockCipher k => Tagged k BitLength
encryptBlock :: BlockCipher k => k -> ByteString -> ByteString
decryptBlock :: BlockCipher k => k -> ByteString -> ByteString
buildKey :: BlockCipher k => ByteString -> Maybe k
keyLength :: BlockCipher k => Tagged k BitLength
ecb :: BlockCipher k => k -> ByteString -> ByteString
unEcb :: BlockCipher k => k -> ByteString -> ByteString
cbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
unCbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
ctr :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
unCtr :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
cfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
unCfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
ofb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
unOfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | The number of bytes in a block cipher block
blockSizeBytes :: BlockCipher k => Tagged k ByteLength

-- | Build a symmetric key using the system entropy (see <a>Random</a>)
buildKeyIO :: BlockCipher k => IO k

-- | A stream cipher class. Instance are expected to work on messages as
--   small as one byte The length of the resulting cipher text should be
--   equal to the length of the input message.
class Serialize k => StreamCipher k iv | k -> iv
buildStreamKey :: StreamCipher k iv => ByteString -> Maybe k
encryptStream :: StreamCipher k iv => k -> iv -> ByteString -> (ByteString, iv)
decryptStream :: StreamCipher k iv => k -> iv -> ByteString -> (ByteString, iv)
streamKeyLength :: StreamCipher k iv => Tagged k BitLength

-- | Build a stream key using the system random generator
buildStreamKeyIO :: StreamCipher k iv => IO k

-- | Asymetric ciphers (common ones being RSA or EC based)
class (Serialize p, Serialize v) => AsymCipher p v | p -> v, v -> p
buildKeyPair :: (AsymCipher p v, CryptoRandomGen g) => g -> BitLength -> Either GenError ((p, v), g)
encryptAsym :: (AsymCipher p v, CryptoRandomGen g) => g -> p -> ByteString -> Either GenError (ByteString, g)
decryptAsym :: AsymCipher p v => v -> ByteString -> Maybe ByteString
publicKeyLength :: AsymCipher p v => p -> BitLength
privateKeyLength :: AsymCipher p v => v -> BitLength

-- | Build a pair of asymmetric keys using the system random generator.
buildKeyPairIO :: AsymCipher p v => BitLength -> IO (Either GenError (p, v))

-- | A class for signing operations which inherently can not be as generic
--   as asymetric ciphers (ex: DSA).
class (Serialize p, Serialize v) => Signing p v | p -> v, v -> p
sign :: (Signing p v, CryptoRandomGen g) => g -> v -> ByteString -> Either GenError (ByteString, g)
verify :: Signing p v => p -> ByteString -> ByteString -> Bool
buildSigningPair :: (Signing p v, CryptoRandomGen g) => g -> BitLength -> Either GenError ((p, v), g)
signingKeyLength :: Signing p v => v -> BitLength
verifyingKeyLength :: Signing p v => p -> BitLength

-- | Build a signing key using the system random generator
buildSigningKeyPairIO :: Signing p v => BitLength -> IO (Either GenError (p, v))

-- | Obtain a tagged value for a given type
for :: Tagged a b -> a -> b

-- | Infix <a>for</a> operator
(.::.) :: Tagged a b -> a -> b

-- | Checks two bytestrings for equality without breaches for timing
--   attacks.
--   
--   Semantically, <tt>constTimeEq = (==)</tt>. However, <tt>x == y</tt>
--   takes less time when the first byte is different than when the first
--   byte is equal. This side channel allows an attacker to mount a timing
--   attack. On the other hand, <tt>constTimeEq</tt> always takes the same
--   time regardless of the bytestrings' contents, unless they are of
--   difference size.
--   
--   You should always use <tt>constTimeEq</tt> when comparing secrets,
--   otherwise you may leave a significant security hole (cf.
--   <a>http://codahale.com/a-lesson-in-timing-attacks/</a>).
constTimeEq :: ByteString -> ByteString -> Bool

-- | Encode a value using binary serialization to a strict ByteString.
encode :: Serialize a => a -> ByteString


module Crypto.HMAC

-- | Message authentication code calculation for lazy bytestrings. <tt>hmac
--   k msg</tt> will compute an authentication code for <tt>msg</tt> using
--   key <tt>k</tt>
hmac :: Hash c d => MacKey c d -> ByteString -> d

-- | <tt>hmac k msg</tt> will compute an authentication code for
--   <tt>msg</tt> using key <tt>k</tt>
hmac' :: Hash c d => MacKey c d -> ByteString -> d

-- | A key carrying phantom types <tt>c</tt> and <tt>d</tt>, forcing the
--   key data to only be used by particular hash algorithms.
newtype MacKey c d
MacKey :: ByteString -> MacKey c d
instance Eq (MacKey c d)
instance Ord (MacKey c d)
instance Show (MacKey c d)


-- | PKCS5 (RFC 1423) and IPSec ESP (RFC 4303) padding methods are
--   implemented both as trivial functions operating on bytestrings and as
--   <a>Put</a> routines usable from the <a>Data.Serialize</a> module.
--   These methods do not work for algorithms or pad sizes in excess of 255
--   bytes (2040 bits, so extremely large as far as cipher needs are
--   concerned).
module Crypto.Padding

-- | PKCS5 (aka RFC1423) padding method. This method will not work properly
--   for pad modulos &gt; 256
padPKCS5 :: ByteLength -> ByteString -> ByteString

-- | PKCS5 (aka RFC1423) padding method using the BlockCipher instance to
--   determine the pad size.
padBlockSize :: BlockCipher k => k -> ByteString -> ByteString

-- | Ex:
--   
--   <pre>
--   putPaddedPKCS5 m bs
--   </pre>
--   
--   Will pad out <tt>bs</tt> to a byte multiple of <tt>m</tt> and put both
--   the bytestring and it's padding via <a>Put</a> (this saves on copying
--   if you are already using Cereal).
putPaddedPKCS5 :: ByteLength -> ByteString -> Put

-- | unpad a strict bytestring padded in the typical PKCS5 manner. This
--   routine verifies all pad bytes and pad length match correctly.
unpadPKCS5safe :: ByteString -> Maybe ByteString

-- | unpad a strict bytestring without checking the pad bytes and length
--   any more than necessary.
unpadPKCS5 :: ByteString -> ByteString

-- | Pad a bytestring to the IPSEC esp specification
--   
--   <pre>
--   padESP m payload
--   </pre>
--   
--   is equivilent to:
--   
--   <pre>
--             (msg)       (padding)       (length field)
--   B.concat [payload, B.pack [1,2,3,4..], B.pack [padLen]]
--   </pre>
--   
--   Where:
--   
--   <ul>
--   <li>the msg is any payload, including TFC.</li>
--   <li>the padding is &lt;= 255</li>
--   <li>the length field is one byte.</li>
--   </ul>
--   
--   Notice the result bytesting length remainder <tt>r</tt> equals zero.
--   The lack of a "next header" field means this function is not directly
--   useable for an IPSec implementation (copy/paste the 4 line function
--   and add in a "next header" field if you are making IPSec ESP).
padESP :: Int -> ByteString -> ByteString

-- | unpad and return the padded message (<a>Nothing</a> is returned if the
--   padding is invalid)
unpadESP :: ByteString -> Maybe ByteString

-- | Like padESP but use the BlockCipher instance to determine padding size
padESPBlockSize :: BlockCipher k => k -> ByteString -> ByteString

-- | Like putPadESP but using the BlockCipher instance to determine padding
--   size
putPadESPBlockSize :: BlockCipher k => k -> ByteString -> Put

-- | Pad a bytestring to the IPSEC ESP specification using <a>Put</a>. This
--   can reduce copying if you are already using <a>Put</a>.
putPadESP :: Int -> ByteString -> Put


-- | Authors: Thomas DuBuisson
--   
--   Generic mode implementations useable by any correct BlockCipher
--   instance Be aware there are no tests for CFB mode yet. See
--   <a>Crypto</a>.
module Crypto.Modes

-- | Obtain an <a>IV</a> using the provided CryptoRandomGenerator.
getIV :: (BlockCipher k, CryptoRandomGen g) => g -> Either GenError (IV k, g)

-- | Obtain an <a>IV</a> using the system entropy (see <a>Random</a>)
getIVIO :: BlockCipher k => IO (IV k)

-- | Obtain an <a>IV</a> made only of zeroes
zeroIV :: BlockCipher k => IV k

-- | Increase an <a>IV</a> by one. This is way faster than decoding,
--   increasing, encoding
incIV :: BlockCipher k => IV k -> IV k

-- | Cook book mode - not really a mode at all. If you don't know what
--   you're doing, don't use this mode^H^H^H^H library.
ecb :: BlockCipher k => k -> ByteString -> ByteString

-- | ECB decrypt, complementary to <a>ecb</a>.
unEcb :: BlockCipher k => k -> ByteString -> ByteString

-- | Cipher block chaining encryption for lazy bytestrings
cbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Cipher block chaining decryption for lazy bytestrings
unCbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Ciphertext feed-back encryption mode for lazy bytestrings (with s ==
--   blockSize)
cfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Ciphertext feed-back decryption mode for lazy bytestrings (with s ==
--   blockSize)
unCfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Output feedback mode for lazy bytestrings
ofb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Output feedback mode for lazy bytestrings
unOfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)

-- | Counter mode for lazy bytestrings
ctr :: BlockCipher k => (IV k -> IV k) -> k -> IV k -> ByteString -> (ByteString, IV k)

-- | Counter mode for lazy bytestrings
unCtr :: BlockCipher k => (IV k -> IV k) -> k -> IV k -> ByteString -> (ByteString, IV k)

-- | Counter mode for strict bytestrings
ctr' :: BlockCipher k => (IV k -> IV k) -> k -> IV k -> ByteString -> (ByteString, IV k)

-- | Counter mode for strict bytestrings
unCtr' :: BlockCipher k => (IV k -> IV k) -> k -> IV k -> ByteString -> (ByteString, IV k)
instance BlockCipher k => Serialize (IV k)
