-- 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.9
-- | Type aliases used throughout the crypto-api modules.
module Crypto.Types
-- | The length of a field (usually a ByteString) in bits
type BitLength = Int
-- | The length fo a field in bytes.
type ByteLength = Int
-- | This module is for instantiating cryptographically strong determinitic
-- random bit generators (DRBGs, aka PRNGs) For the simple use case of
-- using the system random number generator (Random) to seed the
-- DRBG:
--
--
-- g <- newGenIO
--
--
-- Users needing to provide their own entropy can call newGen
-- directly
--
--
-- entropy <- getEntropy nrBytes
-- let generator = newGen entropy
--
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: newGen, genSeedLength,
-- genBytes, reseed.
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 = error $ "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.
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 genInteger g (l,h) and logBase 2 (h - l) >
-- (maxBound :: Int).
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: SystemRandom)
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)
-- | Not that it is technically correct as an instance of
-- CryptoRandomGen, but simply because it's a reasonable
-- engineering choice here is a CryptoRandomGen which streams the system
-- randoms. Take note:
--
--
-- - It uses the default definition of genByteWithEntropy
-- - newGen will always fail!
-- - reseed will always fail!
-- - the handle to the system random is never closed
--
data SystemRandom
instance Eq GenError
instance Ord GenError
instance Show GenError
instance CryptoRandomGen SystemRandom
-- | 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 hash and hash'
-- provide a useful API for comsumers of hash implementations.
--
-- Any instantiated implementation must handle unaligned data
class (Serialize d, Eq d, Ord d) => Hash ctx d | d -> ctx, ctx -> d
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 a lazy ByteString, creating a digest
hash :: Hash ctx d => ByteString -> d
-- | Hash a strict ByteString, creating a digest
hash' :: 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 hash 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 hash' 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 cbc, 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
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
-- | The number of bytes in a block cipher block
blockSizeBytes :: BlockCipher k => Tagged k ByteLength
-- | Build a symmetric key using the system entropy (see Random)
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 for operator
(.::.) :: Tagged a b -> a -> b
-- | Checks two bytestrings for equality without breaches for timing
-- attacks.
--
-- Semantically, constTimeEq = (==). However, x == y
-- 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, constTimeEq always takes the same
-- time regardless of the bytestrings' contents, unless they are of
-- difference size.
--
-- You should always use constTimeEq when comparing secrets,
-- otherwise you may leave a significant security hole (cf.
-- http://codahale.com/a-lesson-in-timing-attacks/).
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. hmac
-- k msg will compute an authentication code for msg using
-- key k
hmac :: Hash c d => MacKey c d -> ByteString -> d
-- | hmac k msg will compute an authentication code for
-- msg using key k
hmac' :: Hash c d => MacKey c d -> ByteString -> d
newtype MacKey c d
MacKey :: ByteString -> MacKey c d
instance Eq (MacKey c d)
instance Ord (MacKey c d)
instance Show (MacKey c d)
-- | Authors: Thomas DuBuisson, Francisco Blas Izquierdo Riera (klondike)
--
-- Generic mode implementations useable by any correct BlockCipher
-- instance Be aware there are no tests for CFB mode yet. See
-- Crypto.
module Crypto.Modes
-- | 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 (getIV or
-- getIVIO) or to use one provided with the ciphertext (using the
-- Serialize instance of IV).
--
-- zeroIV also exists and is of particular use for starting
-- ctr mode with a fresh key.
data IV k
-- | Obtain an IV using the provided CryptoRandomGenerator.
getIV :: (BlockCipher k, CryptoRandomGen g) => g -> Either GenError (IV k, g)
-- | Obtain an IV using the system entropy (see Random)
getIVIO :: BlockCipher k => IO (IV k)
-- | Obtain an IV made only of zeroes
zeroIV :: BlockCipher k => IV k
-- | Increase an IV by one. This is way faster than decoding,
-- increasing, encoding
incIV :: BlockCipher k => IV k -> IV k
-- | Perform doubling as defined by the CMAC and SIV papers
dblIV :: BlockCipher k => IV k -> IV k
ecb :: BlockCipher k => k -> ByteString -> ByteString
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)
ecb' :: BlockCipher k => k -> ByteString -> ByteString
unEcb' :: BlockCipher k => k -> ByteString -> ByteString
-- | Cipher block chaining encryption mode on strict bytestrings
cbc' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
-- | Cipher block chaining decryption for strict bytestrings
unCbc' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
-- | Ciphertext feed-back encryption mode for strict bytestrings (with s ==
-- blockSize)
cfb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
-- | Ciphertext feed-back decryption mode for strict bytestrings (with s ==
-- blockSize)
unCfb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
-- | Output feedback mode for strict bytestrings
ofb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
-- | Output feedback mode for strict 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)
-- | SIV (Synthetic IV) mode for lazy bytestrings. First argument is the
-- optional list of bytestrings to be authenticated but not encrypted As
-- required by the specification this algorithm may return nothing when
-- certain constraints aren't met.
siv :: BlockCipher k => k -> k -> [ByteString] -> ByteString -> Maybe ByteString
-- | SIV (Synthetic IV) for lazy bytestrings. First argument is the
-- optional list of bytestrings to be authenticated but not encrypted. As
-- required by the specification this algorithm may return nothing when
-- authentication fails.
unSiv :: BlockCipher k => k -> k -> [ByteString] -> ByteString -> Maybe ByteString
-- | SIV (Synthetic IV) mode for strict bytestrings. First argument is the
-- optional list of bytestrings to be authenticated but not encrypted. As
-- required by the specification this algorithm may return nothing when
-- certain constraints aren't met.
siv' :: BlockCipher k => k -> k -> [ByteString] -> ByteString -> Maybe ByteString
-- | SIV (Synthetic IV) for strict bytestrings First argument is the
-- optional list of bytestrings to be authenticated but not encrypted As
-- required by the specification this algorithm may return nothing when
-- authentication fails.
unSiv' :: BlockCipher k => k -> k -> [ByteString] -> ByteString -> Maybe ByteString
cbcMac' :: BlockCipher k => k -> ByteString -> ByteString
cbcMac :: BlockCipher k => k -> ByteString -> ByteString
-- | Obtain the cmac for lazy bytestrings
cMac :: BlockCipher k => k -> ByteString -> ByteString
-- | Obtain the cmac for strict bytestrings
cMac' :: BlockCipher k => k -> ByteString -> ByteString
instance Eq (IV k)
instance Ord (IV k)
instance Show (IV k)
instance BlockCipher k => Serialize (IV k)
-- | PKCS5 (RFC 1423) and IPSec ESP (RFC 4303) padding methods are
-- implemented both as trivial functions operating on bytestrings and as
-- Put routines usable from the Data.Serialize 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 > 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:
--
--
-- putPaddedPKCS5 m bs
--
--
-- Will pad out bs to a byte multiple of m and put both
-- the bytestring and it's padding via Put (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
--
--
-- padESP m payload
--
--
-- is equivilent to:
--
--
-- (msg) (padding) (length field)
-- B.concat [payload, B.pack [1,2,3,4..], B.pack [padLen]]
--
--
-- Where:
--
--
-- - the msg is any payload, including TFC.
-- - the padding is <= 255
-- - the length field is one byte.
--
--
-- Notice the result bytesting length remainder r 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 (Nothing 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 Put. This
-- can reduce copying if you are already using Put.
putPadESP :: Int -> ByteString -> Put