module Network.TLS.Extra.Cipher (
    -- * cipher suite
    ciphersuite_default,
    ciphersuite_default_det,
    ciphersuite_all,
    ciphersuite_all_det,
    ciphersuite_strong,
    ciphersuite_strong_det,

    -- * individual ciphers
    cipher_ECDHE_RSA_AES128GCM_SHA256,
    cipher_ECDHE_RSA_AES256GCM_SHA384,
    cipher_ECDHE_RSA_CHACHA20POLY1305_SHA256,
    cipher_ECDHE_ECDSA_AES128CCM_SHA256,
    cipher_ECDHE_ECDSA_AES128CCM8_SHA256,
    cipher_ECDHE_ECDSA_AES128GCM_SHA256,
    cipher_ECDHE_ECDSA_AES256CCM_SHA256,
    cipher_ECDHE_ECDSA_AES256CCM8_SHA256,
    cipher_ECDHE_ECDSA_AES256GCM_SHA384,
    cipher_ECDHE_ECDSA_CHACHA20POLY1305_SHA256,
    -- TLS 1.3
    cipher_TLS13_AES128GCM_SHA256,
    cipher_TLS13_AES256GCM_SHA384,
    cipher_TLS13_CHACHA20POLY1305_SHA256,
    cipher_TLS13_AES128CCM_SHA256,
    cipher_TLS13_AES128CCM8_SHA256,
) where

import qualified Data.ByteString as B

import Data.Tuple (swap)
import Network.TLS.Cipher
import Network.TLS.Types (Version (..))

import Crypto.Cipher.AES
import qualified Crypto.Cipher.ChaChaPoly1305 as ChaChaPoly1305
import Crypto.Cipher.Types hiding (Cipher, cipherName)
import Crypto.Error
import qualified Crypto.MAC.Poly1305 as Poly1305
import Crypto.System.CPU

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

aes128ccm :: BulkDirection -> BulkKey -> BulkAEAD
aes128ccm :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128ccm BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M16 CCM_L
CCM_L3
                aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
mode AES128
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )
aes128ccm BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M16 CCM_L
CCM_L3
                aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
mode AES128
ctx BulkAdditionalData
nonce)
             in AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )

aes128ccm8 :: BulkDirection -> BulkKey -> BulkAEAD
aes128ccm8 :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128ccm8 BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M8 CCM_L
CCM_L3
                aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
mode AES128
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
8
        )
aes128ccm8 BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M8 CCM_L
CCM_L3
                aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
mode AES128
ctx BulkAdditionalData
nonce)
             in AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
8
        )

aes128gcm :: BulkDirection -> BulkKey -> BulkAEAD
aes128gcm :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128gcm BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
AEAD_GCM AES128
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )
aes128gcm BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES128
ctx = CryptoFailable AES128 -> AES128
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES128
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES128
cipherInit BulkAdditionalData
key) :: AES128
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let aeadIni :: AEAD AES128
aeadIni = CryptoFailable (AEAD AES128) -> AEAD AES128
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES128 -> BulkAdditionalData -> CryptoFailable (AEAD AES128)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES128 -> iv -> CryptoFailable (AEAD AES128)
aeadInit AEADMode
AEAD_GCM AES128
ctx BulkAdditionalData
nonce)
             in AEAD AES128
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES128
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )

aes256ccm :: BulkDirection -> BulkKey -> BulkAEAD
aes256ccm :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256ccm BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M16 CCM_L
CCM_L3
                aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
mode AES256
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )
aes256ccm BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M16 CCM_L
CCM_L3
                aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
mode AES256
ctx BulkAdditionalData
nonce)
             in AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )

aes256ccm8 :: BulkDirection -> BulkKey -> BulkAEAD
aes256ccm8 :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256ccm8 BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M8 CCM_L
CCM_L3
                aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
mode AES256
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
8
        )
