diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.6
+
+* Add ChaChaPoly1305 AE cipher
+* Add instructions in README for building on old OSX
+* Fix blocking /dev/random Andrey Sverdlichenko
+
 ## 0.5
 
 * Fix all strays exports to all be under the cryptonite prefix.
diff --git a/Crypto/Cipher/AES.hs b/Crypto/Cipher/AES.hs
--- a/Crypto/Cipher/AES.hs
+++ b/Crypto/Cipher/AES.hs
@@ -1,4 +1,4 @@
-    -- |
+-- |
 -- Module      : Crypto.Cipher.AES
 -- License     : BSD-style
 -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
diff --git a/Crypto/Cipher/ChaChaPoly1305.hs b/Crypto/Cipher/ChaChaPoly1305.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/Cipher/ChaChaPoly1305.hs
@@ -0,0 +1,112 @@
+-- |
+-- Module      : Crypto.Cipher.ChaChaPoly1305
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : stable
+-- Portability : good
+--
+-- A simple AEAD scheme using ChaCha20 and Poly1305.
+-- 
+-- See RFC7539.
+--
+module Crypto.Cipher.ChaChaPoly1305
+    ( State
+    , Nonce
+    , nonce12
+    , nonce8
+    , initialize
+    , appendAAD
+    , finalizeAAD
+    , combine
+    , finalize
+    ) where
+
+import           Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes, ScrubbedBytes)
+import qualified Crypto.Internal.ByteArray as B
+import           Crypto.Internal.Imports
+import           Crypto.Error
+import qualified Crypto.Cipher.ChaCha as ChaCha
+import qualified Crypto.MAC.Poly1305  as Poly1305
+import           Data.Memory.Endian
+import qualified Data.ByteArray.Pack as P
+
+data State = State !ChaCha.State
+                   !Poly1305.State
+                   !Word64 -- AAD length
+                   !Word64 -- ciphertext length
+
+newtype Nonce = Nonce Bytes
+
+-- Based on the following pseudo code:
+--
+-- chacha20_aead_encrypt(aad, key, iv, constant, plaintext):
+--     nonce = constant | iv
+--     otk = poly1305_key_gen(key, nonce)
+--     ciphertext = chacha20_encrypt(key, 1, nonce, plaintext)
+--     mac_data = aad | pad16(aad)
+--     mac_data |= ciphertext | pad16(ciphertext)
+--     mac_data |= num_to_4_le_bytes(aad.length)
+--     mac_data |= num_to_4_le_bytes(ciphertext.length)
+--     tag = poly1305_mac(mac_data, otk)
+--     return (ciphertext, tag)
+
+pad16 :: Word64 -> Bytes
+pad16 n
+    | modLen == 0 = B.empty
+    | otherwise   = B.replicate (16 - modLen) 0
+  where
+    modLen = fromIntegral (n `mod` 16)
+
+-- | Nonce smart constructor 12 bytes IV, nonce constructor
+nonce12 :: ByteArrayAccess iv => iv -> CryptoFailable Nonce
+nonce12 iv
+    | B.length iv /= 12 = CryptoFailed  $ CryptoError_IvSizeInvalid
+    | otherwise         = CryptoPassed $ Nonce (B.convert iv)
+
+-- | 8 bytes IV, nonce constructor
+nonce8 :: ByteArrayAccess ba
+       => ba -- ^ 4 bytes constant 
+       -> ba -- ^ 8 bytes IV
+       -> CryptoFailable Nonce
+nonce8 constant iv
+    | B.length constant /= 4 = CryptoFailed $ CryptoError_IvSizeInvalid
+    | B.length iv       /= 8 = CryptoFailed $ CryptoError_IvSizeInvalid
+    | otherwise              = CryptoPassed $ Nonce $ B.concat [constant, iv]
+
+initialize :: ByteArrayAccess key
+           => key -> Nonce -> CryptoFailable State
+initialize key (Nonce nonce)
+    | B.length key /= 32 = CryptoFailed $ CryptoError_KeySizeInvalid
+    | otherwise          = CryptoPassed $ State encState polyState 0 0
+  where
+    rootState           = ChaCha.initialize 20 key nonce
+    (polyKey, encState) = ChaCha.generate rootState 64
+    polyState           = Poly1305.initialize (B.take 32 polyKey :: ScrubbedBytes)
+
+appendAAD :: ByteArrayAccess ba => ba -> State -> State
+appendAAD ba (State encState macState aadLength plainLength) =
+    State encState newMacState newLength plainLength
+  where
+    newMacState = Poly1305.update macState ba
+    newLength   = aadLength + fromIntegral (B.length ba)
+
+finalizeAAD :: State -> State
+finalizeAAD (State encState macState aadLength plainLength) =
+    State encState newMacState aadLength plainLength
+  where
+    newMacState = Poly1305.update macState $ pad16 aadLength
+
+combine :: ByteArray ba => ba -> State -> (ba, State)
+combine input (State encState macState aadLength plainLength) =
+    (output, State newEncState newMacState aadLength newPlainLength)
+  where
+    (output, newEncState) = ChaCha.combine encState input
+    newMacState           = Poly1305.update macState output
+    newPlainLength        = plainLength + fromIntegral (B.length input)
+
+finalize :: State -> Poly1305.Auth
+finalize (State _ macState aadLength plainLength) =
+    Poly1305.finalize $ Poly1305.updates macState
+        [ pad16 plainLength
+        , either (error "finalize: internal error") id $ P.fill 16 (P.putStorable (LE aadLength) >> P.putStorable (LE plainLength))
+        ]
diff --git a/Crypto/MAC/Poly1305.hs b/Crypto/MAC/Poly1305.hs
--- a/Crypto/MAC/Poly1305.hs
+++ b/Crypto/MAC/Poly1305.hs
@@ -12,13 +12,14 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 module Crypto.MAC.Poly1305
     ( Ctx
+    , State
     , Auth(..)
 
     -- * Incremental MAC Functions
-    , initialize -- :: Ctx
-    , update     -- :: Ctx -> ByteString -> Ctx
-    , updates    -- :: Ctx -> [ByteString] -> Ctx
-    , finalize   -- :: Ctx -> Auth
+    , initialize -- :: State
+    , update     -- :: State -> ByteString -> State
+    , updates    -- :: State -> [ByteString] -> State
+    , finalize   -- :: State -> Auth
     -- * One-pass MAC function
     , auth
     ) where
