1{-# LANGUAGE OverloadedStrings #-} 2-- | 3-- Module : Network.TLS.KeySchedule 4-- License : BSD-style 5-- Maintainer : Vincent Hanquez <vincent@snarc.org> 6-- Stability : experimental 7-- Portability : unknown 8-- 9module Network.TLS.KeySchedule 10 ( hkdfExtract 11 , hkdfExpandLabel 12 , deriveSecret 13 ) where 14 15import qualified Crypto.Hash as H 16import Crypto.KDF.HKDF 17import Data.ByteArray (convert) 18import qualified Data.ByteString as BS 19import Network.TLS.Crypto 20import Network.TLS.Wire 21import Network.TLS.Imports 22 23---------------------------------------------------------------- 24 25hkdfExtract :: Hash -> ByteString -> ByteString -> ByteString 26hkdfExtract SHA1 salt ikm = convert (extract salt ikm :: PRK H.SHA1) 27hkdfExtract SHA256 salt ikm = convert (extract salt ikm :: PRK H.SHA256) 28hkdfExtract SHA384 salt ikm = convert (extract salt ikm :: PRK H.SHA384) 29hkdfExtract SHA512 salt ikm = convert (extract salt ikm :: PRK H.SHA512) 30hkdfExtract _ _ _ = error "hkdfExtract: unsupported hash" 31 32---------------------------------------------------------------- 33 34deriveSecret :: Hash -> ByteString -> ByteString -> ByteString -> ByteString 35deriveSecret h secret label hashedMsgs = 36 hkdfExpandLabel h secret label hashedMsgs outlen 37 where 38 outlen = hashDigestSize h 39 40---------------------------------------------------------------- 41 42hkdfExpandLabel :: Hash 43 -> ByteString 44 -> ByteString 45 -> ByteString 46 -> Int 47 -> ByteString 48hkdfExpandLabel h secret label ctx outlen = expand' h secret hkdfLabel outlen 49 where 50 hkdfLabel = runPut $ do 51 putWord16 $ fromIntegral outlen 52 putOpaque8 ("tls13 " `BS.append` label) 53 putOpaque8 ctx 54 55expand' :: Hash -> ByteString -> ByteString -> Int -> ByteString 56expand' SHA1 secret label len = expand (extractSkip secret :: PRK H.SHA1) label len 57expand' SHA256 secret label len = expand (extractSkip secret :: PRK H.SHA256) label len 58expand' SHA384 secret label len = expand (extractSkip secret :: PRK H.SHA384) label len 59expand' SHA512 secret label len = expand (extractSkip secret :: PRK H.SHA512) label len 60expand' _ _ _ _ = error "expand'" 61 62---------------------------------------------------------------- 63