aes256ccm8 BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let mode :: AEADMode
mode = Int -> CCM_M -> CCM_L -> AEADMode
AEAD_CCM (BulkAdditionalData -> Int
B.length BulkAdditionalData
d) CCM_M
CCM_M8 CCM_L
CCM_L3
                aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
mode AES256
ctx BulkAdditionalData
nonce)
             in AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
8
        )

aes256gcm :: BulkDirection -> BulkKey -> BulkAEAD
aes256gcm :: BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256gcm BulkDirection
BulkEncrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
AEAD_GCM AES256
ctx BulkAdditionalData
nonce)
             in (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a, b) -> (b, a)
swap ((AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag))
-> (AuthTag, BulkAdditionalData) -> (BulkAdditionalData, AuthTag)
forall a b. (a -> b) -> a -> b
$ AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (AuthTag, BulkAdditionalData)
forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )
aes256gcm BulkDirection
BulkDecrypt BulkAdditionalData
key =
    let ctx :: AES256
ctx = CryptoFailable AES256 -> AES256
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable AES256
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
forall key. ByteArray key => key -> CryptoFailable AES256
cipherInit BulkAdditionalData
key) :: AES256
     in ( \BulkAdditionalData
nonce BulkAdditionalData
d BulkAdditionalData
ad ->
            let aeadIni :: AEAD AES256
aeadIni = CryptoFailable (AEAD AES256) -> AEAD AES256
forall a. CryptoFailable a -> a
noFail (AEADMode
-> AES256 -> BulkAdditionalData -> CryptoFailable (AEAD AES256)
forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
forall iv.
ByteArrayAccess iv =>
AEADMode -> AES256 -> iv -> CryptoFailable (AEAD AES256)
aeadInit AEADMode
AEAD_GCM AES256
ctx BulkAdditionalData
nonce)
             in AEAD AES256
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD AES256
aeadIni BulkAdditionalData
ad BulkAdditionalData
d Int
16
        )

simpleDecrypt
    :: AEAD cipher -> B.ByteString -> B.ByteString -> Int -> (B.ByteString, AuthTag)
simpleDecrypt :: forall cipher.
AEAD cipher
-> BulkAdditionalData
-> BulkAdditionalData
-> Int
-> (BulkAdditionalData, AuthTag)
simpleDecrypt AEAD cipher
aeadIni BulkAdditionalData
header BulkAdditionalData
input Int
taglen = (BulkAdditionalData
output, AuthTag
tag)
  where
    aead :: AEAD cipher
aead = AEAD cipher -> BulkAdditionalData -> AEAD cipher
forall aad cipher.
ByteArrayAccess aad =>
AEAD cipher -> aad -> AEAD cipher
aeadAppendHeader AEAD cipher
aeadIni BulkAdditionalData
header
    (BulkAdditionalData
output, AEAD cipher
aeadFinal) = AEAD cipher
-> BulkAdditionalData -> (BulkAdditionalData, AEAD cipher)
forall ba cipher.
ByteArray ba =>
AEAD cipher -> ba -> (ba, AEAD cipher)
aeadDecrypt AEAD cipher
aead BulkAdditionalData
input
    tag :: AuthTag
tag = AEAD cipher -> Int -> AuthTag
forall cipher. AEAD cipher -> Int -> AuthTag
aeadFinalize AEAD cipher
aeadFinal Int
taglen

noFail :: CryptoFailable a -> a
noFail :: forall a. CryptoFailable a -> a
noFail = CryptoFailable a -> a
forall a. CryptoFailable a -> a
throwCryptoError

chacha20poly1305 :: BulkDirection -> BulkKey -> BulkAEAD
chacha20poly1305 :: BulkDirection -> BulkAdditionalData -> BulkAEAD
chacha20poly1305 BulkDirection
BulkEncrypt BulkAdditionalData
key BulkAdditionalData
nonce =
    let st :: State
