diff --git a/CHANGELOG.md b/CHANGELOG.md index 26c53b7..b967519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## 0.9 * Quiet down unused module imports +* Move Curve25519 over to Crypto.Error instead of using Either String. + ## 0.8 * Add support for ChaChaPoly1305 Nonce Increment (John Galt) diff --git a/Crypto/Error/Types.hs b/Crypto/Error/Types.hs index fa07cb7..3163675 100644 --- a/Crypto/Error/Types.hs +++ b/Crypto/Error/Types.hs @@ -33,6 +33,7 @@ data CryptoError = | CryptoError_SecretKeySizeInvalid | CryptoError_SecretKeyStructureInvalid | CryptoError_PublicKeySizeInvalid + | CryptoError_SharedSecretSizeInvalid -- Message authentification error | CryptoError_MacKeyInvalid deriving (Show,Eq,Enum,Data,Typeable) diff --git a/Crypto/PubKey/Curve25519.hs b/Crypto/PubKey/Curve25519.hs index 4d5863c..32163bd 100644 --- a/Crypto/PubKey/Curve25519.hs +++ b/Crypto/PubKey/Curve25519.hs @@ -26,6 +26,7 @@ import Data.Word import Foreign.Ptr import GHC.Ptr +import Crypto.Error import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes, withByteArray) @@ -45,21 +46,21 @@ newtype DhSecret = DhSecret ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | Try to build a public key from a bytearray -publicKey :: ByteArrayAccess bs => bs -> Either String PublicKey +publicKey :: ByteArrayAccess bs => bs -> CryptoFailable PublicKey publicKey bs - | B.length bs == 32 = Right $ PublicKey $ B.copyAndFreeze bs (\_ -> return ()) - | otherwise = Left "invalid public key size" + | B.length bs == 32 = CryptoPassed $ PublicKey $ B.copyAndFreeze bs (\_ -> return ()) + | otherwise = CryptoFailed CryptoError_PublicKeySizeInvalid -- | Try to build a secret key from a bytearray -secretKey :: ByteArrayAccess bs => bs -> Either String SecretKey +secretKey :: ByteArrayAccess bs => bs -> CryptoFailable SecretKey secretKey bs | B.length bs == 32 = unsafeDoIO $ do withByteArray bs $ \inp -> do valid <- isValidPtr inp if valid - then (Right . SecretKey) <$> B.copy bs (\_ -> return ()) - else return $ Left "invalid secret key" - | otherwise = Left "secret key invalid size" + then (CryptoPassed . SecretKey) <$> B.copy bs (\_ -> return ()) + else return $ CryptoFailed CryptoError_SecretKeyStructureInvalid + | otherwise = CryptoFailed CryptoError_SecretKeySizeInvalid where -- e[0] &= 0xf8; -- e[31] &= 0x7f; @@ -80,10 +81,10 @@ secretKey bs {-# NOINLINE secretKey #-} -- | Create a DhSecret from a bytearray object -dhSecret :: ByteArrayAccess b => b -> Either String DhSecret +dhSecret :: ByteArrayAccess b => b -> CryptoFailable DhSecret dhSecret bs - | B.length bs == 32 = Right $ DhSecret $ B.copyAndFreeze bs (\_ -> return ()) - | otherwise = Left "invalid dh secret size" + | B.length bs == 32 = CryptoPassed $ DhSecret $ B.copyAndFreeze bs (\_ -> return ()) + | otherwise = CryptoFailed CryptoError_SharedSecretSizeInvalid -- | Compute the Diffie Hellman secret from a public key and a secret key dh :: PublicKey -> SecretKey -> DhSecret diff --git a/tests/KAT_Curve25519.hs b/tests/KAT_Curve25519.hs index 02a3836..ad368f5 100644 --- a/tests/KAT_Curve25519.hs +++ b/tests/KAT_Curve25519.hs @@ -1,14 +1,15 @@ {-# LANGUAGE OverloadedStrings #-} module KAT_Curve25519 ( tests ) where +import Crypto.Error import qualified Crypto.PubKey.Curve25519 as Curve25519 import Data.ByteArray as B import Imports -alicePrivate = either error id $ Curve25519.secretKey ("\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a" :: ByteString) -alicePublic = either error id $ Curve25519.publicKey ("\x85\x20\xf0\x09\x89\x30\xa7\x54\x74\x8b\x7d\xdc\xb4\x3e\xf7\x5a\x0d\xbf\x3a\x0d\x26\x38\x1a\xf4\xeb\xa4\xa9\x8e\xaa\x9b\x4e\x6a" :: ByteString) -bobPrivate = either error id $ Curve25519.secretKey ("\x5d\xab\x08\x7e\x62\x4a\x8a\x4b\x79\xe1\x7f\x8b\x83\x80\x0e\xe6\x6f\x3b\xb1\x29\x26\x18\xb6\xfd\x1c\x2f\x8b\x27\xff\x88\xe0\xeb" :: ByteString) -bobPublic = either error id $ Curve25519.publicKey ("\xde\x9e\xdb\x7d\x7b\x7d\xc1\xb4\xd3\x5b\x61\xc2\xec\xe4\x35\x37\x3f\x83\x43\xc8\x5b\x78\x67\x4d\xad\xfc\x7e\x14\x6f\x88\x2b\x4f" :: ByteString) +alicePrivate = throwCryptoError $ Curve25519.secretKey ("\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a" :: ByteString) +alicePublic = throwCryptoError $ Curve25519.publicKey ("\x85\x20\xf0\x09\x89\x30\xa7\x54\x74\x8b\x7d\xdc\xb4\x3e\xf7\x5a\x0d\xbf\x3a\x0d\x26\x38\x1a\xf4\xeb\xa4\xa9\x8e\xaa\x9b\x4e\x6a" :: ByteString) +bobPrivate = throwCryptoError $ Curve25519.secretKey ("\x5d\xab\x08\x7e\x62\x4a\x8a\x4b\x79\xe1\x7f\x8b\x83\x80\x0e\xe6\x6f\x3b\xb1\x29\x26\x18\xb6\xfd\x1c\x2f\x8b\x27\xff\x88\xe0\xeb" :: ByteString) +bobPublic = throwCryptoError $ Curve25519.publicKey ("\xde\x9e\xdb\x7d\x7b\x7d\xc1\xb4\xd3\x5b\x61\xc2\xec\xe4\x35\x37\x3f\x83\x43\xc8\x5b\x78\x67\x4d\xad\xfc\x7e\x14\x6f\x88\x2b\x4f" :: ByteString) aliceMultBob = "\x4a\x5d\x9d\x5b\xa4\xce\x2d\xe1\x72\x8e\x3b\xf4\x80\x35\x0f\x25\xe0\x7e\x21\xc9\x47\xd1\x9e\x33\x76\xf0\x9b\x3c\x1e\x16\x17\x42" :: ByteString katTests :: [TestTree]