1 /*
2  * Copyright (c) 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 #include "hks_lite_api.h"
17 #include "hks_log.h"
18 #include "jsi.h"
19 #include "jsi_types.h"
20 
21 #include "hks_api.h"
22 #include "hks_param.h"
23 #include "hks_lite_api_common.h"
24 
25 namespace OHOS {
26 namespace ACELite {
27 // key size 512 plus aead 16
28 #define RESERVED_PADDING_AREA 528
29 
30 typedef int32_t (*HksCallSessionFunc)(struct HksBlob *handle, struct HksParamSet *paramSet, struct HksBlob *inData,
31     struct HksBlob *outData);
32 
HksCallUpdateSession(struct HksBlob * handle,struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)33 static int32_t HksCallUpdateSession(struct HksBlob *handle, struct HksParamSet *paramSet, struct HksBlob *inData,
34     struct HksBlob *outData)
35 {
36     int32_t ret = InitHuksModule();
37     if (ret != HKS_SUCCESS) {
38         HKS_LOG_E("init huks failed");
39         return ret;
40     }
41     ret = HksUpdate(handle, paramSet, inData, outData);
42     return ret;
43 }
44 
HksCallFinishSession(struct HksBlob * handle,struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)45 static int32_t HksCallFinishSession(struct HksBlob *handle, struct HksParamSet *paramSet, struct HksBlob *inData,
46     struct HksBlob *outData)
47 {
48     int32_t ret = InitHuksModule();
49     if (ret != HKS_SUCCESS) {
50         HKS_LOG_E("init huks failed");
51         return ret;
52     }
53     ret = HksFinish(handle, paramSet, inData, outData);
54     return ret;
55 }
56 
InitOutDataBuffer(struct HksBlob * inData,struct HksBlob * outData)57 static int32_t InitOutDataBuffer(struct HksBlob *inData, struct HksBlob *outData)
58 {
59     outData->size = inData->size + RESERVED_PADDING_AREA;
60     outData->data = static_cast<uint8_t *>(HksMalloc(outData->size));
61     if (outData->data == NULL) {
62         return HKS_ERROR_MALLOC_FAIL;
63     }
64     return HKS_SUCCESS;
65 }
66 
InnerUpdateFinishSession(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum,HksCallSessionFunc func)67 static JSIValue InnerUpdateFinishSession(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum,
68     HksCallSessionFunc func)
69 {
70     JSIValue undefValue = JSI::CreateUndefined();
71     uint32_t minNumArgs = 3;
72     if ((argsNum < minNumArgs) || args == nullptr) {
73         HKS_LOG_E("updateSession args invalid, args num(%{public}d).", argsNum);
74         return undefValue;
75     }
76 
77     struct HksParamSet *paramSet = nullptr;
78     struct HksBlob handle = { 0, nullptr };
79     struct HksBlob outData = { 0, nullptr };
80     struct HksBlob inData = { 0, nullptr };
81     int32_t ret;
82     do {
83         ret = HksParseHandle(args, ARGS_INDEX_0, &handle);
84         if (ret != HKS_SUCCESS) {
85             HKS_LOG_E("parse handle failed!");
86             break;
87         }
88 
89         ret = HksParseParamSetWithAdd(args, ARGS_INDEX_1, &paramSet, nullptr, 0);
90         if (ret != HKS_SUCCESS) {
91             HKS_LOG_E("parse paramset failed!");
92             break;
93         }
94         ret = HksParseInData(args, ARGS_INDEX_1, &inData);
95         if (ret != HKS_SUCCESS) {
96             HKS_LOG_E("parse indata failed!");
97             break;
98         }
99         ret = InitOutDataBuffer(&inData, &outData);
100         if (ret != HKS_SUCCESS) {
101             HKS_LOG_E("init outdata buffer failed!");
102             break;
103         }
104         ret = func(&handle, paramSet, &inData, &outData);
105     } while (0);
106     if (ret == HKS_SUCCESS) {
107         struct HksLiteApiResult result = { &outData, nullptr, false };
108         HksCallbackResultSuccess(thisVal, args[ARGS_INDEX_2], &result);
109     } else {
110         HksCallbackResultFailure(thisVal, args[ARGS_INDEX_2], ret);
111     }
112 
113     HKS_FREE_BLOB(handle);
114     HKS_FREE_BLOB(inData);
115     HKS_FREE_BLOB(outData);
116     HksFreeParamSet(&paramSet);
117     return undefValue;
118 }
119 
updateSession(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)120 JSIValue HksLiteModule::updateSession(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
121 {
122     return InnerUpdateFinishSession(thisVal, args, argsNum, HksCallUpdateSession);
123 }
124 
finishSession(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)125 JSIValue HksLiteModule::finishSession(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
126 {
127     return InnerUpdateFinishSession(thisVal, args, argsNum, HksCallFinishSession);
128 }
129 }
130 }