st = CryptoFailable State -> State
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable Nonce
forall iv. ByteArrayAccess iv => iv -> CryptoFailable Nonce
ChaChaPoly1305.nonce12 BulkAdditionalData
nonce CryptoFailable Nonce
-> (Nonce -> CryptoFailable State) -> CryptoFailable State
forall a b.
CryptoFailable a -> (a -> CryptoFailable b) -> CryptoFailable b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= BulkAdditionalData -> Nonce -> CryptoFailable State
forall key.
ByteArrayAccess key =>
key -> Nonce -> CryptoFailable State
ChaChaPoly1305.initialize BulkAdditionalData
key)
     in ( \BulkAdditionalData
input BulkAdditionalData
ad ->
            let st2 :: State
st2 = State -> State
ChaChaPoly1305.finalizeAAD (BulkAdditionalData -> State -> State
forall ba. ByteArrayAccess ba => ba -> State -> State
ChaChaPoly1305.appendAAD BulkAdditionalData
ad State
st)
                (BulkAdditionalData
output, State
st3) = BulkAdditionalData -> State -> (BulkAdditionalData, State)
forall ba. ByteArray ba => ba -> State -> (ba, State)
ChaChaPoly1305.encrypt BulkAdditionalData
input State
st2
                Poly1305.Auth Bytes
tag = State -> Auth
ChaChaPoly1305.finalize State
st3
             in (BulkAdditionalData
output, Bytes -> AuthTag
AuthTag Bytes
tag)
        )
chacha20poly1305 BulkDirection
BulkDecrypt BulkAdditionalData
key BulkAdditionalData
nonce =
    let st :: State
st = CryptoFailable State -> State
forall a. CryptoFailable a -> a
noFail (BulkAdditionalData -> CryptoFailable Nonce
forall iv. ByteArrayAccess iv => iv -> CryptoFailable Nonce
ChaChaPoly1305.nonce12 BulkAdditionalData
nonce CryptoFailable Nonce
-> (Nonce -> CryptoFailable State) -> CryptoFailable State
forall a b.
CryptoFailable a -> (a -> CryptoFailable b) -> CryptoFailable b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= BulkAdditionalData -> Nonce -> CryptoFailable State
forall key.
ByteArrayAccess key =>
key -> Nonce -> CryptoFailable State
ChaChaPoly1305.initialize BulkAdditionalData
key)
     in ( \BulkAdditionalData
input BulkAdditionalData
ad ->
            let st2 :: State
st2 = State -> State
ChaChaPoly1305.finalizeAAD (BulkAdditionalData -> State -> State
forall ba. ByteArrayAccess ba => ba -> State -> State
ChaChaPoly1305.appendAAD BulkAdditionalData
ad State
st)
                (BulkAdditionalData
output, State
st3) = BulkAdditionalData -> State -> (BulkAdditionalData, State)
forall ba. ByteArray ba => ba -> State -> (ba, State)
ChaChaPoly1305.decrypt BulkAdditionalData
input State
st2
                Poly1305.Auth Bytes
tag = State -> Auth
ChaChaPoly1305.finalize State
st3
             in (BulkAdditionalData
output, Bytes -> AuthTag
AuthTag Bytes
tag)
        )

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

data CipherSet
    = SetAead [Cipher] [Cipher] [Cipher] -- gcm, chacha, ccm
    | SetOther [Cipher]

-- Preference between AEAD ciphers having equivalent properties is based on
-- hardware-acceleration support in the crypton implementation.
sortOptimized :: [CipherSet] -> [Cipher]
sortOptimized :: [CipherSet] -> [Cipher]
sortOptimized = (CipherSet -> [Cipher]) -> [CipherSet] -> [Cipher]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CipherSet -> [Cipher]
f
  where
    f :: CipherSet -> [Cipher]
f (SetAead [Cipher]
gcm [Cipher]
chacha [Cipher]
ccm)
        | ProcessorOption
