diff --git a/Crypto/Random/API.hs b/Crypto/Random/API.hs
--- a/Crypto/Random/API.hs
+++ b/Crypto/Random/API.hs
@@ -7,15 +7,34 @@
 
 module Crypto.Random.API
     ( CPRG(..)
+    , ReseedPolicy(..)
     , genRandomBytes
+    , genRandomBytes'
     , withRandomBytes
     , getSystemEntropy
+    -- * System Random generator
+    , SystemRandom
+    , getSystemRandomGen
     ) where
 
+import Control.Applicative
 import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import System.Entropy (getEntropy)
+import qualified System.Entropy as SE
+import System.IO.Unsafe (unsafeInterleaveIO)
+import Data.Word
 
+-- | This is the reseed policy requested by the CPRG
+data ReseedPolicy =
+      NeverReseed          -- ^ there is no need to reseed as either
+                           -- the RG doesn't supports it, it's done automatically
+                           -- or pratically the reseeding period exceed a Word64 type.
+    | ReseedInBytes Word64 -- ^ the RG need to be reseed in the number
+                           -- of bytes joined to the type. it should be done before
+                           -- the number reached 0, otherwise an user of the RG
+                           -- might request too many bytes and get repeated random bytes.
+    deriving (Show,Eq)
+
 -- | A class of Cryptographic Secure Random generator.
 --
 -- The main difference with the generic haskell RNG is that
@@ -25,7 +44,7 @@
 -- except that error are not returned to the user. Instead
 -- the user is suppose to handle reseeding by using the NeedReseed
 -- and SupplyEntropy methods. For other type of errors, the user
--- is expect to generate bytes with the parameters bounds explicity
+-- is expected to generate bytes with the parameters bounds explicity
 -- defined here.
 -- 
 -- The CPRG need to be able to generate up to 2^20 bytes in one call,
@@ -35,39 +54,82 @@
     -- is required to be supplied so the CPRG doesn't repeat output, and
     -- break assumptions. This returns the number of bytes before
     -- which supply entropy should have been called.
-    cprgNeedReseed    :: g -> Int
+    cprgNeedReseed    :: g -> ReseedPolicy
 
     -- | Supply entropy to the CPRG, that can be used now or later
     -- to reseed the CPRG. This should be used in conjunction to
     -- NeedReseed to know when to supply entropy.
-    cprgSupplyEntropy :: g -> ByteString -> g
+    cprgSupplyEntropy :: ByteString -> g -> g
 
     -- | Generate bytes using the CPRG and the number specified.
     --
     -- For user of the API, it's recommended to use genRandomBytes
-    -- instead of this method directly.
-    cprgGenBytes      :: g -> Int -> (ByteString, g)
+    -- instead of this method directly. the CPRG need to be able
+    -- to supply at minimum 2^20 bytes at a time.
+    cprgGenBytes      :: Int -> g -> (ByteString, g)
 
 -- | Generate bytes using the cprg in parameter.
--- 
--- arbitrary limit the number of bytes that can be generated in
--- one go to 10mb.
-genRandomBytes :: CPRG g => g   -- ^ CPRG to use
-                         -> Int -- ^ number of bytes to return
+--
+-- If the number of bytes requested is really high,
+-- it's preferable to use 'genRandomBytes' for better memory efficiency.
+genRandomBytes :: CPRG g => Int -- ^ number of bytes to return
+                         -> g   -- ^ CPRG to use
                          -> (ByteString, g)
-genRandomBytes rng len
+genRandomBytes len rng = (\(lbs,g) -> (B.concat lbs, g)) $ genRandomBytes' len rng
+
+-- | Generate bytes using the cprg in parameter.
+--
+-- This is not tail recursive and an excessive len (>= 2^29) parameter would
+-- result in stack overflow.
+genRandomBytes' :: CPRG g => Int -- ^ number of bytes to return
+                          -> g   -- ^ CPRG to use
+                          -> ([ByteString], g)
+genRandomBytes' len rng
     | len < 0    = error "genBytes: cannot request negative amount of bytes."
-    | len > 2^20 = error "genBytes: cannot request more than 1mb of bytes in one go."
-    | len == 0   = (B.empty, rng)
-    | otherwise  = cprgGenBytes rng len
+    | otherwise  = loop rng len
+            where loop g len
+                    | len == 0  = ([], g)
+                    | otherwise = let itBytes  = min (2^20) len
+                                      (bs, g') = cprgGenBytes itBytes g
+                                      (l, g'') = genRandomBytes' (len-itBytes) g'
+                                   in (bs:l, g'')
 
--- | this is equivalent to using Control.Arrow 'first' with genBytes.
+-- | this is equivalent to using Control.Arrow 'first' with 'genRandomBytes'.
 --
 -- namely it generate @len bytes and map the bytes to the function @f
 withRandomBytes :: CPRG g => g -> Int -> (ByteString -> a) -> (a, g)
 withRandomBytes rng len f = (f bs, rng')
-    where (bs, rng') = genRandomBytes rng len
+    where (bs, rng') = genRandomBytes len rng
 
 -- | Return system entropy using the entropy package 'getEntropy'
 getSystemEntropy :: Int -> IO ByteString
-getSystemEntropy = getEntropy
+getSystemEntropy = SE.getEntropy
+
+-- | This is a simple generator that pull bytes from the system entropy
+-- directly. Its randomness and security properties are absolutely
+-- depends on the underlaying system implementation.
+data SystemRandom = SystemRandom [B.ByteString]
+
+-- | Get a random number generator based on the standard system entropy source
+getSystemRandomGen :: IO SystemRandom
+getSystemRandomGen = do
+    ch <- SE.openHandle
+    let getBS = unsafeInterleaveIO $ do
+        bs   <- SE.hGetEntropy ch 8192
+        more <- getBS
+        return (bs:more)
+    SystemRandom <$> getBS
+
+instance CPRG SystemRandom where
+   cprgNeedReseed      _ = NeverReseed
+   cprgSupplyEntropy _ g = g
+   cprgGenBytes n (SystemRandom l) = (B.concat l1, SystemRandom l2)
+        where (l1, l2) = lbsSplitAt n l
+              lbsSplitAt rBytes (x:xs)
+                | xLen >= rBytes =
+                    let (b1,b2) = B.splitAt rBytes x
+                     in  ([b1], b2:xs)
+                | otherwise =
+                    let (l1,l2) = lbsSplitAt (rBytes-xLen) xs
+                     in (x:l1,l2)
+                where xLen = B.length x
diff --git a/crypto-random-api.cabal b/crypto-random-api.cabal
--- a/crypto-random-api.cabal
+++ b/crypto-random-api.cabal
@@ -1,5 +1,5 @@
 Name:                crypto-random-api
-Version:             0.1.0
+Version:             0.2.0
 Description:         Simple random generators API for cryptography related code
 License:             BSD3
 License-file:        LICENSE
