aboutsummaryrefslogtreecommitdiff
path: root/src/Data/Digest.hs
blob: bc2f944d25e5c79ea82e35d409a75d065daa9828 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
-- Copyright 2017 Google LLC
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may not
-- use this file except in compliance with the License. You may obtain a copy of
-- the License at
--
--     https://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-- License for the specific language governing permissions and limitations under
-- the License.

{-|
  Module: Data.Digest
  Description: Cryptographic hash functions
  Copyright: 2017 Google LLC
  License: Apache License, version 2.0

  Cryptographic hash functions.
-}
module Data.Digest
  ( -- * Computing digests
    Digest(Digest)
  , hash

    -- * Digest algorithms
  , Algorithm

    -- ** SHA-2 family
    -- | The SHA-2 family of hash functions is defined in
    -- [FIPS 180-4](https://csrc.nist.gov/publications/detail/fips/180/4/final).
  , sha224, sha256, sha384, sha512

    -- * Legacy functions
  , md5
  , sha1
  ) where

import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as Lazy (ByteString)
import qualified Data.ByteString.Lazy as ByteString.Lazy
import Foreign.Marshal.Unsafe (unsafeLocalState)

import BTLS.BoringSSL.Base
import BTLS.BoringSSL.Digest
import BTLS.Buffer (onBufferOfMaxSize)
import BTLS.Show (showHex)
import BTLS.Types (Algorithm(Algorithm))

-- | The result of a hash operation. Equality comparisons on this type are
-- variable-time.
--
-- The 'Show' instance for this type displays the digest as a hexadecimal string.
newtype Digest = Digest ByteString
  deriving (Eq, Ord)

instance Show Digest where
  show (Digest d) = showHex d

-- | Message Digest 5, a 128-bit digest defined in
-- [RFC 1321](https://tools.ietf.org/html/rfc1321). This algorithm is
-- cryptographically broken; do not use it except to interface with legacy
-- applications.
md5 :: Algorithm
md5 = Algorithm evpMD5

-- | Secure Hash Algorithm 1, a 160-bit digest defined in
-- [FIPS 180-4](https://csrc.nist.gov/publications/detail/fips/180/4/final).
-- Hashing with this algorithm is cryptographically broken, although
-- constructing HMACs with it is safe.
sha1 :: Algorithm
sha1 = Algorithm evpSHA1

-- | The SHA224 digest, a 224-bit digest and Secure Hash Algorithm 2 family
-- member.
sha224 :: Algorithm
sha224 = Algorithm evpSHA224

-- | The SHA256 digest, a 256-bit digest and Secure Hash Algorithm 2 family
-- member. Prefer this algorithm on 32-bit CPUs; it will run faster than
-- 'sha384' or 'sha512'.
sha256 :: Algorithm
sha256 = Algorithm evpSHA256

-- | The SHA384 digest, a 384-bit digest and Secure Hash Algorithm 2 family
-- member.
sha384 :: Algorithm
sha384 = Algorithm evpSHA384

-- | The SHA512 digest, a 512-bit digest and Secure Hash Algorithm 2 family
-- member. Prefer this algorithm on 64-bit CPUs; it will run faster than
-- 'sha224' or 'sha256'.
sha512 :: Algorithm
sha512 = Algorithm evpSHA512

-- | Hashes according to the given 'Algorithm'.
hash :: Algorithm -> Lazy.ByteString -> Digest
hash (Algorithm md) bytes =
  unsafeLocalState $ do
    ctx <- mallocEVPMDCtx
    evpDigestInitEx ctx md noEngine
    mapM_ (evpDigestUpdate ctx) (ByteString.Lazy.toChunks bytes)
    Digest <$> onBufferOfMaxSize evpMaxMDSize (evpDigestFinalEx ctx)