packages feed

cacophony 0.1.0.0 → 0.2.0

raw patch · 17 files changed

+316/−46 lines, 17 files

Files

cacophony.cabal view
@@ -1,20 +1,24 @@ name:          cacophony-version:       0.1.0.0+version:       0.2.0 synopsis:      A library implementing the Noise protocol. license:       PublicDomain license-file:  LICENSE author:        John Galt-maintainer:    centromere@users.noreply.github.com-homepage:      https://github.com/centromere/cacophony/wiki+maintainer:    jgalt@centromere.net+homepage:      https://github.com/centromere/cacophony bug-reports:   https://github.com/centromere/cacophony/issues category:      Cryptography build-type:    Simple cabal-version: >=1.10 tested-with:   GHC == 7.10.1, GHC == 7.10.2+description:+  This library implements the <https://github.com/trevp/noise/blob/master/noise.md Noise>+  protocol.  extra-source-files:   .travis.yml   README.md+  changelog.md   LICENSE  source-repository head@@ -77,7 +81,6 @@     base >= 4.8 && < 4.9,     bytestring,     cacophony,-    memory,     mtl,     QuickCheck,     tasty,
+ changelog.md view
@@ -0,0 +1,11 @@+# 0.2.0++* Added support for one-way handshakes++* Fixed Noise_IX++* Added helper functions for ScrubbedBytes / ByteString conversion++# 0.1.0.0++* First version.
src/Crypto/Noise/Cipher.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Cipher--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX 
src/Crypto/Noise/Cipher/ChaChaPoly1305.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Cipher.ChaChaPoly1305--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX @@ -15,7 +15,6 @@ import qualified Crypto.Cipher.ChaChaPoly1305 as CCP import qualified Crypto.MAC.Poly1305 as P import qualified Data.ByteArray as B (take, drop, length)-import Data.ByteString (ByteString) import qualified Data.ByteString as BS (replicate)  import Crypto.Noise.Cipher@@ -29,7 +28,7 @@   newtype SymmetricKey ChaChaPoly1305 = SKCCP1305 ScrubbedBytes   newtype Nonce        ChaChaPoly1305 = NCCP1305  CCP.Nonce -  cipherName _      = convert ("ChaChaPoly" :: ByteString)+  cipherName _      = bsToSB' "ChaChaPoly"   cipherEncrypt     = encrypt   cipherDecrypt     = decrypt   cipherZeroNonce   = zeroNonce
src/Crypto/Noise/Curve.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Curve--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX 
src/Crypto/Noise/Curve/Curve25519.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Curve.Curve25519--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX @@ -13,7 +13,6 @@  import Crypto.Random.Entropy import qualified Crypto.PubKey.Curve25519 as C-import Data.ByteString (ByteString)  import Crypto.Noise.Curve import Crypto.Noise.Types@@ -25,7 +24,7 @@   newtype PublicKey Curve25519 = PK25519 C.PublicKey   newtype SecretKey Curve25519 = SK25519 C.SecretKey -  curveName   _    = convert ("25519" :: ByteString)+  curveName   _    = bsToSB' "25519"   curveLength _    = 32   curveGenKey      = genKey   curveDH          = dh
src/Crypto/Noise/Descriptors.hs view
@@ -1,7 +1,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Descriptors--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX --@@ -134,7 +134,22 @@     noiseIXI1,     noiseIXR1,     noiseIXR2,-    noiseIXI2+    noiseIXI2,+    -- * Noise_N+    noiseNI0,+    noiseNR0,+    noiseNI1,+    noiseNR1,+    -- * Noise_K+    noiseKI0,+    noiseKR0,+    noiseKI1,+    noiseKR1,+     -- * Noise_X+    noiseXI0,+    noiseXR0,+    noiseXI1,+    noiseXR1   ) where  import Control.Monad ((>=>))@@ -819,7 +834,7 @@ noiseIXI1 = do   s <- tokenWS   e <- tokenWE-  return $ e `append` s+  return $ s `append` e  noiseIXR1 :: (Cipher c, Curve d, Hash h)           => ByteString@@ -845,4 +860,92 @@   tokenDHSE   rest' <- tokenRS rest   tokenDHES+  return rest'++--------------------------------------------------------------------------------+-- Noise_N++noiseNI0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseNI0 = tokenPreRS++noiseNR0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseNR0 = tokenPreLS++noiseNI1 :: (Cipher c, Curve d, Hash h)+        => DescriptorIO c d h ByteString+noiseNI1 = do+  e <- tokenWE+  tokenDHES+  return e++noiseNR1 :: (Cipher c, Curve d, Hash h)+        => ByteString+        -> Descriptor c d h ByteString+noiseNR1 buf = do+  rest <- tokenRE buf+  tokenDHSE+  return rest++--------------------------------------------------------------------------------+-- Noise_K++noiseKI0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseKI0 = do+  tokenPreRS+  tokenPreLS++noiseKR0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseKR0 = do+  tokenPreLS+  tokenPreRS++noiseKI1 :: (Cipher c, Curve d, Hash h)+          => DescriptorIO c d h ByteString+noiseKI1 = do+  e <- tokenWE+  tokenDHES+  tokenDHSS+  return e++noiseKR1 :: (Cipher c, Curve d, Hash h)+          => ByteString+          -> Descriptor c d h ByteString+noiseKR1 buf = do+  rest <- tokenRE buf+  tokenDHSE+  tokenDHSS+  return rest++--------------------------------------------------------------------------------+-- Noise_X++noiseXI0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseXI0 = tokenPreRS++noiseXR0 :: (Cipher c, Curve d, Hash h)+         => Descriptor c d h ()+noiseXR0 = tokenPreLS++noiseXI1 :: (Cipher c, Curve d, Hash h)+          => DescriptorIO c d h ByteString+noiseXI1 = do+  e <- tokenWE+  tokenDHES+  s <- tokenWS+  tokenDHSS+  return $ e `append` s++noiseXR1 :: (Cipher c, Curve d, Hash h)+          => ByteString+          -> Descriptor c d h ByteString+noiseXR1 buf = do+  rest <- tokenRE buf+  tokenDHSE+  rest' <- tokenRS rest+  tokenDHSS   return rest'
src/Crypto/Noise/Handshake.hs view
@@ -1,7 +1,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Handshake--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX --@@ -12,6 +12,7 @@     HandshakeState,     Descriptor,     DescriptorIO,+    CipherState,     -- * Functions     getRemoteStaticKey,     handshakeState,@@ -24,3 +25,4 @@   ) where  import Crypto.Noise.Internal.HandshakeState+import Crypto.Noise.Internal.CipherState
src/Crypto/Noise/Hash.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Hash--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX 
src/Crypto/Noise/Hash/SHA256.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Hash.SHA256--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX @@ -13,7 +13,6 @@  import qualified Crypto.Hash as H import qualified Crypto.MAC.HMAC as M-import Data.ByteString (ByteString)  import Crypto.Noise.Hash import Crypto.Noise.Types@@ -25,7 +24,7 @@   newtype ChainingKey SHA256 = HCKSHA256 ScrubbedBytes   newtype Digest      SHA256 = HDSHA256  (H.Digest H.SHA256) -  hashName   _  = convert ("SHA256" :: ByteString)+  hashName   _  = bsToSB' "SHA256"   hashLength _  = 32   hash          = hash'   hashHKDF      = hkdf@@ -39,8 +38,8 @@ hkdf :: ChainingKey SHA256 -> ScrubbedBytes -> (ChainingKey SHA256, ScrubbedBytes) hkdf (HCKSHA256 ck) d = (HCKSHA256 ck', sk)   where-    x01   = convert ("\x01" :: ByteString) :: ScrubbedBytes-    x02   = convert ("\x02" :: ByteString) :: ScrubbedBytes+    x01   = bsToSB' "\x01"+    x02   = bsToSB' "\x02"      hmac1 = M.hmac ck d :: M.HMAC H.SHA256     temp  = convert . M.hmacGetDigest $ hmac1 :: ScrubbedBytes
src/Crypto/Noise/Internal/CipherState.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Internal.CipherState--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX 
src/Crypto/Noise/Internal/HandshakeState.hs view
@@ -4,7 +4,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Internal.HandshakeState--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX @@ -308,7 +308,7 @@ encryptPayload pt cs = ((convert . cipherTextToBytes) ct, cs')   where     (ct, cs') = encryptAndIncrement ad pt cs-    ad = AssocData $ convert ("" :: ByteString)+    ad = AssocData . bsToSB' $ ""  -- | Decrypts a payload. The returned 'CipherState' must be used for all --   subsequent calls.@@ -321,4 +321,4 @@ decryptPayload ct cs = (pt, cs')   where     (pt, cs') = decryptAndIncrement ad ((cipherBytesToText . convert) ct) cs-    ad = AssocData $ convert ("" :: ByteString)+    ad = AssocData . bsToSB' $ ""
src/Crypto/Noise/Internal/SymmetricHandshakeState.hs view
@@ -2,7 +2,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Internal.SymmetricHandshakeState--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX 
src/Crypto/Noise/Types.hs view
@@ -1,7 +1,7 @@ ---------------------------------------------------------------- -- | -- Module      : Crypto.Noise.Types--- Maintainer  : John Galt <centromere@users.noreply.github.com>+-- Maintainer  : John Galt <jgalt@centromere.net> -- Stability   : experimental -- Portability : POSIX @@ -10,7 +10,34 @@     ScrubbedBytes,     -- * Functions     convert,-    append+    append,+    concatSB,+    bsToSB,+    bsToSB',+    sbToBS,+    sbToBS',+    sbEq   ) where -import Data.ByteArray (ScrubbedBytes, convert, append)+import Data.ByteArray (ScrubbedBytes, concat, convert, append, eq)+import qualified Data.ByteString as BS (ByteString)+import qualified Data.ByteString.Lazy as BL (ByteString, toStrict, fromStrict)+import Prelude hiding (concat)++concatSB :: [ScrubbedBytes] -> ScrubbedBytes+concatSB = concat++bsToSB :: BL.ByteString -> ScrubbedBytes+bsToSB = convert . BL.toStrict++bsToSB' :: BS.ByteString -> ScrubbedBytes+bsToSB' = convert++sbToBS :: ScrubbedBytes -> BL.ByteString+sbToBS = BL.fromStrict . convert++sbToBS' :: ScrubbedBytes -> BS.ByteString+sbToBS' = convert++sbEq :: ScrubbedBytes -> ScrubbedBytes -> Bool+sbEq = eq
tests/Handshake.hs view
@@ -17,18 +17,17 @@ import Crypto.Noise.Types  import Data.ByteString (ByteString)-import qualified Data.ByteArray as BA (concat)  sampleHSPT :: Plaintext-sampleHSPT = Plaintext $ convert ("cacophony" :: ByteString)+sampleHSPT = Plaintext . bsToSB' $ "cacophony"  makeHSN :: ByteString -> ScrubbedBytes-makeHSN hs = BA.concat [convert hs, u, a, u, b, u, c]+makeHSN hs = concatSB [convert hs, u, a, u, b, u, c]   where     a = curveName  (Proxy :: Proxy Curve25519)     b = cipherName (Proxy :: Proxy ChaChaPoly1305)     c = hashName   (Proxy :: Proxy SHA256)-    u = convert    ("_" :: ByteString)+    u = bsToSB' "_"  -------------------------------------------------------------------------------- -- Noise_NN@@ -765,6 +764,131 @@     encrypt cs p = fst $ encryptPayload p cs     decrypt cs ct = fst $ decryptPayload ct cs +--------------------------------------------------------------------------------+-- Noise_N++hsnN :: ScrubbedBytes+hsnN = makeHSN "Noise_N"++doN :: Plaintext -> Property+doN pt = ioProperty $ do+  bobStaticKey@(_, bobStaticPK) <- curveGenKey :: IO (KeyPair Curve25519)++  let aliceN = handshakeState+               hsnN+               Nothing+               Nothing+               (Just bobStaticPK)+               Nothing+               (Just noiseNI0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++      bobN = handshakeState+             hsnN+             (Just bobStaticKey)+             Nothing+             Nothing+             Nothing+             (Just noiseNR0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++  (aliceToBob1, csAlice1, csAlice2) <- writeHandshakeMsgFinal aliceN noiseNI1 sampleHSPT+  let (hsptFromBob1, csBob1, csBob2) = readHandshakeMsgFinal bobN aliceToBob1 noiseNR1++  return $ conjoin+    [ (decrypt csBob1 . encrypt csAlice1) pt === pt+    , (decrypt csBob2 . encrypt csAlice2) pt === pt+    , (decrypt csAlice1 . encrypt csBob1) pt === pt+    , (decrypt csAlice2 . encrypt csBob2) pt === pt+    , hsptFromBob1 === sampleHSPT+    ]++  where+    encrypt cs p = fst $ encryptPayload p cs+    decrypt cs ct = fst $ decryptPayload ct cs++--------------------------------------------------------------------------------+-- Noise_K++hsnK :: ScrubbedBytes+hsnK = makeHSN "Noise_K"++doK :: Plaintext -> Property+doK pt = ioProperty $ do+  aliceStaticKey@(_, aliceStaticPK) <- curveGenKey :: IO (KeyPair Curve25519)+  bobStaticKey@(_, bobStaticPK) <- curveGenKey :: IO (KeyPair Curve25519)++  let aliceK = handshakeState+               hsnK+               (Just aliceStaticKey)+               Nothing+               (Just bobStaticPK)+               Nothing+               (Just noiseKI0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++      bobK = handshakeState+             hsnK+             (Just bobStaticKey)+             Nothing+             (Just aliceStaticPK)+             Nothing+             (Just noiseKR0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++  (aliceToBob1, csAlice1, csAlice2) <- writeHandshakeMsgFinal aliceK noiseKI1 sampleHSPT+  let (hsptFromBob1, csBob1, csBob2) = readHandshakeMsgFinal bobK aliceToBob1 noiseKR1++  return $ conjoin+    [ (decrypt csBob1 . encrypt csAlice1) pt === pt+    , (decrypt csBob2 . encrypt csAlice2) pt === pt+    , (decrypt csAlice1 . encrypt csBob1) pt === pt+    , (decrypt csAlice2 . encrypt csBob2) pt === pt+    , hsptFromBob1 === sampleHSPT+    ]++  where+    encrypt cs p = fst $ encryptPayload p cs+    decrypt cs ct = fst $ decryptPayload ct cs++--------------------------------------------------------------------------------+-- Noise_X++hsnX :: ScrubbedBytes+hsnX = makeHSN "Noise_X"++doX :: Plaintext -> Property+doX pt = ioProperty $ do+  aliceStaticKey <- curveGenKey :: IO (KeyPair Curve25519)+  bobStaticKey@(_, bobStaticPK) <- curveGenKey :: IO (KeyPair Curve25519)++  let aliceX = handshakeState+               hsnX+               (Just aliceStaticKey)+               Nothing+               (Just bobStaticPK)+               Nothing+               (Just noiseXI0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++      bobX = handshakeState+             hsnX+             (Just bobStaticKey)+             Nothing+             Nothing+             Nothing+             (Just noiseXR0) :: HandshakeState ChaChaPoly1305 Curve25519 SHA256++  (aliceToBob1, csAlice1, csAlice2) <- writeHandshakeMsgFinal aliceX noiseXI1 sampleHSPT+  let (hsptFromBob1, csBob1, csBob2) = readHandshakeMsgFinal bobX aliceToBob1 noiseXR1++  return $ conjoin+    [ (decrypt csBob1 . encrypt csAlice1) pt === pt+    , (decrypt csBob2 . encrypt csAlice2) pt === pt+    , (decrypt csAlice1 . encrypt csBob1) pt === pt+    , (decrypt csAlice2 . encrypt csBob2) pt === pt+    , hsptFromBob1 === sampleHSPT+    ]++  where+    encrypt cs p = fst $ encryptPayload p cs+    decrypt cs ct = fst $ decryptPayload ct cs+ tests :: TestTree tests = testGroup "Handshakes"   [ testProperty "Noise_NN" $ property doNN@@ -782,4 +906,8 @@   , testProperty "Noise_XE" $ property doXE   , testProperty "Noise_IE" $ property doIE   , testProperty "Noise_XX" $ property doXX+  , testProperty "Noise_IX" $ property doIX+  , testProperty "Noise_N"  $ property doN+  , testProperty "Noise_K"  $ property doK+  , testProperty "Noise_X"  $ property doX   ]
tests/Instances.hs view
@@ -2,22 +2,23 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module Instances where -import Control.Monad (liftM, replicateM)-import qualified Data.ByteArray as BA-import qualified Data.ByteString as BS+import Control.Monad   (liftM, replicateM)+import Data.ByteString (pack) import Test.QuickCheck  import Crypto.Noise.Cipher import Crypto.Noise.Internal.CipherState+import Crypto.Noise.Types (ScrubbedBytes, bsToSB', sbEq,+                           sbToBS')  instance Eq Plaintext where-  (Plaintext pt1) == (Plaintext pt2) = pt1 `BA.eq` pt2+  (Plaintext pt1) == (Plaintext pt2) = pt1 `sbEq` pt2  instance Show Plaintext where-  show (Plaintext pt) = show (BA.convert pt :: BS.ByteString)+  show (Plaintext pt) = show . sbToBS' $ pt  instance Show AssocData where-  show (AssocData ad) = show (BA.convert ad :: BS.ByteString)+  show (AssocData ad) = show . sbToBS' $ ad  instance Show (SymmetricKey a) where   show _ = "<symmetric key>"@@ -27,8 +28,8 @@  deriving instance Show (CipherState a) -instance Arbitrary BA.ScrubbedBytes where-  arbitrary = BA.convert `liftM` BS.pack <$> arbitrary+instance Arbitrary ScrubbedBytes where+  arbitrary = bsToSB' `liftM` pack <$> arbitrary  instance Arbitrary Plaintext where   arbitrary = Plaintext `liftM` arbitrary@@ -38,5 +39,5 @@  instance Cipher c => Arbitrary (CipherState c) where   arbitrary = do-    a <- (BA.convert . BS.pack) <$> replicateM 32 arbitrary+    a <- (bsToSB' . pack) <$> replicateM 32 arbitrary     return $ CipherState (cipherBytesToSym a) cipherZeroNonce
tests/SymmetricHandshakeState.hs view
@@ -6,8 +6,6 @@  import Control.Monad.State (runState, state) -import Data.ByteString (ByteString)- import Crypto.Noise.Cipher import Crypto.Noise.Cipher.ChaChaPoly1305 import Crypto.Noise.Hash.SHA256@@ -15,7 +13,7 @@ import Crypto.Noise.Types  shs :: SymmetricHandshakeState ChaChaPoly1305 SHA256-shs = symmetricHandshake $ convert ("handshake name" :: ByteString)+shs = symmetricHandshake $ bsToSB' "handshake name"  roundTripProp :: Plaintext -> Property roundTripProp pt = (decrypt . encrypt) pt === pt