AESNI ProcessorOption -> [ProcessorOption] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [ProcessorOption]
processorOptions = [Cipher]
chacha [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
gcm [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
ccm
        | ProcessorOption
PCLMUL ProcessorOption -> [ProcessorOption] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [ProcessorOption]
processorOptions = [Cipher]
ccm [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
chacha [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
gcm
        | Bool
otherwise = [Cipher]
gcm [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
ccm [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
chacha
    f (SetOther [Cipher]
ciphers) = [Cipher]
ciphers

-- Order which is deterministic but not optimized for the CPU.
sortDeterministic :: [CipherSet] -> [Cipher]
sortDeterministic :: [CipherSet] -> [Cipher]
sortDeterministic = (CipherSet -> [Cipher]) -> [CipherSet] -> [Cipher]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CipherSet -> [Cipher]
f
  where
    f :: CipherSet -> [Cipher]
f (SetAead [Cipher]
gcm [Cipher]
chacha [Cipher]
ccm) = [Cipher]
gcm [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
chacha [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
ccm
    f (SetOther [Cipher]
ciphers) = [Cipher]
ciphers

-- | All AES and ChaCha20-Poly1305 ciphers supported ordered from strong to
-- weak.  This choice of ciphersuites should satisfy most normal needs.  For
-- otherwise strong ciphers we make little distinction between AES128 and
-- AES256, and list each but the weakest of the AES128 ciphers ahead of the
-- corresponding AES256 ciphers.
--
-- AEAD ciphers with equivalent security properties are ordered based on CPU
-- hardware-acceleration support.  If this dynamic runtime behavior is not
-- desired, use 'ciphersuite_default_det' instead.
ciphersuite_default :: [Cipher]
ciphersuite_default :: [Cipher]
ciphersuite_default = [Cipher]
ciphersuite_strong

-- | Same as 'ciphersuite_default', but using deterministic preference not
-- influenced by the CPU.
ciphersuite_default_det :: [Cipher]
ciphersuite_default_det :: [Cipher]
ciphersuite_default_det = [Cipher]
ciphersuite_strong_det

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

-- | The default ciphersuites + some not recommended last resort ciphers.
--
-- AEAD ciphers with equivalent security properties are ordered based on CPU
-- hardware-acceleration support.  If this dynamic runtime behavior is not
-- desired, use 'ciphersuite_all_det' instead.
ciphersuite_all :: [Cipher]
ciphersuite_all :: [Cipher]
ciphersuite_all = [Cipher]
ciphersuite_default [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
complement_all

-- | Same as 'ciphersuite_all', but using deterministic preference not
-- influenced by the CPU.
ciphersuite_all_det :: [Cipher]
ciphersuite_all_det :: [Cipher]
ciphersuite_all_det = [Cipher]
ciphersuite_default_det [Cipher] -> [Cipher] -> [Cipher]
forall a. [a] -> [a] -> [a]
++ [Cipher]
complement_all

complement_all :: [Cipher]
complement_all :: [Cipher]
complement_all =
    [ Cipher
cipher_ECDHE_ECDSA_AES128CCM8_SHA256
    , Cipher
cipher_ECDHE_ECDSA_AES256CCM8_SHA256
    , Cipher
cipher_TLS13_AES128CCM8_SHA256
    ]

-- | The strongest ciphers supported.  For ciphers with PFS, AEAD and SHA2, we
-- list each AES128 variant after the corresponding AES256 and ChaCha20-Poly1305
-- variants.  For weaker constructs, we use just the AES256 form.
--
-- AEAD ciphers with equivalent security properties are ordered based on CPU
-- hardware-acceleration support.  If this dynamic runtime behavior is not
-- desired, use 'ciphersuite_strong_det' instead.
ciphersuite_strong :: [Cipher]
ciphersuite_strong :: [Cipher]
ciphersuite_strong = [CipherSet] -> [Cipher]
sortOptimized [CipherSet]
sets_strong

-- | Same as 'ciphersuite_strong', but using deterministic preference not
-- influenced by the CPU.
ciphersuite_strong_det :: [Cipher]
ciphersuite_strong_det :: [Cipher]
ciphersuite_strong_det = [CipherSet] -> [Cipher]
sortDeterministic [CipherSet]
sets_strong

sets_strong :: [CipherSet]
sets_strong :: [CipherSet]
sets_strong =
    [ -- If we have PFS + AEAD + SHA2, then allow AES128, else just 256
      [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_ECDHE_ECDSA_AES256GCM_SHA384]
        [Cipher
cipher_ECDHE_ECDSA_CHACHA20POLY1305_SHA256]
        [Cipher
cipher_ECDHE_ECDSA_AES256CCM_SHA256]
    , [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_ECDHE_ECDSA_AES128GCM_SHA256]
        []
        [Cipher
cipher_ECDHE_ECDSA_AES128CCM_SHA256]
    , [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_ECDHE_RSA_AES256GCM_SHA384]
        [Cipher
cipher_ECDHE_RSA_CHACHA20POLY1305_SHA256]
        []
    , [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_ECDHE_RSA_AES128GCM_SHA256]
        []
        []
    , -- TLS13 (listed at the end but version is negotiated first)
      [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_TLS13_AES256GCM_SHA384]
        [Cipher
cipher_TLS13_CHACHA20POLY1305_SHA256]
        []
    , [Cipher] -> [Cipher] -> [Cipher] -> CipherSet
SetAead
        [Cipher
cipher_TLS13_AES128GCM_SHA256]
        []
        [Cipher
cipher_TLS13_AES128CCM_SHA256]
    ]

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

bulk_aes128ccm :: Bulk
bulk_aes128ccm :: Bulk
bulk_aes128ccm =
    Bulk
        { bulkName :: String
bulkName = String
"AES128CCM"
        , bulkKeySize :: Int
bulkKeySize = Int
16 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 6655 CCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
16
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128ccm
        }

bulk_aes128ccm8 :: Bulk
bulk_aes128ccm8 :: Bulk
bulk_aes128ccm8 =
    Bulk
        { bulkName :: String
bulkName = String
"AES128CCM8"
        , bulkKeySize :: Int
bulkKeySize = Int
16 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 6655 CCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
8
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128ccm8
        }

bulk_aes128gcm :: Bulk
bulk_aes128gcm :: Bulk
bulk_aes128gcm =
    Bulk
        { bulkName :: String
bulkName = String
"AES128GCM"
        , bulkKeySize :: Int
bulkKeySize = Int
16 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 5288 GCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
16
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes128gcm
        }

bulk_aes256ccm :: Bulk
bulk_aes256ccm :: Bulk
bulk_aes256ccm =
    Bulk
        { bulkName :: String
bulkName = String
"AES256CCM"
        , bulkKeySize :: Int
bulkKeySize = Int
32 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 6655 CCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
16
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256ccm
        }

bulk_aes256ccm8 :: Bulk
bulk_aes256ccm8 :: Bulk
bulk_aes256ccm8 =
    Bulk
        { bulkName :: String
bulkName = String
"AES256CCM8"
        , bulkKeySize :: Int
bulkKeySize = Int
32 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 6655 CCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
8
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256ccm8
        }

bulk_aes256gcm :: Bulk
bulk_aes256gcm :: Bulk
bulk_aes256gcm =
    Bulk
        { bulkName :: String
bulkName = String
"AES256GCM"
        , bulkKeySize :: Int
bulkKeySize = Int
32 -- RFC 5116 Sec 5.1: K_LEN
        , bulkIVSize :: Int
bulkIVSize = Int
4 -- RFC 5288 GCMNonce.salt, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
8
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
16
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
aes256gcm
        }

bulk_chacha20poly1305 :: Bulk
bulk_chacha20poly1305 :: Bulk
bulk_chacha20poly1305 =
    Bulk
        { bulkName :: String
bulkName = String
"CHACHA20POLY1305"
        , bulkKeySize :: Int
bulkKeySize = Int
32
        , bulkIVSize :: Int
bulkIVSize = Int
12 -- RFC 7905 section 2, fixed_iv_length
        , bulkExplicitIV :: Int
bulkExplicitIV = Int
0
        , bulkAuthTagLen :: Int
bulkAuthTagLen = Int
16
        , bulkBlockSize :: Int
bulkBlockSize = Int
0 -- dummy, not used
        , bulkF :: BulkFunctions
bulkF = (BulkDirection -> BulkAdditionalData -> BulkAEAD) -> BulkFunctions
BulkAeadF BulkDirection -> BulkAdditionalData -> BulkAEAD
chacha20poly1305
        }

-- TLS13 bulks are same as TLS12 except they never have explicit IV
bulk_aes128gcm_13 :: Bulk
bulk_aes128gcm_13 :: Bulk
bulk_aes128gcm_13 = Bulk
bulk_aes128gcm{bulkIVSize = 12, bulkExplicitIV = 0}

bulk_aes256gcm_13 :: Bulk
bulk_aes256gcm_13 :: Bulk
bulk_aes256gcm_13 = Bulk
bulk_aes256gcm{bulkIVSize = 12, bulkExplicitIV = 0}

bulk_aes128ccm_13 :: Bulk
bulk_aes128ccm_13 :: Bulk
bulk_aes128ccm_13 = Bulk
bulk_aes128ccm{bulkIVSize = 12, bulkExplicitIV = 0}

bulk_aes128ccm8_13 :: Bulk
bulk_aes128ccm8_13 :: Bulk
bulk_aes128ccm8_13 = Bulk
bulk_aes128ccm8{bulkIVSize = 12, bulkExplicitIV = 0}

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

-- A list of cipher suite is found from:
-- https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4

----------------------------------------------------------------
-- RFC 8446

cipher_TLS13_AES128GCM_SHA256 :: Cipher
cipher_TLS13_AES128GCM_SHA256 :: Cipher
cipher_TLS13_AES128GCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0x1301
        , cipherName :: String
cipherName = String
"TLS_AES_128_GCM_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128gcm_13
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Maybe Hash
forall a. Maybe a
Nothing
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_TLS13
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS13
        }

cipher_TLS13_AES256GCM_SHA384 :: Cipher
cipher_TLS13_AES256GCM_SHA384 :: Cipher
cipher_TLS13_AES256GCM_SHA384 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0x1302
        , cipherName :: String
cipherName = String
"TLS_AES_256_GCM_SHA384"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes256gcm_13
        , cipherHash :: Hash
cipherHash = Hash
SHA384
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Maybe Hash
forall a. Maybe a
Nothing
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_TLS13
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS13
        }

cipher_TLS13_CHACHA20POLY1305_SHA256 :: Cipher
cipher_TLS13_CHACHA20POLY1305_SHA256 :: Cipher
cipher_TLS13_CHACHA20POLY1305_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0x1303
        , cipherName :: String
cipherName = String
"TLS_CHACHA20_POLY1305_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_chacha20poly1305
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Maybe Hash
forall a. Maybe a
Nothing
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_TLS13
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS13
        }

cipher_TLS13_AES128CCM_SHA256 :: Cipher
cipher_TLS13_AES128CCM_SHA256 :: Cipher
cipher_TLS13_AES128CCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0x1304
        , cipherName :: String
cipherName = String
"TLS_AES_128_CCM_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128ccm_13
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Maybe Hash
forall a. Maybe a
Nothing
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_TLS13
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS13
        }

cipher_TLS13_AES128CCM8_SHA256 :: Cipher
cipher_TLS13_AES128CCM8_SHA256 :: Cipher
cipher_TLS13_AES128CCM8_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0x1305
        , cipherName :: String
cipherName = String
"TLS_AES_128_CCM_8_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128ccm8_13
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Maybe Hash
forall a. Maybe a
Nothing
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_TLS13
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS13
        }

----------------------------------------------------------------
-- GCM: RFC 5289

cipher_ECDHE_ECDSA_AES128GCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128GCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128GCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC02B
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128gcm
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 5289
        }

cipher_ECDHE_ECDSA_AES256GCM_SHA384 :: Cipher
cipher_ECDHE_ECDSA_AES256GCM_SHA384 :: Cipher
cipher_ECDHE_ECDSA_AES256GCM_SHA384 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC02C
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes256gcm
        , cipherHash :: Hash
cipherHash = Hash
SHA384
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA384
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 5289
        }

cipher_ECDHE_RSA_AES128GCM_SHA256 :: Cipher
cipher_ECDHE_RSA_AES128GCM_SHA256 :: Cipher
cipher_ECDHE_RSA_AES128GCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC02F
        , cipherName :: String
cipherName = String
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128gcm
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_RSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 5288 Sec 4
        }

cipher_ECDHE_RSA_AES256GCM_SHA384 :: Cipher
cipher_ECDHE_RSA_AES256GCM_SHA384 :: Cipher
cipher_ECDHE_RSA_AES256GCM_SHA384 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC030
        , cipherName :: String
cipherName = String
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes256gcm
        , cipherHash :: Hash
cipherHash = Hash
SHA384
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA384
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_RSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 5289
        }

