]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c
ffaf5fb131ac49b855dd23a151b4a07ff265fdb9
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Kdf / CryptHkdf.c
1 /** @file
2 HMAC-SHA256 KDF Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2018 - 2022, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Library/BaseCryptLib.h>
10 #include <openssl/evp.h>
11 #include <openssl/kdf.h>
12
13 /**
14 Derive HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
15
16 @param[in] Md Message Digest.
17 @param[in] Key Pointer to the user-supplied key.
18 @param[in] KeySize Key size in bytes.
19 @param[in] Salt Pointer to the salt(non-secret) value.
20 @param[in] SaltSize Salt size in bytes.
21 @param[in] Info Pointer to the application specific info.
22 @param[in] InfoSize Info size in bytes.
23 @param[out] Out Pointer to buffer to receive hkdf value.
24 @param[in] OutSize Size of hkdf bytes to generate.
25
26 @retval TRUE Hkdf generated successfully.
27 @retval FALSE Hkdf generation failed.
28
29 **/
30 BOOLEAN
31 HkdfMdExtractAndExpand (
32 IN CONST EVP_MD *Md,
33 IN CONST UINT8 *Key,
34 IN UINTN KeySize,
35 IN CONST UINT8 *Salt,
36 IN UINTN SaltSize,
37 IN CONST UINT8 *Info,
38 IN UINTN InfoSize,
39 OUT UINT8 *Out,
40 IN UINTN OutSize
41 )
42 {
43 EVP_PKEY_CTX *pHkdfCtx;
44 BOOLEAN Result;
45
46 if ((Key == NULL) || (Salt == NULL) || (Info == NULL) || (Out == NULL) ||
47 (KeySize > INT_MAX) || (SaltSize > INT_MAX) || (InfoSize > INT_MAX) || (OutSize > INT_MAX))
48 {
49 return FALSE;
50 }
51
52 pHkdfCtx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL);
53 if (pHkdfCtx == NULL) {
54 return FALSE;
55 }
56
57 Result = EVP_PKEY_derive_init (pHkdfCtx) > 0;
58 if (Result) {
59 Result = EVP_PKEY_CTX_set_hkdf_md (pHkdfCtx, Md) > 0;
60 }
61
62 if (Result) {
63 Result = EVP_PKEY_CTX_set1_hkdf_salt (pHkdfCtx, Salt, (UINT32)SaltSize) > 0;
64 }
65
66 if (Result) {
67 Result = EVP_PKEY_CTX_set1_hkdf_key (pHkdfCtx, Key, (UINT32)KeySize) > 0;
68 }
69
70 if (Result) {
71 Result = EVP_PKEY_CTX_add1_hkdf_info (pHkdfCtx, Info, (UINT32)InfoSize) > 0;
72 }
73
74 if (Result) {
75 Result = EVP_PKEY_derive (pHkdfCtx, Out, &OutSize) > 0;
76 }
77
78 EVP_PKEY_CTX_free (pHkdfCtx);
79 pHkdfCtx = NULL;
80 return Result;
81 }
82
83 /**
84 Derive HMAC-based Extract key Derivation Function (HKDF).
85
86 @param[in] Md message digest.
87 @param[in] Key Pointer to the user-supplied key.
88 @param[in] KeySize key size in bytes.
89 @param[in] Salt Pointer to the salt(non-secret) value.
90 @param[in] SaltSize salt size in bytes.
91 @param[out] PrkOut Pointer to buffer to receive hkdf value.
92 @param[in] PrkOutSize size of hkdf bytes to generate.
93
94 @retval true Hkdf generated successfully.
95 @retval false Hkdf generation failed.
96
97 **/
98 BOOLEAN
99 HkdfMdExtract (
100 IN CONST EVP_MD *Md,
101 IN CONST UINT8 *Key,
102 IN UINTN KeySize,
103 IN CONST UINT8 *Salt,
104 IN UINTN SaltSize,
105 OUT UINT8 *PrkOut,
106 UINTN PrkOutSize
107 )
108 {
109 EVP_PKEY_CTX *pHkdfCtx;
110 BOOLEAN Result;
111
112 if ((Key == NULL) || (Salt == NULL) || (PrkOut == NULL) ||
113 (KeySize > INT_MAX) || (SaltSize > INT_MAX) ||
114 (PrkOutSize > INT_MAX))
115 {
116 return FALSE;
117 }
118
119 pHkdfCtx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL);
120 if (pHkdfCtx == NULL) {
121 return FALSE;
122 }
123
124 Result = EVP_PKEY_derive_init (pHkdfCtx) > 0;
125 if (Result) {
126 Result = EVP_PKEY_CTX_set_hkdf_md (pHkdfCtx, Md) > 0;
127 }
128
129 if (Result) {
130 Result =
131 EVP_PKEY_CTX_hkdf_mode (
132 pHkdfCtx,
133 EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY
134 ) > 0;
135 }
136
137 if (Result) {
138 Result = EVP_PKEY_CTX_set1_hkdf_salt (
139 pHkdfCtx,
140 Salt,
141 (uint32_t)SaltSize
142 ) > 0;
143 }
144
145 if (Result) {
146 Result = EVP_PKEY_CTX_set1_hkdf_key (
147 pHkdfCtx,
148 Key,
149 (uint32_t)KeySize
150 ) > 0;
151 }
152
153 if (Result) {
154 Result = EVP_PKEY_derive (pHkdfCtx, PrkOut, &PrkOutSize) > 0;
155 }
156
157 EVP_PKEY_CTX_free (pHkdfCtx);
158 pHkdfCtx = NULL;
159 return Result;
160 }
161
162 /**
163 Derive SHA256 HMAC-based Expand Key Derivation Function (HKDF).
164
165 @param[in] Md Message Digest.
166 @param[in] Prk Pointer to the user-supplied key.
167 @param[in] PrkSize Key size in bytes.
168 @param[in] Info Pointer to the application specific info.
169 @param[in] InfoSize Info size in bytes.
170 @param[out] Out Pointer to buffer to receive hkdf value.
171 @param[in] OutSize Size of hkdf bytes to generate.
172
173 @retval TRUE Hkdf generated successfully.
174 @retval FALSE Hkdf generation failed.
175
176 **/
177 BOOLEAN
178 HkdfMdExpand (
179 IN CONST EVP_MD *Md,
180 IN CONST UINT8 *Prk,
181 IN UINTN PrkSize,
182 IN CONST UINT8 *Info,
183 IN UINTN InfoSize,
184 OUT UINT8 *Out,
185 IN UINTN OutSize
186 )
187 {
188 EVP_PKEY_CTX *pHkdfCtx;
189 BOOLEAN Result;
190
191 if ((Prk == NULL) || (Info == NULL) || (Out == NULL) ||
192 (PrkSize > INT_MAX) || (InfoSize > INT_MAX) || (OutSize > INT_MAX))
193 {
194 return FALSE;
195 }
196
197 pHkdfCtx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL);
198 if (pHkdfCtx == NULL) {
199 return FALSE;
200 }
201
202 Result = EVP_PKEY_derive_init (pHkdfCtx) > 0;
203 if (Result) {
204 Result = EVP_PKEY_CTX_set_hkdf_md (pHkdfCtx, Md) > 0;
205 }
206
207 if (Result) {
208 Result = EVP_PKEY_CTX_hkdf_mode (pHkdfCtx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) > 0;
209 }
210
211 if (Result) {
212 Result = EVP_PKEY_CTX_set1_hkdf_key (pHkdfCtx, Prk, (UINT32)PrkSize) > 0;
213 }
214
215 if (Result) {
216 Result = EVP_PKEY_CTX_add1_hkdf_info (pHkdfCtx, Info, (UINT32)InfoSize) > 0;
217 }
218
219 if (Result) {
220 Result = EVP_PKEY_derive (pHkdfCtx, Out, &OutSize) > 0;
221 }
222
223 EVP_PKEY_CTX_free (pHkdfCtx);
224 pHkdfCtx = NULL;
225 return Result;
226 }
227
228 /**
229 Derive HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
230
231 @param[in] Key Pointer to the user-supplied key.
232 @param[in] KeySize Key size in bytes.
233 @param[in] Salt Pointer to the salt(non-secret) value.
234 @param[in] SaltSize Salt size in bytes.
235 @param[in] Info Pointer to the application specific info.
236 @param[in] InfoSize Info size in bytes.
237 @param[out] Out Pointer to buffer to receive hkdf value.
238 @param[in] OutSize Size of hkdf bytes to generate.
239
240 @retval TRUE Hkdf generated successfully.
241 @retval FALSE Hkdf generation failed.
242
243 **/
244 BOOLEAN
245 EFIAPI
246 HkdfSha256ExtractAndExpand (
247 IN CONST UINT8 *Key,
248 IN UINTN KeySize,
249 IN CONST UINT8 *Salt,
250 IN UINTN SaltSize,
251 IN CONST UINT8 *Info,
252 IN UINTN InfoSize,
253 OUT UINT8 *Out,
254 IN UINTN OutSize
255 )
256 {
257 return HkdfMdExtractAndExpand (EVP_sha256 (), Key, KeySize, Salt, SaltSize, Info, InfoSize, Out, OutSize);
258 }
259
260 /**
261 Derive SHA256 HMAC-based Extract key Derivation Function (HKDF).
262
263 @param[in] Key Pointer to the user-supplied key.
264 @param[in] KeySize key size in bytes.
265 @param[in] Salt Pointer to the salt(non-secret) value.
266 @param[in] SaltSize salt size in bytes.
267 @param[out] PrkOut Pointer to buffer to receive hkdf value.
268 @param[in] PrkOutSize size of hkdf bytes to generate.
269
270 @retval true Hkdf generated successfully.
271 @retval false Hkdf generation failed.
272
273 **/
274 BOOLEAN
275 EFIAPI
276 HkdfSha256Extract (
277 IN CONST UINT8 *Key,
278 IN UINTN KeySize,
279 IN CONST UINT8 *Salt,
280 IN UINTN SaltSize,
281 OUT UINT8 *PrkOut,
282 UINTN PrkOutSize
283 )
284 {
285 return HkdfMdExtract (
286 EVP_sha256 (),
287 Key,
288 KeySize,
289 Salt,
290 SaltSize,
291 PrkOut,
292 PrkOutSize
293 );
294 }
295
296 /**
297 Derive SHA256 HMAC-based Expand Key Derivation Function (HKDF).
298
299 @param[in] Prk Pointer to the user-supplied key.
300 @param[in] PrkSize Key size in bytes.
301 @param[in] Info Pointer to the application specific info.
302 @param[in] InfoSize Info size in bytes.
303 @param[out] Out Pointer to buffer to receive hkdf value.
304 @param[in] OutSize Size of hkdf bytes to generate.
305
306 @retval TRUE Hkdf generated successfully.
307 @retval FALSE Hkdf generation failed.
308
309 **/
310 BOOLEAN
311 EFIAPI
312 HkdfSha256Expand (
313 IN CONST UINT8 *Prk,
314 IN UINTN PrkSize,
315 IN CONST UINT8 *Info,
316 IN UINTN InfoSize,
317 OUT UINT8 *Out,
318 IN UINTN OutSize
319 )
320 {
321 return HkdfMdExpand (EVP_sha256 (), Prk, PrkSize, Info, InfoSize, Out, OutSize);
322 }
323
324 /**
325 Derive SHA384 HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
326
327 @param[in] Key Pointer to the user-supplied key.
328 @param[in] KeySize Key size in bytes.
329 @param[in] Salt Pointer to the salt(non-secret) value.
330 @param[in] SaltSize Salt size in bytes.
331 @param[in] Info Pointer to the application specific info.
332 @param[in] InfoSize Info size in bytes.
333 @param[out] Out Pointer to buffer to receive hkdf value.
334 @param[in] OutSize Size of hkdf bytes to generate.
335
336 @retval TRUE Hkdf generated successfully.
337 @retval FALSE Hkdf generation failed.
338
339 **/
340 BOOLEAN
341 EFIAPI
342 HkdfSha384ExtractAndExpand (
343 IN CONST UINT8 *Key,
344 IN UINTN KeySize,
345 IN CONST UINT8 *Salt,
346 IN UINTN SaltSize,
347 IN CONST UINT8 *Info,
348 IN UINTN InfoSize,
349 OUT UINT8 *Out,
350 IN UINTN OutSize
351 )
352 {
353 return HkdfMdExtractAndExpand (EVP_sha384 (), Key, KeySize, Salt, SaltSize, Info, InfoSize, Out, OutSize);
354 }
355
356 /**
357 Derive SHA384 HMAC-based Extract key Derivation Function (HKDF).
358
359 @param[in] Key Pointer to the user-supplied key.
360 @param[in] KeySize key size in bytes.
361 @param[in] Salt Pointer to the salt(non-secret) value.
362 @param[in] SaltSize salt size in bytes.
363 @param[out] PrkOut Pointer to buffer to receive hkdf value.
364 @param[in] PrkOutSize size of hkdf bytes to generate.
365
366 @retval true Hkdf generated successfully.
367 @retval false Hkdf generation failed.
368
369 **/
370 BOOLEAN
371 EFIAPI
372 HkdfSha384Extract (
373 IN CONST UINT8 *Key,
374 IN UINTN KeySize,
375 IN CONST UINT8 *Salt,
376 IN UINTN SaltSize,
377 OUT UINT8 *PrkOut,
378 UINTN PrkOutSize
379 )
380 {
381 return HkdfMdExtract (
382 EVP_sha384 (),
383 Key,
384 KeySize,
385 Salt,
386 SaltSize,
387 PrkOut,
388 PrkOutSize
389 );
390 }
391
392 /**
393 Derive SHA384 HMAC-based Expand Key Derivation Function (HKDF).
394
395 @param[in] Prk Pointer to the user-supplied key.
396 @param[in] PrkSize Key size in bytes.
397 @param[in] Info Pointer to the application specific info.
398 @param[in] InfoSize Info size in bytes.
399 @param[out] Out Pointer to buffer to receive hkdf value.
400 @param[in] OutSize Size of hkdf bytes to generate.
401
402 @retval TRUE Hkdf generated successfully.
403 @retval FALSE Hkdf generation failed.
404
405 **/
406 BOOLEAN
407 EFIAPI
408 HkdfSha384Expand (
409 IN CONST UINT8 *Prk,
410 IN UINTN PrkSize,
411 IN CONST UINT8 *Info,
412 IN UINTN InfoSize,
413 OUT UINT8 *Out,
414 IN UINTN OutSize
415 )
416 {
417 return HkdfMdExpand (EVP_sha384 (), Prk, PrkSize, Info, InfoSize, Out, OutSize);
418 }