1 /*
2 * Copyright (c) 2023-2023 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 #include "hks_sm_import_wrap_key.h"
23 #include "securec.h"
24
25 #include <stdbool.h>
26 #include <stddef.h>
27
28 #if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM3_C) && defined(HKS_SUPPORT_SM4_C)
29 #include "hks_ability.h"
30 #include "hks_base_check.h"
31 #include "hks_check_paramset.h"
32 #include "hks_client_service_adapter_common.h"
33 #include "hks_cmd_id.h"
34 #include "hks_common_check.h"
35 #include "hks_crypto_adapter.h"
36 #include "hks_crypto_hal.h"
37 #include "hks_keyblob.h"
38 #include "hks_log.h"
39 #include "hks_mem.h"
40 #include "hks_param.h"
41 #include "hks_template.h"
42 #include "hks_core_service_key_generate.h"
43 #include "hks_core_service_key_operate_one_stage.h"
44
45 #define HKS_PADDING_SUPPLENMENT 16
46
47 static const uint32_t g_validCipher[] = {
48 #ifdef HKS_SUPPORT_SM4_C
49 HKS_ALG_SM4,
50 #endif
51 #ifdef HKS_SUPPORT_SM2_C
52 HKS_ALG_SM2,
53 #endif
54 };
55
ClearAndFreeKeyBlob(struct HksBlob * blobData)56 static void ClearAndFreeKeyBlob(struct HksBlob *blobData)
57 {
58 if (blobData == NULL) {
59 return;
60 }
61 if (blobData->data != NULL) {
62 (void)memset_s(blobData->data, blobData->size, 0, blobData->size);
63 HKS_FREE(blobData->data);
64 }
65 }
66
ClearAndFreeWrappedBlob(struct HksSmWrappedKeyDataBlob * dataParams)67 static void ClearAndFreeWrappedBlob(struct HksSmWrappedKeyDataBlob *dataParams)
68 {
69 if (dataParams == NULL) {
70 return;
71 }
72 ClearAndFreeKeyBlob(&dataParams->originKey);
73 ClearAndFreeKeyBlob(&dataParams->peerPublicKey);
74 ClearAndFreeKeyBlob(&dataParams->kekAndSignData);
75 ClearAndFreeKeyBlob(&dataParams->kekData);
76 ClearAndFreeKeyBlob(&dataParams->signData);
77 ClearAndFreeKeyBlob(&dataParams->deriveKekData1);
78 ClearAndFreeKeyBlob(&dataParams->deriveKekData2);
79 }
80
GetDataLenFromWrappedData(const struct HksBlob * wrappedKeyData,uint32_t partOffset,uint32_t totalBlobs,uint32_t * originDataLen)81 static int32_t GetDataLenFromWrappedData(const struct HksBlob *wrappedKeyData,
82 uint32_t partOffset, uint32_t totalBlobs, uint32_t *originDataLen)
83 {
84 struct HksBlob originDataLenBlobPart = { 0, NULL };
85 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, partOffset, totalBlobs, &originDataLenBlobPart);
86 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get key material len failed!");
87
88 if (originDataLenBlobPart.size != sizeof(uint32_t)) {
89 HKS_LOG_E("len part is invalid!");
90 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
91 }
92
93 uint32_t dataSize = 0;
94 (void)memcpy_s((uint8_t *)&dataSize, sizeof(uint32_t), originDataLenBlobPart.data, originDataLenBlobPart.size);
95 if (dataSize > MAX_KEY_SIZE) {
96 HKS_LOG_E("material size is invalid!");
97 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
98 }
99
100 *originDataLen = dataSize;
101 return HKS_SUCCESS;
102 }
103
GetPublicKeyAndSignDataLength(const struct HksBlob * wrappedKeyData,struct HksKeyNode * keyNode,struct HksSmWrappedKeyDataBlob * dataParams,uint32_t * partOffset)104 static int32_t GetPublicKeyAndSignDataLength(const struct HksBlob *wrappedKeyData, struct HksKeyNode *keyNode,
105 struct HksSmWrappedKeyDataBlob *dataParams, uint32_t *partOffset)
106 {
107 if ((dataParams == NULL) || (keyNode == NULL)) {
108 HKS_LOG_E("invalid argument!");
109 return HKS_ERROR_INVALID_ARGUMENT;
110 }
111 struct HksBlob peerPubKeyPart = { 0, NULL };
112 uint32_t offset = *partOffset;
113 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++, HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS,
114 &peerPubKeyPart);
115 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get peer pub key failed!");
116
117 ret = GetDataLenFromWrappedData(wrappedKeyData, offset++, HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS,
118 &dataParams->signatureDataLength);
119 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get sign data length failed!");
120 if (peerPubKeyPart.size != 0) {
121 ret = GetHksPubKeyInnerFormat(keyNode->paramSet, &peerPubKeyPart, &dataParams->peerPublicKey);
122 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get peer pub key inner format failed!");
123 }
124 *partOffset = offset;
125 return HKS_SUCCESS;
126 }
127
AddDecryptKeyParamSetFromUnwrapSuite(const struct HksParamSet * inParamSet,struct HksParamSet * paramSet)128 static int32_t AddDecryptKeyParamSetFromUnwrapSuite(const struct HksParamSet *inParamSet,
129 struct HksParamSet *paramSet)
130 {
131 struct HksParam decryptParams[] = {
132 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_SM2 },
133 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
134 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_SM2_KEY_SIZE_256 },
135 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE},
136 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE},
137 };
138
139 int32_t ret = HksAddParams(paramSet, decryptParams, sizeof(decryptParams) / sizeof(struct HksParam));
140 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "unwrap suite add params failed.")
141
142 uint32_t accessTagList[] = { HKS_TAG_ACCESS_TOKEN_ID, HKS_TAG_USER_ID, HKS_TAG_PROCESS_NAME };
143 for (uint32_t i = 0; i < HKS_ARRAY_SIZE(accessTagList); ++i) {
144 struct HksParam *tmpParam = NULL;
145 ret = HksGetParam(inParamSet, accessTagList[i], &tmpParam);
146 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get param %" LOG_PUBLIC "u failed.", i)
147
148 ret = HksAddParams(paramSet, tmpParam, 1);
149 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "add param %" LOG_PUBLIC "u failed.", i)
150 }
151 return ret;
152 }
153
GetSm2DecryptParamSet(const struct HksParamSet * inParamSet,struct HksParamSet ** outParamSet)154 static int32_t GetSm2DecryptParamSet(const struct HksParamSet *inParamSet, struct HksParamSet **outParamSet)
155 {
156 struct HksParamSet *paramSet = NULL;
157 int32_t ret = HksInitParamSet(¶mSet);
158 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init key param set fail!")
159
160 ret = AddDecryptKeyParamSetFromUnwrapSuite(inParamSet, paramSet);
161 if (ret != HKS_SUCCESS) {
162 HKS_LOG_E("unwrap suite add params failed.");
163 HksFreeParamSet(¶mSet);
164 return ret;
165 }
166
167 ret = HksBuildParamSet(¶mSet);
168 if (ret != HKS_SUCCESS) {
169 HKS_LOG_E("unwrap suite build params failed.");
170 HksFreeParamSet(¶mSet);
171 return ret;
172 }
173
174 *outParamSet = paramSet;
175 return HKS_SUCCESS;
176 }
177
DecryptKekWithSm2(const struct HksBlob * wrappedKeyData,const struct HksParamSet * paramSet,struct HksKeyNode * keyNode,struct HksSmWrappedKeyDataBlob * dataParams,uint32_t * partOffset)178 static int32_t DecryptKekWithSm2(const struct HksBlob *wrappedKeyData, const struct HksParamSet *paramSet,
179 struct HksKeyNode *keyNode, struct HksSmWrappedKeyDataBlob *dataParams, uint32_t *partOffset)
180 {
181 uint32_t offset = *partOffset;
182 struct HksBlob kekEncDataPart = { 0, NULL };
183 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++,
184 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &kekEncDataPart);
185 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get kek_enc data failed!");
186
187 uint32_t kekOriginDataLen = 0;
188 ret = GetDataLenFromWrappedData(wrappedKeyData, offset++,
189 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &kekOriginDataLen);
190 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get kek origin len failed!");
191
192 struct HksBlob plainTextBlob = { 0, NULL };
193 plainTextBlob.size = kekOriginDataLen + dataParams->signatureDataLength;
194 uint8_t *kekBuffer = (uint8_t *)HksMalloc(plainTextBlob.size);
195 HKS_IF_NULL_LOGE_RETURN(kekBuffer, HKS_ERROR_MALLOC_FAIL, "malloc kekBuffer memory failed!");
196 plainTextBlob.data = kekBuffer;
197 struct HksParamSet *decryptParamSet = NULL;
198 struct HksBlob rawKey = { 0, NULL };
199 struct HksUsageSpec *usageSpec = NULL;
200 do {
201 ret = GetSm2DecryptParamSet(paramSet, &decryptParamSet);
202 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get decrypt param failed!")
203 ret = HksGetRawKey(keyNode->paramSet, &rawKey);
204 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "cipher get raw key failed!")
205 ret = HksBuildCipherUsageSpec(decryptParamSet, false, &kekEncDataPart, &usageSpec);
206 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build usage spec failed!")
207 ret = HksCryptoHalDecrypt(&rawKey, usageSpec, &kekEncDataPart, &plainTextBlob);
208 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt data failed!")
209 } while (0);
210 HksFreeParamSet(&decryptParamSet);
211 HksFreeUsageSpec(&usageSpec);
212 ClearAndFreeKeyBlob(&rawKey);
213 if (ret != HKS_SUCCESS) {
214 HKS_LOG_E("get decrypt param failed!");
215 HKS_FREE(plainTextBlob.data);
216 return ret;
217 }
218 if (dataParams->signatureDataLength == 0) {
219 dataParams->kekData.size = plainTextBlob.size;
220 dataParams->kekData.data = plainTextBlob.data;
221 } else {
222 dataParams->kekAndSignData.size = plainTextBlob.size;
223 dataParams->kekAndSignData.data = plainTextBlob.data;
224 }
225 *partOffset = offset;
226 return HKS_SUCCESS;
227 }
228
SplitKekAndSignData(struct HksSmWrappedKeyDataBlob * dataParams)229 static int32_t SplitKekAndSignData(struct HksSmWrappedKeyDataBlob *dataParams)
230 {
231 struct HksBlob *kekAndSignBlob = &dataParams->kekAndSignData;
232 uint32_t signDataLen = dataParams->signatureDataLength;
233 struct HksBlob kekDataBlob = {0, NULL};
234 struct HksBlob signatureDataBlob = {0, NULL};
235 if (kekAndSignBlob->size < signDataLen) {
236 HKS_LOG_E("sign data size is invalid!");
237 return HKS_ERROR_INVALID_ARGUMENT;
238 }
239 kekDataBlob.size = kekAndSignBlob->size - signDataLen;
240 kekDataBlob.data = (uint8_t *)HksMalloc(kekDataBlob.size);
241 HKS_IF_NULL_LOGE_RETURN(kekDataBlob.data, HKS_ERROR_MALLOC_FAIL, "malloc kekDataBlob memory failed!");
242 int32_t ret = HKS_SUCCESS;
243 do {
244 (void)memcpy_s(kekDataBlob.data, kekDataBlob.size, kekAndSignBlob->data, kekDataBlob.size);
245 if (signDataLen == 0) {
246 break;
247 }
248 signatureDataBlob.size = signDataLen;
249 signatureDataBlob.data = (uint8_t *)HksMalloc(signDataLen);
250 if (signatureDataBlob.data == NULL) {
251 HKS_LOG_E("malloc signatureDataBlob memory failed!");
252 ret = HKS_ERROR_MALLOC_FAIL;
253 break;
254 }
255
256 (void)memcpy_s(signatureDataBlob.data, signatureDataBlob.size, kekAndSignBlob->data + kekDataBlob.size,
257 signatureDataBlob.size);
258 } while (0);
259 if (ret != HKS_SUCCESS) {
260 HKS_FREE(signatureDataBlob.data);
261 HKS_FREE(kekDataBlob.data);
262 return ret;
263 }
264 dataParams->kekData.size = kekDataBlob.size;
265 dataParams->kekData.data = kekDataBlob.data;
266 dataParams->signData.size = signatureDataBlob.size;
267 dataParams->signData.data = signatureDataBlob.data;
268 return ret;
269 }
270
VerifyKekBySm2(const struct HksSmWrappedKeyDataBlob * dataParams)271 static int32_t VerifyKekBySm2(const struct HksSmWrappedKeyDataBlob *dataParams)
272 {
273 struct HksParam verifyParams[] = {
274 {.tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_SM2},
275 {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_VERIFY},
276 {.tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_SM2_KEY_SIZE_256},
277 {.tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SM3},
278 {.tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE},
279 };
280
281 struct HksParamSet *verifyParamSet = NULL;
282 int32_t ret = HksInitParamSet(&verifyParamSet);
283 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init verify key param set failed!");
284
285 ret = HksAddParams(verifyParamSet, verifyParams, sizeof(verifyParams) / sizeof(struct HksParam));
286 if (ret != HKS_SUCCESS) {
287 HKS_LOG_E("HksAddParams failed!");
288 HksFreeParamSet(&verifyParamSet);
289 return ret;
290 }
291 ret = HksBuildParamSet(&verifyParamSet);
292 if (ret != HKS_SUCCESS) {
293 HKS_LOG_E("unwrap suite build params failed.");
294 HksFreeParamSet(&verifyParamSet);
295 return ret;
296 }
297 struct HksUsageSpec usageSpec = { 0 };
298 HksFillUsageSpec(verifyParamSet, &usageSpec);
299
300 struct HksBlob message = {0, NULL};
301 message.size = MAX_HASH_SIZE;
302 message.data = (uint8_t *)HksMalloc(message.size);
303 if (message.data == NULL) {
304 HKS_LOG_E("malloc message memory failed!");
305 HksFreeParamSet(&verifyParamSet);
306 return HKS_ERROR_MALLOC_FAIL;
307 }
308 do {
309 ret = HksCryptoHalHash(HKS_DIGEST_SM3, &dataParams->kekData, &message);
310 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksCryptoHalHash failed!")
311 ret = HksCryptoHalVerify(&dataParams->peerPublicKey, &usageSpec, &message, &dataParams->signData);
312 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksCryptoHalVerify failed!")
313 } while (0);
314 HKS_FREE_BLOB(message);
315 HksFreeParamSet(&verifyParamSet);
316 return ret;
317 }
318
DeriveKeyBySm3(const struct HksBlob * srcData,const struct HksBlob * factor,struct HksBlob * deriveKey)319 static int32_t DeriveKeyBySm3(const struct HksBlob *srcData, const struct HksBlob *factor, struct HksBlob *deriveKey)
320 {
321 struct HksBlob deriveBlob = { 0, NULL };
322 deriveBlob.size = HKS_KEY_BYTES(HKS_SM4_KEY_SIZE_128);
323 deriveBlob.data = (uint8_t *)HksMalloc(deriveBlob.size);
324 HKS_IF_NULL_LOGE_RETURN(deriveBlob.data, HKS_ERROR_MALLOC_FAIL, "malloc deriveBlob memory failed!");
325
326 struct HksKeyDerivationParam derParam = {
327 .digestAlg = HKS_DIGEST_SM3,
328 .info = *factor,
329 };
330 struct HksKeySpec derivationSpec = { HKS_ALG_GMKDF, HKS_KEY_BYTES(HKS_SM4_KEY_SIZE_128), &derParam };
331 int32_t ret = HksCryptoHalDeriveKey(srcData, &derivationSpec, &deriveBlob);
332 if (ret != HKS_SUCCESS) {
333 HKS_FREE(deriveBlob.data);
334 HKS_LOG_E("derive key failed!");
335 return ret;
336 }
337 deriveKey->size = deriveBlob.size;
338 deriveKey->data = deriveBlob.data;
339 return HKS_SUCCESS;
340 }
341
DeriveKeyByFactor(const struct HksBlob * wrappedKeyData,struct HksSmWrappedKeyDataBlob * dataParams,uint32_t * partOffset)342 static int32_t DeriveKeyByFactor(const struct HksBlob *wrappedKeyData, struct HksSmWrappedKeyDataBlob *dataParams,
343 uint32_t *partOffset)
344 {
345 struct HksBlob *deriveKek1 = &dataParams->deriveKekData1;
346 struct HksBlob *deriveKek2 = &dataParams->deriveKekData2;
347 struct HksBlob factor1 = { 0, NULL };
348 struct HksBlob factor2 = { 0, NULL };
349 uint32_t offset = *partOffset;
350 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++,
351 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &factor1);
352 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get factor1 data failed!");
353
354 ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++, HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &factor2);
355 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get factor2 data failed!");
356 do {
357 ret = DeriveKeyBySm3(&dataParams->kekData, &factor1, deriveKek1);
358 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "derive kek1 data failed!") ;
359
360 ret = DeriveKeyBySm3(&dataParams->kekData, &factor2, deriveKek2);
361 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "derive kek2 data failed!") ;
362 } while (0);
363 if (ret != HKS_SUCCESS) {
364 HKS_FREE(deriveKek1->data);
365 HKS_FREE(deriveKek2->data);
366 return ret;
367 }
368 *partOffset = offset;
369 return HKS_SUCCESS;
370 }
371
CompareWrapKeyHmac(const struct HksBlob * wrappedKeyData,struct HksSmWrappedKeyDataBlob * dataParams,struct HksBlob * kEncData,uint32_t * partOffset)372 static int32_t CompareWrapKeyHmac(const struct HksBlob *wrappedKeyData, struct HksSmWrappedKeyDataBlob *dataParams,
373 struct HksBlob *kEncData, uint32_t *partOffset)
374 {
375 struct HksBlob originKeyEncMac = { 0, NULL };
376 uint32_t offset = *partOffset;
377 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++,
378 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &originKeyEncMac);
379 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get originKeyEncMac data failed!");
380 ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++, HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, kEncData);
381 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get kenc data failed!");
382
383 struct HksBlob mac = { 0, NULL };
384 mac.size = originKeyEncMac.size;
385 mac.data = (uint8_t *)HksMalloc(mac.size);
386 HKS_IF_NULL_LOGE_RETURN(mac.data, HKS_ERROR_MALLOC_FAIL, "malloc mac memory failed!");
387 do {
388 ret = HksCryptoHalHmac(&dataParams->deriveKekData2, HKS_DIGEST_SM3, kEncData, &mac);
389 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "cal hmac value failed!")
390 ret = HksMemCmp(originKeyEncMac.data, mac.data, mac.size);
391 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "compare kek enc data mac failed!")
392 } while (0);
393 HKS_FREE(mac.data);
394 if (ret != HKS_SUCCESS) {
395 HKS_LOG_E("compare mac failed!");
396 return ret;
397 }
398 *partOffset = offset;
399 return ret;
400 }
401
BuildDecryptUsageSpecOfSmUnwrap(const struct HksBlob * iv,struct HksUsageSpec * usageSpec)402 static int32_t BuildDecryptUsageSpecOfSmUnwrap(const struct HksBlob *iv, struct HksUsageSpec *usageSpec)
403 {
404 usageSpec->mode = HKS_MODE_CBC;
405 usageSpec->padding = HKS_PADDING_PKCS7;
406 usageSpec->digest = HKS_DIGEST_NONE;
407 usageSpec->algType = HKS_ALG_SM4;
408
409 struct HksCipherParam *cipherParam = (struct HksCipherParam *)HksMalloc(sizeof(struct HksCipherParam));
410 HKS_IF_NULL_LOGE_RETURN(cipherParam, HKS_ERROR_MALLOC_FAIL, "build dec wrapped usage: cipherParam malloc failed!");
411
412 cipherParam->iv = *iv;
413
414 usageSpec->algParam = cipherParam;
415 return HKS_SUCCESS;
416 }
417
SubPaddingPlaintext(const struct HksBlob * srcData,struct HksBlob * outData,uint32_t subLength)418 static int32_t SubPaddingPlaintext(const struct HksBlob *srcData, struct HksBlob *outData, uint32_t subLength)
419 {
420 uint8_t *mallocResultData = (uint8_t *)HksMalloc(subLength);
421 HKS_IF_NULL_LOGE_RETURN(mallocResultData, HKS_ERROR_MALLOC_FAIL, "malloc mallocResultData memory failed!");
422 (void)memcpy_s(mallocResultData, subLength, srcData->data, subLength);
423 outData->size = subLength;
424 outData->data = mallocResultData;
425 return HKS_SUCCESS;
426 }
427
DecryptImportedSmKey(const struct HksBlob * wrappedKeyData,struct HksSmWrappedKeyDataBlob * dataParams,struct HksBlob * kEncData,uint32_t * partOffset)428 static int32_t DecryptImportedSmKey(const struct HksBlob *wrappedKeyData, struct HksSmWrappedKeyDataBlob *dataParams,
429 struct HksBlob *kEncData, uint32_t *partOffset)
430 {
431 uint32_t offset = *partOffset;
432 struct HksBlob ivParam = { 0, NULL };
433 int32_t ret = HksGetBlobFromWrappedData(wrappedKeyData, offset++,
434 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &ivParam);
435 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get ivParam data failed!");
436
437 uint32_t keyMaterialSize = 0;
438 ret = GetDataLenFromWrappedData(wrappedKeyData, offset++,
439 HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, &keyMaterialSize);
440 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get key material data failed!");
441
442 struct HksBlob originKey = { 0, NULL };
443 originKey.size = keyMaterialSize + HKS_PADDING_SUPPLENMENT;
444 uint8_t *originKeyBuffer = (uint8_t *)HksMalloc(originKey.size);
445 HKS_IF_NULL_LOGE_RETURN(originKeyBuffer, HKS_ERROR_MALLOC_FAIL, "malloc originKeyBuffer memory failed!");
446
447 originKey.data = originKeyBuffer;
448 struct HksUsageSpec *decOriginKeyUsageSpec = (struct HksUsageSpec *)HksMalloc(sizeof(struct HksUsageSpec));
449 if (decOriginKeyUsageSpec == NULL) {
450 HKS_LOG_E("malloc originKeyBuffer memory failed!");
451 HKS_FREE(originKey.data);
452 return HKS_ERROR_MALLOC_FAIL;
453 }
454 (void)memset_s(decOriginKeyUsageSpec, sizeof(struct HksUsageSpec), 0, sizeof(struct HksUsageSpec));
455 ret = BuildDecryptUsageSpecOfSmUnwrap(&ivParam, decOriginKeyUsageSpec);
456 if (ret != HKS_SUCCESS) {
457 HKS_LOG_E("build decrypt wrapped data origin key usageSpec failed!");
458 HKS_FREE(originKey.data);
459 HksFreeUsageSpec(&decOriginKeyUsageSpec);
460 return ret;
461 }
462 ret = HksCryptoHalDecrypt(&dataParams->deriveKekData1, decOriginKeyUsageSpec, kEncData, &originKey);
463 HksFreeUsageSpec(&decOriginKeyUsageSpec);
464 if (ret != HKS_SUCCESS) {
465 HKS_LOG_E("decrypt importKey failed!");
466 HKS_FREE(originKey.data);
467 return ret;
468 }
469 ret = SubPaddingPlaintext(&originKey, &dataParams->originKey, keyMaterialSize);
470 ClearAndFreeKeyBlob(&originKey);
471 if (ret != HKS_SUCCESS) {
472 HKS_LOG_E("sub str failed!");
473 return ret;
474 }
475 *partOffset = offset;
476 return HKS_SUCCESS;
477 }
478
HksSmImportWrappedKeyWithVerify(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksKeyNode * keyNode,const struct HksBlob * wrappedKeyData,struct HksBlob * keyOut)479 static int32_t HksSmImportWrappedKeyWithVerify(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
480 struct HksKeyNode *keyNode, const struct HksBlob *wrappedKeyData, struct HksBlob *keyOut)
481 {
482 struct HksSmWrappedKeyDataBlob dataParams = { { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
483 { 0, NULL }, { 0, NULL }, { 0, NULL }, 0 };
484 struct HksBlob kEncData = { 0, NULL };
485 uint32_t partOffset = 0;
486 int32_t ret = HKS_SUCCESS;
487 do {
488 /* 1. get peer public key and sign data length, then transfer public key to inner format */
489 ret = GetPublicKeyAndSignDataLength(wrappedKeyData, keyNode, &dataParams, &partOffset);
490 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get public key and sign data failed!")
491
492 /*2. decrypt kek data*/
493 ret = DecryptKekWithSm2(wrappedKeyData, paramSet, keyNode, &dataParams, &partOffset);
494 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt kek failed!")
495
496 ret = SplitKekAndSignData(&dataParams);
497 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "split kek and sign data failed!")
498
499 /*3. verify data*/
500 ret = VerifyKekBySm2(&dataParams);
501 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "verify data failed!")
502
503 /*4. derive kek1 and kek2*/
504 ret = DeriveKeyByFactor(wrappedKeyData, &dataParams, &partOffset);
505 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "derive data failed!")
506
507 /*5. compare hmac*/
508 ret = CompareWrapKeyHmac(wrappedKeyData, &dataParams, &kEncData, &partOffset);
509 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "compare kek enc mac failed!")
510
511 /*6. decrypt origin key*/
512 ret = DecryptImportedSmKey(wrappedKeyData, &dataParams, &kEncData, &partOffset);
513 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt origin key failed!")
514
515 /* 7. call HksCoreImportKey to build key blob */
516 ret = HksCoreImportKey(keyAlias, &dataParams.originKey, paramSet, keyOut);
517 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "import origin key failed!")
518 } while (0);
519 ClearAndFreeWrappedBlob(&dataParams);
520 return ret;
521 }
522
HksSmImportWrappedKeyWithoutVerify(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,struct HksKeyNode * keyNode,const struct HksBlob * wrappedKeyData,struct HksBlob * keyOut)523 static int32_t HksSmImportWrappedKeyWithoutVerify(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
524 struct HksKeyNode *keyNode, const struct HksBlob *wrappedKeyData, struct HksBlob *keyOut)
525 {
526 struct HksSmWrappedKeyDataBlob dataParams = { { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
527 { 0, NULL }, { 0, NULL }, { 0, NULL }, 0 };
528 struct HksBlob kEncData = { 0, NULL };
529 uint32_t partOffset = 0;
530 int32_t ret = HKS_SUCCESS;
531
532 do {
533 /* 1. decrypt kek data*/
534 ret = DecryptKekWithSm2(wrappedKeyData, paramSet, keyNode, &dataParams, &partOffset);
535 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt kek failed!")
536
537 /* 2. derive kek1 and kek2*/
538 ret = DeriveKeyByFactor(wrappedKeyData, &dataParams, &partOffset);
539 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "derive data failed!")
540
541 /* 3. compare hmac*/
542 ret = CompareWrapKeyHmac(wrappedKeyData, &dataParams, &kEncData, &partOffset);
543 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "compare kek enc mac failed!")
544
545 /* 4. decrypt origin key*/
546 ret = DecryptImportedSmKey(wrappedKeyData, &dataParams, &kEncData, &partOffset);
547 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt origin key failed!")
548
549 /* 5. call HksCoreImportKey to build key blob */
550 ret = HksCoreImportKey(keyAlias, &dataParams.originKey, paramSet, keyOut);
551 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "import origin key failed!")
552 } while (0);
553 ClearAndFreeWrappedBlob(&dataParams);
554 return ret;
555 }
556
CheckAlgAndGetSuit(const struct HksParamSet * paramSet,uint32_t * suit)557 static int32_t CheckAlgAndGetSuit(const struct HksParamSet *paramSet, uint32_t *suit)
558 {
559 struct HksParam *alg = NULL;
560 int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &alg);
561 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
562 "get param %" LOG_PUBLIC "u failed!", HKS_TAG_ALGORITHM)
563 ret = HksCheckValue(alg->uint32Param, g_validCipher, HKS_ARRAY_SIZE(g_validCipher));
564 HKS_IF_NOT_SUCC_RETURN(ret, HKS_ERROR_INVALID_AUTH_TYPE)
565
566 struct HksParam *algorithmSuite = NULL;
567 ret = HksGetParam(paramSet, HKS_TAG_UNWRAP_ALGORITHM_SUITE, &algorithmSuite);
568 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL, "get unwrap algorithm suite fail");
569 *suit = algorithmSuite->uint32Param;
570 return HKS_SUCCESS;
571 }
572
HksSmImportWrappedKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappingKey,const struct HksBlob * wrappedKeyData,struct HksBlob * keyOut)573 int32_t HksSmImportWrappedKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
574 const struct HksBlob *wrappingKey, const struct HksBlob *wrappedKeyData, struct HksBlob *keyOut)
575 {
576 if ((CheckBlob(wrappingKey) != HKS_SUCCESS) || (CheckBlob(wrappedKeyData) != HKS_SUCCESS)) {
577 HKS_LOG_E("invalid argument!");
578 return HKS_ERROR_INVALID_ARGUMENT;
579 }
580 uint32_t algSuit = 0;
581 int32_t ret = CheckAlgAndGetSuit(paramSet, &algSuit);
582 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "check failed.");
583
584 struct HksKeyNode *wrappingKeyNode = HksGenerateKeyNode(wrappingKey);
585 HKS_IF_NULL_LOGE_RETURN(wrappingKeyNode, HKS_ERROR_CORRUPT_FILE, "generate keynode failed")
586
587 if (algSuit == HKS_UNWRAP_SUITE_SM2_SM4_128_CBC_PKCS7_WITH_VERIFY_DIG_SM3) {
588 ret = HksSmImportWrappedKeyWithVerify(keyAlias, paramSet, wrappingKeyNode, wrappedKeyData, keyOut);
589 } else if (algSuit == HKS_UNWRAP_SUITE_SM2_SM4_128_CBC_PKCS7) {
590 ret = HksSmImportWrappedKeyWithoutVerify(keyAlias, paramSet, wrappingKeyNode, wrappedKeyData, keyOut);
591 } else {
592 HKS_LOG_E("invalid alg suit!");
593 ret = HKS_ERROR_NOT_SUPPORTED;
594 }
595 HksFreeKeyNode(&wrappingKeyNode);
596 return ret;
597 }
598
599 #else
600
HksSmImportWrappedKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappingKey,const struct HksBlob * wrappedKeyData,struct HksBlob * keyOut)601 int32_t HksSmImportWrappedKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
602 const struct HksBlob *wrappingKey, const struct HksBlob *wrappedKeyData, struct HksBlob *keyOut)
603 {
604 (void)keyAlias;
605 (void)paramSet;
606 (void)wrappingKey;
607 (void)wrappedKeyData;
608 (void)keyOut;
609 return HKS_ERROR_API_NOT_SUPPORTED;
610 }
611 #endif