diff --git a/Network/TLS.hs b/Network/TLS.hs
--- a/Network/TLS.hs
+++ b/Network/TLS.hs
@@ -29,8 +29,6 @@
 
 	-- * Crypto Key
 	, PrivateKey(..)
-	-- * Crypto RNG
-	, makeSRandomGen, SRandomGen
 	-- * Compressions & Predefined compressions
 	, Compression
 	, nullCompression
@@ -46,5 +44,4 @@
 import Network.TLS.Crypto (PrivateKey(..))
 import Network.TLS.Cipher (Cipher(..))
 import Network.TLS.Compression (Compression(..), nullCompression)
-import Network.TLS.SRandom (makeSRandomGen, SRandomGen)
 import Network.TLS.Core
diff --git a/Network/TLS/Core.hs b/Network/TLS/Core.hs
--- a/Network/TLS/Core.hs
+++ b/Network/TLS/Core.hs
@@ -41,13 +41,13 @@
 import Network.TLS.State
 import Network.TLS.Sending
 import Network.TLS.Receiving
-import Network.TLS.SRandom
 import Data.Maybe
 import Data.Certificate.X509
 import Data.List (intersect, intercalate, find)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 
+import Crypto.Random
 import Control.Applicative ((<$>))
 import Control.Concurrent.MVar
 import Control.Monad.State
@@ -120,7 +120,7 @@
 		Right r  -> return r
 
 getStateRNG :: MonadIO m => TLSCtx -> Int -> m Bytes
-getStateRNG ctx n = usingState_ ctx (withTLSRNG (\rng -> getRandomBytes rng n))
+getStateRNG ctx n = usingState_ ctx (genTLSRandom n)
 
 whileStatus :: MonadIO m => TLSCtx -> (TLSStatus -> Bool) -> m a -> m ()
 whileStatus ctx p a = do
@@ -147,13 +147,13 @@
 
 -- | Create a new Client context with a configuration, a RNG, and a Handle.
 -- It reconfigures the handle buffermode to noBuffering
-client :: MonadIO m => TLSParams -> SRandomGen -> Handle -> m TLSCtx
+client :: (MonadIO m, CryptoRandomGen g) => TLSParams -> g -> Handle -> m TLSCtx
 client params rng handle = liftIO $ newCtx handle params state
 	where state = (newTLSState rng) { stClientContext = True }
 
 -- | Create a new Server context with a configuration, a RNG, and a Handle.
 -- It reconfigures the handle buffermode to noBuffering
-server :: MonadIO m => TLSParams -> SRandomGen -> Handle -> m TLSCtx
+server :: (MonadIO m, CryptoRandomGen g) => TLSParams -> g -> Handle -> m TLSCtx
 server params rng handle = liftIO $ newCtx handle params state
 	where state = (newTLSState rng) { stClientContext = False }
 
diff --git a/Network/TLS/Receiving.hs b/Network/TLS/Receiving.hs
--- a/Network/TLS/Receiving.hs
+++ b/Network/TLS/Receiving.hs
@@ -28,7 +28,6 @@
 import Network.TLS.State
 import Network.TLS.Cipher
 import Network.TLS.Crypto
-import Network.TLS.SRandom
 import Data.Certificate.X509
 
 import qualified Crypto.Cipher.RSA as RSA
@@ -114,9 +113,7 @@
 
 setMasterSecretRandom :: ByteString -> TLSSt ()
 setMasterSecretRandom content = do
