{-# LANGUAGE OverloadedStrings #-}
module Network.TLS.KeySchedule
( hkdfExtract
, hkdfExpandLabel
, deriveSecret
) where
import qualified Crypto.Hash as H
import Crypto.KDF.HKDF
import Data.ByteArray (convert)
import qualified Data.ByteString as BS
import Network.TLS.Crypto
import Network.TLS.Wire
import Network.TLS.Imports
hkdfExtract :: Hash -> ByteString -> ByteString -> ByteString
Hash
SHA1 ByteString
salt ByteString
ikm = PRK SHA1 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert (ByteString -> ByteString -> PRK SHA1
forall a salt ikm.
(HashAlgorithm a, ByteArrayAccess salt, ByteArrayAccess ikm) =>
salt -> ikm -> PRK a
extract ByteString
salt ByteString
ikm :: PRK H.SHA1)
hkdfExtract Hash
SHA256 ByteString
salt ByteString
ikm = PRK SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert (ByteString -> ByteString -> PRK SHA256
forall a salt ikm.
(HashAlgorithm a, ByteArrayAccess salt, ByteArrayAccess ikm) =>
salt -> ikm -> PRK a
extract ByteString
salt ByteString
ikm :: PRK H.SHA256)
hkdfExtract Hash
SHA384 ByteString
salt ByteString
ikm = PRK SHA384 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert (ByteString -> ByteString -> PRK SHA384
forall a salt ikm.
(HashAlgorithm a, ByteArrayAccess salt, ByteArrayAccess ikm) =>
salt -> ikm -> PRK a
extract ByteString
salt ByteString
ikm :: PRK H.SHA384)
hkdfExtract Hash
SHA512 ByteString
salt ByteString
ikm = PRK SHA512 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert (ByteString -> ByteString -> PRK SHA512
forall a salt ikm.
(HashAlgorithm a, ByteArrayAccess salt, ByteArrayAccess ikm) =>
salt -> ikm -> PRK a
extract ByteString
salt ByteString
ikm :: PRK H.SHA512)
hkdfExtract Hash
_ ByteString
_ ByteString
_ = [Char] -> ByteString
forall a. HasCallStack => [Char] -> a
error [Char]
"hkdfExtract: unsupported hash"
deriveSecret :: Hash -> ByteString -> ByteString -> ByteString -> ByteString
deriveSecret :: Hash -> ByteString -> ByteString -> ByteString -> ByteString
deriveSecret Hash
h ByteString
secret ByteString
label ByteString
hashedMsgs =
Hash -> ByteString -> ByteString -> ByteString -> Int -> ByteString
hkdfExpandLabel Hash
h ByteString
secret ByteString
label ByteString
hashedMsgs Int
outlen
where
outlen :: Int
outlen = Hash -> Int
hashDigestSize Hash
h
hkdfExpandLabel :: Hash
-> ByteString
-> ByteString
-> ByteString
-> Int
-> ByteString
hkdfExpandLabel :: Hash -> ByteString -> ByteString -> ByteString -> Int -> ByteString
hkdfExpandLabel Hash
h ByteString
secret ByteString
label ByteString
ctx Int
outlen = Hash -> ByteString -> ByteString -> Int -> ByteString
expand' Hash
h ByteString
secret ByteString
hkdfLabel Int
outlen
where
hkdfLabel :: ByteString
hkdfLabel = Put -> ByteString
runPut (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ do
Word16 -> Put
putWord16 (Word16 -> Put) -> Word16 -> Put
forall a b. (a -> b) -> a -> b
$ Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
outlen
ByteString -> Put
putOpaque8 (ByteString
"tls13 " ByteString -> ByteString -> ByteString
`BS.append` ByteString
label)
ByteString -> Put
putOpaque8 ByteString
ctx
expand' :: Hash -> ByteString -> ByteString -> Int -> ByteString
expand' :: Hash -> ByteString -> ByteString -> Int -> ByteString
expand' Hash
SHA1 ByteString
secret ByteString
label Int
len = PRK SHA1 -> ByteString -> Int -> ByteString
forall a info out.
(HashAlgorithm a, ByteArrayAccess info, ByteArray out) =>
PRK a -> info -> Int -> out
expand (ByteString -> PRK SHA1
forall ikm a. ByteArrayAccess ikm => ikm -> PRK a
extractSkip ByteString
secret :: PRK H.SHA1) ByteString
label Int
len
expand' Hash
SHA256 ByteString
secret ByteString
label Int
len = PRK SHA256 -> ByteString -> Int -> ByteString
forall a info out.
(HashAlgorithm a, ByteArrayAccess info, ByteArray out) =>
PRK a -> info -> Int -> out
expand (ByteString -> PRK SHA256
forall ikm a. ByteArrayAccess ikm => ikm -> PRK a
extractSkip ByteString
secret :: PRK H.SHA256) ByteString
label Int
len
expand' Hash
SHA384 ByteString
secret ByteString
label Int
len = PRK SHA384 -> ByteString -> Int -> ByteString
forall a info out.
(HashAlgorithm a, ByteArrayAccess info, ByteArray out) =>
PRK a -> info -> Int -> out
expand (ByteString -> PRK SHA384
forall ikm a. ByteArrayAccess ikm => ikm -> PRK a
extractSkip ByteString
secret :: PRK H.SHA384) ByteString
label Int
len
expand' Hash
SHA512 ByteString
secret ByteString
label Int
len = PRK SHA512 -> ByteString -> Int -> ByteString
forall a info out.
(HashAlgorithm a, ByteArrayAccess info, ByteArray out) =>
PRK a -> info -> Int -> out
expand (ByteString -> PRK SHA512
forall ikm a. ByteArrayAccess ikm => ikm -> PRK a
extractSkip ByteString
secret :: PRK H.SHA512) ByteString
label Int
len
expand' Hash
_ ByteString
_ ByteString
_ Int
_ = [Char] -> ByteString
forall a. HasCallStack => [Char] -> a
error [Char]
"expand'"