ReactOS 0.4.17-dev-1005-g171e1de
hkdf.c
Go to the documentation of this file.
1//
2// hkdf.c
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7//
8// This module contains the routines to implement the HKDF
9// function for the TLS protocol 1.3. It is used in
10// the protocol's key derivation function.
11//
12//
13
14#include "precomp.h"
15
21 _In_reads_(cbIkm) PCBYTE pbIkm,
22 SIZE_T cbIkm,
23 _In_reads_opt_(cbSalt) PCBYTE pbSalt,
24 SIZE_T cbSalt )
25{
26 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
27
29
31
32 scError = SymCryptHkdfExtractPrk( macAlgorithm, pbIkm, cbIkm, pbSalt, cbSalt, rbPrk, macAlgorithm->resultSize );
33 if (scError != SYMCRYPT_NO_ERROR)
34 {
35 goto cleanup;
36 }
37
39 if (scError != SYMCRYPT_NO_ERROR)
40 {
41 goto cleanup;
42 }
43
45 SymCryptWipeKnownSize(&rbPrk[0], sizeof(rbPrk));
46
47 return scError;
48}
49
54 _In_reads_(cbIkm) PCBYTE pbIkm,
55 SIZE_T cbIkm,
56 _In_reads_opt_(cbSalt) PCBYTE pbSalt,
57 SIZE_T cbSalt,
58 _Out_writes_(cbPrk) PBYTE pbPrk,
59 SIZE_T cbPrk )
60{
61 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
62
65
66 // Ensure that pbPrk is the correct size
67 if (cbPrk != macAlgorithm->resultSize)
68 {
69 scError = SYMCRYPT_INVALID_ARGUMENT;
70 goto cleanup;
71 }
72
73 // Calculation of PRK = HMAC-Hash(salt, IKM)
74 scError = macAlgorithm->expandKeyFunc( &key, pbSalt, cbSalt );
75 if (scError != SYMCRYPT_NO_ERROR)
76 {
77 goto cleanup;
78 }
79
81 macAlgorithm->appendFunc( &state, pbIkm, cbIkm );
82 macAlgorithm->resultFunc( &state, pbPrk );
83
85 SymCryptWipeKnownSize(&key, sizeof(key));
86
87 return scError;
88}
89
95 _In_reads_(cbPrk) PCBYTE pbPrk,
96 SIZE_T cbPrk )
97{
99
100 pExpandedKey->macAlg = macAlgorithm;
101 return macAlgorithm->expandKeyFunc( &pExpandedKey->macKey, pbPrk, cbPrk );
102}
103
108 _In_reads_opt_(cbInfo) PCBYTE pbInfo,
109 SIZE_T cbInfo,
110 _Out_writes_(cbResult) PBYTE pbResult,
111 SIZE_T cbResult)
112{
113
114 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
115
117
118 PCSYMCRYPT_MAC pMacAlgorithm = pExpandedKey->macAlg;
119
121 BYTE * pbCurr = pbResult;
122
123 SIZE_T cbMacResultSize = pMacAlgorithm->resultSize;
124
125 BYTE cntr = 0x01;
126
127 // Check that cbResult <= 255*HashLen
128 if (cbResult > 0xff * cbMacResultSize)
129 {
130 scError = SYMCRYPT_WRONG_DATA_SIZE;
131 goto cleanup;
132 }
133
134 // In the first iteration T(0) is the empty string
135 // Calculate T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
136 pMacAlgorithm->initFunc( &state, pExpandedKey );
137 pMacAlgorithm->appendFunc( &state, pbInfo, cbInfo );
138 pMacAlgorithm->appendFunc( &state, &cntr, sizeof(cntr) );
139 pMacAlgorithm->resultFunc( &state, rbPartialResult );
140
141 // Store the result in the output buffer
142 memcpy(pbCurr, rbPartialResult, SYMCRYPT_MIN(cbResult, cbMacResultSize));
143 if (cbResult <= cbMacResultSize)
144 {
145 goto cleanup;
146 }
147
148 // Update counters
149 cntr++;
150 pbCurr += cbMacResultSize;
151 cbResult -= cbMacResultSize;
152
153 while( cbResult > 0 )
154 {
155 // Calculate T(i) = HMAC-Hash(PRK, T(i-1) | info | 0xi)
156 pMacAlgorithm->initFunc( &state, pExpandedKey );
157 pMacAlgorithm->appendFunc( &state, rbPartialResult, cbMacResultSize );
158 pMacAlgorithm->appendFunc( &state, pbInfo, cbInfo );
159 pMacAlgorithm->appendFunc( &state, &cntr, sizeof(cntr) );
160 pMacAlgorithm->resultFunc( &state, rbPartialResult );
161
162 // Store the result in the output buffer
163 memcpy(pbCurr, rbPartialResult, SYMCRYPT_MIN(cbResult, cbMacResultSize));
164 if (cbResult <= cbMacResultSize)
165 {
166 goto cleanup;
167 }
168
169 // Update counters
170 cntr++;
171 pbCurr += cbMacResultSize;
172 cbResult -= cbMacResultSize;
173 }
174
175cleanup:
176 SymCryptWipeKnownSize(&rbPartialResult[0], sizeof(rbPartialResult));
177
178 return scError;
179}
180
181//
182// The full HKDF
183//
188 _In_reads_(cbIkm) PCBYTE pbIkm,
189 SIZE_T cbIkm,
190 _In_reads_opt_(cbSalt) PCBYTE pbSalt,
191 SIZE_T cbSalt,
192 _In_reads_opt_(cbInfo) PCBYTE pbInfo,
193 SIZE_T cbInfo,
194 _Out_writes_(cbResult) PBYTE pbResult,
195 SIZE_T cbResult)
196{
197 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
199
200 // Create the expanded key
201 scError = SymCryptHkdfExpandKey(
202 &key,
204 pbIkm,
205 cbIkm,
206 pbSalt,
207 cbSalt );
208 if (scError != SYMCRYPT_NO_ERROR)
209 {
210 goto cleanup;
211 }
212
213 // Derive the key
214 scError = SymCryptHkdfDerive(
215 &key,
216 pbInfo,
217 cbInfo,
218 pbResult,
219 cbResult );
220 if (scError != SYMCRYPT_NO_ERROR)
221 {
222 goto cleanup;
223 }
224
225cleanup:
226 SymCryptWipeKnownSize(&key, sizeof(key));
227
228 return scError;
229}
static int state
Definition: maze.c:121
static void cleanup(void)
Definition: main.c:1335
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
BYTE * PBYTE
Definition: pedump.c:66
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfExpandKey(_Out_ PSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbIkm) PCBYTE pbIkm, SIZE_T cbIkm, _In_reads_opt_(cbSalt) PCBYTE pbSalt, SIZE_T cbSalt)
Definition: hkdf.c:18
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdf(PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbIkm) PCBYTE pbIkm, SIZE_T cbIkm, _In_reads_opt_(cbSalt) PCBYTE pbSalt, SIZE_T cbSalt, _In_reads_opt_(cbInfo) PCBYTE pbInfo, SIZE_T cbInfo, _Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult)
Definition: hkdf.c:186
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfDerive(_In_ PCSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey, _In_reads_opt_(cbInfo) PCBYTE pbInfo, SIZE_T cbInfo, _Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult)
Definition: hkdf.c:106
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfExtractPrk(_In_ PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbIkm) PCBYTE pbIkm, SIZE_T cbIkm, _In_reads_opt_(cbSalt) PCBYTE pbSalt, SIZE_T cbSalt, _Out_writes_(cbPrk) PBYTE pbPrk, SIZE_T cbPrk)
Definition: hkdf.c:52
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfPrkExpandKey(_Out_ PSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbPrk) PCBYTE pbPrk, SIZE_T cbPrk)
Definition: hkdf.c:92
static const BYTE pbResult[]
PSYMCRYPT_MAC_EXPAND_KEY expandKeyFunc
PSYMCRYPT_MAC_RESULT resultFunc
PSYMCRYPT_MAC_APPEND appendFunc
PSYMCRYPT_MAC_INIT initFunc
Definition: copy.c:22
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_ALIGN
#define SYMCRYPT_CALL
#define SYMCRYPT_MIN(_a, _b)
const BYTE * PCBYTE
#define SYMCRYPT_MAC_MAX_RESULT_SIZE
PCSYMCRYPT_MAC macAlgorithm
PCVOID pExpandedKey
ULONG_PTR SIZE_T
Definition: typedefs.h:80
unsigned char BYTE
Definition: xxhash.c:193