From 0ed87caa3481cbb6f8c2e809e5ec7df6f6245406 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Fri, 23 Mar 2018 18:34:42 -0400 Subject: Data.Digest: Reify hash algorithms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate the functional interface for hashing. Hashing now occurs exclusively through the `hash` function, which accepts a `Data.Digest.Algorithm`. This makes btls somewhat less extensible, but it’s the most elegant way to support HMACs. --- btls.cabal | 6 ++---- src/Data/Digest.hs | 47 ++++++++++++++++++++++++++++++++++++++++-- src/Data/Digest/Internal.hsc | 12 +++++------ src/Data/Digest/Md5.hs | 12 ----------- src/Data/Digest/Sha1.hs | 12 ----------- src/Data/Digest/Sha2.hs | 30 --------------------------- tests/Data/Digest/Md5Tests.hs | 6 +++--- tests/Data/Digest/Sha1Tests.hs | 6 +++--- tests/Data/Digest/Sha2Tests.hs | 12 +++++------ tests/Data/DigestTests.hs | 18 ++++++++++++++++ tests/Tests.hs | 13 ++---------- 11 files changed, 85 insertions(+), 89 deletions(-) delete mode 100644 src/Data/Digest/Md5.hs delete mode 100644 src/Data/Digest/Sha1.hs delete mode 100644 src/Data/Digest/Sha2.hs create mode 100644 tests/Data/DigestTests.hs diff --git a/btls.cabal b/btls.cabal index 9844a5a..63af3db 100644 --- a/btls.cabal +++ b/btls.cabal @@ -33,9 +33,6 @@ library -Wno-safe -Wno-unsafe -optl-Wl,-z,relro -optl-Wl,-z,now -optl-Wl,-s exposed-modules: Data.Digest - , Data.Digest.Md5 - , Data.Digest.Sha1 - , Data.Digest.Sha2 other-modules: Data.Digest.Internal -- Use special names for the BoringSSL libraries to avoid accidentally pulling -- in OpenSSL. @@ -57,7 +54,8 @@ test-suite tests -Wno-safe -Wno-unsafe -optl-Wl,-z,relro -optl-Wl,-z,now -optl-Wl,-s main-is: Tests.hs - other-modules: Data.Digest.HashTests + other-modules: Data.DigestTests + , Data.Digest.HashTests , Data.Digest.Md5Tests , Data.Digest.Sha1Tests , Data.Digest.Sha2Tests diff --git a/src/Data/Digest.hs b/src/Data/Digest.hs index 6eebd27..7e88c49 100644 --- a/src/Data/Digest.hs +++ b/src/Data/Digest.hs @@ -1,5 +1,48 @@ module Data.Digest - ( Digest + ( Algorithm + , Digest + , hash + , md5 + , sha1 + , sha224 + , sha256 + , sha384 + , sha512 ) where -import Data.Digest.Internal (Digest) \ No newline at end of file +import Foreign (Ptr) + +import Data.Digest.Internal + + +foreign import ccall "openssl/digest.h EVP_md5" evpMd5 :: Ptr EvpMd + +md5 :: Algorithm +md5 = Algorithm evpMd5 + + +foreign import ccall "openssl/digest.h EVP_sha1" evpSha1 :: Ptr EvpMd + +sha1 :: Algorithm +sha1 = Algorithm evpSha1 + + +foreign import ccall "openssl/digest.h EVP_sha224" evpSha224 :: Ptr EvpMd + +foreign import ccall "openssl/digest.h EVP_sha256" evpSha256 :: Ptr EvpMd + +foreign import ccall "openssl/digest.h EVP_sha384" evpSha384 :: Ptr EvpMd + +foreign import ccall "openssl/digest.h EVP_sha512" evpSha512 :: Ptr EvpMd + +sha224 :: Algorithm +sha224 = Algorithm evpSha224 + +sha256 :: Algorithm +sha256 = Algorithm evpSha256 + +sha384 :: Algorithm +sha384 = Algorithm evpSha384 + +sha512 :: Algorithm +sha512 = Algorithm evpSha512 diff --git a/src/Data/Digest/Internal.hsc b/src/Data/Digest/Internal.hsc index 73edbd9..a7f19d7 100644 --- a/src/Data/Digest/Internal.hsc +++ b/src/Data/Digest/Internal.hsc @@ -31,9 +31,6 @@ data Engine -- | The BoringSSL @EVP_MD@ type, representing a hash algorithm. data EvpMd --- | A convenience alias for @Ptr EvpMd@. -type Algo = Ptr EvpMd - -- | The BoringSSL @EVP_MD_CTX@ type, representing the state of a pending -- hashing operation. data EvpMdCtx @@ -103,6 +100,9 @@ foreign import ccall "&btlsFinalizeEvpMdCtx" -- Finally, we're ready to actually implement the hashing interface. +-- | A cryptographic hash function. +newtype Algorithm = Algorithm (Ptr EvpMd) + -- | The result of a hash operation. newtype Digest = Digest ByteString @@ -115,9 +115,9 @@ instance Show Digest where hexit (b `shiftR` 4 .&. 0x0f) : hexit (b .&. 0x0f) : xs hexit = intToDigit . fromIntegral :: Word8 -> Char --- | Hashes according to the given 'Algo'. -hash :: Algo -> LazyByteString -> Digest -hash md bytes = +-- | Hashes according to the given 'Algorithm'. +hash :: Algorithm -> LazyByteString -> Digest +hash (Algorithm md) bytes = unsafeLocalState $ do ctxFP <- mallocEvpMdCtx withForeignPtr ctxFP $ \ctx -> do diff --git a/src/Data/Digest/Md5.hs b/src/Data/Digest/Md5.hs deleted file mode 100644 index 194633b..0000000 --- a/src/Data/Digest/Md5.hs +++ /dev/null @@ -1,12 +0,0 @@ -module Data.Digest.Md5 - ( md5 - ) where - -import Data.ByteString.Lazy (ByteString) - -import Data.Digest.Internal - -foreign import ccall "openssl/digest.h EVP_md5" evpMd5 :: Algo - -md5 :: ByteString -> Digest -md5 = hash evpMd5 diff --git a/src/Data/Digest/Sha1.hs b/src/Data/Digest/Sha1.hs deleted file mode 100644 index 16101b0..0000000 --- a/src/Data/Digest/Sha1.hs +++ /dev/null @@ -1,12 +0,0 @@ -module Data.Digest.Sha1 - ( sha1 - ) where - -import Data.ByteString.Lazy (ByteString) - -import Data.Digest.Internal - -foreign import ccall "openssl/digest.h EVP_sha1" evpSha1 :: Algo - -sha1 :: ByteString -> Digest -sha1 = hash evpSha1 diff --git a/src/Data/Digest/Sha2.hs b/src/Data/Digest/Sha2.hs deleted file mode 100644 index 965686c..0000000 --- a/src/Data/Digest/Sha2.hs +++ /dev/null @@ -1,30 +0,0 @@ -module Data.Digest.Sha2 - ( sha224 - , sha256 - , sha384 - , sha512 - ) where - -import Data.ByteString.Lazy (ByteString) - -import Data.Digest.Internal - -foreign import ccall "openssl/digest.h EVP_sha224" evpSha224 :: Algo - -foreign import ccall "openssl/digest.h EVP_sha256" evpSha256 :: Algo - -foreign import ccall "openssl/digest.h EVP_sha384" evpSha384 :: Algo - -foreign import ccall "openssl/digest.h EVP_sha512" evpSha512 :: Algo - -sha224 :: ByteString -> Digest -sha224 = hash evpSha224 - -sha256 :: ByteString -> Digest -sha256 = hash evpSha256 - -sha384 :: ByteString -> Digest -sha384 = hash evpSha384 - -sha512 :: ByteString -> Digest -sha512 = hash evpSha512 diff --git a/tests/Data/Digest/Md5Tests.hs b/tests/Data/Digest/Md5Tests.hs index f7f62a7..bbc5fba 100644 --- a/tests/Data/Digest/Md5Tests.hs +++ b/tests/Data/Digest/Md5Tests.hs @@ -10,12 +10,12 @@ import Test.Tasty.SmallCheck (testProperty) import Data.Digest.HashTests (tableTestCase, testAgainstCoreutils, testAgainstOpenssl) -import Data.Digest.Md5 +import Data.Digest (hash, md5) tests :: TestTree tests = testGroup - "Data.Digest.Md5" + "MD5" [ testRfcExamples , testGoExamples , testCoreutilsConformance @@ -106,4 +106,4 @@ testOpensslConformance = -- Convenience function. -md5sum = show . md5 . ByteString.Lazy.fromStrict +md5sum = show . hash md5 . ByteString.Lazy.fromStrict diff --git a/tests/Data/Digest/Sha1Tests.hs b/tests/Data/Digest/Sha1Tests.hs index cd1f1c6..63c774d 100644 --- a/tests/Data/Digest/Sha1Tests.hs +++ b/tests/Data/Digest/Sha1Tests.hs @@ -11,12 +11,12 @@ import Test.Tasty.SmallCheck (testProperty) import Data.Digest.HashTests (tableTestCase, testAgainstCoreutils, testAgainstOpenssl) -import Data.Digest.Sha1 +import Data.Digest (hash, sha1) tests :: TestTree tests = testGroup - "Data.Digest.Sha1" + "SHA-1" [ testNistExamples , testGoExamples , testCoreutilsConformance @@ -107,4 +107,4 @@ testOpensslConformance = -- Convenience function. -sha1sum = show . sha1 . ByteString.Lazy.fromStrict +sha1sum = show . hash sha1 . ByteString.Lazy.fromStrict diff --git a/tests/Data/Digest/Sha2Tests.hs b/tests/Data/Digest/Sha2Tests.hs index b1faf27..1df607b 100644 --- a/tests/Data/Digest/Sha2Tests.hs +++ b/tests/Data/Digest/Sha2Tests.hs @@ -11,12 +11,12 @@ import Test.Tasty.SmallCheck (testProperty) import Data.Digest.HashTests (tableTestCase, testAgainstCoreutils, testAgainstOpenssl) -import Data.Digest.Sha2 +import Data.Digest (hash, sha224, sha256, sha384, sha512) tests :: TestTree tests = testGroup - "Data.Digest.Sha2" + "SHA-2" [ testNistExamples , testGoExamples , testCoreutilsConformance @@ -497,10 +497,10 @@ testOpensslConformance = -- Convenience functions. -sha224sum = show . sha224 . ByteString.Lazy.fromStrict +sha224sum = show . hash sha224 . ByteString.Lazy.fromStrict -sha256sum = show . sha256 . ByteString.Lazy.fromStrict +sha256sum = show . hash sha256 . ByteString.Lazy.fromStrict -sha384sum = show . sha384 . ByteString.Lazy.fromStrict +sha384sum = show . hash sha384 . ByteString.Lazy.fromStrict -sha512sum = show . sha512 . ByteString.Lazy.fromStrict +sha512sum = show . hash sha512 . ByteString.Lazy.fromStrict diff --git a/tests/Data/DigestTests.hs b/tests/Data/DigestTests.hs new file mode 100644 index 0000000..e1e67b4 --- /dev/null +++ b/tests/Data/DigestTests.hs @@ -0,0 +1,18 @@ +module Data.DigestTests + ( tests + ) where + +import Test.Tasty (TestTree, testGroup) + +import qualified Data.Digest.Md5Tests +import qualified Data.Digest.Sha1Tests +import qualified Data.Digest.Sha2Tests + +tests :: TestTree +tests = + testGroup + "Data.Digest" + [ Data.Digest.Md5Tests.tests + , Data.Digest.Sha1Tests.tests + , Data.Digest.Sha2Tests.tests + ] diff --git a/tests/Tests.hs b/tests/Tests.hs index caec20a..565ab16 100644 --- a/tests/Tests.hs +++ b/tests/Tests.hs @@ -4,16 +4,7 @@ module Main import Test.Tasty (defaultMain, testGroup) -import qualified Data.Digest.Md5Tests -import qualified Data.Digest.Sha1Tests -import qualified Data.Digest.Sha2Tests +import qualified Data.DigestTests main :: IO () -main = - defaultMain $ - testGroup - "btls" - [ Data.Digest.Md5Tests.tests - , Data.Digest.Sha1Tests.tests - , Data.Digest.Sha2Tests.tests - ] +main = defaultMain $ testGroup "btls" [Data.DigestTests.tests] -- cgit v1.2.3