1 /*
2  * Copyright (c) 2022-2024 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_core_service_three_stage.h"
23 
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 
28 #include "hks_auth.h"
29 #include "hks_base_check.h"
30 #include "hks_check_paramset.h"
31 #include "hks_client_service_adapter_common.h"
32 #include "hks_cmd_id.h"
33 #include "hks_common_check.h"
34 #include "hks_crypto_adapter.h"
35 #include "hks_crypto_hal.h"
36 #include "hks_keyblob.h"
37 #include "hks_log.h"
38 #include "hks_mem.h"
39 #include "hks_param.h"
40 #include "hks_template.h"
41 #include "securec.h"
42 #include "hks_core_service_key_generate.h"
43 
44 #ifndef _CUT_AUTHENTICATE_
45 #define CURVE25519_KEY_BYTE_SIZE HKS_KEY_BYTES(HKS_CURVE25519_KEY_SIZE_256)
46 
47 #ifdef HKS_SUPPORT_ED25519_TO_X25519
48 
49 #endif
50 #define HKS_RSA_OAEP_DIGEST_NUM          2
51 #define HKS_SM2_C1_LEN_NUM               2
52 #define HKS_BLOCK_CIPHER_CBC_BLOCK_SIZE  16
53 #define HKS_TEMP_SIZE                    32
54 #define MAX_BUF_SIZE                     (5 * 1024 * 1024)
55 #define HKS_AES_GCM_NONCE_LEN            12
56 #define HKS_AES_CCM_NONCE_LEN            7
57 
CheckRsaCipherData(bool isEncrypt,uint32_t keyLen,struct HksUsageSpec * usageSpec,const struct HksBlob * outData)58 static int32_t CheckRsaCipherData(bool isEncrypt, uint32_t keyLen, struct HksUsageSpec *usageSpec,
59     const struct HksBlob *outData)
60 {
61     uint32_t keySize = keyLen / HKS_BITS_PER_BYTE;
62     uint32_t padding = usageSpec->padding;
63     uint32_t digest = usageSpec->digest;
64 
65     if (padding == HKS_PADDING_NONE) {
66         if (outData->size < keySize) {
67             HKS_LOG_E("outData buffer too small size: %" LOG_PUBLIC "u, keySize: %" LOG_PUBLIC "u",
68                 outData->size, keySize);
69             return HKS_ERROR_BUFFER_TOO_SMALL;
70         }
71     } else if (padding == HKS_PADDING_OAEP) {
72         uint32_t digestLen;
73         int32_t ret = HksGetDigestLen(digest, &digestLen);
74         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetDigestLen failed, ret = %" LOG_PUBLIC "x", ret)
75 
76         if (keySize <= (HKS_RSA_OAEP_DIGEST_NUM * digestLen + HKS_RSA_OAEP_DIGEST_NUM)) {
77             return HKS_ERROR_INVALID_KEY_FILE;
78         }
79 
80         uint32_t size = keySize - HKS_RSA_OAEP_DIGEST_NUM * digestLen - HKS_RSA_OAEP_DIGEST_NUM;
81         if (isEncrypt) {
82             if (outData->size < keySize) {
83                 HKS_LOG_E("encrypt, outData buffer too small size: %" LOG_PUBLIC "u, keySize: %" LOG_PUBLIC "u",
84                     outData->size, keySize);
85                 return HKS_ERROR_BUFFER_TOO_SMALL;
86             }
87         } else {
88             if (outData->size < size) {
89                 HKS_LOG_E("decrypt, outData buffer too small size: %" LOG_PUBLIC "u, keySize: %" LOG_PUBLIC "u",
90                     outData->size, keySize);
91                 return HKS_ERROR_BUFFER_TOO_SMALL;
92             }
93         }
94     }
95 
96     return HKS_SUCCESS;
97 }
98 
CheckSm2CipherData(bool isEncrypt,const struct HksUsageSpec * usageSpec,const struct HksBlob * inData,const struct HksBlob * outData)99 static int32_t CheckSm2CipherData(bool isEncrypt, const struct HksUsageSpec *usageSpec, const struct HksBlob *inData,
100     const struct HksBlob *outData)
101 {
102     if (!isEncrypt) {
103         return HKS_SUCCESS;
104     }
105     uint32_t digest = usageSpec->digest;
106     uint32_t digestLen;
107     int32_t ret = HksGetDigestLen(digest, &digestLen);
108     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetDigestLen failed, ret = %" LOG_PUBLIC "x", ret)
109     uint32_t lenC1 = HKS_SM2_C1_LEN_NUM * HKS_KEY_BYTES(HKS_SM2_KEY_SIZE_256) + 1;
110     uint32_t needLen = (lenC1 + digestLen + inData->size);
111 
112     if (outData->size < needLen) {
113         HKS_LOG_E("encrypt, outData buffer too small size: %" LOG_PUBLIC "u, needLen: %"
114             LOG_PUBLIC "d", outData->size, needLen);
115         return HKS_ERROR_BUFFER_TOO_SMALL;
116     }
117     return HKS_SUCCESS;
118 }
119 
CheckAesCipherAead(bool isEncrypt,const struct HksBlob * inData,const struct HksBlob * outData)120 static int32_t CheckAesCipherAead(bool isEncrypt, const struct HksBlob *inData,
121     const struct HksBlob *outData)
122 {
123     if (isEncrypt) {
124         if (outData->size < (inData->size + HKS_AE_TAG_LEN)) {
125             HKS_LOG_E("encrypt, out buffer too small size: %" LOG_PUBLIC "u, inSize: %" LOG_PUBLIC "u",
126                 outData->size, inData->size);
127             return HKS_ERROR_BUFFER_TOO_SMALL;
128         }
129     } else {
130         if (outData->size < inData->size) {
131             HKS_LOG_E("decryptfinal, out buffer too small size: %" LOG_PUBLIC "u, inSize: %" LOG_PUBLIC "u",
132                 outData->size, inData->size);
133             return HKS_ERROR_BUFFER_TOO_SMALL;
134         }
135     }
136     return HKS_SUCCESS;
137 }
138 
CheckBlockCipherOther(uint32_t mode,bool isEncrypt,uint32_t padding,const struct HksBlob * inData,const struct HksBlob * outData)139 static int32_t CheckBlockCipherOther(uint32_t mode, bool isEncrypt, uint32_t padding, const struct HksBlob *inData,
140     const struct HksBlob *outData)
141 {
142     uint32_t paddingSize = 0;
143 
144     if (isEncrypt) {
145         if (padding == HKS_PADDING_NONE) {
146             if ((mode == HKS_MODE_CBC || mode == HKS_MODE_ECB) && inData->size % HKS_BLOCK_CIPHER_CBC_BLOCK_SIZE != 0) {
147                 HKS_LOG_E("encrypt cbc or ecb no-padding, invalid inSize: %" LOG_PUBLIC "u", inData->size);
148                 return HKS_ERROR_INVALID_ARGUMENT;
149             }
150         } else {
151             paddingSize = HKS_BLOCK_CIPHER_CBC_BLOCK_SIZE - inData->size % HKS_BLOCK_CIPHER_CBC_BLOCK_SIZE;
152             if (inData->size > (UINT32_MAX - paddingSize)) {
153                 HKS_LOG_E("encrypt, invalid inData size: %" LOG_PUBLIC "u", inData->size);
154                 return HKS_ERROR_INVALID_ARGUMENT;
155             }
156         }
157         if (outData->size < (inData->size + paddingSize)) {
158             HKS_LOG_E("encrypt, outData buffer too small size: %" LOG_PUBLIC "u, need: %" LOG_PUBLIC "u",
159                 outData->size, inData->size + paddingSize);
160             return HKS_ERROR_BUFFER_TOO_SMALL;
161         }
162     } else {
163         if (outData->size < inData->size) {
164             HKS_LOG_E("decrypt, outData buffer too small size: %" LOG_PUBLIC "u, inDataSize: %" LOG_PUBLIC "u",
165                 outData->size, inData->size);
166             return HKS_ERROR_BUFFER_TOO_SMALL;
167         }
168     }
169 
170     return HKS_SUCCESS;
171 }
172 
CheckBlockCipherData(bool isEncrypt,const struct HksUsageSpec * usageSpec,const struct HksBlob * inData,const struct HksBlob * outData)173 static int32_t CheckBlockCipherData(bool isEncrypt, const struct HksUsageSpec *usageSpec,
174     const struct HksBlob *inData, const struct HksBlob *outData)
175 {
176     const uint32_t padding = usageSpec->padding;
177     const uint32_t mode = usageSpec->mode;
178     const uint32_t alg = usageSpec->algType;
179     int32_t ret = HKS_ERROR_NOT_SUPPORTED;
180 
181     if (mode == HKS_MODE_GCM || mode == HKS_MODE_CCM) {
182         if (alg == HKS_ALG_AES) {
183             ret = CheckAesCipherAead(isEncrypt, inData, outData);
184         }
185     } else if (mode == HKS_MODE_CFB || mode == HKS_MODE_OFB) {
186         if (alg == HKS_ALG_SM4) {
187             ret = CheckBlockCipherOther(mode, isEncrypt, padding, inData, outData);
188         }
189     } else if (mode == HKS_MODE_CBC || mode == HKS_MODE_CTR || mode == HKS_MODE_ECB) {
190         ret = CheckBlockCipherOther(mode, isEncrypt, padding, inData, outData);
191     }
192 
193     return ret;
194 }
195 
HksCheckFinishOutSize(bool isEncrypt,struct HksParamSet * paramSet,const struct HksBlob * inData,const struct HksBlob * outData)196 static int32_t HksCheckFinishOutSize(bool isEncrypt, struct HksParamSet *paramSet,
197     const struct HksBlob *inData, const struct HksBlob *outData)
198 {
199     struct HksUsageSpec usageSpec = {0};
200     HksFillUsageSpec(paramSet, &usageSpec);
201     struct HksKeySpec cipherSpec = {0};
202     HksFillKeySpec(paramSet, &cipherSpec);
203     uint32_t alg = usageSpec.algType;
204 
205     switch (alg) {
206         case HKS_ALG_RSA:
207             return CheckRsaCipherData(isEncrypt, cipherSpec.keyLen, &usageSpec, outData);
208         case HKS_ALG_SM2:
209             return CheckSm2CipherData(isEncrypt, &usageSpec, inData, outData);
210         case HKS_ALG_AES:
211             return CheckBlockCipherData(isEncrypt, &usageSpec, inData, outData);
212         case HKS_ALG_SM4:
213             return CheckBlockCipherData(isEncrypt, &usageSpec, inData, outData);
214         default:
215             return HKS_ERROR_INVALID_ALGORITHM;
216     }
217 }
218 
SignVerifyAuth(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet)219 static int32_t SignVerifyAuth(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet)
220 {
221     struct HksParam *algParam = NULL;
222     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
223     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append sign/verify get alg param failed!")
224 
225     if (algParam->uint32Param == HKS_ALG_ECC || algParam->uint32Param == HKS_ALG_SM2 ||
226         algParam->uint32Param == HKS_ALG_DSA) {
227         return HksThreeStageAuth(HKS_AUTH_ID_SIGN_VERIFY_ECC, keyNode);
228     } else if (algParam->uint32Param == HKS_ALG_RSA) {
229         struct HksParam *padding = NULL;
230         ret = HksGetParam(paramSet, HKS_TAG_PADDING, &padding);
231         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append sign/verify get padding param failed!")
232         if (padding->uint32Param == HKS_PADDING_PSS) {
233             ret = HksCheckKeyBlobParamSetEqualRuntimeParamSet(keyNode->keyBlobParamSet,
234                 keyNode->runtimeParamSet, HKS_TAG_RSA_PSS_SALT_LEN_TYPE);
235             HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckKeyBlobParamSetEqualRuntimeParamSet failed!")
236         }
237         return HksThreeStageAuth(HKS_AUTH_ID_SIGN_VERIFY_RSA, keyNode);
238     } else if (algParam->uint32Param == HKS_ALG_ED25519) {
239         return HksThreeStageAuth(HKS_AUTH_ID_SIGN_VERIFY_ED25519, keyNode);
240     }
241     return HKS_ERROR_INVALID_ALGORITHM;
242 }
243 
AgreeAuth(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet)244 static int32_t AgreeAuth(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet)
245 {
246     struct HksParam *algParam = NULL;
247     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
248     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append agree get alg param failed!")
249 
250     if (algParam->uint32Param == HKS_ALG_ECDH || algParam->uint32Param == HKS_ALG_X25519 ||
251         algParam->uint32Param == HKS_ALG_DH || algParam->uint32Param == HKS_ALG_SM2) {
252         return HksThreeStageAuth(HKS_AUTH_ID_AGREE, keyNode);
253     }
254     return HKS_ERROR_INVALID_ALGORITHM;
255 }
256 
HmacAuth(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet)257 static int32_t HmacAuth(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet)
258 {
259     struct HksParam *algParam = NULL;
260     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
261     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append hmac get alg param failed!")
262 
263     if (algParam->uint32Param == HKS_ALG_HMAC) {
264         return HksThreeStageAuth(HKS_AUTH_ID_MAC_HMAC, keyNode);
265     } else if (algParam->uint32Param == HKS_ALG_SM3) {
266         return HksThreeStageAuth(HKS_AUTH_ID_MAC_SM3, keyNode);
267     }
268     return HKS_ERROR_INVALID_ALGORITHM;
269 }
270 
CipherAuth(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet)271 static int32_t CipherAuth(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet)
272 {
273     struct HksParam *algParam = NULL;
274     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
275     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append cipher get alg param failed!")
276 
277     if (algParam->uint32Param == HKS_ALG_AES) {
278         return HksThreeStageAuth(HKS_AUTH_ID_SYM_CIPHER, keyNode);
279     } else if ((algParam->uint32Param == HKS_ALG_RSA) || (algParam->uint32Param == HKS_ALG_SM2)) {
280         return HksThreeStageAuth(HKS_AUTH_ID_ASYM_CIPHER, keyNode);
281     } else if (algParam->uint32Param == HKS_ALG_SM4) {
282         return HksThreeStageAuth(HKS_AUTH_ID_SYM_CIPHER, keyNode);
283     }
284     return HKS_ERROR_INVALID_ALGORITHM;
285 }
286 
GetCryptoCtx(const struct HuksKeyNode * keyNode)287 static void *GetCryptoCtx(const struct HuksKeyNode *keyNode)
288 {
289     struct HksParam *ctxParam = NULL;
290     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
291 
292     return (ret != HKS_SUCCESS || ctxParam == NULL) ? NULL : (void *)(uintptr_t)ctxParam->uint64Param;
293 }
294 
ClearCryptoCtx(const struct HuksKeyNode * keyNode)295 static void ClearCryptoCtx(const struct HuksKeyNode *keyNode)
296 {
297     struct HksParam *ctxParam = NULL;
298     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
299     if (ret != HKS_SUCCESS || ctxParam == NULL) {
300         return;
301     }
302 
303     ctxParam->uint64Param = (uint64_t)(uintptr_t)NULL;
304     return;
305 }
306 
SetCacheModeCtx(const struct HuksKeyNode * keyNode)307 static int32_t SetCacheModeCtx(const struct HuksKeyNode *keyNode)
308 {
309     struct HksParam *ctxParam = NULL;
310     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
311     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
312 
313     struct HksBlob *tempData = (struct HksBlob *)HksMalloc(sizeof(struct HksBlob));
314     HKS_IF_NULL_LOGE_RETURN(tempData, HKS_ERROR_MALLOC_FAIL, "get cache mode ctx malloc fail.")
315 
316     tempData->size = 0;
317     tempData->data = NULL;
318     ctxParam->uint64Param = (uint64_t)(uintptr_t)tempData;
319     return HKS_SUCCESS;
320 }
321 
CopyNewCachedData(const struct HksBlob * cachedBlob,const struct HksBlob * inData,uint8_t * newData,uint32_t newSize)322 static int32_t CopyNewCachedData(const struct HksBlob *cachedBlob, const struct HksBlob *inData,
323     uint8_t *newData, uint32_t newSize)
324 {
325     if (cachedBlob->size != 0) {
326         if (memcpy_s(newData, newSize, cachedBlob->data, cachedBlob->size) != EOK) {
327             HKS_LOG_E("memcpy cached data failed");
328             return HKS_ERROR_INSUFFICIENT_MEMORY;
329         }
330     }
331     if (inData->size != 0) {
332         if (memcpy_s(newData + cachedBlob->size, newSize - cachedBlob->size, inData->data, inData->size) != EOK) {
333             HKS_LOG_E("memcpy in data failed");
334             return HKS_ERROR_INSUFFICIENT_MEMORY;
335         }
336     }
337     return HKS_SUCCESS;
338 }
339 
GetNewCachedData(const struct HksBlob * cachedBlob,const struct HksBlob * inData,struct HksBlob * newBlob)340 static int32_t GetNewCachedData(const struct HksBlob *cachedBlob, const struct HksBlob *inData,
341     struct HksBlob *newBlob)
342 {
343     if ((cachedBlob->size > MAX_BUF_SIZE) || (inData->size > (MAX_BUF_SIZE - cachedBlob->size))) {
344         HKS_LOG_E("input data size too large, size = %" LOG_PUBLIC "u", inData->size);
345         return HKS_ERROR_INVALID_ARGUMENT;
346     }
347 
348     uint32_t newSize = cachedBlob->size + inData->size;
349     uint8_t *newData = (uint8_t *)HksMalloc(newSize);
350     HKS_IF_NULL_LOGE_RETURN(newData, HKS_ERROR_MALLOC_FAIL, "update cache data malloc fail.")
351 
352     int32_t ret = CopyNewCachedData(cachedBlob, inData, newData, newSize);
353     if (ret != HKS_SUCCESS) {
354         HKS_FREE(newData);
355         return ret;
356     }
357 
358     newBlob->data = newData;
359     newBlob->size = newSize;
360     return HKS_SUCCESS;
361 }
362 
UpdateCachedData(const struct HuksKeyNode * keyNode,const struct HksBlob * srcData)363 static int32_t UpdateCachedData(const struct HuksKeyNode *keyNode, const struct HksBlob *srcData)
364 {
365     struct HksParam *ctxParam = NULL;
366     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
367     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
368 
369     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
370     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_BAD_STATE, "ctx is invalid: null!")
371 
372     struct HksBlob *cachedData = (struct HksBlob *)ctx;
373     struct HksBlob *newCachedBlob = (struct HksBlob *)HksMalloc(sizeof(struct HksBlob));
374     HKS_IF_NULL_LOGE_RETURN(newCachedBlob, HKS_ERROR_MALLOC_FAIL, "malloc new blob failed")
375 
376     ret = GetNewCachedData(cachedData, srcData, newCachedBlob);
377     if (ret != HKS_SUCCESS) {
378         HKS_LOG_E("get new cached data failed, ret = %" LOG_PUBLIC "d", ret);
379         HKS_FREE(newCachedBlob);
380         return ret;
381     }
382 
383     HKS_FREE(cachedData->data);
384     HKS_FREE(cachedData);
385     ctxParam->uint64Param = (uint64_t)(uintptr_t)newCachedBlob;
386     return HKS_SUCCESS;
387 }
388 
FreeCachedData(struct HksBlob ** cachedData)389 static void FreeCachedData(struct HksBlob **cachedData)
390 {
391     if ((cachedData == NULL) || (*cachedData == NULL)) {
392         return;
393     }
394     if ((*cachedData)->data != NULL) {
395         (void)memset_s((*cachedData)->data, (*cachedData)->size, 0, (*cachedData)->size);
396         HKS_FREE((*cachedData)->data);
397     }
398     HKS_FREE(*cachedData);
399 }
400 
FinishCachedData(const struct HuksKeyNode * keyNode,const struct HksBlob * srcData,struct HksBlob * outData)401 static int32_t FinishCachedData(const struct HuksKeyNode *keyNode, const struct HksBlob *srcData,
402     struct HksBlob *outData)
403 {
404     struct HksParam *ctxParam = NULL;
405     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
406     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
407 
408     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
409     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_BAD_STATE, "ctx is invalid: null!")
410 
411     struct HksBlob *cachedData = (struct HksBlob *)ctx;
412     ret = GetNewCachedData(cachedData, srcData, outData);
413     HKS_IF_NOT_SUCC_LOGE(ret, "get new cached data failed, ret = %" LOG_PUBLIC "d", ret)
414 
415     FreeCachedData(&cachedData);
416     ctxParam->uint64Param = 0; /* clear ctx to NULL */
417     return ret;
418 }
419 
CheckCachedDataMaxSize(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,const uint32_t maxDataLen)420 static int32_t CheckCachedDataMaxSize(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
421     const uint32_t maxDataLen)
422 {
423     struct HksParam *ctxParam = NULL;
424     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
425     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
426 
427     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
428     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_BAD_STATE, "ctx is invalid: null!")
429 
430     struct HksBlob *cachedData = (struct HksBlob *)ctx;
431     if (maxDataLen < cachedData->size) {
432         HKS_LOG_E("catch already overflow, size = %" LOG_PUBLIC "u", cachedData->size);
433         return HKS_ERROR_INVALID_ARGUMENT;
434     }
435 
436     if (inData->size > (maxDataLen - cachedData->size)) {
437         HKS_LOG_E("input data size too large, size = %" LOG_PUBLIC "u", inData->size);
438         return HKS_ERROR_EXCEED_LIMIT;
439     }
440 
441     return HKS_SUCCESS;
442 }
443 
CoreHashInit(const struct HuksKeyNode * keyNode,uint32_t alg)444 static int32_t CoreHashInit(const struct HuksKeyNode *keyNode, uint32_t alg)
445 {
446     struct HksParam *ctxParam = NULL;
447     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
448     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
449 
450     void *ctx = NULL;
451 
452     ret = HksCryptoHalHashInit(alg, &ctx);
453     if (ret != HKS_SUCCESS)  {
454         HKS_LOG_E("hal hash init failed ret : %" LOG_PUBLIC "d", ret);
455         return ret;
456     }
457     ctxParam->uint64Param = (uint64_t)(uintptr_t)ctx;
458     return HKS_SUCCESS;
459 }
460 
CoreHashUpdate(const struct HuksKeyNode * keyNode,const struct HksBlob * srcData)461 static int32_t CoreHashUpdate(const struct HuksKeyNode *keyNode, const struct HksBlob *srcData)
462 {
463     void *ctx = GetCryptoCtx(keyNode);
464     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_BAD_STATE, "ctx is invalid: null!")
465 
466     int32_t ret = HksCryptoHalHashUpdate(srcData, ctx);
467     HKS_IF_NOT_SUCC_LOGE(ret, "hal hash update failed ret : %" LOG_PUBLIC "d", ret)
468 
469     return ret;
470 }
471 
CoreHashFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * srcData,struct HksBlob * outData)472 static int32_t CoreHashFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *srcData,
473     struct HksBlob *outData)
474 {
475     struct HksParam *ctxParam = NULL;
476     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
477     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
478 
479     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
480     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_BAD_STATE, "ctx is invalid: null!")
481 
482     outData->size = MAX_HASH_SIZE;
483     outData->data = (uint8_t *)HksMalloc(MAX_HASH_SIZE);
484     HKS_IF_NULL_LOGE_RETURN(outData->data, HKS_ERROR_MALLOC_FAIL, "malloc fail.")
485 
486     ret = HksCryptoHalHashFinal(srcData, &ctx, outData);
487     if (ret != HKS_SUCCESS) {
488         HKS_LOG_E("hal hash final failed ret : %" LOG_PUBLIC "d", ret);
489         HKS_FREE_BLOB(*outData);
490     }
491 
492     ctxParam->uint64Param = 0; /* clear ctx to NULL */
493     return ret;
494 }
495 
CheckSignVerifyParams(const struct HuksKeyNode * keyNode,const struct HksBlob * outData)496 static int32_t CheckSignVerifyParams(const struct HuksKeyNode *keyNode, const struct HksBlob *outData)
497 {
498     HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(outData), HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
499 
500     struct HksParam *tmpParam = NULL;
501     int32_t ret = HksGetParam(keyNode->keyBlobParamSet, HKS_TAG_ALGORITHM, &tmpParam);
502     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get alg from keyNode failed!")
503 
504     uint32_t alg = tmpParam->uint32Param;
505 
506     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_PURPOSE, &tmpParam);
507     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get purpoes from keyNode failed!")
508 
509     uint32_t purpose = tmpParam->uint32Param;
510 
511     ret = HksGetParam(keyNode->keyBlobParamSet, HKS_TAG_KEY_SIZE, &tmpParam);
512     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get key size from keyNode failed!")
513 
514     uint32_t keySize = tmpParam->uint32Param;
515 
516     ret = HksCheckSignature((purpose == HKS_KEY_PURPOSE_SIGN) ? HKS_CMD_ID_SIGN : HKS_CMD_ID_VERIFY,
517         alg, keySize, outData);
518     HKS_IF_NOT_SUCC_LOGE(ret, "check signature failed!")
519 
520     return ret;
521 }
522 
CoreSignVerify(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData)523 static int32_t CoreSignVerify(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
524     struct HksBlob *outData)
525 {
526     int32_t ret = CheckSignVerifyParams(keyNode, outData);
527     HKS_IF_NOT_SUCC_RETURN(ret, ret)
528 
529     struct HksBlob rawKey = { 0, NULL };
530     ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
531     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerify get raw key failed!")
532 
533     struct HksUsageSpec usageSpec;
534     (void)memset_s(&usageSpec, sizeof(struct HksUsageSpec), 0, sizeof(struct HksUsageSpec));
535     HksFillUsageSpec(keyNode->runtimeParamSet, &usageSpec);
536     SetRsaPssSaltLenType(keyNode->runtimeParamSet, &usageSpec);
537 
538     if (usageSpec.purpose == HKS_KEY_PURPOSE_SIGN) {
539         ret = HksCryptoHalSign(&rawKey, &usageSpec, inData, outData);
540     } else {
541         ret = HksCryptoHalVerify(&rawKey, &usageSpec, inData, outData);
542     }
543     HKS_IF_NOT_SUCC_LOGE(ret, "SignVerify Finish failed, purpose = 0x%" LOG_PUBLIC "x, ret = %" LOG_PUBLIC "d",
544         usageSpec.purpose, ret)
545 
546     (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
547     HKS_FREE(rawKey.data);
548     return ret;
549 }
550 
FreeSignVerifyCtx(const struct HuksKeyNode * keyNode)551 static void FreeSignVerifyCtx(const struct HuksKeyNode *keyNode)
552 {
553     struct HksParam *ctxParam = NULL;
554     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
555     if (ret != HKS_SUCCESS) {
556         HKS_LOG_E("get ctx from keyNode failed!");
557         return;
558     }
559     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
560     if (ctx == NULL) {
561         return;
562     }
563 
564     struct HksParam *algParam = NULL;
565     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
566     if (ret != HKS_SUCCESS) {
567         HKS_LOG_E("append cipher get alg param failed!");
568         return;
569     }
570     struct HksParam *digestParam = NULL;
571     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_DIGEST, &digestParam);
572     if (ret != HKS_SUCCESS) {
573         HKS_LOG_E("append cipher get digest param failed!");
574         return;
575     }
576     if (HksCheckNeedCache(algParam->uint32Param, digestParam->uint32Param) == HKS_SUCCESS) {
577         struct HksBlob *cachedData = (struct HksBlob *)ctx;
578         FreeCachedData(&cachedData);
579     } else {
580         HksCryptoHalHashFreeCtx(&ctx);
581     }
582 
583     ctxParam->uint64Param = 0; /* clear ctx to NULL */
584 }
585 
CheckWhetherUpdateAesNonce(struct HksParamSet ** runtimeParamSet,const struct HksParamSet * keyBlobParamSet,bool * needRegenerateNonce)586 static int32_t CheckWhetherUpdateAesNonce(struct HksParamSet **runtimeParamSet,
587     const struct HksParamSet *keyBlobParamSet, bool *needRegenerateNonce)
588 {
589     struct HksParam *algParam = NULL;
590     int32_t ret = HksGetParam(*runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
591     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get alg param failed!")
592     if (algParam->uint32Param != HKS_ALG_AES) {
593         *needRegenerateNonce = false;
594         return HKS_SUCCESS;
595     }
596 
597     struct HksParam *modeParam = NULL;
598     ret = HksGetParam(*runtimeParamSet, HKS_TAG_BLOCK_MODE, &modeParam);
599     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get mode param failed!")
600     if (modeParam->uint32Param != HKS_MODE_GCM && modeParam->uint32Param != HKS_MODE_CCM) {
601         *needRegenerateNonce = false;
602         return HKS_SUCCESS;
603     }
604     struct HksParam *purposeParam = NULL;
605     ret = HksGetParam(*runtimeParamSet, HKS_TAG_PURPOSE, &purposeParam);
606     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get purpose param failed!")
607     if (purposeParam->uint32Param != HKS_KEY_PURPOSE_ENCRYPT) {
608         *needRegenerateNonce = false;
609         return HKS_SUCCESS;
610     }
611 
612     struct HksParam *authPurposeParam = NULL;
613     int32_t ret1 = HksGetParam(keyBlobParamSet, HKS_TAG_KEY_AUTH_PURPOSE, &authPurposeParam);
614     struct HksParam *nonceParam = NULL;
615     int32_t ret2 = HksGetParam(*runtimeParamSet, HKS_TAG_NONCE, &nonceParam);
616     if (ret1 == HKS_SUCCESS && ret2 == HKS_SUCCESS) {
617         HKS_LOG_E("do not support pass access control and nonce params together");
618         return HKS_ERROR_NOT_SUPPORTED;
619     }
620     if (ret1 != HKS_SUCCESS && ret2 == HKS_SUCCESS) {
621         *needRegenerateNonce = false;
622         return HKS_SUCCESS;
623     }
624     *needRegenerateNonce = true;
625     return HKS_SUCCESS;
626 }
627 
AddNonceToParamSet(struct HksParamSet ** runtimeParamSet,struct HksParam * nonceParams,uint32_t paramsCnt)628 static int32_t AddNonceToParamSet(struct HksParamSet **runtimeParamSet, struct HksParam *nonceParams,
629     uint32_t paramsCnt)
630 {
631     struct HksParamSet *paramSet = NULL;
632     int32_t ret = HksInitParamSet(&paramSet);
633     if (ret != HKS_SUCCESS) {
634         HKS_LOG_E("init keyNode param set fail");
635         return ret;
636     }
637     for (uint32_t i = 0; i < (*runtimeParamSet)->paramsCnt; ++i) {
638         if ((*runtimeParamSet)->params[i].tag != HKS_TAG_NONCE) {
639             ret = HksAddParams(paramSet, &(*runtimeParamSet)->params[i], 1);
640             if (ret != HKS_SUCCESS) {
641                 HksFreeParamSet(&paramSet);
642                 HKS_LOG_E("add runtime params fail");
643                 return ret;
644             }
645         }
646     }
647     ret = HksAddParams(paramSet, nonceParams, paramsCnt);
648     if (ret != HKS_SUCCESS) {
649         HksFreeParamSet(&paramSet);
650         HKS_LOG_E("add nonceParams fail");
651         return ret;
652     }
653     ret = HksBuildParamSet(&paramSet);
654     if (ret != HKS_SUCCESS) {
655         HksFreeParamSet(&paramSet);
656         HKS_LOG_E("build paramSet fail");
657         return ret;
658     }
659     HksFreeParamSet(runtimeParamSet);
660     *runtimeParamSet = paramSet;
661 
662     return HKS_SUCCESS;
663 }
664 
UpdateNonceForAesAeMode(struct HksParamSet ** runtimeParamSet,const struct HksParamSet * keyBlobParamSet,bool isCcm)665 static int32_t UpdateNonceForAesAeMode(struct HksParamSet **runtimeParamSet, const struct HksParamSet *keyBlobParamSet,
666     bool isCcm)
667 {
668     bool needRegenerateNonce = false;
669     int32_t ret = CheckWhetherUpdateAesNonce(runtimeParamSet, keyBlobParamSet, &needRegenerateNonce);
670     if (ret != HKS_SUCCESS) {
671         return ret;
672     }
673     if (needRegenerateNonce == false) {
674         return ret;
675     }
676 
677     uint32_t nonceLen = isCcm ? HKS_AES_CCM_NONCE_LEN : HKS_AES_GCM_NONCE_LEN;
678     uint8_t* data = (uint8_t *)HksMalloc(nonceLen);
679     HKS_IF_NULL_LOGE_RETURN(data, HKS_ERROR_MALLOC_FAIL, "malloc nonce param set failed!")
680 
681     struct HksParam params[] = {
682         {
683             .tag = HKS_TAG_NONCE,
684             .blob.data = data,
685             .blob.size = nonceLen
686         }, {
687             .tag = HKS_TAG_AES_GCM_NEED_REGENERATE_NONCE,
688             .boolParam = true
689         },
690     };
691 
692     ret = HksCryptoHalFillRandom(&params[0].blob);
693     if (ret != HKS_SUCCESS) {
694         HKS_FREE(params[0].blob.data);
695         HKS_LOG_E("get random failed");
696         return ret;
697     }
698 
699     ret = AddNonceToParamSet(runtimeParamSet, params, HKS_ARRAY_SIZE(params));
700     HKS_FREE(params[0].blob.data);
701     if (ret != HKS_SUCCESS) {
702         HKS_LOG_E("add nonce failed");
703         return ret;
704     }
705     return HKS_SUCCESS;
706 }
707 
CoreCipherInit(const struct HuksKeyNode * keyNode)708 static int32_t CoreCipherInit(const struct HuksKeyNode *keyNode)
709 {
710     int32_t ret = UpdateNonceForAesAeMode((struct HksParamSet **)(unsigned long)&keyNode->runtimeParamSet,
711         keyNode->keyBlobParamSet, false);
712     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "update aes gcm nonce failed")
713 
714     struct HksParam *ctxParam = NULL;
715     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
716     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
717 
718     struct HksParam *purposeParam = NULL;
719     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_PURPOSE, &purposeParam);
720     HKS_IF_NOT_SUCC_RETURN(ret, HKS_ERROR_CHECK_GET_PURPOSE_FAIL)
721 
722     struct HksBlob rawKey = { 0, NULL };
723     struct HksUsageSpec *usageSpec = NULL;
724     do {
725         uint8_t tmpData[HKS_TEMP_SIZE] = {0};
726         struct HksBlob tmpInData = { HKS_TEMP_SIZE, tmpData };
727         bool isEncrypt = (purposeParam->uint32Param == HKS_KEY_PURPOSE_ENCRYPT) ? true : false;
728         ret = HksBuildCipherUsageSpec(keyNode->runtimeParamSet, isEncrypt, &tmpInData, &usageSpec);
729         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build cipher usage failed")
730 
731         ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
732         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "cipher get raw key failed")
733 
734         void *ctx = NULL;
735         if (purposeParam->uint32Param == HKS_KEY_PURPOSE_ENCRYPT) {
736             ret = HksCryptoHalEncryptInit(&rawKey, usageSpec, &ctx);
737         } else {
738             ret = HksCryptoHalDecryptInit(&rawKey, usageSpec, &ctx);
739         }
740         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "cipher ctx init failed, ret = %" LOG_PUBLIC "d", ret)
741         ctxParam->uint64Param = (uint64_t)(uintptr_t)ctx;
742     } while (0);
743 
744     if (rawKey.data != NULL) {
745         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
746     }
747     HKS_FREE(rawKey.data);
748     HksFreeUsageSpec(&usageSpec);
749     return ret;
750 }
751 
CoreCipherUpdate(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)752 static int32_t CoreCipherUpdate(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
753     struct HksBlob *outData, uint32_t alg)
754 {
755     HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(outData), HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
756 
757     if (outData->size < inData->size) {
758         HKS_LOG_E("cipher update, out buffer too small size: %" LOG_PUBLIC "u, inSize: %" LOG_PUBLIC "u",
759             outData->size, inData->size);
760         return HKS_ERROR_BUFFER_TOO_SMALL;
761     }
762 
763     void *ctx = GetCryptoCtx(keyNode);
764     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is invalid: null!")
765 
766     struct HksParam *purposeParam = NULL;
767     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_PURPOSE, &purposeParam);
768     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "append cipher get purpose param failed!")
769 
770     if (purposeParam->uint32Param == HKS_KEY_PURPOSE_ENCRYPT) {
771         ret = HksCryptoHalEncryptUpdate(inData, ctx, outData, alg);
772     } else {
773         ret = HksCryptoHalDecryptUpdate(inData, ctx, outData, alg);
774     }
775     HKS_IF_NOT_SUCC_LOGE(ret, "cipher update failed! ret : %" LOG_PUBLIC "d", ret)
776     return ret;
777 }
778 
AppendNonceWhenNeeded(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,const uint32_t nonceLen,struct HksBlob * outData,struct HksBlob tag)779 static int32_t AppendNonceWhenNeeded(const struct HuksKeyNode *keyNode,
780     const struct HksBlob *inData, const uint32_t nonceLen, struct HksBlob *outData, struct HksBlob tag)
781 {
782     struct HksParam *needAppendNonce = NULL;
783     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_AES_GCM_NEED_REGENERATE_NONCE, &needAppendNonce);
784     if (ret != HKS_SUCCESS) {
785         return HKS_SUCCESS;
786     }
787     if (needAppendNonce->boolParam != true) {
788         HKS_LOG_E("need regenerate nonce value invalid!");
789         return HKS_ERROR_INVALID_ARGUMENT;
790     }
791     struct HksParam *nonceParam = NULL;
792     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_NONCE, &nonceParam);
793     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_NONCE_FAIL, "append cipher get nonce param failed!")
794     if (nonceParam->blob.size != nonceLen) {
795         HKS_LOG_E("nonce size invalid!");
796         return HKS_ERROR_INVALID_ARGUMENT;
797     }
798     if (memcpy_s(outData->data + inData->size + tag.size, nonceLen,
799         nonceParam->blob.data, nonceParam->blob.size) != EOK) {
800         HKS_LOG_E("memcpy cached data failed");
801         return HKS_ERROR_INSUFFICIENT_MEMORY;
802     }
803     outData->size += nonceParam->blob.size;
804     return HKS_SUCCESS;
805 }
806 
CoreAesEncryptFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)807 static int32_t CoreAesEncryptFinish(const struct HuksKeyNode *keyNode,
808     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
809 {
810     struct HksBlob tag = { 0, NULL };
811     int32_t ret = HksGetEncryptAeTag(keyNode->runtimeParamSet, inData, outData, &tag);
812     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher encrypt get ae tag failed!")
813 
814     ret = HksCheckFinishOutSize(true, keyNode->runtimeParamSet, inData, outData);
815     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "aes encrypt finish check data size failed")
816 
817     struct HksParam *ctxParam = NULL;
818     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
819     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get ctx from keyNode failed!")
820 
821     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
822     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is invalid: null!")
823 
824     struct HksParam *needAppendNonce = NULL;
825     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_AES_GCM_NEED_REGENERATE_NONCE, &needAppendNonce);
826     if (ret == HKS_SUCCESS && needAppendNonce->boolParam == true) {
827         if (outData->size < (inData->size + HKS_AE_TAG_LEN + HKS_AES_GCM_NONCE_LEN)) {
828             HKS_LOG_E("too small out buf!");
829             return HKS_ERROR_INVALID_ARGUMENT;
830         }
831     }
832 
833     ret = HksCryptoHalEncryptFinal(inData, &ctx, outData, &tag, alg);
834     ctxParam->uint64Param = 0; /* clear ctx to NULL */
835     if (ret != HKS_SUCCESS) {
836         HKS_LOG_E("aes encrypt Finish failed! ret : %" LOG_PUBLIC "d", ret);
837         return ret;
838     }
839 
840     ret = AppendNonceWhenNeeded(keyNode, inData, HKS_AES_GCM_NONCE_LEN, outData, tag);
841     if (ret != HKS_SUCCESS) {
842         HKS_LOG_E("appned nonce failed!");
843         return ret;
844     }
845 
846     outData->size += tag.size;
847     return HKS_SUCCESS;
848 }
849 
CoreAesDecryptFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)850 static int32_t CoreAesDecryptFinish(const struct HuksKeyNode *keyNode,
851     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
852 {
853     bool isAes = false;
854     bool isAeMode = false;
855     int32_t ret = HksCheckAesAeMode(keyNode->runtimeParamSet, &isAes, &isAeMode);
856     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get aeMode failed!")
857 
858     struct HksBlob tag = { 0, NULL };
859     if (isAes && isAeMode) {
860         struct HksParam *tagParam = NULL;
861         ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_AE_TAG, &tagParam);
862         if (ret != HKS_SUCCESS || tagParam == NULL) {
863             HKS_LOG_E("get tag failed!");
864             return ret;
865         }
866         tag = tagParam->blob;
867     }
868 
869     ret = HksCheckFinishOutSize(false, keyNode->runtimeParamSet, inData, outData);
870     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "aes decrypt finish check data size failed")
871 
872     struct HksParam *ctxParam = NULL;
873     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
874     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get ctx from keyNode failed!")
875 
876     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
877     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is invalid: null!")
878 
879     ret = HksCryptoHalDecryptFinal(inData, &ctx, outData, &tag, alg);
880     HKS_IF_NOT_SUCC_LOGE(ret, "cipher DecryptFinish failed! ret : %" LOG_PUBLIC "d", ret)
881 
882     ctxParam->uint64Param = 0; /* clear ctx to NULL */
883     return ret;
884 }
885 
CoreAesCcmCipherFinish(const struct HuksKeyNode * keyNode,const bool isEncrypt,const struct HksBlob * inData,struct HksBlob * outData)886 static int32_t CoreAesCcmCipherFinish(const struct HuksKeyNode *keyNode, const bool isEncrypt,
887     const struct HksBlob *inData, struct HksBlob *outData)
888 {
889     int32_t ret = HksCheckFinishOutSize(isEncrypt, keyNode->runtimeParamSet, inData, outData);
890     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ccm check data size failed")
891 
892     struct HksBlob rawKey = { 0, NULL };
893     struct HksUsageSpec *usageSpec = NULL;
894     do {
895         uint8_t tmpData[HKS_TEMP_SIZE] = {0};
896         struct HksBlob tmpInData = { HKS_TEMP_SIZE, tmpData };
897         ret = HksBuildCipherUsageSpec(keyNode->runtimeParamSet, isEncrypt, &tmpInData, &usageSpec);
898         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm build cipher usage failed")
899 
900         ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
901         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm get raw key failed")
902 
903         struct HksParam *needAppendNonce = NULL;
904         ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_AES_GCM_NEED_REGENERATE_NONCE, &needAppendNonce);
905         if (ret == HKS_SUCCESS && needAppendNonce->boolParam == true) {
906             if (outData->size < (inData->size + HKS_AE_TAG_LEN + HKS_AES_CCM_NONCE_LEN)) {
907                 HKS_IF_NOT_SUCC_LOGE_BREAK(HKS_ERROR_INVALID_ARGUMENT, "ccm too small out buf")
908             }
909         }
910 
911         struct HksAeadParam *aeadParam = usageSpec->algParam;
912         aeadParam->payloadLen = inData->size;
913         if (usageSpec->purpose == HKS_KEY_PURPOSE_ENCRYPT) {
914             struct HksBlob tag = { 0, NULL };
915             ret = HksGetEncryptAeTag(keyNode->runtimeParamSet, inData, outData, &tag);
916             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm encrypt get ae tag failed")
917             ret = HksCryptoHalEncrypt(&rawKey, usageSpec, inData, outData, &tag);
918             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm encrypt error")
919             ret = AppendNonceWhenNeeded(keyNode, inData, HKS_AES_CCM_NONCE_LEN, outData, tag);
920             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm append nonce failed")
921             outData->size += tag.size;
922         } else {
923             ret = HksGetDecryptAeTag(keyNode->runtimeParamSet, usageSpec);
924             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ccm decrypt get ae tag failed")
925             ret = HksCryptoHalDecrypt(&rawKey, usageSpec, inData, outData);
926         }
927     } while (0);
928 
929     HKS_MEMSET_FREE_BLOB(rawKey);
930     HksFreeUsageSpec(&usageSpec);
931     return ret;
932 }
933 
CoreAesCipherInit(const struct HuksKeyNode * keyNode)934 static int32_t CoreAesCipherInit(const struct HuksKeyNode *keyNode)
935 {
936     struct HksParam *modeParam = NULL;
937     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_BLOCK_MODE, &modeParam);
938     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher init get block mode failed")
939 
940     if (modeParam->uint32Param == HKS_MODE_CCM) {
941         ret = UpdateNonceForAesAeMode((struct HksParamSet **)(unsigned long)&keyNode->runtimeParamSet,
942             keyNode->keyBlobParamSet, true);
943         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "update aes gcm nonce failed")
944         return SetCacheModeCtx(keyNode);
945     }
946 
947     return CoreCipherInit(keyNode);
948 }
949 
CoreAesCipherUpdate(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)950 static int32_t CoreAesCipherUpdate(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
951     struct HksBlob *outData, uint32_t alg)
952 {
953     struct HksParam *modeParam = NULL;
954     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_BLOCK_MODE, &modeParam);
955     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher update get block mode failed")
956 
957     if (modeParam->uint32Param == HKS_MODE_CCM) {
958         ret = CheckCachedDataMaxSize(keyNode, inData, HKS_CIPHER_CCM_MODE_MAX_DATA_LEN);
959         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher update in data is too long")
960         if (outData != NULL) {
961             outData->size = 0;
962         }
963         return UpdateCachedData(keyNode, inData);
964     }
965 
966     return CoreCipherUpdate(keyNode, inData, outData, alg);
967 }
968 
CoreAesCipherFinish(const struct HuksKeyNode * keyNode,const bool isEncrypt,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)969 static int32_t CoreAesCipherFinish(const struct HuksKeyNode *keyNode, const bool isEncrypt,
970     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
971 {
972     struct HksParam *modeParam = NULL;
973     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_BLOCK_MODE, &modeParam);
974     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher finish get block mode failed")
975     if (modeParam->uint32Param == HKS_MODE_CCM) {
976         ret = CheckCachedDataMaxSize(keyNode, inData, HKS_CIPHER_CCM_MODE_MAX_DATA_LEN);
977         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher finish in data size too long")
978 
979         struct HksBlob tempInData = { 0, NULL };
980         ret = FinishCachedData(keyNode, inData, &tempInData);
981         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher finish get aes cipher cached data failed")
982 
983         ret = CoreAesCcmCipherFinish(keyNode, isEncrypt, &tempInData, outData);
984         HKS_FREE_BLOB(tempInData);
985         return ret;
986     }
987 
988     if (isEncrypt) {
989         return CoreAesEncryptFinish(keyNode, inData, outData, alg);
990     }
991 
992     return CoreAesDecryptFinish(keyNode, inData, outData, alg);
993 }
994 
CoreSm4EncryptFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)995 static int32_t CoreSm4EncryptFinish(const struct HuksKeyNode *keyNode,
996     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
997 {
998     int32_t ret = HksCheckFinishOutSize(true, keyNode->runtimeParamSet, inData, outData);
999     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "sm4 encrypt finish check data size failed")
1000 
1001     struct HksParam *ctxParam = NULL;
1002     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1003     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get ctx from keyNode failed!")
1004 
1005     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
1006     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is invalid: null!")
1007 
1008     ret = HksCryptoHalEncryptFinal(inData, &ctx, outData, NULL, alg);
1009     if (ret != HKS_SUCCESS) {
1010         HKS_LOG_E("sm4 encrypt Finish failed! ret : %" LOG_PUBLIC "d", ret);
1011         ctxParam->uint64Param = 0; /* clear ctx to NULL */
1012         return ret;
1013     }
1014 
1015     ctxParam->uint64Param = 0; /* clear ctx to NULL */
1016     return HKS_SUCCESS;
1017 }
1018 
CoreSm4DecryptFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1019 static int32_t CoreSm4DecryptFinish(const struct HuksKeyNode *keyNode,
1020     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1021 {
1022     int32_t ret = HksCheckFinishOutSize(false, keyNode->runtimeParamSet, inData, outData);
1023     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "sm4 decrypt finish check data size failed")
1024 
1025     struct HksParam *ctxParam = NULL;
1026     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1027     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get ctx from keyNode failed!")
1028 
1029     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
1030     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is invalid: null!")
1031 
1032     ret = HksCryptoHalDecryptFinal(inData, &ctx, outData, NULL, alg);
1033     HKS_IF_NOT_SUCC_LOGE(ret, "cipher DecryptFinish failed! ret : %" LOG_PUBLIC "d", ret)
1034 
1035     ctxParam->uint64Param = 0; /* clear ctx to NULL */
1036     return ret;
1037 }
1038 
RsaCipherFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData)1039 static int32_t RsaCipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
1040     struct HksBlob *outData)
1041 {
1042     HKS_LOG_E("rsa inData.size = %" LOG_PUBLIC "u", inData->size);
1043     struct HksBlob rawKey = { 0, NULL };
1044     int32_t ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
1045     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerify get raw key failed!")
1046 
1047     struct HksUsageSpec usageSpec;
1048     (void)memset_s(&usageSpec, sizeof(struct HksUsageSpec), 0, sizeof(struct HksUsageSpec));
1049     HksFillUsageSpec(keyNode->runtimeParamSet, &usageSpec);
1050 
1051     bool isEncrypt = (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT);
1052     ret = HksCheckFinishOutSize(isEncrypt, keyNode->runtimeParamSet, inData, outData);
1053     if (ret != HKS_SUCCESS) {
1054         HKS_LOG_E("rsa cipher finish check data size failed");
1055         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1056         HKS_FREE(rawKey.data);
1057         return ret;
1058     }
1059 
1060     if (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT) {
1061         struct HksBlob tag = { 0, NULL };
1062         ret = HksCryptoHalEncrypt(&rawKey, &usageSpec, inData, outData, &tag);
1063     } else {
1064         ret = HksCryptoHalDecrypt(&rawKey, &usageSpec, inData, outData);
1065     }
1066     HKS_IF_NOT_SUCC_LOGE(ret, "rsa cipher Finish failed, purpose = 0x%" LOG_PUBLIC "x, ret = %" LOG_PUBLIC "d",
1067         usageSpec.purpose, ret)
1068 
1069     (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1070     HKS_FREE(rawKey.data);
1071     return ret;
1072 }
1073 
Sm2CipherFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData)1074 static int32_t Sm2CipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
1075     struct HksBlob *outData)
1076 {
1077     HKS_LOG_I("sm2 CipherFinish, inData.size = %" LOG_PUBLIC "u", inData->size);
1078     struct HksBlob rawKey = { 0, NULL };
1079     int32_t ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
1080     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerify get raw key failed!")
1081 
1082     struct HksUsageSpec usageSpec = {0};
1083     HksFillUsageSpec(keyNode->runtimeParamSet, &usageSpec);
1084 
1085     bool isEncrypt = (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT);
1086     ret = HksCheckFinishOutSize(isEncrypt, keyNode->runtimeParamSet, inData, outData);
1087     if (ret != HKS_SUCCESS) {
1088         HKS_LOG_E("sm2 cipher finish check data size failed");
1089         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1090         HKS_FREE(rawKey.data);
1091         return ret;
1092     }
1093 
1094     if (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT) {
1095         struct HksBlob tag = { 0, NULL };
1096         ret = HksCryptoHalEncrypt(&rawKey, &usageSpec, inData, outData, &tag);
1097     } else {
1098         ret = HksCryptoHalDecrypt(&rawKey, &usageSpec, inData, outData);
1099     }
1100     HKS_IF_NOT_SUCC_LOGE(ret, "sm2 cipher Finish failed, purpose = 0x%" LOG_PUBLIC "x, ret = %" LOG_PUBLIC "d",
1101         usageSpec.purpose, ret)
1102 
1103     (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1104     HKS_FREE(rawKey.data);
1105     return ret;
1106 }
1107 
CoreRsaCipherFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData)1108 static int32_t CoreRsaCipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
1109     struct HksBlob *outData)
1110 {
1111     struct HksBlob tempInData = { 0, NULL };
1112     int32_t ret = FinishCachedData(keyNode, inData, &tempInData);
1113     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get rsa cipher cached data failed")
1114 
1115     ret = RsaCipherFinish(keyNode, &tempInData, outData);
1116     HKS_FREE_BLOB(tempInData);
1117     return ret;
1118 }
1119 
CoreSm2CipherFinish(const struct HuksKeyNode * keyNode,const struct HksBlob * inData,struct HksBlob * outData)1120 static int32_t CoreSm2CipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData,
1121     struct HksBlob *outData)
1122 {
1123     struct HksBlob tempInData = { 0, NULL };
1124     int32_t ret = FinishCachedData(keyNode, inData, &tempInData);
1125     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get sm2 cipher cached data failed")
1126 
1127     ret = Sm2CipherFinish(keyNode, &tempInData, outData);
1128     HKS_FREE_BLOB(tempInData);
1129     return ret;
1130 }
1131 
FreeCryptoCtx(const struct HuksKeyNode * keyNode,uint32_t alg)1132 static void FreeCryptoCtx(const struct HuksKeyNode *keyNode, uint32_t alg)
1133 {
1134     struct HksParam *ctxParam = NULL;
1135     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1136     if (ret != HKS_SUCCESS) {
1137         HKS_LOG_E("get ctx from keyNode failed!");
1138         return;
1139     }
1140     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
1141     if (ctx == NULL) {
1142         return;
1143     }
1144 
1145     if (alg == HKS_ALG_AES) {
1146         struct HksParam *modeParam = NULL;
1147         ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_BLOCK_MODE, &modeParam);
1148         if (ret != HKS_SUCCESS) {
1149             HKS_LOG_E("get ctx from keyNode failed!");
1150             return;
1151         }
1152         if (modeParam->uint32Param == HKS_MODE_CCM) {
1153             struct HksBlob *cachedData = (struct HksBlob *)ctx;
1154             HKS_LOG_D("FreeCryptoCtx free ccm cache data!");
1155             FreeCachedData(&cachedData);
1156         } else {
1157             HksCryptoHalEncryptFreeCtx(&ctx, alg);
1158         }
1159     } else if (alg == HKS_ALG_SM4) {
1160         HksCryptoHalEncryptFreeCtx(&ctx, alg);
1161     } else {
1162         struct HksBlob *cachedData = (struct HksBlob *)ctx;
1163         FreeCachedData(&cachedData);
1164     }
1165 
1166     ctxParam->uint64Param = 0; /* clear ctx to NULL */
1167 }
1168 
GetRawkey(const struct HuksKeyNode * keyNode,struct HksBlob * rawKey)1169 static int32_t GetRawkey(const struct HuksKeyNode *keyNode, struct HksBlob *rawKey)
1170 {
1171     if (GetCryptoCtx(keyNode) != NULL) {
1172         HKS_LOG_E("avoid running into this function multiple times!");
1173         return HKS_FAILURE;
1174     }
1175 
1176     int32_t ret = HksThreeStageAuth(HKS_AUTH_ID_DERIVE, keyNode);
1177     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "derive auth failed!")
1178 
1179     ret = HksGetRawKey(keyNode->keyBlobParamSet, rawKey);
1180     HKS_IF_NOT_SUCC_LOGE(ret, "Derive get raw key failed!")
1181 
1182     return ret;
1183 }
1184 
FreeOutBlob(struct HksBlob ** out)1185 static void FreeOutBlob(struct HksBlob **out)
1186 {
1187     if ((out == NULL) || (*out == NULL)) {
1188         return;
1189     }
1190     HKS_FREE((*out)->data);
1191     HKS_FREE(*out);
1192 }
1193 
ConstructDervieBlob(const struct HksParamSet * paramSet,struct HksBlob ** out)1194 static int32_t ConstructDervieBlob(const struct HksParamSet *paramSet, struct HksBlob **out)
1195 {
1196     struct HksParam *deriveSizeParam = NULL;
1197     int32_t ret = HksGetParam(paramSet, HKS_TAG_DERIVE_KEY_SIZE, &deriveSizeParam);
1198     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "get derive size failed, ret = %" LOG_PUBLIC "d", ret)
1199 
1200     uint32_t deriveSize = deriveSizeParam->uint32Param;
1201     if ((deriveSize == 0) || (deriveSize > MAX_OUT_BLOB_SIZE)) {
1202         HKS_LOG_E("derive size invalid, size = %" LOG_PUBLIC "u", deriveSize);
1203         return HKS_ERROR_INVALID_ARGUMENT;
1204     }
1205 
1206     struct HksBlob *tempOut = (struct HksBlob *)HksMalloc(sizeof(struct HksBlob));
1207     HKS_IF_NULL_LOGE_RETURN(tempOut, HKS_ERROR_MALLOC_FAIL, "construct derive blob malloc failed")
1208 
1209     tempOut->data = (uint8_t *)HksMalloc(deriveSize);
1210     if (tempOut->data == NULL) {
1211         HKS_FREE(tempOut);
1212         HKS_LOG_E("malloc out derive blob data failed.");
1213         return HKS_ERROR_MALLOC_FAIL;
1214     }
1215     tempOut->size = deriveSize;
1216     *out = tempOut;
1217     return HKS_SUCCESS;
1218 }
1219 
ConstructAgreeBlob(struct HksBlob ** agreeOut)1220 static int32_t ConstructAgreeBlob(struct HksBlob **agreeOut)
1221 {
1222     struct HksBlob *agreeTemp = (struct HksBlob *)HksMalloc(sizeof(struct HksBlob));
1223     HKS_IF_NULL_LOGE_RETURN(agreeTemp, HKS_ERROR_MALLOC_FAIL, "malloc agreeTemp failed.")
1224 
1225     agreeTemp->size = MAX_KEY_SIZE;
1226     agreeTemp->data = (uint8_t *)HksMalloc(MAX_KEY_SIZE);
1227     if (agreeTemp->data == NULL) {
1228         HKS_LOG_E("malloc agreeTemp data failed.");
1229         HKS_FREE(agreeTemp);
1230         return HKS_ERROR_MALLOC_FAIL;
1231     }
1232     *agreeOut = agreeTemp;
1233     return HKS_SUCCESS;
1234 }
1235 
1236 
HksCoreSignVerifyThreeStageInit(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1237 int32_t HksCoreSignVerifyThreeStageInit(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1238     uint32_t alg)
1239 {
1240     (void)paramSet;
1241     int32_t ret = SignVerifyAuth(keyNode, keyNode->runtimeParamSet);
1242     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCoreSignVerifyThreeStageInit SignAuth fail ret : %" LOG_PUBLIC "d", ret)
1243 
1244     struct HksParam *algParam = NULL;
1245     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1246     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1247         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1248 
1249     uint32_t digest = alg;  // In signature or verify scenario, alg represents digest. See code {GetPurposeAndAlgorithm}
1250     HKS_LOG_I("Init cache or hash init.");
1251     if (HksCheckNeedCache(algParam->uint32Param, digest) == HKS_SUCCESS) {
1252         return SetCacheModeCtx(keyNode);
1253     } else {
1254         return CoreHashInit(keyNode, alg);
1255     }
1256 }
1257 
HksCoreSignVerifyThreeStageUpdate(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * signature,uint32_t alg)1258 int32_t HksCoreSignVerifyThreeStageUpdate(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1259     const struct HksBlob *srcData, struct HksBlob *signature, uint32_t alg)
1260 {
1261     (void)signature;
1262     (void)alg;
1263     (void)paramSet;
1264 
1265     struct HksParam *algParam = NULL;
1266     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1267     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1268         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1269 
1270     uint32_t digest = alg;  // In signature or verify scenario, alg represents digest. See code {GetPurposeAndAlgorithm}
1271     HKS_LOG_I("Update cache or hash update.");
1272     if (HksCheckNeedCache(algParam->uint32Param, digest) == HKS_SUCCESS) {
1273         return UpdateCachedData(keyNode, srcData);
1274     } else {
1275         return CoreHashUpdate(keyNode, srcData);
1276     }
1277 }
1278 
HksCoreSignVerifyThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1279 int32_t HksCoreSignVerifyThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1280     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1281 {
1282     (void)paramSet;
1283     (void)alg;
1284 
1285     struct HksBlob message = { 0, NULL };
1286     struct HksParam *purposeParam = NULL;
1287     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_PURPOSE, &purposeParam);
1288     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_PURPOSE_FAIL,
1289         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_PURPOSE)
1290 
1291     if (purposeParam->uint32Param == HKS_KEY_PURPOSE_SIGN) { /* inData indicates signature when processing verify */
1292         message.data = inData->data;
1293         message.size = inData->size;
1294     }
1295 
1296     struct HksParam *algParam = NULL;
1297     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1298     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1299         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1300 
1301     uint32_t digest = alg;  // In signature or verify scenario, alg represents digest. See code {GetPurposeAndAlgorithm}
1302 
1303     struct HksBlob signVerifyData = { 0, NULL };
1304     if (HksCheckNeedCache(algParam->uint32Param, digest) == HKS_SUCCESS) {
1305         ret = FinishCachedData(keyNode, &message, &signVerifyData);
1306     } else {
1307         ret = CoreHashFinish(keyNode, &message, &signVerifyData);
1308     }
1309     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "signVerify Finish get Data failed, ret = %" LOG_PUBLIC "d", ret)
1310 
1311     /* inData indicates signature when processing verify */
1312     ret = CoreSignVerify(keyNode, &signVerifyData,
1313         (purposeParam->uint32Param == HKS_KEY_PURPOSE_SIGN) ? outData : (struct HksBlob *)inData);
1314     HKS_FREE_BLOB(signVerifyData);
1315     return ret;
1316 }
1317 
HksCoreSignVerifyThreeStageAbort(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1318 int32_t HksCoreSignVerifyThreeStageAbort(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1319     uint32_t alg)
1320 {
1321     (void)paramSet;
1322     (void)alg;
1323 
1324     FreeSignVerifyCtx(keyNode);
1325     return HKS_SUCCESS;
1326 }
1327 
HksCoreCryptoThreeStageInit(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1328 int32_t HksCoreCryptoThreeStageInit(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1329     uint32_t alg)
1330 {
1331     (void)alg;
1332 
1333     int32_t ret = CipherAuth(keyNode, paramSet);
1334     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher init failed, ret = %" LOG_PUBLIC "d", ret)
1335 
1336     struct HksParam *algParam = NULL;
1337     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1338     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1339         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1340 
1341     HKS_LOG_I("Init cache or cipher init.");
1342 
1343     if ((algParam->uint32Param == HKS_ALG_RSA) || (algParam->uint32Param == HKS_ALG_SM2)) {
1344         return SetCacheModeCtx(keyNode);
1345     } else if (algParam->uint32Param == HKS_ALG_AES) {
1346         return CoreAesCipherInit(keyNode);
1347     } else if (algParam->uint32Param == HKS_ALG_SM4) {
1348         return CoreCipherInit(keyNode);
1349     } else {
1350         return HKS_ERROR_INVALID_ALGORITHM;
1351     }
1352 }
1353 
HksCoreCryptoThreeStageUpdate(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1354 int32_t HksCoreCryptoThreeStageUpdate(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1355     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1356 {
1357     (void)paramSet;
1358     struct HksParam *algParam = NULL;
1359     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1360     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1361         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1362 
1363     if ((algParam->uint32Param == HKS_ALG_RSA) || (algParam->uint32Param == HKS_ALG_SM2)) {
1364         return UpdateCachedData(keyNode, inData);
1365     } else if (algParam->uint32Param == HKS_ALG_AES) {
1366         return CoreAesCipherUpdate(keyNode, inData, outData, alg);
1367     } else if (algParam->uint32Param == HKS_ALG_SM4) {
1368         return CoreCipherUpdate(keyNode, inData, outData, alg);
1369     } else {
1370         return HKS_ERROR_INVALID_ALGORITHM;
1371     }
1372 }
1373 
HksCoreEncryptThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1374 int32_t HksCoreEncryptThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1375     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1376 {
1377     (void)paramSet;
1378     HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(outData), HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
1379 
1380     struct HksParam *algParam = NULL;
1381     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1382     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1383         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1384 
1385     if (algParam->uint32Param == HKS_ALG_RSA) {
1386         return CoreRsaCipherFinish(keyNode, inData, outData);
1387     } else if (algParam->uint32Param == HKS_ALG_SM2) {
1388         return CoreSm2CipherFinish(keyNode, inData, outData);
1389     } else if (algParam->uint32Param == HKS_ALG_AES) {
1390         return CoreAesCipherFinish(keyNode, true, inData, outData, alg);
1391     } else if (algParam->uint32Param == HKS_ALG_SM4) {
1392         return CoreSm4EncryptFinish(keyNode, inData, outData, alg);
1393     } else {
1394         return HKS_ERROR_INVALID_ALGORITHM;
1395     }
1396 }
1397 
HksCoreDecryptThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1398 int32_t HksCoreDecryptThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1399     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1400 {
1401     (void)paramSet;
1402     HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(outData), HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
1403 
1404     struct HksParam *algParam = NULL;
1405     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_ALGORITHM, &algParam);
1406     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
1407         "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM)
1408 
1409     if (algParam->uint32Param == HKS_ALG_RSA) {
1410         return CoreRsaCipherFinish(keyNode, inData, outData);
1411     } else if (algParam->uint32Param == HKS_ALG_SM2) {
1412         return CoreSm2CipherFinish(keyNode, inData, outData);
1413     } else if (algParam->uint32Param == HKS_ALG_AES) {
1414         return CoreAesCipherFinish(keyNode, false, inData, outData, alg);
1415     } else if (algParam->uint32Param == HKS_ALG_SM4) {
1416         return CoreSm4DecryptFinish(keyNode, inData, outData, alg);
1417     } else {
1418         return HKS_ERROR_INVALID_ALGORITHM;
1419     }
1420 }
1421 
HksCoreCryptoThreeStageAbort(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1422 int32_t HksCoreCryptoThreeStageAbort(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1423     uint32_t alg)
1424 {
1425     (void)paramSet;
1426     FreeCryptoCtx(keyNode, alg);
1427     return HKS_SUCCESS;
1428 }
1429 
HksCoreDeriveThreeStageInit(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1430 int32_t HksCoreDeriveThreeStageInit(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1431     uint32_t alg)
1432 {
1433     (void)keyNode;
1434     (void)paramSet;
1435     (void)alg;
1436 
1437     HKS_LOG_D("HksCoreDeriveThreeStageInit start");
1438     return HKS_SUCCESS;
1439 }
1440 
HksCoreDeriveThreeStageUpdate(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * derive,uint32_t alg)1441 int32_t HksCoreDeriveThreeStageUpdate(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1442     const struct HksBlob *srcData, struct HksBlob *derive, uint32_t alg)
1443 {
1444     (void)srcData;
1445     (void)alg;
1446     (void)derive;
1447     (void)paramSet;
1448     struct HksParam *ctxParam = NULL;
1449     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1450     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
1451 
1452     struct HksBlob rawKey = { 0, NULL };
1453     do {
1454         ret = GetRawkey(keyNode, &rawKey);
1455         HKS_IF_NOT_SUCC_BREAK(ret)
1456 
1457         struct HksBlob *deriveBlob = NULL;
1458         ret = ConstructDervieBlob(keyNode->runtimeParamSet, &deriveBlob);
1459         HKS_IF_NOT_SUCC_BREAK(ret)
1460 
1461         struct HksKeyDerivationParam derParam = { { 0, NULL }, { 0, NULL }, 0, 0 };
1462         struct HksKeySpec derivationSpec = { 0, 0, &derParam };
1463         HksFillKeySpec(keyNode->runtimeParamSet, &derivationSpec);
1464         HksFillKeyDerivationParam(keyNode->runtimeParamSet, &derParam);
1465 
1466         ret = HksCryptoHalDeriveKey(&rawKey, &derivationSpec, deriveBlob);
1467         if (ret != HKS_SUCCESS) {
1468             HKS_LOG_E("HksCryptoHalDeriveKey fail");
1469             FreeOutBlob(&deriveBlob);
1470             break;
1471         }
1472 
1473         ctxParam->uint64Param = (uint64_t)(uintptr_t)deriveBlob;
1474     } while (0);
1475 
1476     if (rawKey.data != NULL) {
1477         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1478     }
1479     HKS_FREE(rawKey.data);
1480 
1481     return ret;
1482 }
1483 
DoBuildKeyBlobOrGetOutDataAction(const struct HksParamSet * paramSet,const struct HksBlob * restoreData,struct HksBlob * outData,uint8_t keyFlag,bool isNeedStorage)1484 static int32_t DoBuildKeyBlobOrGetOutDataAction(const struct HksParamSet *paramSet, const struct HksBlob *restoreData,
1485     struct HksBlob *outData, uint8_t keyFlag, bool isNeedStorage)
1486 {
1487     if (isNeedStorage) {
1488         return HksBuildKeyBlob(NULL, keyFlag, restoreData, paramSet, outData);
1489     }
1490     if (outData->size < restoreData->size) {
1491         HKS_LOG_E("outData size is too small, size : %" LOG_PUBLIC "u", outData->size);
1492         return HKS_ERROR_BUFFER_TOO_SMALL;
1493     }
1494     outData->size = restoreData->size;
1495     (void)memcpy_s(outData->data, outData->size, restoreData->data, outData->size);
1496     return HKS_SUCCESS;
1497 }
1498 
BuildAgreeDeriveKeyBlobOrGetOutData(const struct HksParamSet * paramSet,const struct HksBlob * restoreData,struct HksBlob * outData,uint8_t keyFlag,const struct HuksKeyNode * keyNode)1499 static int32_t BuildAgreeDeriveKeyBlobOrGetOutData(const struct HksParamSet *paramSet,
1500     const struct HksBlob *restoreData, struct HksBlob *outData, uint8_t keyFlag, const struct HuksKeyNode *keyNode)
1501 {
1502     bool isNeedStorageOrExported = false;
1503     struct HksParam *keyStorageFlagParam = NULL;
1504     uint32_t storageFlag = 0;
1505     int32_t ret = HksGetParam(keyNode->keyBlobParamSet, HKS_TAG_DERIVE_AGREE_KEY_STORAGE_FLAG, &keyStorageFlagParam);
1506     if (ret == HKS_ERROR_INVALID_ARGUMENT) {
1507         return ret;
1508     }
1509     if (ret == HKS_SUCCESS) {
1510         storageFlag = keyStorageFlagParam->uint32Param;
1511     } else {
1512         isNeedStorageOrExported = true;
1513     }
1514 
1515     bool isNeedStorage = false;
1516     HksCheckKeyNeedStored(paramSet, &isNeedStorage);
1517 
1518     if (isNeedStorage) {
1519         // the paramset is only used when the key needs be stored
1520         ret = HksCoreCheckAgreeDeriveFinishParams(restoreData, paramSet);
1521         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check agree finish key paramset failed!")
1522     }
1523 
1524     if (isNeedStorageOrExported) {
1525         // Whether the derived/agreed key needs to be stored was not specified when generating the key
1526         HKS_LOG_D("default mode of storage");
1527         return DoBuildKeyBlobOrGetOutDataAction(paramSet, restoreData, outData, keyFlag, isNeedStorage);
1528     }
1529     if ((storageFlag == HKS_STORAGE_ONLY_USED_IN_HUKS) == isNeedStorage) {
1530         HKS_LOG_D("need store flag: %" LOG_PUBLIC "d", storageFlag);
1531         ret = DoBuildKeyBlobOrGetOutDataAction(paramSet, restoreData, outData, keyFlag, isNeedStorage);
1532         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "DoBuildKeyBlobOrGetOutDataAction failed!")
1533     } else {
1534         HKS_LOG_E("store flags do not match: genKey flag is %" LOG_PUBLIC "d, use flag is %" LOG_PUBLIC "d",
1535             (storageFlag == HKS_STORAGE_ONLY_USED_IN_HUKS), isNeedStorage);
1536         ret = HKS_ERROR_BAD_STATE;
1537     }
1538     return ret;
1539 }
1540 
HksCoreDeriveThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1541 int32_t HksCoreDeriveThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1542     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1543 {
1544     HKS_LOG_D("HksCoreDeriveThreeStageFinish start");
1545     (void)inData;
1546     (void)alg;
1547     int32_t ret = CheckBlob(outData);
1548     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
1549 
1550     void *ctx = GetCryptoCtx(keyNode);
1551     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is NULL!")
1552 
1553     struct HksBlob *restoreData = (struct HksBlob *)ctx;
1554 
1555     ret = BuildAgreeDeriveKeyBlobOrGetOutData(paramSet, restoreData, outData, HKS_KEY_FLAG_DERIVE_KEY, keyNode);
1556 
1557     FreeCachedData(&restoreData);
1558     ClearCryptoCtx(keyNode);
1559     return ret;
1560 }
1561 
HksCoreDeriveThreeStageAbort(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1562 int32_t HksCoreDeriveThreeStageAbort(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1563     uint32_t alg)
1564 {
1565     (void)paramSet;
1566     (void)alg;
1567 
1568     void *ctx = GetCryptoCtx(keyNode);
1569     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is NULL!")
1570 
1571     struct HksBlob *restoreData = (struct HksBlob *)ctx;
1572 
1573     FreeCachedData(&restoreData);
1574     ClearCryptoCtx(keyNode);
1575     return HKS_SUCCESS;
1576 }
1577 
HksCoreAgreeThreeStageInit(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1578 int32_t HksCoreAgreeThreeStageInit(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1579     uint32_t alg)
1580 {
1581     (void)keyNode;
1582     (void)paramSet;
1583     (void)alg;
1584 
1585     int32_t ret = AgreeAuth(keyNode, keyNode->runtimeParamSet);
1586     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCoreAgreeThreeStageInit AgreeAuth fail ret : %" LOG_PUBLIC "d", ret)
1587 
1588     return HKS_SUCCESS;
1589 }
1590 
HksCoreAgreeThreeStageUpdate(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * signature,uint32_t alg)1591 int32_t HksCoreAgreeThreeStageUpdate(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1592     const struct HksBlob *srcData, struct HksBlob *signature, uint32_t alg)
1593 {
1594     (void)signature;
1595     (void)paramSet;
1596     (void)alg;
1597 
1598     struct HksParam *ctxParam = NULL;
1599     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1600     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
1601 
1602     if (ctxParam->uint64Param != 0) {
1603         HKS_LOG_E("avoid running into this function multiple times!");
1604         return HKS_FAILURE;
1605     }
1606 
1607     struct HksBlob rawKey = { 0, NULL };
1608     struct HksBlob publicKey = { 0, NULL };
1609 
1610     do {
1611         ret = GetHksPubKeyInnerFormat(keyNode->runtimeParamSet, srcData, &publicKey);
1612         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get public key from x509 format failed, ret = %" LOG_PUBLIC "d.", ret)
1613 
1614         struct HksBlob *agreeTemp = NULL;
1615         ret = ConstructAgreeBlob(&agreeTemp);
1616         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksCoreAgreeBuildData failed, ret = %" LOG_PUBLIC "d.", ret)
1617 
1618         ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
1619         if (ret != HKS_SUCCESS) {
1620             HKS_LOG_E("agree get raw key failed!");
1621             FreeOutBlob(&agreeTemp);
1622             break;
1623         }
1624 
1625         struct HksKeySpec agreeSpec = { 0 };
1626         HksFillKeySpec(keyNode->runtimeParamSet, &agreeSpec);
1627 
1628         ret = HksCryptoHalAgreeKey(&rawKey, &publicKey, &agreeSpec, agreeTemp);
1629         if (ret != HKS_SUCCESS) {
1630             HKS_LOG_E("HksCryptoHalAgreeKey failed, ret = %" LOG_PUBLIC "d.", ret);
1631             FreeOutBlob(&agreeTemp);
1632             break;
1633         }
1634 
1635         ctxParam->uint64Param = (uint64_t)(uintptr_t)agreeTemp;
1636     } while (0);
1637 
1638     if (rawKey.data != NULL) {
1639         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1640     }
1641     HKS_FREE(rawKey.data);
1642     HKS_FREE(publicKey.data);
1643     return ret;
1644 }
1645 
HksCoreAgreeThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1646 int32_t HksCoreAgreeThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1647     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1648 {
1649     (void)inData;
1650     (void)alg;
1651     int32_t ret = CheckBlob(outData);
1652     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "invalid outData")
1653 
1654     void *ctx = GetCryptoCtx(keyNode);
1655     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is NULL!")
1656 
1657     struct HksBlob *restoreData = (struct HksBlob *)ctx;
1658 
1659     ret = BuildAgreeDeriveKeyBlobOrGetOutData(paramSet, restoreData, outData, HKS_KEY_FLAG_AGREE_KEY, keyNode);
1660 
1661     FreeCachedData(&restoreData);
1662     ClearCryptoCtx(keyNode);
1663     return ret;
1664 }
1665 
HksCoreAgreeThreeStageAbort(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1666 int32_t HksCoreAgreeThreeStageAbort(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet, uint32_t alg)
1667 {
1668     (void)paramSet;
1669     (void)alg;
1670 
1671     void *ctx = GetCryptoCtx(keyNode);
1672     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is NULL!")
1673 
1674     struct HksBlob *restoreData = (struct HksBlob *)ctx;
1675 
1676     FreeCachedData(&restoreData);
1677     ClearCryptoCtx(keyNode);
1678     return HKS_SUCCESS;
1679 }
1680 
HksCoreMacThreeStageInit(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1681 int32_t HksCoreMacThreeStageInit(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1682     uint32_t alg)
1683 {
1684     (void)paramSet;
1685     int32_t ret = HmacAuth(keyNode, keyNode->runtimeParamSet);
1686     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCoreMacThreeStageInit MacAuth fail ret : %" LOG_PUBLIC "d", ret)
1687 
1688     struct HksParam *ctxParam = NULL;
1689     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1690     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
1691 
1692     struct HksBlob rawKey = { 0, NULL };
1693     do {
1694         ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey);
1695         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Derive get raw key failed!")
1696 
1697         void *ctx = NULL;
1698         ret = HksCryptoHalHmacInit(&rawKey, alg, &ctx);
1699         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "hmac init failed! ret : %" LOG_PUBLIC "d", ret)
1700 
1701         ctxParam->uint64Param = (uint64_t)(uintptr_t)ctx;
1702     } while (0);
1703 
1704     if (rawKey.data != NULL) {
1705         (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size);
1706     }
1707     HKS_FREE(rawKey.data);
1708 
1709     return ret;
1710 }
1711 
HksCoreMacThreeStageUpdate(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * mac,uint32_t alg)1712 int32_t HksCoreMacThreeStageUpdate(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1713     const struct HksBlob *srcData, struct HksBlob *mac, uint32_t alg)
1714 {
1715     (void)paramSet;
1716     (void)mac;
1717     (void)alg;
1718     int32_t ret;
1719 
1720     void *ctx = GetCryptoCtx(keyNode);
1721     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx is NULL!")
1722 
1723     ret = HksCryptoHalHmacUpdate(srcData, ctx);
1724     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "hmac update failed! ret : %" LOG_PUBLIC "d", ret)
1725 
1726     return HKS_SUCCESS;
1727 }
1728 
HksCoreMacThreeStageFinish(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,uint32_t alg)1729 int32_t HksCoreMacThreeStageFinish(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet,
1730     const struct HksBlob *inData, struct HksBlob *outData, uint32_t alg)
1731 {
1732     (void)paramSet;
1733     (void)alg;
1734 
1735     struct HksParam *digestParam = NULL;
1736     int32_t ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_DIGEST, &digestParam);
1737     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_DIGEST_FAIL, "get ctx from keyNode failed!")
1738 
1739     uint32_t macLen;
1740     ret = HksGetDigestLen(digestParam->uint32Param, &macLen);
1741     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get digest len failed")
1742 
1743     if ((CheckBlob(outData) != HKS_SUCCESS) || (outData->size < macLen)) {
1744         HKS_LOG_E("out buffer too small");
1745         return HKS_ERROR_BUFFER_TOO_SMALL;
1746     }
1747 
1748     struct HksParam *ctxParam = NULL;
1749     ret = HksGetParam(keyNode->runtimeParamSet, HKS_TAG_CRYPTO_CTX, &ctxParam);
1750     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get ctx from keyNode failed!")
1751 
1752     void *ctx = (void *)(uintptr_t)ctxParam->uint64Param;
1753     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx invalid")
1754 
1755     ret = HksCryptoHalHmacFinal(inData, &ctx, outData);
1756     HKS_IF_NOT_SUCC_LOGE(ret, "hmac final failed! ret : %" LOG_PUBLIC "d", ret)
1757 
1758     ctxParam->uint64Param = 0; /* clear ctx to NULL */
1759     return ret;
1760 }
1761 
HksCoreMacThreeStageAbort(const struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet,uint32_t alg)1762 int32_t HksCoreMacThreeStageAbort(const struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet, uint32_t alg)
1763 {
1764     (void)alg;
1765     (void)paramSet;
1766 
1767     void *ctx = GetCryptoCtx(keyNode);
1768     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_NULL_POINTER, "ctx invalid")
1769 
1770     HksCryptoHalHmacFreeCtx(&ctx);
1771     ClearCryptoCtx(keyNode);
1772 
1773     return HKS_SUCCESS;
1774 }
1775 
1776 #endif /* _CUT_AUTHENTICATE_ */