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_mem.h"
26 #include "hks_openssl_engine.h"
27 #include "hks_openssl_hash.h"
28 #include "hks_template.h"
29 #include "securec.h"
30
31 #ifdef HKS_SUPPORT_KDF_SM3
32 #define HKS_DIGEST_SM3_LEN 32
33 #define HKS_BITS_PER_INT 32
34 #define HKS_BYTE_PER_INT 4
35 #define HKS_START_NUM 1
36 #endif
GetDeriveDigestType(uint32_t digestAlg)37 static const EVP_MD *GetDeriveDigestType(uint32_t digestAlg)
38 {
39 switch (digestAlg) {
40 case (HKS_DIGEST_SHA256):
41 return EVP_sha256();
42 case (HKS_DIGEST_SHA384):
43 return EVP_sha384();
44 case (HKS_DIGEST_SHA512):
45 return EVP_sha512();
46 default:
47 return NULL;
48 }
49 }
50
HksOpensslPbkdf2(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)51 int32_t HksOpensslPbkdf2(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
52 struct HksBlob *derivedKey)
53 {
54 struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
55 const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
56 if (PKCS5_PBKDF2_HMAC((char *)mainKey->data, mainKey->size, deriveParam->salt.data, deriveParam->salt.size,
57 deriveParam->iterations, md, derivedKey->size, derivedKey->data) != 1) {
58 HKS_LOG_E("derive pbkdf2 key using openssl interface failed");
59 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
60 }
61 return HKS_SUCCESS;
62 }
63
HksOpensslHkdf(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)64 int32_t HksOpensslHkdf(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
65 struct HksBlob *derivedKey)
66 {
67 struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
68 const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
69 EVP_PKEY_CTX *pctx;
70 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
71 int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
72 do {
73 if (EVP_PKEY_derive_init(pctx) <= 0) {
74 HksLogOpensslError();
75 break;
76 }
77 if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
78 HksLogOpensslError();
79 break;
80 }
81 if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, deriveParam->salt.data, deriveParam->salt.size) <= 0) {
82 HksLogOpensslError();
83 break;
84 }
85 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, mainKey->data, mainKey->size) <= 0) {
86 HksLogOpensslError();
87 break;
88 }
89 if (EVP_PKEY_CTX_add1_hkdf_info(pctx, deriveParam->info.data, deriveParam->info.size) <= 0) {
90 HksLogOpensslError();
91 break;
92 }
93 size_t keyLen = derivedKey->size;
94 if (EVP_PKEY_derive(pctx, derivedKey->data, &keyLen) <= 0) {
95 HksLogOpensslError();
96 break;
97 }
98 derivedKey->size = (uint32_t)keyLen;
99 ret = HKS_SUCCESS;
100 } while (0);
101 EVP_PKEY_CTX_free(pctx);
102 return ret;
103 }
104
105 #ifdef HKS_SUPPORT_KDF_SM3
106
AppendKekAndFactor(const struct HksBlob * kekData,const struct HksBlob * factor,struct HksBlob * appendedData)107 static int32_t AppendKekAndFactor(const struct HksBlob *kekData, const struct HksBlob *factor,
108 struct HksBlob *appendedData)
109 {
110 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(factor), HKS_ERROR_INVALID_ARGUMENT, "Invalid param mainKey!");
111 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(kekData), HKS_ERROR_INVALID_ARGUMENT, "Invalid param derivedKey!");
112 struct HksBlob destData = {0, NULL};
113 destData.size = kekData->size + factor->size;
114 destData.data = (uint8_t *)HksMalloc(destData.size);
115 HKS_IF_NULL_LOGE_RETURN(destData.data, HKS_ERROR_MALLOC_FAIL, "malloc destData memory failed!");
116 (void)memcpy_s(destData.data, destData.size, kekData->data, kekData->size);
117 (void)memcpy_s(destData.data + kekData->size, destData.size - kekData->size, factor->data, factor->size);
118 appendedData->size = destData.size;
119 appendedData->data = destData.data;
120 return HKS_SUCCESS;
121 }
122
HksOpensslSmKdf(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)123 int32_t HksOpensslSmKdf(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
124 struct HksBlob *derivedKey)
125 {
126 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(mainKey), HKS_ERROR_INVALID_ARGUMENT, "Invalid param mainKey!");
127 HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(derivedKey),
128 HKS_ERROR_INVALID_ARGUMENT, "Invalid param derivedKey!");
129 struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
130 struct HksBlob appendedKeyData = { 0, NULL };
131 int32_t ret = AppendKekAndFactor(mainKey, &deriveParam->info, &appendedKeyData);
132 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "append data failed!")
133 unsigned int hashSize = appendedKeyData.size + HKS_BYTE_PER_INT;
134 struct HksBlob inputHashBlob = { 0, NULL };
135 inputHashBlob.size = hashSize;
136 inputHashBlob.data = (uint8_t *)HksMalloc(inputHashBlob.size);
137 if (inputHashBlob.data == NULL) {
138 HKS_FREE(appendedKeyData.data);
139 return HKS_ERROR_MALLOC_FAIL;
140 }
141 (void)memcpy_s(inputHashBlob.data, inputHashBlob.size, appendedKeyData.data, appendedKeyData.size);
142 uint8_t digestDataArray[HKS_DIGEST_SM3_LEN] = { 0 };
143 unsigned int digestLength = HKS_DIGEST_SM3_LEN;
144 struct HksBlob cdgstBlob = {digestLength, digestDataArray};
145 unsigned int index = (derivedKey->size - 1) / HKS_DIGEST_SM3_LEN + 1; // round up
146 unsigned char counterBytes[HKS_BYTE_PER_INT] = { 0 };
147 unsigned int counter = HKS_START_NUM;
148 do {
149 for (unsigned int i = 0; i < index; i++) {
150 for (unsigned int j = HKS_START_NUM; j <= HKS_BYTE_PER_INT; j++) {
151 counterBytes[j - 1] = (counter >> (HKS_BITS_PER_INT - HKS_BITS_PER_BYTE * j)) & 0xFF;
152 }
153 (void)memcpy_s(inputHashBlob.data + appendedKeyData.size, HKS_BYTE_PER_INT, counterBytes, HKS_BYTE_PER_INT);
154 ret = HksOpensslHash(HKS_DIGEST_SM3, &inputHashBlob, &cdgstBlob);
155 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Hash data failed!");
156 if ((i == (index - 1)) && (derivedKey->size % HKS_DIGEST_SM3_LEN != 0)) {
157 digestLength = (derivedKey->size) % HKS_DIGEST_SM3_LEN;
158 }
159 if (memcpy_s(derivedKey->data + HKS_DIGEST_SM3_LEN * i,
160 digestLength, cdgstBlob.data, digestLength) != EOK) {
161 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
162 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "memcp derivedkey data failed!");
163 }
164 counter++;
165 }
166 } while (0);
167 HKS_FREE_BLOB(appendedKeyData);
168 HKS_FREE_BLOB(inputHashBlob);
169 HKS_IF_NOT_SUCC_RETURN(ret, ret);
170 return ret;
171 }
172 #endif /* HKS_SUPPORT_KDF_SM3 */