-	st <- get
-	let (bytes, g') = getRandomBytes (stRandomGen st) (fromIntegral $ B.length content)
-	put $ st { stRandomGen = g' }
+	bytes <- genTLSRandom (fromIntegral $ B.length content)
 	setMasterSecret bytes
 
 processClientKeyXchg :: Version -> ByteString -> TLSSt ()
diff --git a/Network/TLS/SRandom.hs b/Network/TLS/SRandom.hs
deleted file mode 100644
--- a/Network/TLS/SRandom.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-module Network.TLS.SRandom
-	( SRandomGen
-	, makeSRandomGen
-	, getRandomBytes
-	) where
-
-import Data.Word
-import Crypto.Random
-import System.Crypto.Random (getEntropy)
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import qualified Crypto.Cipher.AES as AES
-import Data.Bits (xor)
-import Data.Serialize
-
-{-
- - the following CPRNG is an AES cbc based counter system.
- -
- - 16 bytes IV, 16 bytes counter, 32 bytes key
- - (IV `xor` counter) `aes` key -> 16 bytes output
- -}
-
-data Word128 = Word128 !Word64 !Word64
-
-{-| An opaque object containing an AES CPRNG -}
-data SRandomGen = RNG !ByteString !Word128 !AES.Key
-
-instance Show SRandomGen where
-	show _ = "srandomgen[..]"
-
-put128 :: Word128 -> ByteString
-put128 (Word128 a b) = runPut (putWord64host a >> putWord64host b)
-
-get128 :: ByteString -> Word128
-get128 = either (\_ -> Word128 0 0) id . runGet (getWord64host >>= \a -> (getWord64host >>= \b -> return $ Word128 a b))
-
-add1 :: Word128 -> Word128
-add1 (Word128 a b) = if b == 0xffffffffffffffff then Word128 (a+1) 0 else Word128 a (b+1)
-
-makeParams :: ByteString -> (AES.Key, ByteString, ByteString)
-makeParams b = (key, cnt, iv)
-	where
-		(Right key)  = AES.initKey256 $ B.take 32 left2
-		(cnt, left2) = B.splitAt 16 left1
-		(iv, left1)  = B.splitAt 16 b
-
-make :: B.ByteString -> Either GenError SRandomGen
-make b
-	| B.length b < 64 = Left NotEnoughEntropy
-	| otherwise       = Right $ RNG iv (get128 cnt) key
-		where
-			(key, cnt, iv) = makeParams b
-
-chunkSize :: Int
-chunkSize = 16
-
-bxor :: ByteString -> ByteString -> ByteString
-bxor a b = B.pack $ B.zipWith xor a b
-
-nextChunk :: SRandomGen -> (ByteString, SRandomGen)
-nextChunk (RNG iv counter key) = (chunk, newrng)
-	where
-		newrng = RNG chunk (add1 counter) key
-		chunk  = AES.encryptCBC key iv bytes
-		bytes  = iv `bxor` (put128 counter)
-
-{-| initialize from system a new SrandomGen -}
-makeSRandomGen :: IO (Either GenError SRandomGen)
-makeSRandomGen = getEntropy 64 >>= return . make
-
-getRandomBytes :: SRandomGen -> Int -> (ByteString, SRandomGen)
-getRandomBytes rng n =
-	let list = helper rng n in
-	(B.concat $ map fst list, snd $ last list)
-	where
-		helper _ 0 = []
-		helper g i =
-			let (b, g') = nextChunk g in
-			if chunkSize >= i
-				then [ (B.take i b, g') ]
-				else (b, g') : helper g' (i-chunkSize)
-
-instance CryptoRandomGen SRandomGen where
-	newGen           = make
-	genSeedLength    = 64
-	genBytes len rng = Right $ getRandomBytes rng len
-	reseed b rng@(RNG _ cnt1 _)
-		| B.length b < 64 = Left NotEnoughEntropy
-		| otherwise       = Right $ RNG (r16 `bxor` iv2) (get128 (put128 cnt1 `bxor` cnt2)) key2
-			where
-				(r16, _)          = nextChunk rng
-				(key2, cnt2, iv2) = makeParams b
diff --git a/Network/TLS/Sending.hs b/Network/TLS/Sending.hs
--- a/Network/TLS/Sending.hs
+++ b/Network/TLS/Sending.hs
@@ -103,13 +103,10 @@
 encryptRSA :: ByteString -> TLSSt ByteString
 encryptRSA content = do
 	st <- get
-	let g = stRandomGen st
 	let rsakey = fromJust "rsa public key" $ hstRSAPublicKey $ fromJust "handshake" $ stHandshake st
-	case kxEncrypt g rsakey content of
-		Left err             -> fail ("rsa encrypt failed: " ++ show err)
-		Right (econtent, g') -> do
-			put (st { stRandomGen = g' })
-			return econtent
+	case withTLSRNG (stRandomGen st) (\g -> kxEncrypt g rsakey content) of
+		Left err               -> fail ("rsa encrypt failed: " ++ show err)
+		Right (econtent, rng') -> put (st { stRandomGen = rng' }) >> return econtent
 
 encryptContent :: (Header, ByteString) -> TLSSt (Header, ByteString)
 encryptContent (hdr@(Header pt ver _), content) = do
diff --git a/Network/TLS/State.hs b/Network/TLS/State.hs
--- a/Network/TLS/State.hs
+++ b/Network/TLS/State.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleContexts, MultiParamTypeClasses #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleContexts, MultiParamTypeClasses, ExistentialQuantification, RankNTypes #-}
 -- |
 -- Module      : Network.TLS.State
 -- License     : BSD-style
@@ -19,6 +19,7 @@
 	, TLSStatus(..)
 	, HandshakeStatus(..)
 	, newTLSState
+	, genTLSRandom
 	, withTLSRNG
 	, assert -- FIXME move somewhere else (Internal.hs ?)
 	, updateStatusHs
@@ -48,7 +49,6 @@
 import Data.Maybe (isNothing)
 import Network.TLS.Util
 import Network.TLS.Struct
-import Network.TLS.SRandom
 import Network.TLS.Wire
 import Network.TLS.Packet
 import Network.TLS.Crypto
@@ -58,6 +58,7 @@
 import Control.Monad
 import Control.Monad.State
 import Control.Monad.Error
+import Crypto.Random
 
 assert :: Monad m => String -> [(String,Bool)] -> m ()
 assert fctname list = forM_ list $ \ (name, assumption) -> do
@@ -105,6 +106,11 @@
 	, hstHandshakeDigest :: Maybe (HashCtx, HashCtx) -- FIXME could be only 1 hash in tls12
 	} deriving (Show)
 
+data StateRNG = forall g . CryptoRandomGen g => StateRNG g
+
+instance Show StateRNG where
+	show _ = "rng[..]"
+
 data TLSState = TLSState
 	{ stClientContext :: Bool
 	, stVersion       :: !Version
@@ -117,7 +123,7 @@
 	, stTxMacState    :: !(Maybe TLSMacState)
 	, stRxMacState    :: !(Maybe TLSMacState)
 	, stCipher        :: Maybe Cipher
-	, stRandomGen     :: SRandomGen
+	, stRandomGen     :: StateRNG
 	} deriving (Show)
 
 newtype TLSSt a = TLSSt { runTLSSt :: ErrorT TLSError (State TLSState) a }
@@ -133,7 +139,7 @@
 runTLSState :: TLSSt a -> TLSState -> (Either TLSError a, TLSState)
 runTLSState f st = runState (runErrorT (runTLSSt f)) st
 
-newTLSState :: SRandomGen -> TLSState
+newTLSState :: CryptoRandomGen g => g -> TLSState
 newTLSState rng = TLSState
 	{ stClientContext = False
 	, stVersion       = TLS10
@@ -146,15 +152,20 @@
 	, stTxMacState    = Nothing
 	, stRxMacState    = Nothing
 	, stCipher        = Nothing
-	, stRandomGen     = rng
+	, stRandomGen     = StateRNG rng
 	}
 
-withTLSRNG :: MonadState TLSState m => (SRandomGen -> (a, SRandomGen)) -> m a
-withTLSRNG f = do
+withTLSRNG :: StateRNG -> (forall g . CryptoRandomGen g => g -> Either e (a,g)) -> Either e (a, StateRNG)
+withTLSRNG (StateRNG rng) f = case f rng of
+	Left err        -> Left err
+	Right (a, rng') -> Right (a, StateRNG rng')
+
+genTLSRandom :: (MonadState TLSState m, MonadError TLSError m) => Int -> m Bytes
+genTLSRandom n = do
 	st <- get
-	let (a, newrng) = f (stRandomGen st)
-	put (st { stRandomGen = newrng })
-	return a
+	case withTLSRNG (stRandomGen st) (genBytes n) of
+		Left err            -> throwError $ Error_Random $ show err
+		Right (bytes, rng') -> put (st { stRandomGen = rng' }) >> return bytes
 
 makeDigest :: MonadState TLSState m => Bool -> Header -> Bytes -> m Bytes
 makeDigest w hdr content = do
diff --git a/Network/TLS/Struct.hs b/Network/TLS/Struct.hs
--- a/Network/TLS/Struct.hs
+++ b/Network/TLS/Struct.hs
@@ -108,6 +108,7 @@
 data TLSError =
 	  Error_Misc String
 	| Error_Certificate String
+	| Error_Random String
 	| Error_Digest ([Word8], [Word8])
 	| Error_Packet String
 	| Error_Packet_Size_Mismatch (Int, Int)
diff --git a/Tests.hs b/Tests.hs
--- a/Tests.hs
+++ b/Tests.hs
@@ -92,8 +92,6 @@
 prop_handshake_marshalling_id x = (decodeHs $ encodeHandshake x) == Right x
 	where
 		decodeHs b = either (Left . id) (uncurry (decodeHandshake TLS10) . head) $ decodeHandshakes b
---import qualified Tests.Connection as Connection
---import qualified Tests.Ciphers as Ciphers
 
 myQuickCheckArgs = stdArgs
 	{ replay     = Nothing
@@ -110,6 +108,3 @@
 main = do
 	run_test "marshalling header = id" prop_header_marshalling_id
 	run_test "marshalling handshake = id" prop_handshake_marshalling_id
-	--Marshal.runTests
-	--Ciphers.runTests
-	--Connection.runTests
diff --git a/tls.cabal b/tls.cabal
--- a/tls.cabal
+++ b/tls.cabal
@@ -1,5 +1,5 @@
 Name:                tls
-Version:             0.5.1
+Version:             0.6.0
 Description:
    native TLS protocol implementation, focusing on purity and more type-checking.
    .
@@ -44,7 +44,6 @@
                      Network.TLS.Compression
                      Network.TLS.Internal
   other-modules:     Network.TLS.Cap
-                     Network.TLS.SRandom
                      Network.TLS.Struct
                      Network.TLS.MAC
                      Network.TLS.Core
