File: Cipher.hs

package info (click to toggle)
haskell-tls 2.1.8-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,056 kB
  • sloc: haskell: 15,695; makefile: 3
file content (119 lines) | stat: -rw-r--r-- 3,518 bytes parent folder | download
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Network.TLS.Types.Cipher where

import Crypto.Cipher.Types (AuthTag)
import Data.IORef
import GHC.Generics
import System.IO.Unsafe (unsafePerformIO)
import Text.Printf

import Network.TLS.Crypto (Hash (..))
import Network.TLS.Imports
import Network.TLS.Types.Version

----------------------------------------------------------------

-- | Cipher identification
type CipherID = Word16

newtype CipherId = CipherId {fromCipherId :: Word16}
    deriving (Eq, Ord, Enum, Num, Integral, Real, Read, Generic)

instance Show CipherId where
    show (CipherId 0x00FF) = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"
    show (CipherId n) = case find eqID dict of
        Just c -> cipherName c
        Nothing -> printf "0x%04X" n
      where
        eqID c = cipherID c == n
        dict = unsafePerformIO $ readIORef globalCipherDict

-- "ciphersuite" is designed extensible.
-- So, it's not available from internal modules.
-- This is a compromise to gule "ciphersuite" to Show CipherID.

{-# NOINLINE globalCipherDict #-}
globalCipherDict :: IORef [Cipher]
globalCipherDict = unsafePerformIO $ newIORef []

----------------------------------------------------------------

-- | Cipher algorithm
data Cipher = Cipher
    { cipherID :: CipherID
    , cipherName :: String
    , cipherHash :: Hash
    , cipherBulk :: Bulk
    , cipherKeyExchange :: CipherKeyExchangeType
    , cipherMinVer :: Maybe Version
    , cipherPRFHash :: Maybe Hash
    }

instance Show Cipher where
    show c = cipherName c

instance Eq Cipher where
    (==) c1 c2 = cipherID c1 == cipherID c2

----------------------------------------------------------------

data CipherKeyExchangeType
    = CipherKeyExchange_RSA
    | CipherKeyExchange_DH_Anon
    | CipherKeyExchange_DHE_RSA
    | CipherKeyExchange_ECDHE_RSA
    | CipherKeyExchange_DHE_DSA
    | CipherKeyExchange_DH_DSA
    | CipherKeyExchange_DH_RSA
    | CipherKeyExchange_ECDH_ECDSA
    | CipherKeyExchange_ECDH_RSA
    | CipherKeyExchange_ECDHE_ECDSA
    | CipherKeyExchange_TLS13 -- not expressed in cipher suite
    deriving (Show, Eq)

----------------------------------------------------------------

data Bulk = Bulk
    { bulkName :: String
    , bulkKeySize :: Int
    , bulkIVSize :: Int
    , bulkExplicitIV :: Int -- Explicit size for IV for AEAD Cipher, 0 otherwise
    , bulkAuthTagLen :: Int -- Authentication tag length in bytes for AEAD Cipher, 0 otherwise
    , bulkBlockSize :: Int
    , bulkF :: BulkFunctions
    }

instance Show Bulk where
    show bulk = bulkName bulk
instance Eq Bulk where
    b1 == b2 =
        and
            [ bulkName b1 == bulkName b2
            , bulkKeySize b1 == bulkKeySize b2
            , bulkIVSize b1 == bulkIVSize b2
            , bulkBlockSize b1 == bulkBlockSize b2
            ]

----------------------------------------------------------------

data BulkFunctions
    = BulkBlockF (BulkDirection -> BulkKey -> BulkBlock)
    | BulkStreamF (BulkDirection -> BulkKey -> BulkStream)
    | BulkAeadF (BulkDirection -> BulkKey -> BulkAEAD)

data BulkDirection = BulkEncrypt | BulkDecrypt
    deriving (Show, Eq)

type BulkBlock = BulkIV -> ByteString -> (ByteString, BulkIV)

type BulkKey = ByteString
type BulkIV = ByteString
type BulkNonce = ByteString
type BulkAdditionalData = ByteString

newtype BulkStream = BulkStream (ByteString -> (ByteString, BulkStream))

type BulkAEAD =
    BulkNonce -> ByteString -> BulkAdditionalData -> (ByteString, AuthTag)