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(&paramSet);
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(&paramSet);
164         return ret;
165     }
166 
167     ret = HksBuildParamSet(&paramSet);
168     if (ret != HKS_SUCCESS) {
169         HKS_LOG_E("unwrap suite build params failed.");
170         HksFreeParamSet(&paramSet);
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