From 9aba33ea076e751c869e298246c853f4b6018fea Mon Sep 17 00:00:00 2001 From: kang1024 Date: Fri, 6 Jun 2025 09:32:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=BA=E5=9F=BA=E4=B8=80=E9=98=B6=E6=AE=B5?= =?UTF-8?q?=E9=9C=80=E6=B1=82=E5=9B=9E=E5=90=88=E4=B8=BB=E5=B9=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: kang1024 --- BUILD.gn | 1 + bundle.json | 3 +- frameworks/crypto_operation/mac.c | 4 +- frameworks/js/ani/BUILD.gn | 116 +++++ frameworks/js/ani/dts/cryptoFramework.d.ts | 490 ++++++++++++++++++ ...rity.cryptoFramework.cryptoFramework.taihe | 83 +++ frameworks/js/ani/inc/ani_common.h | 35 ++ frameworks/js/ani/inc/ani_key.h | 37 ++ frameworks/js/ani/inc/ani_mac.h | 43 ++ frameworks/js/ani/inc/ani_md.h | 42 ++ frameworks/js/ani/inc/ani_rand.h | 41 ++ frameworks/js/ani/inc/ani_sym_key.h | 43 ++ frameworks/js/ani/inc/ani_sym_key_generator.h | 41 ++ frameworks/js/ani/src/ani_constructor.cpp | 30 ++ frameworks/js/ani/src/ani_key.cpp | 41 ++ frameworks/js/ani/src/ani_mac.cpp | 110 ++++ frameworks/js/ani/src/ani_md.cpp | 91 ++++ frameworks/js/ani/src/ani_rand.cpp | 84 +++ frameworks/js/ani/src/ani_sym_key.cpp | 56 ++ .../js/ani/src/ani_sym_key_generator.cpp | 75 +++ ...y.cryptoFramework.cryptoFramework.impl.cpp | 193 +++++++ frameworks/js/ani/test/arktsconfig.json | 21 + frameworks/js/ani/test/test_mac.ets | 41 ++ frameworks/js/ani/test/test_main.ets | 24 + frameworks/js/ani/test/test_md.ets | 35 ++ frameworks/js/ani/test/test_rand.ets | 34 ++ frameworks/js/ani/test/test_utils.ets | 51 ++ test/unittest/src/crypto_cmac_test.cpp | 4 +- test/unittest/src/crypto_mac_test.cpp | 2 +- test/unittest/src/crypto_sm3_mac_test.cpp | 2 +- 30 files changed, 1866 insertions(+), 7 deletions(-) create mode 100644 frameworks/js/ani/BUILD.gn create mode 100644 frameworks/js/ani/dts/cryptoFramework.d.ts create mode 100644 frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe create mode 100644 frameworks/js/ani/inc/ani_common.h create mode 100644 frameworks/js/ani/inc/ani_key.h create mode 100644 frameworks/js/ani/inc/ani_mac.h create mode 100644 frameworks/js/ani/inc/ani_md.h create mode 100644 frameworks/js/ani/inc/ani_rand.h create mode 100644 frameworks/js/ani/inc/ani_sym_key.h create mode 100644 frameworks/js/ani/inc/ani_sym_key_generator.h create mode 100644 frameworks/js/ani/src/ani_constructor.cpp create mode 100644 frameworks/js/ani/src/ani_key.cpp create mode 100644 frameworks/js/ani/src/ani_mac.cpp create mode 100644 frameworks/js/ani/src/ani_md.cpp create mode 100644 frameworks/js/ani/src/ani_rand.cpp create mode 100644 frameworks/js/ani/src/ani_sym_key.cpp create mode 100644 frameworks/js/ani/src/ani_sym_key_generator.cpp create mode 100644 frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp create mode 100644 frameworks/js/ani/test/arktsconfig.json create mode 100644 frameworks/js/ani/test/test_mac.ets create mode 100644 frameworks/js/ani/test/test_main.ets create mode 100644 frameworks/js/ani/test/test_md.ets create mode 100644 frameworks/js/ani/test/test_rand.ets create mode 100644 frameworks/js/ani/test/test_utils.ets diff --git a/BUILD.gn b/BUILD.gn index d8af064..b87568a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -20,6 +20,7 @@ group("crypto_framework_component") { deps = [ "frameworks:crypto_framework_lib", "frameworks/cj:cj_cryptoframework_ffi", + "frameworks/js/ani:cryptoframework_ani", "frameworks/js/napi/crypto:cryptoframework_napi", "frameworks/native:ohcrypto", "plugin:crypto_openssl_plugin_lib", diff --git a/bundle.json b/bundle.json index 8571e81..61860f6 100644 --- a/bundle.json +++ b/bundle.json @@ -40,7 +40,8 @@ "c_utils", "napi", "openssl", - "bounds_checking_function" + "bounds_checking_function", + "runtime_core" ], "third_party": [] }, diff --git a/frameworks/crypto_operation/mac.c b/frameworks/crypto_operation/mac.c index ea6c22e..88b5f2f 100644 --- a/frameworks/crypto_operation/mac.c +++ b/frameworks/crypto_operation/mac.c @@ -180,7 +180,7 @@ static HcfResult HandleCmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *par return HCF_INVALID_PARAMS; } *createSpiFunc = OpensslCmacSpiCreate; - return SetMacAlgoName(macImpl, cipherName); + return SetMacAlgoName(macImpl, paramsSpec->algName); } static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec, @@ -192,7 +192,7 @@ static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *par LOGE("Unsupported HMAC algorithm: %{public}s", mdName); return HCF_INVALID_PARAMS; } - return SetMacAlgoName(macImpl, mdName); + return SetMacAlgoName(macImpl, paramsSpec->algName); } HcfResult HcfMacCreate(HcfMacParamsSpec *paramsSpec, HcfMac **mac) diff --git a/frameworks/js/ani/BUILD.gn b/frameworks/js/ani/BUILD.gn new file mode 100644 index 0000000..a8ba392 --- /dev/null +++ b/frameworks/js/ani/BUILD.gn @@ -0,0 +1,116 @@ +# Copyright (C) 2025-2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/security/crypto_framework/common/common.gni") +import("//base/security/crypto_framework/frameworks/frameworks.gni") +import("//base/security/crypto_framework/plugin/plugin.gni") +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") + +subsystem_name = "security" +part_name = "crypto_framework" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_taihe") { + sources = [ "${framework_path}/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe" ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.security.cryptoFramework.cryptoFramework.ani.cpp", + "$taihe_generated_file_path/src/ohos.security.cryptoFramework.cryptoFramework.abi.c", + ] +} + +taihe_shared_library("crypto_framework_ani") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + include_dirs = framework_inc_path + include_dirs += [ "${framework_path}/js/ani/inc" ] + sources = get_target_outputs(":run_taihe") + sources += [ + "${framework_path}/js/ani/src/ani_constructor.cpp", + "${framework_path}/js/ani/src/ani_key.cpp", + "${framework_path}/js/ani/src/ani_mac.cpp", + "${framework_path}/js/ani/src/ani_md.cpp", + "${framework_path}/js/ani/src/ani_rand.cpp", + "${framework_path}/js/ani/src/ani_sym_key.cpp", + "${framework_path}/js/ani/src/ani_sym_key_generator.cpp", + ] + deps = [ + ":run_taihe", + "${framework_path}:crypto_framework_lib", + ] + if (os_level == "standard") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + } + cflags = [ + "-DHILOG_ENABLE", + "-fPIC", + "-g3", + ] + external_deps = [ + "bounds_checking_function:libsec_shared", + "c_utils:utils", + "hilog:libhilog", + "openssl:libcrypto_shared", + "runtime_core:ani", + ] +} + +generate_static_abc("crypto_framework_ets") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.security.cryptoFramework.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/crypto_framework_ets.abc" + dependencies = [ ":run_taihe" ] +} + +generate_static_abc("crypto_framework_test") { + base_url = "${framework_path}/js/ani/test" + files = [ + "${framework_path}/js/ani/test/test_main.ets", + "${framework_path}/js/ani/test/test_md.ets", + "${framework_path}/js/ani/test/test_mac.ets", + "${framework_path}/js/ani/test/test_rand.ets", + "${framework_path}/js/ani/test/test_utils.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/crypto_framework_test.abc" +} + +ohos_prebuilt_etc("crypto_framework_etc") { + source = "$target_out_dir/crypto_framework_ets.abc" + module_install_dir = "framework" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [ + ":crypto_framework_ets", + # ":crypto_framework_test", + ] +} + +group("cryptoframework_ani") { + deps = [ + ":crypto_framework_ani", + ":crypto_framework_etc", + ] +} diff --git a/frameworks/js/ani/dts/cryptoFramework.d.ts b/frameworks/js/ani/dts/cryptoFramework.d.ts new file mode 100644 index 0000000..87c5247 --- /dev/null +++ b/frameworks/js/ani/dts/cryptoFramework.d.ts @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { AsyncCallback, Callback } from './@ohos.base'; + +declare namespace cryptoFramework { + enum Result { + INVALID_PARAMS = 401, + NOT_SUPPORT = 801, + ERR_OUT_OF_MEMORY = 17620001, + ERR_RUNTIME_ERROR = 17620002, + ERR_CRYPTO_OPERATION = 17630001 + } + + interface DataBlob { + data: Uint8Array; + } + + interface ParamsSpec { + algName: string; + } + + interface IvParamsSpec extends ParamsSpec { + iv: DataBlob; + } + + interface GcmParamsSpec extends ParamsSpec { + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; + } + + interface CcmParamsSpec extends ParamsSpec { + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; + } + + enum CryptoMode { + ENCRYPT_MODE = 0, + DECRYPT_MODE = 1 + } + + interface KeyEncodingConfig { + password: string; + cipherName: string; + } + + + interface Key { + getEncoded(): DataBlob; + readonly format: string; + readonly algName: string; + } + + interface SymKey extends Key { + clearMem(): void; + } + + interface PriKey extends Key { + clearMem(): void; + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getEncodedDer(format: string): DataBlob; + getEncodedPem(format: string): string; + getEncodedPem(format: string, config: KeyEncodingConfig): string; + } + + interface PubKey extends Key { + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getEncodedDer(format: string): DataBlob; + getEncodedPem(format: string): string; + } + + interface KeyPair { + readonly priKey: PriKey; + readonly pubKey: PubKey; + } + + interface Random { + generateRandom(len: number, callback: AsyncCallback): void; + generateRandom(len: number): Promise; + generateRandomSync(len: number): DataBlob; + setSeed(seed: DataBlob): void; + readonly algName: string; + } + function createRandom(): Random; + + interface AsyKeyGenerator { + generateKeyPair(callback: AsyncCallback): void; + generateKeyPair(): Promise; + generateKeyPairSync(): KeyPair; + convertKey(pubKey: DataBlob, priKey: DataBlob, callback: AsyncCallback): void; + convertKey(pubKey: DataBlob | null, priKey: DataBlob | null, callback: AsyncCallback): void; + convertKey(pubKey: DataBlob, priKey: DataBlob): Promise; + convertKey(pubKey: DataBlob | null, priKey: DataBlob | null): Promise; + convertKeySync(pubKey: DataBlob | null, priKey: DataBlob | null): KeyPair; + convertPemKey(pubKey: string | null, priKey: string | null): Promise; + convertPemKey(pubKey: string | null, priKey: string | null, password: string): Promise; + convertPemKeySync(pubKey: string | null, priKey: string | null): KeyPair; + convertPemKeySync(pubKey: string | null, priKey: string | null, password: string): KeyPair; + readonly algName: string; + } + + interface SymKeyGenerator { + generateSymKey(callback: AsyncCallback): void; + generateSymKey(): Promise; + generateSymKeySync(): SymKey; + convertKey(key: DataBlob, callback: AsyncCallback): void; + convertKey(key: DataBlob): Promise; + convertKeySync(key: DataBlob): SymKey; + readonly algName: string; + } + + function createAsyKeyGenerator(algName: string): AsyKeyGenerator; + function createSymKeyGenerator(algName: string): SymKeyGenerator; + + interface MacSpec { + algName: string; + } + + interface HmacSpec extends MacSpec { + mdName: string; + } + + interface CmacSpec extends MacSpec { + cipherName: string; + } + + interface Mac { + init(key: SymKey, callback: AsyncCallback): void; + init(key: SymKey): Promise; + initSync(key: SymKey): void; + update(input: DataBlob, callback: AsyncCallback): void; + update(input: DataBlob): Promise; + updateSync(input: DataBlob): void; + doFinal(callback: AsyncCallback): void; + doFinal(): Promise; + doFinalSync(): DataBlob; + getMacLength(): number; + readonly algName: string; + } + function createMac(algName: string): Mac; + function createMac(macSpec: MacSpec): Mac; + + interface Md { + update(input: DataBlob, callback: AsyncCallback): void; + update(input: DataBlob): Promise; + updateSync(input: DataBlob): void; + digest(callback: AsyncCallback): void; + digest(): Promise; + digestSync(): DataBlob; + getMdLength(): number; + readonly algName: string; + } + function createMd(algName: string): Md; + + enum CipherSpecItem { + OAEP_MD_NAME_STR = 100, + OAEP_MGF_NAME_STR = 101, + OAEP_MGF1_MD_STR = 102, + OAEP_MGF1_PSRC_UINT8ARR = 103, + SM2_MD_NAME_STR = 104 + } + + enum SignSpecItem { + PSS_MD_NAME_STR = 100, + PSS_MGF_NAME_STR = 101, + PSS_MGF1_MD_STR = 102, + PSS_SALT_LEN_NUM = 103, + PSS_TRAILER_FIELD_NUM = 104, + SM2_USER_ID_UINT8ARR = 105 + } + + interface Cipher { + init(opMode: CryptoMode, key: Key, params: ParamsSpec, callback: AsyncCallback): void; + init(opMode: CryptoMode, key: Key, params: ParamsSpec | null, callback: AsyncCallback): void; + init(opMode: CryptoMode, key: Key, params: ParamsSpec): Promise; + init(opMode: CryptoMode, key: Key, params: ParamsSpec | null): Promise; + initSync(opMode: CryptoMode, key: Key, params: ParamsSpec | null): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): DataBlob; + doFinal(data: DataBlob, callback: AsyncCallback): void; + doFinal(data: DataBlob | null, callback: AsyncCallback): void; + doFinal(data: DataBlob): Promise; + doFinal(data: DataBlob | null): Promise; + doFinalSync(data: DataBlob | null): DataBlob; + setCipherSpec(itemType: CipherSpecItem, itemValue: Uint8Array): void; + getCipherSpec(itemType: CipherSpecItem): string | Uint8Array; + readonly algName: string; + } + function createCipher(transformation: string): Cipher; + + interface Sign { + init(priKey: PriKey, callback: AsyncCallback): void; + init(priKey: PriKey): Promise; + initSync(priKey: PriKey): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): void; + sign(data: DataBlob, callback: AsyncCallback): void; + sign(data: DataBlob | null, callback: AsyncCallback): void; + sign(data: DataBlob): Promise; + sign(data: DataBlob | null): Promise; + signSync(data: DataBlob | null): DataBlob; + setSignSpec(itemType: SignSpecItem, itemValue: number): void; + setSignSpec(itemType: SignSpecItem, itemValue: number | Uint8Array): void; + getSignSpec(itemType: SignSpecItem): string | number; + readonly algName: string; + } + + interface Verify { + init(pubKey: PubKey, callback: AsyncCallback): void; + init(pubKey: PubKey): Promise; + initSync(pubKey: PubKey): void; + update(data: DataBlob, callback: AsyncCallback): void; + update(data: DataBlob): Promise; + updateSync(data: DataBlob): void; + verify(data: DataBlob, signatureData: DataBlob, callback: AsyncCallback): void; + verify(data: DataBlob | null, signatureData: DataBlob, callback: AsyncCallback): void; + verify(data: DataBlob, signatureData: DataBlob): Promise; + verify(data: DataBlob | null, signatureData: DataBlob): Promise; + verifySync(data: DataBlob | null, signatureData: DataBlob): boolean; + recover(signatureData: DataBlob): Promise; + recoverSync(signatureData: DataBlob): DataBlob | null; + setVerifySpec(itemType: SignSpecItem, itemValue: number): void; + setVerifySpec(itemType: SignSpecItem, itemValue: number | Uint8Array): void; + getVerifySpec(itemType: SignSpecItem): string | number; + readonly algName: string; + } + function createSign(algName: string): Sign; + function createVerify(algName: string): Verify; + + interface KeyAgreement { + generateSecret(priKey: PriKey, pubKey: PubKey, callback: AsyncCallback): void; + generateSecret(priKey: PriKey, pubKey: PubKey): Promise; + generateSecretSync(priKey: PriKey, pubKey: PubKey): DataBlob; + readonly algName: string; + } + function createKeyAgreement(algName: string): KeyAgreement; + + enum AsyKeySpecItem { + DSA_P_BN = 101, + DSA_Q_BN = 102, + DSA_G_BN = 103, + DSA_SK_BN = 104, + DSA_PK_BN = 105, + ECC_FP_P_BN = 201, + ECC_A_BN = 202, + ECC_B_BN = 203, + ECC_G_X_BN = 204, + ECC_G_Y_BN = 205, + ECC_N_BN = 206, + ECC_H_NUM = 207, + ECC_SK_BN = 208, + ECC_PK_X_BN = 209, + ECC_PK_Y_BN = 210, + ECC_FIELD_TYPE_STR = 211, + ECC_FIELD_SIZE_NUM = 212, + ECC_CURVE_NAME_STR = 213, + RSA_N_BN = 301, + RSA_SK_BN = 302, + RSA_PK_BN = 303, + DH_P_BN = 401, + DH_G_BN = 402, + DH_L_NUM = 403, + DH_SK_BN = 404, + DH_PK_BN = 405, + ED25519_SK_BN = 501, + ED25519_PK_BN = 502, + X25519_SK_BN = 601, + X25519_PK_BN = 602 + } + + enum AsyKeySpecType { + COMMON_PARAMS_SPEC = 0, + PRIVATE_KEY_SPEC = 1, + PUBLIC_KEY_SPEC = 2, + KEY_PAIR_SPEC = 3 + } + + interface AsyKeySpec { + algName: string; + specType: AsyKeySpecType; + } + + interface DSACommonParamsSpec extends AsyKeySpec { + p: bigint; + q: bigint; + g: bigint; + } + + interface DSAPubKeySpec extends AsyKeySpec { + params: DSACommonParamsSpec; + pk: bigint; + } + + interface DSAKeyPairSpec extends AsyKeySpec { + params: DSACommonParamsSpec; + sk: bigint; + pk: bigint; + } + + interface ECField { + fieldType: string; + } + + interface ECFieldFp extends ECField { + p: bigint; + } + + interface Point { + x: bigint; + y: bigint; + } + + interface ECCCommonParamsSpec extends AsyKeySpec { + field: ECField; + a: bigint; + b: bigint; + g: Point; + n: bigint; + h: number; + } + + interface ECCPriKeySpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + sk: bigint; + } + + interface ECCPubKeySpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + pk: Point; + } + + interface ECCKeyPairSpec extends AsyKeySpec { + params: ECCCommonParamsSpec; + sk: bigint; + pk: Point; + } + + class ECCKeyUtil { + static genECCCommonParamsSpec(curveName: string): ECCCommonParamsSpec; + static convertPoint(curveName: string, encodedPoint: Uint8Array): Point; + static getEncodedPoint(curveName: string, point: Point, format: string): Uint8Array; + } + + interface DHCommonParamsSpec extends AsyKeySpec { + p: bigint; + g: bigint; + l: number; + } + + interface DHPriKeySpec extends AsyKeySpec { + params: DHCommonParamsSpec; + sk: bigint; + } + + interface DHPubKeySpec extends AsyKeySpec { + params: DHCommonParamsSpec; + pk: bigint; + } + + interface DHKeyPairSpec extends AsyKeySpec { + params: DHCommonParamsSpec; + sk: bigint; + pk: bigint; + } + + class DHKeyUtil { + static genDHCommonParamsSpec(pLen: number, skLen?: number): DHCommonParamsSpec; + } + + interface ED25519PriKeySpec extends AsyKeySpec { + sk: bigint; + } + + interface ED25519PubKeySpec extends AsyKeySpec { + pk: bigint; + } + + interface ED25519KeyPairSpec extends AsyKeySpec { + sk: bigint; + pk: bigint; + } + + interface X25519PriKeySpec extends AsyKeySpec { + sk: bigint; + } + + interface X25519PubKeySpec extends AsyKeySpec { + pk: bigint; + } + + interface X25519KeyPairSpec extends AsyKeySpec { + sk: bigint; + pk: bigint; + } + + interface RSACommonParamsSpec extends AsyKeySpec { + n: bigint; + } + + interface RSAPubKeySpec extends AsyKeySpec { + params: RSACommonParamsSpec; + pk: bigint; + } + + interface RSAKeyPairSpec extends AsyKeySpec { + params: RSACommonParamsSpec; + sk: bigint; + pk: bigint; + } + + interface AsyKeyGeneratorBySpec { + generateKeyPair(callback: AsyncCallback): void; + generateKeyPair(): Promise; + generateKeyPairSync(): KeyPair; + generatePriKey(callback: AsyncCallback): void; + generatePriKey(): Promise; + generatePriKeySync(): PriKey; + generatePubKey(callback: AsyncCallback): void; + generatePubKey(): Promise; + generatePubKeySync(): PubKey; + readonly algName: string; + } + function createAsyKeyGeneratorBySpec(asyKeySpec: AsyKeySpec): AsyKeyGeneratorBySpec; + + interface KdfSpec { + algName: string; + } + + interface PBKDF2Spec extends KdfSpec { + password: string | Uint8Array; + salt: Uint8Array; + iterations: number; + keySize: number; + } + + interface HKDFSpec extends KdfSpec { + key: string | Uint8Array; + salt: Uint8Array; + info: Uint8Array; + keySize: number; + } + + interface ScryptSpec extends KdfSpec { + passphrase: string | Uint8Array; + salt: Uint8Array; + n: number; + r: number; + p: number; + maxMemory: number; + keySize: number; + } + + interface Kdf { + generateSecret(params: KdfSpec, callback: AsyncCallback): void; + generateSecret(params: KdfSpec): Promise; + generateSecretSync(params: KdfSpec): DataBlob; + readonly algName: string; + } + function createKdf(algName: string): Kdf; + + interface SM2CipherTextSpec { + xCoordinate: bigint; + yCoordinate: bigint; + cipherTextData: Uint8Array; + hashData: Uint8Array; + } + + class SM2CryptoUtil { + static genCipherTextBySpec(spec: SM2CipherTextSpec, mode?: string): DataBlob; + static getCipherTextSpec(cipherText: DataBlob, mode?: string): SM2CipherTextSpec; + } +} + +export default cryptoFramework; diff --git a/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe b/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe new file mode 100644 index 0000000..42b5987 --- /dev/null +++ b/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@!namespace("@ohos.security.cryptoFramework", "cryptoFramework") +@!typed_array + +@!sts_inject(""" +static { loadLibrary("crypto_framework_ani.z"); } +""") + +struct DataBlob { + data: Array; +} + +interface Md { + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): void; + @gen_async("digest") + @gen_promise("digest") + DigestSync(): DataBlob; + GetMdLength(): i32; + @get GetAlgName(): String; +} +function CreateMd(algName: String): Md; + +interface Random { + @gen_async("generateRandom") + @gen_promise("generateRandom") + GenerateRandomSync(len: i32): DataBlob; + SetSeed(seed: DataBlob): void; + @get GetAlgName(): String; +} +function CreateRandom(): Random; + +interface Mac { + @gen_async("init") + @gen_promise("init") + InitSync(key: SymKey): void; + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): void; + @gen_async("doFinal") + @gen_promise("doFinal") + DoFinalSync(): DataBlob; + GetMacLength(): i32; + @get GetAlgName(): String; +} +function CreateMac(algName: String): Mac; + +interface Key { + GetEncoded(): DataBlob; + @get GetFormat(): String; + @get GetAlgName(): String; +} + +interface SymKey: Key { + ClearMem(): void; + GetSymKeyObj(): i64; +} + +interface SymKeyGenerator { + @gen_async("generateSymKey") + @gen_promise("generateSymKey") + GenerateSymKeySync(): SymKey; + @gen_async("convertKey") + @gen_promise("convertKey") + ConvertKeySync(key: DataBlob): SymKey; + @get GetAlgName(): String; +} +function CreateSymKeyGenerator(algName: String): SymKeyGenerator; diff --git a/frameworks/js/ani/inc/ani_common.h b/frameworks/js/ani/inc/ani_common.h new file mode 100644 index 0000000..ce4e8ba --- /dev/null +++ b/frameworks/js/ani/inc/ani_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_COMMON_H +#define ANI_COMMON_H + +#include "stdexcept" +#include "taihe/runtime.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.proj.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.impl.hpp" + +#include "log.h" +#include "blob.h" +#include "result.h" +#include "object_base.h" + +#define ANI_LOGE_THROW(code, msg) \ + do { \ + taihe::set_business_error(code, msg); \ + LOGE(msg); \ + } while (0) + +#endif // ANI_COMMON_H diff --git a/frameworks/js/ani/inc/ani_key.h b/frameworks/js/ani/inc/ani_key.h new file mode 100644 index 0000000..1cf1f40 --- /dev/null +++ b/frameworks/js/ani/inc/ani_key.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_KEY_H +#define ANI_KEY_H + +#include "ani_common.h" +#include "key.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class KeyImpl { +public: + KeyImpl(); + ~KeyImpl(); + + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_KEY_H diff --git a/frameworks/js/ani/inc/ani_mac.h b/frameworks/js/ani/inc/ani_mac.h new file mode 100644 index 0000000..0416ef2 --- /dev/null +++ b/frameworks/js/ani/inc/ani_mac.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_MAC_H +#define ANI_MAC_H + +#include "ani_common.h" +#include "mac.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class MacImpl { +public: + MacImpl(); + explicit MacImpl(HcfMac *obj); + ~MacImpl(); + + void InitSync(weak::SymKey key); + void UpdateSync(DataBlob const& input); + DataBlob DoFinalSync(); + int32_t GetMacLength(); + string GetAlgName(); + +private: + HcfMac *macObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_MAC_H diff --git a/frameworks/js/ani/inc/ani_md.h b/frameworks/js/ani/inc/ani_md.h new file mode 100644 index 0000000..35cbe7c --- /dev/null +++ b/frameworks/js/ani/inc/ani_md.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_MD_H +#define ANI_MD_H + +#include "ani_common.h" +#include "md.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class MdImpl { +public: + MdImpl(); + explicit MdImpl(HcfMd *obj); + ~MdImpl(); + + void UpdateSync(DataBlob const& input); + DataBlob DigestSync(); + int32_t GetMdLength(); + string GetAlgName(); + +private: + HcfMd *mdObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_MD_H diff --git a/frameworks/js/ani/inc/ani_rand.h b/frameworks/js/ani/inc/ani_rand.h new file mode 100644 index 0000000..f027dcd --- /dev/null +++ b/frameworks/js/ani/inc/ani_rand.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_RAND_H +#define ANI_RAND_H + +#include "ani_common.h" +#include "rand.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class RandomImpl { +public: + RandomImpl(); + explicit RandomImpl(HcfRand *obj); + ~RandomImpl(); + + DataBlob GenerateRandomSync(int32_t len); + void SetSeed(DataBlob const& seed); + string GetAlgName(); + +private: + HcfRand *randObj = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_RAND_H diff --git a/frameworks/js/ani/inc/ani_sym_key.h b/frameworks/js/ani/inc/ani_sym_key.h new file mode 100644 index 0000000..af42597 --- /dev/null +++ b/frameworks/js/ani/inc/ani_sym_key.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_SYM_KEY_H +#define ANI_SYM_KEY_H + +#include "ani_common.h" +#include "sym_key.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class SymKeyImpl { +public: + SymKeyImpl(); + explicit SymKeyImpl(HcfSymKey *obj); + ~SymKeyImpl(); + + void ClearMem(); + int64_t GetSymKeyObj(); + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); + +private: + HcfSymKey *symKey = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SYM_KEY_H diff --git a/frameworks/js/ani/inc/ani_sym_key_generator.h b/frameworks/js/ani/inc/ani_sym_key_generator.h new file mode 100644 index 0000000..4ad8250 --- /dev/null +++ b/frameworks/js/ani/inc/ani_sym_key_generator.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANI_SYM_KEY_GENERATOR_H +#define ANI_SYM_KEY_GENERATOR_H + +#include "ani_common.h" +#include "sym_key_generator.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +class SymKeyGeneratorImpl { +public: + SymKeyGeneratorImpl(); + explicit SymKeyGeneratorImpl(HcfSymKeyGenerator *obj); + ~SymKeyGeneratorImpl(); + + SymKey GenerateSymKeySync(); + SymKey ConvertKeySync(DataBlob const& key); + string GetAlgName(); + +private: + HcfSymKeyGenerator *generator = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SYM_KEY_GENERATOR_H diff --git a/frameworks/js/ani/src/ani_constructor.cpp b/frameworks/js/ani/src/ani_constructor.cpp new file mode 100644 index 0000000..9d38ae4 --- /dev/null +++ b/frameworks/js/ani/src/ani_constructor.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos.security.cryptoFramework.cryptoFramework.ani.hpp" + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::security::cryptoFramework::cryptoFramework::ANIRegister(env)) { + std::cerr << "ohos::security::cryptoFramework::cryptoFramework" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/frameworks/js/ani/src/ani_key.cpp b/frameworks/js/ani/src/ani_key.cpp new file mode 100644 index 0000000..d297915 --- /dev/null +++ b/frameworks/js/ani/src/ani_key.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_key.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +KeyImpl::KeyImpl() {} + +KeyImpl::~KeyImpl() {} + +DataBlob KeyImpl::GetEncoded() +{ + TH_THROW(std::runtime_error, "GetEncoded not implemented"); +} + +string KeyImpl::GetFormat() +{ + TH_THROW(std::runtime_error, "GetFormat not implemented"); +} + +string KeyImpl::GetAlgName() +{ + TH_THROW(std::runtime_error, "GetAlgName not implemented"); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_mac.cpp b/frameworks/js/ani/src/ani_mac.cpp new file mode 100644 index 0000000..918562f --- /dev/null +++ b/frameworks/js/ani/src/ani_mac.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_mac.h" +#include "detailed_hmac_params.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +MacImpl::MacImpl() : macObj(nullptr) {} + +MacImpl::MacImpl(HcfMac *obj) : macObj(obj) {} + +MacImpl::~MacImpl() +{ + HcfObjDestroy(macObj); +} + +void MacImpl::InitSync(weak::SymKey key) +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return; + } + HcfSymKey *symKey = reinterpret_cast(key->GetSymKeyObj()); + HcfResult res = macObj->init(macObj, symKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac init failed!"); + return; + } +} + +void MacImpl::UpdateSync(DataBlob const& input) +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return; + } + HcfBlob inBlob = { .data = input.data.data(), .len = input.data.size() }; + HcfResult res = macObj->update(macObj, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac update failed!"); + return; + } +} + +DataBlob MacImpl::DoFinalSync() +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = macObj->doFinal(macObj, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac doFinal failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +int32_t MacImpl::GetMacLength() +{ + if (macObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); + return 0; + } + uint32_t length = macObj->getMacLength(macObj); + return static_cast(length); +} + +string MacImpl::GetAlgName() +{ + if (macObj == nullptr) { + return ""; + } + const char *algName = macObj->getAlgoName(macObj); + return (algName == nullptr) ? "" : string(algName); +} + +Mac CreateMac(string_view algName) +{ + HcfMac *macObj = nullptr; + HcfHmacParamsSpec parmas = { { "HMAC" }, algName.c_str() }; + HcfResult res = HcfMacCreate(reinterpret_cast(&parmas), &macObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C mac obj failed."); + return make_holder(nullptr); + } + return make_holder(macObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateMac(CreateMac); diff --git a/frameworks/js/ani/src/ani_md.cpp b/frameworks/js/ani/src/ani_md.cpp new file mode 100644 index 0000000..c264161 --- /dev/null +++ b/frameworks/js/ani/src/ani_md.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_md.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +MdImpl::MdImpl() : mdObj(nullptr) {} + +MdImpl::MdImpl(HcfMd *obj) : mdObj(obj) {} + +MdImpl::~MdImpl() {} + +void MdImpl::UpdateSync(DataBlob const& input) +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return; + } + HcfBlob inBlob = { .data = input.data.data(), .len = input.data.size() }; + HcfResult res = mdObj->update(mdObj, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "md doFinal failed!"); + return; + } +} + +DataBlob MdImpl::DigestSync() +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = mdObj->doFinal(mdObj, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "mac doFinal failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +int32_t MdImpl::GetMdLength() +{ + if (mdObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); + return 0; + } + uint32_t length = mdObj->getMdLength(mdObj); + return static_cast(length); +} + +string MdImpl::GetAlgName() +{ + if (mdObj == nullptr) { + return ""; + } + const char *algName = mdObj->getAlgoName(mdObj); + return (algName == nullptr) ? "" : string(algName); +} + +Md CreateMd(string_view algName) +{ + HcfMd *mdObj = nullptr; + HcfResult res = HcfMdCreate(algName.c_str(), &mdObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C md obj failed."); + return make_holder(nullptr); + } + return make_holder(mdObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateMd(CreateMd); diff --git a/frameworks/js/ani/src/ani_rand.cpp b/frameworks/js/ani/src/ani_rand.cpp new file mode 100644 index 0000000..0022017 --- /dev/null +++ b/frameworks/js/ani/src/ani_rand.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_rand.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +RandomImpl::RandomImpl() : randObj(nullptr) {} + +RandomImpl::RandomImpl(HcfRand *obj) : randObj(obj) {} + +RandomImpl::~RandomImpl() +{ + HcfObjDestroy(randObj); +} + +DataBlob RandomImpl::GenerateRandomSync(int32_t len) +{ + if (randObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); + return { taihe::array(nullptr, 0) }; + } + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult res = randObj->generateRandom(randObj, len, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generateRandom failed!"); + return { taihe::array(nullptr, 0) }; + } + taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +void RandomImpl::SetSeed(DataBlob const& seed) +{ + if (randObj == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); + return; + } + HcfBlob seedBlob = { .data = seed.data.data(), .len = seed.data.size() }; + HcfResult res = randObj->setSeed(randObj, &seedBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set seed failed."); + return; + } +} + +string RandomImpl::GetAlgName() +{ + if (randObj == nullptr) { + return ""; + } + const char *algName = randObj->getAlgoName(randObj); + return (algName == nullptr) ? "" : string(algName); +} + +Random CreateRandom() +{ + HcfRand *randObj = nullptr; + HcfResult res = HcfRandCreate(&randObj); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C rand obj failed."); + return make_holder(nullptr); + } + return make_holder(randObj); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateRandom(CreateRandom); diff --git a/frameworks/js/ani/src/ani_sym_key.cpp b/frameworks/js/ani/src/ani_sym_key.cpp new file mode 100644 index 0000000..cb08945 --- /dev/null +++ b/frameworks/js/ani/src/ani_sym_key.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_sym_key.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +SymKeyImpl::SymKeyImpl() : symKey(nullptr) {} + +SymKeyImpl::SymKeyImpl(HcfSymKey *obj) : symKey(obj) {} + +SymKeyImpl::~SymKeyImpl() +{ + HcfObjDestroy(symKey); +} + +void SymKeyImpl::ClearMem() +{ + TH_THROW(std::runtime_error, "ClearMem not implemented"); +} + +int64_t SymKeyImpl::GetSymKeyObj() +{ + return reinterpret_cast(symKey); +} + +DataBlob SymKeyImpl::GetEncoded() +{ + TH_THROW(std::runtime_error, "GetEncoded not implemented"); +} + +string SymKeyImpl::GetFormat() +{ + TH_THROW(std::runtime_error, "GetFormat not implemented"); +} + +string SymKeyImpl::GetAlgName() +{ + TH_THROW(std::runtime_error, "GetAlgName not implemented"); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_sym_key_generator.cpp b/frameworks/js/ani/src/ani_sym_key_generator.cpp new file mode 100644 index 0000000..5b45115 --- /dev/null +++ b/frameworks/js/ani/src/ani_sym_key_generator.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_sym_key_generator.h" +#include "ani_sym_key.h" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; +using namespace ANI::CryptoFramework; + +namespace ANI::CryptoFramework { +SymKeyGeneratorImpl::SymKeyGeneratorImpl() : generator(nullptr) {} + +SymKeyGeneratorImpl::SymKeyGeneratorImpl(HcfSymKeyGenerator *obj) : generator(obj) {} + +SymKeyGeneratorImpl::~SymKeyGeneratorImpl() +{ + HcfObjDestroy(generator); +} + +SymKey SymKeyGeneratorImpl::GenerateSymKeySync() +{ + return make_holder(nullptr); +} + +SymKey SymKeyGeneratorImpl::ConvertKeySync(DataBlob const& key) +{ + if (generator == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(nullptr); + } + HcfSymKey *symKey = nullptr; + HcfBlob keyData = { .data = key.data.data(), .len = key.data.size() }; + HcfResult res = generator->convertSymKey(generator, &keyData, &symKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "convertSymKey key failed!"); + return make_holder(nullptr); + } + return make_holder(symKey); +} + +string SymKeyGeneratorImpl::GetAlgName() +{ + if (generator == nullptr) { + return ""; + } + const char *algName = generator->getAlgoName(generator); + return (algName == nullptr) ? "" : string(algName); +} + +SymKeyGenerator CreateSymKeyGenerator(string_view algName) +{ + HcfSymKeyGenerator *generator = nullptr; + HcfResult res = HcfSymKeyGeneratorCreate(algName.c_str(), &generator); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create C generator obj fail."); + return make_holder(nullptr); + } + return make_holder(generator); +} +} // namespace ANI::CryptoFramework + +TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); diff --git a/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp b/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp new file mode 100644 index 0000000..5327a10 --- /dev/null +++ b/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos.security.cryptoFramework.cryptoFramework.proj.hpp" +#include "ohos.security.cryptoFramework.cryptoFramework.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" + +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +namespace { +// To be implemented. + +class MdImpl { +public: + MdImpl() { + // Don't forget to implement the constructor. + } + + void UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob DigestSync() { + TH_THROW(std::runtime_error, "DigestSync not implemented"); + } + + int32_t GetMdLength() { + TH_THROW(std::runtime_error, "GetMdLength not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class RandomImpl { +public: + RandomImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GenerateRandomSync(int32_t len) { + TH_THROW(std::runtime_error, "GenerateRandomSync not implemented"); + } + + void SetSeed(DataBlob const& seed) { + TH_THROW(std::runtime_error, "SetSeed not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class MacImpl { +public: + MacImpl() { + // Don't forget to implement the constructor. + } + + void InitSync(weak::SymKey key) { + TH_THROW(std::runtime_error, "InitSync not implemented"); + } + + void UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob DoFinalSync() { + TH_THROW(std::runtime_error, "DoFinalSync not implemented"); + } + + int32_t GetMacLength() { + TH_THROW(std::runtime_error, "GetMacLength not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class KeyImpl { +public: + KeyImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GetEncoded() { + TH_THROW(std::runtime_error, "GetEncoded not implemented"); + } + + string GetFormat() { + TH_THROW(std::runtime_error, "GetFormat not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class SymKeyImpl { +public: + SymKeyImpl() { + // Don't forget to implement the constructor. + } + + void ClearMem() { + TH_THROW(std::runtime_error, "ClearMem not implemented"); + } + + int64_t GetSymKeyObj() { + TH_THROW(std::runtime_error, "GetSymKeyObj not implemented"); + } + + DataBlob GetEncoded() { + TH_THROW(std::runtime_error, "GetEncoded not implemented"); + } + + string GetFormat() { + TH_THROW(std::runtime_error, "GetFormat not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class SymKeyGeneratorImpl { +public: + SymKeyGeneratorImpl() { + // Don't forget to implement the constructor. + } + + SymKey GenerateSymKeySync() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); + } + + SymKey ConvertKeySync(DataBlob const& key) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +Md CreateMd(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +Random CreateRandom() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +Mac CreateMac(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +SymKeyGenerator CreateSymKeyGenerator(string_view algName) { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} +} // namespace + +TH_EXPORT_CPP_API_CreateMd(CreateMd); +TH_EXPORT_CPP_API_CreateRandom(CreateRandom); +TH_EXPORT_CPP_API_CreateMac(CreateMac); +TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); diff --git a/frameworks/js/ani/test/arktsconfig.json b/frameworks/js/ani/test/arktsconfig.json new file mode 100644 index 0000000..6973403 --- /dev/null +++ b/frameworks/js/ani/test/arktsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "package": "", + "baseUrl": ".", + "outDir": "./dist", + "paths": { + "std": [ + "../../../../../../../arkcompiler/runtime_core/static_core/plugins/ets/stdlib/std" + ], + "escompat": [ + "../../../../../../../arkcompiler/runtime_core/static_core/plugins/ets/stdlib/escompat" + ], + "@ohos": [ + "../../../../../../../interface/sdk-js/api/@ohos" + ] + } + }, + "includes": [ + "*.ets" + ] +} diff --git a/frameworks/js/ani/test/test_mac.ets b/frameworks/js/ani/test/test_mac.ets new file mode 100644 index 0000000..69f74d5 --- /dev/null +++ b/frameworks/js/ani/test/test_mac.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testMac() { + try { + let key = "1234567890"; + let keyBytes = utils.hexStrToUint8Array(key); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + let symKey = cryptoFramework.createSymKeyGenerator("HMAC").convertKeySync({ + data: keyBytes + }); + let mac = cryptoFramework.createMac("SHA256"); + mac.initSync(symKey); + mac.updateSync({ + data: dataBytes + }); + let output = mac.doFinalSync(); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("HMAC algName: " + mac.algName); + console.log("HMAC-SHA256: " + str); + } + catch (err) { + console.error("HMAC-SHA256: " + err) + } +} diff --git a/frameworks/js/ani/test/test_main.ets b/frameworks/js/ani/test/test_main.ets new file mode 100644 index 0000000..616b5c3 --- /dev/null +++ b/frameworks/js/ani/test/test_main.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { testMd } from "./test_md"; +import { testRandom } from "./test_rand"; +import { testMac } from "./test_mac"; + +function main() { + testMac(); + testMd(); + testRandom(); +} diff --git a/frameworks/js/ani/test/test_md.ets b/frameworks/js/ani/test/test_md.ets new file mode 100644 index 0000000..e2f7949 --- /dev/null +++ b/frameworks/js/ani/test/test_md.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testMd() { + try { + let md = cryptoFramework.createMd("MD5"); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + md.updateSync({ + data: dataBytes + }); + let output = md.digestSync(); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("MD5: " + str); + let length = md.getMdLength(); + console.log("MD5 length: " + length); + } catch (err) { + console.log("MD5: " + err); + } +} diff --git a/frameworks/js/ani/test/test_rand.ets b/frameworks/js/ani/test/test_rand.ets new file mode 100644 index 0000000..5dcf01e --- /dev/null +++ b/frameworks/js/ani/test/test_rand.ets @@ -0,0 +1,34 @@ + +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +export function testRandom() { + try { + let random = cryptoFramework.createRandom(); + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + random.setSeed({ + data: dataBytes + }); + let output = random.generateRandomSync(16); + let str = utils.uint8ArrayToHexStr(output.data); + console.log("Random: " + str); + } catch (err) { + console.error("Random: " + err) + } +} diff --git a/frameworks/js/ani/test/test_utils.ets b/frameworks/js/ani/test/test_utils.ets new file mode 100644 index 0000000..38a1239 --- /dev/null +++ b/frameworks/js/ani/test/test_utils.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// import buffer from "@ohos.buffer" + +namespace utils { +export function hexStrToUint8Array(data: string): Uint8Array { + // return new Uint8Array(buffer.from(data, 'hex').buffer); + if (data.length % 2 !== 0) { + throw new Error("Invalid hex string"); + } + const array = new Uint8Array(data.length / 2); + for (let i = 0; i < data.length; i += 2) { + array[i / 2] = parseInt(data.substring(i, i + 2), 16); + } + return array; +} + +export function stringToUint8Array(str: string): Uint8Array { + // return new Uint8Array(buffer.from(str, 'utf-8').buffer); + const array = new Uint8Array(str.length); + for (let i = 0; i < str.length; i++) { + array[i] = str.charCodeAt(i); + } + return array; +} + +export function uint8ArrayToHexStr(data: Uint8Array): string { + // return buffer.from(data).toString('hex').toUpperCase(); + let str = ''; + for (let i = 0; i < data.length; i++) { + let num: Number = new Number(data[i]) + str += num.toString(16).padStart(2, '0'); + } + return str; +} +} // namespace utils + +export default utils; diff --git a/test/unittest/src/crypto_cmac_test.cpp b/test/unittest/src/crypto_cmac_test.cpp index 4df5204..3dead5e 100644 --- a/test/unittest/src/crypto_cmac_test.cpp +++ b/test/unittest/src/crypto_cmac_test.cpp @@ -130,8 +130,8 @@ HWTEST_F(CryptoCmacTest, CryptoCmacTest005, TestSize.Level0) ASSERT_EQ(ret, HCF_SUCCESS); EXPECT_NE(macObj, nullptr); // test api functions - const char *cipherName = macObj->getAlgoName(macObj); - int32_t cmpRes = strcmp(cipherName, "AES128"); + const char *algoName = macObj->getAlgoName(macObj); + int32_t cmpRes = strcmp(algoName, params.base.algName); EXPECT_EQ(cmpRes, HCF_SUCCESS); HcfObjDestroy(macObj); } diff --git a/test/unittest/src/crypto_mac_test.cpp b/test/unittest/src/crypto_mac_test.cpp index 0f6c439..fa036ae 100644 --- a/test/unittest/src/crypto_mac_test.cpp +++ b/test/unittest/src/crypto_mac_test.cpp @@ -139,7 +139,7 @@ HWTEST_F(CryptoMacTest, CryptoFrameworkHmacAlgoNameTest001, TestSize.Level0) EXPECT_NE(macObj, nullptr); // test api functions const char *algoName = macObj->getAlgoName(macObj); - int32_t cmpRes = strcmp(algoName, "SHA1"); + int32_t cmpRes = strcmp(algoName, params.base.algName); EXPECT_EQ(cmpRes, HCF_SUCCESS); HcfObjDestroy(macObj); } diff --git a/test/unittest/src/crypto_sm3_mac_test.cpp b/test/unittest/src/crypto_sm3_mac_test.cpp index 522be43..a98b376 100644 --- a/test/unittest/src/crypto_sm3_mac_test.cpp +++ b/test/unittest/src/crypto_sm3_mac_test.cpp @@ -131,7 +131,7 @@ HWTEST_F(CryptoSM3MacTest, CryptoFrameworkHmacSM3AlgoNameTest001, TestSize.Level EXPECT_NE(macObj, nullptr); // test api functions const char *algoName = macObj->getAlgoName(macObj); - int32_t cmpRes = strcmp(algoName, "SM3"); + int32_t cmpRes = strcmp(algoName, params.base.algName); EXPECT_EQ(cmpRes, HCF_SUCCESS); HcfObjDestroy(macObj); } -- Gitee