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
|
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Network.TLS.KeySchedule
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
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
----------------------------------------------------------------
-- | @HKDF-Extract@ function. Returns the pseudorandom key (PRK) from salt and
-- input keying material (IKM).
hkdfExtract :: Hash -> ByteString -> ByteString -> ByteString
hkdfExtract SHA1 salt ikm = convert (extract salt ikm :: PRK H.SHA1)
hkdfExtract SHA256 salt ikm = convert (extract salt ikm :: PRK H.SHA256)
hkdfExtract SHA384 salt ikm = convert (extract salt ikm :: PRK H.SHA384)
hkdfExtract SHA512 salt ikm = convert (extract salt ikm :: PRK H.SHA512)
hkdfExtract _ _ _ = error "hkdfExtract: unsupported hash"
----------------------------------------------------------------
deriveSecret :: Hash -> ByteString -> ByteString -> ByteString -> ByteString
deriveSecret h secret label hashedMsgs =
hkdfExpandLabel h secret label hashedMsgs outlen
where
outlen = hashDigestSize h
----------------------------------------------------------------
-- | @HKDF-Expand-Label@ function. Returns output keying material of the
-- specified length from the PRK, customized for a TLS label and context.
hkdfExpandLabel :: Hash
-> ByteString
-> ByteString
-> ByteString
-> Int
-> ByteString
hkdfExpandLabel h secret label ctx outlen = expand' h secret hkdfLabel outlen
where
hkdfLabel = runPut $ do
putWord16 $ fromIntegral outlen
putOpaque8 ("tls13 " `BS.append` label)
putOpaque8 ctx
expand' :: Hash -> ByteString -> ByteString -> Int -> ByteString
expand' SHA1 secret label len = expand (extractSkip secret :: PRK H.SHA1) label len
expand' SHA256 secret label len = expand (extractSkip secret :: PRK H.SHA256) label len
expand' SHA384 secret label len = expand (extractSkip secret :: PRK H.SHA384) label len
expand' SHA512 secret label len = expand (extractSkip secret :: PRK H.SHA512) label len
expand' _ _ _ _ = error "expand'"
----------------------------------------------------------------
|