]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Kdf/CryptHkdf.c
CryptoPkg/BaseCryptLib: Wrap OpenSSL HKDF algorithm
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Kdf / CryptHkdf.c
1 /** @file
2 HMAC-SHA256 KDF Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2018 - 2019, 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] Key Pointer to the user-supplied key.
17 @param[in] KeySize Key size in bytes.
18 @param[in] Salt Pointer to the salt(non-secret) value.
19 @param[in] SaltSize Salt size in bytes.
20 @param[in] Info Pointer to the application specific info.
21 @param[in] InfoSize Info size in bytes.
22 @param[Out] Out Pointer to buffer to receive hkdf value.
23 @param[in] OutSize Size of hkdf bytes to generate.
24
25 @retval TRUE Hkdf generated successfully.
26 @retval FALSE Hkdf generation failed.
27
28 **/
29 BOOLEAN
30 EFIAPI
31 HkdfSha256ExtractAndExpand (
32 IN CONST UINT8 *Key,
33 IN UINTN KeySize,
34 IN CONST UINT8 *Salt,
35 IN UINTN SaltSize,
36 IN CONST UINT8 *Info,
37 IN UINTN InfoSize,
38 OUT UINT8 *Out,
39 IN UINTN OutSize
40 )
41 {
42 EVP_PKEY_CTX *pHkdfCtx;
43 BOOLEAN Result;
44
45 if (Key == NULL || Salt == NULL || Info == NULL || Out == NULL ||
46 KeySize > INT_MAX || SaltSize > INT_MAX || InfoSize > INT_MAX || OutSize > INT_MAX ) {
47 return FALSE;
48 }
49
50 pHkdfCtx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
51 if (pHkdfCtx == NULL) {
52 return FALSE;
53 }
54
55 Result = EVP_PKEY_derive_init(pHkdfCtx) > 0;
56 if (Result) {
57 Result = EVP_PKEY_CTX_set_hkdf_md(pHkdfCtx, EVP_sha256()) > 0;
58 }
59 if (Result) {
60 Result = EVP_PKEY_CTX_set1_hkdf_salt(pHkdfCtx, Salt, (UINT32)SaltSize) > 0;
61 }
62 if (Result) {
63 Result = EVP_PKEY_CTX_set1_hkdf_key(pHkdfCtx, Key, (UINT32)KeySize) > 0;
64 }
65 if (Result) {
66 Result = EVP_PKEY_CTX_add1_hkdf_info(pHkdfCtx, Info, (UINT32)InfoSize) > 0;
67 }
68 if (Result) {
69 Result = EVP_PKEY_derive(pHkdfCtx, Out, &OutSize) > 0;
70 }
71
72 EVP_PKEY_CTX_free(pHkdfCtx);
73 pHkdfCtx = NULL;
74 return Result;
75 }