@@ -29,10 +30,13 @@
 import           Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes)
 import qualified Crypto.Internal.ByteArray as B
 
--- | Poly1305 Context
-newtype Ctx = Ctx ScrubbedBytes
+-- | Poly1305 State
+newtype State = State ScrubbedBytes
     deriving (ByteArrayAccess)
 
+type Ctx = State
+{-# DEPRECATED Ctx "use Poly1305 State instead" #-}
+
 -- | Poly1305 Auth
 newtype Auth = Auth Bytes
     deriving (ByteArrayAccess)
@@ -41,35 +45,35 @@
     (Auth a1) == (Auth a2) = B.constEq a1 a2
 
 foreign import ccall unsafe "cryptonite_poly1305.h cryptonite_poly1305_init"
-    c_poly1305_init :: Ptr Ctx -> Ptr Word8 -> IO ()
+    c_poly1305_init :: Ptr State -> Ptr Word8 -> IO ()
 
 foreign import ccall "cryptonite_poly1305.h cryptonite_poly1305_update"
-    c_poly1305_update :: Ptr Ctx -> Ptr Word8 -> CUInt -> IO ()
+    c_poly1305_update :: Ptr State -> Ptr Word8 -> CUInt -> IO ()
 
 foreign import ccall unsafe "cryptonite_poly1305.h cryptonite_poly1305_finalize"
-    c_poly1305_finalize :: Ptr Word8 -> Ptr Ctx -> IO ()
+    c_poly1305_finalize :: Ptr Word8 -> Ptr State -> IO ()
 
 -- | initialize a Poly1305 context
 initialize :: ByteArrayAccess key
            => key
-           -> Ctx
+           -> State
 initialize key
     | B.length key /= 32 = error "Poly1305: key length expected 32 bytes"
-    | otherwise          = Ctx $ B.allocAndFreeze 84 $ \ctxPtr ->
+    | otherwise          = State $ B.allocAndFreeze 84 $ \ctxPtr ->
         B.withByteArray key $ \keyPtr ->
             c_poly1305_init (castPtr ctxPtr) keyPtr
 {-# NOINLINE initialize #-}
 
 -- | update a context with a bytestring
-update :: ByteArrayAccess ba => Ctx -> ba -> Ctx
-update (Ctx prevCtx) d = Ctx $ B.copyAndFreeze prevCtx $ \ctxPtr ->
+update :: ByteArrayAccess ba => State -> ba -> State
+update (State prevCtx) d = State $ B.copyAndFreeze prevCtx $ \ctxPtr ->
     B.withByteArray d $ \dataPtr ->
         c_poly1305_update (castPtr ctxPtr) dataPtr (fromIntegral $ B.length d)
 {-# NOINLINE update #-}
 
 -- | updates a context with multiples bytestring
-updates :: ByteArrayAccess ba => Ctx -> [ba] -> Ctx
-updates (Ctx prevCtx) d = Ctx $ B.copyAndFreeze prevCtx (loop d)
+updates :: ByteArrayAccess ba => State -> [ba] -> State
+updates (State prevCtx) d = State $ B.copyAndFreeze prevCtx (loop d)
   where loop []     _      = return ()
         loop (x:xs) ctxPtr = do
             B.withByteArray x $ \dataPtr -> c_poly1305_update ctxPtr dataPtr (fromIntegral $ B.length x)
@@ -77,8 +81,8 @@
 {-# NOINLINE updates #-}
 
 -- | finalize the context into a digest bytestring
-finalize :: Ctx -> Auth
-finalize (Ctx prevCtx) = Auth $ B.allocAndFreeze 16 $ \dst -> do
+finalize :: State -> Auth
+finalize (State prevCtx) = Auth $ B.allocAndFreeze 16 $ \dst -> do
     _ <- B.copy prevCtx (\ctxPtr -> c_poly1305_finalize dst (castPtr ctxPtr)) :: IO ScrubbedBytes
     return ()
 {-# NOINLINE finalize #-}
diff --git a/Crypto/Random/Entropy/Unix.hs b/Crypto/Random/Entropy/Unix.hs
--- a/Crypto/Random/Entropy/Unix.hs
+++ b/Crypto/Random/Entropy/Unix.hs
@@ -31,7 +31,7 @@
 instance EntropySource DevRandom where
     entropyOpen = fmap DevRandom `fmap` testOpen "/dev/random"
     entropyGather (DevRandom name) ptr n =
-        withDev name $ \h -> gatherDevEntropy h ptr n
+        withDev name $ \h -> gatherDevEntropyNonBlock h ptr n
     entropyClose (DevRandom _)  = return ()
 
 instance EntropySource DevURandom where
@@ -66,4 +66,9 @@
 gatherDevEntropy :: H -> Ptr Word8 -> Int -> IO Int
 gatherDevEntropy h ptr sz =
      (fromIntegral `fmap` hGetBufSome h ptr (fromIntegral sz))
+    `E.catch` \(_ :: IOException) -> return 0
+
+gatherDevEntropyNonBlock :: H -> Ptr Word8 -> Int -> IO Int
+gatherDevEntropyNonBlock h ptr sz =
+     (fromIntegral `fmap` hGetBufNonBlocking h ptr (fromIntegral sz))
     `E.catch` \(_ :: IOException) -> return 0
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@
 * Windows >= 8
 * OSX >= 10.8
 * Linux
+* BSDs
 
 On the following architectures:
 
@@ -56,6 +57,33 @@
 
 Further platforms and architectures probably works too, but until maintainer(s) don't have regular
 access to them, we can't commit for further support
+
+Known Building Issues
+---------------------
+
+on OSX <= 10.7, the system compiler doesn't understand the '-maes' option, and
+with the lack of autodetection feature builtin in .cabal file, it is left on
+the user to disable the aesni. See the [Disabling AESNI] section
+
+Disabling AESNI
+---------------
+
+It may be useful to disable AESNI (for building, testing or runtime purpose), and one can do that with the
+*support_aesni* flag.
+
+As part of configure of cryptonite:
+
+```
+  cabal configure --flag='-support_aesni'
+```
+
+or as part of an installation:
+
+```
+  cabal install --constraint="cryptonite -support_aesni"
+```
+
+For help with cabal flags, see: [stackoverflow : is there a way to define flags for cabal](http://stackoverflow.com/questions/23523869/is-there-any-way-to-define-flags-for-cabal-dependencies)
 
 Links
 -----
diff --git a/cryptonite.cabal b/cryptonite.cabal
--- a/cryptonite.cabal
+++ b/cryptonite.cabal
@@ -1,5 +1,5 @@
 Name:                cryptonite
-Version:             0.5
+Version:             0.6
 Synopsis:            Cryptography Primitives sink
 Description:
     A repository of cryptographic primitives.
@@ -51,6 +51,11 @@
   Default:           True
   Manual:            True
 
+Flag support_rdrand
+  Description:       allow compilation with AESNI on system and architecture that supports it
+  Default:           True
+  Manual:            True
+
 Flag support_pclmuldq
   Description:       Allow compilation with pclmuldq on architecture that supports it
   Default:           False
@@ -71,6 +76,7 @@
                      Crypto.Cipher.Blowfish
                      Crypto.Cipher.Camellia
                      Crypto.Cipher.ChaCha
+                     Crypto.Cipher.ChaChaPoly1305
                      Crypto.Cipher.DES
                      Crypto.Cipher.RC4
                      Crypto.Cipher.Salsa
@@ -202,7 +208,7 @@
   if arch(i386)
     CPP-options: -DARCH_X86
 
-  if arch(x86_64)
+  if flag(support_rdrand) && arch(x86_64)
     CPP-options:    -DARCH_X86_64
     CPP-options:    -DSUPPORT_RDRAND
     Other-modules:  Crypto.Random.Entropy.RDRand
diff --git a/tests/ChaChaPoly1305.hs b/tests/ChaChaPoly1305.hs
new file mode 100644
--- /dev/null
+++ b/tests/ChaChaPoly1305.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE OverloadedStrings #-}
+module ChaChaPoly1305 where
+
+import qualified Crypto.Cipher.ChaChaPoly1305 as AEAD
+import Imports
+import Crypto.Error
+import Poly1305 ()
+
+import qualified Data.ByteString as B
+import qualified Data.ByteArray as B (convert)
+
+plaintext, aad, key, iv, ciphertext, tag :: B.ByteString
+plaintext = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
+aad = "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+iv = "\x40\x41\x42\x43\x44\x45\x46\x47"
+constant = "\x07\x00\x00\x00"
+ciphertext = "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b\x61\x16"
+tag = "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91"
+
+tests = testGroup "ChaChaPoly1305"
+    [ testCase "V1" runEncrypt
+    ]
+  where runEncrypt =
+            let ini                 = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv)
+                afterAAD            = AEAD.finalizeAAD (AEAD.appendAAD aad ini)
+                (out, afterEncrypt) = AEAD.combine plaintext afterAAD
+                outtag              = AEAD.finalize afterEncrypt
+             in propertyHoldCase [ eqTest "ciphertext" ciphertext out
+                                 , eqTest "tag" tag (B.convert outtag)
+                                 ]
diff --git a/tests/Number.hs b/tests/Number.hs
--- a/tests/Number.hs
+++ b/tests/Number.hs
@@ -20,28 +20,29 @@
     ]
 
 tests = testGroup "number"
-    [ testProperty "num-bits" $ \(Positive i) ->
+    [ testProperty "num-bits" $ \(Int0_2901 i) ->
         and [ (numBits (2^i-1) == i)
             , (numBits (2^i) == i+1)
             , (numBits (2^i + (2^i-1)) == i+1)
             ]
     , testProperty "num-bits2" $ \(Positive i) ->
         not (i `testBit` numBits i) && (i `testBit` (numBits i - 1))
-    , testProperty "generate-param" $ \testDRG (Positive bits)  ->
+    , testProperty "generate-param" $ \testDRG (Int0_2901 bits)  ->
         let r = withTestDRG testDRG $ generateParams bits (Just SetHighest) False
          in r >= 0 && numBits r == bits && testBit r (bits-1)
-    , testProperty "generate-param2" $ \testDRG (Positive m1bits) ->
+    , testProperty "generate-param2" $ \testDRG (Int0_2901 m1bits) ->
         let bits = m1bits + 1 -- make sure minimum is 2
             r = withTestDRG testDRG $ generateParams bits (Just SetTwoHighest) False
          in r >= 0 && numBits r == bits && testBit r (bits-1) && testBit r (bits-2)
-    , testProperty "generate-param-odd" $ \testDRG (Positive bits) ->
+    , testProperty "generate-param-odd" $ \testDRG (Int0_2901 bits) ->
         let r = withTestDRG testDRG $ generateParams bits Nothing True
          in r >= 0 && odd r
     , testProperty "generate-range" $ \testDRG (Positive range) ->
         let r = withTestDRG testDRG $ generateMax range
          in 0 <= r && r < range
-    , testProperty "generate-prime" $ \testDRG (Positive baseBits) ->
-        let bits  = 48 + baseBits -- no point generating lower than 48 bits ..
+    , testProperty "generate-prime" $ \testDRG (Int0_2901 baseBits') ->
+        let baseBits = baseBits' `mod` 800
+            bits  = 48 + baseBits -- no point generating lower than 48 bits ..
             prime = withTestDRG testDRG $ generatePrime bits
         -- with small base bits numbers, the probability that we "cross" this bit size ness
         -- to the next is quite high, as the number generated has two highest bit set.
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -8,6 +8,7 @@
 import qualified Poly1305
 import qualified Salsa
 import qualified ChaCha
+import qualified ChaChaPoly1305
 import qualified KAT_HMAC
 import qualified KAT_PBKDF2
 import qualified KAT_Curve25519
@@ -48,6 +49,7 @@
     , testGroup "stream-cipher"
         [ KAT_RC4.tests
         , ChaCha.tests
+        , ChaChaPoly1305.tests
         , Salsa.tests
         ]
     , KAT_AFIS.tests
diff --git a/tests/Utils.hs b/tests/Utils.hs
--- a/tests/Utils.hs
+++ b/tests/Utils.hs
@@ -14,6 +14,7 @@
 import Prelude
 
 import Test.Tasty.QuickCheck
+import Test.Tasty.HUnit ((@=?))
 
 newtype TestDRG = TestDRG (Word64, Word64, Word64, Word64, Word64)
     deriving (Show,Eq)
@@ -142,3 +143,6 @@
         | a == b    = acc
         | otherwise =
             (name ++ ": expected " ++ show a ++ " but got: " ++ show b) : acc
+
+propertyHoldCase :: [PropertyTest] -> IO ()
+propertyHoldCase l = True @=? propertyHold l
