-- 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.8 -- | 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 -- (System.Crypto.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 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: -- -- 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 -- System.Crypto.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 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. -- -- You should always use constTimeEq when comparing hashes, -- otherwise you may leave a significant security hole (cf. -- http://codahale.com/a-lesson-in-timing-attacks/). constTimeEq :: ByteString -> ByteString -> Bool 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 -> ByteString -> d -- | hmac k msg will compute an authentication code for -- msg using key k hmac' :: Hash c d => MacKey -> ByteString -> d newtype MacKey MacKey :: ByteString -> MacKey instance Eq MacKey instance Ord MacKey instance Show MacKey -- | 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 -- Test.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 -- System.Crypto.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: -- -- -- -- 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 -- | A static espPad allows reuse of a single B.pack'ed pad for all calls -- to padESP -- -- 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