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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
-- Copyright 2018 Google LLC
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may not
-- use this file except in compliance with the License. You may obtain a copy of
-- the License at
--
-- https://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-- License for the specific language governing permissions and limitations under
-- the License.
{-|
Module: Codec.Crypto.HKDF
Description: Hash-based key derivation
Copyright: 2018 Google LLC
License: Apache License, version 2.0
The hash-based key derivation function (HKDF), as specified in
[RFC 5869](https://tools.ietf.org/html/rfc5869).
-}
module Codec.Crypto.HKDF
( -- * Computing keys
hkdf, HKDFParams(..)
, extract, ExtractParams(..)
, expand, ExpandParams(..)
-- * Cryptographic hash algorithms
, Algorithm
, sha1
-- ** SHA-2 family
-- | The SHA-2 family of hash functions is defined in
-- [FIPS 180-4](https://csrc.nist.gov/publications/detail/fips/180/4/final).
, sha224, sha256, sha384, sha512
-- * Error handling
, Error
-- * Legacy functions
, md5
) where
import Control.Monad ((>=>))
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (runExceptT)
import Data.ByteString (ByteString)
import Foreign (allocaArray)
import Foreign.Marshal.Unsafe (unsafeLocalState)
import BTLS.BoringSSL.Digest (evpMaxMDSize)
import BTLS.BoringSSL.HKDF
import BTLS.Buffer (onBufferOfMaxSize', packCUStringLen)
import BTLS.Result (Error, check)
import BTLS.Types (Algorithm(Algorithm))
import Data.Digest (md5, sha1, sha224, sha256, sha384, sha512)
-- | Computes an HKDF. It is defined as the composition of 'extract' and
-- 'expand' but may be faster than calling the two functions individually.
hkdf :: HKDFParams -> ByteString -> Either [Error] ByteString
hkdf (HKDFParams md salt info outLen) =
extract (ExtractParams md salt) >=> expand (ExpandParams md info outLen)
data HKDFParams = HKDFParams
{ algorithm :: Algorithm
, salt :: ByteString
, associatedData :: ByteString
, secretLen :: Int
} deriving (Eq, Show)
-- | Computes an HKDF pseudorandom key (PRK).
extract :: ExtractParams -> ByteString -> Either [Error] ByteString
extract (ExtractParams (Algorithm md) salt) secret =
unsafeLocalState $
onBufferOfMaxSize' evpMaxMDSize $ \pOutKey pOutLen ->
check $ hkdfExtract pOutKey pOutLen md secret salt
data ExtractParams = ExtractParams
{ extractAlgorithm :: Algorithm
, extractSalt :: ByteString
} deriving (Eq, Show)
-- | Computes HKDF output key material (OKM).
expand :: ExpandParams -> ByteString -> Either [Error] ByteString
expand (ExpandParams (Algorithm md) info outLen) secret =
unsafeLocalState $
allocaArray outLen $ \pOutKey -> runExceptT $ do
check $ hkdfExpand pOutKey outLen md secret info
lift $ packCUStringLen (pOutKey, outLen)
data ExpandParams = ExpandParams
{ expandAlgorithm :: Algorithm
, expandAssociatedData :: ByteString
, expandSecretLen :: Int
} deriving (Eq, Show)
|