úÎ.,B    portableStable%Michael Snoyman <michael@snoyman.com>None=The initialization vector used by AES. Should be exactly 16  bytes long. =The keys used to store the cookies. We have an AES key used ? to encrypt the cookie and a Skein-MAC-512-256 key used verify @ the authencity and integrity of the cookie. The AES key needs = to have exactly 32 bytes (256 bits) while Skein-MAC-512-256 " should have 64 bytes (512 bits).  See also  and . AES key with 32 bytes. +Skein-MAC key. Instead of storing the key - data, we store a partially applied function  for calculating the MAC (see ). *Construct an initialization vector from a .  Fails if there isn't exactly 16 bytes. 7Randomly construct a fresh initialization vector. You   should not reuse initialization vectors. The default key file.  Simply calls  . $Get a key from the given text file. =If the file does not exist or is corrupted a random key will ' be generated and stored in that file. Generate a random . Besides the , the   ByteString passed to  is returned so that it can be  saved for later use. Initializes a  from a random  . Fails if  there isn'2t exactly 96 bytes (256 bits for AES and 512 bits  for Skein-MAC-512-512). Same as  !, however randomly generates the  initialization vector for you. 8Encrypt (AES-CTR), authenticate (Skein-MAC-512-256) and ; encode (Base64) the given cookie data. The returned byte 2 string is ready to be used in a response header. 7Decode (Base64), verify the integrity and authenticity = (Skein-MAC-512-256) and decrypt (AES-CTR) the given encoded < cookie data. Returns the original serialized cookie data. ! Fails if the data is corrupted. &Construct initial state of the CPRNG. 8Reseed the CPRNG with new entropy from the system pool. IORef2 that keeps the current state of the CPRNG. Yep, 6 global state. Used in thread-safe was only, though. ;Construct a new 16-byte IV using our CPRNG. Forks another ; thread to reseed the CPRNG should its usage count reach a  hardcoded threshold. =How many IVs should be generated before reseeding the CPRNG. < This number depends basically on how paranoid you are. We @ think 100.000 is a good compromise: larger numbers give only a ? small performance advantage, while it still is a small number @ since we only generate 1.5 MiB of random data between reseeds. Dummy  instance. ! File name where key is stored. The actual key.  Key of the server. 'New, random initialization vector (see ). Serialized cookie data. #Encoded cookie data to be given to  the client browser. Key of the server. *Encoded cookie data given by the browser. Serialized cookie data.  !"#      !"#$      !"#$%&'()*clientsession-0.9.0.3Web.ClientSessionIVKeymkIVrandomIVdefaultKeyFile getDefaultKeygetKey randomKeyinitKey encryptIOencryptdecryptaesKeymacKey skein-1.0.8 Crypto.Skein skeinMAC'bytestring-0.10.0.2Data.ByteString.Internal ByteStringaesSeed aesReseedaesRefaesRNG threshold $fShowKeybaseGHC.ShowShowAESStateAStkeyRaw unsafeMkIVunIV $fSerializeIV$fShowIV$fOrdIV$fEqIV$fSerializeKey$fEqKey