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 #include "napi_mac.h"
17
18 #include "securec.h"
19 #include "log.h"
20 #include "memory.h"
21
22 #include "napi_sym_key.h"
23 #include "napi_utils.h"
24 #include "napi_crypto_framework_defines.h"
25
26 namespace OHOS {
27 namespace CryptoFramework {
28 thread_local napi_ref NapiMac::classRef_ = nullptr;
29
30 struct MacCtx {
31 napi_env env = nullptr;
32
33 AsyncType asyncType = ASYNC_CALLBACK;
34 napi_ref callback = nullptr;
35 napi_deferred deferred = nullptr;
36 napi_value promise = nullptr;
37 napi_async_work asyncWork = nullptr;
38 napi_ref macRef = nullptr;
39 napi_ref symKeyRef = nullptr;
40
41 std::string algoName = "";
42 HcfSymKey *symKey = nullptr;
43 HcfBlob *inBlob = nullptr;
44
45 HcfResult errCode = HCF_SUCCESS;
46 const char *errMsg = nullptr;
47 HcfBlob *outBlob = nullptr;
48 HcfMac *mac = nullptr;
49 };
50
FreeCryptoFwkCtx(napi_env env,MacCtx * context)51 static void FreeCryptoFwkCtx(napi_env env, MacCtx *context)
52 {
53 if (context == nullptr) {
54 return;
55 }
56 if (context->asyncWork != nullptr) {
57 napi_delete_async_work(env, context->asyncWork);
58 context->asyncWork = nullptr;
59 }
60 if (context->callback != nullptr) {
61 napi_delete_reference(env, context->callback);
62 context->callback = nullptr;
63 }
64 if (context->macRef != nullptr) {
65 napi_delete_reference(env, context->macRef);
66 context->macRef = nullptr;
67 }
68 if (context->symKeyRef != nullptr) {
69 napi_delete_reference(env, context->symKeyRef);
70 context->symKeyRef = nullptr;
71 }
72 context->symKey = nullptr;
73 if (context->inBlob != nullptr) {
74 HcfFree(context->inBlob->data);
75 context->inBlob->data = nullptr;
76 context->inBlob->len = 0;
77 HcfFree(context->inBlob);
78 context->inBlob = nullptr;
79 }
80 if (context->outBlob != nullptr) {
81 HcfFree(context->outBlob->data);
82 context->outBlob->data = nullptr;
83 context->outBlob->len = 0;
84 HcfFree(context->outBlob);
85 context->outBlob = nullptr;
86 }
87 context->errMsg = nullptr;
88 context->mac = nullptr;
89 HcfFree(context);
90 }
91
ReturnCallbackResult(napi_env env,MacCtx * context,napi_value result)92 static void ReturnCallbackResult(napi_env env, MacCtx *context, napi_value result)
93 {
94 napi_value businessError = nullptr;
95 if (context->errCode != HCF_SUCCESS) {
96 businessError = GenerateBusinessError(env, context->errCode, context->errMsg);
97 }
98 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
99
100 napi_value func = nullptr;
101 napi_get_reference_value(env, context->callback, &func);
102
103 napi_value recv = nullptr;
104 napi_value callFuncRet = nullptr;
105 napi_get_undefined(env, &recv);
106 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
107 }
108
ReturnPromiseResult(napi_env env,MacCtx * context,napi_value result)109 static void ReturnPromiseResult(napi_env env, MacCtx *context, napi_value result)
110 {
111 if (context->errCode == HCF_SUCCESS) {
112 napi_resolve_deferred(env, context->deferred, result);
113 } else {
114 napi_reject_deferred(env, context->deferred,
115 GenerateBusinessError(env, context->errCode, context->errMsg));
116 }
117 }
118
MacInitExecute(napi_env env,void * data)119 static void MacInitExecute(napi_env env, void *data)
120 {
121 MacCtx *context = static_cast<MacCtx *>(data);
122 HcfMac *macObj = context->mac;
123 HcfSymKey *symKey = context->symKey;
124 context->errCode = macObj->init(macObj, symKey);
125 if (context->errCode != HCF_SUCCESS) {
126 LOGD("[error] init failed!");
127 context->errMsg = "init failed";
128 }
129 }
130
MacInitComplete(napi_env env,napi_status status,void * data)131 static void MacInitComplete(napi_env env, napi_status status, void *data)
132 {
133 MacCtx *context = static_cast<MacCtx *>(data);
134 napi_value nullInstance = nullptr;
135 napi_get_null(env, &nullInstance);
136 if (context->asyncType == ASYNC_CALLBACK) {
137 ReturnCallbackResult(env, context, nullInstance);
138 } else {
139 ReturnPromiseResult(env, context, nullInstance);
140 }
141 FreeCryptoFwkCtx(env, context);
142 }
143
MacUpdateExecute(napi_env env,void * data)144 static void MacUpdateExecute(napi_env env, void *data)
145 {
146 MacCtx *context = static_cast<MacCtx *>(data);
147 HcfMac *macObj = context->mac;
148 HcfBlob *inBlob = reinterpret_cast<HcfBlob *>(context->inBlob);
149 context->errCode = macObj->update(macObj, inBlob);
150 if (context->errCode != HCF_SUCCESS) {
151 LOGD("[error] update failed!");
152 context->errMsg = "update failed";
153 }
154 }
155
MacUpdateComplete(napi_env env,napi_status status,void * data)156 static void MacUpdateComplete(napi_env env, napi_status status, void *data)
157 {
158 MacCtx *context = static_cast<MacCtx *>(data);
159 napi_value nullInstance = nullptr;
160 napi_get_null(env, &nullInstance);
161 if (context->asyncType == ASYNC_CALLBACK) {
162 ReturnCallbackResult(env, context, nullInstance);
163 } else {
164 ReturnPromiseResult(env, context, nullInstance);
165 }
166 FreeCryptoFwkCtx(env, context);
167 }
168
MacDoFinalExecute(napi_env env,void * data)169 static void MacDoFinalExecute(napi_env env, void *data)
170 {
171 MacCtx *context = static_cast<MacCtx *>(data);
172 HcfMac *macObj = context->mac;
173 HcfBlob *outBlob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
174 if (outBlob == nullptr) {
175 LOGD("[error] outBlob is null!");
176 context->errCode = HCF_ERR_MALLOC;
177 context->errMsg = "malloc data blob failed";
178 return;
179 }
180 context->errCode = macObj->doFinal(macObj, outBlob);
181 if (context->errCode != HCF_SUCCESS) {
182 HcfFree(outBlob);
183 LOGE("doFinal failed!");
184 context->errMsg = "doFinal failed";
185 return;
186 }
187 context->outBlob = outBlob;
188 }
189
MacDoFinalComplete(napi_env env,napi_status status,void * data)190 static void MacDoFinalComplete(napi_env env, napi_status status, void *data)
191 {
192 MacCtx *context = static_cast<MacCtx *>(data);
193 napi_value returnOutBlob = ConvertBlobToNapiValue(env, context->outBlob);
194 if (returnOutBlob == nullptr) {
195 LOGE("returnOutBlob is nullptr!");
196 returnOutBlob = NapiGetNull(env);
197 }
198 if (context->asyncType == ASYNC_CALLBACK) {
199 ReturnCallbackResult(env, context, returnOutBlob);
200 } else {
201 ReturnPromiseResult(env, context, returnOutBlob);
202 }
203 FreeCryptoFwkCtx(env, context);
204 }
205
BuildMacJsInitCtx(napi_env env,napi_callback_info info,MacCtx * context)206 static bool BuildMacJsInitCtx(napi_env env, napi_callback_info info, MacCtx *context)
207 {
208 napi_value thisVar = nullptr;
209 NapiMac *napiMac = nullptr;
210 size_t expectedArgsCount = ARGS_SIZE_TWO;
211 size_t argc = expectedArgsCount;
212 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
213 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
214 if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
215 return false;
216 }
217
218 context->asyncType = isCallback(env, argv[expectedArgsCount - 1], argc, expectedArgsCount) ?
219 ASYNC_CALLBACK : ASYNC_PROMISE;
220 NapiSymKey *symKey = nullptr;
221 napi_status status = napi_unwrap(env, argv[PARAM0], reinterpret_cast<void **>(&symKey));
222 if (status != napi_ok || symKey == nullptr) {
223 LOGE("symKey is null!");
224 return false;
225 }
226 context->symKey = symKey->GetSymKey();
227 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
228 if (status != napi_ok || napiMac == nullptr) {
229 LOGE("failed to unwrap napiMac obj!");
230 return false;
231 }
232
233 context->mac = napiMac->GetMac();
234
235 if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) {
236 LOGE("create mac ref failed when do mac init!");
237 return false;
238 }
239
240 if (napi_create_reference(env, argv[PARAM0], 1, &context->symKeyRef) != napi_ok) {
241 LOGE("create sym key ref failed when do mac init!");
242 return false;
243 }
244
245 if (context->asyncType == ASYNC_PROMISE) {
246 napi_create_promise(env, &context->deferred, &context->promise);
247 return true;
248 } else {
249 return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback);
250 }
251 }
252
BuildMacJsUpdateCtx(napi_env env,napi_callback_info info,MacCtx * context)253 static bool BuildMacJsUpdateCtx(napi_env env, napi_callback_info info, MacCtx *context)
254 {
255 napi_value thisVar = nullptr;
256 NapiMac *napiMac = nullptr;
257 size_t expectedArgsCount = ARGS_SIZE_TWO;
258 size_t argc = expectedArgsCount;
259 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
260 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
261 if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
262 return false;
263 }
264
265 context->asyncType = isCallback(env, argv[expectedArgsCount - 1], argc, expectedArgsCount) ?
266 ASYNC_CALLBACK : ASYNC_PROMISE;
267 context->inBlob = GetBlobFromNapiDataBlob(env, argv[PARAM0]);
268 if (context->inBlob == nullptr) {
269 LOGE("inBlob is null!");
270 return false;
271 }
272 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
273 if (status != napi_ok || napiMac == nullptr) {
274 LOGE("failed to unwrap napiMac obj!");
275 return false;
276 }
277
278 context->mac = napiMac->GetMac();
279
280 if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) {
281 LOGE("create mac ref failed when do mac update!");
282 return false;
283 }
284
285 if (context->asyncType == ASYNC_PROMISE) {
286 napi_create_promise(env, &context->deferred, &context->promise);
287 return true;
288 } else {
289 return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback);
290 }
291 }
292
BuildMacJsDoFinalCtx(napi_env env,napi_callback_info info,MacCtx * context)293 static bool BuildMacJsDoFinalCtx(napi_env env, napi_callback_info info, MacCtx *context)
294 {
295 napi_value thisVar = nullptr;
296 NapiMac *napiMac = nullptr;
297 size_t expectedArgsCount = ARGS_SIZE_ONE;
298 size_t argc = expectedArgsCount;
299 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
300 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
301 if (!CheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
302 return false;
303 }
304
305 context->asyncType = isCallback(env, argv[expectedArgsCount - 1], argc, expectedArgsCount) ?
306 ASYNC_CALLBACK : ASYNC_PROMISE;
307 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
308 if (status != napi_ok || napiMac == nullptr) {
309 LOGE("failed to unwrap napiMac obj!");
310 return false;
311 }
312
313 context->mac = napiMac->GetMac();
314
315 if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) {
316 LOGE("create mac ref failed when do mac final!");
317 return false;
318 }
319
320 if (context->asyncType == ASYNC_PROMISE) {
321 napi_create_promise(env, &context->deferred, &context->promise);
322 return true;
323 } else {
324 return GetCallbackFromJSParams(env, argv[PARAM0], &context->callback);
325 }
326 }
327
NewMacJsInitAsyncWork(napi_env env,MacCtx * context)328 static napi_value NewMacJsInitAsyncWork(napi_env env, MacCtx *context)
329 {
330 napi_create_async_work(
331 env, nullptr, GetResourceName(env, "MacInit"),
332 [](napi_env env, void *data) {
333 MacInitExecute(env, data);
334 return;
335 },
336 [](napi_env env, napi_status status, void *data) {
337 MacInitComplete(env, status, data);
338 return;
339 },
340 static_cast<void *>(context),
341 &context->asyncWork);
342
343 napi_queue_async_work(env, context->asyncWork);
344 if (context->asyncType == ASYNC_PROMISE) {
345 return context->promise;
346 } else {
347 return NapiGetNull(env);
348 }
349 }
350
NewMacJsUpdateAsyncWork(napi_env env,MacCtx * context)351 static napi_value NewMacJsUpdateAsyncWork(napi_env env, MacCtx *context)
352 {
353 napi_create_async_work(
354 env, nullptr, GetResourceName(env, "MacUpdate"),
355 [](napi_env env, void *data) {
356 MacUpdateExecute(env, data);
357 return;
358 },
359 [](napi_env env, napi_status status, void *data) {
360 MacUpdateComplete(env, status, data);
361 return;
362 },
363 static_cast<void *>(context),
364 &context->asyncWork);
365
366 napi_queue_async_work(env, context->asyncWork);
367 if (context->asyncType == ASYNC_PROMISE) {
368 return context->promise;
369 } else {
370 return NapiGetNull(env);
371 }
372 }
373
NewMacJsDoFinalAsyncWork(napi_env env,MacCtx * context)374 static napi_value NewMacJsDoFinalAsyncWork(napi_env env, MacCtx *context)
375 {
376 napi_create_async_work(
377 env, nullptr, GetResourceName(env, "MacDoFinal"),
378 [](napi_env env, void *data) {
379 MacDoFinalExecute(env, data);
380 return;
381 },
382 [](napi_env env, napi_status status, void *data) {
383 MacDoFinalComplete(env, status, data);
384 return;
385 },
386 static_cast<void *>(context),
387 &context->asyncWork);
388
389 napi_queue_async_work(env, context->asyncWork);
390 if (context->asyncType == ASYNC_PROMISE) {
391 return context->promise;
392 } else {
393 return NapiGetNull(env);
394 }
395 }
396
397
NapiMac(HcfMac * macObj)398 NapiMac::NapiMac(HcfMac *macObj)
399 {
400 this->macObj_ = macObj;
401 }
402
~NapiMac()403 NapiMac::~NapiMac()
404 {
405 HcfObjDestroy(this->macObj_);
406 }
407
GetMac()408 HcfMac *NapiMac::GetMac()
409 {
410 return this->macObj_;
411 }
412
JsMacInit(napi_env env,napi_callback_info info)413 napi_value NapiMac::JsMacInit(napi_env env, napi_callback_info info)
414 {
415 MacCtx *context = static_cast<MacCtx *>(HcfMalloc(sizeof(MacCtx), 0));
416 if (context == nullptr) {
417 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed"));
418 LOGE("malloc context failed!");
419 return nullptr;
420 }
421
422 if (!BuildMacJsInitCtx(env, info, context)) {
423 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
424 LOGE("build context fail.");
425 FreeCryptoFwkCtx(env, context);
426 return nullptr;
427 }
428
429 return NewMacJsInitAsyncWork(env, context);
430 }
431
JsMacInitSync(napi_env env,napi_callback_info info)432 napi_value NapiMac::JsMacInitSync(napi_env env, napi_callback_info info)
433 {
434 napi_value thisVar = nullptr;
435 NapiMac *napiMac = nullptr;
436 size_t argc = ARGS_SIZE_ONE;
437 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
438 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
439 if (argc != ARGS_SIZE_ONE) {
440 LOGE("The input args num is invalid.");
441 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
442 return nullptr;
443 }
444 NapiSymKey *napiSysKey = nullptr;
445 napi_status status = napi_unwrap(env, argv[PARAM0], reinterpret_cast<void **>(&napiSysKey));
446 if (status != napi_ok || napiSysKey == nullptr) {
447 LOGE("napiSysKey is null!");
448 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "napiSysKey is null!"));
449 return nullptr;
450 }
451 HcfSymKey *symKey = napiSysKey->GetSymKey();
452 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
453 if (status != napi_ok || napiMac == nullptr) {
454 LOGE("failed to unwrap napiMac obj!");
455 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiMac obj!"));
456 return nullptr;
457 }
458 HcfMac *mac = napiMac->GetMac();
459 if (mac == nullptr) {
460 LOGE("mac is nullptr!");
461 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "mac is nullptr!"));
462 return nullptr;
463 }
464 HcfResult errCode = mac->init(mac, symKey);
465 if (errCode != HCF_SUCCESS) {
466 LOGE("mac init failed!");
467 napi_throw(env, GenerateBusinessError(env, HCF_ERR_CRYPTO_OPERATION, "mac init failed!"));
468 return nullptr;
469 }
470 napi_value nullInstance = nullptr;
471 napi_get_null(env, &nullInstance);
472 return nullInstance;
473 }
474
JsMacUpdate(napi_env env,napi_callback_info info)475 napi_value NapiMac::JsMacUpdate(napi_env env, napi_callback_info info)
476 {
477 MacCtx *context = static_cast<MacCtx *>(HcfMalloc(sizeof(MacCtx), 0));
478 if (context == nullptr) {
479 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed"));
480 LOGE("malloc context failed!");
481 return nullptr;
482 }
483
484 if (!BuildMacJsUpdateCtx(env, info, context)) {
485 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
486 LOGE("build context fail.");
487 FreeCryptoFwkCtx(env, context);
488 return nullptr;
489 }
490
491 return NewMacJsUpdateAsyncWork(env, context);
492 }
493
JsMacUpdateSync(napi_env env,napi_callback_info info)494 napi_value NapiMac::JsMacUpdateSync(napi_env env, napi_callback_info info)
495 {
496 napi_value thisVar = nullptr;
497 NapiMac *napiMac = nullptr;
498 size_t argc = ARGS_SIZE_ONE;
499 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
500 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
501 if (argc != ARGS_SIZE_ONE) {
502 LOGE("The input args num is invalid.");
503 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
504 return nullptr;
505 }
506
507 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
508 if (status != napi_ok || napiMac == nullptr) {
509 LOGE("failed to unwrap napiMac obj!");
510 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiMac obj!"));
511 return nullptr;
512 }
513
514 HcfBlob *inBlob = GetBlobFromNapiDataBlob(env, argv[PARAM0]);
515 if (inBlob == nullptr) {
516 LOGE("inBlob is null!");
517 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "inBlob is null!"));
518 return nullptr;
519 }
520
521 HcfMac *mac = napiMac->GetMac();
522 if (mac == nullptr) {
523 LOGE("mac is nullptr!");
524 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "mac is nullptr!"));
525 HcfBlobDataClearAndFree(inBlob);
526 HcfFree(inBlob);
527 return nullptr;
528 }
529 HcfResult errCode = mac->update(mac, inBlob);
530 HcfBlobDataClearAndFree(inBlob);
531 HcfFree(inBlob);
532 if (errCode != HCF_SUCCESS) {
533 LOGE("mac update failed!");
534 napi_throw(env, GenerateBusinessError(env, HCF_ERR_CRYPTO_OPERATION, "mac update failed!"));
535 return nullptr;
536 }
537 napi_value nullInstance = nullptr;
538 napi_get_null(env, &nullInstance);
539 return nullInstance;
540 }
541
JsMacDoFinal(napi_env env,napi_callback_info info)542 napi_value NapiMac::JsMacDoFinal(napi_env env, napi_callback_info info)
543 {
544 MacCtx *context = static_cast<MacCtx *>(HcfMalloc(sizeof(MacCtx), 0));
545 if (context == nullptr) {
546 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed"));
547 LOGE("malloc context failed!");
548 return nullptr;
549 }
550
551 if (!BuildMacJsDoFinalCtx(env, info, context)) {
552 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
553 LOGE("build context fail.");
554 FreeCryptoFwkCtx(env, context);
555 return nullptr;
556 }
557
558 return NewMacJsDoFinalAsyncWork(env, context);
559 }
560
JsMacDoFinalSync(napi_env env,napi_callback_info info)561 napi_value NapiMac::JsMacDoFinalSync(napi_env env, napi_callback_info info)
562 {
563 napi_value thisVar = nullptr;
564 NapiMac *napiMac = nullptr;
565 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
566 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
567 if (status != napi_ok || napiMac == nullptr) {
568 LOGE("failed to unwrap napiMac obj!");
569 napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napiMac obj."));
570 return nullptr;
571 }
572 HcfMac *mac = napiMac->GetMac();
573 if (mac == nullptr) {
574 LOGE("mac is nullptr!");
575 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "mac is nullptr!"));
576 return nullptr;
577 }
578 HcfBlob outBlob = { .data = nullptr, .len = 0 };
579 HcfResult errCode = mac->doFinal(mac, &outBlob);
580 if (errCode != HCF_SUCCESS) {
581 LOGE("mac doFinal failed!");
582 napi_throw(env, GenerateBusinessError(env, errCode, "mac doFinal failed!"));
583 HcfBlobDataClearAndFree(&outBlob);
584 return nullptr;
585 }
586
587 napi_value returnOutBlob = nullptr;
588 errCode = ConvertDataBlobToNapiValue(env, &outBlob, &returnOutBlob);
589 HcfBlobDataClearAndFree(&outBlob);
590 if (errCode != HCF_SUCCESS) {
591 LOGE("mac convert dataBlob to napi_value failed!");
592 napi_throw(env, GenerateBusinessError(env, errCode, "mac convert dataBlob to napi_value failed!"));
593 return nullptr;
594 }
595
596 return returnOutBlob;
597 }
598
JsGetMacLength(napi_env env,napi_callback_info info)599 napi_value NapiMac::JsGetMacLength(napi_env env, napi_callback_info info)
600 {
601 napi_value thisVar = nullptr;
602 NapiMac *napiMac = nullptr;
603
604 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
605 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiMac));
606 if (status != napi_ok || napiMac == nullptr) {
607 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiMac obj!"));
608 LOGE("failed to unwrap napiMac obj!");
609 return nullptr;
610 }
611
612 HcfMac *mac = napiMac->GetMac();
613 if (mac == nullptr) {
614 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get mac obj!"));
615 LOGE("fail to get mac obj!");
616 return nullptr;
617 }
618
619 uint32_t retLen = mac->getMacLength(mac);
620 napi_value napiLen = nullptr;
621 napi_create_uint32(env, retLen, &napiLen);
622 return napiLen;
623 }
624
MacConstructor(napi_env env,napi_callback_info info)625 napi_value NapiMac::MacConstructor(napi_env env, napi_callback_info info)
626 {
627 napi_value thisVar = nullptr;
628 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
629 return thisVar;
630 }
631
NapiWrapMac(napi_env env,napi_value instance,NapiMac * macNapiObj)632 static napi_value NapiWrapMac(napi_env env, napi_value instance, NapiMac *macNapiObj)
633 {
634 napi_status status = napi_wrap(
635 env, instance, macNapiObj,
636 [](napi_env env, void *data, void *hint) {
637 NapiMac *mac = static_cast<NapiMac *>(data);
638 delete mac;
639 return;
640 }, nullptr, nullptr);
641 if (status != napi_ok) {
642 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap NapiMac obj!"));
643 delete macNapiObj;
644 LOGE("failed to wrap NapiMac obj!");
645 return nullptr;
646 }
647 return instance;
648 }
649
CreateMac(napi_env env,napi_callback_info info)650 napi_value NapiMac::CreateMac(napi_env env, napi_callback_info info)
651 {
652 size_t expectedArgc = ARGS_SIZE_ONE;
653 size_t argc = expectedArgc;
654 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
655 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
656 if (argc != expectedArgc) {
657 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
658 LOGE("The input args num is invalid.");
659 return nullptr;
660 }
661 std::string algoName;
662 if (!GetStringFromJSParams(env, argv[PARAM0], algoName)) {
663 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Failed to get algorithm."));
664 LOGE("Failed to get algorithm.");
665 return nullptr;
666 }
667 HcfMac *macObj = nullptr;
668 HcfResult res = HcfMacCreate(algoName.c_str(), &macObj);
669 if (res != HCF_SUCCESS) {
670 napi_throw(env, GenerateBusinessError(env, res, "create C obj failed."));
671 LOGE("create c macObj failed.");
672 return nullptr;
673 }
674 napi_value napiAlgName = nullptr;
675 napi_create_string_utf8(env, algoName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName);
676 napi_value instance = nullptr;
677 napi_value constructor = nullptr;
678 napi_get_reference_value(env, classRef_, &constructor);
679 napi_new_instance(env, constructor, argc, argv, &instance);
680 napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
681 NapiMac *macNapiObj = new (std::nothrow) NapiMac(macObj);
682 if (macNapiObj == nullptr) {
683 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new mac napi obj failed."));
684 HcfObjDestroy(macObj);
685 LOGE("create napi obj failed");
686 return nullptr;
687 }
688
689 return NapiWrapMac(env, instance, macNapiObj);
690 }
691
DefineMacJSClass(napi_env env,napi_value exports)692 void NapiMac::DefineMacJSClass(napi_env env, napi_value exports)
693 {
694 napi_property_descriptor desc[] = {
695 DECLARE_NAPI_FUNCTION("createMac", NapiMac::CreateMac),
696 };
697 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
698 napi_property_descriptor classDesc[] = {
699 DECLARE_NAPI_FUNCTION("init", NapiMac::JsMacInit),
700 DECLARE_NAPI_FUNCTION("initSync", NapiMac::JsMacInitSync),
701 DECLARE_NAPI_FUNCTION("update", NapiMac::JsMacUpdate),
702 DECLARE_NAPI_FUNCTION("updateSync", NapiMac::JsMacUpdateSync),
703 DECLARE_NAPI_FUNCTION("doFinal", NapiMac::JsMacDoFinal),
704 DECLARE_NAPI_FUNCTION("doFinalSync", NapiMac::JsMacDoFinalSync),
705 DECLARE_NAPI_FUNCTION("getMacLength", NapiMac::JsGetMacLength),
706 };
707 napi_value constructor = nullptr;
708 napi_define_class(env, "Mac", NAPI_AUTO_LENGTH, MacConstructor, nullptr,
709 sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
710 napi_create_reference(env, constructor, 1, &classRef_);
711 }
712 } // CryptoFramework
713 } // OHOS