1 /*
2 * Copyright (c) 2020-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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21
22 #ifdef HKS_SUPPORT_KDF_C
23
24 #include "hks_mbedtls_kdf.h"
25
26 #include <mbedtls/hkdf.h>
27 #include <mbedtls/md.h>
28 #include <mbedtls/pkcs5.h>
29 #include <securec.h>
30
31 #include "hks_log.h"
32 #include "hks_mbedtls_common.h"
33 #include "hks_template.h"
34 #include "hks_type_inner.h"
35
36 #ifdef _CUT_AUTHENTICATE
37 #undef HKS_SUPPORT_KDF_PBKDF2
38 #endif
39
40 #ifdef HKS_SUPPORT_KDF_PBKDF2
DeriveKeyPbkdf2(const struct HksBlob * mainKey,const struct HksKeyDerivationParam * derParam,const mbedtls_md_info_t * info,struct HksBlob * derivedKey)41 static int32_t DeriveKeyPbkdf2(const struct HksBlob *mainKey, const struct HksKeyDerivationParam *derParam,
42 const mbedtls_md_info_t *info, struct HksBlob *derivedKey)
43 {
44 mbedtls_md_context_t ctx;
45 (void)memset_s(&ctx, sizeof(mbedtls_md_context_t), 0, sizeof(mbedtls_md_context_t));
46 mbedtls_md_init(&ctx);
47
48 int32_t ret;
49 do {
50 ret = mbedtls_md_setup(&ctx, info, 1); /* 1 for using HMAC */
51 if (ret != HKS_MBEDTLS_SUCCESS) {
52 HKS_LOG_E("Mbedtls md setup failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
53 break;
54 }
55
56 ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, mainKey->data, mainKey->size, derParam->salt.data,
57 derParam->salt.size, derParam->iterations, derivedKey->size, derivedKey->data);
58 if (ret != HKS_MBEDTLS_SUCCESS) {
59 HKS_LOG_E("Mbedtls pbkdf2 failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
60 (void)memset_s(derivedKey->data, derivedKey->size, 0, derivedKey->size);
61 }
62 } while (0);
63
64 mbedtls_md_free(&ctx);
65 return ret;
66 }
67 #endif /* HKS_SUPPORT_KDF_PBKDF2 */
68
69 #ifdef HKS_SUPPORT_KDF_HKDF
DeriveKeyHkdf(const struct HksBlob * mainKey,const struct HksKeyDerivationParam * derParam,const mbedtls_md_info_t * info,struct HksBlob * derivedKey)70 static int32_t DeriveKeyHkdf(const struct HksBlob *mainKey, const struct HksKeyDerivationParam *derParam,
71 const mbedtls_md_info_t *info, struct HksBlob *derivedKey)
72 {
73 int32_t ret = mbedtls_hkdf(info, derParam->salt.data, derParam->salt.size, mainKey->data, mainKey->size,
74 derParam->info.data, derParam->info.size, derivedKey->data, derivedKey->size);
75 if (ret != HKS_MBEDTLS_SUCCESS) {
76 HKS_LOG_E("Mbedtls hkdf failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
77 (void)memset_s(derivedKey->data, derivedKey->size, 0, derivedKey->size);
78 }
79
80 return ret;
81 }
82 #endif /* HKS_SUPPORT_KDF_HKDF */
83
HksMbedtlsDeriveKey(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)84 int32_t HksMbedtlsDeriveKey(const struct HksBlob *mainKey,
85 const struct HksKeySpec *derivationSpec, struct HksBlob *derivedKey)
86 {
87 const struct HksKeyDerivationParam *derParam = (struct HksKeyDerivationParam *)(derivationSpec->algParam);
88
89 uint32_t mbedtlsAlg;
90 int32_t ret = HksToMbedtlsDigestAlg(derParam->digestAlg, &mbedtlsAlg);
91 HKS_IF_NOT_SUCC_RETURN(ret, ret)
92
93 const mbedtls_md_info_t *info = mbedtls_md_info_from_type((mbedtls_md_type_t)mbedtlsAlg);
94 HKS_IF_NULL_LOGE_RETURN(info, HKS_ERROR_CRYPTO_ENGINE_ERROR,
95 "Mbedtls get md info failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret)
96
97 switch (derivationSpec->algType) {
98 #ifdef HKS_SUPPORT_KDF_PBKDF2
99 case HKS_ALG_PBKDF2:
100 return DeriveKeyPbkdf2(mainKey, derParam, info, derivedKey);
101 #endif
102 #ifdef HKS_SUPPORT_KDF_HKDF
103 case HKS_ALG_HKDF:
104 return DeriveKeyHkdf(mainKey, derParam, info, derivedKey);
105 #endif
106 default:
107 HKS_LOG_E("Unsupport derive key alg! mode = 0x%" LOG_PUBLIC "X", derivationSpec->algType);
108 return HKS_ERROR_INVALID_ARGUMENT;
109 }
110 }
111 #endif /* HKS_SUPPORT_KDF_C */
112