1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hks_openssl_kdf.h"
17
18 #include <openssl/evp.h>
19 #include <openssl/kdf.h>
20 #include <openssl/ossl_typ.h>
21 #include <stddef.h>
22
23 #include "hks_crypto_hal.h"
24 #include "hks_log.h"
25 #include "hks_openssl_engine.h"
26
GetDeriveDigestType(uint32_t digestAlg)27 static const EVP_MD *GetDeriveDigestType(uint32_t digestAlg)
28 {
29 switch (digestAlg) {
30 case (HKS_DIGEST_SHA256):
31 return EVP_sha256();
32 case (HKS_DIGEST_SHA384):
33 return EVP_sha384();
34 case (HKS_DIGEST_SHA512):
35 return EVP_sha512();
36 default:
37 return NULL;
38 }
39 }
40
HksOpensslPbkdf2(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)41 int32_t HksOpensslPbkdf2(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
42 struct HksBlob *derivedKey)
43 {
44 struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
45 const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
46 if (PKCS5_PBKDF2_HMAC((char *)mainKey->data, mainKey->size, deriveParam->salt.data, deriveParam->salt.size,
47 deriveParam->iterations, md, derivedKey->size, derivedKey->data) != 1) {
48 HKS_LOG_E("derive pbkdf2 key using openssl interface failed");
49 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
50 }
51 return HKS_SUCCESS;
52 }
53
HksOpensslHkdf(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)54 int32_t HksOpensslHkdf(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
55 struct HksBlob *derivedKey)
56 {
57 struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
58 const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
59 EVP_PKEY_CTX *pctx;
60 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
61 int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
62 do {
63 if (EVP_PKEY_derive_init(pctx) <= 0) {
64 HksLogOpensslError();
65 break;
66 }
67 if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
68 HksLogOpensslError();
69 break;
70 }
71 if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, deriveParam->salt.data, deriveParam->salt.size) <= 0) {
72 HksLogOpensslError();
73 break;
74 }
75 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, mainKey->data, mainKey->size) <= 0) {
76 HksLogOpensslError();
77 break;
78 }
79 if (EVP_PKEY_CTX_add1_hkdf_info(pctx, deriveParam->info.data, deriveParam->info.size) <= 0) {
80 HksLogOpensslError();
81 break;
82 }
83 size_t keyLen = derivedKey->size;
84 if (EVP_PKEY_derive(pctx, derivedKey->data, &keyLen) <= 0) {
85 HksLogOpensslError();
86 break;
87 }
88 derivedKey->size = (uint32_t)keyLen;
89 ret = HKS_SUCCESS;
90 } while (0);
91 EVP_PKEY_CTX_free(pctx);
92 return ret;
93 }
94