1 /*
2  * Copyright (C) 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 #include "jsi_api.h"
17 #include "jsi_api_common.h"
18 #include "jsi_api_errcode.h"
19 #include "jsi_utils.h"
20 #include "jsi_list.h"
21 #include "securec.h"
22 #include "jsi.h"
23 #include "jsi_types.h"
24 #include "log.h"
25 
26 namespace OHOS {
27 namespace ACELite {
28 
CreateRandom(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)29 JSIValue CryptoFrameworkLiteModule::CreateRandom(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
30 {
31     HcfRand *randObj = nullptr;
32     HcfResult res = HcfRandCreate(&randObj);
33     if (res != HCF_SUCCESS) {
34         LOGE("CreateRandom is randObj err %d!", res);
35         return ThrowErrorCodeResult(res);
36     }
37 
38     res = ListAddObjNode(JSI_ALG_RAND, (uint32_t)randObj);
39     if (res != HCF_SUCCESS) {
40         LOGE("rand add node is %d err!", res);
41         HcfObjDestroy(static_cast<void *>(randObj));
42         return ThrowErrorCodeResult(res);
43     }
44 
45     JSIValue serviceObj = JSI::CreateObject();
46     JSIValue generateRandom = JSI::CreateFunction(GenerateRandom);
47     JSIValue generateRandomSync = JSI::CreateFunction(GenerateRandomSync);
48     JSIValue setSeed = JSI::CreateFunction(SetSeed);
49 
50     JSI::SetNamedProperty(serviceObj, "generateRandom", generateRandom);
51     JSI::SetNamedProperty(serviceObj, "generateRandomSync", generateRandomSync);
52     JSI::SetNamedProperty(serviceObj, "setSeed", setSeed);
53     JSI::SetNumberProperty(serviceObj, "randObj", (double)(uint32_t)randObj);
54     JSI::ReleaseValueList(generateRandom, generateRandomSync, setSeed, ARGS_END);
55 
56     return serviceObj;
57 }
58 
GenerateRandom(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)59 JSIValue CryptoFrameworkLiteModule::GenerateRandom(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
60 {
61     if ((args == nullptr) || (argsNum != ARRAY_MAX_SIZE) || (args[ARRAY_INDEX_ONE] == nullptr)) {
62         LOGE("GenerateRandom params is err!");
63         return JSI::CreateUndefined();
64     }
65 
66     HcfRand *randObj = reinterpret_cast<HcfRand *>((uint32_t)JSI::GetNumberProperty(thisVal, "randObj"));
67     if (randObj == nullptr) {
68         LOGE("GenerateRandom randObj is null!");
69         CallbackErrorCodeOrDataResult(thisVal, args[ARRAY_INDEX_ONE], HCF_INVALID_PARAMS, JSI::CreateUndefined());
70         return JSI::CreateUndefined();
71     }
72 
73     int32_t numBytes = (int32_t)JSI::ValueToNumber(args[0]);
74     if (numBytes <= 0) {
75         LOGE("GenerateRandom numBytes too small!");
76         CallbackErrorCodeOrDataResult(thisVal, args[ARRAY_INDEX_ONE], HCF_INVALID_PARAMS, JSI::CreateUndefined());
77         return JSI::CreateUndefined();
78     }
79     HcfBlob randBlob = { .data = nullptr, .len = 0 };
80     HcfResult res = randObj->generateRandom(randObj, numBytes, &randBlob);
81     if (res != HCF_SUCCESS) {
82         LOGE("GenerateRandom randObj not is success!");
83         CallbackErrorCodeOrDataResult(thisVal, args[ARRAY_INDEX_ONE], res, JSI::CreateUndefined());
84         return JSI::CreateUndefined();
85     }
86 
87     JSIValue outVlaue = ConstructJSIReturnResult(&randBlob);
88     CallbackErrorCodeOrDataResult(thisVal, args[ARRAY_INDEX_ONE], res, outVlaue);
89     HcfBlobDataClearAndFree(&randBlob);
90 
91     return JSI::CreateUndefined();
92 }
93 
GenerateRandomSync(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)94 JSIValue CryptoFrameworkLiteModule::GenerateRandomSync(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
95 {
96     if ((args == nullptr) || (argsNum != ARRAY_INDEX_ONE)) {
97         LOGE("GenerateRandomSync params is err");
98         return ThrowErrorCodeResult(HCF_INVALID_PARAMS);
99     }
100 
101     HcfRand *randObj = reinterpret_cast<HcfRand *>((uint32_t)JSI::GetNumberProperty(thisVal, "randObj"));
102     if (randObj == nullptr) {
103         LOGE("GenerateRandom randObj is null!!");
104         return ThrowErrorCodeResult(HCF_INVALID_PARAMS);
105     }
106 
107     int32_t numBytes = (int32_t)JSI::ValueToNumber(args[0]);
108     if (numBytes <= 0) {
109         LOGE("GenerateRandomSync numBytes too small!");
110         return ThrowErrorCodeResult(HCF_INVALID_PARAMS);
111     }
112     HcfBlob randBlob = { .data = nullptr, .len = 0 };
113     HcfResult res = randObj->generateRandom(randObj, numBytes, &randBlob);
114     if (res != HCF_SUCCESS) {
115         LOGE("GenerateRandomSync randObj not is success!");
116         HcfBlobDataClearAndFree(&randBlob);
117         return ThrowErrorCodeResult(res);
118     }
119     JSIValue randomSyncData = ConstructJSIReturnResult(&randBlob);
120     HcfBlobDataClearAndFree(&randBlob);
121 
122     return randomSyncData;
123 }
124 
SetSeed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)125 JSIValue CryptoFrameworkLiteModule::SetSeed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
126 {
127     HcfRand *randObj = reinterpret_cast<HcfRand *>((uint32_t)JSI::GetNumberProperty(thisVal, "randObj"));
128     if (randObj == nullptr) {
129         LOGE("SetSeed randObj is null!!");
130         return ThrowErrorCodeResult(HCF_INVALID_PARAMS);
131     }
132     if ((args == nullptr) || (argsNum != ARRAY_INDEX_ONE)) {
133         LOGE("SetSeed params is null");
134         return ThrowErrorCodeResult(HCF_INVALID_PARAMS);
135     }
136     JSIValue inVlaue = JSI::GetNamedProperty(args[ARRAY_INDEX_ZERO], "data");
137     HcfBlob seedBlob = { .data = nullptr, .len = 0 };
138     HcfResult errCode = ParseUint8ArrayToBlob(inVlaue, &seedBlob);
139     if (errCode != HCF_SUCCESS) {
140         LOGE("SetSeed seedBlob is null!");
141         return ThrowErrorCodeResult(HCF_ERR_MALLOC);
142     }
143 
144     HcfResult res = randObj->setSeed(randObj, &seedBlob);
145     HcfBlobDataClearAndFree(&seedBlob);
146     if (res != HCF_SUCCESS) {
147         LOGE("setSeed randObj not is success!");
148         return ThrowErrorCodeResult(res);
149     }
150 
151     return ThrowErrorCodeResult(HCF_SUCCESS);
152 }
153 
RandomDestroy(void)154 void CryptoFrameworkLiteModule::RandomDestroy(void)
155 {
156     ListDestroy(JSI_ALG_RAND);
157 }
158 
159 }  // namespace ACELite
160 }  // namespace OHOS
161