tls-2.1.12: Benchmarks/Benchmarks.hs
{-# LANGUAGE BangPatterns #-}
module Main where
import Certificate
import Control.Concurrent.Chan
import Data.Default (def)
import Data.IORef
import Data.X509
import Data.X509.Validation
import Test.Tasty.Bench
import Network.TLS
import Network.TLS.Extra.Cipher
import Session
import Run
import PubKey
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
blockCipher :: Cipher
blockCipher =
Cipher
{ cipherID = 0xff12
, cipherName = "rsa-id-const"
, cipherBulk =
Bulk
{ bulkName = "id"
, bulkKeySize = 16
, bulkIVSize = 16
, bulkExplicitIV = 0
, bulkAuthTagLen = 0
, bulkBlockSize = 16
, bulkF = BulkBlockF $ \_ _ _ m -> (m, B.empty)
}
, cipherHash = MD5
, cipherPRFHash = Nothing
, cipherKeyExchange = CipherKeyExchange_RSA
, cipherMinVer = Nothing
}
getParams :: Version -> Cipher -> (ClientParams, ServerParams)
getParams connectVer cipher = (cParams, sParams)
where
sParams =
def
{ serverSupported = supported
, serverShared =
def
{ sharedCredentials =
Credentials
[(CertificateChain [simpleX509 $ PubKeyRSA pubKey], PrivKeyRSA privKey)]
}
}
cParams =
(defaultParamsClient "" B.empty)
{ clientSupported = supported
, clientShared =
def
{ sharedValidationCache =
ValidationCache
{ cacheAdd = \_ _ _ -> return ()
, cacheQuery = \_ _ _ -> return ValidationCachePass
}
}
}
supported =
def
{ supportedCiphers = [cipher]
, supportedVersions = [connectVer]
, supportedGroups = [X25519, FFDHE2048]
}
(pubKey, privKey) = getGlobalRSAPair
runTLSPipe
:: (ClientParams, ServerParams)
-> (Context -> Chan b -> IO ())
-> (Chan a -> Context -> IO ())
-> a
-> IO b
runTLSPipe params tlsServer tlsClient d = do
withDataPipe params tlsServer tlsClient $ \(writeStart, readResult) -> do
writeStart d
readResult
runTLSPipeSimple
:: (ClientParams, ServerParams) -> B.ByteString -> IO B.ByteString
runTLSPipeSimple params = runTLSPipe params tlsServer tlsClient
where
tlsServer ctx queue = do
handshake ctx
d <- recvData ctx
writeChan queue d
bye ctx
tlsClient queue ctx = do
handshake ctx
d <- readChan queue
sendData ctx (L.fromChunks [d])
byeBye ctx
benchConnection
:: (ClientParams, ServerParams) -> B.ByteString -> String -> Benchmark
benchConnection params !d name = bench name . nfIO $ runTLSPipeSimple params d
benchResumption
:: (ClientParams, ServerParams) -> B.ByteString -> String -> Benchmark
benchResumption params !d name = env initializeSession runResumption
where
initializeSession = do
sessionRefs <- twoSessionRefs
let sessionManagers = twoSessionManagers sessionRefs
params1 = setPairParamsSessionManagers sessionManagers params
_ <- runTLSPipeSimple params1 d
Just sessionParams <- readClientSessionRef sessionRefs
let params2 = setPairParamsSessionResuming sessionParams params1
newIORef params2
runResumption paramsRef = bench name . nfIO $ do
params2 <- readIORef paramsRef
runTLSPipeSimple params2 d
benchResumption13
:: (ClientParams, ServerParams) -> B.ByteString -> String -> Benchmark
benchResumption13 params !d name = env initializeSession runResumption
where
initializeSession = do
sessionRefs <- twoSessionRefs
let sessionManagers = twoSessionManagers sessionRefs
params1 = setPairParamsSessionManagers sessionManagers params
_ <- runTLSPipeSimple params1 d
newIORef (params1, sessionRefs)
-- with TLS13 the sessionId is constantly changing so we must update
-- our parameters at each iteration unfortunately
runResumption paramsRef = bench name . nfIO $ do
(params1, sessionRefs) <- readIORef paramsRef
Just sessionParams <- readClientSessionRef sessionRefs
let params2 = setPairParamsSessionResuming sessionParams params1
runTLSPipeSimple params2 d
benchCiphers :: String -> Version -> B.ByteString -> [Cipher] -> Benchmark
benchCiphers name connectVer d = bgroup name . map doBench
where
doBench cipher =
benchResumption13 (getParams connectVer cipher) d (cipherName cipher)
main :: IO ()
main =
defaultMain
[ bgroup
"connection"
-- not sure the number actually make sense for anything. improve ..
[ benchConnection (getParams TLS12 blockCipher) small "TLS12-256 bytes"
]
, bgroup
"resumption"
[ benchResumption (getParams TLS12 blockCipher) small "TLS12-256 bytes"
]
, -- Here we try to measure TLS12 and TLS13 performance with AEAD ciphers.
-- Resumption and a larger message can be a demonstration of the symmetric
-- crypto but for TLS13 this does not work so well because of dhe_psk.
benchCiphers
"TLS12"
TLS12
large
[ cipher_DHE_RSA_WITH_AES_128_GCM_SHA256
, cipher_DHE_RSA_WITH_AES_256_GCM_SHA384
, cipher_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
, cipher_ECDHE_RSA_WITH_AES_128_GCM_SHA256
, cipher_ECDHE_RSA_WITH_AES_256_GCM_SHA384
, cipher_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
]
, benchCiphers
"TLS13"
TLS13
large
[ cipher13_AES_128_GCM_SHA256
, cipher13_AES_256_GCM_SHA384
, cipher13_CHACHA20_POLY1305_SHA256
, cipher13_AES_128_CCM_SHA256
, cipher13_AES_128_CCM_8_SHA256
]
]
where
small = B.replicate 256 0
large = B.replicate 102400 0