----------------------------------------------------------------------------- -- | -- Module : Codec.Encryption.Modes -- Copyright : (c) Dominic Steinitz 2001-2003 -- License : BSD-style (see the file ReadMe.tex) -- -- Maintainer : dominic.steinitz@blueyonder.co.uk -- Stability : experimental -- Portability : portable -- -- This module currently supports Cipher Block Chaining (CBC) mode. -- See <http://www.itl.nist.gov/fipspubs/fip81.htm> for further details. -- ----------------------------------------------------------------------------- module Codec.Encryption.Modes ( -- * Function types cbc, unCbc ) where import Data.Word import Data.Bits -- * CBC or Cipher Block Chaining Mode -- | In CBC or Cipher Block Chaining mode each block is XORed with -- the previous enciphered block before encryption. For the first -- block, start with an initialization vector. -- Take an encryption function, an initialisation vector, a key and -- a list of blocks and return the encrypted blocks using CBC. cbc :: Bits block => (key -> block -> block) -> block -> key -> [block] -> [block] cbc e iv k ps = ciphers where ciphers = map (e k) feedIns feedIns = zipWith xor (iv : ciphers) ps -- | To decipher in CBC or Cipher Block Chaining mode, decipher -- each block, then XOR the result with the previous block of -- plaintext result. Note that the initialization vector is treated as the -- zeroth block of plaintext. -- Take a decryption function, an initialisation vector, a key and a list -- of encrypted blocks using CBC and return plaintext blocks. unCbc :: Bits block => (key -> block -> block) -> block -> key -> [block] -> [block] unCbc d iv k ms = outOfCbcs where beforeXOrs = map (d k) ms outOfCbcs = zipWith xor (iv : ms) beforeXOrs