----------------------------------------------------------------
-- CCM/ECC: RFC 7251

cipher_ECDHE_ECDSA_AES128CCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128CCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128CCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC0AC
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128ccm
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 7251
        }

cipher_ECDHE_ECDSA_AES256CCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES256CCM_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES256CCM_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC0AD
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_256_CCM"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes256ccm
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 7251
        }

cipher_ECDHE_ECDSA_AES128CCM8_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128CCM8_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES128CCM8_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC0AE
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes128ccm8
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 7251
        }

cipher_ECDHE_ECDSA_AES256CCM8_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES256CCM8_SHA256 :: Cipher
cipher_ECDHE_ECDSA_AES256CCM8_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xC0AF
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_aes256ccm8
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12 -- RFC 7251
        }

----------------------------------------------------------------
-- RFC 7905

cipher_ECDHE_RSA_CHACHA20POLY1305_SHA256 :: Cipher
cipher_ECDHE_RSA_CHACHA20POLY1305_SHA256 :: Cipher
cipher_ECDHE_RSA_CHACHA20POLY1305_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xCCA8
        , cipherName :: String
cipherName = String
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_chacha20poly1305
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_RSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12
        }

cipher_ECDHE_ECDSA_CHACHA20POLY1305_SHA256 :: Cipher
cipher_ECDHE_ECDSA_CHACHA20POLY1305_SHA256 :: Cipher
cipher_ECDHE_ECDSA_CHACHA20POLY1305_SHA256 =
    Cipher
        { cipherID :: CipherID
cipherID = CipherID
0xCCA9
        , cipherName :: String
cipherName = String
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
        , cipherBulk :: Bulk
cipherBulk = Bulk
bulk_chacha20poly1305
        , cipherHash :: Hash
cipherHash = Hash
SHA256
        , cipherPRFHash :: Maybe Hash
cipherPRFHash = Hash -> Maybe Hash
forall a. a -> Maybe a
Just Hash
SHA256
        , cipherKeyExchange :: CipherKeyExchangeType
cipherKeyExchange = CipherKeyExchangeType
CipherKeyExchange_ECDHE_ECDSA
        , cipherMinVer :: Maybe Version
cipherMinVer = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
TLS12
        }