diff --git a/bundle.json b/bundle.json index 61860f688ee0fd643e659a6774ca7563f93b01a8..c43cc5bb921ff4f95598626660e533813ee6fa96 100644 --- a/bundle.json +++ b/bundle.json @@ -96,6 +96,9 @@ }, { "name": "//base/security/crypto_framework/frameworks/cj:cj_cryptoframework_ffi" + }, + { + "name": "//base/security/crypto_framework/frameworks/js/ani:copy_taihe" } ], "test": [ diff --git a/frameworks/js/ani/BUILD.gn b/frameworks/js/ani/BUILD.gn index a8ba39266cb68506284c79aa6d80e330d36634af..623d825dabc969409ddb3ce536d07602a53bbce2 100644 --- a/frameworks/js/ani/BUILD.gn +++ b/frameworks/js/ani/BUILD.gn @@ -13,7 +13,6 @@ 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") @@ -43,13 +42,28 @@ taihe_shared_library("crypto_framework_ani") { include_dirs += [ "${framework_path}/js/ani/inc" ] sources = get_target_outputs(":run_taihe") sources += [ + "${framework_path}/js/ani/src/ani_asy_key_generator.cpp", + "${framework_path}/js/ani/src/ani_asy_key_generator_by_spec.cpp", + "${framework_path}/js/ani/src/ani_cipher.cpp", + "${framework_path}/js/ani/src/ani_common.cpp", "${framework_path}/js/ani/src/ani_constructor.cpp", + "${framework_path}/js/ani/src/ani_dh_key_util.cpp", + "${framework_path}/js/ani/src/ani_ecc_key_util.cpp", + "${framework_path}/js/ani/src/ani_kdf.cpp", "${framework_path}/js/ani/src/ani_key.cpp", + "${framework_path}/js/ani/src/ani_key_agreement.cpp", + "${framework_path}/js/ani/src/ani_key_pair.cpp", "${framework_path}/js/ani/src/ani_mac.cpp", "${framework_path}/js/ani/src/ani_md.cpp", + "${framework_path}/js/ani/src/ani_pri_key.cpp", + "${framework_path}/js/ani/src/ani_pub_key.cpp", "${framework_path}/js/ani/src/ani_rand.cpp", + "${framework_path}/js/ani/src/ani_sign.cpp", + "${framework_path}/js/ani/src/ani_signature_utils.cpp", + "${framework_path}/js/ani/src/ani_sm2_crypto_util.cpp", "${framework_path}/js/ani/src/ani_sym_key.cpp", "${framework_path}/js/ani/src/ani_sym_key_generator.cpp", + "${framework_path}/js/ani/src/ani_verify.cpp", ] deps = [ ":run_taihe", @@ -69,10 +83,7 @@ taihe_shared_library("crypto_framework_ani") { ] external_deps = [ "bounds_checking_function:libsec_shared", - "c_utils:utils", "hilog:libhilog", - "openssl:libcrypto_shared", - "runtime_core:ani", ] } @@ -84,28 +95,12 @@ generate_static_abc("crypto_framework_ets") { 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", - ] + deps = [ ":crypto_framework_ets" ] } group("cryptoframework_ani") { diff --git a/frameworks/js/ani/dts/cryptoFramework.d.ts b/frameworks/js/ani/dts/cryptoFramework.d.ts index 87c524711c78a40711c04b02962461bde1056d5d..8dfe765c45d34e0ff569012a6a988c56ce5b33af 100644 --- a/frameworks/js/ani/dts/cryptoFramework.d.ts +++ b/frameworks/js/ani/dts/cryptoFramework.d.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import type { AsyncCallback, Callback } from './@ohos.base'; +import type { AsyncCallback } from './@ohos.base'; declare namespace cryptoFramework { enum Result { @@ -21,6 +21,7 @@ declare namespace cryptoFramework { NOT_SUPPORT = 801, ERR_OUT_OF_MEMORY = 17620001, ERR_RUNTIME_ERROR = 17620002, + ERR_PARAMETER_CHECK_FAILED = 17620003, ERR_CRYPTO_OPERATION = 17630001 } @@ -58,7 +59,6 @@ declare namespace cryptoFramework { cipherName: string; } - interface Key { getEncoded(): DataBlob; readonly format: string; @@ -71,14 +71,14 @@ declare namespace cryptoFramework { interface PriKey extends Key { clearMem(): void; - getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | int; getEncodedDer(format: string): DataBlob; getEncodedPem(format: string): string; getEncodedPem(format: string, config: KeyEncodingConfig): string; } interface PubKey extends Key { - getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | number; + getAsyKeySpec(itemType: AsyKeySpecItem): bigint | string | int; getEncodedDer(format: string): DataBlob; getEncodedPem(format: string): string; } @@ -89,9 +89,9 @@ declare namespace cryptoFramework { } interface Random { - generateRandom(len: number, callback: AsyncCallback): void; - generateRandom(len: number): Promise; - generateRandomSync(len: number): DataBlob; + generateRandom(len: int, callback: AsyncCallback): void; + generateRandom(len: int): Promise; + generateRandomSync(len: int): DataBlob; setSeed(seed: DataBlob): void; readonly algName: string; } @@ -101,9 +101,7 @@ declare namespace cryptoFramework { 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; @@ -148,7 +146,7 @@ declare namespace cryptoFramework { doFinal(callback: AsyncCallback): void; doFinal(): Promise; doFinalSync(): DataBlob; - getMacLength(): number; + getMacLength(): int; readonly algName: string; } function createMac(algName: string): Mac; @@ -161,7 +159,7 @@ declare namespace cryptoFramework { digest(callback: AsyncCallback): void; digest(): Promise; digestSync(): DataBlob; - getMdLength(): number; + getMdLength(): int; readonly algName: string; } function createMd(algName: string): Md; @@ -184,17 +182,13 @@ declare namespace cryptoFramework { } 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; @@ -210,14 +204,11 @@ declare namespace cryptoFramework { 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; + setSignSpec(itemType: SignSpecItem, itemValue: int | Uint8Array): void; + getSignSpec(itemType: SignSpecItem): string | int; readonly algName: string; } @@ -228,16 +219,13 @@ declare namespace cryptoFramework { 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; + setVerifySpec(itemType: SignSpecItem, itemValue: int | Uint8Array): void; + getVerifySpec(itemType: SignSpecItem): string | int; readonly algName: string; } function createSign(algName: string): Sign; @@ -332,7 +320,7 @@ declare namespace cryptoFramework { b: bigint; g: Point; n: bigint; - h: number; + h: int; } interface ECCPriKeySpec extends AsyKeySpec { @@ -360,7 +348,7 @@ declare namespace cryptoFramework { interface DHCommonParamsSpec extends AsyKeySpec { p: bigint; g: bigint; - l: number; + l: int; } interface DHPriKeySpec extends AsyKeySpec { @@ -380,7 +368,7 @@ declare namespace cryptoFramework { } class DHKeyUtil { - static genDHCommonParamsSpec(pLen: number, skLen?: number): DHCommonParamsSpec; + static genDHCommonParamsSpec(pLen: int, skLen?: int): DHCommonParamsSpec; } interface ED25519PriKeySpec extends AsyKeySpec { @@ -445,25 +433,25 @@ declare namespace cryptoFramework { interface PBKDF2Spec extends KdfSpec { password: string | Uint8Array; salt: Uint8Array; - iterations: number; - keySize: number; + iterations: int; + keySize: int; } interface HKDFSpec extends KdfSpec { key: string | Uint8Array; salt: Uint8Array; info: Uint8Array; - keySize: number; + keySize: int; } interface ScryptSpec extends KdfSpec { passphrase: string | Uint8Array; salt: Uint8Array; - n: number; - r: number; - p: number; - maxMemory: number; - keySize: number; + n: long; + r: long; + p: long; + maxMemory: long; + keySize: int; } interface Kdf { @@ -485,6 +473,16 @@ declare namespace cryptoFramework { static genCipherTextBySpec(spec: SM2CipherTextSpec, mode?: string): DataBlob; static getCipherTextSpec(cipherText: DataBlob, mode?: string): SM2CipherTextSpec; } + + interface EccSignatureSpec { + r: bigint; + s: bigint; + } + + class SignatureUtils { + static genEccSignatureSpec(data: Uint8Array): EccSignatureSpec; + static genEccSignature(spec: EccSignatureSpec): Uint8Array; + } } 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 index 42b5987704e0770de321b6d19b279062c32a14df..8ae1bbed4239b693f715ffba7d8987baa6264c09 100644 --- a/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe +++ b/frameworks/js/ani/idl/ohos.security.cryptoFramework.cryptoFramework.taihe @@ -14,14 +14,47 @@ */ @!namespace("@ohos.security.cryptoFramework", "cryptoFramework") -@!typed_array @!sts_inject(""" static { loadLibrary("crypto_framework_ani.z"); } """) +enum Result: i32 { + INVALID_PARAMS = 401, + NOT_SUPPORT = 801, + ERR_OUT_OF_MEMORY = 17620001, + ERR_RUNTIME_ERROR = 17620002, + ERR_PARAMETER_CHECK_FAILED = 17620003, + ERR_CRYPTO_OPERATION = 17630001 +} + struct DataBlob { - data: Array; + data: @typedarray Array; +} + +union OptString { + STRING: String; + @null EMPTY; +} + +union OptDataBlob { + DATABLOB: DataBlob; + @null EMPTY; +} + +union OptStrUint8Arr { + STRING: String; + UINT8ARRAY: @typedarray Array; +} + +union OptStrInt { + STRING: String; + INT32: i32; +} + +union OptIntUint8Arr { + INT32: i32; + UINT8ARRAY: @typedarray Array; } interface Md { @@ -32,7 +65,7 @@ interface Md { @gen_promise("digest") DigestSync(): DataBlob; GetMdLength(): i32; - @get GetAlgName(): String; + @get("algName") GetAlgName(): String; } function CreateMd(algName: String): Md; @@ -41,10 +74,30 @@ interface Random { @gen_promise("generateRandom") GenerateRandomSync(len: i32): DataBlob; SetSeed(seed: DataBlob): void; - @get GetAlgName(): String; + @get("algName") GetAlgName(): String; } function CreateRandom(): Random; +struct MacSpec { + algName: String; +} + +struct HmacSpec { + @extends base: MacSpec; + mdName: String; +} + +struct CmacSpec { + @extends base: MacSpec; + cipherName: String; +} + +union OptExtMacSpec { + HMACSPEC: HmacSpec; + CMACSPEC: CmacSpec; + MACSPEC: MacSpec; +} + interface Mac { @gen_async("init") @gen_promise("init") @@ -56,19 +109,117 @@ interface Mac { @gen_promise("doFinal") DoFinalSync(): DataBlob; GetMacLength(): i32; - @get GetAlgName(): String; + @get("algName") GetAlgName(): String; } -function CreateMac(algName: String): Mac; +@overload("createMac") +function CreateMacByStr(algName: String): Mac; +@overload("createMac") +function CreateMacBySpec(macSpec: OptExtMacSpec): Mac; interface Key { + GetKeyObj(): i64; GetEncoded(): DataBlob; - @get GetFormat(): String; - @get GetAlgName(): String; + @get("format") GetFormat(): String; + @get("algName") GetAlgName(): String; } -interface SymKey: Key { +enum AsyKeySpecType: i32 { + COMMON_PARAMS_SPEC = 0, + PRIVATE_KEY_SPEC = 1, + PUBLIC_KEY_SPEC = 2, + KEY_PAIR_SPEC = 3 +} + +enum AsyKeySpecItem: i32 { + 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 CipherSpecItem: i32 { + 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: i32 { + 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 +} + +struct KeyEncodingConfig { + password: String; + cipherName: String; +} + +union OptKeySpec { + BIGINT: @bigint Array; + STRING: String; + INT32: i32; +} + +interface PriKey: Key { + GetPriKeyObj(): i64; ClearMem(): void; + GetAsyKeySpec(itemType: AsyKeySpecItem): OptKeySpec; + GetEncodedDer(format: String): DataBlob; + @overload("getEncodedPem") + GetEncodedPem(format: String): String; + @overload("getEncodedPem") + GetEncodedPemEx(format: String, config: KeyEncodingConfig): String; +} + +interface PubKey: Key { + @!sts_inject_into_class(""" + static { loadLibrary("crypto_framework_ani.z"); } + """) + GetPubKeyObj(): i64; + GetAsyKeySpec(itemType: AsyKeySpecItem): OptKeySpec; + GetEncodedDer(format: String): DataBlob; + GetEncodedPem(format: String): String; +} + +interface KeyPair { + @get("priKey") GetPriKey(): PriKey; + @get("pubKey") GetPubKey(): PubKey; +} + +interface SymKey: Key { GetSymKeyObj(): i64; + ClearMem(): void; } interface SymKeyGenerator { @@ -78,6 +229,409 @@ interface SymKeyGenerator { @gen_async("convertKey") @gen_promise("convertKey") ConvertKeySync(key: DataBlob): SymKey; - @get GetAlgName(): String; + @get("algName") GetAlgName(): String; } function CreateSymKeyGenerator(algName: String): SymKeyGenerator; + +interface AsyKeyGenerator { + @gen_async("generateKeyPair") + @gen_promise("generateKeyPair") + GenerateKeyPairSync(): KeyPair; + @gen_async("convertKey") + @gen_promise("convertKey") + ConvertKeySync(pubKey: OptDataBlob, priKey: OptDataBlob): KeyPair; + @gen_async("convertPemKey") + @gen_promise("convertPemKey") + @overload("convertPemKeySync") + ConvertPemKeySync(pubKey: OptString, priKey: OptString): KeyPair; + @gen_async("convertPemKey") + @gen_promise("convertPemKey") + @overload("convertPemKeySync") + ConvertPemKeySyncEx(pubKey: OptString, priKey: OptString, password: String): KeyPair; + @get("algName") GetAlgName(): String; +} +function CreateAsyKeyGenerator(algName: String): AsyKeyGenerator; + +struct KdfSpec { + algName: String; +} + +struct PBKDF2Spec { + @extends base: KdfSpec; + password: OptStrUint8Arr; + salt: @typedarray Array; + iterations: i32; + keySize: i32; +} + +struct HKDFSpec { + @extends base: KdfSpec; + key: OptStrUint8Arr; + salt: @typedarray Array; + info: @typedarray Array; + keySize: i32; +} + +struct ScryptSpec { + @extends base: KdfSpec; + passphrase: OptStrUint8Arr; + salt: @typedarray Array; + n: i64; + r: i64; + p: i64; + maxMemory: i64; + keySize: i32; +} + +union OptExtKdfSpec { + PBKDF2SPEC: PBKDF2Spec; + HKDFSPEC: HKDFSpec; + SCRYPTSPEC: ScryptSpec; + KDFSPEC: KdfSpec; +} + +interface Kdf { + @gen_async("generateSecret") + @gen_promise("generateSecret") + GenerateSecretSync(params: OptExtKdfSpec): DataBlob; + @get("algName") GetAlgName(): String; +} +function CreateKdf(algName: String): Kdf; + +enum CryptoMode: i32 { + ENCRYPT_MODE = 0, + DECRYPT_MODE = 1 +} + +struct ParamsSpec { + algName: String; +} + +struct IvParamsSpec { + @extends base: ParamsSpec; + iv: DataBlob; +} + +struct GcmParamsSpec { + @extends base: ParamsSpec; + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; +} + +struct CcmParamsSpec { + @extends base: ParamsSpec; + iv: DataBlob; + aad: DataBlob; + authTag: DataBlob; +} + +union OptExtParamsSpec { + IVPARAMSSPEC: IvParamsSpec; + GCMPARAMSSPEC: GcmParamsSpec; + CCMPARAMSSPEC: CcmParamsSpec; + PARAMSSPEC: ParamsSpec; +} + +union OptParamsSpec { + PARAMSSPEC: OptExtParamsSpec; + @null EMPTY; +} + +interface Cipher { + @gen_async("init") + @gen_promise("init") + InitSync(opMode: CryptoMode, key: Key, params: OptParamsSpec): void; + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): DataBlob; + @gen_async("doFinal") + @gen_promise("doFinal") + DoFinalSync(input: OptDataBlob): DataBlob; + SetCipherSpec(itemType: CipherSpecItem, itemValue: @typedarray Array): void; + GetCipherSpec(itemType: CipherSpecItem): OptStrUint8Arr; + @get("algName") GetAlgName(): String; +} +function CreateCipher(transformation: String): Cipher; + +interface Verify { + @gen_async("init") + @gen_promise("init") + InitSync(pubKey: PubKey): void; + @gen_async("update") + @gen_promise("update") + UpdateSync(input: DataBlob): void; + @gen_async("verify") + @gen_promise("verify") + VerifySync(data: OptDataBlob, signature: DataBlob): bool; + @gen_async("recover") + @gen_promise("recover") + RecoverSync(signature: DataBlob): OptDataBlob; + SetVerifySpec(itemType: SignSpecItem, itemValue: OptIntUint8Arr): void; + GetVerifySpec(itemType: SignSpecItem): OptStrInt; + @get("algName") GetAlgName(): String; +} +function CreateVerify(algName: String): Verify; + +interface Sign { + @gen_async("init") + @gen_promise("init") + InitSync(priKey: PriKey): void; + @gen_async("update") + @gen_promise("update") + UpdateSync(data: DataBlob): void; + @gen_async("sign") + @gen_promise("sign") + SignSync(data: OptDataBlob): DataBlob; + SetSignSpec(itemType: SignSpecItem, itemValue: OptIntUint8Arr): void; + GetSignSpec(itemType: SignSpecItem): OptStrInt; + @get("algName") GetAlgName(): String; +} +function CreateSign(algName: String): Sign; + +struct AsyKeySpec { + algName: String; + specType: AsyKeySpecType; +} + +struct DSACommonParamsSpec { + @extends base: AsyKeySpec; + p: @bigint Array; + q: @bigint Array; + g: @bigint Array; +} + +struct DSAPubKeySpec { + @extends base: AsyKeySpec; + params: DSACommonParamsSpec; + pk: @bigint Array; +} + +struct DSAKeyPairSpec { + @extends base: AsyKeySpec; + params: DSACommonParamsSpec; + sk: @bigint Array; + pk: @bigint Array; +} + +struct DSAAsyKeySpec { + @extends base: AsyKeySpec; + params: DSACommonParamsSpec; + sk: @bigint Array; +} + +struct Point { + x: @bigint Array; + y: @bigint Array; +} + +struct ECCCommonParamsSpec { + @extends base: AsyKeySpec; + field: OptECField; + a: @bigint Array; + b: @bigint Array; + g: Point; + n: @bigint Array; + h: i32; +} + +struct ECCPriKeySpec { + @extends base: AsyKeySpec; + params: ECCCommonParamsSpec; + sk: @bigint Array; +} + +struct ECCPubKeySpec { + @extends base: AsyKeySpec; + params: ECCCommonParamsSpec; + pk: Point; +} + +struct ECCKeyPairSpec { + @extends base: AsyKeySpec; + params: ECCCommonParamsSpec; + sk: @bigint Array; + pk: Point; +} + +struct ECCAsyKeySpec { + @extends base: AsyKeySpec; + params: ECCCommonParamsSpec; + sk: @bigint Array; +} + +struct DHCommonParamsSpec { + @extends base: AsyKeySpec; + p: @bigint Array; + g: @bigint Array; + l: i32; +} + +struct DHPriKeySpec { + @extends base: AsyKeySpec; + params: DHCommonParamsSpec; + sk: @bigint Array; +} + +struct DHPubKeySpec { + @extends base: AsyKeySpec; + params: DHCommonParamsSpec; + pk: @bigint Array; +} + +struct DHKeyPairSpec { + @extends base: AsyKeySpec; + params: DHCommonParamsSpec; + sk: @bigint Array; + pk: @bigint Array; +} + +struct ED25519PriKeySpec { + @extends base: AsyKeySpec; + sk: @bigint Array; +} + +struct ED25519PubKeySpec { + @extends base: AsyKeySpec; + pk: @bigint Array; +} + +struct ED25519KeyPairSpec { + @extends base: AsyKeySpec; + sk: @bigint Array; + pk: @bigint Array; +} + +struct X25519PriKeySpec { + @extends base: AsyKeySpec; + sk: @bigint Array; +} + +struct X25519PubKeySpec { + @extends base: AsyKeySpec; + pk: @bigint Array; +} + +struct X25519KeyPairSpec { + @extends base: AsyKeySpec; + sk: @bigint Array; + pk: @bigint Array; +} + +struct RSACommonParamsSpec { + @extends base: AsyKeySpec; + n: @bigint Array; +} + +struct RSAPubKeySpec { + @extends base: AsyKeySpec; + params: RSACommonParamsSpec; + pk: @bigint Array; +} + +struct RSAKeyPairSpec { + @extends base: AsyKeySpec; + params: RSACommonParamsSpec; + sk: @bigint Array; + pk: @bigint Array; +} + +struct ECField { + fieldType: String; +} + +struct ECFieldFp { + @extends base: ECField; + p: @bigint Array; +} + +union OptECField { + ECFIELDFP: ECFieldFp; + ECFIELD: ECField; +} + +union OptAsyKeySpec { + DSACOMMONPARAMSSPEC: DSACommonParamsSpec; + DSAPUBKEYSPEC: DSAPubKeySpec; + DSAKEYPAIRSPEC: DSAKeyPairSpec; + ECCCOMMONPARAMSSPEC: ECCCommonParamsSpec; + ECCPRIKEYSPEC: ECCPriKeySpec; + ECCPUBKEYSPEC: ECCPubKeySpec; + ECCKEYPAIRSPEC: ECCKeyPairSpec; + DHCOMMONPARAMSSPEC: DHCommonParamsSpec; + DHPRIKEYSPEC: DHPriKeySpec; + DHPUBKEYSPEC: DHPubKeySpec; + DHKEYPAIRSPEC: DHKeyPairSpec; + ED25519PRIKEYSPEC: ED25519PriKeySpec; + ED25519PUBKEYSPEC: ED25519PubKeySpec; + ED25519KEYPAIRSPEC: ED25519KeyPairSpec; + X25519PRIKEYSPEC: X25519PriKeySpec; + X25519PUBKEYSPEC: X25519PubKeySpec; + X25519KEYPAIRSPEC: X25519KeyPairSpec; + RSACOMMONPARAMSSPEC: RSACommonParamsSpec; + RSAPUBKEYSPEC: RSAPubKeySpec; + RSAKEYPAIRSPEC: RSAKeyPairSpec; + ASYKEYSPEC: AsyKeySpec; +} + +interface AsyKeyGeneratorBySpec { + @gen_async("generateKeyPair") + @gen_promise("generateKeyPair") + GenerateKeyPairSync(): KeyPair; + @gen_async("generatePriKey") + @gen_promise("generatePriKey") + GeneratePriKeySync(): PriKey; + @gen_async("generatePubKey") + @gen_promise("generatePubKey") + GeneratePubKeySync(): PubKey; + @get("algName") GetAlgName(): String; +} +function CreateAsyKeyGeneratorBySpec(asyKeySpec: OptAsyKeySpec): AsyKeyGeneratorBySpec; + +interface KeyAgreement { + @gen_async("generateSecret") + @gen_promise("generateSecret") + GenerateSecretSync(priKey: PriKey, pubKey: PubKey): DataBlob; + @get("algName") GetAlgName(): String; +} +function CreateKeyAgreement(algName: String): KeyAgreement; + +@class +interface DHKeyUtil {} +@static("DHKeyUtil") +function GenDHCommonParamsSpec(pLen: i32, skLen: Optional): DHCommonParamsSpec; + +@class +interface ECCKeyUtil {} +@static("ECCKeyUtil") +function GenECCCommonParamsSpec(curveName: String): ECCCommonParamsSpec; +@static("ECCKeyUtil") +function ConvertPoint(curveName: String, encodedPoint: @typedarray Array): Point; +@static("ECCKeyUtil") +function GetEncodedPoint(curveName: String, point: Point, format: String): @typedarray Array; + +struct SM2CipherTextSpec { + xCoordinate: @bigint Array; + yCoordinate: @bigint Array; + cipherTextData: @typedarray Array; + hashData: @typedarray Array; +} + +@class +interface SM2CryptoUtil {} +@static("SM2CryptoUtil") +function GenCipherTextBySpec(spec: SM2CipherTextSpec, mode: Optional): DataBlob; +@static("SM2CryptoUtil") +function GetCipherTextSpec(cipherText: DataBlob, mode: Optional): SM2CipherTextSpec; + +struct EccSignatureSpec { + r: @bigint Array; + s: @bigint Array; +} + +@class +interface SignatureUtils {} +@static("SignatureUtils") +function GenEccSignatureSpec(data: @typedarray Array): EccSignatureSpec; +@static("SignatureUtils") +function GenEccSignature(spec: EccSignatureSpec): @typedarray Array; diff --git a/frameworks/js/ani/inc/ani_asy_key_generator.h b/frameworks/js/ani/inc/ani_asy_key_generator.h new file mode 100644 index 0000000000000000000000000000000000000000..8b5eba6b1a1f7223ef60382612d47573de5a3f9a --- /dev/null +++ b/frameworks/js/ani/inc/ani_asy_key_generator.h @@ -0,0 +1,40 @@ +/* + * 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_ASY_KEY_GENERATOR_H +#define ANI_ASY_KEY_GENERATOR_H + +#include "ani_common.h" +#include "asy_key_generator.h" + +namespace ANI::CryptoFramework { +class AsyKeyGeneratorImpl { +public: + AsyKeyGeneratorImpl(); + explicit AsyKeyGeneratorImpl(HcfAsyKeyGenerator *generator); + ~AsyKeyGeneratorImpl(); + + KeyPair GenerateKeyPairSync(); + KeyPair ConvertKeySync(OptDataBlob const& pubKey, OptDataBlob const& priKey); + KeyPair ConvertPemKeySync(OptString const& pubKey, OptString const& priKey); + KeyPair ConvertPemKeySyncEx(OptString const& pubKey, OptString const& priKey, string_view password); + string GetAlgName(); + +private: + HcfAsyKeyGenerator *generator_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_ASY_KEY_GENERATOR_H diff --git a/frameworks/js/ani/inc/ani_asy_key_generator_by_spec.h b/frameworks/js/ani/inc/ani_asy_key_generator_by_spec.h new file mode 100644 index 0000000000000000000000000000000000000000..27754f84173114e6df0d8bdbc91e1af5737a582c --- /dev/null +++ b/frameworks/js/ani/inc/ani_asy_key_generator_by_spec.h @@ -0,0 +1,39 @@ +/* + * 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_ASY_KEY_GENERATOR_BY_SPEC_H +#define ANI_ASY_KEY_GENERATOR_BY_SPEC_H + +#include "ani_common.h" +#include "asy_key_generator.h" + +namespace ANI::CryptoFramework { +class AsyKeyGeneratorBySpecImpl { +public: + AsyKeyGeneratorBySpecImpl(); + explicit AsyKeyGeneratorBySpecImpl(HcfAsyKeyGeneratorBySpec *generator); + ~AsyKeyGeneratorBySpecImpl(); + + KeyPair GenerateKeyPairSync(); + PriKey GeneratePriKeySync(); + PubKey GeneratePubKeySync(); + string GetAlgName(); + +private: + HcfAsyKeyGeneratorBySpec *generator_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_ASY_KEY_GENERATOR_BY_SPEC_H diff --git a/frameworks/js/ani/inc/ani_cipher.h b/frameworks/js/ani/inc/ani_cipher.h new file mode 100644 index 0000000000000000000000000000000000000000..2a5753769311940f7204df3b3a5873e98cb70ff5 --- /dev/null +++ b/frameworks/js/ani/inc/ani_cipher.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_CIPHER_H +#define ANI_CIPHER_H + +#include "ani_common.h" +#include "cipher.h" + +namespace ANI::CryptoFramework { +class CipherImpl { +public: + CipherImpl(); + explicit CipherImpl(HcfCipher *cipher); + ~CipherImpl(); + + void InitSync(CryptoMode opMode, weak::Key key, OptParamsSpec const& params); + DataBlob UpdateSync(DataBlob const& input); + DataBlob DoFinalSync(OptDataBlob const& input); + void SetCipherSpec(ThCipherSpecItem itemType, array_view itemValue); + OptStrUint8Arr GetCipherSpec(ThCipherSpecItem itemType); + string GetAlgName(); + +private: + HcfCipher *cipher_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_CIPHER_H diff --git a/frameworks/js/ani/inc/ani_common.h b/frameworks/js/ani/inc/ani_common.h index ce4e8ba6a67188432ee1ce0c9a0ba6c07e57a3df..f9bd6fb0da05aea22f2b6ef0a4e20563d4c0c112 100644 --- a/frameworks/js/ani/inc/ani_common.h +++ b/frameworks/js/ani/inc/ani_common.h @@ -24,12 +24,47 @@ #include "log.h" #include "blob.h" #include "result.h" +#include "memory.h" #include "object_base.h" +#include "big_integer.h" + +#include "key.h" +#include "cipher.h" +#include "signature.h" + +namespace ANI::CryptoFramework { +using namespace taihe; +using namespace ohos::security::cryptoFramework::cryptoFramework; + +// Resolve the issue of enumeration conflicts with the same name between inner and taihe +using HcfAsyKeySpecItem = ::AsyKeySpecItem; +using HcfCipherSpecItem = ::CipherSpecItem; +using HcfSignSpecItem = ::SignSpecItem; +using ThAsyKeySpecItem = ohos::security::cryptoFramework::cryptoFramework::AsyKeySpecItem; +using ThCipherSpecItem = ohos::security::cryptoFramework::cryptoFramework::CipherSpecItem; +using ThSignSpecItem = ohos::security::cryptoFramework::cryptoFramework::SignSpecItem; + +constexpr int SPEC_ITEM_TYPE_BIG_INT = 1; +constexpr int SPEC_ITEM_TYPE_NUM = 2; +constexpr int SPEC_ITEM_TYPE_STR = 3; +constexpr int SPEC_ITEM_TYPE_UINT8ARR = 4; #define ANI_LOGE_THROW(code, msg) \ do { \ - taihe::set_business_error(code, msg); \ - LOGE(msg); \ + LOGE("%{public}s", msg); \ + set_business_error(ConvertResultCode(code), msg); \ } while (0) +int ConvertResultCode(HcfResult res); + +void ArrayU8ToDataBlob(const array &arr, HcfBlob &blob); +void DataBlobToArrayU8(const HcfBlob &blob, array &arr); +void ArrayU8ToBigInteger(const array &arr, HcfBigInteger &bigint); +void BigIntegerToArrayU8(const HcfBigInteger &bigint, array &arr); +void StringToDataBlob(const string &str, HcfBlob &blob); + +int GetAsyKeySpecType(HcfAsyKeySpecItem item); +int GetSignSpecType(HcfSignSpecItem item); +} // namespace ANI::CryptoFramework + #endif // ANI_COMMON_H diff --git a/frameworks/js/ani/inc/ani_dh_key_util.h b/frameworks/js/ani/inc/ani_dh_key_util.h new file mode 100644 index 0000000000000000000000000000000000000000..eac9149dd4e2f47add707f18d8c065e16e210576 --- /dev/null +++ b/frameworks/js/ani/inc/ani_dh_key_util.h @@ -0,0 +1,29 @@ +/* + * 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_DH_KEY_UTIL_H +#define ANI_DH_KEY_UTIL_H + +#include "ani_common.h" + +namespace ANI::CryptoFramework { +class DHKeyUtilImpl { +public: + DHKeyUtilImpl() = delete; + ~DHKeyUtilImpl() = delete; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_DH_KEY_UTIL_H diff --git a/frameworks/js/ani/inc/ani_ecc_key_util.h b/frameworks/js/ani/inc/ani_ecc_key_util.h new file mode 100644 index 0000000000000000000000000000000000000000..ccb22eb847c057529fd6000b829a3668ed40e46a --- /dev/null +++ b/frameworks/js/ani/inc/ani_ecc_key_util.h @@ -0,0 +1,29 @@ +/* + * 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_ECC_KEY_UTIL_H +#define ANI_ECC_KEY_UTIL_H + +#include "ani_common.h" + +namespace ANI::CryptoFramework { +class ECCKeyUtilImpl { +public: + ECCKeyUtilImpl() = delete; + ~ECCKeyUtilImpl() = delete; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_ECC_KEY_UTIL_H diff --git a/frameworks/js/ani/inc/ani_kdf.h b/frameworks/js/ani/inc/ani_kdf.h new file mode 100644 index 0000000000000000000000000000000000000000..92e78a3e30674be8c77f4bda632b1c1a3b89bacd --- /dev/null +++ b/frameworks/js/ani/inc/ani_kdf.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_MAC_H +#define ANI_MAC_H + +#include "ani_common.h" +#include "kdf.h" + +namespace ANI::CryptoFramework { +class KdfImpl { +public: + KdfImpl(); + explicit KdfImpl(HcfKdf *kdf); + ~KdfImpl(); + + DataBlob GenerateSecretSync(OptExtKdfSpec const& params); + string GetAlgName(); + +private: + HcfKdf *kdf_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_MAC_H diff --git a/frameworks/js/ani/inc/ani_key.h b/frameworks/js/ani/inc/ani_key.h index 1cf1f4021071d687dc44585217470366f19c09df..3d49d9695dfd5ae3cee888fe1bf888f799d68463 100644 --- a/frameworks/js/ani/inc/ani_key.h +++ b/frameworks/js/ani/inc/ani_key.h @@ -20,17 +20,19 @@ #include "key.h" namespace ANI::CryptoFramework { -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; - class KeyImpl { public: KeyImpl(); + explicit KeyImpl(HcfKey *key); ~KeyImpl(); + int64_t GetKeyObj(); DataBlob GetEncoded(); string GetFormat(); string GetAlgName(); + +private: + HcfKey *key_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_key_agreement.h b/frameworks/js/ani/inc/ani_key_agreement.h new file mode 100644 index 0000000000000000000000000000000000000000..d21fdf492714bc4a517151bffe0783b43d2c861c --- /dev/null +++ b/frameworks/js/ani/inc/ani_key_agreement.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_AGREEMENT_H +#define ANI_KEY_AGREEMENT_H + +#include "ani_common.h" +#include "key_agreement.h" + +namespace ANI::CryptoFramework { +class KeyAgreementImpl { +public: + KeyAgreementImpl(); + explicit KeyAgreementImpl(HcfKeyAgreement *keyAgreement); + ~KeyAgreementImpl(); + + DataBlob GenerateSecretSync(weak::PriKey priKey, weak::PubKey pubKey); + string GetAlgName(); + +private: + HcfKeyAgreement *keyAgreement_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_KEY_AGREEMENT_H diff --git a/frameworks/js/ani/inc/ani_key_pair.h b/frameworks/js/ani/inc/ani_key_pair.h new file mode 100644 index 0000000000000000000000000000000000000000..246abd50f18ec24da92817d8055af9ffefef6552 --- /dev/null +++ b/frameworks/js/ani/inc/ani_key_pair.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_PAIR_H +#define ANI_KEY_PAIR_H + +#include "ani_common.h" +#include "key_pair.h" + +namespace ANI::CryptoFramework { +class KeyPairImpl { +public: + KeyPairImpl(); + explicit KeyPairImpl(HcfKeyPair *keyPair); + ~KeyPairImpl(); + + PriKey GetPriKey(); + PubKey GetPubKey(); + +private: + HcfKeyPair *keyPair_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_KEY_PAIR_H diff --git a/frameworks/js/ani/inc/ani_mac.h b/frameworks/js/ani/inc/ani_mac.h index 0416ef2670564b81cecea7032a1aae9e8f85bdd3..b795047714332c08a79e31887217a37219f32c1d 100644 --- a/frameworks/js/ani/inc/ani_mac.h +++ b/frameworks/js/ani/inc/ani_mac.h @@ -20,13 +20,10 @@ #include "mac.h" namespace ANI::CryptoFramework { -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; - class MacImpl { public: MacImpl(); - explicit MacImpl(HcfMac *obj); + explicit MacImpl(HcfMac *mac); ~MacImpl(); void InitSync(weak::SymKey key); @@ -36,7 +33,7 @@ public: string GetAlgName(); private: - HcfMac *macObj = nullptr; + HcfMac *mac_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_md.h b/frameworks/js/ani/inc/ani_md.h index 35cbe7cc7bccec19761845672133eed483b9fc37..446eb88fa14a1a5bc5be4fc1a15c3bc3d83bd634 100644 --- a/frameworks/js/ani/inc/ani_md.h +++ b/frameworks/js/ani/inc/ani_md.h @@ -20,13 +20,10 @@ #include "md.h" namespace ANI::CryptoFramework { -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; - class MdImpl { public: MdImpl(); - explicit MdImpl(HcfMd *obj); + explicit MdImpl(HcfMd *md); ~MdImpl(); void UpdateSync(DataBlob const& input); @@ -35,7 +32,7 @@ public: string GetAlgName(); private: - HcfMd *mdObj = nullptr; + HcfMd *md_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_pri_key.h b/frameworks/js/ani/inc/ani_pri_key.h new file mode 100644 index 0000000000000000000000000000000000000000..f052d9e67e7a64bfb42c6302722ec31388f37271 --- /dev/null +++ b/frameworks/js/ani/inc/ani_pri_key.h @@ -0,0 +1,46 @@ +/* + * 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_PRI_KEY_H +#define ANI_PRI_KEY_H + +#include "ani_common.h" +#include "pri_key.h" + +namespace ANI::CryptoFramework { +class PriKeyImpl { +public: + PriKeyImpl(); + explicit PriKeyImpl(HcfPriKey *priKey, bool owner = true); + ~PriKeyImpl(); + + int64_t GetPriKeyObj(); + void ClearMem(); + OptKeySpec GetAsyKeySpec(ThAsyKeySpecItem itemType); + DataBlob GetEncodedDer(string_view format); + string GetEncodedPem(string_view format); + string GetEncodedPemEx(string_view format, KeyEncodingConfig const& config); + int64_t GetKeyObj(); + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); + +private: + HcfPriKey *priKey_ = nullptr; + bool owner_ = false; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_PRI_KEY_H diff --git a/frameworks/js/ani/inc/ani_pub_key.h b/frameworks/js/ani/inc/ani_pub_key.h new file mode 100644 index 0000000000000000000000000000000000000000..c361597237fabc27b7438d03547150478f9970f5 --- /dev/null +++ b/frameworks/js/ani/inc/ani_pub_key.h @@ -0,0 +1,44 @@ +/* + * 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_PUB_KEY_H +#define ANI_PUB_KEY_H + +#include "ani_common.h" +#include "pub_key.h" + +namespace ANI::CryptoFramework { +class PubKeyImpl { +public: + PubKeyImpl(); + explicit PubKeyImpl(HcfPubKey *pubKey, bool owner = true); + ~PubKeyImpl(); + + int64_t GetPubKeyObj(); + OptKeySpec GetAsyKeySpec(ThAsyKeySpecItem itemType); + DataBlob GetEncodedDer(string_view format); + string GetEncodedPem(string_view format); + int64_t GetKeyObj(); + DataBlob GetEncoded(); + string GetFormat(); + string GetAlgName(); + +private: + HcfPubKey *pubKey_ = nullptr; + bool owner_ = false; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_PUB_KEY_H diff --git a/frameworks/js/ani/inc/ani_rand.h b/frameworks/js/ani/inc/ani_rand.h index f027dcd3a1202548568f1e77068803c8cdc5cb04..a4d22e33eb76485a1c047613353a1be253f445ee 100644 --- a/frameworks/js/ani/inc/ani_rand.h +++ b/frameworks/js/ani/inc/ani_rand.h @@ -20,13 +20,10 @@ #include "rand.h" namespace ANI::CryptoFramework { -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; - class RandomImpl { public: RandomImpl(); - explicit RandomImpl(HcfRand *obj); + explicit RandomImpl(HcfRand *rand); ~RandomImpl(); DataBlob GenerateRandomSync(int32_t len); @@ -34,7 +31,7 @@ public: string GetAlgName(); private: - HcfRand *randObj = nullptr; + HcfRand *rand_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_sign.h b/frameworks/js/ani/inc/ani_sign.h new file mode 100644 index 0000000000000000000000000000000000000000..4a8010061d2dbd69880ef8894120e56ef5b984fa --- /dev/null +++ b/frameworks/js/ani/inc/ani_sign.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_SIGN_H +#define ANI_SIGN_H + +#include "ani_common.h" +#include "signature.h" + +namespace ANI::CryptoFramework { +class SignImpl { +public: + SignImpl(); + explicit SignImpl(HcfSign *sign); + ~SignImpl(); + + void InitSync(weak::PriKey priKey); + void UpdateSync(DataBlob const& data); + DataBlob SignSync(OptDataBlob const& data); + void SetSignSpec(ThSignSpecItem itemType, OptIntUint8Arr const& itemValue); + OptStrInt GetSignSpec(ThSignSpecItem itemType); + string GetAlgName(); + +private: + HcfSign *sign_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SIGN_H diff --git a/frameworks/js/ani/inc/ani_signature_utils.h b/frameworks/js/ani/inc/ani_signature_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..5a8d4098f9d067ffe06c6b6e119f6c6b7ddd62a5 --- /dev/null +++ b/frameworks/js/ani/inc/ani_signature_utils.h @@ -0,0 +1,29 @@ +/* + * 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_SIGNATURE_UTILS_H +#define ANI_SIGNATURE_UTILS_H + +#include "ani_common.h" + +namespace ANI::CryptoFramework { +class SignatureUtilsImpl { +public: + SignatureUtilsImpl() = delete; + ~SignatureUtilsImpl() = delete; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SIGNATURE_UTILS_H diff --git a/frameworks/js/ani/inc/ani_sm2_crypto_util.h b/frameworks/js/ani/inc/ani_sm2_crypto_util.h new file mode 100644 index 0000000000000000000000000000000000000000..88a96ccfac362c8c47bdf8317c6f8666f6d029ff --- /dev/null +++ b/frameworks/js/ani/inc/ani_sm2_crypto_util.h @@ -0,0 +1,29 @@ +/* + * 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_SM2_CRYPTO_UTIL_H +#define ANI_SM2_CRYPTO_UTIL_H + +#include "ani_common.h" + +namespace ANI::CryptoFramework { +class SM2CryptoUtilImpl { +public: + SM2CryptoUtilImpl() = delete; + ~SM2CryptoUtilImpl() = delete; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_SM2_CRYPTO_UTIL_H diff --git a/frameworks/js/ani/inc/ani_sym_key.h b/frameworks/js/ani/inc/ani_sym_key.h index af42597e1eaf517827d5e5fa5a43b4171817a0bf..b54667521049ffcb0a5041994bf68d8b09d6c671 100644 --- a/frameworks/js/ani/inc/ani_sym_key.h +++ b/frameworks/js/ani/inc/ani_sym_key.h @@ -20,23 +20,21 @@ #include "sym_key.h" namespace ANI::CryptoFramework { -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; - class SymKeyImpl { public: SymKeyImpl(); - explicit SymKeyImpl(HcfSymKey *obj); + explicit SymKeyImpl(HcfSymKey *symKey); ~SymKeyImpl(); - void ClearMem(); int64_t GetSymKeyObj(); + void ClearMem(); + int64_t GetKeyObj(); DataBlob GetEncoded(); string GetFormat(); string GetAlgName(); private: - HcfSymKey *symKey = nullptr; + HcfSymKey *symKey_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_sym_key_generator.h b/frameworks/js/ani/inc/ani_sym_key_generator.h index 4ad82506d77db225d8c87930f0fdd64c23e6d690..026f6a037a92cd7afcf012f94ca620e1649b6da9 100644 --- a/frameworks/js/ani/inc/ani_sym_key_generator.h +++ b/frameworks/js/ani/inc/ani_sym_key_generator.h @@ -20,13 +20,10 @@ #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); + explicit SymKeyGeneratorImpl(HcfSymKeyGenerator *generator); ~SymKeyGeneratorImpl(); SymKey GenerateSymKeySync(); @@ -34,7 +31,7 @@ public: string GetAlgName(); private: - HcfSymKeyGenerator *generator = nullptr; + HcfSymKeyGenerator *generator_ = nullptr; }; } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/inc/ani_verify.h b/frameworks/js/ani/inc/ani_verify.h new file mode 100644 index 0000000000000000000000000000000000000000..acaa12357922475444dd7452004371b7257fe060 --- /dev/null +++ b/frameworks/js/ani/inc/ani_verify.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_VERIFY_H +#define ANI_VERIFY_H + +#include "ani_common.h" +#include "signature.h" + +namespace ANI::CryptoFramework { +class VerifyImpl { +public: + VerifyImpl(); + explicit VerifyImpl(HcfVerify *verify); + ~VerifyImpl(); + + void InitSync(weak::PubKey pubKey); + void UpdateSync(DataBlob const& input); + bool VerifySync(OptDataBlob const& data, DataBlob const& signature); + OptDataBlob RecoverSync(DataBlob const& signature); + void SetVerifySpec(ThSignSpecItem itemType, OptIntUint8Arr const& itemValue); + OptStrInt GetVerifySpec(ThSignSpecItem itemType); + string GetAlgName(); + +private: + HcfVerify *verify_ = nullptr; +}; +} // namespace ANI::CryptoFramework + +#endif // ANI_VERIFY_H diff --git a/frameworks/js/ani/src/ani_asy_key_generator.cpp b/frameworks/js/ani/src/ani_asy_key_generator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..be9470d4566d24a98073bb6ddd5d1d344e824353 --- /dev/null +++ b/frameworks/js/ani/src/ani_asy_key_generator.cpp @@ -0,0 +1,137 @@ +/* + * 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_asy_key_generator.h" +#include "ani_key_pair.h" + +namespace { +using namespace ANI::CryptoFramework; + +KeyPair ConvertPemKeyInner(HcfAsyKeyGenerator *self, HcfParamsSpec *spec, + OptString const& pubKey, OptString const& priKey) +{ + if (self == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(); + } + const char *pkStr = nullptr; + const char *skStr = nullptr; + if (pubKey.get_tag() == OptString::tag_t::STRING) { + pkStr = pubKey.get_STRING_ref().c_str(); + } + if (priKey.get_tag() == OptString::tag_t::STRING) { + skStr = priKey.get_STRING_ref().c_str(); + } + HcfKeyPair *keyPair = nullptr; + HcfResult res = self->convertPemKey(self, spec, pkStr, skStr, &keyPair); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "convert pem key fail."); + return make_holder(); + } + return make_holder(keyPair); +} +} // namespace + +namespace ANI::CryptoFramework { +AsyKeyGeneratorImpl::AsyKeyGeneratorImpl() {} + +AsyKeyGeneratorImpl::AsyKeyGeneratorImpl(HcfAsyKeyGenerator *generator) : generator_(generator) {} + +AsyKeyGeneratorImpl::~AsyKeyGeneratorImpl() +{ + HcfObjDestroy(this->generator_); + this->generator_ = nullptr; +} + +KeyPair AsyKeyGeneratorImpl::GenerateKeyPairSync() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(); + } + HcfKeyPair *keyPair = nullptr; + HcfResult res = this->generator_->generateKeyPair(this->generator_, nullptr, &(keyPair)); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generate key pair fail."); + return make_holder(); + } + return make_holder(keyPair); +} + +KeyPair AsyKeyGeneratorImpl::ConvertKeySync(OptDataBlob const& pubKey, OptDataBlob const& priKey) +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(); + } + HcfKeyPair *keyPair = nullptr; + HcfBlob *pubKeyBlob = nullptr; + HcfBlob *priKeyBlob = nullptr; + HcfBlob pkBlob = {}; + HcfBlob skBlob = {}; + if (pubKey.get_tag() == OptDataBlob::tag_t::DATABLOB) { + ArrayU8ToDataBlob(pubKey.get_DATABLOB_ref().data, pkBlob); + pubKeyBlob = &pkBlob; + } + if (priKey.get_tag() == OptDataBlob::tag_t::DATABLOB) { + ArrayU8ToDataBlob(priKey.get_DATABLOB_ref().data, skBlob); + priKeyBlob = &skBlob; + } + HcfResult res = this->generator_->convertKey(this->generator_, nullptr, pubKeyBlob, priKeyBlob, &keyPair); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "convert key fail."); + return make_holder(); + } + return make_holder(keyPair); +} + +KeyPair AsyKeyGeneratorImpl::ConvertPemKeySync(OptString const& pubKey, OptString const& priKey) +{ + return ConvertPemKeyInner(this->generator_, nullptr, pubKey, priKey); +} + +KeyPair AsyKeyGeneratorImpl::ConvertPemKeySyncEx(OptString const& pubKey, OptString const& priKey, string_view password) +{ + HcfKeyDecodingParamsSpec spec = {}; + spec.password = const_cast(password.c_str()); + return ConvertPemKeyInner(this->generator_, reinterpret_cast(&spec), pubKey, priKey); +} + +string AsyKeyGeneratorImpl::GetAlgName() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return ""; + } + const char *algName = this->generator_->getAlgoName(this->generator_); + return (algName == nullptr) ? "" : string(algName); +} + +AsyKeyGenerator CreateAsyKeyGenerator(string_view algName) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfResult res = HcfAsyKeyGeneratorCreate(algName.c_str(), &generator); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create generator obj fail!"); + return make_holder(); + } + return make_holder(generator); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateAsyKeyGenerator(ANI::CryptoFramework::CreateAsyKeyGenerator); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_asy_key_generator_by_spec.cpp b/frameworks/js/ani/src/ani_asy_key_generator_by_spec.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e79c6931badf166418891695d2b73839fae22cb0 --- /dev/null +++ b/frameworks/js/ani/src/ani_asy_key_generator_by_spec.cpp @@ -0,0 +1,496 @@ +/* + * 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_asy_key_generator_by_spec.h" +#include "ani_key_pair.h" +#include "ani_pri_key.h" +#include "ani_pub_key.h" +#include "detailed_dsa_key_params.h" +#include "detailed_ecc_key_params.h" +#include "detailed_rsa_key_params.h" +#include "detailed_alg_25519_key_params.h" +#include "detailed_dh_key_params.h" + +namespace { +using namespace ANI::CryptoFramework; + +const std::string DSA_ALG_NAME = "DSA"; +const std::string ECC_ALG_NAME = "ECC"; +const std::string RSA_ALG_NAME = "RSA"; +const std::string DH_ALG_NAME = "DH"; +const std::string ED25519_ALG_NAME = "Ed25519"; +const std::string X25519_ALG_NAME = "X25519"; +const std::string SM2_ALG_NAME = "SM2"; + +void SetDSAKeyPairParamsSpecAttribute(DSAKeyPairSpec const& dsaParams, HcfDsaKeyPairParamsSpec &dsaKeyPairSpec) +{ + dsaKeyPairSpec.base.base.specType = static_cast(dsaParams.base.specType.get_value()); + dsaKeyPairSpec.base.base.algName = const_cast(dsaParams.base.algName.c_str()); + ArrayU8ToBigInteger(dsaParams.params.p, dsaKeyPairSpec.base.p); + ArrayU8ToBigInteger(dsaParams.params.q, dsaKeyPairSpec.base.q); + ArrayU8ToBigInteger(dsaParams.params.g, dsaKeyPairSpec.base.g); + ArrayU8ToBigInteger(dsaParams.pk, dsaKeyPairSpec.pk); + ArrayU8ToBigInteger(dsaParams.sk, dsaKeyPairSpec.sk); +} + +void SetDSAPubKeyParamsSpecAttribute(DSAPubKeySpec const& dsaParams, HcfDsaPubKeyParamsSpec &dsaPubKeySpec) +{ + dsaPubKeySpec.base.base.specType = static_cast(dsaParams.base.specType.get_value()); + dsaPubKeySpec.base.base.algName = const_cast(dsaParams.base.algName.c_str()); + ArrayU8ToBigInteger(dsaParams.params.p, dsaPubKeySpec.base.p); + ArrayU8ToBigInteger(dsaParams.params.q, dsaPubKeySpec.base.q); + ArrayU8ToBigInteger(dsaParams.params.g, dsaPubKeySpec.base.g); + ArrayU8ToBigInteger(dsaParams.pk, dsaPubKeySpec.pk); +} + +void SetDSACommonParamsSpecAttribute(DSACommonParamsSpec const& dsaParams, HcfDsaCommParamsSpec &dsaCommonParamsSpec) +{ + dsaCommonParamsSpec.base.specType = static_cast(dsaParams.base.specType.get_value()); + dsaCommonParamsSpec.base.algName = const_cast(dsaParams.base.algName.c_str()); + ArrayU8ToBigInteger(dsaParams.p, dsaCommonParamsSpec.p); + ArrayU8ToBigInteger(dsaParams.q, dsaCommonParamsSpec.q); + ArrayU8ToBigInteger(dsaParams.g, dsaCommonParamsSpec.g); +} + +void SetECCKeyPairParamsSpecAttribute(ECCKeyPairSpec const& eccParams, HcfEccKeyPairParamsSpec &eccKeyPairSpec) +{ + eccKeyPairSpec.base.base.specType = static_cast(eccParams.base.specType.get_value()); + eccKeyPairSpec.base.base.algName = const_cast(eccParams.base.algName.c_str()); + if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELD) { + eccKeyPairSpec.base.field->fieldType = + const_cast(eccParams.params.field.get_ECFIELD_ref().fieldType.c_str()); + } else if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELDFP) { + HcfECFieldFp* fieldFp = reinterpret_cast(eccKeyPairSpec.base.field); + fieldFp->base.fieldType = + const_cast(eccParams.params.field.get_ECFIELDFP_ref().base.fieldType.c_str()); + ArrayU8ToBigInteger(eccParams.params.field.get_ECFIELDFP_ref().p, fieldFp->p); + } + eccKeyPairSpec.base.h = eccParams.params.h; + ArrayU8ToBigInteger(eccParams.params.a, eccKeyPairSpec.base.a); + ArrayU8ToBigInteger(eccParams.params.b, eccKeyPairSpec.base.b); + ArrayU8ToBigInteger(eccParams.params.g.x, eccKeyPairSpec.base.g.x); + ArrayU8ToBigInteger(eccParams.params.g.y, eccKeyPairSpec.base.g.y); + ArrayU8ToBigInteger(eccParams.params.n, eccKeyPairSpec.base.n); + ArrayU8ToBigInteger(eccParams.pk.x, eccKeyPairSpec.pk.x); + ArrayU8ToBigInteger(eccParams.pk.y, eccKeyPairSpec.pk.y); + ArrayU8ToBigInteger(eccParams.sk, eccKeyPairSpec.sk); +} + +void SetECCPubKeyParamsSpecAttribute(ECCPubKeySpec const& eccParams, HcfEccPubKeyParamsSpec &eccPubKeySpec) +{ + eccPubKeySpec.base.base.specType = static_cast(eccParams.base.specType.get_value()); + eccPubKeySpec.base.base.algName = const_cast(eccParams.base.algName.c_str()); + if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELD) { + eccPubKeySpec.base.field->fieldType = + const_cast(eccParams.params.field.get_ECFIELD_ref().fieldType.c_str()); + } else if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELDFP) { + HcfECFieldFp* fieldFp = reinterpret_cast(eccPubKeySpec.base.field); + fieldFp->base.fieldType = + const_cast(eccParams.params.field.get_ECFIELDFP_ref().base.fieldType.c_str()); + ArrayU8ToBigInteger(eccParams.params.field.get_ECFIELDFP_ref().p, fieldFp->p); + } + eccPubKeySpec.base.h = eccParams.params.h; + ArrayU8ToBigInteger(eccParams.params.a, eccPubKeySpec.base.a); + ArrayU8ToBigInteger(eccParams.params.b, eccPubKeySpec.base.b); + ArrayU8ToBigInteger(eccParams.params.g.x, eccPubKeySpec.base.g.x); + ArrayU8ToBigInteger(eccParams.params.g.y, eccPubKeySpec.base.g.y); + ArrayU8ToBigInteger(eccParams.params.n, eccPubKeySpec.base.n); + ArrayU8ToBigInteger(eccParams.pk.x, eccPubKeySpec.pk.x); + ArrayU8ToBigInteger(eccParams.pk.y, eccPubKeySpec.pk.y); +} + +void SetECCPriKeyParamsSpecAttribute(ECCPriKeySpec const& eccParams, HcfEccPriKeyParamsSpec &eccPriKeySpec) +{ + eccPriKeySpec.base.base.specType = static_cast(eccParams.base.specType.get_value()); + eccPriKeySpec.base.base.algName = const_cast(eccParams.base.algName.c_str()); + if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELD) { + eccPriKeySpec.base.field->fieldType = + const_cast(eccParams.params.field.get_ECFIELD_ref().fieldType.c_str()); + } else if (eccParams.params.field.get_tag() == OptECField::tag_t::ECFIELDFP) { + HcfECFieldFp* fieldFp = reinterpret_cast(eccPriKeySpec.base.field); + fieldFp->base.fieldType = + const_cast(eccParams.params.field.get_ECFIELDFP_ref().base.fieldType.c_str()); + ArrayU8ToBigInteger(eccParams.params.field.get_ECFIELDFP_ref().p, fieldFp->p); + } + eccPriKeySpec.base.h = eccParams.params.h; + ArrayU8ToBigInteger(eccParams.params.a, eccPriKeySpec.base.a); + ArrayU8ToBigInteger(eccParams.params.b, eccPriKeySpec.base.b); + ArrayU8ToBigInteger(eccParams.params.g.x, eccPriKeySpec.base.g.x); + ArrayU8ToBigInteger(eccParams.params.g.y, eccPriKeySpec.base.g.y); + ArrayU8ToBigInteger(eccParams.params.n, eccPriKeySpec.base.n); + ArrayU8ToBigInteger(eccParams.sk, eccPriKeySpec.sk); +} + +void SetECCCommonParamsSpecAttribute(ECCCommonParamsSpec const& eccParams, HcfEccCommParamsSpec &eccCommonParamsSpec) +{ + eccCommonParamsSpec.base.specType = static_cast(eccParams.base.specType.get_value()); + eccCommonParamsSpec.base.algName = const_cast(eccParams.base.algName.c_str()); + if (eccParams.field.get_tag() == OptECField::tag_t::ECFIELD) { + eccCommonParamsSpec.field->fieldType = const_cast(eccParams.field.get_ECFIELD_ref().fieldType.c_str()); + } else if (eccParams.field.get_tag() == OptECField::tag_t::ECFIELDFP) { + HcfECFieldFp* fieldFp = reinterpret_cast(eccCommonParamsSpec.field); + fieldFp->base.fieldType = const_cast(eccParams.field.get_ECFIELDFP_ref().base.fieldType.c_str()); + ArrayU8ToBigInteger(eccParams.field.get_ECFIELDFP_ref().p, fieldFp->p); + } + eccCommonParamsSpec.h = eccParams.h; + ArrayU8ToBigInteger(eccParams.a, eccCommonParamsSpec.a); + ArrayU8ToBigInteger(eccParams.b, eccCommonParamsSpec.b); + ArrayU8ToBigInteger(eccParams.g.x, eccCommonParamsSpec.g.x); + ArrayU8ToBigInteger(eccParams.g.y, eccCommonParamsSpec.g.y); + ArrayU8ToBigInteger(eccParams.n, eccCommonParamsSpec.n); +} + +void SetRSAKeyPairParamsSpecAttribute(RSAKeyPairSpec const& rsaParams, HcfRsaKeyPairParamsSpec &rsaKeyPairSpec) +{ + rsaKeyPairSpec.base.base.specType = static_cast(rsaParams.base.specType.get_value()); + rsaKeyPairSpec.base.base.algName = const_cast(rsaParams.base.algName.c_str()); + ArrayU8ToBigInteger(rsaParams.params.n, rsaKeyPairSpec.base.n); + ArrayU8ToBigInteger(rsaParams.pk, rsaKeyPairSpec.pk); + ArrayU8ToBigInteger(rsaParams.sk, rsaKeyPairSpec.sk); +} + +void SetRSAPubKeyParamsSpecAttribute(RSAPubKeySpec const& rsaParams, HcfRsaPubKeyParamsSpec &rsaPubKeySpec) +{ + rsaPubKeySpec.base.base.specType = static_cast(rsaParams.base.specType.get_value()); + rsaPubKeySpec.base.base.algName = const_cast(rsaParams.base.algName.c_str()); + ArrayU8ToBigInteger(rsaParams.params.n, rsaPubKeySpec.base.n); + ArrayU8ToBigInteger(rsaParams.pk, rsaPubKeySpec.pk); +} + +void SetEd25519KeyPairParamsSpecAttribute(ED25519KeyPairSpec const& ed25519Params, + HcfAlg25519KeyPairParamsSpec &ed25519KeyPairSpec) +{ + ed25519KeyPairSpec.base.specType = static_cast(ed25519Params.base.specType.get_value()); + ed25519KeyPairSpec.base.algName = const_cast(ed25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(ed25519Params.pk, ed25519KeyPairSpec.pk); + ArrayU8ToBigInteger(ed25519Params.sk, ed25519KeyPairSpec.sk); +} + +void SetEd25519PubKeyParamsSpecAttribute(ED25519PubKeySpec const& ed25519Params, + HcfAlg25519PubKeyParamsSpec &ed25519PubKeySpec) +{ + ed25519PubKeySpec.base.specType = static_cast(ed25519Params.base.specType.get_value()); + ed25519PubKeySpec.base.algName = const_cast(ed25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(ed25519Params.pk, ed25519PubKeySpec.pk); +} + +void SetEd25519PriKeyParamsSpecAttribute(ED25519PriKeySpec const& ed25519Params, + HcfAlg25519PriKeyParamsSpec &ed25519PriKeySpec) +{ + ed25519PriKeySpec.base.specType = static_cast(ed25519Params.base.specType.get_value()); + ed25519PriKeySpec.base.algName = const_cast(ed25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(ed25519Params.sk, ed25519PriKeySpec.sk); +} + +void SetX25519KeyPairParamsSpecAttribute(X25519KeyPairSpec const& x25519Params, + HcfAlg25519KeyPairParamsSpec &x25519KeyPairSpec) +{ + x25519KeyPairSpec.base.specType = static_cast(x25519Params.base.specType.get_value()); + x25519KeyPairSpec.base.algName = const_cast(x25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(x25519Params.pk, x25519KeyPairSpec.pk); + ArrayU8ToBigInteger(x25519Params.sk, x25519KeyPairSpec.sk); +} + +void SetX25519PubKeyParamsSpecAttribute(X25519PubKeySpec const& x25519Params, + HcfAlg25519PubKeyParamsSpec &x25519PubKeySpec) +{ + x25519PubKeySpec.base.specType = static_cast(x25519Params.base.specType.get_value()); + x25519PubKeySpec.base.algName = const_cast(x25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(x25519Params.pk, x25519PubKeySpec.pk); +} + +void SetX25519PriKeyParamsSpecAttribute(X25519PriKeySpec const& x25519Params, + HcfAlg25519PriKeyParamsSpec &x25519PriKeySpec) +{ + x25519PriKeySpec.base.specType = static_cast(x25519Params.base.specType.get_value()); + x25519PriKeySpec.base.algName = const_cast(x25519Params.base.algName.c_str()); + ArrayU8ToBigInteger(x25519Params.sk, x25519PriKeySpec.sk); +} + +void SetDhKeyPairParamsSpecAttribute(DHKeyPairSpec const& dhParams, HcfDhKeyPairParamsSpec &dhKeyPairSpec) +{ + dhKeyPairSpec.base.base.specType = static_cast(dhParams.base.specType.get_value()); + dhKeyPairSpec.base.base.algName = const_cast(dhParams.base.algName.c_str()); + dhKeyPairSpec.base.length = dhParams.params.l; + ArrayU8ToBigInteger(dhParams.params.p, dhKeyPairSpec.base.p); + ArrayU8ToBigInteger(dhParams.params.g, dhKeyPairSpec.base.g); + ArrayU8ToBigInteger(dhParams.pk, dhKeyPairSpec.pk); + ArrayU8ToBigInteger(dhParams.sk, dhKeyPairSpec.sk); +} + +void SetDhPubKeyParamsSpecAttribute(DHPubKeySpec const& dhParams, HcfDhPubKeyParamsSpec &dhPubKeySpec) +{ + dhPubKeySpec.base.base.specType = static_cast(dhParams.base.specType.get_value()); + dhPubKeySpec.base.base.algName = const_cast(dhParams.base.algName.c_str()); + dhPubKeySpec.base.length = dhParams.params.l; + ArrayU8ToBigInteger(dhParams.params.p, dhPubKeySpec.base.p); + ArrayU8ToBigInteger(dhParams.params.g, dhPubKeySpec.base.g); + ArrayU8ToBigInteger(dhParams.pk, dhPubKeySpec.pk); +} + +void SetDhPriKeyParamsSpecAttribute(DHPriKeySpec const& dhParams, HcfDhPriKeyParamsSpec &dhPriKeySpec) +{ + dhPriKeySpec.base.base.specType = static_cast(dhParams.base.specType.get_value()); + dhPriKeySpec.base.base.algName = const_cast(dhParams.base.algName.c_str()); + dhPriKeySpec.base.length = dhParams.params.l; + ArrayU8ToBigInteger(dhParams.params.p, dhPriKeySpec.base.p); + ArrayU8ToBigInteger(dhParams.params.g, dhPriKeySpec.base.g); + ArrayU8ToBigInteger(dhParams.sk, dhPriKeySpec.sk); +} + +void SetDhCommonParamsSpecAttribute(DHCommonParamsSpec const& dhParams, HcfDhCommParamsSpec &dhCommonParamsSpec) +{ + dhCommonParamsSpec.base.specType = static_cast(dhParams.base.specType.get_value()); + dhCommonParamsSpec.base.algName = const_cast(dhParams.base.algName.c_str()); + dhCommonParamsSpec.length = dhParams.l; + ArrayU8ToBigInteger(dhParams.p, dhCommonParamsSpec.p); + ArrayU8ToBigInteger(dhParams.g, dhCommonParamsSpec.g); +} + +HcfAsyKeyParamsSpec* CreateDSASpec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfDsaKeyPairParamsSpec dsaKeyPairSpec = {}; + static HcfDsaPubKeyParamsSpec dsaPubKeySpec = {}; + static HcfDsaCommParamsSpec dsaCommonParamsSpec = {}; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DSAKEYPAIRSPEC) { + SetDSAKeyPairParamsSpecAttribute(asyKeySpec.get_DSAKEYPAIRSPEC_ref(), dsaKeyPairSpec); + return reinterpret_cast(&dsaKeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DSAPUBKEYSPEC) { + SetDSAPubKeyParamsSpecAttribute(asyKeySpec.get_DSAPUBKEYSPEC_ref(), dsaPubKeySpec); + return reinterpret_cast(&dsaPubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DSACOMMONPARAMSSPEC) { + SetDSACommonParamsSpecAttribute(asyKeySpec.get_DSACOMMONPARAMSSPEC_ref(), dsaCommonParamsSpec); + return reinterpret_cast(&dsaCommonParamsSpec); + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateECCSpec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfEccKeyPairParamsSpec eccKeyPairSpec = {}; + static HcfEccPubKeyParamsSpec eccPubKeySpec = {}; + static HcfEccPriKeyParamsSpec eccPriKeySpec = {}; + static HcfEccCommParamsSpec eccCommonParamsSpec = {}; + static HcfECFieldFp ecFieldFp = {}; + static HcfECField* ecField = &ecFieldFp.base; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ECCKEYPAIRSPEC) { + eccKeyPairSpec.base.field = ecField; + SetECCKeyPairParamsSpecAttribute(asyKeySpec.get_ECCKEYPAIRSPEC_ref(), eccKeyPairSpec); + return reinterpret_cast(&eccKeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ECCPUBKEYSPEC) { + eccPubKeySpec.base.field = ecField; + SetECCPubKeyParamsSpecAttribute(asyKeySpec.get_ECCPUBKEYSPEC_ref(), eccPubKeySpec); + return reinterpret_cast(&eccPubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ECCPRIKEYSPEC) { + eccPriKeySpec.base.field = ecField; + SetECCPriKeyParamsSpecAttribute(asyKeySpec.get_ECCPRIKEYSPEC_ref(), eccPriKeySpec); + return reinterpret_cast(&eccPriKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ECCCOMMONPARAMSSPEC) { + eccCommonParamsSpec.field = ecField; + SetECCCommonParamsSpecAttribute(asyKeySpec.get_ECCCOMMONPARAMSSPEC_ref(), eccCommonParamsSpec); + return reinterpret_cast(&eccCommonParamsSpec); + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateRSASpec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfRsaKeyPairParamsSpec rsaKeyPairSpec = {}; + static HcfRsaPubKeyParamsSpec rsaPubKeySpec = {}; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::RSAKEYPAIRSPEC) { + SetRSAKeyPairParamsSpecAttribute(asyKeySpec.get_RSAKEYPAIRSPEC_ref(), rsaKeyPairSpec); + return reinterpret_cast(&rsaKeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::RSAPUBKEYSPEC) { + SetRSAPubKeyParamsSpecAttribute(asyKeySpec.get_RSAPUBKEYSPEC_ref(), rsaPubKeySpec); + return reinterpret_cast(&rsaPubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::RSACOMMONPARAMSSPEC) { + LOGE("RSA not support comm key spec"); + return nullptr; + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateEd25519Spec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfAlg25519KeyPairParamsSpec ed25519KeyPairSpec = {}; + static HcfAlg25519PubKeyParamsSpec ed25519PubKeySpec = {}; + static HcfAlg25519PriKeyParamsSpec ed25519PriKeySpec = {}; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ED25519KEYPAIRSPEC) { + SetEd25519KeyPairParamsSpecAttribute(asyKeySpec.get_ED25519KEYPAIRSPEC_ref(), ed25519KeyPairSpec); + return reinterpret_cast(&ed25519KeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ED25519PUBKEYSPEC) { + SetEd25519PubKeyParamsSpecAttribute(asyKeySpec.get_ED25519PUBKEYSPEC_ref(), ed25519PubKeySpec); + return reinterpret_cast(&ed25519PubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::ED25519PRIKEYSPEC) { + SetEd25519PriKeyParamsSpecAttribute(asyKeySpec.get_ED25519PRIKEYSPEC_ref(), ed25519PriKeySpec); + return reinterpret_cast(&ed25519PriKeySpec); + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateX25519Spec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfAlg25519KeyPairParamsSpec x25519KeyPairSpec = {}; + static HcfAlg25519PubKeyParamsSpec x25519PubKeySpec = {}; + static HcfAlg25519PriKeyParamsSpec x25519PriKeySpec = {}; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::X25519KEYPAIRSPEC) { + SetX25519KeyPairParamsSpecAttribute(asyKeySpec.get_X25519KEYPAIRSPEC_ref(), x25519KeyPairSpec); + return reinterpret_cast(&x25519KeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::X25519PUBKEYSPEC) { + SetX25519PubKeyParamsSpecAttribute(asyKeySpec.get_X25519PUBKEYSPEC_ref(), x25519PubKeySpec); + return reinterpret_cast(&x25519PubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::X25519PRIKEYSPEC) { + SetX25519PriKeyParamsSpecAttribute(asyKeySpec.get_X25519PRIKEYSPEC_ref(), x25519PriKeySpec); + return reinterpret_cast(&x25519PriKeySpec); + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateDHSpec(OptAsyKeySpec const& asyKeySpec) +{ + static HcfDhKeyPairParamsSpec dhKeyPairSpec = {}; + static HcfDhPubKeyParamsSpec dhPubKeySpec = {}; + static HcfDhPriKeyParamsSpec dhPriKeySpec = {}; + static HcfDhCommParamsSpec dhCommonParamsSpec = {}; + + if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DHKEYPAIRSPEC) { + SetDhKeyPairParamsSpecAttribute(asyKeySpec.get_DHKEYPAIRSPEC_ref(), dhKeyPairSpec); + return reinterpret_cast(&dhKeyPairSpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DHPUBKEYSPEC) { + SetDhPubKeyParamsSpecAttribute(asyKeySpec.get_DHPUBKEYSPEC_ref(), dhPubKeySpec); + return reinterpret_cast(&dhPubKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DHPRIKEYSPEC) { + SetDhPriKeyParamsSpecAttribute(asyKeySpec.get_DHPRIKEYSPEC_ref(), dhPriKeySpec); + return reinterpret_cast(&dhPriKeySpec); + } else if (asyKeySpec.get_tag() == OptAsyKeySpec::tag_t::DHCOMMONPARAMSSPEC) { + SetDhCommonParamsSpecAttribute(asyKeySpec.get_DHCOMMONPARAMSSPEC_ref(), dhCommonParamsSpec); + return reinterpret_cast(&dhCommonParamsSpec); + } + return nullptr; +} + +HcfAsyKeyParamsSpec* CreateParamsSpec(OptAsyKeySpec const& asyKeySpec) +{ + const std::string &algName = asyKeySpec.get_ASYKEYSPEC_ref().algName.c_str(); + if (algName == DSA_ALG_NAME) { + return CreateDSASpec(asyKeySpec); + } else if (algName == ECC_ALG_NAME || algName == SM2_ALG_NAME) { + return CreateECCSpec(asyKeySpec); + } else if (algName == RSA_ALG_NAME) { + return CreateRSASpec(asyKeySpec); + } else if (algName == ED25519_ALG_NAME) { + return CreateEd25519Spec(asyKeySpec); + } else if (algName == X25519_ALG_NAME) { + return CreateX25519Spec(asyKeySpec); + } else if (algName == DH_ALG_NAME) { + return CreateDHSpec(asyKeySpec); + } + return nullptr; +} +} // namespace + +namespace ANI::CryptoFramework { +AsyKeyGeneratorBySpecImpl::AsyKeyGeneratorBySpecImpl() {} + +AsyKeyGeneratorBySpecImpl::AsyKeyGeneratorBySpecImpl(HcfAsyKeyGeneratorBySpec *generator) : generator_(generator) {} + +AsyKeyGeneratorBySpecImpl::~AsyKeyGeneratorBySpecImpl() +{ + HcfObjDestroy(this->generator_); + this->generator_ = nullptr; +} + +KeyPair AsyKeyGeneratorBySpecImpl::GenerateKeyPairSync() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator spec obj is nullptr!"); + return make_holder(); + } + HcfKeyPair *keyPair = nullptr; + HcfResult res = this->generator_->generateKeyPair(this->generator_, &keyPair); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generateKeyPair failed"); + return make_holder(); + } + return make_holder(keyPair); +} + +PriKey AsyKeyGeneratorBySpecImpl::GeneratePriKeySync() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator spec obj is nullptr!"); + return make_holder(); + } + HcfPriKey *priKey = nullptr; + HcfResult res = this->generator_->generatePriKey(this->generator_, &priKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generatePriKey failed"); + return make_holder(); + } + return make_holder(priKey); +} + +PubKey AsyKeyGeneratorBySpecImpl::GeneratePubKeySync() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator spec obj is nullptr!"); + return make_holder(); + } + HcfPubKey *pubKey = nullptr; + HcfResult res = this->generator_->generatePubKey(this->generator_, &pubKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generatePubKey failed"); + return make_holder(); + } + return make_holder(pubKey); +} + +string AsyKeyGeneratorBySpecImpl::GetAlgName() +{ + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator spec obj is nullptr!"); + return ""; + } + const char *algName = this->generator_->getAlgName(this->generator_); + return (algName == nullptr) ? "" : string(algName); +} + +AsyKeyGeneratorBySpec CreateAsyKeyGeneratorBySpec(OptAsyKeySpec const& asyKeySpec) +{ + HcfAsyKeyParamsSpec *spec = CreateParamsSpec(asyKeySpec); + if (spec == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "invalid asy key spec!"); + return make_holder(); + } + + HcfAsyKeyGeneratorBySpec *generator = nullptr; + HcfResult res = HcfAsyKeyGeneratorBySpecCreate(spec, &generator); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create generator spec obj fail!"); + return make_holder(); + } + return make_holder(generator); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateAsyKeyGeneratorBySpec(ANI::CryptoFramework::CreateAsyKeyGeneratorBySpec); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_cipher.cpp b/frameworks/js/ani/src/ani_cipher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e4495dee76eab446b038ea13f06217b8e101bc7f --- /dev/null +++ b/frameworks/js/ani/src/ani_cipher.cpp @@ -0,0 +1,259 @@ +/* + * 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_cipher.h" +#include "detailed_iv_params.h" +#include "detailed_gcm_params.h" +#include "detailed_ccm_params.h" + +namespace { +using namespace ANI::CryptoFramework; + +const std::string IV_PARAMS_SPEC = "IvParamsSpec"; +const std::string GCM_PARAMS_SPEC = "GcmParamsSpec"; +const std::string CCM_PARAMS_SPEC = "CcmParamsSpec"; + +static const std::unordered_map CIPHER_SPEC_RELATION_MAP = { + { OAEP_MD_NAME_STR, SPEC_ITEM_TYPE_STR }, + { OAEP_MGF_NAME_STR, SPEC_ITEM_TYPE_STR }, + { OAEP_MGF1_MD_STR, SPEC_ITEM_TYPE_STR }, + { OAEP_MGF1_PSRC_UINT8ARR, SPEC_ITEM_TYPE_UINT8ARR }, + { SM2_MD_NAME_STR, SPEC_ITEM_TYPE_STR }, +}; + +const char *GetIvParamsSpecType() +{ + return IV_PARAMS_SPEC.c_str(); +} + +const char *GetGcmParamsSpecType() +{ + return GCM_PARAMS_SPEC.c_str(); +} + +const char *GetCcmParamsSpecType() +{ + return CCM_PARAMS_SPEC.c_str(); +} + +void SetIvParamsSpecAttribute(const IvParamsSpec ¶ms, HcfIvParamsSpec &ivParamsSpec) +{ + ivParamsSpec.base.getType = GetIvParamsSpecType; + ArrayU8ToDataBlob(params.iv.data, ivParamsSpec.iv); +} + +void SetGcmParamsSpecAttribute(const GcmParamsSpec ¶ms, HcfGcmParamsSpec &gcmParamsSpec) +{ + gcmParamsSpec.base.getType = GetGcmParamsSpecType; + ArrayU8ToDataBlob(params.iv.data, gcmParamsSpec.iv); + ArrayU8ToDataBlob(params.aad.data, gcmParamsSpec.aad); + ArrayU8ToDataBlob(params.authTag.data, gcmParamsSpec.tag); +} + +void SetCcmParamsSpecAttribute(const CcmParamsSpec ¶ms, HcfCcmParamsSpec &ccmParamsSpec) +{ + ccmParamsSpec.base.getType = GetCcmParamsSpecType; + ArrayU8ToDataBlob(params.iv.data, ccmParamsSpec.iv); + ArrayU8ToDataBlob(params.aad.data, ccmParamsSpec.aad); + ArrayU8ToDataBlob(params.authTag.data, ccmParamsSpec.tag); +} + +int32_t GetCipherSpecType(HcfCipherSpecItem item) +{ + if (CIPHER_SPEC_RELATION_MAP.count(item) > 0) { + return CIPHER_SPEC_RELATION_MAP.at(item); + } + return -1; +} + +OptStrUint8Arr GetCipherSpecString(HcfCipher *cipher, HcfCipherSpecItem item) +{ + char *str = nullptr; + HcfResult res = cipher->getCipherSpecString(cipher, item, &str); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get cipher spec string fail."); + return OptStrUint8Arr::make_STRING(""); + } + string data = string(str); + HcfFree(str); + return OptStrUint8Arr::make_STRING(data); +} + +OptStrUint8Arr GetCipherSpecUint8Array(HcfCipher *cipher, HcfCipherSpecItem item) +{ + HcfBlob outBlob = {}; + HcfResult res = cipher->getCipherSpecUint8Array(cipher, item, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get cipher spec uint8 array fail."); + return OptStrUint8Arr::make_UINT8ARRAY(array{}); + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return OptStrUint8Arr::make_UINT8ARRAY(data); +} +} // namespace + +namespace ANI::CryptoFramework { +CipherImpl::CipherImpl() {} + +CipherImpl::CipherImpl(HcfCipher *cipher) : cipher_(cipher) {} + +CipherImpl::~CipherImpl() +{ + HcfObjDestroy(this->cipher_); + this->cipher_ = nullptr; +} + +void CipherImpl::InitSync(CryptoMode opMode, weak::Key key, OptParamsSpec const& params) +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return; + } + HcfParamsSpec *paramsSpec = nullptr; + HcfIvParamsSpec ivParamsSpec = {}; + HcfGcmParamsSpec gcmParamsSpec = {}; + HcfCcmParamsSpec ccmParamsSpec = {}; + if (params.get_tag() != OptParamsSpec::tag_t::EMPTY) { + const OptExtParamsSpec &tmp = params.get_PARAMSSPEC_ref(); + const std::string &algName = tmp.get_PARAMSSPEC_ref().algName.c_str(); + if (tmp.get_tag() == OptExtParamsSpec::tag_t::IVPARAMSSPEC && algName == IV_PARAMS_SPEC) { + SetIvParamsSpecAttribute(tmp.get_IVPARAMSSPEC_ref(), ivParamsSpec); + paramsSpec = reinterpret_cast(&ivParamsSpec); + } else if (tmp.get_tag() == OptExtParamsSpec::tag_t::GCMPARAMSSPEC && algName == GCM_PARAMS_SPEC) { + SetGcmParamsSpecAttribute(tmp.get_GCMPARAMSSPEC_ref(), gcmParamsSpec); + paramsSpec = reinterpret_cast(&gcmParamsSpec); + } else if (tmp.get_tag() == OptExtParamsSpec::tag_t::CCMPARAMSSPEC && algName == CCM_PARAMS_SPEC) { + SetCcmParamsSpecAttribute(tmp.get_CCMPARAMSSPEC_ref(), ccmParamsSpec); + paramsSpec = reinterpret_cast(&ccmParamsSpec); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "invalid cipher spec!"); + return; + } + } + HcfKey *hcfKey = reinterpret_cast(key->GetKeyObj()); + HcfResult res = this->cipher_->init(this->cipher_, static_cast(opMode.get_value()), + hcfKey, paramsSpec); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "init cipher fail."); + return; + } +} + +DataBlob CipherImpl::UpdateSync(DataBlob const& input) +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return {}; + } + HcfBlob inBlob = {}; + HcfBlob outBlob = {}; + ArrayU8ToDataBlob(input.data, inBlob); + HcfResult res = this->cipher_->update(this->cipher_, &inBlob, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "cipher update failed!"); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +DataBlob CipherImpl::DoFinalSync(OptDataBlob const& input) +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return {}; + } + HcfBlob *inBlob = nullptr; + HcfBlob dataBlob = {}; + if (input.get_tag() == OptDataBlob::tag_t::DATABLOB) { + ArrayU8ToDataBlob(input.get_DATABLOB_ref().data, dataBlob); + inBlob = &dataBlob; + } + HcfBlob outBlob = {}; + HcfResult res = this->cipher_->doFinal(this->cipher_, inBlob, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "cipher doFinal failed!"); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +void CipherImpl::SetCipherSpec(ThCipherSpecItem itemType, array_view itemValue) +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return; + } + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(itemValue, inBlob); + HcfCipherSpecItem item = static_cast(itemType.get_value()); + HcfResult res = this->cipher_->setCipherSpecUint8Array(this->cipher_, item, inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set cipher spec uint8 array failed."); + return; + } +} + +OptStrUint8Arr CipherImpl::GetCipherSpec(ThCipherSpecItem itemType) +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return OptStrUint8Arr::make_STRING(""); + } + HcfCipherSpecItem item = static_cast(itemType.get_value()); + int32_t type = GetCipherSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetCipherSpecString(this->cipher_, item); + } else if (type == SPEC_ITEM_TYPE_UINT8ARR) { + return GetCipherSpecUint8Array(this->cipher_, item); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher spec item not support!"); + return OptStrUint8Arr::make_STRING(""); + } +} + +string CipherImpl::GetAlgName() +{ + if (this->cipher_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "cipher obj is nullptr!"); + return ""; + } + const char *algName = this->cipher_->getAlgorithm(this->cipher_); + return (algName == nullptr) ? "" : string(algName); +} + +Cipher CreateCipher(string_view transformation) +{ + HcfCipher *cipher = nullptr; + HcfResult res = HcfCipherCreate(transformation.c_str(), &cipher); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create cipher obj fail!"); + return make_holder(); + } + return make_holder(cipher); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateCipher(ANI::CryptoFramework::CreateCipher); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_common.cpp b/frameworks/js/ani/src/ani_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d6a8d9f08141b1556e27ddc60e8c1c5a770175c --- /dev/null +++ b/frameworks/js/ani/src/ani_common.cpp @@ -0,0 +1,142 @@ +/* + * 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_common.h" +#include + +namespace { +using namespace ANI::CryptoFramework; + +enum ResultCode { + SUCCESS = 0, + INVALID_PARAMS = 401, + NOT_SUPPORT = 801, + ERR_OUT_OF_MEMORY = 17620001, + ERR_RUNTIME_ERROR = 17620002, + ERR_PARAMETER_CHECK_FAILED = 17620003, + ERR_CRYPTO_OPERATION = 17630001, +}; + +static const std::unordered_map RESULT_CODE = { + { HCF_SUCCESS, SUCCESS }, + { HCF_INVALID_PARAMS, INVALID_PARAMS }, + { HCF_NOT_SUPPORT, NOT_SUPPORT }, + { HCF_ERR_MALLOC, ERR_OUT_OF_MEMORY }, + { HCF_ERR_PARAMETER_CHECK_FAILED, ERR_PARAMETER_CHECK_FAILED }, + { HCF_ERR_CRYPTO_OPERATION, ERR_CRYPTO_OPERATION }, +}; + +static const std::unordered_map ASY_KEY_SPEC_RELATION_MAP = { + { DSA_P_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DSA_Q_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DSA_G_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_FP_P_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_A_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_B_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_G_X_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_G_Y_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_N_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_H_INT, SPEC_ITEM_TYPE_NUM }, // warning: ECC_H_NUM in JS + { ECC_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_PK_X_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_PK_Y_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ECC_FIELD_TYPE_STR, SPEC_ITEM_TYPE_STR }, + { ECC_FIELD_SIZE_INT, SPEC_ITEM_TYPE_NUM }, // warning: ECC_FIELD_SIZE_NUM in JS + { ECC_CURVE_NAME_STR, SPEC_ITEM_TYPE_STR }, + { RSA_N_BN, SPEC_ITEM_TYPE_BIG_INT }, + { RSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { RSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DH_P_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DH_G_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DH_L_NUM, SPEC_ITEM_TYPE_NUM }, + { DH_PK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { DH_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ED25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { ED25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { X25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT }, + { X25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT }, +}; + +static const std::unordered_map SIGN_SPEC_RELATION_MAP = { + { PSS_MD_NAME_STR, SPEC_ITEM_TYPE_STR }, + { PSS_MGF_NAME_STR, SPEC_ITEM_TYPE_STR }, + { PSS_MGF1_MD_STR, SPEC_ITEM_TYPE_STR }, + { PSS_SALT_LEN_INT, SPEC_ITEM_TYPE_NUM }, // warning: PSS_SALT_LEN_NUM in JS + { PSS_TRAILER_FIELD_INT, SPEC_ITEM_TYPE_NUM }, // warning: PSS_TRAILER_FIELD_NUM in JS + { SM2_USER_ID_UINT8ARR, SPEC_ITEM_TYPE_UINT8ARR }, +}; +} // namespace + +namespace ANI::CryptoFramework { +int ConvertResultCode(HcfResult res) +{ + if (RESULT_CODE.count(res) > 0) { + return RESULT_CODE.at(res); + } + return ERR_RUNTIME_ERROR; +} + +void ArrayU8ToDataBlob(const array &arr, HcfBlob &blob) +{ + blob.data = arr.empty() ? nullptr : arr.data(); + blob.len = arr.size(); +} + +void DataBlobToArrayU8(const HcfBlob &blob, array &arr) +{ + arr = array(move_data_t{}, blob.data, blob.len); +} + +void ArrayU8ToBigInteger(const array &arr, HcfBigInteger &bigint) +{ + bigint.data = arr.empty() ? nullptr : arr.data(); + bigint.len = arr.size(); + if (bigint.len > 0 && bigint.data[bigint.len - 1] == 0) { // remove the sign bit of big integer + bigint.len--; + } +} + +void BigIntegerToArrayU8(const HcfBigInteger &bigint, array &arr) +{ + arr = array(bigint.len + 1); + std::copy(bigint.data, bigint.data + bigint.len, arr.data()); + // 0x00 is the sign bit of big integer, it's always a positive number in this implementation + arr[bigint.len] = 0x00; +} + +void StringToDataBlob(const string &str, HcfBlob &blob) +{ + blob.data = str.empty() ? nullptr : reinterpret_cast(const_cast(str.c_str())); + blob.len = str.size() + 1; +} + +int GetAsyKeySpecType(HcfAsyKeySpecItem item) +{ + if (ASY_KEY_SPEC_RELATION_MAP.count(item) > 0) { + return ASY_KEY_SPEC_RELATION_MAP.at(item); + } + return -1; +} + +int GetSignSpecType(HcfSignSpecItem item) +{ + if (SIGN_SPEC_RELATION_MAP.count(item) > 0) { + return SIGN_SPEC_RELATION_MAP.at(item); + } + return -1; +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_constructor.cpp b/frameworks/js/ani/src/ani_constructor.cpp index 9d38ae4c497803e0ad462e2bec33e2b7d09ebf37..ce1f62a85ef16dd18c38dc0035f020800b52c162 100644 --- a/frameworks/js/ani/src/ani_constructor.cpp +++ b/frameworks/js/ani/src/ani_constructor.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "taihe/runtime.hpp" #include "ohos.security.cryptoFramework.cryptoFramework.ani.hpp" ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) @@ -22,7 +23,7 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return ANI_ERROR; } if (ANI_OK != ohos::security::cryptoFramework::cryptoFramework::ANIRegister(env)) { - std::cerr << "ohos::security::cryptoFramework::cryptoFramework" << std::endl; + std::cerr << "Error from ohos::security::cryptoFramework::cryptoFramework::ANIRegister" << std::endl; return ANI_ERROR; } *result = ANI_VERSION_1; diff --git a/frameworks/js/ani/src/ani_dh_key_util.cpp b/frameworks/js/ani/src/ani_dh_key_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c7294ee05d880dd4cc0acd290f241cc7bb6dde7 --- /dev/null +++ b/frameworks/js/ani/src/ani_dh_key_util.cpp @@ -0,0 +1,48 @@ +/* + * 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_dh_key_util.h" +#include "dh_key_util.h" +#include "detailed_dh_key_params.h" + +namespace ANI::CryptoFramework { +DHCommonParamsSpec GenDHCommonParamsSpec(int32_t pLen, optional_view skLen) +{ + DHCommonParamsSpec dh = { + .base = { + .specType = AsyKeySpecType::key_t::COMMON_PARAMS_SPEC + } + }; + int32_t skLenValue = skLen.has_value() ? skLen.value() : 0; + HcfDhCommParamsSpec *dhCommParamsSpec = nullptr; + HcfResult res = HcfDhKeyUtilCreate(pLen, skLenValue, &dhCommParamsSpec); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create dhKey obj fail!"); + return dh; + } + dh.base.algName = string(dhCommParamsSpec->base.algName); + dh.base.specType = AsyKeySpecType(static_cast(dhCommParamsSpec->base.specType)); + dh.l = dhCommParamsSpec->length; + BigIntegerToArrayU8(dhCommParamsSpec->p, dh.p); + BigIntegerToArrayU8(dhCommParamsSpec->g, dh.g); + HcfObjDestroy(dhCommParamsSpec); + return dh; +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_GenDHCommonParamsSpec(ANI::CryptoFramework::GenDHCommonParamsSpec); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_ecc_key_util.cpp b/frameworks/js/ani/src/ani_ecc_key_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4de03d1936c5c28564439d1b32be1ff4e6bcfd02 --- /dev/null +++ b/frameworks/js/ani/src/ani_ecc_key_util.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_ecc_key_util.h" +#include "detailed_ecc_key_params.h" +#include "ecc_key_util.h" + +namespace ANI::CryptoFramework { +ECCCommonParamsSpec GenECCCommonParamsSpec(string_view curveName) +{ + ECFieldFp ecFieldFp = {}; + ECCCommonParamsSpec ecc = { + .base = { + .specType = AsyKeySpecType::key_t::COMMON_PARAMS_SPEC, + }, + .field = OptECField::make_ECFIELDFP(ecFieldFp) + }; + HcfEccCommParamsSpec *eccCommParamsSpec = nullptr; + HcfResult res = HcfEccKeyUtilCreate(curveName.c_str(), &eccCommParamsSpec); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create eccKey obj fail!"); + return ecc; + } + HcfECFieldFp *tmp = reinterpret_cast(eccCommParamsSpec->field); + ecFieldFp.base.fieldType = string(tmp->base.fieldType); + BigIntegerToArrayU8(tmp->p, ecFieldFp.p); + ecc.field = OptECField::make_ECFIELDFP(ecFieldFp); + ecc.base.algName = string(eccCommParamsSpec->base.algName); + ecc.base.specType = AsyKeySpecType(static_cast(eccCommParamsSpec->base.specType)); + ecc.h = eccCommParamsSpec->h; + BigIntegerToArrayU8(eccCommParamsSpec->a, ecc.a); + BigIntegerToArrayU8(eccCommParamsSpec->b, ecc.b); + BigIntegerToArrayU8(eccCommParamsSpec->g.x, ecc.g.x); + BigIntegerToArrayU8(eccCommParamsSpec->g.y, ecc.g.y); + BigIntegerToArrayU8(eccCommParamsSpec->n, ecc.n); + HcfObjDestroy(eccCommParamsSpec); + return ecc; +} + +Point ConvertPoint(string_view curveName, array_view encodedPoint) +{ + HcfPoint hcfPoint = {}; + HcfBlob pointBlob = {}; + ArrayU8ToDataBlob(encodedPoint, pointBlob); + HcfResult res = HcfConvertPoint(curveName.c_str(), &pointBlob, &hcfPoint); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "failed to convert point."); + return {}; + } + Point point = {}; + BigIntegerToArrayU8(hcfPoint.x, point.x); + BigIntegerToArrayU8(hcfPoint.y, point.y); + FreeEcPointMem(&hcfPoint); + return point; +} + +array GetEncodedPoint(string_view curveName, Point const& point, string_view format) +{ + HcfPoint hcfPoint = {}; + ArrayU8ToBigInteger(point.x, hcfPoint.x); + ArrayU8ToBigInteger(point.y, hcfPoint.y); + HcfBlob outBlob = {}; + HcfResult res = HcfGetEncodedPoint(curveName.c_str(), &hcfPoint, format.c_str(), &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "fail to get point data."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return data; +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_GenECCCommonParamsSpec(ANI::CryptoFramework::GenECCCommonParamsSpec); +TH_EXPORT_CPP_API_ConvertPoint(ANI::CryptoFramework::ConvertPoint); +TH_EXPORT_CPP_API_GetEncodedPoint(ANI::CryptoFramework::GetEncodedPoint); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_kdf.cpp b/frameworks/js/ani/src/ani_kdf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0611c9e7aa0160107f090d09d21471f7b46b7f6 --- /dev/null +++ b/frameworks/js/ani/src/ani_kdf.cpp @@ -0,0 +1,152 @@ +/* + * 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_kdf.h" +#include "detailed_pbkdf2_params.h" +#include "detailed_hkdf_params.h" +#include "detailed_scrypt_params.h" + +namespace { +using namespace ANI::CryptoFramework; + +const std::string PBKDF2_ALG_NAME = "PBKDF2"; +const std::string HKDF_ALG_NAME = "HKDF"; +const std::string SCRYPT_ALG_NAME = "SCRYPT"; + +void SetPBKDF2ParamsSpecAttribute(const PBKDF2Spec ¶ms, HcfPBKDF2ParamsSpec &pbkdf2Spec, HcfBlob &outBlob) +{ + pbkdf2Spec.base.algName = params.base.algName.c_str(); + if (params.password.get_tag() == OptStrUint8Arr::tag_t::STRING) { + StringToDataBlob(params.password.get_STRING_ref(), pbkdf2Spec.password); + } else { // OptStrUint8Arr::tag_t::UINT8ARRAY + ArrayU8ToDataBlob(params.password.get_UINT8ARRAY_ref(), pbkdf2Spec.password); + } + ArrayU8ToDataBlob(params.salt, pbkdf2Spec.salt); + pbkdf2Spec.iterations = params.iterations; + size_t keySize = params.keySize; + outBlob.data = static_cast(HcfMalloc(keySize, 0)); + outBlob.len = (outBlob.data == nullptr) ? 0 : keySize; + pbkdf2Spec.output = outBlob; +} + +void SetHkdfParamsSpecAttribute(const HKDFSpec ¶ms, HcfHkdfParamsSpec &hkdfSpec, HcfBlob &outBlob) +{ + hkdfSpec.base.algName = params.base.algName.c_str(); + if (params.key.get_tag() == OptStrUint8Arr::tag_t::STRING) { + StringToDataBlob(params.key.get_STRING_ref(), hkdfSpec.key); + } else { // OptStrUint8Arr::tag_t::UINT8ARRAY + ArrayU8ToDataBlob(params.key.get_UINT8ARRAY_ref(), hkdfSpec.key); + } + ArrayU8ToDataBlob(params.salt, hkdfSpec.salt); + ArrayU8ToDataBlob(params.info, hkdfSpec.info); + size_t keySize = params.keySize; + outBlob.data = static_cast(HcfMalloc(keySize, 0)); + outBlob.len = (outBlob.data == nullptr) ? 0 : keySize; + hkdfSpec.output = outBlob; +} + +void SetScryptParamsSpecAttribute(const ScryptSpec ¶ms, HcfScryptParamsSpec &scryptSpec, HcfBlob &outBlob) +{ + scryptSpec.base.algName = params.base.algName.c_str(); + if (params.passphrase.get_tag() == OptStrUint8Arr::tag_t::STRING) { + StringToDataBlob(params.passphrase.get_STRING_ref(), scryptSpec.passPhrase); + } else { // OptStrUint8Arr::tag_t::UINT8ARRAY + ArrayU8ToDataBlob(params.passphrase.get_UINT8ARRAY_ref(), scryptSpec.passPhrase); + } + ArrayU8ToDataBlob(params.salt, scryptSpec.salt); + scryptSpec.n = params.n; + scryptSpec.r = params.r; + scryptSpec.p = params.p; + scryptSpec.maxMem = params.maxMemory; + size_t keySize = params.keySize; + outBlob.data = static_cast(HcfMalloc(keySize, 0)); + outBlob.len = (outBlob.data == nullptr) ? 0 : keySize; + scryptSpec.output = outBlob; +} +} // namespace + +namespace ANI::CryptoFramework { +KdfImpl::KdfImpl() {} + +KdfImpl::KdfImpl(HcfKdf *kdf) : kdf_(kdf) {} + +KdfImpl::~KdfImpl() +{ + HcfObjDestroy(this->kdf_); + this->kdf_ = nullptr; +} + +DataBlob KdfImpl::GenerateSecretSync(OptExtKdfSpec const& params) +{ + if (this->kdf_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "kdf obj is nullptr!"); + return {}; + } + HcfKdfParamsSpec *paramsSpec = nullptr; + HcfPBKDF2ParamsSpec pbkdf2Spec = {}; + HcfHkdfParamsSpec hkdfSpec = {}; + HcfScryptParamsSpec scryptSpec = {}; + HcfBlob outBlob = {}; + const std::string &algName = params.get_KDFSPEC_ref().algName.c_str(); + if (params.get_tag() == OptExtKdfSpec::tag_t::PBKDF2SPEC && algName == PBKDF2_ALG_NAME) { + SetPBKDF2ParamsSpecAttribute(params.get_PBKDF2SPEC_ref(), pbkdf2Spec, outBlob); + paramsSpec = reinterpret_cast(&pbkdf2Spec); + } else if (params.get_tag() == OptExtKdfSpec::tag_t::HKDFSPEC && algName == HKDF_ALG_NAME) { + SetHkdfParamsSpecAttribute(params.get_HKDFSPEC_ref(), hkdfSpec, outBlob); + paramsSpec = reinterpret_cast(&hkdfSpec); + } else if (params.get_tag() == OptExtKdfSpec::tag_t::SCRYPTSPEC && algName == SCRYPT_ALG_NAME) { + SetScryptParamsSpecAttribute(params.get_SCRYPTSPEC_ref(), scryptSpec, outBlob); + paramsSpec = reinterpret_cast(&scryptSpec); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "invalid kdf spec!"); + return {}; + } + HcfResult res = this->kdf_->generateSecret(this->kdf_, paramsSpec); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "kdf generateSecret failed!"); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string KdfImpl::GetAlgName() +{ + if (this->kdf_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "kdf obj is nullptr!"); + return ""; + } + const char *algName = this->kdf_->getAlgorithm(this->kdf_); + return (algName == nullptr) ? "" : string(algName); +} + +Kdf CreateKdf(string_view algName) +{ + HcfKdf *kdf = nullptr; + HcfResult res = HcfKdfCreate(algName.c_str(), &kdf); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create kdf obj failed."); + return make_holder(); + } + return make_holder(kdf); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateKdf(ANI::CryptoFramework::CreateKdf); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_key.cpp b/frameworks/js/ani/src/ani_key.cpp index d2979155632bb69d28bcfce4e274bf68b81018f2..cb15e66c339e97cd7b90a86024846c91aba60b36 100644 --- a/frameworks/js/ani/src/ani_key.cpp +++ b/frameworks/js/ani/src/ani_key.cpp @@ -15,27 +15,57 @@ #include "ani_key.h" -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; -using namespace ANI::CryptoFramework; - namespace ANI::CryptoFramework { KeyImpl::KeyImpl() {} -KeyImpl::~KeyImpl() {} +KeyImpl::KeyImpl(HcfKey *key) : key_(key) {} + +KeyImpl::~KeyImpl() +{ + HcfObjDestroy(this->key_); + this->key_ = nullptr; +} + +int64_t KeyImpl::GetKeyObj() +{ + return reinterpret_cast(this->key_); +} DataBlob KeyImpl::GetEncoded() { - TH_THROW(std::runtime_error, "GetEncoded not implemented"); + if (this->key_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "key obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->key_->getEncoded(this->key_, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncoded failed."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; } string KeyImpl::GetFormat() { - TH_THROW(std::runtime_error, "GetFormat not implemented"); + if (this->key_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "key obj is nullptr!"); + return ""; + } + const char *format = this->key_->getFormat(this->key_); + return (format == nullptr) ? "" : string(format); } string KeyImpl::GetAlgName() { - TH_THROW(std::runtime_error, "GetAlgName not implemented"); + if (this->key_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "key obj is nullptr!"); + return ""; + } + const char *algName = this->key_->getAlgorithm(this->key_); + return (algName == nullptr) ? "" : string(algName); } } // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_key_agreement.cpp b/frameworks/js/ani/src/ani_key_agreement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..caaf54c27e9fd1d6e873d7d6dd813550745d1ec4 --- /dev/null +++ b/frameworks/js/ani/src/ani_key_agreement.cpp @@ -0,0 +1,74 @@ +/* + * 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_agreement.h" + +namespace ANI::CryptoFramework { +KeyAgreementImpl::KeyAgreementImpl() {} + +KeyAgreementImpl::KeyAgreementImpl(HcfKeyAgreement *keyAgreement) : keyAgreement_(keyAgreement) {} + +KeyAgreementImpl::~KeyAgreementImpl() +{ + HcfObjDestroy(this->keyAgreement_); + this->keyAgreement_ = nullptr; +} + +DataBlob KeyAgreementImpl::GenerateSecretSync(weak::PriKey priKey, weak::PubKey pubKey) +{ + if (this->keyAgreement_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "keyAgreement obj is nullptr!"); + return {}; + } + HcfPriKey *hcfPriKey = reinterpret_cast(priKey->GetPriKeyObj()); + HcfPubKey *hcfPubKey = reinterpret_cast(pubKey->GetPubKeyObj()); + HcfBlob outBlob = {}; + HcfResult res = this->keyAgreement_->generateSecret(this->keyAgreement_, hcfPriKey, hcfPubKey, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "keyAgreement generateSecret fail."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string KeyAgreementImpl::GetAlgName() +{ + if (this->keyAgreement_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "keyAgreement obj is nullptr!"); + return ""; + } + const char *algName = this->keyAgreement_->getAlgoName(this->keyAgreement_); + return (algName == nullptr) ? "" : string(algName); +} + +KeyAgreement CreateKeyAgreement(string_view algName) +{ + HcfKeyAgreement *keyAgreement = nullptr; + HcfResult res = HcfKeyAgreementCreate(algName.c_str(), &keyAgreement); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create keyAgreement obj fail."); + return make_holder(); + } + return make_holder(keyAgreement); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateKeyAgreement(ANI::CryptoFramework::CreateKeyAgreement); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_key_pair.cpp b/frameworks/js/ani/src/ani_key_pair.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b1f335ae94d55b98ac922316f50b76085c86ebe --- /dev/null +++ b/frameworks/js/ani/src/ani_key_pair.cpp @@ -0,0 +1,50 @@ +/* + * 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_pair.h" +#include "ani_pri_key.h" +#include "ani_pub_key.h" + +namespace ANI::CryptoFramework { +KeyPairImpl::KeyPairImpl() {} + +KeyPairImpl::KeyPairImpl(HcfKeyPair *keyPair) : keyPair_(keyPair) {} + +KeyPairImpl::~KeyPairImpl() +{ + HcfObjDestroy(this->keyPair_); + this->keyPair_ = nullptr; +} + +PriKey KeyPairImpl::GetPriKey() +{ + if (this->keyPair_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "keyPair obj is nullptr!"); + return make_holder(); + } + HcfPriKey *priKey = this->keyPair_->priKey; + return make_holder(priKey, false); +} + +PubKey KeyPairImpl::GetPubKey() +{ + if (this->keyPair_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "keyPair obj is nullptr!"); + return make_holder(); + } + HcfPubKey *pubKey = this->keyPair_->pubKey; + return make_holder(pubKey, false); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_mac.cpp b/frameworks/js/ani/src/ani_mac.cpp index 2ac696d8f4fd64ad61b35f3f0af38349ce09ac5b..0c9ea4716569dc400218b9ab14c68684dce93a8c 100644 --- a/frameworks/js/ani/src/ani_mac.cpp +++ b/frameworks/js/ani/src/ani_mac.cpp @@ -15,30 +15,45 @@ #include "ani_mac.h" #include "detailed_hmac_params.h" +#include "detailed_cmac_params.h" -using namespace taihe; -using namespace ohos::security::cryptoFramework::cryptoFramework; +namespace { using namespace ANI::CryptoFramework; +const std::string HMAC_ALG_NAME = "HMAC"; +const std::string CMAC_ALG_NAME = "CMAC"; + +Mac CreateMacInner(HcfMacParamsSpec *spec) +{ + HcfMac *mac = nullptr; + HcfResult res = HcfMacCreate(spec, &mac); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create mac obj failed."); + return make_holder(); + } + return make_holder(mac); +} +} // namespace + namespace ANI::CryptoFramework { -MacImpl::MacImpl() : macObj(nullptr) {} +MacImpl::MacImpl() {} -MacImpl::MacImpl(HcfMac *obj) : macObj(obj) {} +MacImpl::MacImpl(HcfMac *mac) : mac_(mac) {} MacImpl::~MacImpl() { - HcfObjDestroy(macObj); - macObj = nullptr; + HcfObjDestroy(this->mac_); + this->mac_ = nullptr; } void MacImpl::InitSync(weak::SymKey key) { - if (macObj == nullptr) { + if (this->mac_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); return; } - HcfSymKey *symKey = reinterpret_cast(key->GetSymKeyObj()); - HcfResult res = macObj->init(macObj, symKey); + HcfSymKey *hcfSymKey = reinterpret_cast(key->GetSymKeyObj()); + HcfResult res = this->mac_->init(this->mac_, hcfSymKey); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "mac init failed!"); return; @@ -47,12 +62,13 @@ void MacImpl::InitSync(weak::SymKey key) void MacImpl::UpdateSync(DataBlob const& input) { - if (macObj == nullptr) { + if (this->mac_ == 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); + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(input.data, inBlob); + HcfResult res = this->mac_->update(this->mac_, &inBlob); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "mac update failed!"); return; @@ -61,51 +77,74 @@ void MacImpl::UpdateSync(DataBlob const& input) DataBlob MacImpl::DoFinalSync() { - if (macObj == nullptr) { + if (this->mac_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); - return { taihe::array(nullptr, 0) }; + return {}; } - HcfBlob outBlob = { .data = nullptr, .len = 0 }; - HcfResult res = macObj->doFinal(macObj, &outBlob); + HcfBlob outBlob = {}; + HcfResult res = this->mac_->doFinal(this->mac_, &outBlob); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "mac doFinal failed!"); - return { taihe::array(nullptr, 0) }; + return {}; } - taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + array data = {}; + DataBlobToArrayU8(outBlob, data); HcfBlobDataClearAndFree(&outBlob); return { data }; } int32_t MacImpl::GetMacLength() { - if (macObj == nullptr) { + if (this->mac_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); return 0; } - uint32_t length = macObj->getMacLength(macObj); + uint32_t length = this->mac_->getMacLength(this->mac_); return static_cast(length); } string MacImpl::GetAlgName() { - if (macObj == nullptr) { + if (this->mac_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "mac obj is nullptr!"); return ""; } - const char *algName = macObj->getAlgoName(macObj); + const char *algName = this->mac_->getAlgoName(this->mac_); return (algName == nullptr) ? "" : string(algName); } -Mac CreateMac(string_view algName) +Mac CreateMacByStr(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); + HcfHmacParamsSpec spec = {}; + spec.base.algName = HMAC_ALG_NAME.c_str(); + spec.mdName = algName.c_str(); + return CreateMacInner(reinterpret_cast(&spec)); +} + +Mac CreateMacBySpec(OptExtMacSpec const& macSpec) +{ + HcfMacParamsSpec *spec = nullptr; + HcfHmacParamsSpec hmacSpec = {}; + HcfCmacParamsSpec cmacSpec = {}; + const std::string &algName = macSpec.get_MACSPEC_ref().algName.c_str(); + if (macSpec.get_tag() == OptExtMacSpec::tag_t::HMACSPEC && algName == HMAC_ALG_NAME) { + hmacSpec.base.algName = algName.c_str(); + hmacSpec.mdName = macSpec.get_HMACSPEC_ref().mdName.c_str(); + spec = reinterpret_cast(&hmacSpec); + } else if (macSpec.get_tag() == OptExtMacSpec::tag_t::CMACSPEC && algName == CMAC_ALG_NAME) { + cmacSpec.base.algName = algName.c_str(); + cmacSpec.cipherName = macSpec.get_CMACSPEC_ref().cipherName.c_str(); + spec = reinterpret_cast(&cmacSpec); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "invalid mac spec!"); + return make_holder(); } - return make_holder(macObj); + return CreateMacInner(spec); } } // namespace ANI::CryptoFramework -TH_EXPORT_CPP_API_CreateMac(CreateMac); +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateMacByStr(ANI::CryptoFramework::CreateMacByStr); +TH_EXPORT_CPP_API_CreateMacBySpec(ANI::CryptoFramework::CreateMacBySpec); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_md.cpp b/frameworks/js/ani/src/ani_md.cpp index c264161e20b7fcffdd4fa72a56d20af4b4376515..d2efc233b2b24ba3a7889e205dbe28f31b1e7efa 100644 --- a/frameworks/js/ani/src/ani_md.cpp +++ b/frameworks/js/ani/src/ani_md.cpp @@ -15,77 +15,83 @@ #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() {} -MdImpl::MdImpl(HcfMd *obj) : mdObj(obj) {} +MdImpl::MdImpl(HcfMd *md) : md_(md) {} -MdImpl::~MdImpl() {} +MdImpl::~MdImpl() +{ + HcfObjDestroy(this->md_); + this->md_ = nullptr; +} void MdImpl::UpdateSync(DataBlob const& input) { - if (mdObj == nullptr) { + if (this->md_ == 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); + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(input.data, inBlob); + HcfResult res = this->md_->update(this->md_, &inBlob); if (res != HCF_SUCCESS) { - ANI_LOGE_THROW(res, "md doFinal failed!"); + ANI_LOGE_THROW(res, "md update failed!"); return; } } DataBlob MdImpl::DigestSync() { - if (mdObj == nullptr) { + if (this->md_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); - return { taihe::array(nullptr, 0) }; + return {}; } - HcfBlob outBlob = { .data = nullptr, .len = 0 }; - HcfResult res = mdObj->doFinal(mdObj, &outBlob); + HcfBlob outBlob = {}; + HcfResult res = this->md_->doFinal(this->md_, &outBlob); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "mac doFinal failed!"); - return { taihe::array(nullptr, 0) }; + return {}; } - taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + array data = {}; + DataBlobToArrayU8(outBlob, data); HcfBlobDataClearAndFree(&outBlob); return { data }; } int32_t MdImpl::GetMdLength() { - if (mdObj == nullptr) { + if (this->md_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); return 0; } - uint32_t length = mdObj->getMdLength(mdObj); + uint32_t length = this->md_->getMdLength(this->md_); return static_cast(length); } string MdImpl::GetAlgName() { - if (mdObj == nullptr) { + if (this->md_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "md obj is nullptr!"); return ""; } - const char *algName = mdObj->getAlgoName(mdObj); + const char *algName = this->md_->getAlgoName(this->md_); return (algName == nullptr) ? "" : string(algName); } Md CreateMd(string_view algName) { - HcfMd *mdObj = nullptr; - HcfResult res = HcfMdCreate(algName.c_str(), &mdObj); + HcfMd *md = nullptr; + HcfResult res = HcfMdCreate(algName.c_str(), &md); if (res != HCF_SUCCESS) { - ANI_LOGE_THROW(res, "create C md obj failed."); - return make_holder(nullptr); + ANI_LOGE_THROW(res, "create md obj failed."); + return make_holder(); } - return make_holder(mdObj); + return make_holder(md); } } // namespace ANI::CryptoFramework -TH_EXPORT_CPP_API_CreateMd(CreateMd); +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateMd(ANI::CryptoFramework::CreateMd); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_pri_key.cpp b/frameworks/js/ani/src/ani_pri_key.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d2debd6c8e1c13b630b14ca2fc00382d4d563ce --- /dev/null +++ b/frameworks/js/ani/src/ani_pri_key.cpp @@ -0,0 +1,198 @@ +/* + * 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_pri_key.h" +#include "key.h" + +namespace { +using namespace ANI::CryptoFramework; + +OptKeySpec GetAsyKeySpecNumber(HcfPriKey *priKey, HcfAsyKeySpecItem item) +{ + int num = 0; + HcfResult res = priKey->getAsyKeySpecInt(priKey, item, &num); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec int fail."); + return OptKeySpec::make_INT32(-1); + } + return OptKeySpec::make_INT32(num); +} + +OptKeySpec GetAsyKeySpecString(HcfPriKey *priKey, HcfAsyKeySpecItem item) +{ + char *str = nullptr; + HcfResult res = priKey->getAsyKeySpecString(priKey, item, &str); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec string fail."); + return OptKeySpec::make_STRING(""); + } + string data = string(str); + HcfFree(str); + return OptKeySpec::make_STRING(data); +} + +OptKeySpec GetAsyKeySpecBigInt(HcfPriKey *priKey, HcfAsyKeySpecItem item) +{ + HcfBigInteger bigint = {}; + HcfResult res = priKey->getAsyKeySpecBigInteger(priKey, item, &bigint); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec biginteger failed."); + return OptKeySpec::make_BIGINT(array{}); + } + array data = {}; + BigIntegerToArrayU8(bigint, data); + HcfBlobDataClearAndFree(reinterpret_cast(&bigint)); + return OptKeySpec::make_BIGINT(data); +} + +string GetEncodedPemInner(const HcfPriKey *self, HcfParamsSpec *params, string_view format) +{ + if (self == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return ""; + } + char *encoded = nullptr; + HcfResult res = self->getEncodedPem(self, params, format.c_str(), &encoded); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncodedPem fail."); + return ""; + } + string str = string(encoded); + HcfFree(encoded); + return str; +} +} // namespace + +namespace ANI::CryptoFramework { +PriKeyImpl::PriKeyImpl() {} + +PriKeyImpl::PriKeyImpl(HcfPriKey *priKey, bool owner /* = true */) : priKey_(priKey), owner_(owner) {} + +PriKeyImpl::~PriKeyImpl() +{ + if (this->owner_) { + HcfObjDestroy(this->priKey_); + this->priKey_ = nullptr; + } +} + +int64_t PriKeyImpl::GetPriKeyObj() +{ + return reinterpret_cast(this->priKey_); +} + +void PriKeyImpl::ClearMem() +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return; + } + this->priKey_->clearMem(this->priKey_); +} + +OptKeySpec PriKeyImpl::GetAsyKeySpec(ThAsyKeySpecItem itemType) +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return OptKeySpec::make_INT32(-1); + } + HcfAsyKeySpecItem item = static_cast(itemType.get_value()); + int type = GetAsyKeySpecType(item); + if (type == SPEC_ITEM_TYPE_NUM) { + return GetAsyKeySpecNumber(this->priKey_, item); + } else if (type == SPEC_ITEM_TYPE_STR) { + return GetAsyKeySpecString(this->priKey_, item); + } else if (type == SPEC_ITEM_TYPE_BIG_INT) { + return GetAsyKeySpecBigInt(this->priKey_, item); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "asy key spec item not support!"); + return OptKeySpec::make_INT32(-1); + } +} + +DataBlob PriKeyImpl::GetEncodedDer(string_view format) +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->priKey_->getEncodedDer(this->priKey_, format.c_str(), &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncodedDer fail."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string PriKeyImpl::GetEncodedPem(string_view format) +{ + return GetEncodedPemInner(this->priKey_, nullptr, format); +} + +string PriKeyImpl::GetEncodedPemEx(string_view format, KeyEncodingConfig const& config) +{ + HcfKeyEncodingParamsSpec spec = {}; + spec.password = const_cast(config.password.c_str()); + spec.cipher = const_cast(config.cipherName.c_str()); + return GetEncodedPemInner(this->priKey_, reinterpret_cast(&spec), format); +} + +int64_t PriKeyImpl::GetKeyObj() +{ + return reinterpret_cast(&this->priKey_->base); +} + +DataBlob PriKeyImpl::GetEncoded() +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->priKey_->base.getEncoded(&this->priKey_->base, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncoded failed."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string PriKeyImpl::GetFormat() +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return ""; + } + const char *format = this->priKey_->base.getFormat(&this->priKey_->base); + return (format == nullptr) ? "" : string(format); +} + +string PriKeyImpl::GetAlgName() +{ + if (this->priKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "priKey obj is nullptr!"); + return ""; + } + const char *algName = this->priKey_->base.getAlgorithm(&this->priKey_->base); + return (algName == nullptr) ? "" : string(algName); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_pub_key.cpp b/frameworks/js/ani/src/ani_pub_key.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e031c1a4081f14458d8bac314410d5bffd720992 --- /dev/null +++ b/frameworks/js/ani/src/ani_pub_key.cpp @@ -0,0 +1,176 @@ +/* + * 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_pub_key.h" +#include "key.h" + +namespace { +using namespace ANI::CryptoFramework; + +OptKeySpec GetAsyKeySpecNumber(HcfPubKey *pubKey, HcfAsyKeySpecItem item) +{ + int num = 0; + HcfResult res = pubKey->getAsyKeySpecInt(pubKey, item, &num); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec int fail."); + return OptKeySpec::make_INT32(-1); + } + return OptKeySpec::make_INT32(num); +} + +OptKeySpec GetAsyKeySpecString(HcfPubKey *pubKey, HcfAsyKeySpecItem item) +{ + char *str = nullptr; + HcfResult res = pubKey->getAsyKeySpecString(pubKey, item, &str); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec string fail."); + return OptKeySpec::make_STRING(""); + } + string data = string(str); + HcfFree(str); + return OptKeySpec::make_STRING(data); +} + +OptKeySpec GetAsyKeySpecBigInt(HcfPubKey *pubKey, HcfAsyKeySpecItem item) +{ + HcfBigInteger bigint = {}; + HcfResult res = pubKey->getAsyKeySpecBigInteger(pubKey, item, &bigint); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get asy key spec bigint failed."); + return OptKeySpec::make_BIGINT(array{}); + } + array data = {}; + BigIntegerToArrayU8(bigint, data); + HcfFree(bigint.data); + return OptKeySpec::make_BIGINT(data); +} +} // namespace + +namespace ANI::CryptoFramework { +PubKeyImpl::PubKeyImpl() {} + +PubKeyImpl::PubKeyImpl(HcfPubKey *pubKey, bool owner /* = true */) : pubKey_(pubKey), owner_(owner) {} + +PubKeyImpl::~PubKeyImpl() +{ + if (this->owner_) { + HcfObjDestroy(this->pubKey_); + this->pubKey_ = nullptr; + } +} + +int64_t PubKeyImpl::GetPubKeyObj() +{ + return reinterpret_cast(this->pubKey_); +} + +OptKeySpec PubKeyImpl::GetAsyKeySpec(ThAsyKeySpecItem itemType) +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return OptKeySpec::make_INT32(-1); + } + HcfAsyKeySpecItem item = static_cast(itemType.get_value()); + int type = GetAsyKeySpecType(item); + if (type == SPEC_ITEM_TYPE_NUM) { + return GetAsyKeySpecNumber(this->pubKey_, item); + } else if (type == SPEC_ITEM_TYPE_STR) { + return GetAsyKeySpecString(this->pubKey_, item); + } else if (type == SPEC_ITEM_TYPE_BIG_INT) { + return GetAsyKeySpecBigInt(this->pubKey_, item); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "asy key spec item not support!"); + return OptKeySpec::make_INT32(-1); + } +} + +DataBlob PubKeyImpl::GetEncodedDer(string_view format) +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->pubKey_->getEncodedDer(this->pubKey_, format.c_str(), &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncodedDer failed."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string PubKeyImpl::GetEncodedPem(string_view format) +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return ""; + } + char *encoded = nullptr; + HcfResult res = this->pubKey_->base.getEncodedPem(&this->pubKey_->base, format.c_str(), &encoded); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncodedPem failed."); + return ""; + } + string str = string(encoded); + HcfFree(encoded); + return str; +} + +int64_t PubKeyImpl::GetKeyObj() +{ + return reinterpret_cast(&this->pubKey_->base); +} + +DataBlob PubKeyImpl::GetEncoded() +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->pubKey_->base.getEncoded(&this->pubKey_->base, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncoded failed."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +string PubKeyImpl::GetFormat() +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return ""; + } + const char *format = this->pubKey_->base.getFormat(&this->pubKey_->base); + return (format == nullptr) ? "" : string(format); +} + +string PubKeyImpl::GetAlgName() +{ + if (this->pubKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "pubKey obj is nullptr!"); + return ""; + } + const char *algName = this->pubKey_->base.getAlgorithm(&this->pubKey_->base); + return (algName == nullptr) ? "" : string(algName); +} +} // namespace ANI::CryptoFramework diff --git a/frameworks/js/ani/src/ani_rand.cpp b/frameworks/js/ani/src/ani_rand.cpp index 8820b79781f4704cfcf848717cfb1ea358ed889e..37c4f381dbb544f0cb159a164974df1f17e2834f 100644 --- a/frameworks/js/ani/src/ani_rand.cpp +++ b/frameworks/js/ani/src/ani_rand.cpp @@ -15,46 +15,44 @@ #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() {} -RandomImpl::RandomImpl(HcfRand *obj) : randObj(obj) {} +RandomImpl::RandomImpl(HcfRand *rand) : rand_(rand) {} RandomImpl::~RandomImpl() { - HcfObjDestroy(randObj); - randObj = nullptr; + HcfObjDestroy(this->rand_); + this->rand_ = nullptr; } DataBlob RandomImpl::GenerateRandomSync(int32_t len) { - if (randObj == nullptr) { + if (this->rand_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); - return { taihe::array(nullptr, 0) }; + return {}; } - HcfBlob outBlob = { .data = nullptr, .len = 0 }; - HcfResult res = randObj->generateRandom(randObj, len, &outBlob); + HcfBlob outBlob = {}; + HcfResult res = this->rand_->generateRandom(this->rand_, len, &outBlob); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "generateRandom failed!"); - return { taihe::array(nullptr, 0) }; + return {}; } - taihe::array data(move_data_t{}, outBlob.data, outBlob.len); + array data = {}; + DataBlobToArrayU8(outBlob, data); HcfBlobDataClearAndFree(&outBlob); return { data }; } void RandomImpl::SetSeed(DataBlob const& seed) { - if (randObj == nullptr) { + if (this->rand_ == 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); + HcfBlob seedBlob = {}; + ArrayU8ToDataBlob(seed.data, seedBlob); + HcfResult res = this->rand_->setSeed(this->rand_, &seedBlob); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "set seed failed."); return; @@ -63,23 +61,27 @@ void RandomImpl::SetSeed(DataBlob const& seed) string RandomImpl::GetAlgName() { - if (randObj == nullptr) { + if (this->rand_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "rand obj is nullptr!"); return ""; } - const char *algName = randObj->getAlgoName(randObj); + const char *algName = this->rand_->getAlgoName(this->rand_); return (algName == nullptr) ? "" : string(algName); } Random CreateRandom() { - HcfRand *randObj = nullptr; - HcfResult res = HcfRandCreate(&randObj); + HcfRand *rand = nullptr; + HcfResult res = HcfRandCreate(&rand); if (res != HCF_SUCCESS) { - ANI_LOGE_THROW(res, "create C rand obj failed."); - return make_holder(nullptr); + ANI_LOGE_THROW(res, "create rand obj failed."); + return make_holder(); } - return make_holder(randObj); + return make_holder(rand); } } // namespace ANI::CryptoFramework -TH_EXPORT_CPP_API_CreateRandom(CreateRandom); +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateRandom(ANI::CryptoFramework::CreateRandom); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_sign.cpp b/frameworks/js/ani/src/ani_sign.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7cb193077f492f83a8db4b6813f14c49253ea415 --- /dev/null +++ b/frameworks/js/ani/src/ani_sign.cpp @@ -0,0 +1,190 @@ +/* + * 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_sign.h" + +namespace { +using namespace ANI::CryptoFramework; + +void SetSignSaltLenInt(HcfSign *sign, HcfSignSpecItem item, int32_t saltLen) +{ + HcfResult res = sign->setSignSpecInt(sign, item, saltLen); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set sign spec int fail."); + return; + } +} + +void SetSignUserIdUintArray(HcfSign *sign, HcfSignSpecItem item, const array &data) +{ + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(data, inBlob); + HcfResult res = sign->setSignSpecUint8Array(sign, item, inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set sign spec uint8 array fail."); + return; + } +} + +OptStrInt GetSignSpecString(HcfSign *sign, HcfSignSpecItem item) +{ + char *str = nullptr; + HcfResult res = sign->getSignSpecString(sign, item, &str); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get sign spec string fail."); + return OptStrInt::make_STRING(""); + } + string data = string(str); + HcfFree(str); + return OptStrInt::make_STRING(data); +} + +OptStrInt GetSignSpecNumber(HcfSign *sign, HcfSignSpecItem item) +{ + int num = 0; + HcfResult res = sign->getSignSpecInt(sign, item, &num); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get sign spec number fail."); + return OptStrInt::make_INT32(-1); + } + return OptStrInt::make_INT32(num); +} +} // namespace + +namespace ANI::CryptoFramework { +SignImpl::SignImpl() {} + +SignImpl::SignImpl(HcfSign *sign) : sign_(sign) {} + +SignImpl::~SignImpl() +{ + HcfObjDestroy(this->sign_); + this->sign_ = nullptr; +} + +void SignImpl::InitSync(weak::PriKey priKey) +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return; + } + HcfPriKey *hcfPriKey = reinterpret_cast(priKey->GetPriKeyObj()); + HcfResult res = this->sign_->init(this->sign_, nullptr, hcfPriKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "sign init failed."); + return; + } +} + +void SignImpl::UpdateSync(DataBlob const& data) +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return; + } + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(data.data, inBlob); + HcfResult res = this->sign_->update(this->sign_, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "sign update failed!"); + return; + } +} + +DataBlob SignImpl::SignSync(OptDataBlob const& data) +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return {}; + } + HcfBlob *inBlob = nullptr; + HcfBlob dataBlob = {}; + if (data.get_tag() == OptDataBlob::tag_t::DATABLOB) { + ArrayU8ToDataBlob(data.get_DATABLOB_ref().data, dataBlob); + inBlob = &dataBlob; + } + HcfBlob outBlob = {}; + HcfResult res = this->sign_->sign(this->sign_, inBlob, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "sign doFinal failed!"); + return {}; + } + array out = {}; + DataBlobToArrayU8(outBlob, out); + HcfBlobDataClearAndFree(&outBlob); + return { out }; +} + +void SignImpl::SetSignSpec(ThSignSpecItem itemType, OptIntUint8Arr const& itemValue) +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return; + } + HcfSignSpecItem item = static_cast(itemType.get_value()); + if (itemValue.get_tag() == OptIntUint8Arr::tag_t::INT32 && item == PSS_SALT_LEN_INT) { + return SetSignSaltLenInt(this->sign_, item, itemValue.get_INT32_ref()); + } else if (itemValue.get_tag() == OptIntUint8Arr::tag_t::UINT8ARRAY && item == SM2_USER_ID_UINT8ARR) { + return SetSignUserIdUintArray(this->sign_, item, itemValue.get_UINT8ARRAY_ref()); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign spec item not support!"); + return; + } +} + +OptStrInt SignImpl::GetSignSpec(ThSignSpecItem itemType) +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return OptStrInt::make_INT32(-1); + } + HcfSignSpecItem item = static_cast(itemType.get_value()); + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetSignSpecString(this->sign_, item); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetSignSpecNumber(this->sign_, item); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign spec item not support!"); + return OptStrInt::make_INT32(-1); + } +} + +string SignImpl::GetAlgName() +{ + if (this->sign_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "sign obj is nullptr!"); + return ""; + } + const char *algName = this->sign_->getAlgoName(this->sign_); + return (algName == nullptr) ? "" : string(algName); +} + +Sign CreateSign(string_view algName) +{ + HcfSign *sign = nullptr; + HcfResult res = HcfSignCreate(algName.c_str(), &sign); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create sign obj fail!"); + return make_holder(); + } + return make_holder(sign); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateSign(ANI::CryptoFramework::CreateSign); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_signature_utils.cpp b/frameworks/js/ani/src/ani_signature_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e99e161f8cdaefbfbb6f98e30340d71e65cdac8 --- /dev/null +++ b/frameworks/js/ani/src/ani_signature_utils.cpp @@ -0,0 +1,36 @@ +/* + * 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_signature_utils.h" + +namespace ANI::CryptoFramework { +EccSignatureSpec GenEccSignatureSpec(array_view data) +{ + // api 20 + TH_THROW(std::runtime_error, "GenEccSignatureSpec not implemented"); +} + +array GenEccSignature(EccSignatureSpec const& spec) +{ + // api 20 + TH_THROW(std::runtime_error, "GenEccSignature not implemented"); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_GenEccSignatureSpec(ANI::CryptoFramework::GenEccSignatureSpec); +TH_EXPORT_CPP_API_GenEccSignature(ANI::CryptoFramework::GenEccSignature); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_sm2_crypto_util.cpp b/frameworks/js/ani/src/ani_sm2_crypto_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a69d995935e2b5ffc9471b889f8b02e0860db47 --- /dev/null +++ b/frameworks/js/ani/src/ani_sm2_crypto_util.cpp @@ -0,0 +1,66 @@ +/* + * 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_sm2_crypto_util.h" +#include "sm2_crypto_params.h" +#include "sm2_crypto_util.h" + +namespace ANI::CryptoFramework { +DataBlob GenCipherTextBySpec(SM2CipherTextSpec const& spec, optional_view mode) +{ + Sm2CipherTextSpec hcfSpec = {}; + ArrayU8ToBigInteger(spec.xCoordinate, hcfSpec.xCoordinate); + ArrayU8ToBigInteger(spec.yCoordinate, hcfSpec.yCoordinate); + ArrayU8ToDataBlob(spec.cipherTextData, hcfSpec.cipherTextData); + ArrayU8ToDataBlob(spec.hashData, hcfSpec.hashData); + string dataMode = mode.has_value() ? mode.value() : ""; + HcfBlob outBlob = {}; + HcfResult res = HcfGenCipherTextBySpec(&hcfSpec, dataMode.c_str(), &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "gen cipher text by spec fail."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; +} + +SM2CipherTextSpec GetCipherTextSpec(DataBlob const& cipherText, optional_view mode) +{ + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(cipherText.data, inBlob); + string dataMode = mode.has_value() ? mode.value() : ""; + Sm2CipherTextSpec *hcfSpec = nullptr; + HcfResult res = HcfGetCipherTextSpec(&inBlob, dataMode.c_str(), &hcfSpec); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get cipher text spec fail."); + return {}; + } + SM2CipherTextSpec spec = {}; + BigIntegerToArrayU8(hcfSpec->xCoordinate, spec.xCoordinate); + BigIntegerToArrayU8(hcfSpec->yCoordinate, spec.yCoordinate); + DataBlobToArrayU8(hcfSpec->cipherTextData, spec.cipherTextData); + DataBlobToArrayU8(hcfSpec->hashData, spec.hashData); + DestroySm2CipherTextSpec(hcfSpec); + return spec; +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_GenCipherTextBySpec(ANI::CryptoFramework::GenCipherTextBySpec); +TH_EXPORT_CPP_API_GetCipherTextSpec(ANI::CryptoFramework::GetCipherTextSpec); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_sym_key.cpp b/frameworks/js/ani/src/ani_sym_key.cpp index 4eabfca2f8f4f484c5fa3077d4b1e66ba65236a8..71b2cdacb094e6e02d131f4077f99763c1158764 100644 --- a/frameworks/js/ani/src/ani_sym_key.cpp +++ b/frameworks/js/ani/src/ani_sym_key.cpp @@ -15,43 +15,71 @@ #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() : symKey_(nullptr) {} -SymKeyImpl::SymKeyImpl(HcfSymKey *obj) : symKey(obj) {} +SymKeyImpl::SymKeyImpl(HcfSymKey *symKey) : symKey_(symKey) {} SymKeyImpl::~SymKeyImpl() { - HcfObjDestroy(symKey); - symKey = nullptr; + HcfObjDestroy(this->symKey_); + this->symKey_ = nullptr; +} + +int64_t SymKeyImpl::GetSymKeyObj() +{ + return reinterpret_cast(this->symKey_); } void SymKeyImpl::ClearMem() { - TH_THROW(std::runtime_error, "ClearMem not implemented"); + if (this->symKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "symKey obj is nullptr!"); + return; + } + this->symKey_->clearMem(this->symKey_); } -int64_t SymKeyImpl::GetSymKeyObj() +int64_t SymKeyImpl::GetKeyObj() { - return reinterpret_cast(symKey); + return reinterpret_cast(&this->symKey_->key); } DataBlob SymKeyImpl::GetEncoded() { - TH_THROW(std::runtime_error, "GetEncoded not implemented"); + if (this->symKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "symKey obj is nullptr!"); + return {}; + } + HcfBlob outBlob = {}; + HcfResult res = this->symKey_->key.getEncoded(&this->symKey_->key, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "getEncoded failed."); + return {}; + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return { data }; } string SymKeyImpl::GetFormat() { - TH_THROW(std::runtime_error, "GetFormat not implemented"); + if (this->symKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "symKey obj is nullptr!"); + return ""; + } + const char *format = this->symKey_->key.getFormat(&this->symKey_->key); + return (format == nullptr) ? "" : string(format); } string SymKeyImpl::GetAlgName() { - TH_THROW(std::runtime_error, "GetAlgName not implemented"); + if (this->symKey_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "symKey obj is nullptr!"); + return ""; + } + const char *algName = this->symKey_->key.getAlgorithm(&this->symKey_->key); + return (algName == nullptr) ? "" : string(algName); } } // 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 index 0d45da86c9f0210cde4833b454164edce8e2ef73..027330111cad8533d5da02d752be4cd02de93e5b 100644 --- a/frameworks/js/ani/src/ani_sym_key_generator.cpp +++ b/frameworks/js/ani/src/ani_sym_key_generator.cpp @@ -16,48 +16,56 @@ #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() {} -SymKeyGeneratorImpl::SymKeyGeneratorImpl(HcfSymKeyGenerator *obj) : generator(obj) {} +SymKeyGeneratorImpl::SymKeyGeneratorImpl(HcfSymKeyGenerator *generator) : generator_(generator) {} SymKeyGeneratorImpl::~SymKeyGeneratorImpl() { - HcfObjDestroy(generator); - generator = nullptr; + HcfObjDestroy(this->generator_); + this->generator_ = nullptr; } SymKey SymKeyGeneratorImpl::GenerateSymKeySync() { - return make_holder(nullptr); + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); + return make_holder(); + } + HcfSymKey *symKey = nullptr; + HcfResult res = this->generator_->generateSymKey(this->generator_, &symKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "generate sym key failed."); + return make_holder(); + } + return make_holder(symKey); } SymKey SymKeyGeneratorImpl::ConvertKeySync(DataBlob const& key) { - if (generator == nullptr) { + if (this->generator_ == nullptr) { ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); - return make_holder(nullptr); + return make_holder(); } HcfSymKey *symKey = nullptr; - HcfBlob keyData = { .data = key.data.data(), .len = key.data.size() }; - HcfResult res = generator->convertSymKey(generator, &keyData, &symKey); + HcfBlob keyData = {}; + ArrayU8ToDataBlob(key.data, keyData); + HcfResult res = this->generator_->convertSymKey(this->generator_, &keyData, &symKey); if (res != HCF_SUCCESS) { ANI_LOGE_THROW(res, "convertSymKey key failed!"); - return make_holder(nullptr); + return make_holder(); } return make_holder(symKey); } string SymKeyGeneratorImpl::GetAlgName() { - if (generator == nullptr) { + if (this->generator_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "generator obj is nullptr!"); return ""; } - const char *algName = generator->getAlgoName(generator); + const char *algName = this->generator_->getAlgoName(this->generator_); return (algName == nullptr) ? "" : string(algName); } @@ -66,11 +74,14 @@ 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); + ANI_LOGE_THROW(res, "create generator obj fail."); + return make_holder(); } return make_holder(generator); } } // namespace ANI::CryptoFramework -TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateSymKeyGenerator(ANI::CryptoFramework::CreateSymKeyGenerator); +// NOLINTEND diff --git a/frameworks/js/ani/src/ani_verify.cpp b/frameworks/js/ani/src/ani_verify.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb2a772b2421332b42d3c20bd7c3de625f86c407 --- /dev/null +++ b/frameworks/js/ani/src/ani_verify.cpp @@ -0,0 +1,210 @@ +/* + * 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_verify.h" +#include "ani_pub_key.h" + +namespace { +using namespace ANI::CryptoFramework; + +void SetVerifySaltLenInt(HcfVerify *verify, HcfSignSpecItem item, int32_t saltLen) +{ + HcfResult res = verify->setVerifySpecInt(verify, item, saltLen); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set verify spec int fail."); + return; + } +} + +void SetVerifyUserIdUintArray(HcfVerify *verify, HcfSignSpecItem item, const array &data) +{ + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(data, inBlob); + HcfResult res = verify->setVerifySpecUint8Array(verify, item, inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "set verify spec uint8 array fail."); + return; + } +} + +OptStrInt GetVerifySpecString(HcfVerify *verify, HcfSignSpecItem item) +{ + char *str = nullptr; + HcfResult res = verify->getVerifySpecString(verify, item, &str); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get verify spec string fail."); + return OptStrInt::make_STRING(""); + } + string data = string(str); + HcfFree(str); + return OptStrInt::make_STRING(data); +} + +OptStrInt GetVerifySpecNumber(HcfVerify *verify, HcfSignSpecItem item) +{ + int num = 0; + HcfResult res = verify->getVerifySpecInt(verify, item, &num); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "get verify spec number fail."); + return OptStrInt::make_INT32(-1); + } + return OptStrInt::make_INT32(num); +} +} // namespace + +namespace ANI::CryptoFramework { +VerifyImpl::VerifyImpl() {} + +VerifyImpl::VerifyImpl(HcfVerify *verify) : verify_(verify) {} + +VerifyImpl::~VerifyImpl() +{ + HcfObjDestroy(this->verify_); + this->verify_ = nullptr; +} + +void VerifyImpl::InitSync(weak::PubKey pubKey) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return; + } + HcfPubKey *hcfPubKey = reinterpret_cast(pubKey->GetPubKeyObj()); + HcfResult res = this->verify_->init(this->verify_, nullptr, hcfPubKey); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "verify init failed."); + return; + } +} + +void VerifyImpl::UpdateSync(DataBlob const& input) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return; + } + HcfBlob inBlob = {}; + ArrayU8ToDataBlob(input.data, inBlob); + HcfResult res = this->verify_->update(this->verify_, &inBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "verify update failed!"); + return; + } +} + +bool VerifyImpl::VerifySync(OptDataBlob const& data, DataBlob const& signature) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return false; + } + HcfBlob *inBlob = nullptr; + HcfBlob dataBlob = {}; + if (data.get_tag() == OptDataBlob::tag_t::DATABLOB) { + ArrayU8ToDataBlob(data.get_DATABLOB_ref().data, dataBlob); + inBlob = &dataBlob; + } + HcfBlob signData = {}; + ArrayU8ToDataBlob(signature.data, signData); + bool res = this->verify_->verify(this->verify_, inBlob, &signData); + if (!res) { + LOGE("verify doFinal failed."); + return false; + } + return true; +} + +OptDataBlob VerifyImpl::RecoverSync(DataBlob const& signature) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return OptDataBlob::make_EMPTY(); + } + HcfBlob inBlob = {}; + HcfBlob outBlob = {}; + ArrayU8ToDataBlob(signature.data, inBlob); + HcfResult res = this->verify_->recover(this->verify_, &inBlob, &outBlob); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "verify recover failed!"); + return OptDataBlob::make_EMPTY(); + } + array data = {}; + DataBlobToArrayU8(outBlob, data); + HcfBlobDataClearAndFree(&outBlob); + return OptDataBlob::make_DATABLOB(DataBlob({ data })); +} + +void VerifyImpl::SetVerifySpec(ThSignSpecItem itemType, OptIntUint8Arr const& itemValue) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return; + } + + HcfSignSpecItem item = static_cast(itemType.get_value()); + if (itemValue.get_tag() == OptIntUint8Arr::tag_t::INT32 && item == PSS_SALT_LEN_INT) { + return SetVerifySaltLenInt(this->verify_, item, itemValue.get_INT32_ref()); + } else if (itemValue.get_tag() == OptIntUint8Arr::tag_t::UINT8ARRAY && item == SM2_USER_ID_UINT8ARR) { + return SetVerifyUserIdUintArray(this->verify_, item, itemValue.get_UINT8ARRAY_ref()); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify spec item not support!"); + return; + } +} + +OptStrInt VerifyImpl::GetVerifySpec(ThSignSpecItem itemType) +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return OptStrInt::make_INT32(-1); + } + HcfSignSpecItem item = static_cast(itemType.get_value()); + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetVerifySpecString(this->verify_, item); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetVerifySpecNumber(this->verify_, item); + } else { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify spec item not support!"); + return OptStrInt::make_INT32(-1); + } +} + +string VerifyImpl::GetAlgName() +{ + if (this->verify_ == nullptr) { + ANI_LOGE_THROW(HCF_INVALID_PARAMS, "verify obj is nullptr!"); + return ""; + } + const char *algName = this->verify_->getAlgoName(this->verify_); + return (algName == nullptr) ? "" : string(algName); +} + +Verify CreateVerify(string_view algName) +{ + HcfVerify *verify = nullptr; + HcfResult res = HcfVerifyCreate(algName.c_str(), &verify); + if (res != HCF_SUCCESS) { + ANI_LOGE_THROW(res, "create verify obj fail!"); + return make_holder(); + } + return make_holder(verify); +} +} // namespace ANI::CryptoFramework + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateVerify(ANI::CryptoFramework::CreateVerify); +// NOLINTEND 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 index 5327a103aa53a212fafe9c25c4d4caf117d5372f..375b8f6be3dbc32bedb08b480c4fbe14fd407593 100644 --- a/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp +++ b/frameworks/js/ani/src/impl/ohos.security.cryptoFramework.cryptoFramework.impl.cpp @@ -99,6 +99,10 @@ public: // Don't forget to implement the constructor. } + int64_t GetKeyObj() { + TH_THROW(std::runtime_error, "GetKeyObj not implemented"); + } + DataBlob GetEncoded() { TH_THROW(std::runtime_error, "GetEncoded not implemented"); } @@ -112,20 +116,129 @@ public: } }; -class SymKeyImpl { +class PriKeyImpl { public: - SymKeyImpl() { + PriKeyImpl() { // Don't forget to implement the constructor. } + int64_t GetPriKeyObj() { + TH_THROW(std::runtime_error, "GetPriKeyObj not implemented"); + } + void ClearMem() { TH_THROW(std::runtime_error, "ClearMem not implemented"); } + OptKeySpec GetAsyKeySpec(AsyKeySpecItem itemType) { + TH_THROW(std::runtime_error, "GetAsyKeySpec not implemented"); + } + + DataBlob GetEncodedDer(string_view format) { + TH_THROW(std::runtime_error, "GetEncodedDer not implemented"); + } + + string GetEncodedPem(string_view format) { + TH_THROW(std::runtime_error, "GetEncodedPem not implemented"); + } + + string GetEncodedPemEx(string_view format, KeyEncodingConfig const& config) { + TH_THROW(std::runtime_error, "GetEncodedPemEx not implemented"); + } + + int64_t GetKeyObj() { + TH_THROW(std::runtime_error, "GetKeyObj 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 PubKeyImpl { +public: + PubKeyImpl() { + // Don't forget to implement the constructor. + } + + int64_t GetPubKeyObj() { + TH_THROW(std::runtime_error, "GetPubKeyObj not implemented"); + } + + OptKeySpec GetAsyKeySpec(AsyKeySpecItem itemType) { + TH_THROW(std::runtime_error, "GetAsyKeySpec not implemented"); + } + + DataBlob GetEncodedDer(string_view format) { + TH_THROW(std::runtime_error, "GetEncodedDer not implemented"); + } + + string GetEncodedPem(string_view format) { + TH_THROW(std::runtime_error, "GetEncodedPem not implemented"); + } + + int64_t GetKeyObj() { + TH_THROW(std::runtime_error, "GetKeyObj 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 KeyPairImpl { +public: + KeyPairImpl() { + // Don't forget to implement the constructor. + } + + PriKey GetPriKey() { + // 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(); + } + + PubKey GetPubKey() { + // 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(); + } +}; + +class SymKeyImpl { +public: + SymKeyImpl() { + // Don't forget to implement the constructor. + } + int64_t GetSymKeyObj() { TH_THROW(std::runtime_error, "GetSymKeyObj not implemented"); } + void ClearMem() { + TH_THROW(std::runtime_error, "ClearMem not implemented"); + } + + int64_t GetKeyObj() { + TH_THROW(std::runtime_error, "GetKeyObj not implemented"); + } + DataBlob GetEncoded() { TH_THROW(std::runtime_error, "GetEncoded not implemented"); } @@ -162,6 +275,225 @@ public: } }; +class AsyKeyGeneratorImpl { +public: + AsyKeyGeneratorImpl() { + // Don't forget to implement the constructor. + } + + KeyPair GenerateKeyPairSync() { + // 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(); + } + + KeyPair ConvertKeySync(OptDataBlob const& pubKey, OptDataBlob const& priKey) { + // 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(); + } + + KeyPair ConvertPemKeySync(OptString const& pubKey, OptString const& priKey) { + // 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(); + } + + KeyPair ConvertPemKeySyncEx(OptString const& pubKey, OptString const& priKey, string_view password) { + // 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"); + } +}; + +class KdfImpl { +public: + KdfImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GenerateSecretSync(OptExtKdfSpec const& params) { + TH_THROW(std::runtime_error, "GenerateSecretSync not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class CipherImpl { +public: + CipherImpl() { + // Don't forget to implement the constructor. + } + + void InitSync(CryptoMode opMode, weak::Key key, OptParamsSpec const& params) { + TH_THROW(std::runtime_error, "InitSync not implemented"); + } + + DataBlob UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob DoFinalSync(OptDataBlob const& input) { + TH_THROW(std::runtime_error, "DoFinalSync not implemented"); + } + + void SetCipherSpec(CipherSpecItem itemType, array_view itemValue) { + TH_THROW(std::runtime_error, "SetCipherSpec not implemented"); + } + + OptStrUint8Arr GetCipherSpec(CipherSpecItem itemType) { + TH_THROW(std::runtime_error, "GetCipherSpec not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class VerifyImpl { +public: + VerifyImpl() { + // Don't forget to implement the constructor. + } + + void InitSync(weak::PubKey pubKey) { + TH_THROW(std::runtime_error, "InitSync not implemented"); + } + + void UpdateSync(DataBlob const& input) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + bool VerifySync(OptDataBlob const& data, DataBlob const& signature) { + TH_THROW(std::runtime_error, "VerifySync not implemented"); + } + + OptDataBlob RecoverSync(DataBlob const& signature) { + TH_THROW(std::runtime_error, "RecoverSync not implemented"); + } + + void SetVerifySpec(SignSpecItem itemType, OptIntUint8Arr const& itemValue) { + TH_THROW(std::runtime_error, "SetVerifySpec not implemented"); + } + + OptStrInt GetVerifySpec(SignSpecItem itemType) { + TH_THROW(std::runtime_error, "GetVerifySpec not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class SignImpl { +public: + SignImpl() { + // Don't forget to implement the constructor. + } + + void InitSync(weak::PriKey priKey) { + TH_THROW(std::runtime_error, "InitSync not implemented"); + } + + void UpdateSync(DataBlob const& data) { + TH_THROW(std::runtime_error, "UpdateSync not implemented"); + } + + DataBlob SignSync(OptDataBlob const& data) { + TH_THROW(std::runtime_error, "SignSync not implemented"); + } + + void SetSignSpec(SignSpecItem itemType, OptIntUint8Arr const& itemValue) { + TH_THROW(std::runtime_error, "SetSignSpec not implemented"); + } + + OptStrInt GetSignSpec(SignSpecItem itemType) { + TH_THROW(std::runtime_error, "GetSignSpec not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class AsyKeyGeneratorBySpecImpl { +public: + AsyKeyGeneratorBySpecImpl() { + // Don't forget to implement the constructor. + } + + KeyPair GenerateKeyPairSync() { + // 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(); + } + + PriKey GeneratePriKeySync() { + // 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(); + } + + PubKey GeneratePubKeySync() { + // 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"); + } +}; + +class KeyAgreementImpl { +public: + KeyAgreementImpl() { + // Don't forget to implement the constructor. + } + + DataBlob GenerateSecretSync(weak::PriKey priKey, weak::PubKey pubKey) { + TH_THROW(std::runtime_error, "GenerateSecretSync not implemented"); + } + + string GetAlgName() { + TH_THROW(std::runtime_error, "GetAlgName not implemented"); + } +}; + +class DHKeyUtilImpl { +public: + DHKeyUtilImpl() { + // Don't forget to implement the constructor. + } +}; + +class ECCKeyUtilImpl { +public: + ECCKeyUtilImpl() { + // Don't forget to implement the constructor. + } +}; + +class SM2CryptoUtilImpl { +public: + SM2CryptoUtilImpl() { + // Don't forget to implement the constructor. + } +}; + +class SignatureUtilsImpl { +public: + SignatureUtilsImpl() { + // Don't forget to implement the constructor. + } +}; + 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. @@ -174,7 +506,13 @@ Random CreateRandom() { return make_holder(); } -Mac CreateMac(string_view algName) { +Mac CreateMacByStr(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(); +} + +Mac CreateMacBySpec(OptExtMacSpec const& macSpec) { // 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(); @@ -185,9 +523,102 @@ SymKeyGenerator CreateSymKeyGenerator(string_view algName) { // as the parameters in the constructor of the actual implementation class. return make_holder(); } + +AsyKeyGenerator CreateAsyKeyGenerator(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(); +} + +Kdf CreateKdf(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(); +} + +Cipher CreateCipher(string_view transformation) { + // 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(); +} + +Verify CreateVerify(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(); +} + +Sign CreateSign(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(); +} + +AsyKeyGeneratorBySpec CreateAsyKeyGeneratorBySpec(OptAsyKeySpec const& asyKeySpec) { + // 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(); +} + +KeyAgreement CreateKeyAgreement(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(); +} + +DHCommonParamsSpec GenDHCommonParamsSpec(int32_t pLen, optional_view skLen) { + TH_THROW(std::runtime_error, "GenDHCommonParamsSpec not implemented"); +} + +ECCCommonParamsSpec GenECCCommonParamsSpec(string_view curveName) { + TH_THROW(std::runtime_error, "GenECCCommonParamsSpec not implemented"); +} + +Point ConvertPoint(string_view curveName, array_view encodedPoint) { + TH_THROW(std::runtime_error, "ConvertPoint not implemented"); +} + +array GetEncodedPoint(string_view curveName, Point const& point, string_view format) { + TH_THROW(std::runtime_error, "GetEncodedPoint not implemented"); +} + +DataBlob GenCipherTextBySpec(SM2CipherTextSpec const& spec, optional_view mode) { + TH_THROW(std::runtime_error, "GenCipherTextBySpec not implemented"); +} + +SM2CipherTextSpec GetCipherTextSpec(DataBlob const& cipherText, optional_view mode) { + TH_THROW(std::runtime_error, "GetCipherTextSpec not implemented"); +} + +EccSignatureSpec GenEccSignatureSpec(array_view data) { + TH_THROW(std::runtime_error, "GenEccSignatureSpec not implemented"); +} + +array GenEccSignature(EccSignatureSpec const& spec) { + TH_THROW(std::runtime_error, "GenEccSignature not implemented"); +} } // namespace +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN TH_EXPORT_CPP_API_CreateMd(CreateMd); TH_EXPORT_CPP_API_CreateRandom(CreateRandom); -TH_EXPORT_CPP_API_CreateMac(CreateMac); +TH_EXPORT_CPP_API_CreateMacByStr(CreateMacByStr); +TH_EXPORT_CPP_API_CreateMacBySpec(CreateMacBySpec); TH_EXPORT_CPP_API_CreateSymKeyGenerator(CreateSymKeyGenerator); +TH_EXPORT_CPP_API_CreateAsyKeyGenerator(CreateAsyKeyGenerator); +TH_EXPORT_CPP_API_CreateKdf(CreateKdf); +TH_EXPORT_CPP_API_CreateCipher(CreateCipher); +TH_EXPORT_CPP_API_CreateVerify(CreateVerify); +TH_EXPORT_CPP_API_CreateSign(CreateSign); +TH_EXPORT_CPP_API_CreateAsyKeyGeneratorBySpec(CreateAsyKeyGeneratorBySpec); +TH_EXPORT_CPP_API_CreateKeyAgreement(CreateKeyAgreement); +TH_EXPORT_CPP_API_GenDHCommonParamsSpec(GenDHCommonParamsSpec); +TH_EXPORT_CPP_API_GenECCCommonParamsSpec(GenECCCommonParamsSpec); +TH_EXPORT_CPP_API_ConvertPoint(ConvertPoint); +TH_EXPORT_CPP_API_GetEncodedPoint(GetEncodedPoint); +TH_EXPORT_CPP_API_GenCipherTextBySpec(GenCipherTextBySpec); +TH_EXPORT_CPP_API_GetCipherTextSpec(GetCipherTextSpec); +TH_EXPORT_CPP_API_GenEccSignatureSpec(GenEccSignatureSpec); +TH_EXPORT_CPP_API_GenEccSignature(GenEccSignature); +// NOLINTEND diff --git a/frameworks/js/ani/test/arktsconfig.json b/frameworks/js/ani/test/arktsconfig.json index 697340388f74caafb268c583bd4d2e5ad0947dad..75d080a5b371312491f1709212b6010801d8fdeb 100644 --- a/frameworks/js/ani/test/arktsconfig.json +++ b/frameworks/js/ani/test/arktsconfig.json @@ -17,5 +17,9 @@ }, "includes": [ "*.ets" + ], + "#files": [ + "./test_utils.ets", + "./test_main.ets" ] } diff --git a/frameworks/js/ani/test/build_test.sh b/frameworks/js/ani/test/build_test.sh new file mode 100644 index 0000000000000000000000000000000000000000..3bd49bc1d3dbcb392b708590da8e395280f703ce --- /dev/null +++ b/frameworks/js/ani/test/build_test.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# 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. + +set -e + +CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_PATH="$(cd "${CURRENT_DIR}/../../../../../../.." && pwd)" +BASE_PATH="${ROOT_PATH}/base/security/crypto_framework" +TEST_PATH="${BASE_PATH}/frameworks/js/ani/test" +OUT_PATH="${ROOT_PATH}/out/rk3568" +ABC_NAME="crypto_framework_test.abc" + +ES2PANDA="${OUT_PATH}/clang_x64/arkcompiler/ets_frontend/es2panda" +ARK_LINK="${OUT_PATH}/clang_x64/arkcompiler/runtime_core/ark_link" + +cd "${OUT_PATH}/security/crypto_framework" +"${ES2PANDA}" --arktsconfig "${TEST_PATH}/arktsconfig.json" --ets-module +"${ARK_LINK}" --output="${ABC_NAME}" -- "${TEST_PATH}/dist/"* +rm -rf "${TEST_PATH}/dist" + +echo -e "output abc file: \033[1;32m${OUT_PATH}/security/crypto_framework/${ABC_NAME}\033[0m" diff --git a/frameworks/js/ani/test/test_asy_key_generator.ets b/frameworks/js/ani/test/test_asy_key_generator.ets new file mode 100644 index 0000000000000000000000000000000000000000..77293747d95974f849dac5ccd9d80e88e5cf077c --- /dev/null +++ b/frameworks/js/ani/test/test_asy_key_generator.ets @@ -0,0 +1,241 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testAsyKeyGeneratorSync() { + try { + let generator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2'); + let keyPair = generator.generateKeyPairSync(); + let pubKey = keyPair.pubKey; + let priKey = keyPair.priKey; + let pkBlob = pubKey.getEncoded(); + let skBlob = priKey.getEncoded(); + let pkStr = utils.uint8ArrayToHexStr(pkBlob.data); + let skStr = utils.uint8ArrayToHexStr(skBlob.data); + console.println("AsyKeyGenerator algName: " + generator.algName); + console.println('generateKeyPair pubKey: ' + pkStr); + console.println('generateKeyPair priKey: ' + skStr); + priKey.clearMem(); + } catch (err: BusinessError) { + console.println(`[error] generateKeyPair: ${err.code} ${err.message}`); + } +} + +function testAsyKeyConvertKeySync() { + try { + let pubKeyArray = new Uint8Array([ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D, 0x03, 0x42, 0x00, 0x04, 0x5A, 0x03, 0x3A, 0x9D, 0xBE, + 0xF8, 0x4C, 0x07, 0x84, 0xC8, 0x97, 0xD0, 0x70, 0xE6, 0x60, 0x8C, 0x5A, 0xEE, 0xD3, 0x9B, 0x80, + 0x6D, 0xF8, 0x28, 0x53, 0xD6, 0x4E, 0x2A, 0x68, 0x6A, 0x37, 0x94, 0xF9, 0x23, 0x3D, 0x20, 0xDD, + 0x87, 0x8F, 0x64, 0x2D, 0x61, 0xC2, 0xB0, 0x34, 0x49, 0x88, 0xAE, 0x28, 0x46, 0x46, 0x22, 0x67, + 0x67, 0xA1, 0x63, 0x1B, 0xBB, 0x0D, 0xBB, 0x6D, 0xF4, 0x0D, 0x07 + ]); + let priKeyArray = new Uint8Array([ + 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0x36, 0x29, 0xEF, 0xF0, 0x3F, 0xBC, 0x86, 0x71, 0x1F, + 0x66, 0x95, 0xCB, 0xF5, 0x59, 0x0F, 0x0F, 0x2F, 0xCA, 0xAA, 0x3C, 0x26, 0x9A, 0x1C, 0xA9, 0xBD, + 0x64, 0xFB, 0x4C, 0x70, 0xDF, 0x9C, 0x9F, 0xA0, 0x0A, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, + 0x01, 0x82, 0x2D + ]); + let pubKeyBlob: cryptoFramework.DataBlob = { + data: pubKeyArray + }; + let priKeyBlob: cryptoFramework.DataBlob = { + data: priKeyArray + }; + let generator = cryptoFramework.createAsyKeyGenerator('SM2_256'); + let keyPair = generator.convertKeySync(pubKeyBlob, priKeyBlob); + let pubKey = keyPair.pubKey; + let priKey = keyPair.priKey; + let pkBlob = pubKey.getEncoded(); + let skBlob = priKey.getEncoded(); + let pkStr = utils.uint8ArrayToHexStr(pkBlob.data); + let skStr = utils.uint8ArrayToHexStr(skBlob.data); + console.println("AsyKeyGenerator algName: " + generator.algName); + console.println('convertKey pubKey: ' + pkStr); + console.println('convertKey priKey: ' + skStr); + priKey.clearMem(); + } catch (err: BusinessError) { + console.println(`[error] convertKey: ${err.code} ${err.message}`); + } +} + +function testConvertPemKeySync() { + try { + let priKeyPkcs1Str1024: string = + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIICXQIBAAKBgQCwIN3mr21+N96ToxnVnaS+xyK9cNRAHiHGgrbjHw6RAj3V+l+W\n" + + "Y68IhIe3DudVlzE9oMjeOQwkMkq//HCxNlIlFR6O6pa0mrXSwPRE7YKG97CeKk2g\n" + + "YOS8YEh8toAvm7xKbiLkXuuMlxrjP2j/mb5iI/UASFSPZiQ/IyxDr0AQaQIDAQAB\n" + + "AoGAEvBFzBNa+7J4PXnRQlYEK/tvsd0bBZX33ceacMubHl6WVZbphltLq+fMTBPP\n" + + "LjXmtpC+aJ7Lvmyl+wTi/TsxE9vxW5JnbuRT48rnZ/Xwq0eozDeEeIBRrpsr7Rvr\n" + + "7ctrgzr4m4yMHq9aDgpxj8IR7oHkfwnmWr0wM3FuiVlj650CQQDineeNZ1hUTkj4\n" + + "D3O+iCi3mxEVEeJrpqrmSFolRMb+iozrIRKuJlgcOs+Gqi2fHfOTTL7LkpYe8SVg\n" + + "e3JxUdVLAkEAxvcZXk+byMFoetrnlcMR13VHUpoVeoV9qkv6CAWLlbMdgf7uKmgp\n" + + "a1Yp3QPDNQQqkPvrqtfR19JWZ4uy1qREmwJALTU3BjyBoH/liqb6fh4HkWk75Som\n" + + "MzeSjFIOubSYxhq5tgZpBZjcpvUMhV7Zrw54kwASZ+YcUJvmyvKViAm9NQJBAKF7\n" + + "DyXSKrem8Ws0m1ybM7HQx5As6l3EVhePDmDQT1eyRbKp+xaD74nkJpnwYdB3jyyY\n" + + "qc7A1tj5J5NmeEFolR0CQQCn76Xp8HCjGgLHw9vg7YyIL28y/XyfFyaZAzzK+Yia\n" + + "akNwQ6NeGtXSsuGCcyyfpacHp9xy8qXQNKSkw03/5vDO\n" + + "-----END RSA PRIVATE KEY-----\n"; + let publicPkcs1Str1024: string = + "-----BEGIN RSA PUBLIC KEY-----\n" + + "MIGJAoGBALAg3eavbX433pOjGdWdpL7HIr1w1EAeIcaCtuMfDpECPdX6X5ZjrwiE\n" + + "h7cO51WXMT2gyN45DCQySr/8cLE2UiUVHo7qlrSatdLA9ETtgob3sJ4qTaBg5Lxg\n" + + "SHy2gC+bvEpuIuRe64yXGuM/aP+ZvmIj9QBIVI9mJD8jLEOvQBBpAgMBAAE=\n" + + "-----END RSA PUBLIC KEY-----\n"; + let generator = cryptoFramework.createAsyKeyGenerator('RSA1024'); + let keyPair = generator.convertPemKeySync(publicPkcs1Str1024, priKeyPkcs1Str1024); + let pubKey = keyPair.pubKey; + let priKey = keyPair.priKey; + let pkStr = pubKey.getEncodedPem('X509'); + let skStr = priKey.getEncodedPem('PKCS8'); + console.println("AsyKeyGenerator algName: " + generator.algName); + console.println('convertPemKey pubKey: ' + pkStr); + console.println('convertPemKey priKey: ' + skStr); + priKey.clearMem(); + } catch (err: BusinessError) { + console.println(`[error] convertPemKey: ${err.code} ${err.message}`); + } +} + +// ERROR: TypeError: Cannot find type 'AsyKeySpecItem'. +/* +function showEccSpecDetailInfo(keyName: string, key: cryptoFramework.PubKey | cryptoFramework.PriKey) { + console.println('showEccSpecDetailInfo ' + keyName + ':'); + let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); + console.println('a: ' + a); + let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); + console.println('b: ' + b); + let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); + console.println('gX: ' + gX); + let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); + console.println('gY: ' + gY); + let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); + console.println('n: ' + n); + let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); + console.println('h: ' + h); + let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); + console.println('fieldType: ' + fieldType); + let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); + console.println('fieldSize: ' + fieldSize); + let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); + console.println('curveName: ' + curveName); + if (keyName === 'pubKey') { + let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); + console.println('pkX: ' + pkX); + let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); + console.println('pkY: ' + pkY); + } else if (keyName === 'priKey') { + let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); + console.println('sk: ' + sk); + } +} +*/ + +function showPubKeyEccSpecDetailInfo(key: cryptoFramework.PubKey) { + console.println('showPubKeyEccSpecDetailInfo:'); + let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); + console.println('a: ' + a); + let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); + console.println('b: ' + b); + let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); + console.println('gX: ' + gX); + let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); + console.println('gY: ' + gY); + let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); + console.println('n: ' + n); + let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); + console.println('h: ' + h); + let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); + console.println('fieldType: ' + fieldType); + let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); + console.println('fieldSize: ' + fieldSize); + let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); + console.println('curveName: ' + curveName); + let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); + console.println('pkX: ' + pkX); + let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); + console.println('pkY: ' + pkY); +} + +function showPriKeyEccSpecDetailInfo(key: cryptoFramework.PriKey) { + console.println('showPriKeyEccSpecDetailInfo:'); + let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); + console.println('a: ' + a); + let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); + console.println('b: ' + b); + let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); + console.println('gX: ' + gX); + let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); + console.println('gY: ' + gY); + let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); + console.println('n: ' + n); + let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); + console.println('h: ' + h); + let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); + console.println('fieldType: ' + fieldType); + let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); + console.println('fieldSize: ' + fieldSize); + let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); + console.println('curveName: ' + curveName); + let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); + console.println('sk: ' + sk); +} + +function testAsyKeySpec() { + try { + let fieldFp: cryptoFramework.ECFieldFp = { + fieldType: 'Fp', + p: BigInt('26959946667150639794667015087019630673557916260026308143510066298881') + } + let G: cryptoFramework.Point = { + x: BigInt('19277929113566293071110308034699488026831934219452440156649784352033'), + y: BigInt('19926808758034470970197974370888749184205991990603949537637343198772') + } + let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { + algName: 'ECC', + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + field: fieldFp, + a: BigInt('26959946667150639794667015087019630673557916260026308143510066298878'), + b: BigInt('18958286285566608000408668544493926415504680968679321075787234672564'), + g: G, + n: BigInt('26959946667150639794667015087019625940457807714424391721682722368061'), + h: 1 + } + let generator = cryptoFramework.createAsyKeyGeneratorBySpec(eccCommonSpec); + let keyPair = generator.generateKeyPairSync(); + let pubKey = keyPair.pubKey; + let priKey = keyPair.priKey; + showPubKeyEccSpecDetailInfo(pubKey); + showPriKeyEccSpecDetailInfo(priKey); + } catch (err: BusinessError) { + console.println(`[error] AsyKeySpec: ${err.code} ${err.message}`); + } +} + +export function testAsyKeyGenerator() { + console.println(">>>>>>>>>>>>>>>>>>>> AsyKeyGeneratorSync"); + testAsyKeyGeneratorSync(); + console.println(">>>>>>>>>>>>>>>>>>>> AsyKeyConvertKeySync"); + testAsyKeyConvertKeySync(); + console.println(">>>>>>>>>>>>>>>>>>>> AsyKeyConvertPemKeySync"); + testConvertPemKeySync(); + console.println(">>>>>>>>>>>>>>>>>>>> AsyKeySpec"); + testAsyKeySpec(); +} diff --git a/frameworks/js/ani/test/test_asy_key_generator_by_spec.ets b/frameworks/js/ani/test/test_asy_key_generator_by_spec.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ee2996a364375688161d2ee918a87240f87a132 --- /dev/null +++ b/frameworks/js/ani/test/test_asy_key_generator_by_spec.ets @@ -0,0 +1,498 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testRsaKeyPairSpec() { + let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { + n: BigInt('18478533428762900543234234052165078897463517255891144687945154912560048989428973394502225231475673469493935673076685067666412374336644121661834634328568716128398010589214210242328473325052801924104401463496007910632384934591085795699377924655299831802536043790200563589400549497200957189436092639854513167455276408048482654440065204807879459064738847828290321155399964745065695320081378543586408514487910074079683525564599260683751683646405712006009189387522266386739458730786983547267804377576955002031599762775938196698277063712871930011053484489532696001735479019329660933285131374020059017332898114690445944576549'), + algName: "RSA", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + }; + let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = { + params: rsaCommSpec, + sk: BigInt('13443367797579784472906374191268730591149473415683261174245648123593551364374079107625793014808865760593273402148759743980757062361671347127799770055874205659183190363964544152829383091462724002309744989516180102276157076935260650085211862081846405192552335715817353665234496972306343601367818009443948359153845315745091050102576900263842800919302048139131982882174917741979278274761193212951786209086143141198926907682548667292864640458922412016755237410423934679056828519631212431348847746741608018079408263762113939943821319770453677716209206087481504965313847534151150635490465180371871825563931626039033876425137'), + pk: BigInt('65537'), + algName: "RSA", + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + }; + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get rsa key pair result success!'); + } else { + console.println('get rsa key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testRsaKeyPairSpec: ${err.code} ${err.message}`); + } +} + +function testRsaPubKeySpec() { + try { + let nIn = BigInt('18478533428762900543234234052165078897463517255891144687945154912560048989428973394502225231475673469493935673076685067666412374336644121661834634328568716128398010589214210242328473325052801924104401463496007910632384934591085795699377924655299831802536043790200563589400549497200957189436092639854513167455276408048482654440065204807879459064738847828290321155399964745065695320081378543586408514487910074079683525564599260683751683646405712006009189387522266386739458730786983547267804377576955002031599762775938196698277063712871930011053484489532696001735479019329660933285131374020059017332898114690445944576549'); + let eIn = BigInt('65537'); + let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { + n: nIn, + algName: 'RSA', + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC + }; + let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = { + params: rsaCommSpec, + pk: eIn, + algName: 'RSA', + specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC + }; + let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); + let pubKey = rsaGeneratorSpec.generatePubKeySync(); + if (pubKey !== null) { + console.println('get rsa pub key result success!'); + } else { + console.println('get rsa pub key result fail!'); + } + + } catch (err: BusinessError) { + console.println(`[error] testRsaPubKeySpec: ${err.code} ${err.message}`); + } +} + +function testEccCommonSpec() { + let fieldFp: cryptoFramework.ECFieldFp = { + fieldType: 'Fp', + p: BigInt('26959946667150639794667015087019630673557916260026308143510066298881') + } + let G: cryptoFramework.Point = { + x: BigInt('19277929113566293071110308034699488026831934219452440156649784352033'), + y: BigInt('19926808758034470970197974370888749184205991990603949537637343198772') + } + let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { + algName: 'ECC', + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + field: fieldFp, + a: BigInt('26959946667150639794667015087019630673557916260026308143510066298878'), + b: BigInt('18958286285566608000408668544493926415504680968679321075787234672564'), + g: G, + n: BigInt('26959946667150639794667015087019625940457807714424391721682722368061'), + h: 1 + } + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(eccCommonSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); // Generate an ECC key pair. + if (keyPair !== null) { + console.println('get key pair result success!'); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testEccCommonSpec: ${err.code} ${err.message}`); + } +} + +function genEccPriKeySpec(xIn: bigint, yIn: bigint, aIn: bigint, bIn: bigint, pIn: bigint, + nIn: bigint, skIn: bigint): cryptoFramework.ECCPriKeySpec { + let field: cryptoFramework.ECFieldFp = { + fieldType: "Fp", + p: pIn + }; + let g: cryptoFramework.Point = { + x: xIn, + y: yIn + }; + let params: cryptoFramework.ECCCommonParamsSpec = { + field: field, + a: aIn, + b: bIn, + g: g, + n: nIn, + h: 1, + algName: "ECC", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC + }; + + let eccPriKeySpec: cryptoFramework.ECCPriKeySpec = { + params: params, + sk: skIn, + algName: "ECC", + specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC + } + + return eccPriKeySpec; +} + +function testEccPriKeySpec() { + try { + let a: bigint = BigInt('26959946667150639794667015087019630673557916260026308143510066298878'); + let b: bigint = BigInt('18958286285566608000408668544493926415504680968679321075787234672564'); + let p: bigint = BigInt('26959946667150639794667015087019630673557916260026308143510066298881'); + let gX: bigint = BigInt('19277929113566293071110308034699488026831934219452440156649784352033'); + let gY: bigint = BigInt('19926808758034470970197974370888749184205991990603949537637343198772'); + let n: bigint = BigInt('26959946667150639794667015087019625940457807714424391721682722368061'); + let sk: bigint = BigInt('5958211279885070464920675858557961186290168537951857871398143937432'); + let eccPriKeySpec: cryptoFramework.ECCPriKeySpec = genEccPriKeySpec(gX, gY, a, b, p, n, sk); + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(eccPriKeySpec); + let priKey = generatorBySpec.generatePriKeySync(); + if (priKey !== null) { + console.println('get pri key result success!'); + } else { + console.println('get pri key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testEccPriKeySpec: ${err.code} ${err.message}`); + } +} + +function testSm2KeyPairSpec() { + let fieldFp: cryptoFramework.ECFieldFp = { + fieldType: 'Fp', + p: BigInt('115792089210356248756420345214020892766250353991924191454421193933289684991999') + } + let G: cryptoFramework.Point = { + x: BigInt('22963146547237050559479531362550074578802567295341616970375194840604139615431'), + y: BigInt('85132369209828568825618990617112496413088388631904505083283536607588877201568') + }; + let sm2CommonParamsSpec: cryptoFramework.ECCCommonParamsSpec = { + algName: 'SM2', + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + field: fieldFp, + a: BigInt('115792089210356248756420345214020892766250353991924191454421193933289684991996'), + b: BigInt('18505919022281880113072981827955639221458448578012075254857346196103069175443'), + g: G, + n: BigInt('115792089210356248756420345214020892766061623724957744567843809356293439045923'), + h: 1 + }; + let sm2KeyPairSpec: cryptoFramework.ECCKeyPairSpec = { + algName: "SM2", + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + params: sm2CommonParamsSpec, + sk: BigInt('44865034034753528279576865928075303946258226058363947036220155068824166297716'), + pk: { + x: BigInt('47018839338924435050110785031351759007822306695053504711021879526595239871172'), + y: BigInt('96133091491756192384849037905113087024675932328759814704074462890629083635825') + }, + }; + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(sm2KeyPairSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get key pair result success!'); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testSm2AsyKeyGeneratorBySpecSync: ${err.code} ${err.message}`); + } +} + +function getDsaCommonParamsSpec() { + let dsaCommonSpec: cryptoFramework.DSACommonParamsSpec = { + algName: "DSA", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + p: BigInt('20216857044408199932376494764599580727974045843915439721502938327198864725169044809813204952147752413624701213316563574475039748055346468178028625826092035313601316397655587341814674633664886284528623285325653023780498382484985239780177599233965758919159102159171718273864148712746797113414042595739717319731696609579150841956081703573371531465350272238016149836326224001841088360384367898447054044508716751610019070103182911963258176168025828573385356097755187338108832184592810352254309012721096301415240345204182050921863355546837078288047550266434252240460770780823402663658159753063957196734025229736568089530267'), + q: BigInt("867213547744821940284222002039163947454712583963"), + g: BigInt('5613702672530613039214328932450936898231965110898797142283557379865685939526291625923546497805448201404435739446597666135884235480978009652818140400499199787725528596067079382996609708472937555140407402057536621734502472274147757401975812355605352555485852816071445663853971471514294654628089019755771069636793509413303062371896404562622361502073164175883230960631373093173990688756272270068057277748993274083763062285503458176853646465605466871218985585055660513268314836972803355963121806305145618647016398490455324285041057243421484005529145312291069828934043829252492089834817718429184649225777566648238469211448'), + } + return dsaCommonSpec; +} + +function testDsaKeyPairSpec() { + let dsaCommonSpec = getDsaCommonParamsSpec(); + let dsaKeyPairSpec: cryptoFramework.DSAKeyPairSpec = { + algName: "DSA", + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + params: dsaCommonSpec, + sk: BigInt("287759317661555678461170451498783134028435263911"), + pk: BigInt('2974320683131303383593011718103778438067248821010128068603330890682877434550441281827351603361334506610914048116228047158214093207291532728181748676811787843316027859373324322706845202765204260289964362553170484033902517855022371250354897430992714094652148720967777508481265194493537489752556929433399052957551421373353304195295773950194626096020536543310165869112300390873999312126377909122302697760566740696966174036865456319235321580616931347110147760623816495949862659419251353007558185295016129505360845025009080058771674461404631229857893492589646335484050582997233310521320078311463229120799046072712830367694'), + }; + try { + let asyKeyPairSpec = cryptoFramework.createAsyKeyGeneratorBySpec(dsaKeyPairSpec); + let keyPair = asyKeyPairSpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get key pair result success!'); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] getDsaCommonParamsSpec: ${err.code} ${err.message}`); + } +} + +function testDsaPubKeySpec() { + let dsaCommonSpec = getDsaCommonParamsSpec(); + let dsaPubKeySpec: cryptoFramework.DSAPubKeySpec = { + algName: "DSA", + specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC, + params: dsaCommonSpec, + pk: BigInt('2974320683131303383593011718103778438067248821010128068603330890682877434550441281827351603361334506610914048116228047158214093207291532728181748676811787843316027859373324322706845202765204260289964362553170484033902517855022371250354897430992714094652148720967777508481265194493537489752556929433399052957551421373353304195295773950194626096020536543310165869112300390873999312126377909122302697760566740696966174036865456319235321580616931347110147760623816495949862659419251353007558185295016129505360845025009080058771674461404631229857893492589646335484050582997233310521320078311463229120799046072712830367694'), + }; + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(dsaPubKeySpec); + let pubKey = generatorBySpec.generatePubKeySync(); + if (pubKey !== null) { + console.println('get pub key result success!'); + } else { + console.println('get pub key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testDsaPubKeySpec: ${err.code} ${err.message}`); + } +} + +function testX25519Keypair() { + let X25519CommonParamsSpec: cryptoFramework.X25519KeyPairSpec = { + algName: 'X25519', + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + sk: BigInt("29134879258262849023515049744816060961199782584720683500454612335506387469072"), + pk: BigInt("31365230504828109670384793213724615431161708201306102578527937807624152602700") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(X25519CommonParamsSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get key pair result success!'); + let pkBlob = keyPair.pubKey.getEncoded(); + let skBlob = keyPair.priKey.getEncoded(); + let pkStr = utils.uint8ArrayToHexStr(pkBlob.data); + let skStr = utils.uint8ArrayToHexStr(skBlob.data); + console.println('pub key: ' + pkStr); + console.println('pri key: ' + skStr); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testX25519Keypair: ${err.code} ${err.message}`); + } +} + +function testX25519PubKeySpec() { + let X25519CommonParamsSpec: cryptoFramework.X25519PubKeySpec = { + algName: 'X25519', + specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC, + pk: BigInt("31365230504828109670384793213724615431161708201306102578527937807624152602700") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(X25519CommonParamsSpec); + let pubKey = generatorBySpec.generatePubKeySync(); + if (pubKey !== null) { + console.println('get pub key result success!'); + } else { + console.println('get pub key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testX25519PubKeySpec: ${err.code} ${err.message}`); + } +} + +function testX25519PriKeySpec() { + let X25519CommonParamsSpec: cryptoFramework.X25519PriKeySpec = { + algName: 'X25519', + specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC, + sk: BigInt("29134879258262849023515049744816060961199782584720683500454612335506387469072") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(X25519CommonParamsSpec); + let priKey = generatorBySpec.generatePriKeySync(); + if (priKey !== null) { + console.println('get pri key result success!'); + } else { + console.println('get pri key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testX25519PriKeySpec: ${err.code} ${err.message}`); + } +} + +function testEd25519Keypair() { + let ed25519CommonParamsSpec: cryptoFramework.ED25519KeyPairSpec = { + algName: 'Ed25519', + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + sk: BigInt("43647624700350065415986689228612485845309737963740022737531181108678917972381"), + pk: BigInt("11904025543770991234575058927481377460341025403748801838533672290029823089367") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(ed25519CommonParamsSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get key pair result success!'); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testEd25519Keypair: ${err.code} ${err.message}`); + } +} + +function testEd25519PubKeySpec() { + let ed25519CommonParamsSpec: cryptoFramework.ED25519PubKeySpec = { + algName: 'Ed25519', + specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC, + pk: BigInt("11904025543770991234575058927481377460341025403748801838533672290029823089367") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(ed25519CommonParamsSpec); + let pubKey = generatorBySpec.generatePubKeySync(); + if (pubKey !== null) { + console.println('get pub key result success!'); + } else { + console.println('get pub key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testEd25519PubKeySpec: ${err.code} ${err.message}`); + } +} + +function testEd25519PriKeySpec() { + let ed25519CommonParamsSpec: cryptoFramework.ED25519PriKeySpec = { + algName: 'Ed25519', + specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC, + sk: BigInt("43647624700350065415986689228612485845309737963740022737531181108678917972381") + }; + + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(ed25519CommonParamsSpec); + let priKey = generatorBySpec.generatePriKeySync(); + if (priKey !== null) { + console.println('get pri key result success!'); + } else { + console.println('get pri key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testEd25519PriKeySpec: ${err.code} ${err.message}`); + } +} + +function testDhKeyPairSpec() { + let dhCommonParamsSpec: cryptoFramework.DHCommonParamsSpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + p: BigInt("32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559"), + g: BigInt("2"), + l: 0 + } + let dhKeyPairSpec: cryptoFramework.DHKeyPairSpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, + params: dhCommonParamsSpec, + sk: BigInt("9125804188382698099196638873877782224672995953990412992193262858452"), + pk: BigInt("11186379976064470039868881878113769238712700906887300917098479964653512172113576763135554305151065797508933293770633594570926859095962764040640418979407741972148004696002324963207972460619492683808125462174028180856400991828519744547190389466471420338820024463169406721124154332160520586677979673497445849107467994302619965190756490288108819919869861215042849364387924978117630413281355079408669272089515824403370917658313427949840680278654651434802556809089942821560326598440829155965101298935067032294104326983788672385588749202093591460978545538061369828131252628133733300047966728872928488819485461523493709658652"), + } + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(dhKeyPairSpec); + let keyPair = generatorBySpec.generateKeyPairSync(); + if (keyPair !== null) { + console.println('get key pair result success!'); + } else { + console.println('get key pair result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testDhKeyPairSpec: ${err.code} ${err.message}`); + } +} + +function testDhPubKeySpec() { + let dhCommonParamsSpec: cryptoFramework.DHCommonParamsSpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + p: BigInt("32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559"), + g: BigInt("2"), + l: 0 + } + let dhPubKeySpec: cryptoFramework.DHPubKeySpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC, + params: dhCommonParamsSpec, + pk: BigInt("11186379976064470039868881878113769238712700906887300917098479964653512172113576763135554305151065797508933293770633594570926859095962764040640418979407741972148004696002324963207972460619492683808125462174028180856400991828519744547190389466471420338820024463169406721124154332160520586677979673497445849107467994302619965190756490288108819919869861215042849364387924978117630413281355079408669272089515824403370917658313427949840680278654651434802556809089942821560326598440829155965101298935067032294104326983788672385588749202093591460978545538061369828131252628133733300047966728872928488819485461523493709658652"), + } + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(dhPubKeySpec); + let pubKey = generatorBySpec.generatePubKeySync(); + if (pubKey !== null) { + console.println('get pub key result success!'); + } else { + console.println('get pub key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testDhPubKeySpec: ${err.code} ${err.message}`); + } +} + +function testDhPriKeySpec() { + let dhCommonParamsSpec: cryptoFramework.DHCommonParamsSpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, + p: BigInt("32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559"), + g: BigInt("2"), + l: 0 + } + let dhPriKeySpec: cryptoFramework.DHPriKeySpec = { + algName: "DH", + specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC, + params: dhCommonParamsSpec, + sk: BigInt("9125804188382698099196638873877782224672995953990412992193262858452"), + } + try { + let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(dhPriKeySpec); + let priKey = generatorBySpec.generatePriKeySync(); + if (priKey !== null) { + console.println('get pri key result success!'); + } else { + console.println('get pri key result fail!'); + } + } catch (err: BusinessError) { + console.println(`[error] testDhPriKeySpec: ${err.code} ${err.message}`); + } +} + +export function testAsyKeyGeneratorBySpec() { + console.println(">>>>>>>>>>>>>>>>>>>> EccCommonSpec"); + testEccCommonSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> EccPriKeySpec"); + testEccPriKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> Sm2KeyPairSpec"); + testSm2KeyPairSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> DsaKeyPairSpec"); + testDsaKeyPairSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> DsaPubKeySpec"); + testDsaPubKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> RsaKeyPairSpec"); + testRsaKeyPairSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> RsaPubKeySpec"); + testRsaPubKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> X25519Keypair"); + testX25519Keypair(); + console.println(">>>>>>>>>>>>>>>>>>>> X25519PubKeySpec"); + testX25519PubKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> X25519PriKeySpec"); + testX25519PriKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> Ed25519Keypair"); + testEd25519Keypair(); + console.println(">>>>>>>>>>>>>>>>>>>> Ed25519PubKeySpec"); + testEd25519PubKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> Ed25519PriKeySpec"); + testEd25519PriKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> DhKeyPairSpec"); + testDhKeyPairSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> DhPubKeySpec"); + testDhPubKeySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> DhPriKeySpec"); + testDhPriKeySpec(); +} diff --git a/frameworks/js/ani/test/test_cipher.ets b/frameworks/js/ani/test/test_cipher.ets new file mode 100644 index 0000000000000000000000000000000000000000..4f8c0f1bc9231baf8462e4ebb5b88f30d1afa744 --- /dev/null +++ b/frameworks/js/ani/test/test_cipher.ets @@ -0,0 +1,150 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function generateRandom(len: int) { + let rand = cryptoFramework.createRandom(); + let generater = rand.generateRandomSync(len); + return generater; +} + +function genSymKeyByData(symKeyData: Uint8Array) { + let symKeyBlob: cryptoFramework.DataBlob = { + data: symKeyData + }; + let generator = cryptoFramework.createSymKeyGenerator('AES128'); + let symKey = generator.convertKeySync(symKeyBlob); + return symKey; +} + +function encrypt(algorithm: string, symKey: cryptoFramework.SymKey, data: cryptoFramework.DataBlob, + params: cryptoFramework.GcmParamsSpec | cryptoFramework.CcmParamsSpec | cryptoFramework.IvParamsSpec | null +): cryptoFramework.DataBlob { + let cipher = cryptoFramework.createCipher(algorithm); + console.println("Cipher algName: " + cipher.algName); + cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, params); + if (algorithm.includes('GCM') || algorithm.includes('CCM')) { + let encryptData = cipher.updateSync(data); + if (algorithm.includes('GCM')) { + (params as cryptoFramework.GcmParamsSpec).authTag = cipher.doFinalSync(null); + } else if (algorithm.includes('CCM')) { + (params as cryptoFramework.CcmParamsSpec).authTag = cipher.doFinalSync(null); + } + return encryptData; + } else { // CBC/ECB + return cipher.doFinalSync(data); + } +} + +function decrypt(algorithm: string, symKey: cryptoFramework.SymKey, data: cryptoFramework.DataBlob, + params: cryptoFramework.GcmParamsSpec | cryptoFramework.CcmParamsSpec | cryptoFramework.IvParamsSpec | null +): cryptoFramework.DataBlob { + let decoder = cryptoFramework.createCipher(algorithm); + decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, params); + if (algorithm.includes('GCM')) { + let decryptData = decoder.updateSync(data); + decoder.doFinalSync(null); + return decryptData; + } else if (algorithm.includes('CCM')) { + return decoder.doFinalSync(data); + } else { // CBC/ECB + return decoder.doFinalSync(data); + } +} + +function aesCipher(algorithm: string, + params: cryptoFramework.GcmParamsSpec | cryptoFramework.CcmParamsSpec | cryptoFramework.IvParamsSpec | null) { + try { + let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); + let symKey = genSymKeyByData(keyData); + let message = "This is a test"; + let plainText: cryptoFramework.DataBlob = { + data: utils.stringToUint8Array(message) + }; + let encryptText = encrypt(algorithm, symKey, plainText, params); + let decryptText = decrypt(algorithm, symKey, encryptText, params); + if (plainText.data.toString() === decryptText.data.toString()) { + console.println(`${algorithm} success`); + } else { + console.println(`${algorithm} failed`); + } + } catch (err: BusinessError) { + console.println(`[error] ${algorithm}: ${err.code} ${err.message}`); + } +} + +function testAesGcmSync() { + let params: cryptoFramework.GcmParamsSpec = { + algName: "GcmParamsSpec", + iv: generateRandom(12), + aad: generateRandom(8), + authTag: generateRandom(16), + }; + aesCipher('AES128|GCM|PKCS7', params); +} + +function testAesCcmSync() { + let params: cryptoFramework.CcmParamsSpec = { + algName: "CcmParamsSpec", + iv: generateRandom(7), + aad: generateRandom(8), + authTag: generateRandom(12), + }; + aesCipher('AES128|CCM', params); +} + +function testAesCbcSync() { + let params: cryptoFramework.IvParamsSpec = { + algName: "IvParamsSpec", + iv: generateRandom(16), + }; + aesCipher('AES128|CBC|PKCS7', params); +} + +function testAesEcbSync() { + aesCipher('AES128|ECB|PKCS7', null); +} + +function testCipherSpec() { + try { + let spec = new Uint8Array([0x01, 0x02, 0x03, 0x04]); + let cipher = cryptoFramework.createCipher("RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1"); + cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, spec); + let mgf1Psrc = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR); + let mgfName = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR); + let mdName = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR); + console.println("CipherSpec Uint8Array: " + mgf1Psrc.toString()); + console.println("CipherSpec mgfName: " + mgfName); + console.println("CipherSpec mdName: " + mdName); + } catch (err: BusinessError) { + console.println(`[error] CipherSpec: ${err.code} ${err.message}`); + } +} + +export function testCipher() { + console.println(">>>>>>>>>>>>>>>>>>>> AesGcmSync"); + testAesGcmSync(); + console.println(">>>>>>>>>>>>>>>>>>>> AesCcmSync"); + testAesCcmSync(); + console.println(">>>>>>>>>>>>>>>>>>>> AesCbcSync"); + testAesCbcSync(); + console.println(">>>>>>>>>>>>>>>>>>>> AesEcbSync"); + testAesEcbSync(); + console.println(">>>>>>>>>>>>>>>>>>>> CipherSpec"); + testCipherSpec(); +} diff --git a/frameworks/js/ani/test/test_dh_key_util.ets b/frameworks/js/ani/test/test_dh_key_util.ets new file mode 100644 index 0000000000000000000000000000000000000000..7aaa47c72ba9a332814dcca925fd759b24156549 --- /dev/null +++ b/frameworks/js/ani/test/test_dh_key_util.ets @@ -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. + */ + +import { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testGenDHCommonParamsSpec() { + try { + let spec = cryptoFramework.DHKeyUtil.genDHCommonParamsSpec(2048, 1024); + console.println("DHKeyUtil.genDHCommonParamsSpec:"); + console.println("DHCommonParamsSpec spec.algName: " + spec.algName); + console.println("DHCommonParamsSpec spec.specType: " + spec.specType); + console.println("DHCommonParamsSpec spec.p: " + spec.p); + console.println("DHCommonParamsSpec spec.g: " + spec.g); + console.println("DHCommonParamsSpec spec.l: " + spec.l); + } catch (err: BusinessError) { + console.println(`[error] DHKeyUtil.genDHCommonParamsSpec: ${err.code} ${err.message}`); + } +} + +export function testDHKeyUtil() { + console.println(">>>>>>>>>>>>>>>>>>>> GenDHCommonParamsSpec"); + testGenDHCommonParamsSpec(); +} diff --git a/frameworks/js/ani/test/test_ecc_key_util.ets b/frameworks/js/ani/test/test_ecc_key_util.ets new file mode 100644 index 0000000000000000000000000000000000000000..ca3db7a32d35aeba9e9e805402fb57dd68226839 --- /dev/null +++ b/frameworks/js/ani/test/test_ecc_key_util.ets @@ -0,0 +1,79 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testGenECCCommonParamsSpec() { + try { + let spec = cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_brainpoolP256r1'); + let ecFiledFp = spec.field as cryptoFramework.ECFieldFp; + console.println("ECCKeyUtil.genECCCommonParamsSpec:"); + console.println("ECCCommonParamsSpec spec.algName: " + spec.algName); + console.println("ECCCommonParamsSpec spec.specType: " + spec.specType); + console.println("ECCCommonParamsSpec spec.field.fieldType: " + ecFiledFp.fieldType); + console.println("ECCCommonParamsSpec spec.field.p: " + ecFiledFp.p); + console.println("ECCCommonParamsSpec spec.a: " + spec.a); + console.println("ECCCommonParamsSpec spec.b: " + spec.b); + console.println("ECCCommonParamsSpec spec.g.x: " + spec.g.x); + console.println("ECCCommonParamsSpec spec.g.y: " + spec.g.y); + console.println("ECCCommonParamsSpec spec.n: " + spec.n); + console.println("ECCCommonParamsSpec spec.h: " + spec.h); + } catch (err: BusinessError) { + console.println(`[error] ECCKeyUtil.genECCCommonParamsSpec: ${err.code} ${err.message}`); + } +} + +function testConvertPoint() { + try { + let pkData = new Uint8Array([ + 0x04, 0x8F, 0x27, 0x39, 0xF9, 0x91, 0x32, 0x3F, 0xDE, 0x23, 0x46, 0xB2, 0x79, 0xCA, 0x9A, 0x15, + 0x92, 0x81, 0x4B, 0x4C, 0x3F, 0x08, 0xC3, 0x9D, 0x6F, 0x28, 0xD9, 0xD7, 0x94, 0x78, 0xE0, 0xCD, + 0x52, 0x53, 0x5C, 0xB9, 0x15, 0xD3, 0xB8, 0x05, 0x13, 0x72, 0x21, 0x56, 0x55, 0xE4, 0x7B, 0xF2, + 0xCE, 0xC8, 0x62, 0xB2, 0xB8, 0x82, 0x23, 0xE8, 0x2D, 0x05, 0xCA, 0xBD, 0x0B, 0x2E, 0xA3, 0x9C, + 0x98 + ]); + let point = cryptoFramework.ECCKeyUtil.convertPoint('NID_brainpoolP256r1', pkData); + console.println("ECCKeyUtil.convertPoint:"); + console.println("Point point.x: " + point.x); + console.println("Point point.y: " + point.y); + } catch (err: BusinessError) { + console.println(`[error] ECCKeyUtil.convertPoint: ${err.code} ${err.message}`); + } +} + +function testGetEncodedPoint() { + try { + let point: cryptoFramework.Point = { + x: BigInt('64750044510792891439269945828433327517677381559622384455951527515863444933970'), + y: BigInt('37705793773900352766227640862738381713868374157045352837992005507978837073048') + }; + let encoded = cryptoFramework.ECCKeyUtil.getEncodedPoint('NID_brainpoolP256r1', point, 'COMPRESSED'); + console.println("ECCKeyUtil.getEncodedPoint:"); + console.println("Uint8Array encoded: " + encoded); + } catch (err: BusinessError) { + console.println(`[error] ECCKeyUtil.getEncodedPoint: ${err.code} ${err.message}`); + } +} + +export function testECCKeyUtil() { + console.println(">>>>>>>>>>>>>>>>>>>> GenECCCommonParamsSpec"); + testGenECCCommonParamsSpec(); + console.println(">>>>>>>>>>>>>>>>>>>> ConvertPoint"); + testConvertPoint(); + console.println(">>>>>>>>>>>>>>>>>>>> GetEncodedPoint"); + testGetEncodedPoint(); +} diff --git a/frameworks/js/ani/test/test_kdf.ets b/frameworks/js/ani/test/test_kdf.ets new file mode 100644 index 0000000000000000000000000000000000000000..14e2c1b494b39fa40636a78e9c14abd531778976 --- /dev/null +++ b/frameworks/js/ani/test/test_kdf.ets @@ -0,0 +1,88 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testPBKDF2Sync() { + try { + let spec: cryptoFramework.PBKDF2Spec = { + algName: 'PBKDF2', + password: utils.stringToUint8Array("123456"), + salt: utils.stringToUint8Array("0123456789"), + iterations: 10000, + keySize: 32, + }; + let kdf = cryptoFramework.createKdf('PBKDF2|SHA256'); + let secret = kdf.generateSecretSync(spec); + let str = utils.uint8ArrayToHexStr(secret.data); + console.println("PBKDF2 algName: " + kdf.algName); + console.println("PBKDF2: " + str); + } + catch (err: BusinessError) { + console.println(`[error] PBKDF2: ${err.code} ${err.message}`); + } +} + +function testHKDFSync() { + try { + let spec: cryptoFramework.HKDFSpec = { + algName: 'HKDF', + key: utils.stringToUint8Array("012345678901234567890123456789"), + salt: utils.stringToUint8Array("0123456789"), + info: utils.stringToUint8Array("infostring"), + keySize: 32, + }; + let kdf = cryptoFramework.createKdf('HKDF|SHA256|EXTRACT_AND_EXPAND'); + let secret = kdf.generateSecretSync(spec); + let str = utils.uint8ArrayToHexStr(secret.data); + console.println("HKDF algName: " + kdf.algName); + console.println("HKDF: " + str); + } catch (err: BusinessError) { + console.println(`[error] HKDF: ${err.code} ${err.message}`); + } +} + +function testScryptSync() { + try { + let spec: cryptoFramework.ScryptSpec = { + algName: 'SCRYPT', + passphrase: "123456", + salt: utils.stringToUint8Array("0123456789"), + n: 1024, + p: 16, + r: 8, + maxMemory: 1024 * 16 * 8 * 10, // n * p * r * 10 + keySize: 64, + }; + let kdf = cryptoFramework.createKdf('SCRYPT'); + let secret = kdf.generateSecretSync(spec); + let str = utils.uint8ArrayToHexStr(secret.data); + console.println("Scrypt algName: " + kdf.algName); + console.println("Scrypt: " + str); + } catch (err: BusinessError) { + console.println(`[error] Scrypt: ${err.code} ${err.message}`); + } +} + +export function testKdf() { + console.println(">>>>>>>>>>>>>>>>>>>> PBKDF2Sync"); + testPBKDF2Sync(); + console.println(">>>>>>>>>>>>>>>>>>>> HKDFSync"); + testHKDFSync(); + console.println(">>>>>>>>>>>>>>>>>>>> ScryptSync"); + testScryptSync(); +} diff --git a/frameworks/js/ani/test/test_key_agreement.ets b/frameworks/js/ani/test/test_key_agreement.ets new file mode 100644 index 0000000000000000000000000000000000000000..7291fc3d029d8f97ab0521dd69ac528928d99533 --- /dev/null +++ b/frameworks/js/ani/test/test_key_agreement.ets @@ -0,0 +1,59 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testKeyAgreementSync() +{ + try { + let pubKeyArray = new Uint8Array([ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x53, 0x60, 0x8E, 0x09, 0x56, + 0xD6, 0x7E, 0x6A, 0xF7, 0xE9, 0x5C, 0x7D, 0x04, 0x80, 0x8A, 0x69, 0xF6, 0xA2, 0xD7, 0x47, 0x51, + 0x3A, 0xCA, 0x79, 0x1A, 0x69, 0xD3, 0x37, 0x82, 0x2D, 0xEC, 0x8F, 0x37, 0x10, 0xF8, 0x4B, 0xA7, + 0xA0, 0xA7, 0x6A, 0x02, 0x98, 0xF3, 0x2C, 0x44, 0x42, 0x00, 0xA7, 0x63, 0x5C, 0xEB, 0xD7, 0x9F, + 0xEF, 0x1C, 0x6A, 0x7C, 0xAB, 0x22, 0x91, 0x7C, 0xAE, 0x39, 0x5C + ]); + let priKeyArray = new Uint8Array([ + 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0x73, 0x38, 0x89, 0x23, 0xCF, 0x00, 0x3C, 0xBF, 0x5A, + 0x3D, 0x88, 0x69, 0xD2, 0x10, 0x1B, 0x04, 0xAB, 0x39, 0x0A, 0x3D, 0x7B, 0x28, 0xBD, 0x1C, 0x22, + 0xCF, 0xEC, 0x16, 0x2D, 0xDF, 0x0A, 0xBD, 0xA0, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07 + ]); + let generator = cryptoFramework.createAsyKeyGenerator('ECC256'); + let keyPairA = generator.convertKeySync({ data: pubKeyArray }, { data: priKeyArray }); + let keyPairB = generator.generateKeyPairSync(); + let keyAgreement = cryptoFramework.createKeyAgreement('ECC256'); + console.println("KeyAgreement algName: " + keyAgreement.algName); + let secret1 = keyAgreement.generateSecretSync(keyPairA.priKey, keyPairB.pubKey); + let secret2 = keyAgreement.generateSecretSync(keyPairB.priKey, keyPairA.pubKey); + if (secret1.data.toString() === secret2.data.toString()) { + console.println('KeyAgreement ecdh result success'); + console.println('KeyAgreement ecdh secret.data: ' + utils.uint8ArrayToHexStr(secret1.data)); + } else { + console.println('KeyAgreement ecdh result failed'); + } + } catch (err: BusinessError) { + console.println(`[error] KeyAgreement: ${err.code} ${err.message}`); + } +} + +export function testKeyAgreement() +{ + console.println(">>>>>>>>>>>>>>>>>>>> KeyAgreementSync"); + testKeyAgreementSync(); +} diff --git a/frameworks/js/ani/test/test_mac.ets b/frameworks/js/ani/test/test_mac.ets index 69f74d5243426eb6e3008160188079df9df52318..7932c2c222b8bea4d5cc92427f5c4fb283acb565 100644 --- a/frameworks/js/ani/test/test_mac.ets +++ b/frameworks/js/ani/test/test_mac.ets @@ -13,29 +13,67 @@ * limitations under the License. */ +import { BusinessError } from "@ohos.base"; import cryptoFramework from "@ohos.security.cryptoFramework"; import utils from "./test_utils"; -export function testMac() { +function testMacSync() { try { - let key = "1234567890"; - let keyBytes = utils.hexStrToUint8Array(key); + let key = "12345678abcdefgh"; let data = "Hello World"; + let keyBytes = utils.stringToUint8Array(key); let dataBytes = utils.stringToUint8Array(data); - let symKey = cryptoFramework.createSymKeyGenerator("HMAC").convertKeySync({ + let generator = cryptoFramework.createSymKeyGenerator("AES128"); + let symKey = generator.convertKeySync({ data: keyBytes }); - let mac = cryptoFramework.createMac("SHA256"); + let spec: cryptoFramework.CmacSpec = { + algName: "CMAC", + cipherName: "AES128", + }; + let mac = cryptoFramework.createMac(spec); 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); + console.println("CMAC algName: " + mac.algName); + console.println("CMAC-AES128: " + str); } - catch (err) { - console.error("HMAC-SHA256: " + err) + catch (err: BusinessError) { + console.println(`[error] CMAC-AES128: ${err.code} ${err.message}`); } } + +function testMacAsync() { + try { + let key = "1234567890"; + let data = "Hello World"; + let keyBytes = utils.hexStrToUint8Array(key); + let dataBytes = utils.stringToUint8Array(data);; + let generator = cryptoFramework.createSymKeyGenerator("HMAC"); + let symKey = await generator.convertKey({ + data: keyBytes + }); + let mac = cryptoFramework.createMac("SHA256"); + await mac.init(symKey); + await mac.update({ + data: dataBytes + }); + let output = await mac.doFinal(); + let str = utils.uint8ArrayToHexStr(output.data); + console.println("HMAC algName: " + mac.algName); + console.println("HMAC-SHA256: " + str); + } + catch (err: BusinessError) { + console.println(`[error] HMAC-SHA256: ${err.code} ${err.message}`); + } +} + +export function testMac() { + console.println(">>>>>>>>>>>>>>>>>>>> MacSync"); + testMacSync(); + console.println(">>>>>>>>>>>>>>>>>>>> MacAsync"); + testMacAsync(); +} diff --git a/frameworks/js/ani/test/test_main.ets b/frameworks/js/ani/test/test_main.ets index 616b5c3cad3eca2fe041be07f294068b803fbd55..eabb66be738ba7928837857eeaa3dc9a04d37cc9 100644 --- a/frameworks/js/ani/test/test_main.ets +++ b/frameworks/js/ani/test/test_main.ets @@ -13,12 +13,38 @@ * limitations under the License. */ -import { testMd } from "./test_md"; +import utils from "./test_utils"; import { testRandom } from "./test_rand"; +import { testMd } from "./test_md"; import { testMac } from "./test_mac"; +import { testKdf } from "./test_kdf"; +import { testAsyKeyGenerator } from "./test_asy_key_generator"; +import { testSymKeyGenerator } from "./test_sym_key_generator"; +import { testAsyKeyGeneratorBySpec } from "./test_asy_key_generator_by_spec"; +import { testCipher } from "./test_cipher"; +import { testSign } from "./test_sign"; +import { testVerify } from "./test_verify"; +import { testKeyAgreement } from "./test_key_agreement"; +import { testDHKeyUtil } from "./test_dh_key_util"; +import { testECCKeyUtil } from "./test_ecc_key_util"; +import { testSM2CryptoUtil } from "./test_sm2_crypto_util"; function main() { - testMac(); - testMd(); testRandom(); + testMd(); + testMac(); + testKdf(); + testAsyKeyGenerator(); + testSymKeyGenerator(); + testAsyKeyGeneratorBySpec(); + testCipher(); + testSign(); + testVerify(); + testKeyAgreement(); + testDHKeyUtil(); + testECCKeyUtil(); + testSM2CryptoUtil(); + + utils.doFullGC(); + utils.stopTaskPool(); } diff --git a/frameworks/js/ani/test/test_md.ets b/frameworks/js/ani/test/test_md.ets index e2f7949787459a31839bdc5a52306af40214ffb0..1e2e80271cf23c9217d0d49a5b8dcac4fb545951 100644 --- a/frameworks/js/ani/test/test_md.ets +++ b/frameworks/js/ani/test/test_md.ets @@ -13,23 +13,50 @@ * limitations under the License. */ +import { BusinessError } from "@ohos.base"; import cryptoFramework from "@ohos.security.cryptoFramework"; import utils from "./test_utils"; -export function testMd() { +function testMdSync() { try { - let md = cryptoFramework.createMd("MD5"); let data = "Hello World"; let dataBytes = utils.stringToUint8Array(data); + let md = cryptoFramework.createMd("MD5"); md.updateSync({ data: dataBytes }); let output = md.digestSync(); let str = utils.uint8ArrayToHexStr(output.data); - console.log("MD5: " + str); + console.println("MD5 algName: " + md.algName); + console.println("MD5: " + str); let length = md.getMdLength(); - console.log("MD5 length: " + length); - } catch (err) { - console.log("MD5: " + err); + console.println("MD5 length: " + length); + } catch (err: BusinessError) { + console.println(`[error] MD5: ${err.code} ${err.message}`); } } + +function testMdAsync() { + try { + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + let md = cryptoFramework.createMd("MD5"); + await md.update({ + data: dataBytes + }); + let output = await md.digest(); + let str = utils.uint8ArrayToHexStr(output.data); + console.println("MD5: " + str); + let length = md.getMdLength(); + console.println("MD5 length: " + length); + } catch (err: BusinessError) { + console.println(`[error] MD5: ${err.code} ${err.message}`); + } +} + +export function testMd() { + console.println(">>>>>>>>>>>>>>>>>>>> MdSync"); + testMdSync(); + console.println(">>>>>>>>>>>>>>>>>>>> MdAsync"); + testMdAsync(); +} diff --git a/frameworks/js/ani/test/test_rand.ets b/frameworks/js/ani/test/test_rand.ets index 5dcf01e6e8b00470c774916998e80cd03523f1ad..e39a0f9b1a9a9e0c0687085b2d6edb88599a0578 100644 --- a/frameworks/js/ani/test/test_rand.ets +++ b/frameworks/js/ani/test/test_rand.ets @@ -14,21 +14,47 @@ * limitations under the License. */ +import { BusinessError } from "@ohos.base"; import cryptoFramework from "@ohos.security.cryptoFramework"; import utils from "./test_utils"; -export function testRandom() { +function testRandomSync() { try { - let random = cryptoFramework.createRandom(); let data = "Hello World"; let dataBytes = utils.stringToUint8Array(data); + let random = cryptoFramework.createRandom(); 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) + console.println("Random algName: " + random.algName); + console.println("Random: " + str); + } catch (err: BusinessError) { + console.println(`[error] Random: ${err.code} ${err.message}`); } } + +function testRandomAsync() { + try { + let data = "Hello World"; + let dataBytes = utils.stringToUint8Array(data); + let random = cryptoFramework.createRandom(); + random.setSeed({ + data: dataBytes + }); + let output = await random.generateRandom(16); + let str = utils.uint8ArrayToHexStr(output.data); + console.println("Random algName: " + random.algName); + console.println("Random: " + str); + } catch (err: BusinessError) { + console.println(`[error] Random: ${err.code} ${err.message}`); + } +} + +export function testRandom() { + console.println(">>>>>>>>>>>>>>>>>>>> RandomSync"); + testRandomSync(); + console.println(">>>>>>>>>>>>>>>>>>>> RandomAsync"); + testRandomAsync(); +} diff --git a/frameworks/js/ani/test/test_sign.ets b/frameworks/js/ani/test/test_sign.ets new file mode 100644 index 0000000000000000000000000000000000000000..24ec27e20a2b968eb9e2d0fab133c47ee75bd3c2 --- /dev/null +++ b/frameworks/js/ani/test/test_sign.ets @@ -0,0 +1,86 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function sign(algName: string, priKey: cryptoFramework.PriKey, + input1: cryptoFramework.DataBlob, input2: cryptoFramework.DataBlob) { + let signer = cryptoFramework.createSign(algName); + signer.initSync(priKey); + signer.updateSync(input1); + let signData = signer.signSync(input2); + console.println("sign algName: " + signer.algName); + return signData; +} + +function verify(algName: string, pubKey: cryptoFramework.PubKey, signData: cryptoFramework.DataBlob, + input1: cryptoFramework.DataBlob, input2: cryptoFramework.DataBlob) { + let verifier = cryptoFramework.createVerify(algName); + verifier.initSync(pubKey); + verifier.updateSync(input1); + let res = verifier.verifySync(input2, signData); + console.println("verify algName: " + verifier.algName); + return res; +} + +function testSignSync() { + try { + let algName = "SM2_256|SM3"; + let str1 = "This is Sign test plan1"; + let str2 = "This is Sign test plan2"; + let input1: cryptoFramework.DataBlob = { + data: utils.stringToUint8Array(str1) + }; + let input2: cryptoFramework.DataBlob = { + data: utils.stringToUint8Array(str2) + }; + let generator = cryptoFramework.createAsyKeyGenerator("SM2_256"); + console.println("AsyKeyGenerator algName: " + generator.algName); + let keyPair = generator.generateKeyPairSync(); + let signData = sign(algName, keyPair.priKey, input1, input2); + let res = verify(algName, keyPair.pubKey, signData, input1, input2); + if (res === true) { + console.println('Sign success'); + } else { + console.println('Sign failed'); + } + } catch (err: BusinessError) { + console.println(`[error] Sign: ${err.code} ${err.message}`); + } +} + +function testSignSpec() { + try { + let signer = cryptoFramework.createSign("RSA|PSS|SHA256|MGF1_SHA256"); + signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, 32); + let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); + let mdName = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); + let mgfName = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); + console.println("SignSpec saltLen: " + saltLen); + console.println("SignSpec mdName: " + mdName); + console.println("SignSpec mgfName: " + mgfName); + } catch (err: BusinessError) { + console.println(`[error] SignSpec: ${err.code} ${err.message}`); + } +} + +export function testSign() { + console.println(">>>>>>>>>>>>>>>>>>>> SignSync"); + testSignSync(); + console.println(">>>>>>>>>>>>>>>>>>>> SignSpec"); + testSignSpec(); +} diff --git a/frameworks/js/ani/test/test_sm2_crypto_util.ets b/frameworks/js/ani/test/test_sm2_crypto_util.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bee988c6dcc469d405a3860a40e04378e781fb5 --- /dev/null +++ b/frameworks/js/ani/test/test_sm2_crypto_util.ets @@ -0,0 +1,74 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testGenCipherTextBySpec() { + try { + let spec: cryptoFramework.SM2CipherTextSpec = { + xCoordinate: BigInt('20625015362595980457695435345498579729138244358573902431560627260141789922999'), + yCoordinate: BigInt('48563164792857017065725892921053777369510340820930241057309844352421738767712'), + cipherTextData: new Uint8Array([ + 0x64, 0xE3, 0x4E, 0xC3, 0xF9, 0xB3, 0x2B, 0x46, 0xF2, 0x45, 0xA9, 0x0A, 0x41, 0x7B + ]), + hashData: new Uint8Array([ + 0x57, 0xA7, 0xA7, 0xF7, 0x58, 0x92, 0xCB, 0xEA, 0x53, 0x7E, 0x75, 0x81, 0x34, 0x8E, 0x52, 0x36, + 0x98, 0xE2, 0xC9, 0x6F, 0x8F, 0x73, 0xA9, 0x7D, 0x80, 0x2A, 0x9D, 0x1F, 0x72, 0xC6, 0x6D, 0xF4 + ]) + } + let cipherText = cryptoFramework.SM2CryptoUtil.genCipherTextBySpec(spec, 'C1C3C2'); + console.println("SM2CryptoUtil.genCipherTextBySpec:"); + console.println("CipherText cipherText.data: " + cipherText.data); + } + catch (err: BusinessError) { + console.println(`[error] SM2CryptoUtil.genCipherTextBySpec: ${err.code} ${err.message}`); + } +} + +function testGetCipherTextSpec() { + try { + let cipherTextArray = new Uint8Array([ + 0x30, 0x76, 0x02, 0x20, 0x2D, 0x99, 0x58, 0x52, 0x68, 0xDD, 0xE2, 0x2B, 0xAE, 0x15, 0x7A, 0xF8, + 0x05, 0xE8, 0x69, 0x29, 0x5C, 0x5F, 0x66, 0xE0, 0xD8, 0x95, 0x55, 0xEC, 0x6E, 0x06, 0x40, 0xBC, + 0x95, 0x46, 0x46, 0xB7, 0x02, 0x20, 0x6B, 0x5D, 0xC6, 0xF7, 0x77, 0x12, 0x28, 0x6E, 0x5A, 0x9C, + 0xC1, 0x9E, 0xCD, 0x71, 0xAA, 0x80, 0x92, 0x6D, 0x4B, 0x11, 0xB5, 0x6D, 0x6E, 0x5B, 0x95, 0x05, + 0x6E, 0xE9, 0xD1, 0x4E, 0xE5, 0x60, 0x04, 0x20, 0x57, 0xA7, 0xA7, 0xF7, 0x58, 0x92, 0xCB, 0xEA, + 0x53, 0x7E, 0x75, 0x81, 0x34, 0x8E, 0x52, 0x36, 0x98, 0xE2, 0xC9, 0x6F, 0x8F, 0x73, 0xA9, 0x7D, + 0x80, 0x2A, 0x9D, 0x1F, 0x72, 0xC6, 0x6D, 0xF4, 0x04, 0x0E, 0x64, 0xE3, 0x4E, 0xC3, 0xF9, 0xB3, + 0x2B, 0x46, 0xF2, 0x45, 0xA9, 0x0A, 0x41, 0x7B + ]); + let cipherText: cryptoFramework.DataBlob = { + data: cipherTextArray + }; + let spec: cryptoFramework.SM2CipherTextSpec = cryptoFramework.SM2CryptoUtil.getCipherTextSpec(cipherText, 'C1C3C2'); + console.println("SM2CryptoUtil.getCipherTextSpec:"); + console.println("SM2CipherTextSpec spec.xCoordinate: " + spec.xCoordinate); + console.println("SM2CipherTextSpec spec.yCoordinate: " + spec.yCoordinate); + console.println("SM2CipherTextSpec spec.cipherTextData: " + utils.uint8ArrayToHexStr(spec.cipherTextData)); + console.println("SM2CipherTextSpec spec.hashData: " + utils.uint8ArrayToHexStr(spec.hashData)); + } + catch (err: BusinessError) { + console.println(`[error] SM2CryptoUtil.getCipherTextSpec: ${err.code} ${err.message}`); + } +} + +export function testSM2CryptoUtil() { + console.println(">>>>>>>>>>>>>>>>>>>> GenCipherTextBySpec"); + testGenCipherTextBySpec(); + console.println(">>>>>>>>>>>>>>>>>>>> GetCipherTextSpec"); + testGetCipherTextSpec(); +} diff --git a/frameworks/js/ani/test/test_sym_key_generator.ets b/frameworks/js/ani/test/test_sym_key_generator.ets new file mode 100644 index 0000000000000000000000000000000000000000..68f971509a8d1d3055029d25b96ee0fe92a8b82e --- /dev/null +++ b/frameworks/js/ani/test/test_sym_key_generator.ets @@ -0,0 +1,60 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testSymKeyGeneratorSync() { + try { + let generator = cryptoFramework.createSymKeyGenerator('SM4_128'); + let symKey = generator.generateSymKeySync(); + let encodedKey = symKey.getEncoded(); + let str = utils.uint8ArrayToHexStr(encodedKey.data); + console.println("SymKeyGenerator algName: " + generator.algName); + console.println("SymKeyGenerator symKey.algName: " + symKey.algName); + console.println("SymKeyGenerator symKey.format: " + symKey.format); + console.println("generateSymKey: " + str); + symKey.clearMem(); + } catch (err: BusinessError) { + console.println(`[error] generateSymKey: ${err.code} ${err.message}`); + } +} + +function testSymKeyConvertKeySync() { + try { + let keyBlob: cryptoFramework.DataBlob = { + data: utils.stringToUint8Array('12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh') + } + let generator = cryptoFramework.createSymKeyGenerator('HMAC'); + let symKey = generator.convertKeySync(keyBlob); + let encodedKey = symKey.getEncoded(); + let str = utils.uint8ArrayToHexStr(encodedKey.data); + console.println("SymKeyGenerator algName: " + generator.algName); + console.println("SymKeyGenerator symKey.algName: " + symKey.algName); + console.println("SymKeyGenerator symKey.format: " + symKey.format); + console.println("convertKey: " + str); + symKey.clearMem(); + } catch (err: BusinessError) { + console.println(`[error] convertKey: ${err.code} ${err.message}`); + } +} + +export function testSymKeyGenerator() { + console.println(">>>>>>>>>>>>>>>>>>>> SymKeyGeneratorSync"); + testSymKeyGeneratorSync(); + console.println(">>>>>>>>>>>>>>>>>>>> SymKeyConvertKeySync"); + testSymKeyConvertKeySync(); +} diff --git a/frameworks/js/ani/test/test_utils.ets b/frameworks/js/ani/test/test_utils.ets index 38a123987e38e0f561b68e72c84d398494a03f61..45337a803b12cb0f45c4ce456c5bdb28e6a40c1f 100644 --- a/frameworks/js/ani/test/test_utils.ets +++ b/frameworks/js/ani/test/test_utils.ets @@ -41,11 +41,29 @@ 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]) + let num: Number = new Number(data[i]); str += num.toString(16).padStart(2, '0'); } return str; } + +export function uint8ArrayToString(data: Uint8Array): string { + // return buffer.from(data).toString('utf-8').toUpperCase(); + let str = ''; + for (let i = 0; i < data.length; i++) { + str += String.fromCharCode(data[i]); + } + return str; +} + +export function doFullGC(): void { + GC.waitForFinishGC(GC.startGC(GC.Cause.FULL, GC.IN_PLACE_MODE)); + Coroutine.Schedule(); +} + +export function stopTaskPool(): void { + CoroutineExtras.stopTaskpool(); +} } // namespace utils export default utils; diff --git a/frameworks/js/ani/test/test_verify.ets b/frameworks/js/ani/test/test_verify.ets new file mode 100644 index 0000000000000000000000000000000000000000..923949e97881f0d3804d153b5c358a6e48fe4f15 --- /dev/null +++ b/frameworks/js/ani/test/test_verify.ets @@ -0,0 +1,123 @@ +/* + * 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 { BusinessError } from "@ohos.base"; +import cryptoFramework from "@ohos.security.cryptoFramework"; +import utils from "./test_utils"; + +function testVerifySync() { + try { + let keyGenAlg = "SM2_256"; + let pubKeyArray = new Uint8Array([ + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D, 0x03, 0x42, 0x00, 0x04, 0x5A, 0x03, 0x3A, 0x9D, 0xBE, + 0xF8, 0x4C, 0x07, 0x84, 0xC8, 0x97, 0xD0, 0x70, 0xE6, 0x60, 0x8C, 0x5A, 0xEE, 0xD3, 0x9B, 0x80, + 0x6D, 0xF8, 0x28, 0x53, 0xD6, 0x4E, 0x2A, 0x68, 0x6A, 0x37, 0x94, 0xF9, 0x23, 0x3D, 0x20, 0xDD, + 0x87, 0x8F, 0x64, 0x2D, 0x61, 0xC2, 0xB0, 0x34, 0x49, 0x88, 0xAE, 0x28, 0x46, 0x46, 0x22, 0x67, + 0x67, 0xA1, 0x63, 0x1B, 0xBB, 0x0D, 0xBB, 0x6D, 0xF4, 0x0D, 0x07 + ]); + let priKeyArray = new Uint8Array([ + 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0x36, 0x29, 0xEF, 0xF0, 0x3F, 0xBC, 0x86, 0x71, 0x1F, + 0x66, 0x95, 0xCB, 0xF5, 0x59, 0x0F, 0x0F, 0x2F, 0xCA, 0xAA, 0x3C, 0x26, 0x9A, 0x1C, 0xA9, 0xBD, + 0x64, 0xFB, 0x4C, 0x70, 0xDF, 0x9C, 0x9F, 0xA0, 0x0A, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, + 0x01, 0x82, 0x2D + ]); + let pubKeyBlob: cryptoFramework.DataBlob = { + data: pubKeyArray + }; + let priKeyBlob: cryptoFramework.DataBlob = { + data: priKeyArray + }; + let generator = cryptoFramework.createAsyKeyGenerator(keyGenAlg); + let keyPair = generator.convertKeySync(pubKeyBlob, priKeyBlob); + let signData = new Uint8Array([ + 0x30, 0x45, 0x02, 0x20, 0x61, 0x00, 0x29, 0xFA, 0x0C, 0x48, 0x3E, 0xAD, 0x3C, 0x90, 0x65, 0x75, + 0xF9, 0x48, 0x32, 0x79, 0xBF, 0xD8, 0x52, 0x52, 0xC3, 0x57, 0x5C, 0x6D, 0xC5, 0x5D, 0x68, 0x0F, + 0xC3, 0xF7, 0x14, 0x55, 0x02, 0x21, 0x00, 0xA4, 0x16, 0x22, 0xAF, 0x70, 0xA1, 0xAA, 0x32, 0xA5, + 0xFD, 0xF8, 0xF8, 0x79, 0x10, 0x53, 0xD6, 0x44, 0xBC, 0x9E, 0x82, 0x36, 0x59, 0xFA, 0x8F, 0x1F, + 0xE2, 0x1A, 0x79, 0xA2, 0x99, 0x66, 0x1C + ]) + let signDataBytes: cryptoFramework.DataBlob = { + data: signData + }; + let input = new Uint8Array([ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 + ]); + let inputData: cryptoFramework.DataBlob = { + data: input + }; + let verify = cryptoFramework.createVerify("SM2_256|SM3"); + verify.initSync(keyPair.pubKey); + verify.updateSync(inputData); + let res = verify.verifySync(null, signDataBytes); + console.println("Verify algName: " + verify.algName); + if (res === true) { + console.println('Verify success'); + } else { + console.println('Verify failed'); + } + } catch (err: BusinessError) { + console.println(`[error] Verify: ${err.code} ${err.message}`); + } +} + +function testRecoverSync() { + try { + let generator = cryptoFramework.createAsyKeyGenerator("RSA1024"); + let keyPair = generator.generateKeyPairSync(); + let signAlg = "RSA1024|PKCS1|NoHash|OnlySign"; + let signer = cryptoFramework.createSign(signAlg); + signer.initSync(keyPair.priKey); + let input: cryptoFramework.DataBlob = { + data: utils.hexStrToUint8Array("0123456789ABCDEF") + }; + let signData = signer.signSync(input); + let verifyAlg = "RSA1024|PKCS1|NoHash|Recover"; + let verifier = cryptoFramework.createVerify(verifyAlg); + verifier.initSync(keyPair.pubKey); + let rawSignData = verifier.recoverSync(signData); + if (rawSignData !== null) { + console.println("Recover rawSignData: " + utils.uint8ArrayToHexStr(rawSignData.data)); + } else { + console.println("Recover failed"); + } + } catch (err: BusinessError) { + console.println(`[error] Recover: ${err.code} ${err.message}`); + } +} + +function testVerifySpec() { + try { + let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256"); + verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, 32); + let saltLen = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); + let mdName = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); + let mgfName = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); + console.println("VerifySpec saltLen: " + saltLen); + console.println("VerifySpec mdName: " + mdName); + console.println("VerifySpec mgfName: " + mgfName); + } catch (err: BusinessError) { + console.println(`[error] VerifySpec: ${err.code} ${err.message}`); + } +} + +export function testVerify() { + console.println(">>>>>>>>>>>>>>>>>>>> VerifySync"); + testVerifySync(); + console.println(">>>>>>>>>>>>>>>>>>>> RecoverSync"); + testRecoverSync(); + console.println(">>>>>>>>>>>>>>>>>>>> VerifySpec"); + testVerifySpec(); +} diff --git a/interfaces/inner_api/common/blob.h b/interfaces/inner_api/common/blob.h index ff0345038c08e528f60901633575cc3791890428..76ffcbf0a0713c326449ea67d3f3e92dcdbf1f09 100644 --- a/interfaces/inner_api/common/blob.h +++ b/interfaces/inner_api/common/blob.h @@ -25,11 +25,6 @@ struct HcfBlob { size_t len; }; -enum EncodingFormat { - HCF_FORMAT_DER = 0, - HCF_FORMAT_PEM = 1, -}; - #ifdef __cplusplus extern "C" { #endif