DRBG 0.2 → 0.2.2
raw patch · 3 files changed
+30/−25 lines, 3 filesdep +cryptocipherPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: cryptocipher
API changes (from Hackage documentation)
+ Crypto.Random.DRBG: type GenAES = GenCounter AES128
- Crypto.Random.DRBG: newGenAutoReseedIO :: (CryptoRandomGen a, CryptoRandomGen b) => Int -> IO (Either GenError (GenAutoReseed a b))
+ Crypto.Random.DRBG: newGenAutoReseedIO :: (CryptoRandomGen a, CryptoRandomGen b) => Int -> IO (GenAutoReseed a b)
Files
- CHANGELOG +3/−0
- Crypto/Random/DRBG.hs +24/−23
- DRBG.cabal +3/−2
CHANGELOG view
@@ -1,3 +1,6 @@+0.2.2+* Depend on cryptocipher to provide an AES based DRBG+* We now have a GenCounter instance that uses ctr from crypto-api 0.1.4 * Documentation fixes
Crypto/Random/DRBG.hs view
@@ -38,7 +38,7 @@ HmacDRBG, HashDRBG , HmacDRBGWith, HashDRBGWith -- * Basic Cipher-based Generator- , GenCounter+ , GenAES, GenCounter -- * CryptoRandomGen Transformers , GenXor , GenBuffered@@ -60,6 +60,7 @@ import Crypto.Hash.SHA256 (SHA256) import Crypto.Hash.SHA224 (SHA224) import Crypto.Hash.SHA1 (SHA1)+import Crypto.Cipher.AES (AES128) import System.Crypto.Random import qualified Data.ByteString as B import qualified Data.ByteString.Internal as BI@@ -70,6 +71,7 @@ import Control.Monad (liftM) import Control.Monad.Error () -- Either instance import Data.Serialize (encode)+import Data.Word instance H.SeedLength SHA512 where seedlen = Tagged 888@@ -130,16 +132,11 @@ -- interval of @i@ bytes, using the system random number generator as a seed. -- -- See 'newGenAutoReseed'.-newGenAutoReseedIO :: (CryptoRandomGen a, CryptoRandomGen b) =>- Int -> IO (Either GenError (GenAutoReseed a b))+newGenAutoReseedIO :: (CryptoRandomGen a, CryptoRandomGen b) => Int -> IO (GenAutoReseed a b) newGenAutoReseedIO i = do- let p = Proxy- getG :: (CryptoRandomGen a, CryptoRandomGen b) => - Proxy (GenAutoReseed a b) -> IO (Either GenError (GenAutoReseed a b))- getG p = liftM (\bs -> newGenAutoReseed bs i `asProxyTypeOf` rightProxy p)- (getEntropy (seed p))- g <- getG p- return (g `asProxyTypeOf` p)+ g1 <- newGenIO+ g2 <- newGenIO+ return $ GenAutoReseed g1 g2 i 0 seed :: CryptoRandomGen g => Proxy g -> Int seed x = proxy genSeedLength x@@ -226,11 +223,7 @@ {-# SPECIALIZE instance CryptoRandomGen (GenAutoReseed HashDRBG HmacDRBG) #-} {-# SPECIALIZE instance CryptoRandomGen (GenAutoReseed HmacDRBG HashDRBG) #-} newGen bs = newGenAutoReseed bs (2^15)- newGenIO = do- b <- newGenAutoReseedIO (2^15)- case b of- Left err -> error $ show err- Right g -> return g+ newGenIO = newGenAutoReseedIO (2^15) genSeedLength = let a = helper1 res b = helper2 res@@ -399,33 +392,41 @@ eval (Left x) = Left x eval (Right (g,bs)) = bs `seq` (g `seq` (Right (g, bs))) +-- |A random number generator using AES128 in ctr mode.+type GenAES = GenCounter AES128+ -- |@GenCounter k@ is a cryptographic BlockCipher with key @k@ -- being used in 'ctr' mode to generate random bytes.-data GenCounter a = GenCounter a (IV a)+data GenCounter a = GenCounter {-# UNPACK #-} !Word64 a (IV a) instance BlockCipher x => CryptoRandomGen (GenCounter x) where- newGen bytes = case buildKey bytes of Nothing -> Left NotEnoughEntropy- Just x -> Right (GenCounter x zeroIV)+ newGen bytes =+ let kl = keyLength+ in case buildKey (B.take (untag kl `div` 8) bytes) of+ Nothing -> Left NotEnoughEntropy+ Just x -> Right (GenCounter 0 (x `asTaggedTypeOf` kl) zeroIV) newGenIO = do let b = keyLength kd <- getEntropy ((untag b + 7) `div` 8) case buildKey kd of Nothing -> error "Failed to generate key for GenCounter"- Just k -> return $ GenCounter (k `asTaggedTypeOf` b) zeroIV+ Just k -> return $ GenCounter 0 (k `asTaggedTypeOf` b) zeroIV genSeedLength = let rt :: Tagged x Int -> Tagged (GenCounter x) Int rt = Tagged . (`div` 8) . unTagged in rt keyLength -- If this is called for less than blockSize data - genBytes req (GenCounter k counter) =- let bs = B.replicate req' 0+ genBytes req (GenCounter rs k counter) =+ let bs = B.replicate (req' * blkSz) 0 blkSz = blockSizeBytes `for` k (rnd,iv) = ctr' incIV k counter bs req' = (req + blkSz - 1) `div` blkSz- in Right (B.take req rnd, GenCounter k iv)+ in if rs >= 2^48+ then Left NeedReseed+ else Right (B.take req rnd, GenCounter (rs+1) k iv) - reseed bs (GenCounter k _) = newGen (xorExtendBS (encode k) bs)+ reseed bs (GenCounter _ k _) = newGen (xorExtendBS (encode k) bs) xorExtendBS a b = res where
DRBG.cabal view
@@ -1,5 +1,5 @@ name: DRBG-version: 0.2+version: 0.2.2 license: BSD3 license-file: LICENSE author: Thomas DuBuisson <thomas.dubuisson@gmail.com>@@ -22,7 +22,8 @@ Library Build-Depends: base >= 4.0 && < 5, cereal >= 0.2, bytestring, prettyclass, tagged >= 0.2,- crypto-api >= 0.6, cryptohash >= 0.6.1, parallel, mtl >= 2.0+ crypto-api >= 0.6, cryptohash >= 0.6.1, parallel, mtl >= 2.0,+ cryptocipher ghc-options: -O2 hs-source-dirs: exposed-modules: Crypto.Random.DRBG.Hash, Crypto.Random.DRBG.HMAC, Crypto.Random.DRBG, Crypto.Random.DRBG.Types