From e8c5a8990e4ace46da977000e28edaee1a902dfc Mon Sep 17 00:00:00 2001 From: xuejikan Date: Thu, 25 May 2023 11:09:08 +0800 Subject: [PATCH] test Signed-off-by: xuejikan --- BUILD.gn | 2 +- bundle.json | 9 +- cfi_blocklist.txt | 1 - common/common.gni | 5 +- common/inc/config.h | 2 +- common/inc/params_parser.h | 56 +- common/src/asy_key_params.c | 269 + common/src/big_int.c | 48 + common/src/params_parser.c | 33 + frameworks/BUILD.gn | 3 +- frameworks/crypto_operation/cipher.c | 104 +- frameworks/crypto_operation/key_agreement.c | 24 +- frameworks/crypto_operation/mac.c | 4 +- frameworks/crypto_operation/md.c | 4 +- frameworks/{rand => crypto_operation}/rand.c | 26 +- frameworks/crypto_operation/signature.c | 142 +- frameworks/frameworks.gni | 11 +- frameworks/js/napi/crypto/BUILD.gn | 5 +- .../crypto/inc/napi_asy_key_spec_generator.h | 50 + frameworks/js/napi/crypto/inc/napi_cipher.h | 5 +- .../inc/napi_crypto_framework_defines.h | 30 +- frameworks/js/napi/crypto/inc/napi_mac.h | 17 +- frameworks/js/napi/crypto/inc/napi_md.h | 15 +- frameworks/js/napi/crypto/inc/napi_pri_key.h | 1 + frameworks/js/napi/crypto/inc/napi_pub_key.h | 1 + frameworks/js/napi/crypto/inc/napi_rand.h | 13 +- frameworks/js/napi/crypto/inc/napi_sign.h | 5 +- frameworks/js/napi/crypto/inc/napi_utils.h | 24 +- frameworks/js/napi/crypto/inc/napi_verify.h | 5 +- .../crypto/src/napi_asy_key_generator.cpp | 178 +- .../src/napi_asy_key_spec_generator.cpp | 531 ++ frameworks/js/napi/crypto/src/napi_cipher.cpp | 228 +- frameworks/js/napi/crypto/src/napi_init.cpp | 127 +- frameworks/js/napi/crypto/src/napi_key.cpp | 44 +- .../js/napi/crypto/src/napi_key_agreement.cpp | 89 +- .../js/napi/crypto/src/napi_key_pair.cpp | 42 +- frameworks/js/napi/crypto/src/napi_mac.cpp | 398 +- frameworks/js/napi/crypto/src/napi_md.cpp | 325 +- .../js/napi/crypto/src/napi_pri_key.cpp | 132 +- .../js/napi/crypto/src/napi_pub_key.cpp | 119 +- frameworks/js/napi/crypto/src/napi_rand.cpp | 254 +- frameworks/js/napi/crypto/src/napi_sign.cpp | 278 +- .../js/napi/crypto/src/napi_sym_key.cpp | 17 +- .../crypto/src/napi_sym_key_generator.cpp | 67 +- frameworks/js/napi/crypto/src/napi_utils.cpp | 935 +- frameworks/js/napi/crypto/src/napi_verify.cpp | 284 +- frameworks/key/asy_key_generator.c | 966 ++- frameworks/key/sym_key_generator.c | 11 +- frameworks/spi/asy_key_generator_spi.h | 12 +- frameworks/spi/cipher_factory_spi.h | 8 +- frameworks/spi/rand_spi.h | 6 +- frameworks/spi/signature_spi.h | 15 +- .../algorithm_parameter/asy_key_params.h | 42 + .../detailed_dsa_key_params.h | 59 + .../detailed_ecc_key_params.h | 80 + .../detailed_rsa_key_params.h | 56 + interfaces/innerkits/common/big_integer.h | 39 + .../innerkits/crypto_operation/cipher.h | 17 +- .../{rand => crypto_operation}/rand.h | 2 + .../innerkits/crypto_operation/signature.h | 22 +- interfaces/innerkits/key/asy_key_generator.h | 25 +- interfaces/innerkits/key/key.h | 28 +- interfaces/innerkits/key/pri_key.h | 10 +- interfaces/innerkits/key/pub_key.h | 10 +- plugin/BUILD.gn | 3 +- .../src/x509_certificate_openssl.c | 24 +- .../common/inc/ecc_openssl_common.h | 533 ++ .../common/inc/openssl_adapter.h | 183 +- .../openssl_plugin/common/inc/openssl_class.h | 28 +- .../common/inc/openssl_common.h | 29 +- .../common/inc/rsa_openssl_common.h | 9 +- .../common/src/openssl_adapter.c | 784 +- .../common/src/openssl_common.c | 194 +- .../common/src/rsa_openssl_common.c | 15 +- .../{aes => cipher}/inc/aes_openssl.h | 0 .../{rsa => cipher}/inc/cipher_rsa_openssl.h | 0 .../{aes => cipher}/src/cipher_3des_openssl.c | 68 +- .../{aes => cipher}/src/cipher_aes_common.c | 3 +- .../{aes => cipher}/src/cipher_aes_openssl.c | 270 +- .../{rsa => cipher}/src/cipher_rsa_openssl.c | 317 +- .../crypto_operation/hmac/src/mac_openssl.c | 25 +- .../key_agreement/src/ecdh_openssl.c | 68 +- .../crypto_operation/md/src/md_openssl.c | 27 +- .../rand/inc/rand_openssl.h | 0 .../rand/src/rand_openssl.c | 24 +- .../signature/inc/dsa_openssl.h | 33 + .../signature/inc/signature_rsa_openssl.h | 2 +- .../signature/src/dsa_openssl.c | 623 ++ .../signature/src/ecdsa_openssl.c | 69 +- .../signature/src/signature_rsa_openssl.c | 426 +- .../inc/dsa_asy_key_generator_openssl.h | 32 + .../src/dsa_asy_key_generator_openssl.c | 966 +++ .../src/ecc_asy_key_generator_openssl.c | 1369 ++- .../src/rsa_asy_key_generator_openssl.c | 519 +- .../inc/sym_common_defines.h | 2 +- .../sym_key_generator/src/sym_key_openssl.c | 12 +- plugin/plugin.gni | 20 +- .../hcfciphercreate_fuzzer/BUILD.gn | 2 +- .../hcfciphercreate_fuzzer/corpus/init | 2 +- .../hcfciphercreate_fuzzer.cpp | 2 +- .../hcfciphercreate_fuzzer.h | 2 +- .../hcfciphercreate_fuzzer/project.xml | 2 +- .../hcfkeyagreementcreate_fuzzer/BUILD.gn | 2 +- .../hcfkeyagreementcreate_fuzzer/corpus/init | 2 +- .../hcfkeyagreementcreate_fuzzer.cpp | 2 +- .../hcfkeyagreementcreate_fuzzer.h | 2 +- .../hcfkeyagreementcreate_fuzzer/project.xml | 2 +- .../hcfmaccreate_fuzzer/BUILD.gn | 2 +- .../hcfmaccreate_fuzzer/corpus/init | 2 +- .../hcfmaccreate_fuzzer.cpp | 2 +- .../hcfmaccreate_fuzzer/hcfmaccreate_fuzzer.h | 2 +- .../hcfmaccreate_fuzzer/project.xml | 2 +- .../hcfmdcreate_fuzzer/BUILD.gn | 2 +- .../hcfmdcreate_fuzzer/corpus/init | 2 +- .../hcfmdcreate_fuzzer/hcfmdcreate_fuzzer.cpp | 2 +- .../hcfmdcreate_fuzzer/hcfmdcreate_fuzzer.h | 2 +- .../hcfmdcreate_fuzzer/project.xml | 2 +- .../hcfsigncreate_fuzzer/BUILD.gn | 2 +- .../hcfsigncreate_fuzzer/corpus/init | 2 +- .../hcfsigncreate_fuzzer.cpp | 2 +- .../hcfsigncreate_fuzzer.h | 2 +- .../hcfsigncreate_fuzzer/project.xml | 2 +- .../hcfverifycreate_fuzzer/BUILD.gn | 2 +- .../hcfverifycreate_fuzzer/corpus/init | 2 +- .../hcfverifycreate_fuzzer.cpp | 2 +- .../hcfverifycreate_fuzzer.h | 2 +- .../hcfverifycreate_fuzzer/project.xml | 2 +- .../key/asykeygenerator_fuzzer/BUILD.gn | 7 +- .../asykeygenerator_fuzzer.cpp | 667 +- .../asykeygenerator_fuzzer.h | 2 +- .../key/asykeygenerator_fuzzer/corpus/init | 2 +- .../key/asykeygenerator_fuzzer/project.xml | 2 +- .../key/symkeygenerator_fuzzer/BUILD.gn | 2 +- .../key/symkeygenerator_fuzzer/corpus/init | 2 +- .../key/symkeygenerator_fuzzer/project.xml | 2 +- .../symkeygenerator_fuzzer.cpp | 2 +- .../symkeygenerator_fuzzer.h | 2 +- .../rand/hcfrandcreate_fuzzer/BUILD.gn | 2 +- .../rand/hcfrandcreate_fuzzer/corpus/init | 2 +- .../hcfrandcreate_fuzzer.cpp | 3 +- .../hcfrandcreate_fuzzer.h | 2 +- .../rand/hcfrandcreate_fuzzer/project.xml | 2 +- test/unittest/BUILD.gn | 10 + test/unittest/include/openssl_adapter_mock.h | 2 +- test/unittest/src/crypto_3des_cipher_test.cpp | 8 +- test/unittest/src/crypto_aes_cipher_test.cpp | 6 +- ...pto_dsa_asy_key_generator_by_spec_test.cpp | 1645 ++++ .../src/crypto_dsa_asy_key_generator_test.cpp | 1283 +++ test/unittest/src/crypto_dsa_sign_test.cpp | 1576 ++++ test/unittest/src/crypto_dsa_verify_test.cpp | 117 + ...pto_ecc_asy_key_generator_by_spec_test.cpp | 7521 +++++++++++++++++ .../src/crypto_ecc_asy_key_generator_test.cpp | 120 +- .../crypto_ecc_key_agreement_by_spec_test.cpp | 778 ++ .../src/crypto_ecc_key_agreement_test.cpp | 106 +- .../src/crypto_ecc_no_length_sign_test.cpp | 3006 +++++++ .../src/crypto_ecc_no_length_verify_test.cpp | 3651 ++++++++ test/unittest/src/crypto_ecc_sign_test.cpp | 298 +- test/unittest/src/crypto_ecc_verify_test.cpp | 276 +- test/unittest/src/crypto_rand_test.cpp | 41 +- ...pto_rsa_asy_key_generator_by_spec_test.cpp | 2202 +++++ .../src/crypto_rsa_asy_key_generator_test.cpp | 102 +- test/unittest/src/crypto_rsa_cipher_test.cpp | 625 +- test/unittest/src/crypto_rsa_sign_test.cpp | 1346 ++- test/unittest/src/crypto_rsa_verify_test.cpp | 555 +- .../src/crypto_x509_certificate_test.cpp | 13 +- test/unittest/src/openssl_adapter_mock.c | 1111 ++- 166 files changed, 37729 insertions(+), 2477 deletions(-) create mode 100644 common/src/asy_key_params.c create mode 100644 common/src/big_int.c rename frameworks/{rand => crypto_operation}/rand.c (83%) create mode 100644 frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h create mode 100644 frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp create mode 100644 interfaces/innerkits/algorithm_parameter/asy_key_params.h create mode 100644 interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h create mode 100644 interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h create mode 100644 interfaces/innerkits/algorithm_parameter/detailed_rsa_key_params.h create mode 100644 interfaces/innerkits/common/big_integer.h rename interfaces/innerkits/{rand => crypto_operation}/rand.h (95%) create mode 100644 plugin/openssl_plugin/common/inc/ecc_openssl_common.h rename plugin/openssl_plugin/crypto_operation/{aes => cipher}/inc/aes_openssl.h (100%) rename plugin/openssl_plugin/crypto_operation/{rsa => cipher}/inc/cipher_rsa_openssl.h (100%) rename plugin/openssl_plugin/crypto_operation/{aes => cipher}/src/cipher_3des_openssl.c (81%) rename plugin/openssl_plugin/crypto_operation/{aes => cipher}/src/cipher_aes_common.c (96%) rename plugin/openssl_plugin/crypto_operation/{aes => cipher}/src/cipher_aes_openssl.c (74%) rename plugin/openssl_plugin/crypto_operation/{rsa => cipher}/src/cipher_rsa_openssl.c (45%) rename plugin/openssl_plugin/{ => crypto_operation}/rand/inc/rand_openssl.h (100%) rename plugin/openssl_plugin/{ => crypto_operation}/rand/src/rand_openssl.c (81%) create mode 100644 plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h create mode 100644 plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c create mode 100644 plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h create mode 100644 plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c create mode 100644 test/unittest/src/crypto_dsa_asy_key_generator_by_spec_test.cpp create mode 100644 test/unittest/src/crypto_dsa_asy_key_generator_test.cpp create mode 100644 test/unittest/src/crypto_dsa_sign_test.cpp create mode 100644 test/unittest/src/crypto_dsa_verify_test.cpp create mode 100644 test/unittest/src/crypto_ecc_asy_key_generator_by_spec_test.cpp create mode 100644 test/unittest/src/crypto_ecc_key_agreement_by_spec_test.cpp create mode 100644 test/unittest/src/crypto_ecc_no_length_sign_test.cpp create mode 100644 test/unittest/src/crypto_ecc_no_length_verify_test.cpp create mode 100644 test/unittest/src/crypto_rsa_asy_key_generator_by_spec_test.cpp diff --git a/BUILD.gn b/BUILD.gn index e61b17d..e3dc71b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 diff --git a/bundle.json b/bundle.json index 014342c..5f33d1d 100644 --- a/bundle.json +++ b/bundle.json @@ -40,15 +40,20 @@ "header": { "header_files": [ "algorithm_parameter/algorithm_parameter.h", + "algorithm_parameter/asy_key_params.h", "algorithm_parameter/detailed_ccm_params.h", + "algorithm_parameter/detailed_dsa_key_params.h", + "algorithm_parameter/detailed_ecc_key_params.h", "algorithm_parameter/detailed_gcm_params.h", "algorithm_parameter/detailed_iv_params.h", + "algorithm_parameter/detailed_rsa_key_params.h", "certificate/cert_chain_validator.h", "certificate/certificate.h", "certificate/crl.h", "certificate/x509_certificate.h", "certificate/x509_crl_entry.h", "certificate/x509_crl.h", + "common/big_integer.h", "common/blob.h", "common/object_base.h", "common/result.h", @@ -56,6 +61,7 @@ "crypto_operation/key_agreement.h", "crypto_operation/mac.h", "crypto_operation/md.h", + "crypto_operation/rand.h", "crypto_operation/signature.h", "key/asy_key_generator.h", "key/key_pair.h", @@ -63,8 +69,7 @@ "key/pri_key.h", "key/pub_key.h", "key/sym_key_generator.h", - "key/sym_key.h", - "rand/rand.h" + "key/sym_key.h" ], "header_base": "//base/security/crypto_framework/interfaces/innerkits" } diff --git a/cfi_blocklist.txt b/cfi_blocklist.txt index b7fb0f1..1e562df 100644 --- a/cfi_blocklist.txt +++ b/cfi_blocklist.txt @@ -1,6 +1,5 @@ src:*/frameworks/certificate/* src:*/frameworks/crypto_operation/* src:*/frameworks/key/* -src:*/frameworks/rand/* src:*/frameworks/js/napi/certificate/src/* src:*/frameworks/js/napi/crypto/src/* \ No newline at end of file diff --git a/common/common.gni b/common/common.gni index 264ae1d..4b58caf 100644 --- a/common/common.gni +++ b/common/common.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -13,10 +13,13 @@ crypto_framwork_common_inc_path = [ "//base/security/crypto_framework/interfaces/innerkits/common", + "//base/security/crypto_framework/interfaces/innerkits/algorithm_parameter", "//base/security/crypto_framework/common/inc", ] framework_common_util_files = [ + "//base/security/crypto_framework/common/src/asy_key_params.c", + "//base/security/crypto_framework/common/src/big_int.c", "//base/security/crypto_framework/common/src/blob.c", "//base/security/crypto_framework/common/src/utils.c", "//base/security/crypto_framework/common/src/log.c", diff --git a/common/inc/config.h b/common/inc/config.h index cefcd5f..7dbe5f6 100644 --- a/common/inc/config.h +++ b/common/inc/config.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index e29f325..3912e86 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -27,14 +27,15 @@ typedef enum { HCF_ALG_PRIMES, HCF_ALG_DIGEST, HCF_ALG_MGF1_DIGEST, -} HCF_ALG_PARA_TYPE; +} HcfAlgParaType; typedef enum { HCF_ALG_AES = 1, HCF_ALG_DES, HCF_ALG_RSA, HCF_ALG_ECC, -} HCF_ALG_VALUE; + HCF_ALG_DSA, +} HcfAlgValue; typedef enum { HCF_ALG_ECC_224 = 1, @@ -92,40 +93,55 @@ typedef enum { HCF_OPENSSL_PRIMES_3, HCF_OPENSSL_PRIMES_4, HCF_OPENSSL_PRIMES_5, -} HCF_ALG_PARA_VALUE; + + // dsa + HCF_ALG_DSA_1024, + HCF_ALG_DSA_2048, + HCF_ALG_DSA_3072, + + // 4.0 added: only for algName(NO SIZE) + HCF_ALG_DSA_DEFAULT, + HCF_ALG_RSA_DEFAULT, + HCF_ALG_ECC_DEFAULT, + HCF_ALG_AES_DEFAULT, + HCF_ALG_3DES_DEFAULT, +} HcfAlgParaValue; typedef struct { const char* tag; - HCF_ALG_PARA_TYPE paraType; - HCF_ALG_PARA_VALUE paraValue; + HcfAlgParaType paraType; + HcfAlgParaValue paraValue; } HcfParaConfig; typedef struct { - HCF_ALG_VALUE algo; - HCF_ALG_PARA_VALUE keySize; - HCF_ALG_PARA_VALUE mode; - HCF_ALG_PARA_VALUE paddingMode; - HCF_ALG_PARA_VALUE md; - HCF_ALG_PARA_VALUE mgf1md; + const char* algNameStr; + HcfAlgValue algValue; +} HcfAlgMap; + +typedef struct { + HcfAlgValue algo; + HcfAlgParaValue keySize; + HcfAlgParaValue mode; + HcfAlgParaValue paddingMode; + HcfAlgParaValue md; + HcfAlgParaValue mgf1md; } CipherAttr; typedef struct { - HCF_ALG_VALUE algo; // algType + HcfAlgValue algo; // algType int32_t bits; // keyLen int32_t primes; // number of primes } HcfAsyKeyGenParams; typedef struct { - HCF_ALG_VALUE algo; // algType - HCF_ALG_PARA_VALUE keyLen; - HCF_ALG_PARA_VALUE padding; - HCF_ALG_PARA_VALUE md; - HCF_ALG_PARA_VALUE mgf1md; + HcfAlgValue algo; // algType + HcfAlgParaValue padding; + HcfAlgParaValue md; + HcfAlgParaValue mgf1md; } HcfSignatureParams; typedef struct { - HCF_ALG_VALUE algo; - HCF_ALG_PARA_VALUE keyLen; + HcfAlgValue algo; } HcfKeyAgreementParams; typedef HcfResult (*SetParameterFunc) (const HcfParaConfig* config, void *params); @@ -136,6 +152,8 @@ extern "C" { HcfResult ParseAndSetParameter(const char *paramsStr, void *params, SetParameterFunc setFunc); +HcfResult ParseAlgNameToParams(const char *algNameStr, HcfAsyKeyGenParams *params); + #ifdef __cplusplus } #endif diff --git a/common/src/asy_key_params.c b/common/src/asy_key_params.c new file mode 100644 index 0000000..2de7d28 --- /dev/null +++ b/common/src/asy_key_params.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2023 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 "asy_key_params.h" + +#include +#include +#include + +#include "big_integer.h" +#include "detailed_dsa_key_params.h" +#include "detailed_ecc_key_params.h" +#include "detailed_rsa_key_params.h" +#include "memory.h" +#include "log.h" + +#define ALG_NAME_DSA "DSA" +#define ALG_NAME_ECC "ECC" +#define ALG_NAME_RSA "RSA" + +void FreeDsaCommParamsSpec(HcfDsaCommParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + HcfFree(spec->base.algName); + spec->base.algName = NULL; + HcfFree(spec->p.data); + spec->p.data = NULL; + HcfFree(spec->q.data); + spec->q.data = NULL; + HcfFree(spec->g.data); + spec->g.data = NULL; +} + +static void DestroyDsaCommParamsSpec(HcfDsaCommParamsSpec *spec) +{ + FreeDsaCommParamsSpec(spec); + HcfFree(spec); +} + +void DestroyDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeDsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + spec->pk.data = NULL; + HcfFree(spec); +} + +void DestroyDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeDsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + spec->pk.data = NULL; + (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len); + HcfFree(spec->sk.data); + spec->sk.data = NULL; + HcfFree(spec); +} + +static void FreeEcFieldMem(HcfECField **field) +{ + HcfFree((*field)->fieldType); + (*field)->fieldType = NULL; + HcfFree(((HcfECFieldFp *)(*field))->p.data); + ((HcfECFieldFp *)(*field))->p.data = NULL; + HcfFree(*field); + *field = NULL; +} + +static void FreeEcPointMem(HcfPoint *point) +{ + HcfFree(point->x.data); + point->x.data = NULL; + HcfFree(point->y.data); + point->y.data = NULL; +} + +void FreeEccCommParamsSpec(HcfEccCommParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + HcfFree(spec->base.algName); + spec->base.algName = NULL; + HcfFree(spec->a.data); + spec->a.data = NULL; + HcfFree(spec->b.data); + spec->b.data = NULL; + HcfFree(spec->n.data); + spec->n.data = NULL; + FreeEcFieldMem(&(spec->field)); + spec->field = NULL; + FreeEcPointMem(&(spec->g)); +} + +static void DestroyEccCommParamsSpec(HcfEccCommParamsSpec *spec) +{ + FreeEccCommParamsSpec(spec); + HcfFree(spec); +} + +void DestroyEccPubKeySpec(HcfEccPubKeyParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeEccCommParamsSpec(&(spec->base)); + FreeEcPointMem(&(spec->pk)); + HcfFree(spec); +} + +void DestroyEccPriKeySpec(HcfEccPriKeyParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeEccCommParamsSpec(&(spec->base)); + (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len); + HcfFree(spec->sk.data); + spec->sk.data = NULL; + HcfFree(spec); +} + +void DestroyEccKeyPairSpec(HcfEccKeyPairParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeEccCommParamsSpec(&(spec->base)); + FreeEcPointMem(&(spec->pk)); + (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len); + HcfFree(spec->sk.data); + spec->sk.data = NULL; + HcfFree(spec); +} + +void FreeRsaCommParamsSpec(HcfRsaCommParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + HcfFree(spec->base.algName); + spec->base.algName = NULL; + HcfFree(spec->n.data); + spec->n.data = NULL; +} + +static void DestroyRsaCommParamsSpec(HcfRsaCommParamsSpec *spec) +{ + FreeRsaCommParamsSpec(spec); + HcfFree(spec); +} + +void DestroyRsaPubKeySpec(HcfRsaPubKeyParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + spec->pk.data = NULL; + HcfFree(spec); +} + +void DestroyRsaKeyPairSpec(HcfRsaKeyPairParamsSpec *spec) +{ + if (spec == NULL) { + return; + } + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + spec->pk.data = NULL; + (void)memset_s(spec->sk.data, spec->sk.len, 0, spec->sk.len); + HcfFree(spec->sk.data); + spec->sk.data = NULL; + HcfFree(spec); +} + +static void DestroyDsaParamsSpec(HcfAsyKeyParamsSpec *spec) +{ + switch (spec->specType) { + case HCF_COMMON_PARAMS_SPEC: + DestroyDsaCommParamsSpec((HcfDsaCommParamsSpec *)spec); + break; + case HCF_PUBLIC_KEY_SPEC: + DestroyDsaPubKeySpec((HcfDsaPubKeyParamsSpec *)spec); + break; + case HCF_KEY_PAIR_SPEC: + DestroyDsaKeyPairSpec((HcfDsaKeyPairParamsSpec *)spec); + break; + default: + LOGE("No matching DSA key params spec type."); + break; + } +} + +static void DestroyEccParamsSpec(HcfAsyKeyParamsSpec *spec) +{ + switch (spec->specType) { + case HCF_COMMON_PARAMS_SPEC: + DestroyEccCommParamsSpec((HcfEccCommParamsSpec *)spec); + break; + case HCF_PRIVATE_KEY_SPEC: + DestroyEccPriKeySpec((HcfEccPriKeyParamsSpec *)spec); + break; + case HCF_PUBLIC_KEY_SPEC: + DestroyEccPubKeySpec((HcfEccPubKeyParamsSpec *)spec); + break; + case HCF_KEY_PAIR_SPEC: + DestroyEccKeyPairSpec((HcfEccKeyPairParamsSpec *)spec); + break; + default: + LOGE("No matching ECC key params spec type."); + break; + } +} + +static void DestroyRsaParamsSpec(HcfAsyKeyParamsSpec *spec) +{ + switch (spec->specType) { + case HCF_COMMON_PARAMS_SPEC: + DestroyRsaCommParamsSpec((HcfRsaCommParamsSpec *)spec); + break; + case HCF_PUBLIC_KEY_SPEC: + DestroyRsaPubKeySpec((HcfRsaPubKeyParamsSpec *)spec); + break; + case HCF_KEY_PAIR_SPEC: + DestroyRsaKeyPairSpec((HcfRsaKeyPairParamsSpec *)spec); + break; + default: + LOGE("No matching RSA key params spec type."); + break; + } +} + +void FreeAsyKeySpec(HcfAsyKeyParamsSpec *spec) +{ + if (spec == NULL || spec->algName == NULL) { + return; + } + if (strcmp(spec->algName, ALG_NAME_DSA) == 0) { + return DestroyDsaParamsSpec(spec); + } else if (strcmp(spec->algName, ALG_NAME_ECC) == 0) { + return DestroyEccParamsSpec(spec); + } else if (strcmp(spec->algName, ALG_NAME_RSA) == 0) { + return DestroyRsaParamsSpec(spec); + } else { + LOGE("No matching key params spec alg name."); + } +} \ No newline at end of file diff --git a/common/src/big_int.c b/common/src/big_int.c new file mode 100644 index 0000000..516de7c --- /dev/null +++ b/common/src/big_int.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 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 "big_integer.h" + +#include +#include "memory.h" +#include "log.h" + +void HcfBigIntDataFree(HcfBigInteger *bigInt) +{ + if ((bigInt == NULL) || (bigInt->data == NULL)) { + return; + } + HcfFree(bigInt->data); + bigInt->data = NULL; + bigInt->len = 0; +} + +void HcfBigIntFree(HcfBigInteger *bigInt) +{ + HcfBigIntDataFree(bigInt); + HcfFree(bigInt); +} + +void HcfBigIntDataClearAndFree(HcfBigInteger *bigInt) +{ + if ((bigInt == NULL) || (bigInt->data == NULL)) { + LOGD("The input blob is null, no need to free."); + return; + } + (void)memset_s(bigInt->data, bigInt->len, 0, bigInt->len); + HcfFree(bigInt->data); + bigInt->data = NULL; + bigInt->len = 0; +} \ No newline at end of file diff --git a/common/src/params_parser.c b/common/src/params_parser.c index 8aa0ccd..809fc6b 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -17,6 +17,7 @@ #include #include +#include #include "hcf_string.h" #include "log.h" @@ -59,6 +60,7 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"PKCS1_OAEP", HCF_ALG_PADDING_TYPE, HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING}, {"PSS", HCF_ALG_PADDING_TYPE, HCF_OPENSSL_RSA_PSS_PADDING}, + {"NoHash", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_NONE}, {"MD5", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_MD5}, {"SHA1", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA1}, {"SHA224", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA224}, @@ -78,6 +80,21 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"PRIMES_4", HCF_ALG_PRIMES, HCF_OPENSSL_PRIMES_4}, {"PRIMES_5", HCF_ALG_PRIMES, HCF_OPENSSL_PRIMES_5}, + {"DSA1024", HCF_ALG_KEY_TYPE, HCF_ALG_DSA_1024}, + {"DSA2048", HCF_ALG_KEY_TYPE, HCF_ALG_DSA_2048}, + {"DSA3072", HCF_ALG_KEY_TYPE, HCF_ALG_DSA_3072}, + + {"RSA", HCF_ALG_TYPE, HCF_ALG_RSA_DEFAULT}, + {"DSA", HCF_ALG_TYPE, HCF_ALG_DSA_DEFAULT}, + {"ECC", HCF_ALG_TYPE, HCF_ALG_ECC_DEFAULT}, + {"AES", HCF_ALG_TYPE, HCF_ALG_AES_DEFAULT}, + {"3DES", HCF_ALG_TYPE, HCF_ALG_3DES_DEFAULT}, +}; + +static const HcfAlgMap ALG_MAP[] = { + {"DSA", HCF_ALG_DSA}, + {"RSA", HCF_ALG_RSA}, + {"ECC", HCF_ALG_ECC}, }; static const HcfParaConfig *FindConfig(const HcString* tag) @@ -138,3 +155,19 @@ HcfResult ParseAndSetParameter(const char *paramsStr, void *params, SetParameter DeleteString(&str); return ret; } + +HcfResult ParseAlgNameToParams(const char *algNameStr, HcfAsyKeyGenParams *params) +{ + if (algNameStr == NULL || params == NULL) { + return HCF_INVALID_PARAMS; + } + for (uint32_t i = 0; i < sizeof(ALG_MAP) / sizeof(HcfAlgMap); ++i) { + if (strcmp(algNameStr, ALG_MAP[i].algNameStr) == 0) { + params->algo = ALG_MAP[i].algValue; + params->bits = 0; + return HCF_SUCCESS; + } + } + LOGE("Not support algorithm name: %s", algNameStr); + return HCF_INVALID_PARAMS; +} diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn index 1892fce..ee541a3 100644 --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -22,7 +22,6 @@ config("framework_config") { "//base/security/crypto_framework/interfaces/innerkits/common", "//base/security/crypto_framework/interfaces/innerkits/crypto_operation", "//base/security/crypto_framework/interfaces/innerkits/key", - "//base/security/crypto_framework/interfaces/innerkits/rand", ] } diff --git a/frameworks/crypto_operation/cipher.c b/frameworks/crypto_operation/cipher.c index 65674c1..318e73d 100644 --- a/frameworks/crypto_operation/cipher.c +++ b/frameworks/crypto_operation/cipher.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -37,7 +37,7 @@ typedef struct { } HcfCipherGenFuncSet; typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; HcfCipherGenFuncSet funcSet; } HcfCipherGenAbility; @@ -47,7 +47,29 @@ static const HcfCipherGenAbility CIPHER_ABILITY_SET[] = { { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } } }; -static void SetKeyLength(HCF_ALG_PARA_VALUE value, void *cipher) +static void SetKeyType(HcfAlgParaValue value, void *cipher) +{ + CipherAttr *cipherAttr = (CipherAttr *)cipher; + + cipherAttr->keySize = 0; + + switch (value) { + case HCF_ALG_AES_DEFAULT: + cipherAttr->algo = HCF_ALG_AES; + break; + case HCF_ALG_3DES_DEFAULT: + cipherAttr->algo = HCF_ALG_DES; + break; + case HCF_ALG_RSA_DEFAULT: + cipherAttr->algo = HCF_ALG_RSA; + break; + default: + LOGE("Invalid algo %u.", value); + break; + } +} + +static void SetKeyLength(HcfAlgParaValue value, void *cipher) { CipherAttr *cipherAttr = (CipherAttr *)cipher; @@ -77,24 +99,24 @@ static void SetKeyLength(HCF_ALG_PARA_VALUE value, void *cipher) } } -static void SetMode(HCF_ALG_PARA_VALUE value, void *cipher) +static void SetMode(HcfAlgParaValue value, void *cipher) { CipherAttr *cipherAttr = (CipherAttr *)cipher; cipherAttr->mode = value ; } -static void SetPadding(HCF_ALG_PARA_VALUE value, void *cipher) +static void SetPadding(HcfAlgParaValue value, void *cipher) { CipherAttr *cipherAttr = (CipherAttr *)cipher; cipherAttr->paddingMode = value; } -static void SetDigest(HCF_ALG_PARA_VALUE value, CipherAttr *cipher) +static void SetDigest(HcfAlgParaValue value, CipherAttr *cipher) { cipher->md = value; } -static void SetMgf1Digest(HCF_ALG_PARA_VALUE value, CipherAttr *cipher) +static void SetMgf1Digest(HcfAlgParaValue value, CipherAttr *cipher) { cipher->mgf1md = value; } @@ -108,6 +130,8 @@ static HcfResult OnSetParameter(const HcfParaConfig *config, void *cipher) LOGD("Set Parameter:%s", config->tag); switch (config->paraType) { case HCF_ALG_TYPE: + SetKeyType(config->paraValue, cipher); + break; case HCF_ALG_KEY_TYPE: SetKeyLength(config->paraValue, cipher); break; @@ -162,6 +186,67 @@ static void CipherDestroy(HcfObjectBase *self) HcfFree(impl); } +static HcfResult SetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob pSource) +{ + // only implemented for OAEP_MGF1_PSRC_UINT8ARR + // if pSource == NULL or len == 0, it means cleaning the pSource + if (self == NULL || pSource.len < 0) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != OAEP_MGF1_PSRC_UINT8ARR) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + CipherGenImpl *impl = (CipherGenImpl *)self; + return impl->spiObj->setCipherSpecUint8Array(impl->spiObj, item, pSource); +} + +static bool CheckCipherSpecString(CipherSpecItem item) +{ + return item == OAEP_MD_NAME_STR || item == OAEP_MGF_NAME_STR || item == OAEP_MGF1_MD_STR; +} + +static HcfResult GetCipherSpecString(HcfCipher *self, CipherSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!CheckCipherSpecString(item)) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + CipherGenImpl *impl = (CipherGenImpl *)self; + return impl->spiObj->getCipherSpecString(impl->spiObj, item, returnString); +} + +static HcfResult GetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob *returnUint8Array) +{ + if (self == NULL || returnUint8Array == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != OAEP_MGF1_PSRC_UINT8ARR) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + CipherGenImpl *impl = (CipherGenImpl *)self; + return impl->spiObj->getCipherSpecUint8Array(impl->spiObj, item, returnUint8Array); +} + static HcfResult CipherInit(HcfCipher *self, enum HcfCryptoMode opMode, HcfKey *key, HcfParamsSpec *params) { @@ -213,6 +298,9 @@ static void InitCipher(HcfCipherGeneratorSpi *spiObj, CipherGenImpl *cipher) cipher->super.getAlgorithm = GetAlogrithm; cipher->super.base.destroy = CipherDestroy; cipher->super.base.getClass = GetCipherGeneratorClass; + cipher->super.getCipherSpecString = GetCipherSpecString; + cipher->super.getCipherSpecUint8Array = GetCipherSpecUint8Array; + cipher->super.setCipherSpecUint8Array = SetCipherSpecUint8Array; } static const HcfCipherGenFuncSet *FindAbility(CipherAttr *attr) @@ -254,7 +342,7 @@ HcfResult HcfCipherCreate(const char *transformation, HcfCipher **returnObj) if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnGenerator); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfCipherGeneratorSpi *spiObj = NULL; HcfResult res = funcSet->createFunc(&attr, &spiObj); diff --git a/frameworks/crypto_operation/key_agreement.c b/frameworks/crypto_operation/key_agreement.c index 5a49e3b..262c816 100644 --- a/frameworks/crypto_operation/key_agreement.c +++ b/frameworks/crypto_operation/key_agreement.c @@ -36,7 +36,7 @@ typedef struct { } HcfKeyAgreementImpl; typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; HcfKeyAgreementSpiCreateFunc createSpiFunc; } HcfKeyAgreementGenAbility; @@ -56,14 +56,13 @@ static HcfKeyAgreementSpiCreateFunc FindAbility(HcfKeyAgreementParams *params) return NULL; } -static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfKeyAgreementParams *paramsObj) +static void SetKeyType(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj) { switch (value) { case HCF_ALG_ECC_224: case HCF_ALG_ECC_256: case HCF_ALG_ECC_384: case HCF_ALG_ECC_521: - paramsObj->keyLen = value; paramsObj->algo = HCF_ALG_ECC; break; default: @@ -71,6 +70,18 @@ static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfKeyAgreementParams *paramsOb } } +static void SetKeyTypeDefault(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj) +{ + switch (value) { + case HCF_ALG_ECC_DEFAULT: + paramsObj->algo = HCF_ALG_ECC; + break; + default: + LOGE("Invalid algo %u.", value); + break; + } +} + static HcfResult ParseKeyAgreementParams(const HcfParaConfig* config, void *params) { if (config == NULL || params == NULL) { @@ -80,6 +91,9 @@ static HcfResult ParseKeyAgreementParams(const HcfParaConfig* config, void *para HcfKeyAgreementParams *paramsObj = (HcfKeyAgreementParams *)params; LOGI("Set Parameter: %s", config->tag); switch (config->paraType) { + case HCF_ALG_TYPE: + SetKeyTypeDefault(config->paraValue, paramsObj); + break; case HCF_ALG_KEY_TYPE: SetKeyType(config->paraValue, paramsObj); break; @@ -162,10 +176,10 @@ HcfResult HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnOb if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnGenerator); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfKeyAgreementSpi *spiObj = NULL; - int32_t res = createSpiFunc(¶ms, &spiObj); + HcfResult res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnGenerator); diff --git a/frameworks/crypto_operation/mac.c b/frameworks/crypto_operation/mac.c index 819cec0..22e1bb9 100644 --- a/frameworks/crypto_operation/mac.c +++ b/frameworks/crypto_operation/mac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -168,7 +168,7 @@ HcfResult HcfMacCreate(const char *algoName, HcfMac **mac) if (strcpy_s(returnMacApi->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnMacApi); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfMacSpi *spiObj = NULL; HcfResult res = createSpiFunc(algoName, &spiObj); diff --git a/frameworks/crypto_operation/md.c b/frameworks/crypto_operation/md.c index fdc1d45..ed231ce 100644 --- a/frameworks/crypto_operation/md.c +++ b/frameworks/crypto_operation/md.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -156,7 +156,7 @@ HcfResult HcfMdCreate(const char *algoName, HcfMd **md) if (strcpy_s(returnMdApi->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnMdApi); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfMdSpi *spiObj = NULL; HcfResult res = createSpiFunc(algoName, &spiObj); diff --git a/frameworks/rand/rand.c b/frameworks/crypto_operation/rand.c similarity index 83% rename from frameworks/rand/rand.c rename to frameworks/crypto_operation/rand.c index 5bbd0cd..0cb464d 100644 --- a/frameworks/rand/rand.c +++ b/frameworks/crypto_operation/rand.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -14,6 +14,8 @@ */ #include "rand.h" + +#include #include #include "rand_spi.h" #include "rand_openssl.h" @@ -60,10 +62,14 @@ static HcfRandSpiCreateFunc FindAbility(const char *algoName) static HcfResult GenerateRandom(HcfRand *self, int32_t numBytes, HcfBlob *random) { - if ((self == NULL) || (numBytes <= 0) || (numBytes > HCF_MAX_BUFFER_LEN) || (random == NULL)) { + if ((self == NULL) || (random == NULL)) { LOGE("Invalid params!"); return HCF_INVALID_PARAMS; } + if ((numBytes <= 0) || (numBytes > INT_MAX)) { + LOGE("Invalid numBytes!"); + return HCF_INVALID_PARAMS; + } if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) { LOGE("Class is not match."); return HCF_INVALID_PARAMS; @@ -72,9 +78,22 @@ static HcfResult GenerateRandom(HcfRand *self, int32_t numBytes, HcfBlob *random ((HcfRandImpl *)self)->spiObj, numBytes, random); } +static const char *GetAlgoName(HcfRand *self) +{ + if (self == NULL) { + LOGE("The input self ptr is NULL!"); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) { + LOGE("Class is not match!"); + return NULL; + } + return ((HcfRandImpl *)self)->spiObj->engineGetAlgoName(((HcfRandImpl *)self)->spiObj); +} + static HcfResult SetSeed(HcfRand *self, HcfBlob *seed) { - if ((self == NULL) || (!IsBlobValid(seed)) || (seed->len > HCF_MAX_BUFFER_LEN)) { + if ((self == NULL) || (!IsBlobValid(seed)) || (seed->len > INT_MAX)) { LOGE("The input self ptr is NULL!"); return HCF_INVALID_PARAMS; } @@ -128,6 +147,7 @@ HcfResult HcfRandCreate(HcfRand **random) returnRandApi->base.base.getClass = GetRandClass; returnRandApi->base.base.destroy = HcfRandDestroy; returnRandApi->base.generateRandom = GenerateRandom; + returnRandApi->base.getAlgoName = GetAlgoName; returnRandApi->base.setSeed = SetSeed; returnRandApi->spiObj = spiObj; *random = (HcfRand *)returnRandApi; diff --git a/frameworks/crypto_operation/signature.c b/frameworks/crypto_operation/signature.c index d5fbedf..d84ee23 100644 --- a/frameworks/crypto_operation/signature.c +++ b/frameworks/crypto_operation/signature.c @@ -18,6 +18,7 @@ #include #include "config.h" +#include "dsa_openssl.h" #include "ecdsa_openssl.h" #include "log.h" #include "memory.h" @@ -46,25 +47,27 @@ typedef struct { } HcfVerifyImpl; typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; HcfSignSpiCreateFunc createFunc; } HcfSignGenAbility; typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; HcfVerifySpiCreateFunc createFunc; } HcfVerifyGenAbility; static const HcfSignGenAbility SIGN_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfSignSpiEcdsaCreate }, - { HCF_ALG_RSA, HcfSignSpiRsaCreate } + { HCF_ALG_RSA, HcfSignSpiRsaCreate }, + { HCF_ALG_DSA, HcfSignSpiDsaCreate } }; static const HcfVerifyGenAbility VERIFY_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfVerifySpiEcdsaCreate }, - { HCF_ALG_RSA, HcfVerifySpiRsaCreate } + { HCF_ALG_RSA, HcfVerifySpiRsaCreate }, + { HCF_ALG_DSA, HcfVerifySpiDsaCreate } }; static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) @@ -89,14 +92,31 @@ static HcfVerifySpiCreateFunc FindVerifyAbility(HcfSignatureParams *params) return NULL; } -static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) +static void SetKeyTypeDefault(HcfAlgParaValue value, HcfSignatureParams *paramsObj) +{ + switch (value) { + case HCF_ALG_ECC_DEFAULT: + paramsObj->algo = HCF_ALG_ECC; + break; + case HCF_ALG_RSA_DEFAULT: + paramsObj->algo = HCF_ALG_RSA; + break; + case HCF_ALG_DSA_DEFAULT: + paramsObj->algo = HCF_ALG_DSA; + break; + default: + LOGE("Invalid algo %u.", value); + break; + } +} + +static void SetKeyType(HcfAlgParaValue value, HcfSignatureParams *paramsObj) { switch (value) { case HCF_ALG_ECC_224: case HCF_ALG_ECC_256: case HCF_ALG_ECC_384: case HCF_ALG_ECC_521: - paramsObj->keyLen = value; paramsObj->algo = HCF_ALG_ECC; break; case HCF_OPENSSL_RSA_512: @@ -108,6 +128,11 @@ static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) case HCF_OPENSSL_RSA_8192: paramsObj->algo = HCF_ALG_RSA; break; + case HCF_ALG_DSA_1024: + case HCF_ALG_DSA_2048: + case HCF_ALG_DSA_3072: + paramsObj->algo = HCF_ALG_DSA; + break; default: LOGE("there is not matched algorithm."); break; @@ -121,8 +146,11 @@ static HcfResult ParseSignatureParams(const HcfParaConfig* config, void *params) } HcfResult ret = HCF_SUCCESS; HcfSignatureParams *paramsObj = (HcfSignatureParams *)params; - LOGI("Set Parameter: %s", config->tag); + LOGD("Set Parameter: %s", config->tag); switch (config->paraType) { + case HCF_ALG_TYPE: + SetKeyTypeDefault(config->paraValue, paramsObj); + break; case HCF_ALG_KEY_TYPE: SetKeyType(config->paraValue, paramsObj); break; @@ -204,6 +232,45 @@ static void DestroyVerify(HcfObjectBase *self) HcfFree(impl); } +static HcfResult SetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineSetSignSpecInt(tmpSelf->spiObj, item, saltLen); +} + +static HcfResult GetSignSpecString(HcfSign *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineGetSignSpecString(tmpSelf->spiObj, item, returnString); +} + +static HcfResult GetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineGetSignSpecInt(tmpSelf->spiObj, item, returnInt); +} + static HcfResult SignInit(HcfSign *self, HcfParamsSpec *params, HcfPriKey *privateKey) { if (self == NULL) { @@ -243,6 +310,45 @@ static HcfResult SignDoFinal(HcfSign *self, HcfBlob *data, HcfBlob *returnSignat return ((HcfSignImpl *)self)->spiObj->engineSign(((HcfSignImpl *)self)->spiObj, data, returnSignatureData); } +static HcfResult SetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineSetVerifySpecInt(tmpSelf->spiObj, item, saltLen); +} + +static HcfResult GetVerifySpecString(HcfVerify *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineGetVerifySpecString(tmpSelf->spiObj, item, returnString); +} + +static HcfResult GetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineGetVerifySpecInt(tmpSelf->spiObj, item, returnInt); +} + static HcfResult VerifyInit(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey) { if (self == NULL) { @@ -283,7 +389,7 @@ static bool VerifyDoFinal(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) { - LOGI("HcfSignCreate start"); + LOGD("HcfSignCreate start"); if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { return HCF_INVALID_PARAMS; } @@ -308,10 +414,10 @@ HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) if (strcpy_s(returnSign->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnSign); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfSignSpi *spiObj = NULL; - int32_t res = createSpiFunc(¶ms, &spiObj); + HcfResult res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnSign); @@ -323,16 +429,19 @@ HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) returnSign->base.init = SignInit; returnSign->base.update = SignUpdate; returnSign->base.sign = SignDoFinal; + returnSign->base.setSignSpecInt = SetSignSpecInt; + returnSign->base.getSignSpecInt = GetSignSpecInt; + returnSign->base.getSignSpecString = GetSignSpecString; returnSign->spiObj = spiObj; *returnObj = (HcfSign *)returnSign; - LOGI("HcfSignCreate end"); + LOGD("HcfSignCreate end"); return HCF_SUCCESS; } HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) { - LOGI("HcfVerifyCreate start"); + LOGD("HcfVerifyCreate start"); if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { return HCF_INVALID_PARAMS; } @@ -355,10 +464,10 @@ HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) if (strcpy_s(returnVerify->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnVerify); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfVerifySpi *spiObj = NULL; - int32_t res = createSpiFunc(¶ms, &spiObj); + HcfResult res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnVerify); @@ -370,8 +479,11 @@ HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) returnVerify->base.init = VerifyInit; returnVerify->base.update = VerifyUpdate; returnVerify->base.verify = VerifyDoFinal; + returnVerify->base.setVerifySpecInt = SetVerifySpecInt; + returnVerify->base.getVerifySpecInt = GetVerifySpecInt; + returnVerify->base.getVerifySpecString = GetVerifySpecString; returnVerify->spiObj = spiObj; *returnObj = (HcfVerify *)returnVerify; - LOGI("HcfVerifyCreate end"); + LOGD("HcfVerifyCreate end"); return HCF_SUCCESS; } diff --git a/frameworks/frameworks.gni b/frameworks/frameworks.gni index af458e2..1a4930e 100644 --- a/frameworks/frameworks.gni +++ b/frameworks/frameworks.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -21,19 +21,18 @@ framework_inc_path = [ "${base_path}/interfaces/innerkits/common", "${base_path}/interfaces/innerkits/crypto_operation", "${base_path}/interfaces/innerkits/key", - "${base_path}/interfaces/innerkits/rand", "${base_path}/common/inc", "${plugin_path}/openssl_plugin/certificate/inc", + "${plugin_path}/openssl_plugin/common/inc", "${plugin_path}/openssl_plugin/crypto_operation/key_agreement/inc", "${plugin_path}/openssl_plugin/crypto_operation/signature/inc", - "${plugin_path}/openssl_plugin/crypto_operation/aes/inc", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/inc", "${plugin_path}/openssl_plugin/key/sym_key_generator/inc", "${plugin_path}/openssl_plugin/key/asy_key_generator/inc", "${plugin_path}/openssl_plugin/certificate/inc", "${plugin_path}/openssl_plugin/crypto_operation/hmac/inc", "${plugin_path}/openssl_plugin/crypto_operation/md/inc", - "${plugin_path}/openssl_plugin/crypto_operation/rsa/inc", - "${plugin_path}/openssl_plugin/rand/inc", + "${plugin_path}/openssl_plugin/crypto_operation/rand/inc", "${framework_path}/spi", ] @@ -57,7 +56,7 @@ framework_key_files = [ framework_mac_files = [ "${framework_path}/crypto_operation/mac.c" ] -framework_rand_files = [ "${framework_path}/rand/rand.c" ] +framework_rand_files = [ "${framework_path}/crypto_operation/rand.c" ] framework_md_files = [ "${framework_path}/crypto_operation/md.c" ] diff --git a/frameworks/js/napi/crypto/BUILD.gn b/frameworks/js/napi/crypto/BUILD.gn index c113fd1..e3ae19f 100644 --- a/frameworks/js/napi/crypto/BUILD.gn +++ b/frameworks/js/napi/crypto/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -9,7 +9,7 @@ # 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. +# limitations under the License. import("//base/security/crypto_framework/common/common.gni") import("//base/security/crypto_framework/frameworks/frameworks.gni") @@ -43,6 +43,7 @@ ohos_shared_library("cryptoframework_napi") { sources = [ "src/napi_asy_key_generator.cpp", + "src/napi_asy_key_spec_generator.cpp", "src/napi_cipher.cpp", "src/napi_init.cpp", "src/napi_key.cpp", diff --git a/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h b/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h new file mode 100644 index 0000000..dd45e66 --- /dev/null +++ b/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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 HCF_NAPI_ASY_KEY_SPEC_GENERATOR_H +#define HCF_NAPI_ASY_KEY_SPEC_GENERATOR_H + +#include +#include "asy_key_generator.h" +#include "log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace CryptoFramework { +class NapiAsyKeyGeneratorBySpec { +public: + explicit NapiAsyKeyGeneratorBySpec(HcfAsyKeyGeneratorBySpec *generator); + ~NapiAsyKeyGeneratorBySpec(); + + HcfAsyKeyGeneratorBySpec *GetAsyKeyGeneratorBySpec(); + + static void DefineAsyKeyGeneratorBySpecJSClass(napi_env env, napi_value exports); + static napi_value AsyKeyGeneratorBySpecConstructor(napi_env env, napi_callback_info info); + static napi_value CreateJsAsyKeyGeneratorBySpec(napi_env env, napi_callback_info info); + + static napi_value JsGenerateKeyPair(napi_env env, napi_callback_info info); + static napi_value JsGeneratePubKey(napi_env env, napi_callback_info info); + static napi_value JsGeneratePriKey(napi_env env, napi_callback_info info); + static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); + + static thread_local napi_ref classRef_; + +private: + HcfAsyKeyGeneratorBySpec *generator_ = nullptr; +}; +} // namespace CryptoFramework +} // namespace OHOS +#endif diff --git a/frameworks/js/napi/crypto/inc/napi_cipher.h b/frameworks/js/napi/crypto/inc/napi_cipher.h index 6c36b67..fe7dc8d 100644 --- a/frameworks/js/napi/crypto/inc/napi_cipher.h +++ b/frameworks/js/napi/crypto/inc/napi_cipher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -38,6 +38,9 @@ public: static napi_value JsCipherUpdate(napi_env env, napi_callback_info info); static napi_value JsCipherDoFinal(napi_env env, napi_callback_info info); static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); + + static napi_value JsSetCipherSpec(napi_env env, napi_callback_info info); + static napi_value JsGetCipherSpec(napi_env env, napi_callback_info info); HcfCipher *GetCipher() const; static thread_local napi_ref classRef_; diff --git a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h index ae2dcd3..bfbaac5 100644 --- a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h +++ b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -37,6 +37,11 @@ constexpr uint32_t JS_ERR_OUT_OF_MEMORY = 17620001; constexpr uint32_t JS_ERR_RUNTIME_ERROR = 17620002; constexpr uint32_t JS_ERR_CRYPTO_OPERATION = 17630001; +constexpr int32_t SPEC_ITEM_TYPE_BIG_INT = 1; +constexpr int32_t SPEC_ITEM_TYPE_NUM = 2; +constexpr int32_t SPEC_ITEM_TYPE_STR = 3; +constexpr int32_t SPEC_ITEM_TYPE_UINT8ARR = 4; + const std::string CRYPTO_TAG_DATA = "data"; const std::string CRYPTO_TAG_ERR_CODE = "code"; const std::string CRYPTO_TAG_ERR_MSG = "message"; @@ -44,6 +49,7 @@ const std::string CRYPTO_TAG_ALG_NAME = "algName"; const std::string CRYPTO_TAG_FORMAT = "format"; const std::string CRYPTO_TAG_PUB_KEY = "pubKey"; const std::string CRYPTO_TAG_PRI_KEY = "priKey"; +const std::string CRYPTO_TAG_COMM_PARAMS = "params"; const std::string IV_PARAMS = "iv"; const std::string AAD_PARAMS = "aad"; const std::string AUTHTAG_PARAMS = "authTag"; @@ -52,12 +58,24 @@ const std::string ALGO_PARAMS_OLD = "algoName"; const std::string IV_PARAMS_SPEC = "IvParamsSpec"; const std::string GCM_PARAMS_SPEC = "GcmParamsSpec"; const std::string CCM_PARAMS_SPEC = "CcmParamsSpec"; -const std::string COMMON_ERR_MSG = "An exception occurs."; -enum CfAsyncType { - ASYNC_TYPE_CALLBACK = 1, - ASYNC_TYPE_PROMISE = 2 -}; +const std::string DSA_ASY_KEY_SPEC = "DSA"; +const std::string ECC_ASY_KEY_SPEC = "ECC"; +const std::string RSA_ASY_KEY_SPEC = "RSA"; +const std::string TAG_SPEC_TYPE = "specType"; +const std::string DSA_COMM_ASY_KEY_SPEC = "DsaCommParamsSpec"; +const std::string DSA_PUB_ASY_KEY_SPEC = "DsaPubKeyParamsSpec"; +const std::string DSA_KEYPAIR_ASY_KEY_SPEC = "DsaKeyPairParamsSpec"; + +const std::string ECC_COMM_ASY_KEY_SPEC = "EccCommParamsSpec"; +const std::string ECC_PRI_ASY_KEY_SPEC = "EccPriKeyParamsSpec"; +const std::string ECC_PUB_ASY_KEY_SPEC = "EccPubKeyParamsSpec"; +const std::string ECC_KEYPAIR_ASY_KEY_SPEC = "EccKeyPairParamsSpec"; +const std::string ECC_FIELD_TYPE_FP = "Fp"; + +const std::string RSA_COMM_ASY_KEY_SPEC = "RsaCommParamsSpec"; +const std::string RSA_PUB_ASY_KEY_SPEC = "RsaPubKeyParamsSpec"; +const std::string RSA_KEYPAIR_ASY_KEY_SPEC = "RsaKeyPairParamsSpec"; } // namespace CryptoFramework } // namespace OHOS diff --git a/frameworks/js/napi/crypto/inc/napi_mac.h b/frameworks/js/napi/crypto/inc/napi_mac.h index 3e979f9..133de48 100644 --- a/frameworks/js/napi/crypto/inc/napi_mac.h +++ b/frameworks/js/napi/crypto/inc/napi_mac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022 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 @@ -30,21 +30,18 @@ class NapiMac { public: explicit NapiMac(HcfMac *macObj); ~NapiMac(); + HcfMac *GetMac(); + static thread_local napi_ref classRef_; static void DefineMacJSClass(napi_env env, napi_value exports); static napi_value CreateMac(napi_env env, napi_callback_info info); static napi_value MacConstructor(napi_env env, napi_callback_info info); - napi_value MacInit(napi_env env, napi_callback_info info); - napi_value MacUpdate(napi_env env, napi_callback_info info); - napi_value MacDoFinal(napi_env env, napi_callback_info info); - napi_value GetMacLength(napi_env env, napi_callback_info info); - - HcfMac *GetMac() - { - return macObj_; - } + static napi_value JsMacInit(napi_env env, napi_callback_info info); + static napi_value JsMacUpdate(napi_env env, napi_callback_info info); + static napi_value JsMacDoFinal(napi_env env, napi_callback_info info); + static napi_value JsGetMacLength(napi_env env, napi_callback_info info); private: HcfMac *macObj_ = nullptr; diff --git a/frameworks/js/napi/crypto/inc/napi_md.h b/frameworks/js/napi/crypto/inc/napi_md.h index 50f5d49..0e97c09 100644 --- a/frameworks/js/napi/crypto/inc/napi_md.h +++ b/frameworks/js/napi/crypto/inc/napi_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022 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 @@ -30,20 +30,17 @@ class NapiMd { public: explicit NapiMd(HcfMd *mdObj); ~NapiMd(); + HcfMd *GetMd(); + static thread_local napi_ref classRef_; static void DefineMdJSClass(napi_env env, napi_value exports); static napi_value CreateMd(napi_env env, napi_callback_info info); static napi_value MdConstructor(napi_env env, napi_callback_info info); - napi_value MdUpdate(napi_env env, napi_callback_info info); - napi_value MdDoFinal(napi_env env, napi_callback_info info); - napi_value GetMdLength(napi_env env, napi_callback_info info); - - HcfMd *GetMd() - { - return mdObj_; - } + static napi_value JsMdUpdate(napi_env env, napi_callback_info info); + static napi_value JsMdDoFinal(napi_env env, napi_callback_info info); + static napi_value JsGetMdLength(napi_env env, napi_callback_info info); private: HcfMd *mdObj_ = nullptr; diff --git a/frameworks/js/napi/crypto/inc/napi_pri_key.h b/frameworks/js/napi/crypto/inc/napi_pri_key.h index b87dd94..8046cff 100644 --- a/frameworks/js/napi/crypto/inc/napi_pri_key.h +++ b/frameworks/js/napi/crypto/inc/napi_pri_key.h @@ -38,6 +38,7 @@ public: static napi_value JsGetEncoded(napi_env env, napi_callback_info info); static napi_value JsClearMem(napi_env env, napi_callback_info info); + static napi_value JsGetAsyKeySpec(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; }; diff --git a/frameworks/js/napi/crypto/inc/napi_pub_key.h b/frameworks/js/napi/crypto/inc/napi_pub_key.h index 389aaca..a1ce1d0 100644 --- a/frameworks/js/napi/crypto/inc/napi_pub_key.h +++ b/frameworks/js/napi/crypto/inc/napi_pub_key.h @@ -37,6 +37,7 @@ public: static napi_value PubKeyConstructor(napi_env env, napi_callback_info info); static napi_value JsGetEncoded(napi_env env, napi_callback_info info); + static napi_value JsGetAsyKeySpec(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; }; diff --git a/frameworks/js/napi/crypto/inc/napi_rand.h b/frameworks/js/napi/crypto/inc/napi_rand.h index 927ada8..5858ab0 100644 --- a/frameworks/js/napi/crypto/inc/napi_rand.h +++ b/frameworks/js/napi/crypto/inc/napi_rand.h @@ -30,19 +30,18 @@ class NapiRand { public: explicit NapiRand(HcfRand *randObj); ~NapiRand(); + HcfRand *GetRand(); + static thread_local napi_ref classRef_; static void DefineRandJSClass(napi_env env, napi_value exports); static napi_value CreateRand(napi_env env, napi_callback_info info); static napi_value RandConstructor(napi_env env, napi_callback_info info); - napi_value GenerateRandom(napi_env env, napi_callback_info info); - napi_value SetSeed(napi_env env, napi_callback_info info); - - HcfRand *GetRand() - { - return randObj_; - } + static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); + static napi_value JsGenerateRandom(napi_env env, napi_callback_info info); + static napi_value JsGenerateRandomSync(napi_env env, napi_callback_info info); + static napi_value JsSetSeed(napi_env env, napi_callback_info info); private: HcfRand *randObj_ = nullptr; diff --git a/frameworks/js/napi/crypto/inc/napi_sign.h b/frameworks/js/napi/crypto/inc/napi_sign.h index e4f7776..4833806 100644 --- a/frameworks/js/napi/crypto/inc/napi_sign.h +++ b/frameworks/js/napi/crypto/inc/napi_sign.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,6 +39,9 @@ public: static napi_value JsUpdate(napi_env env, napi_callback_info info); static napi_value JsSign(napi_env env, napi_callback_info info); + static napi_value JsSetSignSpec(napi_env env, napi_callback_info info); + static napi_value JsGetSignSpec(napi_env env, napi_callback_info info); + static thread_local napi_ref classRef_; private: diff --git a/frameworks/js/napi/crypto/inc/napi_utils.h b/frameworks/js/napi/crypto/inc/napi_utils.h index 0adb0cb..30858e1 100644 --- a/frameworks/js/napi/crypto/inc/napi_utils.h +++ b/frameworks/js/napi/crypto/inc/napi_utils.h @@ -18,11 +18,15 @@ #include #include -#include "napi/native_api.h" -#include "napi/native_node_api.h" -#include "blob.h" + #include "algorithm_parameter.h" +#include "blob.h" +#include "big_integer.h" #include "cipher.h" +#include "asy_key_params.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "signature.h" namespace OHOS { namespace CryptoFramework { @@ -44,17 +48,29 @@ inline void AddUint32Property(napi_env env, napi_value object, const char *name, } HcfBlob *GetBlobFromNapiValue(napi_env env, napi_value arg); + +HcfBlob *GeneralGetBlobFromNapiValue(napi_env env, napi_value data); + bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec); napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob); +napi_value ConvertCipherBlobToNapiValue(napi_env env, HcfBlob *blob); + +bool GetAsyKeySpecFromNapiValue(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec); +napi_value ConvertBigIntToNapiValue(napi_env env, HcfBigInteger *blob); + bool GetStringFromJSParams(napi_env env, napi_value arg, std::string &returnStr); bool GetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt); bool GetUint32FromJSParams(napi_env env, napi_value arg, uint32_t &returnInt); bool GetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb); bool CheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync); +bool isCallback(napi_env env, napi_value argv, size_t argc, size_t expectedArgc); napi_value GetResourceName(napi_env env, const char *name); napi_value NapiGetNull(napi_env env); -napi_value GenerateBusinessError(napi_env env, int32_t errCode, const char *errMsg); +napi_value GenerateBusinessError(napi_env env, HcfResult errCode, const char *errMsg); +int32_t GetAsyKeySpecType(AsyKeySpecItem targetItemType); +int32_t GetSignSpecType(SignSpecItem targetItemType); +int32_t GetCipherSpecType(CipherSpecItem targetItemType); } // namespace CryptoFramework } // namespace OHOS #endif diff --git a/frameworks/js/napi/crypto/inc/napi_verify.h b/frameworks/js/napi/crypto/inc/napi_verify.h index 705c067..f7211ab 100644 --- a/frameworks/js/napi/crypto/inc/napi_verify.h +++ b/frameworks/js/napi/crypto/inc/napi_verify.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,6 +39,9 @@ public: static napi_value JsUpdate(napi_env env, napi_callback_info info); static napi_value JsVerify(napi_env env, napi_callback_info info); + static napi_value JsSetVerifySpec(napi_env env, napi_callback_info info); + static napi_value JsGetVerifySpec(napi_env env, napi_callback_info info); + static thread_local napi_ref classRef_; private: diff --git a/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp b/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp index ee947fd..8405e73 100644 --- a/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -36,11 +36,12 @@ struct GenKeyPairCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfAsyKeyGenerator *generator; - HcfParamsSpec *params; + HcfAsyKeyGenerator *generator = nullptr; + HcfParamsSpec *params = nullptr; - HcfResult result; - HcfKeyPair *returnKeyPair; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; + HcfKeyPair *returnKeyPair = nullptr; }; struct ConvertKeyCtx { @@ -52,13 +53,14 @@ struct ConvertKeyCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfAsyKeyGenerator *generator; - HcfParamsSpec *params; - HcfBlob *pubKey; - HcfBlob *priKey; + HcfAsyKeyGenerator *generator = nullptr; + HcfParamsSpec *params = nullptr; + HcfBlob *pubKey = nullptr; + HcfBlob *priKey = nullptr; - HcfResult result; - HcfKeyPair *returnKeyPair; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; + HcfKeyPair *returnKeyPair = nullptr; }; thread_local napi_ref NapiAsyKeyGenerator::classRef_ = nullptr; @@ -114,16 +116,14 @@ static bool BuildGenKeyPairCtx(napi_env env, napi_callback_info info, GenKeyPair napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[0], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiAsyKeyGenerator *napiGenerator; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); - if (status != napi_ok) { + if (status != napi_ok || napiGenerator == nullptr) { LOGE("failed to unwrap napi asyKeyGenerator obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -148,8 +148,6 @@ static bool GetPkAndSkBlobFromNapiValueIfInput(napi_env env, napi_value pkValue, pubKey = GetBlobFromNapiValue(env, pkValue); if (pubKey == nullptr) { LOGE("failed to get pubKey."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[PubKey]: must be of the DataBlob type.")); return false; } } @@ -160,8 +158,6 @@ static bool GetPkAndSkBlobFromNapiValueIfInput(napi_env env, napi_value pkValue, priKey = GetBlobFromNapiValue(env, skValue); if (priKey == nullptr) { LOGE("failed to get priKey."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[PriKey]: must be of the DataBlob type.")); return false; } } @@ -180,16 +176,14 @@ static bool BuildConvertKeyCtx(napi_env env, napi_callback_info info, ConvertKey napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiAsyKeyGenerator *napiGenerator; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); - if (status != napi_ok) { + if (status != napi_ok || napiGenerator == nullptr) { LOGE("failed to unwrap napi asyKeyGenerator obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -215,8 +209,8 @@ static bool BuildConvertKeyCtx(napi_env env, napi_callback_info info, ConvertKey static void ReturnGenKeyPairCallbackResult(napi_env env, GenKeyPairCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -232,19 +226,19 @@ static void ReturnGenKeyPairCallbackResult(napi_env env, GenKeyPairCtx *ctx, nap static void ReturnGenKeyPairPromiseResult(napi_env env, GenKeyPairCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnConvertKeyCallbackResult(napi_env env, ConvertKeyCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -260,11 +254,11 @@ static void ReturnConvertKeyCallbackResult(napi_env env, ConvertKeyCtx *ctx, nap static void ReturnConvertKeyPromiseResult(napi_env env, ConvertKeyCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -272,11 +266,10 @@ static void GenKeyPairAsyncWorkProcess(napi_env env, void *data) { GenKeyPairCtx *ctx = static_cast(data); - HcfResult res = ctx->generator->generateKeyPair(ctx->generator, ctx->params, &(ctx->returnKeyPair)); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->generator->generateKeyPair(ctx->generator, ctx->params, &(ctx->returnKeyPair)); + if (ctx->errCode != HCF_SUCCESS) { LOGE("generate key pair fail."); + ctx->errMsg = "generate key pair fail."; } } @@ -285,18 +278,29 @@ static void GenKeyPairAsyncWorkReturn(napi_env env, napi_status status, void *da GenKeyPairCtx *ctx = static_cast(data); napi_value instance = nullptr; - if (ctx->result == HCF_SUCCESS) { - NapiKeyPair *napiKeyPair = new NapiKeyPair(ctx->returnKeyPair); + if (ctx->errCode == HCF_SUCCESS) { + NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair); + if (napiKeyPair == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!")); + LOGE("new napi key pair failed"); + FreeGenKeyPairCtx(env, ctx); + return; + } instance = napiKeyPair->ConvertToJsKeyPair(env); - napi_wrap( + napi_status ret = napi_wrap( env, instance, napiKeyPair, [](napi_env env, void *data, void *hint) { NapiKeyPair *keyPair = static_cast(data); delete keyPair; return; - }, - nullptr, nullptr); + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiKeyPair obj!"); + ctx->errCode = HCF_INVALID_PARAMS; + ctx->errMsg = "failed to wrap napiKeyPair obj!"; + delete napiKeyPair; + } } if (ctx->asyncType == ASYNC_CALLBACK) { @@ -311,12 +315,11 @@ static void ConvertKeyAsyncWorkProcess(napi_env env, void *data) { ConvertKeyCtx *ctx = static_cast(data); - HcfResult res = ctx->generator->convertKey(ctx->generator, ctx->params, + ctx->errCode = ctx->generator->convertKey(ctx->generator, ctx->params, ctx->pubKey, ctx->priKey, &(ctx->returnKeyPair)); - - ctx->result = res; - if (res != HCF_SUCCESS) { + if (ctx->errCode != HCF_SUCCESS) { LOGE("convert key fail."); + ctx->errMsg = "convert key fail."; } } @@ -325,18 +328,29 @@ static void ConvertKeyAsyncWorkReturn(napi_env env, napi_status status, void *da ConvertKeyCtx *ctx = static_cast(data); napi_value instance = nullptr; - if (ctx->result == HCF_SUCCESS) { - NapiKeyPair *napiKeyPair = new NapiKeyPair(ctx->returnKeyPair); + if (ctx->errCode == HCF_SUCCESS) { + NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair); + if (napiKeyPair == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!")); + LOGE("new napi key pair failed"); + FreeConvertKeyCtx(env, ctx); + return; + } instance = napiKeyPair->ConvertToJsKeyPair(env); - napi_wrap( + napi_status ret = napi_wrap( env, instance, napiKeyPair, [](napi_env env, void *data, void *hint) { NapiKeyPair *keyPair = static_cast(data); delete keyPair; return; - }, - nullptr, nullptr); + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiKeyPair obj!"); + ctx->errCode = HCF_INVALID_PARAMS; + ctx->errMsg = "failed to wrap napiKeyPair obj!"; + delete napiKeyPair; + } } if (ctx->asyncType == ASYNC_CALLBACK) { @@ -369,9 +383,7 @@ static napi_value NewGenKeyPairAsyncWork(napi_env env, GenKeyPairCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -397,9 +409,7 @@ static napi_value NewConvertKeyAsyncWork(napi_env env, ConvertKeyCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -420,15 +430,15 @@ HcfAsyKeyGenerator *NapiAsyKeyGenerator::GetAsyKeyGenerator() napi_value NapiAsyKeyGenerator::JsGenerateKeyPair(napi_env env, napi_callback_info info) { - LOGI("enter ..."); GenKeyPairCtx *ctx = static_cast(HcfMalloc(sizeof(GenKeyPairCtx), 0)); if (ctx == nullptr) { - LOGE("create context fail."); napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc ctx fail.")); + LOGE("create context fail."); return nullptr; } if (!BuildGenKeyPairCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeGenKeyPairCtx(env, ctx); return nullptr; @@ -439,14 +449,15 @@ napi_value NapiAsyKeyGenerator::JsGenerateKeyPair(napi_env env, napi_callback_in napi_value NapiAsyKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info) { - LOGI("enter ..."); ConvertKeyCtx *ctx = static_cast(HcfMalloc(sizeof(ConvertKeyCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); LOGE("create context fail."); return nullptr; } if (!BuildConvertKeyCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeConvertKeyCtx(env, ctx); return nullptr; @@ -457,24 +468,38 @@ napi_value NapiAsyKeyGenerator::JsConvertKey(napi_env env, napi_callback_info in napi_value NapiAsyKeyGenerator::AsyKeyGeneratorConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } +static napi_value NapiWrapAsyKeyGen(napi_env env, napi_value instance, NapiAsyKeyGenerator *napiAsyKeyGenerator) +{ + napi_status status = napi_wrap( + env, instance, napiAsyKeyGenerator, + [](napi_env env, void *data, void *hint) { + NapiAsyKeyGenerator *napiAsyKeyGenerator = static_cast(data); + delete napiAsyKeyGenerator; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiAsyKeyGenerator obj!")); + delete napiAsyKeyGenerator; + napiAsyKeyGenerator = nullptr; + LOGE("failed to wrap napiAsyKeyGenerator obj!"); + return nullptr; + } + return instance; +} + napi_value NapiAsyKeyGenerator::CreateJsAsyKeyGenerator(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = expectedArgc; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return NapiGetNull(env); } @@ -486,35 +511,32 @@ napi_value NapiAsyKeyGenerator::CreateJsAsyKeyGenerator(napi_env env, napi_callb std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName.")); LOGE("failed to get algoName."); return NapiGetNull(env); } HcfAsyKeyGenerator *generator = nullptr; - int32_t res = HcfAsyKeyGeneratorCreate(algName.c_str(), &generator); + HcfResult res = HcfAsyKeyGeneratorCreate(algName.c_str(), &generator); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c generator fail.")); LOGE("create c generator fail."); return NapiGetNull(env); } - NapiAsyKeyGenerator *napiAsyKeyGenerator = new NapiAsyKeyGenerator(generator); - - napi_wrap( - env, instance, napiAsyKeyGenerator, - [](napi_env env, void *data, void *hint) { - NapiAsyKeyGenerator *napiAsyKeyGenerator = static_cast(data); - delete napiAsyKeyGenerator; - return; - }, - nullptr, - nullptr); + NapiAsyKeyGenerator *napiAsyKeyGenerator = new (std::nothrow) NapiAsyKeyGenerator(generator); + if (napiAsyKeyGenerator == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi asy key napi generator failed!")); + LOGE("new napi asy key napi generator failed"); + HcfObjDestroy(generator); + return NapiGetNull(env); + } napi_value napiAlgName = nullptr; napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); - LOGI("out ..."); - return instance; + return NapiWrapAsyKeyGen(env, instance, napiAsyKeyGenerator); } void NapiAsyKeyGenerator::DefineAsyKeyGeneratorJSClass(napi_env env, napi_value exports) diff --git a/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp b/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp new file mode 100644 index 0000000..f9f6ce0 --- /dev/null +++ b/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp @@ -0,0 +1,531 @@ +/* + * Copyright (C) 2022-2023 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 "napi_asy_key_spec_generator.h" + +#include "asy_key_params.h" +#include "securec.h" +#include "log.h" +#include "memory.h" + +#include "napi_crypto_framework_defines.h" +#include "napi_utils.h" +#include "napi_key_pair.h" +#include "napi_pri_key.h" +#include "napi_pub_key.h" + +namespace OHOS { +namespace CryptoFramework { +struct AsyKeyCtx { + napi_env env = nullptr; + + AsyncType asyncType = ASYNC_CALLBACK; + napi_ref callback = nullptr; + napi_deferred deferred = nullptr; + napi_value promise = nullptr; + napi_async_work asyncWork = nullptr; + + HcfAsyKeyGeneratorBySpec *generator; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; + HcfKeyPair *returnKeyPair = nullptr; + HcfPubKey *returnPubKey = nullptr; + HcfPriKey *returnPriKey = nullptr; +}; + +thread_local napi_ref NapiAsyKeyGeneratorBySpec::classRef_ = nullptr; + +static void FreeAsyKeyCtx(napi_env env, AsyKeyCtx *ctx) +{ + if (ctx == nullptr) { + return; + } + + if (ctx->asyncWork != nullptr) { + napi_delete_async_work(env, ctx->asyncWork); + ctx->asyncWork = nullptr; + } + + if (ctx->callback != nullptr) { + napi_delete_reference(env, ctx->callback); + ctx->callback = nullptr; + } + HcfFree(ctx); +} + +static bool BuildAsyKeyCtx(napi_env env, napi_callback_info info, AsyKeyCtx *ctx) +{ + napi_value thisVar = nullptr; + size_t expectedArgc = PARAMS_NUM_ONE; + size_t argc = expectedArgc; + napi_value argv[PARAMS_NUM_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc && argc != expectedArgc - 1) { + LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); + return false; + } + ctx->asyncType = isCallback(env, argv[0], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + + NapiAsyKeyGeneratorBySpec *napiGenerator; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (status != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap napi asyKeyGenerator obj."); + return false; + } + ctx->generator = napiGenerator->GetAsyKeyGeneratorBySpec(); + if (ctx->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &ctx->deferred, &ctx->promise); + return true; + } else { + return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback); + } +} + +static void ReturnAsyKeyCallbackResult(napi_env env, AsyKeyCtx *ctx, napi_value result) +{ + napi_value businessError = nullptr; + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); + } + + napi_value params[ARGS_SIZE_TWO] = { businessError, result }; + + napi_value func = nullptr; + napi_get_reference_value(env, ctx->callback, &func); + + napi_value recv = nullptr; + napi_value callFuncRet = nullptr; + napi_get_undefined(env, &recv); + napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet); +} + +static void ReturnAsyKeyPromiseResult(napi_env env, AsyKeyCtx *ctx, napi_value result) +{ + if (ctx->errCode == HCF_SUCCESS) { + napi_resolve_deferred(env, ctx->deferred, result); + } else { + napi_reject_deferred(env, ctx->deferred, + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); + } +} + +static void GenKeyPairAsyncWorkProcess(napi_env env, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + ctx->errCode = ctx->generator->generateKeyPair(ctx->generator, &(ctx->returnKeyPair)); + if (ctx->errCode != HCF_SUCCESS) { + LOGE("generate key pair fail."); + ctx->errMsg = "generate key pair fail."; + } +} + +static void GenKeyPairAsyncWorkReturn(napi_env env, napi_status status, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + napi_value instance = nullptr; + if (ctx->errCode == HCF_SUCCESS) { + NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair); + if (napiKeyPair == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!")); + LOGE("new napi key pair failed"); + FreeAsyKeyCtx(env, ctx); + return; + } + instance = napiKeyPair->ConvertToJsKeyPair(env); + + napi_status ret = napi_wrap( + env, instance, napiKeyPair, + [](napi_env env, void *data, void *hint) { + NapiKeyPair *keyPair = static_cast(data); + delete keyPair; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiKeyPair obj!"); + ctx->errCode = HCF_INVALID_PARAMS; + ctx->errMsg = "failed to wrap napiKeyPair obj!"; + delete napiKeyPair; + } + } + + if (ctx->asyncType == ASYNC_CALLBACK) { + ReturnAsyKeyCallbackResult(env, ctx, instance); + } else { + ReturnAsyKeyPromiseResult(env, ctx, instance); + } + FreeAsyKeyCtx(env, ctx); +} + +static void PubKeyAsyncWorkProcess(napi_env env, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + ctx->errCode = ctx->generator->generatePubKey(ctx->generator, &(ctx->returnPubKey)); + if (ctx->errCode != HCF_SUCCESS) { + LOGE("generate PubKey fail."); + ctx->errMsg = "generate PubKey fail."; + } +} + +static void PubKeyAsyncWorkReturn(napi_env env, napi_status status, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + napi_value instance = nullptr; + if (ctx->errCode == HCF_SUCCESS) { + NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(ctx->returnPubKey); + if (napiPubKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pub key failed!")); + LOGE("new napi pub key failed"); + FreeAsyKeyCtx(env, ctx); + return; + } + instance = napiPubKey->ConvertToJsPubKey(env); + + napi_status ret = napi_wrap( + env, instance, napiPubKey, + [](napi_env env, void *data, void *hint) { + NapiPubKey *napiPubKey = static_cast(data); + HcfObjDestroy(napiPubKey->GetPubKey()); + delete napiPubKey; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiPubKey obj!"); + ctx->errCode = HCF_INVALID_PARAMS; + ctx->errMsg = "failed to wrap napiPubKey obj!"; + delete napiPubKey; + } + } + + if (ctx->asyncType == ASYNC_CALLBACK) { + ReturnAsyKeyCallbackResult(env, ctx, instance); + } else { + ReturnAsyKeyPromiseResult(env, ctx, instance); + } + FreeAsyKeyCtx(env, ctx); +} + +static void PriKeyAsyncWorkProcess(napi_env env, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + ctx->errCode = ctx->generator->generatePriKey(ctx->generator, &(ctx->returnPriKey)); + if (ctx->errCode != HCF_SUCCESS) { + LOGE("generate PriKey fail."); + ctx->errMsg = "generate PriKey fail."; + } +} + +static void PriKeyAsyncWorkReturn(napi_env env, napi_status status, void *data) +{ + AsyKeyCtx *ctx = static_cast(data); + + napi_value instance = nullptr; + if (ctx->errCode == HCF_SUCCESS) { + NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(ctx->returnPriKey); + if (napiPriKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pri key failed!")); + LOGE("new napi pri key failed"); + FreeAsyKeyCtx(env, ctx); + return; + } + instance = napiPriKey->ConvertToJsPriKey(env); + + napi_status ret = napi_wrap( + env, instance, napiPriKey, + [](napi_env env, void *data, void *hint) { + NapiPriKey *napiPriKey = static_cast(data); + HcfObjDestroy(napiPriKey->GetPriKey()); + delete napiPriKey; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiPriKey obj!"); + ctx->errCode = HCF_INVALID_PARAMS; + ctx->errMsg = "failed to wrap napiPriKey obj!"; + delete napiPriKey; + } + } + + if (ctx->asyncType == ASYNC_CALLBACK) { + ReturnAsyKeyCallbackResult(env, ctx, instance); + } else { + ReturnAsyKeyPromiseResult(env, ctx, instance); + } + FreeAsyKeyCtx(env, ctx); +} + +static napi_value NewGenKeyPairAsyncWork(napi_env env, AsyKeyCtx *ctx) +{ + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "generateKeyPair", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work( + env, nullptr, resourceName, + [](napi_env env, void *data) { + GenKeyPairAsyncWorkProcess(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + GenKeyPairAsyncWorkReturn(env, status, data); + return; + }, + static_cast(ctx), + &ctx->asyncWork); + + napi_queue_async_work(env, ctx->asyncWork); + if (ctx->asyncType == ASYNC_PROMISE) { + return ctx->promise; + } else { + return NapiGetNull(env); + } +} + +static napi_value NewPubKeyAsyncWork(napi_env env, AsyKeyCtx *ctx) +{ + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "generatePubKey", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work( + env, nullptr, resourceName, + [](napi_env env, void *data) { + PubKeyAsyncWorkProcess(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + PubKeyAsyncWorkReturn(env, status, data); + return; + }, + static_cast(ctx), + &ctx->asyncWork); + + napi_queue_async_work(env, ctx->asyncWork); + if (ctx->asyncType == ASYNC_PROMISE) { + return ctx->promise; + } else { + return NapiGetNull(env); + } +} + +static napi_value NewPriKeyAsyncWork(napi_env env, AsyKeyCtx *ctx) +{ + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "generatePriKey", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work( + env, nullptr, resourceName, + [](napi_env env, void *data) { + PriKeyAsyncWorkProcess(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + PriKeyAsyncWorkReturn(env, status, data); + return; + }, + static_cast(ctx), + &ctx->asyncWork); + + napi_queue_async_work(env, ctx->asyncWork); + if (ctx->asyncType == ASYNC_PROMISE) { + return ctx->promise; + } else { + return NapiGetNull(env); + } +} + +NapiAsyKeyGeneratorBySpec::NapiAsyKeyGeneratorBySpec(HcfAsyKeyGeneratorBySpec *generator) +{ + this->generator_ = generator; +} + +NapiAsyKeyGeneratorBySpec::~NapiAsyKeyGeneratorBySpec() +{ + HcfObjDestroy(this->generator_); +} + +HcfAsyKeyGeneratorBySpec *NapiAsyKeyGeneratorBySpec::GetAsyKeyGeneratorBySpec() +{ + return this->generator_; +} + +napi_value NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair(napi_env env, napi_callback_info info) +{ + AsyKeyCtx *ctx = static_cast(HcfMalloc(sizeof(AsyKeyCtx), 0)); + if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); + LOGE("create context fail."); + return nullptr; + } + + if (!BuildAsyKeyCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!")); + LOGE("build context fail."); + FreeAsyKeyCtx(env, ctx); + return nullptr; + } + + return NewGenKeyPairAsyncWork(env, ctx); +} + +napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKey(napi_env env, napi_callback_info info) +{ + AsyKeyCtx *ctx = static_cast(HcfMalloc(sizeof(AsyKeyCtx), 0)); + if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); + LOGE("create context fail."); + return nullptr; + } + + if (!BuildAsyKeyCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!")); + LOGE("build context fail."); + FreeAsyKeyCtx(env, ctx); + return nullptr; + } + + return NewPubKeyAsyncWork(env, ctx); +} + +napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKey(napi_env env, napi_callback_info info) +{ + AsyKeyCtx *ctx = static_cast(HcfMalloc(sizeof(AsyKeyCtx), 0)); + if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); + LOGE("create context fail."); + return nullptr; + } + + if (!BuildAsyKeyCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!")); + LOGE("build context fail."); + FreeAsyKeyCtx(env, ctx); + return nullptr; + } + + return NewPriKeyAsyncWork(env, ctx); +} + +napi_value NapiAsyKeyGeneratorBySpec::AsyKeyGeneratorBySpecConstructor(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + return thisVar; +} + +napi_value NapiAsyKeyGeneratorBySpec::CreateJsAsyKeyGeneratorBySpec(napi_env env, napi_callback_info info) +{ + size_t expectedArgc = PARAMS_NUM_ONE; + size_t argc = expectedArgc; + napi_value argv[PARAMS_NUM_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); + LOGE("The input args num is invalid."); + return nullptr; + } + + napi_value instance; + napi_value constructor = nullptr; + napi_get_reference_value(env, classRef_, &constructor); + napi_new_instance(env, constructor, argc, argv, &instance); + + HcfAsyKeyParamsSpec *asyKeySpec = nullptr; + if (!GetAsyKeySpecFromNapiValue(env, argv[0], &asyKeySpec)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get valid asyKeySpec!")); + LOGE("GetAsyKeySpecFromNapiValue failed!"); + return nullptr; + } + HcfAsyKeyGeneratorBySpec *generator = nullptr; + HcfResult res = HcfAsyKeyGeneratorBySpecCreate(asyKeySpec, &generator); + FreeAsyKeySpec(asyKeySpec); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "create C generator by sepc fail.")); + LOGE("create C generator by spec fail."); + return nullptr; + } + + NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = new (std::nothrow) NapiAsyKeyGeneratorBySpec(generator); + if (napiAsyKeyGeneratorBySpec == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi asy key generator by spec failed!")); + LOGE("new napi asy key generator by spec failed!"); + HcfObjDestroy(generator); + return nullptr; + } + + napi_status status = napi_wrap(env, instance, napiAsyKeyGeneratorBySpec, + [](napi_env env, void *data, void *hint) { + NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = static_cast(data); + delete napiAsyKeyGeneratorBySpec; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, + "failed to wrap napiAsyKeyGeneratorBySpec obj!")); + LOGE("failed to wrap napiAsyKeyGeneratorBySpec obj!"); + delete napiAsyKeyGeneratorBySpec; + return nullptr; + } + return instance; +} + +napi_value NapiAsyKeyGeneratorBySpec::JsGetAlgorithm(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiAsyKeyGeneratorBySpec)); + if (status != napi_ok || napiAsyKeyGeneratorBySpec == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi asyKeyGenerator obj.")); + LOGE("failed to unwrap napi asyKeyGenerator obj."); + return nullptr; + } + HcfAsyKeyGeneratorBySpec *generator = napiAsyKeyGeneratorBySpec->GetAsyKeyGeneratorBySpec(); + if (generator == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get generator by spec obj!")); + LOGE("fail to get generator by spec obj!"); + return nullptr; + } + + const char *algo = generator->getAlgName(generator); + napi_value instance = nullptr; + napi_create_string_utf8(env, algo, NAPI_AUTO_LENGTH, &instance); + return instance; +} + +void NapiAsyKeyGeneratorBySpec::DefineAsyKeyGeneratorBySpecJSClass(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("createAsyKeyGeneratorBySpec", NapiAsyKeyGeneratorBySpec::CreateJsAsyKeyGeneratorBySpec), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + + napi_property_descriptor classDesc[] = { + DECLARE_NAPI_FUNCTION("generateKeyPair", NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair), + DECLARE_NAPI_FUNCTION("generatePriKey", NapiAsyKeyGeneratorBySpec::JsGeneratePriKey), + DECLARE_NAPI_FUNCTION("generatePubKey", NapiAsyKeyGeneratorBySpec::JsGeneratePubKey), + { .utf8name = "algName", .getter = NapiAsyKeyGeneratorBySpec::JsGetAlgorithm }, + }; + napi_value constructor = nullptr; + napi_define_class(env, "AsyKeyGeneratorBySpec", NAPI_AUTO_LENGTH, + NapiAsyKeyGeneratorBySpec::AsyKeyGeneratorBySpecConstructor, + nullptr, sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor); + napi_create_reference(env, constructor, 1, &classRef_); +} +} // CryptoFramework +} // OHOS diff --git a/frameworks/js/napi/crypto/src/napi_cipher.cpp b/frameworks/js/napi/crypto/src/napi_cipher.cpp index ce22b36..71c618f 100644 --- a/frameworks/js/napi/crypto/src/napi_cipher.cpp +++ b/frameworks/js/napi/crypto/src/napi_cipher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -45,7 +45,7 @@ struct CipherFwkCtxT { HcfBlob output = { .data = nullptr, .len = 0 }; enum HcfCryptoMode opMode = ENCRYPT_MODE; - int32_t errCode = 0; + HcfResult errCode = HCF_SUCCESS; const char *errMsg = nullptr; }; @@ -134,14 +134,13 @@ bool BuildContextForInit(napi_env env, napi_callback_info info, CipherFwkCtx con napi_value argv[ARGS_SIZE_FOUR] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); LOGE("wrong argument num. require 3 or 4 arguments. [Argc]: %zu!", argc); return false; } - context->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); - if (status != napi_ok) { + if (status != napi_ok || napiCipher == nullptr) { LOGE("failed to unwrap napi napiCipher obj!"); return false; } @@ -150,15 +149,13 @@ bool BuildContextForInit(napi_env env, napi_callback_info info, CipherFwkCtx con // get opMode, type is uint32 size_t index = 0; if (napi_get_value_uint32(env, argv[index++], reinterpret_cast(&(context->opMode))) != napi_ok) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get opMode failed!")); LOGE("get opMode failed!"); return false; } // get key, unwrap from JS status = napi_unwrap(env, argv[index++], reinterpret_cast(&napiKey)); - if (status != napi_ok) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi napiSymKey obj!")); + if (status != napi_ok || napiKey == nullptr) { LOGE("failed to unwrap napi napiSymKey obj!"); return false; } @@ -169,7 +166,6 @@ bool BuildContextForInit(napi_env env, napi_callback_info info, CipherFwkCtx con napi_typeof(env, argv[index], &valueType); if (valueType != napi_null) { if (!GetParamsSpecFromNapiValue(env, argv[index], context->opMode, &context->paramsSpec)) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get valid params spec!")); LOGE("GetParamsSpecFromNapiValue failed!"); return false; } @@ -192,15 +188,15 @@ bool BuildContextForUpdate(napi_env env, napi_callback_info info, CipherFwkCtx c size_t argc = ARGS_SIZE_TWO; napi_value argv[ARGS_SIZE_TWO] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + // argc : in & out, receives the actual count of arguments if (argc != expectedArgc && argc != expectedArgc - 1) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "update failed for wrong argument num.")); LOGE("wrong argument num. require 1 or 2 arguments. [Argc]: %zu!", argc); return false; } - context->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); - if (status != napi_ok) { + if (status != napi_ok || napiCipher == nullptr) { LOGE("failed to unwrap napi napiCipher obj!"); return false; } @@ -211,7 +207,6 @@ bool BuildContextForUpdate(napi_env env, napi_callback_info info, CipherFwkCtx c HcfBlob *input = nullptr; input = GetBlobFromNapiValue(env, argv[index++]); if (input == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "update failed for invalid input blob.")); LOGE("GetBlobFromNapiValue failed!"); return false; } @@ -235,15 +230,13 @@ bool BuildContextForFinal(napi_env env, napi_callback_info info, CipherFwkCtx co napi_value argv[ARGS_SIZE_TWO] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "doFinal failed for invalid input blob.")); LOGE("wrong argument num. require 1 or 2 arguments. [Argc]: %zu!", argc); return false; } - context->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); - if (status != napi_ok) { + if (status != napi_ok || napiCipher == nullptr) { LOGE("failed to unwrap napi napiCipher obj!"); return false; } @@ -257,8 +250,6 @@ bool BuildContextForFinal(napi_env env, napi_callback_info info, CipherFwkCtx co HcfBlob *input = nullptr; input = GetBlobFromNapiValue(env, argv[index]); if (input == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "doFinal failed for invalid input blob.")); LOGE("GetBlobFromNapiValue failed!"); return false; } @@ -305,74 +296,46 @@ static void ReturnPromiseResult(napi_env env, CipherFwkCtx context, napi_value r // init execute void AsyncInitProcess(napi_env env, void *data) { - if (data == nullptr) { - return; - } CipherFwkCtx context = static_cast(data); HcfCipher *cipher = context->cipher; HcfParamsSpec *params = context->paramsSpec; HcfKey *key = context->key; - HcfResult res = cipher->init(cipher, context->opMode, key, params); - if (res != HCF_SUCCESS) { - LOGE("init ret:%d", res); - context->errCode = res; + context->errCode = cipher->init(cipher, context->opMode, key, params); + if (context->errCode != HCF_SUCCESS) { + LOGE("init ret:%d", context->errCode); context->errMsg = "init failed."; - return; } - context->errCode = HCF_SUCCESS; } // update execute void AsyncUpdateProcess(napi_env env, void *data) { - if (data == nullptr) { - return; - } CipherFwkCtx context = static_cast(data); HcfCipher *cipher = context->cipher; - HcfResult res = cipher->update(cipher, &context->input, &context->output); - if (res != HCF_SUCCESS) { - LOGE("Update ret:%d!", res); - context->errCode = res; + context->errCode = cipher->update(cipher, &context->input, &context->output); + if (context->errCode != HCF_SUCCESS) { + LOGE("Update ret:%d!", context->errCode); context->errMsg = "update failed."; - return; } - context->errCode = HCF_SUCCESS; } void AsyncDoFinalProcess(napi_env env, void *data) { - if (data == nullptr) { - return; - } CipherFwkCtx context = static_cast(data); HcfCipher *cipher = context->cipher; - HcfResult res = cipher->doFinal(cipher, &context->input, &context->output); - if (res != HCF_SUCCESS) { - LOGE("doFinal ret:%d!", res); - context->errCode = res; + context->errCode = cipher->doFinal(cipher, &context->input, &context->output); + if (context->errCode != HCF_SUCCESS) { + LOGE("doFinal ret:%d!", context->errCode); context->errMsg = "doFinal failed."; - return; - } - context->errCode = HCF_SUCCESS; -} - -napi_value GetNapiNull(napi_env env) -{ - napi_value output = nullptr; - napi_status status = napi_get_null(env, &output); - if (status != napi_ok) { - LOGE("create null napi value failed"); } - return output; } void AsyncInitReturn(napi_env env, napi_status status, void *data) { CipherFwkCtx context = static_cast(data); - napi_value result = GetNapiNull(env); + napi_value result = NapiGetNull(env); if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, result); @@ -388,7 +351,7 @@ void AsyncUpdateReturn(napi_env env, napi_status status, void *data) napi_value instance = ConvertBlobToNapiValue(env, &context->output); if (instance == nullptr) { LOGE("May be nullptr!"); - instance = GetNapiNull(env); + instance = NapiGetNull(env); } if (context->asyncType == ASYNC_CALLBACK) { @@ -405,7 +368,7 @@ void AsyncDoFinalReturn(napi_env env, napi_status status, void *data) napi_value instance = ConvertBlobToNapiValue(env, &context->output); if (instance == nullptr) { LOGE("Maybe in decrypt mode, or CCM crypto maybe occur!"); - instance = GetNapiNull(env); + instance = NapiGetNull(env); } if (context->asyncType == ASYNC_CALLBACK) { @@ -513,11 +476,13 @@ napi_value NapiCipher::JsCipherInit(napi_env env, napi_callback_info info) { CipherFwkCtx context = static_cast(HcfMalloc(sizeof(CipherFwkCtxT), 0)); if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); LOGE("create context fail!"); return nullptr; } if (!BuildContextForInit(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context for init fail!")); LOGE("build context for init fail!"); FreeCipherFwkCtx(env, context); return nullptr; @@ -530,11 +495,13 @@ napi_value NapiCipher::JsCipherUpdate(napi_env env, napi_callback_info info) { CipherFwkCtx context = static_cast(HcfMalloc(sizeof(CipherFwkCtxT), 0)); if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); LOGE("create context fail!"); return nullptr; } if (!BuildContextForUpdate(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context for update fail!")); LOGE("build context for update fail!"); FreeCipherFwkCtx(env, context); return nullptr; @@ -547,11 +514,13 @@ napi_value NapiCipher::JsCipherDoFinal(napi_env env, napi_callback_info info) { CipherFwkCtx context = static_cast(HcfMalloc(sizeof(CipherFwkCtxT), 0)); if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!")); LOGE("create context fail!"); return nullptr; } if (!BuildContextForFinal(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context for final fail!")); LOGE("build context for final fail!"); FreeCipherFwkCtx(env, context); return nullptr; @@ -564,10 +533,10 @@ napi_value NapiCipher::JsGetAlgorithm(napi_env env, napi_callback_info info) napi_value thisVar = nullptr; NapiCipher *napiCipher = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); - if (status != napi_ok) { + if (status != napi_ok || napiCipher == nullptr) { LOGE("failed to unwrap napiCipher obj!"); return nullptr; } @@ -588,7 +557,7 @@ napi_value NapiCipher::JsGetAlgorithm(napi_env env, napi_callback_info info) napi_value NapiCipher::CipherConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); return thisVar; } @@ -598,7 +567,7 @@ napi_value NapiCipher::CreateCipher(napi_env env, napi_callback_info info) size_t expectedArgc = ARGS_SIZE_ONE; size_t argc = ARGS_SIZE_ONE; napi_value argv[ARGS_SIZE_ONE] = { nullptr }; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != expectedArgc) { napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); @@ -609,13 +578,14 @@ napi_value NapiCipher::CreateCipher(napi_env env, napi_callback_info info) // create instance according to input js object napi_value instance = nullptr; napi_value constructor = nullptr; - NAPI_CALL(env, napi_get_reference_value(env, classRef_, &constructor)); - NAPI_CALL(env, napi_new_instance(env, constructor, argc, argv, &instance)); + napi_get_reference_value(env, classRef_, &constructor); + napi_new_instance(env, constructor, argc, argv, &instance); // parse input string std::string algoName; if (!GetStringFromJSParams(env, argv[0], algoName)) { - LOGE("GetStringFromJSParams failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName.")); + LOGE("failed to get algoName."); return nullptr; } @@ -629,6 +599,7 @@ napi_value NapiCipher::CreateCipher(napi_env env, napi_callback_info info) } NapiCipher *napiCipher = new (std::nothrow) NapiCipher(cipher); if (napiCipher == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napiCipher failed!")); LOGE("new napiCipher failed!"); HcfObjDestroy(cipher); return nullptr; @@ -639,10 +610,9 @@ napi_value NapiCipher::CreateCipher(napi_env env, napi_callback_info info) NapiCipher *napiCipher = static_cast(data); delete napiCipher; return; - }, - nullptr, - nullptr); + }, nullptr, nullptr); if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiCipher obj.")); LOGE("failed to wrap napiCipher obj!"); delete napiCipher; return nullptr; @@ -650,6 +620,124 @@ napi_value NapiCipher::CreateCipher(napi_env env, napi_callback_info info) return instance; } +napi_value NapiCipher::JsSetCipherSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiCipher *napiCipher = nullptr; + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + CipherSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get JsGetCipherSpecUint8Array failed!")); + LOGE("get JsGetCipherSpecUint8Array failed!"); + return nullptr; + } + HcfBlob *pSource = nullptr; + pSource = GeneralGetBlobFromNapiValue(env, argv[1]); + if (pSource == nullptr || pSource->len == 0) { + LOGE("failed to get pSource."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, + "[pSource]: must be of the DataBlob type.")); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); + if (status != napi_ok || napiCipher == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiCipher obj!")); + LOGE("failed to unwrap napiCipher obj!"); + return nullptr; + } + HcfCipher *cipher = napiCipher->GetCipher(); + HcfResult res = cipher->setCipherSpecUint8Array(cipher, item, *pSource); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c set cipher spec failed.")); + LOGE("c set cipher spec failed."); + return nullptr; + } + return thisVar; +} + +static napi_value GetCipherSpecString(napi_env env, CipherSpecItem item, HcfCipher *cipher) +{ + char *returnString = nullptr; + HcfResult res = cipher->getCipherSpecString(cipher, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c getCipherSpecString failed.")); + LOGE("c getCipherSpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance); + HcfFree(returnString); + return instance; +} + +static napi_value GetCipherSpecUint8Array(napi_env env, CipherSpecItem item, HcfCipher *cipher) +{ + HcfBlob blob = { .data = nullptr, .len = 0 }; + HcfResult res = cipher->getCipherSpecUint8Array(cipher, item, &blob); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c getCipherSpecUint8Array fail.")); + LOGE("c getCipherSpecUint8Array fail."); + return nullptr; + } + + napi_value instance = ConvertCipherBlobToNapiValue(env, &blob); + HcfBlobDataClearAndFree(&blob); + return instance; +} + +napi_value NapiCipher::JsGetCipherSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiCipher *napiCipher = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + CipherSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getCipherSpecString failed!")); + LOGE("get getCipherSpecString failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); + if (status != napi_ok || napiCipher == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiCipher obj!")); + LOGE("failed to unwrap napiCipher obj!"); + return nullptr; + } + HcfCipher *cipher = napiCipher->GetCipher(); + if (cipher == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get cipher obj!")); + LOGE("failed to get cipher obj!"); + return nullptr; + } + + int32_t type = GetCipherSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetCipherSpecString(env, item, cipher); + } else if (type == SPEC_ITEM_TYPE_UINT8ARR) { + return GetCipherSpecUint8Array(env, item, cipher); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "CipherSpecItem not support!")); + return nullptr; + } +} + void NapiCipher::DefineCipherJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -661,6 +749,8 @@ void NapiCipher::DefineCipherJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiCipher::JsCipherInit), DECLARE_NAPI_FUNCTION("update", NapiCipher::JsCipherUpdate), DECLARE_NAPI_FUNCTION("doFinal", NapiCipher::JsCipherDoFinal), + DECLARE_NAPI_FUNCTION("setCipherSpec", NapiCipher::JsSetCipherSpec), + DECLARE_NAPI_FUNCTION("getCipherSpec", NapiCipher::JsGetCipherSpec), { .utf8name = "algName", .getter = NapiCipher::JsGetAlgorithm }, }; napi_value constructor = nullptr; diff --git a/frameworks/js/napi/crypto/src/napi_init.cpp b/frameworks/js/napi/crypto/src/napi_init.cpp index b5932dc..a2039a5 100644 --- a/frameworks/js/napi/crypto/src/napi_init.cpp +++ b/frameworks/js/napi/crypto/src/napi_init.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -17,6 +17,7 @@ #include "log.h" #include "napi_asy_key_generator.h" +#include "napi_asy_key_spec_generator.h" #include "napi_sym_key_generator.h" #include "napi_cipher.h" #include "napi_key_pair.h" @@ -32,6 +33,8 @@ #include "napi_key.h" #include "napi_utils.h" #include "napi_crypto_framework_defines.h" +#include "key.h" +#include "asy_key_params.h" namespace OHOS { namespace CryptoFramework { @@ -53,6 +56,7 @@ static void DefineCryptoModeProperties(napi_env env, napi_value exports) napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); } +// enum Result in JS static napi_value CreateResultCode(napi_env env) { napi_value resultCode = nullptr; @@ -75,6 +79,110 @@ static void DefineResultCodeProperties(napi_env env, napi_value exports) napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); } +// enum AsyKeySpecItem in JS +static napi_value CreateAsyKeySpecItemCode(napi_env env) +{ + napi_value code = nullptr; + napi_create_object(env, &code); + + AddUint32Property(env, code, "DSA_P_BN", DSA_P_BN); + AddUint32Property(env, code, "DSA_Q_BN", DSA_Q_BN); + AddUint32Property(env, code, "DSA_G_BN", DSA_G_BN); + AddUint32Property(env, code, "DSA_SK_BN", DSA_SK_BN); + AddUint32Property(env, code, "DSA_PK_BN", DSA_PK_BN); + + AddUint32Property(env, code, "ECC_FP_P_BN", ECC_FP_P_BN); + AddUint32Property(env, code, "ECC_A_BN", ECC_A_BN); + AddUint32Property(env, code, "ECC_B_BN", ECC_B_BN); + AddUint32Property(env, code, "ECC_G_X_BN", ECC_G_X_BN); + AddUint32Property(env, code, "ECC_G_Y_BN", ECC_G_Y_BN); + AddUint32Property(env, code, "ECC_N_BN", ECC_N_BN); + AddUint32Property(env, code, "ECC_H_NUM", ECC_H_INT); + AddUint32Property(env, code, "ECC_SK_BN", ECC_SK_BN); + AddUint32Property(env, code, "ECC_PK_X_BN", ECC_PK_X_BN); + AddUint32Property(env, code, "ECC_PK_Y_BN", ECC_PK_Y_BN); + AddUint32Property(env, code, "ECC_FIELD_TYPE_STR", ECC_FIELD_TYPE_STR); + AddUint32Property(env, code, "ECC_FIELD_SIZE_NUM", ECC_FIELD_SIZE_INT); + AddUint32Property(env, code, "ECC_CURVE_NAME_STR", ECC_CURVE_NAME_STR); + + AddUint32Property(env, code, "RSA_N_BN", RSA_N_BN); + AddUint32Property(env, code, "RSA_SK_BN", RSA_SK_BN); + AddUint32Property(env, code, "RSA_PK_BN", RSA_PK_BN); + return code; +} + +static void DefineAsyKeySpecItemProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("AsyKeySpecItem", CreateAsyKeySpecItemCode(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + +// enum AsyKeySpecType in JS +static napi_value CreateAsyKeySpecTypeCode(napi_env env) +{ + napi_value code = nullptr; + napi_create_object(env, &code); + + AddUint32Property(env, code, "COMMON_PARAMS_SPEC", HCF_COMMON_PARAMS_SPEC); + AddUint32Property(env, code, "PRIVATE_KEY_SPEC", HCF_PRIVATE_KEY_SPEC); + AddUint32Property(env, code, "PUBLIC_KEY_SPEC", HCF_PUBLIC_KEY_SPEC); + AddUint32Property(env, code, "KEY_PAIR_SPEC", HCF_KEY_PAIR_SPEC); + return code; +} + +static void DefineAsyKeySpecTypeProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("AsyKeySpecType", CreateAsyKeySpecTypeCode(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + +// enum CipherSpecItem in JS +static napi_value CreateCipherSpecItemCode(napi_env env) +{ + napi_value code = nullptr; + napi_create_object(env, &code); + + AddUint32Property(env, code, "OAEP_MD_NAME_STR", OAEP_MD_NAME_STR); + AddUint32Property(env, code, "OAEP_MGF_NAME_STR", OAEP_MGF_NAME_STR); + AddUint32Property(env, code, "OAEP_MGF1_MD_STR", OAEP_MGF1_MD_STR); + AddUint32Property(env, code, "OAEP_MGF1_PSRC_UINT8ARR", OAEP_MGF1_PSRC_UINT8ARR); + return code; +} + +static void DefineCipherSpecItemProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("CipherSpecItem", CreateCipherSpecItemCode(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + +// enum SignSpecItem in JS +static napi_value CreateSignSpecItemCode(napi_env env) +{ + napi_value code = nullptr; + napi_create_object(env, &code); + + AddUint32Property(env, code, "PSS_MD_NAME_STR", PSS_MD_NAME_STR); + AddUint32Property(env, code, "PSS_MGF_NAME_STR", PSS_MGF_NAME_STR); + AddUint32Property(env, code, "PSS_MGF1_MD_STR", PSS_MGF1_MD_STR); + AddUint32Property(env, code, "PSS_SALT_LEN_NUM", PSS_SALT_LEN_INT); + AddUint32Property(env, code, "PSS_TRAILER_FIELD_NUM", PSS_TRAILER_FIELD_INT); + return code; +} + +static void DefineSignSpecItemProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("SignSpecItem", CreateSignSpecItemCode(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + /*********************************************** * Module export and register ***********************************************/ @@ -84,10 +192,20 @@ static napi_value ModuleExport(napi_env env, napi_value exports) DefineCryptoModeProperties(env, exports); DefineResultCodeProperties(env, exports); - NapiAsyKeyGenerator::DefineAsyKeyGeneratorJSClass(env, exports); - NapiKeyPair::DefineKeyPairJSClass(env); + DefineAsyKeySpecItemProperties(env, exports); + DefineAsyKeySpecTypeProperties(env, exports); + DefineCipherSpecItemProperties(env, exports); + DefineSignSpecItemProperties(env, exports); + + NapiKey::DefineHcfKeyJSClass(env); NapiPubKey::DefinePubKeyJSClass(env); NapiPriKey::DefinePriKeyJSClass(env); + NapiKeyPair::DefineKeyPairJSClass(env); + NapiSymKey::DefineSymKeyJSClass(env); + + NapiAsyKeyGenerator::DefineAsyKeyGeneratorJSClass(env, exports); + NapiAsyKeyGeneratorBySpec::DefineAsyKeyGeneratorBySpecJSClass(env, exports); + NapiSymKeyGenerator::DefineSymKeyGeneratorJSClass(env, exports); NapiSign::DefineSignJSClass(env, exports); NapiVerify::DefineVerifyJSClass(env, exports); @@ -95,10 +213,7 @@ static napi_value ModuleExport(napi_env env, napi_value exports) NapiMac::DefineMacJSClass(env, exports); NapiMd::DefineMdJSClass(env, exports); NapiRand::DefineRandJSClass(env, exports); - NapiSymKeyGenerator::DefineSymKeyGeneratorJSClass(env, exports); NapiCipher::DefineCipherJSClass(env, exports); - NapiSymKey::DefineSymKeyJSClass(env); - NapiKey::DefineHcfKeyJSClass(env); LOGI("module init end."); return exports; } diff --git a/frameworks/js/napi/crypto/src/napi_key.cpp b/frameworks/js/napi/crypto/src/napi_key.cpp index dcbe772..2cfb2ed 100644 --- a/frameworks/js/napi/crypto/src/napi_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -40,10 +40,20 @@ napi_value NapiKey::JsGetAlgorithm(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; NapiKey *napiKey = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiKey))); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiKey)); + if (status != napi_ok || napiKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi key obj.")); + LOGE("failed to unwrap napi key obj."); + return nullptr; + } HcfKey *key = napiKey->GetHcfKey(); + if (key == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get key obj!")); + LOGE("fail to get key obj!"); + return nullptr; + } const char *algo = key->getAlgorithm(key); napi_value instance = nullptr; @@ -55,10 +65,20 @@ napi_value NapiKey::JsGetFormat(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; NapiKey *napiKey = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiKey))); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiKey)); + if (status != napi_ok || napiKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi key obj.")); + LOGE("failed to unwrap napi key obj."); + return nullptr; + } HcfKey *key = napiKey->GetHcfKey(); + if (key == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get key obj!")); + LOGE("fail to get key obj!"); + return nullptr; + } const char *format = key->getFormat(key); napi_value instance = nullptr; @@ -70,10 +90,20 @@ napi_value NapiKey::JsGetEncoded(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; NapiKey *napiKey = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiKey))); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiKey)); + if (status != napi_ok || napiKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi key obj.")); + LOGE("failed to unwrap napi key obj."); + return nullptr; + } HcfKey *key = napiKey->GetHcfKey(); + if (key == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get key obj!")); + LOGE("fail to get key obj!"); + return nullptr; + } HcfBlob blob = { .data = nullptr, .len = 0 }; HcfResult res = key->getEncoded(key, &blob); diff --git a/frameworks/js/napi/crypto/src/napi_key_agreement.cpp b/frameworks/js/napi/crypto/src/napi_key_agreement.cpp index 7fb23eb..cf6e24d 100644 --- a/frameworks/js/napi/crypto/src/napi_key_agreement.cpp +++ b/frameworks/js/napi/crypto/src/napi_key_agreement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -35,12 +35,13 @@ struct KeyAgreementCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfKeyAgreement *keyAgreement; - HcfPriKey *priKey; - HcfPubKey *pubKey; + HcfKeyAgreement *keyAgreement = nullptr; + HcfPriKey *priKey = nullptr; + HcfPubKey *pubKey = nullptr; - HcfResult result; - HcfBlob returnSecret; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; + HcfBlob returnSecret { .data = nullptr, .len = 0 }; }; thread_local napi_ref NapiKeyAgreement::classRef_ = nullptr; @@ -79,34 +80,30 @@ static bool BuildKeyAgreementJsCtx(napi_env env, napi_callback_info info, KeyAgr napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiKeyAgreement *napiKeyAgreement = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiKeyAgreement)); - if (status != napi_ok) { + if (status != napi_ok || napiKeyAgreement == nullptr) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } size_t index = 0; NapiPriKey *napiPriKey = nullptr; status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPriKey)); - if (status != napi_ok) { + if (status != napi_ok || napiPriKey == nullptr) { LOGE("failed to unwrap priKey verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PriKey]: param unwarp error.")); return false; } index++; NapiPubKey *napiPubKey = nullptr; status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPubKey)); - if (status != napi_ok) { + if (status != napi_ok || napiPubKey == nullptr) { LOGE("failed to unwrap napi pubKey obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PubKey]: param unwarp error.")); return false; } @@ -125,8 +122,8 @@ static bool BuildKeyAgreementJsCtx(napi_env env, napi_callback_info info, KeyAgr static void ReturnCallbackResult(napi_env env, KeyAgreementCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -142,11 +139,11 @@ static void ReturnCallbackResult(napi_env env, KeyAgreementCtx *ctx, napi_value static void ReturnPromiseResult(napi_env env, KeyAgreementCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -154,12 +151,11 @@ void KeyAgreementAsyncWorkProcess(napi_env env, void *data) { KeyAgreementCtx *ctx = static_cast(data); - HcfResult res = ctx->keyAgreement->generateSecret(ctx->keyAgreement, + ctx->errCode = ctx->keyAgreement->generateSecret(ctx->keyAgreement, ctx->priKey, ctx->pubKey, &ctx->returnSecret); - - ctx->result = res; - if (res != HCF_SUCCESS) { + if (ctx->errCode != HCF_SUCCESS) { LOGE("generate secret fail."); + ctx->errMsg = "generate secret fail."; } } @@ -168,7 +164,7 @@ void KeyAgreementAsyncWorkReturn(napi_env env, napi_status status, void *data) KeyAgreementCtx *ctx = static_cast(data); napi_value dataBlob = nullptr; - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { dataBlob = ConvertBlobToNapiValue(env, &ctx->returnSecret); } @@ -202,9 +198,7 @@ static napi_value NewKeyAgreementAsyncWork(napi_env env, KeyAgreementCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -225,14 +219,15 @@ HcfKeyAgreement *NapiKeyAgreement::GetKeyAgreement() napi_value NapiKeyAgreement::JsGenerateSecret(napi_env env, napi_callback_info info) { - LOGI("enter ..."); KeyAgreementCtx *ctx = static_cast(HcfMalloc(sizeof(KeyAgreementCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildKeyAgreementJsCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeKeyAgreementCtx(env, ctx); return nullptr; @@ -243,24 +238,19 @@ napi_value NapiKeyAgreement::JsGenerateSecret(napi_env env, napi_callback_info i napi_value NapiKeyAgreement::KeyAgreementConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } napi_value NapiKeyAgreement::CreateJsKeyAgreement(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = PARAMS_NUM_ONE; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } @@ -272,33 +262,44 @@ napi_value NapiKeyAgreement::CreateJsKeyAgreement(napi_env env, napi_callback_in std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Get algName is invalid.")); return nullptr; } HcfKeyAgreement *keyAgreement = nullptr; - int32_t res = HcfKeyAgreementCreate(algName.c_str(), &keyAgreement); + HcfResult res = HcfKeyAgreementCreate(algName.c_str(), &keyAgreement); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "create c keyAgreement fail.")); LOGE("create c keyAgreement fail."); return nullptr; } - NapiKeyAgreement *napiKeyAgreement = new NapiKeyAgreement(keyAgreement); + NapiKeyAgreement *napiKeyAgreement = new (std::nothrow) NapiKeyAgreement(keyAgreement); + if (napiKeyAgreement == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key agreement failed.")); + LOGE("new napi key agreement failed"); + HcfObjDestroy(keyAgreement); + return nullptr; + } - napi_wrap( + napi_value napiAlgName = nullptr; + napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); + napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); + + napi_status status = napi_wrap( env, instance, napiKeyAgreement, [](napi_env env, void *data, void *hint) { NapiKeyAgreement *napiKeyAgreement = static_cast(data); delete napiKeyAgreement; return; - }, - nullptr, - nullptr); - - napi_value napiAlgName = nullptr; - napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); - napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiKeyAgreement obj!")); + LOGE("failed to wrap napiKeyAgreement obj!"); + delete napiKeyAgreement; + return nullptr; + } - LOGI("out ..."); return instance; } diff --git a/frameworks/js/napi/crypto/src/napi_key_pair.cpp b/frameworks/js/napi/crypto/src/napi_key_pair.cpp index a2fb45b..0cd42a9 100644 --- a/frameworks/js/napi/crypto/src/napi_key_pair.cpp +++ b/frameworks/js/napi/crypto/src/napi_key_pair.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -20,6 +20,7 @@ #include "napi_crypto_framework_defines.h" #include "napi_pri_key.h" #include "napi_pub_key.h" +#include "napi_utils.h" namespace OHOS { namespace CryptoFramework { @@ -38,51 +39,62 @@ NapiKeyPair::~NapiKeyPair() napi_value NapiKeyPair::KeyPairConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - LOGI("out ..."); return thisVar; } napi_value NapiKeyPair::ConvertToJsKeyPair(napi_env env) { - LOGI("enter ..."); - napi_value instance; napi_value constructor = nullptr; napi_get_reference_value(env, classRef_, &constructor); napi_new_instance(env, constructor, 0, nullptr, &instance); if (this->keyPair_->pubKey != nullptr) { - NapiPubKey *napiPubKey = new NapiPubKey(this->keyPair_->pubKey); + NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(this->keyPair_->pubKey); + if (napiPubKey == nullptr) { + LOGE("new napi pub key failed"); + return nullptr; + } napi_value pubKey = napiPubKey->ConvertToJsPubKey(env); - napi_wrap( + napi_status status = napi_wrap( env, pubKey, napiPubKey, [](napi_env env, void *data, void *hint) { NapiPubKey *napiPubKey = static_cast(data); delete napiPubKey; return; - }, - nullptr, nullptr); + }, nullptr, nullptr); + if (status != napi_ok) { + LOGE("failed to wrap napiPubKey obj!"); + delete napiPubKey; + return nullptr; + } napi_set_named_property(env, instance, CRYPTO_TAG_PUB_KEY.c_str(), pubKey); } if (this->keyPair_->priKey != nullptr) { - NapiPriKey *napiPriKey = new NapiPriKey(this->keyPair_->priKey); + NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(this->keyPair_->priKey); + if (napiPriKey == nullptr) { + LOGE("new napi pri key failed"); + return nullptr; + } napi_value priKey = napiPriKey->ConvertToJsPriKey(env); - napi_wrap( + napi_status status = napi_wrap( env, priKey, napiPriKey, [](napi_env env, void *data, void *hint) { NapiPriKey *napiPriKey = static_cast(data); delete napiPriKey; return; - }, - nullptr, nullptr); + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiPriKey obj!")); + LOGE("failed to wrap napiPriKey obj!"); + delete napiPriKey; + return nullptr; + } napi_set_named_property(env, instance, CRYPTO_TAG_PRI_KEY.c_str(), priKey); } - - LOGI("out ..."); return instance; } diff --git a/frameworks/js/napi/crypto/src/napi_mac.cpp b/frameworks/js/napi/crypto/src/napi_mac.cpp index 9fcbca6..675805b 100644 --- a/frameworks/js/napi/crypto/src/napi_mac.cpp +++ b/frameworks/js/napi/crypto/src/napi_mac.cpp @@ -30,13 +30,12 @@ thread_local napi_ref NapiMac::classRef_ = nullptr; struct MacCtx { napi_env env = nullptr; - CfAsyncType asyncType = ASYNC_TYPE_CALLBACK; + AsyncType asyncType = ASYNC_CALLBACK; napi_ref callback = nullptr; napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - NapiMac *macClass = nullptr; std::string algoName = ""; HcfSymKey *symKey = nullptr; HcfBlob *inBlob = nullptr; @@ -44,6 +43,7 @@ struct MacCtx { HcfResult errCode = HCF_SUCCESS; const char *errMsg = nullptr; HcfBlob *outBlob = nullptr; + HcfMac *mac = nullptr; }; static void FreeCryptoFwkCtx(napi_env env, MacCtx *context) @@ -75,6 +75,7 @@ static void FreeCryptoFwkCtx(napi_env env, MacCtx *context) context->outBlob = nullptr; } context->errMsg = nullptr; + context->mac = nullptr; HcfFree(context); context = nullptr; } @@ -106,36 +107,10 @@ static void ReturnPromiseResult(napi_env env, MacCtx *context, napi_value result } } -static bool CreateCallbackAndPromise(napi_env env, MacCtx *context, size_t argc, - size_t maxCount, napi_value callbackValue) -{ - context->asyncType = (argc == maxCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE; - if (context->asyncType == ASYNC_TYPE_CALLBACK) { - if (!GetCallbackFromJSParams(env, callbackValue, &context->callback)) { - LOGE("get callback failed!"); - return false; - } - } else { - napi_create_promise(env, &context->deferred, &context->promise); - } - return true; -} - -NapiMac::NapiMac(HcfMac *macObj) -{ - this->macObj_ = macObj; -} - -NapiMac::~NapiMac() -{ - HcfObjDestroy(this->macObj_); -} - static void MacInitExecute(napi_env env, void *data) { MacCtx *context = static_cast(data); - NapiMac *macClass = context->macClass; - HcfMac *macObj = macClass->GetMac(); + HcfMac *macObj = context->mac; HcfSymKey *symKey = context->symKey; context->errCode = macObj->init(macObj, symKey); if (context->errCode != HCF_SUCCESS) { @@ -149,7 +124,7 @@ static void MacInitComplete(napi_env env, napi_status status, void *data) MacCtx *context = static_cast(data); napi_value nullInstance = nullptr; napi_get_null(env, &nullInstance); - if (context->asyncType == ASYNC_TYPE_CALLBACK) { + if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, nullInstance); } else { ReturnPromiseResult(env, context, nullInstance); @@ -160,8 +135,7 @@ static void MacInitComplete(napi_env env, napi_status status, void *data) static void MacUpdateExecute(napi_env env, void *data) { MacCtx *context = static_cast(data); - NapiMac *macClass = context->macClass; - HcfMac *macObj = macClass->GetMac(); + HcfMac *macObj = context->mac; HcfBlob *inBlob = reinterpret_cast(context->inBlob); context->errCode = macObj->update(macObj, inBlob); if (context->errCode != HCF_SUCCESS) { @@ -175,7 +149,7 @@ static void MacUpdateComplete(napi_env env, napi_status status, void *data) MacCtx *context = static_cast(data); napi_value nullInstance = nullptr; napi_get_null(env, &nullInstance); - if (context->asyncType == ASYNC_TYPE_CALLBACK) { + if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, nullInstance); } else { ReturnPromiseResult(env, context, nullInstance); @@ -186,8 +160,7 @@ static void MacUpdateComplete(napi_env env, napi_status status, void *data) static void MacDoFinalExecute(napi_env env, void *data) { MacCtx *context = static_cast(data); - NapiMac *macClass = context->macClass; - HcfMac *macObj = macClass->GetMac(); + HcfMac *macObj = context->mac; HcfBlob *outBlob = reinterpret_cast(HcfMalloc(sizeof(HcfBlob), 0)); if (outBlob == nullptr) { LOGE("outBlob is null!"); @@ -197,10 +170,9 @@ static void MacDoFinalExecute(napi_env env, void *data) } context->errCode = macObj->doFinal(macObj, outBlob); if (context->errCode != HCF_SUCCESS) { + HcfFree(outBlob); LOGE("doFinal failed!"); context->errMsg = "doFinal failed"; - HcfFree(outBlob); - outBlob = nullptr; return; } context->outBlob = outBlob; @@ -214,7 +186,7 @@ static void MacDoFinalComplete(napi_env env, napi_status status, void *data) LOGE("returnOutBlob is nullptr!"); returnOutBlob = NapiGetNull(env); } - if (context->asyncType == ASYNC_TYPE_CALLBACK) { + if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, returnOutBlob); } else { ReturnPromiseResult(env, context, returnOutBlob); @@ -222,188 +194,271 @@ static void MacDoFinalComplete(napi_env env, napi_status status, void *data) FreeCryptoFwkCtx(env, context); } -napi_value NapiMac::MacInit(napi_env env, napi_callback_info info) +static bool BuildMacJsInitCtx(napi_env env, napi_callback_info info, MacCtx *context) { + napi_value thisVar = nullptr; + NapiMac *napiMac = nullptr; size_t expectedArgsCount = ARGS_SIZE_TWO; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_TWO] = { nullptr }; - napi_value thisVar = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) { - return nullptr; + return false; } - MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return nullptr; - } - context->macClass = this; + + context->asyncType = (argc == expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSymKey *symKey = nullptr; - napi_unwrap(env, argv[PARAM0], reinterpret_cast(&symKey)); - if (symKey == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "symKey is null")); + napi_status status = napi_unwrap(env, argv[PARAM0], reinterpret_cast(&symKey)); + if (status != napi_ok || symKey == nullptr) { LOGE("symKey is null!"); - FreeCryptoFwkCtx(env, context); - return nullptr; + return false; } context->symKey = symKey->GetSymKey(); - context->asyncType = (argc == expectedArgsCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE; - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMac)); + if (status != napi_ok || napiMac == nullptr) { + LOGE("failed to unwrap napiMac obj!"); + return false; } - napi_create_async_work( - env, nullptr, GetResourceName(env, "Init"), - MacInitExecute, - MacInitComplete, - static_cast(context), - &context->asyncWork); - napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { - return context->promise; + + context->mac = napiMac->GetMac(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; } else { - return NapiGetNull(env); + return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback); } } -napi_value NapiMac::MacUpdate(napi_env env, napi_callback_info info) +static bool BuildMacJsUpdateCtx(napi_env env, napi_callback_info info, MacCtx *context) { + napi_value thisVar = nullptr; + NapiMac *napiMac = nullptr; size_t expectedArgsCount = ARGS_SIZE_TWO; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_TWO] = { nullptr }; - napi_value thisVar = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) { - return nullptr; - } - MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return nullptr; + return false; } - context->macClass = this; + + context->asyncType = (argc == expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; context->inBlob = GetBlobFromNapiValue(env, argv[PARAM0]); if (context->inBlob == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "inBlob is null")); LOGE("inBlob is null!"); - FreeCryptoFwkCtx(env, context); - return nullptr; + return false; } - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMac)); + if (status != napi_ok || napiMac == nullptr) { + LOGE("failed to unwrap napiMac obj!"); + return false; } - napi_create_async_work( - env, nullptr, GetResourceName(env, "MacUpate"), - MacUpdateExecute, - MacUpdateComplete, - static_cast(context), - &context->asyncWork); - napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { - return context->promise; + + context->mac = napiMac->GetMac(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; } else { - return NapiGetNull(env); + return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback); } } -napi_value NapiMac::MacDoFinal(napi_env env, napi_callback_info info) +static bool BuildMacJsDoFinalCtx(napi_env env, napi_callback_info info, MacCtx *context) { + napi_value thisVar = nullptr; + NapiMac *napiMac = nullptr; size_t expectedArgsCount = ARGS_SIZE_ONE; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_ONE] = { nullptr }; - napi_value thisVar = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (!CheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) { - return nullptr; + return false; } - MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return nullptr; + + context->asyncType = (argc == expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMac)); + if (status != napi_ok || napiMac == nullptr) { + LOGE("failed to unwrap napiMac obj!"); + return false; } - context->macClass = this; - context->asyncType = (argc == expectedArgsCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE; - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + + context->mac = napiMac->GetMac(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; + } else { + return GetCallbackFromJSParams(env, argv[PARAM0], &context->callback); } +} + +static napi_value NewMacJsInitAsyncWork(napi_env env, MacCtx *context) +{ napi_create_async_work( - env, nullptr, GetResourceName(env, "MacDoFinal"), - MacDoFinalExecute, - MacDoFinalComplete, + env, nullptr, GetResourceName(env, "MacInit"), + [](napi_env env, void *data) { + MacInitExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + MacInitComplete(env, status, data); + return; + }, static_cast(context), &context->asyncWork); + napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { + if (context->asyncType == ASYNC_PROMISE) { return context->promise; } else { return NapiGetNull(env); } } -napi_value NapiMac::GetMacLength(napi_env env, napi_callback_info info) +static napi_value NewMacJsUpdateAsyncWork(napi_env env, MacCtx *context) { - HcfMac *macObj = GetMac(); - uint32_t retLen = macObj->getMacLength(macObj); - napi_value napiLen = nullptr; - napi_create_uint32(env, retLen, &napiLen); - return napiLen; + napi_create_async_work( + env, nullptr, GetResourceName(env, "MacUpdate"), + [](napi_env env, void *data) { + MacUpdateExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + MacUpdateComplete(env, status, data); + return; + }, + static_cast(context), + &context->asyncWork); + + napi_queue_async_work(env, context->asyncWork); + if (context->asyncType == ASYNC_PROMISE) { + return context->promise; + } else { + return NapiGetNull(env); + } } -static napi_value NapiMacInit(napi_env env, napi_callback_info info) +static napi_value NewMacJsDoFinalAsyncWork(napi_env env, MacCtx *context) { - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMac *macObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&macObj)); - if (macObj == nullptr) { - LOGE("macObj is nullptr!"); + napi_create_async_work( + env, nullptr, GetResourceName(env, "MacDoFinal"), + [](napi_env env, void *data) { + MacDoFinalExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + MacDoFinalComplete(env, status, data); + return; + }, + static_cast(context), + &context->asyncWork); + + napi_queue_async_work(env, context->asyncWork); + if (context->asyncType == ASYNC_PROMISE) { + return context->promise; + } else { return NapiGetNull(env); } - return macObj->MacInit(env, info); } -static napi_value NapiMacUpdate(napi_env env, napi_callback_info info) + +NapiMac::NapiMac(HcfMac *macObj) { - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMac *macObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&macObj)); - if (macObj == nullptr) { - LOGE("macObj is nullptr!"); - return NapiGetNull(env); + this->macObj_ = macObj; +} + +NapiMac::~NapiMac() +{ + HcfObjDestroy(this->macObj_); +} + +HcfMac *NapiMac::GetMac() +{ + return this->macObj_; +} + +napi_value NapiMac::JsMacInit(napi_env env, napi_callback_info info) +{ + MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; + } + + if (!BuildMacJsInitCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; } - return macObj->MacUpdate(env, info); + + return NewMacJsInitAsyncWork(env, context); } -static napi_value NapiMacDoFinal(napi_env env, napi_callback_info info) +napi_value NapiMac::JsMacUpdate(napi_env env, napi_callback_info info) { - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMac *macObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&macObj)); - if (macObj == nullptr) { - LOGE("macObj is nullptr!"); - return NapiGetNull(env); + MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; } - return macObj->MacDoFinal(env, info); + + if (!BuildMacJsUpdateCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; + } + + return NewMacJsUpdateAsyncWork(env, context); } -static napi_value NapiGetMacLength(napi_env env, napi_callback_info info) +napi_value NapiMac::JsMacDoFinal(napi_env env, napi_callback_info info) +{ + MacCtx *context = static_cast(HcfMalloc(sizeof(MacCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; + } + + if (!BuildMacJsDoFinalCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; + } + + return NewMacJsDoFinalAsyncWork(env, context); +} + +napi_value NapiMac::JsGetMacLength(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; + NapiMac *napiMac = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMac *macObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&macObj)); - if (macObj == nullptr) { - LOGE("macObj is nullptr!"); - return NapiGetNull(env); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMac)); + if (status != napi_ok || napiMac == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiMac obj!")); + LOGE("failed to unwrap napiMac obj!"); + return nullptr; + } + + HcfMac *mac = napiMac->GetMac(); + if (mac == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get mac obj!")); + LOGE("fail to get mac obj!"); + return nullptr; } - return macObj->GetMacLength(env, info); + + uint32_t retLen = mac->getMacLength(mac); + napi_value napiLen = nullptr; + napi_create_uint32(env, retLen, &napiLen); + return napiLen; } napi_value NapiMac::MacConstructor(napi_env env, napi_callback_info info) @@ -413,6 +468,25 @@ napi_value NapiMac::MacConstructor(napi_env env, napi_callback_info info) return thisVar; } +static napi_value NapiWrapMac(napi_env env, napi_value instance, NapiMac *macNapiObj) +{ + napi_status status = napi_wrap( + env, instance, macNapiObj, + [](napi_env env, void *data, void *hint) { + NapiMac *mac = static_cast(data); + delete mac; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap NapiMac obj!")); + delete macNapiObj; + macNapiObj = nullptr; + LOGE("failed to wrap NapiMac obj!"); + return nullptr; + } + return instance; +} + napi_value NapiMac::CreateMac(napi_env env, napi_callback_info info) { size_t expectedArgc = ARGS_SIZE_ONE; @@ -420,11 +494,13 @@ napi_value NapiMac::CreateMac(napi_env env, napi_callback_info info) napi_value argv[ARGS_SIZE_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } std::string algoName; if (!GetStringFromJSParams(env, argv[PARAM0], algoName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Failed to get algorithm.")); LOGE("Failed to get algorithm."); return nullptr; } @@ -444,32 +520,26 @@ napi_value NapiMac::CreateMac(napi_env env, napi_callback_info info) napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); NapiMac *macNapiObj = new (std::nothrow) NapiMac(macObj); if (macNapiObj == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new mac napi obj failed.")); + HcfObjDestroy(macObj); LOGE("create napi obj failed"); return nullptr; } - napi_wrap( - env, instance, macNapiObj, - [](napi_env env, void *data, void *hint) { - NapiMac *mac = static_cast(data); - delete mac; - return; - }, - nullptr, - nullptr); - return instance; + + return NapiWrapMac(env, instance, macNapiObj); } void NapiMac::DefineMacJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("createMac", CreateMac), + DECLARE_NAPI_FUNCTION("createMac", NapiMac::CreateMac), }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); napi_property_descriptor classDesc[] = { - DECLARE_NAPI_FUNCTION("init", NapiMacInit), - DECLARE_NAPI_FUNCTION("update", NapiMacUpdate), - DECLARE_NAPI_FUNCTION("doFinal", NapiMacDoFinal), - DECLARE_NAPI_FUNCTION("getMacLength", NapiGetMacLength), + DECLARE_NAPI_FUNCTION("init", NapiMac::JsMacInit), + DECLARE_NAPI_FUNCTION("update", NapiMac::JsMacUpdate), + DECLARE_NAPI_FUNCTION("doFinal", NapiMac::JsMacDoFinal), + DECLARE_NAPI_FUNCTION("getMacLength", NapiMac::JsGetMacLength), }; napi_value constructor = nullptr; napi_define_class(env, "Mac", NAPI_AUTO_LENGTH, MacConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_md.cpp b/frameworks/js/napi/crypto/src/napi_md.cpp index 86dd81d..29da799 100644 --- a/frameworks/js/napi/crypto/src/napi_md.cpp +++ b/frameworks/js/napi/crypto/src/napi_md.cpp @@ -29,20 +29,20 @@ thread_local napi_ref NapiMd::classRef_ = nullptr; struct MdCtx { napi_env env = nullptr; - CfAsyncType asyncType = ASYNC_TYPE_CALLBACK; + AsyncType asyncType = ASYNC_CALLBACK; napi_ref callback = nullptr; napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - NapiMd *mdClass = nullptr; std::string algoName = ""; HcfBlob *inBlob = nullptr; HcfResult errCode = HCF_SUCCESS; const char *errMsg = nullptr; HcfBlob *outBlob = nullptr; + HcfMd *md = nullptr; }; static void FreeCryptoFwkCtx(napi_env env, MdCtx *context) @@ -73,6 +73,7 @@ static void FreeCryptoFwkCtx(napi_env env, MdCtx *context) context->outBlob = nullptr; } context->errMsg = nullptr; + context->md = nullptr; HcfFree(context); context = nullptr; } @@ -103,36 +104,10 @@ static void ReturnPromiseResult(napi_env env, MdCtx *context, napi_value result) } } -static bool CreateCallbackAndPromise(napi_env env, MdCtx *context, size_t argc, - size_t maxCount, napi_value callbackValue) -{ - context->asyncType = (argc == maxCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE; - if (context->asyncType == ASYNC_TYPE_CALLBACK) { - if (!GetCallbackFromJSParams(env, callbackValue, &context->callback)) { - LOGE("get callback failed!"); - return false; - } - } else { - napi_create_promise(env, &context->deferred, &context->promise); - } - return true; -} - -NapiMd::NapiMd(HcfMd *mdObj) -{ - this->mdObj_ = mdObj; -} - -NapiMd::~NapiMd() -{ - HcfObjDestroy(this->mdObj_); -} - static void MdUpdateExecute(napi_env env, void *data) { MdCtx *context = static_cast(data); - NapiMd *mdClass = context->mdClass; - HcfMd *mdObj = mdClass->GetMd(); + HcfMd *mdObj = context->md; context->errCode = mdObj->update(mdObj, context->inBlob); if (context->errCode != HCF_SUCCESS) { LOGE("update failed!"); @@ -140,24 +115,10 @@ static void MdUpdateExecute(napi_env env, void *data) } } -static void MdUpdateComplete(napi_env env, napi_status status, void *data) -{ - MdCtx *context = static_cast(data); - napi_value nullInstance = nullptr; - napi_get_null(env, &nullInstance); - if (context->asyncType == ASYNC_TYPE_CALLBACK) { - ReturnCallbackResult(env, context, nullInstance); - } else { - ReturnPromiseResult(env, context, nullInstance); - } - FreeCryptoFwkCtx(env, context); -} - static void MdDoFinalExecute(napi_env env, void *data) { MdCtx *context = static_cast(data); - NapiMd *mdClass = context->mdClass; - HcfMd *mdObj = mdClass->GetMd(); + HcfMd *mdObj = context->md; HcfBlob *outBlob = reinterpret_cast(HcfMalloc(sizeof(HcfBlob), 0)); if (outBlob == nullptr) { LOGE("outBlob is null!"); @@ -167,15 +128,27 @@ static void MdDoFinalExecute(napi_env env, void *data) } context->errCode = mdObj->doFinal(mdObj, outBlob); if (context->errCode != HCF_SUCCESS) { + HcfFree(outBlob); LOGE("doFinal failed!"); context->errMsg = "doFinal failed"; - HcfFree(outBlob); - outBlob = nullptr; return; } context->outBlob = outBlob; } +static void MdUpdateComplete(napi_env env, napi_status status, void *data) +{ + MdCtx *context = static_cast(data); + napi_value nullInstance = nullptr; + napi_get_null(env, &nullInstance); + if (context->asyncType == ASYNC_CALLBACK) { + ReturnCallbackResult(env, context, nullInstance); + } else { + ReturnPromiseResult(env, context, nullInstance); + } + FreeCryptoFwkCtx(env, context); +} + static void MdDoFinalComplete(napi_env env, napi_status status, void *data) { MdCtx *context = static_cast(data); @@ -184,7 +157,7 @@ static void MdDoFinalComplete(napi_env env, napi_status status, void *data) LOGE("returnOutBlob is nullptr!"); returnOutBlob = NapiGetNull(env); } - if (context->asyncType == ASYNC_TYPE_CALLBACK) { + if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, returnOutBlob); } else { ReturnPromiseResult(env, context, returnOutBlob); @@ -192,129 +165,194 @@ static void MdDoFinalComplete(napi_env env, napi_status status, void *data) FreeCryptoFwkCtx(env, context); } -napi_value NapiMd::MdUpdate(napi_env env, napi_callback_info info) +static bool BuildMdJsUpdateCtx(napi_env env, napi_callback_info info, MdCtx *context) { - // check param count - size_t argc = ARGS_SIZE_TWO; - napi_value argv[ARGS_SIZE_TWO] = { nullptr }; napi_value thisVar = nullptr; + NapiMd *napiMd = nullptr; + size_t expectedArgsCount = ARGS_SIZE_TWO; + size_t argc = expectedArgsCount; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) { - return nullptr; + return false; } - MdCtx *context = static_cast(HcfMalloc(sizeof(MdCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return nullptr; - } - context->mdClass = this; + + context->asyncType = (argc == expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; context->inBlob = GetBlobFromNapiValue(env, argv[PARAM0]); if (context->inBlob == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "inBlob is null")); LOGE("inBlob is null!"); - FreeCryptoFwkCtx(env, context); - return nullptr; + return false; } - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMd)); + if (status != napi_ok || napiMd == nullptr) { + LOGE("failed to unwrap NapiMd obj!"); + return false; } - napi_create_async_work( - env, nullptr, GetResourceName(env, "MdUpdate"), - MdUpdateExecute, - MdUpdateComplete, - static_cast(context), - &context->asyncWork); - napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { - return context->promise; + + context->md = napiMd->GetMd(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; } else { - return NapiGetNull(env); + return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback); } } -napi_value NapiMd::MdDoFinal(napi_env env, napi_callback_info info) +static bool BuildMdJsDoFinalCtx(napi_env env, napi_callback_info info, MdCtx *context) { + napi_value thisVar = nullptr; + NapiMd *napiMd = nullptr; size_t expectedArgsCount = ARGS_SIZE_ONE; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_ONE] = { nullptr }; - napi_value thisVar = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (!CheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) { - return nullptr; + return false; } - MdCtx *context = static_cast(HcfMalloc(sizeof(MdCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return nullptr; + + context->asyncType = (argc == expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMd)); + if (status != napi_ok || napiMd == nullptr) { + LOGE("failed to unwrap NapiMd obj!"); + return false; } - context->mdClass = this; - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + + context->md = napiMd->GetMd(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; + } else { + return GetCallbackFromJSParams(env, argv[PARAM0], &context->callback); } +} + +static napi_value NewMdJsUpdateAsyncWork(napi_env env, MdCtx *context) +{ + napi_create_async_work( + env, nullptr, GetResourceName(env, "MdUpdate"), + [](napi_env env, void *data) { + MdUpdateExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + MdUpdateComplete(env, status, data); + return; + }, + static_cast(context), + &context->asyncWork); + + napi_queue_async_work(env, context->asyncWork); + if (context->asyncType == ASYNC_PROMISE) { + return context->promise; + } else { + return NapiGetNull(env); + } +} + +static napi_value NewMdJsDoFinalAsyncWork(napi_env env, MdCtx *context) +{ napi_create_async_work( env, nullptr, GetResourceName(env, "MdDoFinal"), - MdDoFinalExecute, - MdDoFinalComplete, + [](napi_env env, void *data) { + MdDoFinalExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + MdDoFinalComplete(env, status, data); + return; + }, static_cast(context), &context->asyncWork); + napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { + if (context->asyncType == ASYNC_PROMISE) { return context->promise; } else { return NapiGetNull(env); } } -napi_value NapiMd::GetMdLength(napi_env env, napi_callback_info info) +NapiMd::NapiMd(HcfMd *mdObj) { - HcfMd *mdObj = GetMd(); - uint32_t retLen = mdObj->getMdLength(mdObj); - napi_value napiLen = nullptr; - napi_create_uint32(env, retLen, &napiLen); - return napiLen; + this->mdObj_ = mdObj; } -static napi_value NapiMdUpdate(napi_env env, napi_callback_info info) +NapiMd::~NapiMd() { - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMd *mdObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&mdObj)); - if (mdObj == nullptr) { - LOGE("mdObj is nullptr!"); - return NapiGetNull(env); + HcfObjDestroy(this->mdObj_); +} + +HcfMd *NapiMd::GetMd() +{ + return this->mdObj_; +} + +napi_value NapiMd::JsMdUpdate(napi_env env, napi_callback_info info) +{ + MdCtx *context = static_cast(HcfMalloc(sizeof(MdCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; + } + + if (!BuildMdJsUpdateCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; } - return mdObj->MdUpdate(env, info); + + return NewMdJsUpdateAsyncWork(env, context); } -static napi_value NapiMdDoFinal(napi_env env, napi_callback_info info) +napi_value NapiMd::JsMdDoFinal(napi_env env, napi_callback_info info) { - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMd *mdObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&mdObj)); - if (mdObj == nullptr) { - LOGE("mdObj is nullptr!"); - return NapiGetNull(env); + MdCtx *context = static_cast(HcfMalloc(sizeof(MdCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; + } + + if (!BuildMdJsDoFinalCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; } - return mdObj->MdDoFinal(env, info); + + return NewMdJsDoFinalAsyncWork(env, context); } -static napi_value NapiGetMdLength(napi_env env, napi_callback_info info) +napi_value NapiMd::JsGetMdLength(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; + NapiMd *napiMd = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiMd *mdObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&mdObj)); - if (mdObj == nullptr) { - LOGE("mdObj is nullptr!"); - return NapiGetNull(env); + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiMd)); + if (status != napi_ok || napiMd == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap NapiMd obj!")); + LOGE("failed to unwrap NapiMd obj!"); + return nullptr; } - return mdObj->GetMdLength(env, info); + + HcfMd *md = napiMd->GetMd(); + if (md == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get md obj!")); + LOGE("fail to get md obj!"); + return nullptr; + } + + uint32_t retLen = md->getMdLength(md); + napi_value napiLen = nullptr; + napi_create_uint32(env, retLen, &napiLen); + return napiLen; } napi_value NapiMd::MdConstructor(napi_env env, napi_callback_info info) @@ -324,6 +362,25 @@ napi_value NapiMd::MdConstructor(napi_env env, napi_callback_info info) return thisVar; } +static napi_value NapiWrapMd(napi_env env, napi_value instance, NapiMd *mdNapiObj) +{ + napi_status status = napi_wrap( + env, instance, mdNapiObj, + [](napi_env env, void *data, void *hint) { + NapiMd *md = static_cast(data); + delete md; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap NapiMd obj!")); + delete mdNapiObj; + mdNapiObj = nullptr; + LOGE("failed to wrap NapiMd obj!"); + return nullptr; + } + return instance; +} + napi_value NapiMd::CreateMd(napi_env env, napi_callback_info info) { size_t expectedArgc = ARGS_SIZE_ONE; @@ -331,11 +388,13 @@ napi_value NapiMd::CreateMd(napi_env env, napi_callback_info info) napi_value argv[ARGS_SIZE_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } std::string algoName; if (!GetStringFromJSParams(env, argv[PARAM0], algoName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Failed to get algorithm.")); LOGE("Failed to get algorithm."); return nullptr; } @@ -355,31 +414,25 @@ napi_value NapiMd::CreateMd(napi_env env, napi_callback_info info) napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); NapiMd *mdNapiObj = new (std::nothrow) NapiMd(mdObj); if (mdNapiObj == nullptr) { - LOGE("create napi obj failed"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new md napi obj failed!")); + HcfObjDestroy(mdObj); + LOGE("create md napi obj failed!"); return nullptr; } - napi_wrap( - env, instance, mdNapiObj, - [](napi_env env, void *data, void *hint) { - NapiMd *md = static_cast(data); - delete md; - return; - }, - nullptr, - nullptr); - return instance; + + return NapiWrapMd(env, instance, mdNapiObj); } void NapiMd::DefineMdJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("createMd", CreateMd), + DECLARE_NAPI_FUNCTION("createMd", NapiMd::CreateMd), }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); napi_property_descriptor classDesc[] = { - DECLARE_NAPI_FUNCTION("update", NapiMdUpdate), - DECLARE_NAPI_FUNCTION("digest", NapiMdDoFinal), - DECLARE_NAPI_FUNCTION("getMdLength", NapiGetMdLength), + DECLARE_NAPI_FUNCTION("update", NapiMd::JsMdUpdate), + DECLARE_NAPI_FUNCTION("digest", NapiMd::JsMdDoFinal), + DECLARE_NAPI_FUNCTION("getMdLength", NapiMd::JsGetMdLength), }; napi_value constructor = nullptr; napi_define_class(env, "Md", NAPI_AUTO_LENGTH, MdConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_pri_key.cpp b/frameworks/js/napi/crypto/src/napi_pri_key.cpp index 9014e15..751e5b5 100644 --- a/frameworks/js/napi/crypto/src/napi_pri_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_pri_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -16,9 +16,11 @@ #include "napi_pri_key.h" #include "log.h" +#include "memory.h" #include "napi_crypto_framework_defines.h" #include "napi_utils.h" #include "securec.h" +#include "key.h" namespace OHOS { namespace CryptoFramework { @@ -35,19 +37,13 @@ HcfPriKey *NapiPriKey::GetPriKey() napi_value NapiPriKey::PriKeyConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } napi_value NapiPriKey::ConvertToJsPriKey(napi_env env) { - LOGI("enter ..."); - napi_value instance; napi_value constructor = nullptr; napi_get_reference_value(env, classRef_, &constructor); @@ -63,8 +59,6 @@ napi_value NapiPriKey::ConvertToJsPriKey(napi_env env) napi_value napiFormat = nullptr; napi_create_string_utf8(env, format, NAPI_AUTO_LENGTH, &napiFormat); napi_set_named_property(env, instance, CRYPTO_TAG_FORMAT.c_str(), napiFormat); - - LOGI("out ..."); return instance; } @@ -73,13 +67,24 @@ napi_value NapiPriKey::JsGetEncoded(napi_env env, napi_callback_info info) napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); NapiPriKey *napiPriKey = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + if (status != napi_ok || napiPriKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!")); + LOGE("failed to unwrap napiPriKey obj!"); + return nullptr; + } HcfPriKey *priKey = napiPriKey->GetPriKey(); + if (priKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!")); + LOGE("failed to get priKey obj!"); + return nullptr; + } HcfBlob returnBlob; HcfResult res = priKey->base.getEncoded(&priKey->base, &returnBlob); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c getEncoded fail.")); LOGE("c getEncoded fail."); return nullptr; } @@ -94,19 +99,124 @@ napi_value NapiPriKey::JsClearMem(napi_env env, napi_callback_info info) napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); NapiPriKey *napiPriKey = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + if (status != napi_ok || napiPriKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!")); + LOGE("failed to unwrap napiPriKey obj!"); + return nullptr; + } HcfPriKey *priKey = napiPriKey->GetPriKey(); + if (priKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!")); + LOGE("failed to get priKey obj!"); + return nullptr; + } priKey->clearMem(priKey); return nullptr; } +static napi_value GetAsyKeySpecBigInt(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey) +{ + HcfBigInteger returnBigInteger = { 0 }; + HcfResult res = priKey->getAsyKeySpecBigInteger(priKey, item, &returnBigInteger); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecBigInteger failed.")); + LOGE("C getAsyKeySpecBigInteger failed."); + return nullptr; + } + + napi_value instance = ConvertBigIntToNapiValue(env, &returnBigInteger); + HcfFree(returnBigInteger.data); + return instance; +} + +static napi_value GetAsyKeySpecNumber(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey) +{ + int returnInt = 0; + HcfResult res = priKey->getAsyKeySpecInt(priKey, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecInt failed.")); + LOGE("C getAsyKeySpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_int32(env, returnInt, &instance); + return instance; +} + +static napi_value GetAsyKeySpecString(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey) +{ + char *returnString = nullptr; + HcfResult res = priKey->getAsyKeySpecString(priKey, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecString failed.")); + LOGE("c getAsyKeySpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance); + HcfFree(returnString); + return instance; +} + +napi_value NapiPriKey::JsGetAsyKeySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiPriKey *napiPriKey = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec fail, wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + + AsyKeySpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec failed!")); + LOGE("JsGetAsyKeySpec failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + if (status != napi_ok || napiPriKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!")); + LOGE("failed to unwrap napiPriKey obj!"); + return nullptr; + } + HcfPriKey *priKey = napiPriKey->GetPriKey(); + if (priKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!")); + LOGE("failed to get priKey obj!"); + return nullptr; + } + LOGD("prepare priKey ok."); + + int32_t type = GetAsyKeySpecType(item); + if (type == SPEC_ITEM_TYPE_BIG_INT) { + return GetAsyKeySpecBigInt(env, item, priKey); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetAsyKeySpecNumber(env, item, priKey); + } else if (type == SPEC_ITEM_TYPE_STR) { + return GetAsyKeySpecString(env, item, priKey); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "AsyKeySpecItem not support!")); + return nullptr; + } +} + void NapiPriKey::DefinePriKeyJSClass(napi_env env) { napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("getEncoded", NapiPriKey::JsGetEncoded), DECLARE_NAPI_FUNCTION("clearMem", NapiPriKey::JsClearMem), + DECLARE_NAPI_FUNCTION("getAsyKeySpec", NapiPriKey::JsGetAsyKeySpec), }; napi_value constructor = nullptr; napi_define_class(env, "PriKey", NAPI_AUTO_LENGTH, NapiPriKey::PriKeyConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_pub_key.cpp b/frameworks/js/napi/crypto/src/napi_pub_key.cpp index ac5ce9a..317e350 100644 --- a/frameworks/js/napi/crypto/src/napi_pub_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_pub_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -16,9 +16,11 @@ #include "napi_pub_key.h" #include "log.h" +#include "memory.h" #include "napi_crypto_framework_defines.h" #include "napi_utils.h" #include "securec.h" +#include "key.h" namespace OHOS { namespace CryptoFramework { @@ -35,19 +37,13 @@ HcfPubKey *NapiPubKey::GetPubKey() napi_value NapiPubKey::PubKeyConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } napi_value NapiPubKey::ConvertToJsPubKey(napi_env env) { - LOGI("enter ..."); - napi_value instance; napi_value constructor = nullptr; napi_get_reference_value(env, classRef_, &constructor); @@ -63,8 +59,6 @@ napi_value NapiPubKey::ConvertToJsPubKey(napi_env env) napi_value napiFormat = nullptr; napi_create_string_utf8(env, format, NAPI_AUTO_LENGTH, &napiFormat); napi_set_named_property(env, instance, CRYPTO_TAG_FORMAT.c_str(), napiFormat); - - LOGI("out ..."); return instance; } @@ -73,12 +67,24 @@ napi_value NapiPubKey::JsGetEncoded(napi_env env, napi_callback_info info) napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); NapiPubKey *napiPubKey = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&napiPubKey)); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPubKey)); + if (status != napi_ok || napiPubKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPubKey obj!")); + LOGE("failed to unwrap napiPubKey obj!"); + return nullptr; + } HcfPubKey *pubKey = napiPubKey->GetPubKey(); + if (pubKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get pubKey obj!")); + LOGE("failed to get pubKey obj!"); + return nullptr; + } + HcfBlob returnBlob; HcfResult res = pubKey->base.getEncoded(&pubKey->base, &returnBlob); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "c getEncoded fail.")); LOGE("c getEncoded fail."); return nullptr; } @@ -88,10 +94,103 @@ napi_value NapiPubKey::JsGetEncoded(napi_env env, napi_callback_info info) return instance; } +static napi_value GetAsyKeySpecBigInt(napi_env env, AsyKeySpecItem item, HcfPubKey *pubKey) +{ + HcfBigInteger returnBigInteger = { 0 }; + HcfResult res = pubKey->getAsyKeySpecBigInteger(pubKey, item, &returnBigInteger); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecBigInteger failed.")); + LOGE("C getAsyKeySpecBigInteger failed."); + return nullptr; + } + + napi_value instance = ConvertBigIntToNapiValue(env, &returnBigInteger); + HcfFree(returnBigInteger.data); + return instance; +} + +static napi_value GetAsyKeySpecNumber(napi_env env, AsyKeySpecItem item, HcfPubKey *pubKey) +{ + int returnInt = 0; + HcfResult res = pubKey->getAsyKeySpecInt(pubKey, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecInt failed.")); + LOGE("C getAsyKeySpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_int32(env, returnInt, &instance); + return instance; +} + +static napi_value GetAsyKeySpecString(napi_env env, AsyKeySpecItem item, HcfPubKey *pubKey) +{ + char *returnString = nullptr; + HcfResult res = pubKey->getAsyKeySpecString(pubKey, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecString failed.")); + LOGE("c getAsyKeySpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance); + HcfFree(returnString); + return instance; +} + +napi_value NapiPubKey::JsGetAsyKeySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiPubKey *napiPubKey = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec fail, wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + AsyKeySpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec failed!")); + LOGE("JsGetAsyKeySpec failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPubKey)); + if (status != napi_ok || napiPubKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPubKey obj!")); + LOGE("failed to unwrap napiPubKey obj!"); + return nullptr; + } + HcfPubKey *pubKey = napiPubKey->GetPubKey(); + if (pubKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get pubKey obj!")); + LOGE("failed to get pubKey obj!"); + return nullptr; + } + + int32_t type = GetAsyKeySpecType(item); + if (type == SPEC_ITEM_TYPE_BIG_INT) { + return GetAsyKeySpecBigInt(env, item, pubKey); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetAsyKeySpecNumber(env, item, pubKey); + } else if (type == SPEC_ITEM_TYPE_STR) { + return GetAsyKeySpecString(env, item, pubKey); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "AsyKeySpecItem not support!")); + return nullptr; + } +} + void NapiPubKey::DefinePubKeyJSClass(napi_env env) { napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("getEncoded", NapiPubKey::JsGetEncoded), + DECLARE_NAPI_FUNCTION("getAsyKeySpec", NapiPubKey::JsGetAsyKeySpec), }; napi_value constructor = nullptr; napi_define_class(env, "PubKey", NAPI_AUTO_LENGTH, NapiPubKey::PubKeyConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_rand.cpp b/frameworks/js/napi/crypto/src/napi_rand.cpp index 24d8756..5452fd3 100644 --- a/frameworks/js/napi/crypto/src/napi_rand.cpp +++ b/frameworks/js/napi/crypto/src/napi_rand.cpp @@ -29,19 +29,19 @@ thread_local napi_ref NapiRand::classRef_ = nullptr; struct RandCtx { napi_env env = nullptr; - CfAsyncType asyncType = ASYNC_TYPE_CALLBACK; + AsyncType asyncType = ASYNC_CALLBACK; napi_ref callback = nullptr; napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - NapiRand *randClass = nullptr; uint32_t numBytes = 0; HcfBlob *seedBlob = nullptr; HcfResult errCode = HCF_SUCCESS; const char *errMsg = nullptr; HcfBlob *randBlob = nullptr; + HcfRand *rand = nullptr; }; static void FreeCryptoFwkCtx(napi_env env, RandCtx *context) @@ -73,6 +73,7 @@ static void FreeCryptoFwkCtx(napi_env env, RandCtx *context) context->randBlob = nullptr; } context->errMsg = nullptr; + context->rand = nullptr; HcfFree(context); context = nullptr; } @@ -104,36 +105,10 @@ static void ReturnPromiseResult(napi_env env, RandCtx *context, napi_value resul } } -static bool CreateCallbackAndPromise(napi_env env, RandCtx *context, size_t argc, - size_t maxCount, napi_value callbackValue) -{ - context->asyncType = (argc == maxCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE; - if (context->asyncType == ASYNC_TYPE_CALLBACK) { - if (!GetCallbackFromJSParams(env, callbackValue, &context->callback)) { - LOGE("get callback failed!"); - return false; - } - } else { - napi_create_promise(env, &context->deferred, &context->promise); - } - return true; -} - -NapiRand::NapiRand(HcfRand *randObj) -{ - this->randObj_ = randObj; -} - -NapiRand::~NapiRand() -{ - HcfObjDestroy(this->randObj_); -} - static void GenerateRandomExecute(napi_env env, void *data) { RandCtx *context = static_cast(data); - NapiRand *randClass = context->randClass; - HcfRand *randObj = randClass->GetRand(); + HcfRand *randObj = context->rand; HcfBlob *randBlob = reinterpret_cast(HcfMalloc(sizeof(HcfBlob), 0)); if (randBlob == nullptr) { LOGE("randBlob is null!"); @@ -147,7 +122,6 @@ static void GenerateRandomExecute(napi_env env, void *data) LOGE("generateRandom failed!"); context->errMsg = "generateRandom failed"; HcfFree(randBlob); - randBlob = nullptr; return; } context->randBlob = randBlob; @@ -161,7 +135,7 @@ static void GenerateRandomComplete(napi_env env, napi_status status, void *data) LOGE("returnOutBlob is nullptr!"); returnRandBlob = NapiGetNull(env); } - if (context->asyncType == ASYNC_TYPE_CALLBACK) { + if (context->asyncType == ASYNC_CALLBACK) { ReturnCallbackResult(env, context, returnRandBlob); } else { ReturnPromiseResult(env, context, returnRandBlob); @@ -169,55 +143,154 @@ static void GenerateRandomComplete(napi_env env, napi_status status, void *data) FreeCryptoFwkCtx(env, context); } -napi_value NapiRand::GenerateRandom(napi_env env, napi_callback_info info) +static bool BuildGenerateRandomCtx(napi_env env, napi_callback_info info, RandCtx *context) { + napi_value thisVar = nullptr; size_t expectedArgsCount = ARGS_SIZE_TWO; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_TWO] = { nullptr }; - napi_value thisVar = nullptr; - napi_value ret = NapiGetNull(env); napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgsCount) && (argc != expectedArgsCount - CALLBACK_SIZE)) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); LOGE("The arguments count is not expected!"); - return ret; + return false; } - RandCtx *context = static_cast(HcfMalloc(sizeof(RandCtx), 0)); - if (context == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); - LOGE("malloc context failed!"); - return ret; - } - context->randClass = this; + if (!GetUint32FromJSParams(env, argv[PARAM0], context->numBytes)) { LOGE("get numBytes failed!"); - FreeCryptoFwkCtx(env, context); - return ret; + return false; } - if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) { - FreeCryptoFwkCtx(env, context); - return nullptr; + context->asyncType = isCallback(env, argv[expectedArgsCount - 1], argc, expectedArgsCount) ? + ASYNC_CALLBACK : ASYNC_PROMISE; + + NapiRand *napiRand = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiRand)); + if (status != napi_ok || napiRand == nullptr) { + LOGE("failed to unwrap NapiRand obj!"); + return false; + } + + context->rand = napiRand->GetRand(); + + if (context->asyncType == ASYNC_PROMISE) { + napi_create_promise(env, &context->deferred, &context->promise); + return true; + } else { + return GetCallbackFromJSParams(env, argv[PARAM1], &context->callback); } +} + +static napi_value NewRandJsGenerateAsyncWork(napi_env env, RandCtx *context) +{ napi_create_async_work( env, nullptr, GetResourceName(env, "GenerateRandom"), - GenerateRandomExecute, - GenerateRandomComplete, + [](napi_env env, void *data) { + GenerateRandomExecute(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + GenerateRandomComplete(env, status, data); + return; + }, static_cast(context), &context->asyncWork); + napi_queue_async_work(env, context->asyncWork); - if (context->asyncType == ASYNC_TYPE_PROMISE) { + if (context->asyncType == ASYNC_PROMISE) { return context->promise; } else { return NapiGetNull(env); } } -napi_value NapiRand::SetSeed(napi_env env, napi_callback_info info) +NapiRand::NapiRand(HcfRand *randObj) +{ + this->randObj_ = randObj; +} + +NapiRand::~NapiRand() +{ + HcfObjDestroy(this->randObj_); +} + +HcfRand *NapiRand::GetRand() +{ + return this->randObj_; +} + +napi_value NapiRand::JsGenerateRandom(napi_env env, napi_callback_info info) +{ + RandCtx *context = static_cast(HcfMalloc(sizeof(RandCtx), 0)); + if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc context failed")); + LOGE("malloc context failed!"); + return nullptr; + } + + if (!BuildGenerateRandomCtx(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + LOGE("build context fail."); + FreeCryptoFwkCtx(env, context); + return nullptr; + } + + return NewRandJsGenerateAsyncWork(env, context); +} + +napi_value NapiRand::JsGenerateRandomSync(napi_env env, napi_callback_info info) { + napi_value thisVar = nullptr; + NapiRand *napiRand = nullptr; size_t expectedArgsCount = ARGS_SIZE_ONE; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgsCount) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); + LOGE("The arguments count is not expected!"); + return nullptr; + } + + uint32_t numBytes = 0; + if (!GetUint32FromJSParams(env, argv[PARAM0], numBytes)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get numBytes failed!")); + LOGE("get numBytes failed!"); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiRand)); + if (status != napi_ok || napiRand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap NapiRand obj!")); + LOGE("failed to unwrap NapiRand obj!"); + return nullptr; + } + HcfRand *rand = napiRand->GetRand(); + if (rand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get rand obj!")); + LOGE("fail to get rand obj!"); + return nullptr; + } + + HcfBlob randBlob = { .data = nullptr, .len = 0}; + HcfResult res = rand->generateRandom(rand, numBytes, &randBlob); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get rand obj!")); + LOGE("generateRandom failed!"); + return nullptr; + } + + napi_value instance = ConvertBlobToNapiValue(env, &randBlob); + HcfBlobDataClearAndFree(&randBlob); + return instance; +} + +napi_value NapiRand::JsSetSeed(napi_env env, napi_callback_info info) +{ napi_value thisVar = nullptr; + NapiRand *napiRand = nullptr; + size_t expectedArgsCount = ARGS_SIZE_ONE; + size_t argc = expectedArgsCount; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgsCount) { napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); @@ -225,39 +298,52 @@ napi_value NapiRand::SetSeed(napi_env env, napi_callback_info info) return nullptr; } HcfBlob *seedBlob = GetBlobFromNapiValue(env, argv[PARAM0]); - HcfRand *randObj = GetRand(); - HcfResult res = randObj->setSeed(randObj, seedBlob); + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiRand)); + if (status != napi_ok || napiRand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap NapiRand obj!")); + LOGE("failed to unwrap NapiRand obj!"); + return nullptr; + } + HcfRand *rand = napiRand->GetRand(); + if (rand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get rand obj!")); + LOGE("fail to get rand obj!"); + return nullptr; + } + HcfResult res = rand->setSeed(rand, seedBlob); if (res != HCF_SUCCESS) { napi_throw(env, GenerateBusinessError(env, res, "set seed failed.")); LOGE("set seed failed."); + return nullptr; } - return nullptr; + return thisVar; } -static napi_value NapiGenerateRandom(napi_env env, napi_callback_info info) +napi_value NapiRand::JsGetAlgorithm(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; + NapiRand *napiRand = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiRand *randObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&randObj)); - if (randObj == nullptr) { - LOGE("randObj is nullptr!"); - return NapiGetNull(env); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiRand)); + if (status != napi_ok || napiRand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap NapiRand obj!")); + LOGE("failed to unwrap NapiRand obj!"); + return nullptr; } - return randObj->GenerateRandom(env, info); -} -static napi_value NapiSetSeed(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NapiRand *randObj = nullptr; - napi_unwrap(env, thisVar, reinterpret_cast(&randObj)); - if (randObj == nullptr) { - LOGE("randObj is nullptr!"); + HcfRand *rand = napiRand->GetRand(); + if (rand == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get rand obj!")); + LOGE("fail to get rand obj!"); return nullptr; } - return randObj->SetSeed(env, info); + + const char *algoName = rand->getAlgoName(rand); + napi_value instance = nullptr; + napi_create_string_utf8(env, algoName, NAPI_AUTO_LENGTH, &instance); + return instance; } napi_value NapiRand::RandConstructor(napi_env env, napi_callback_info info) @@ -282,30 +368,38 @@ napi_value NapiRand::CreateRand(napi_env env, napi_callback_info info) napi_new_instance(env, constructor, 0, nullptr, &instance); NapiRand *randNapiObj = new (std::nothrow) NapiRand(randObj); if (randNapiObj == nullptr) { - LOGE("create napi obj failed"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new rand napi obj failed.")); + HcfObjDestroy(randObj); + LOGE("create rand napi obj failed"); return nullptr; } - napi_wrap( + napi_status status = napi_wrap( env, instance, randNapiObj, [](napi_env env, void *data, void *hint) { NapiRand *rand = static_cast(data); delete rand; return; - }, - nullptr, - nullptr); + }, nullptr, nullptr); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap NapiRand obj!")); + delete randNapiObj; + LOGE("failed to wrap NapiRand obj!"); + return nullptr; + } return instance; } void NapiRand::DefineRandJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("createRandom", CreateRand), + DECLARE_NAPI_FUNCTION("createRandom", NapiRand::CreateRand), }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); napi_property_descriptor classDesc[] = { - DECLARE_NAPI_FUNCTION("generateRandom", NapiGenerateRandom), - DECLARE_NAPI_FUNCTION("setSeed", NapiSetSeed), + DECLARE_NAPI_FUNCTION("generateRandom", NapiRand::JsGenerateRandom), + DECLARE_NAPI_FUNCTION("generateRandomSync", NapiRand::JsGenerateRandomSync), + DECLARE_NAPI_FUNCTION("setSeed", NapiRand::JsSetSeed), + {.utf8name = "algName", .getter = NapiRand::JsGetAlgorithm}, }; napi_value constructor = nullptr; napi_define_class(env, "Random", NAPI_AUTO_LENGTH, RandConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_sign.cpp b/frameworks/js/napi/crypto/src/napi_sign.cpp index dee597a..bfaccaa 100644 --- a/frameworks/js/napi/crypto/src/napi_sign.cpp +++ b/frameworks/js/napi/crypto/src/napi_sign.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -35,11 +35,12 @@ struct SignInitCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfSign *sign; - HcfParamsSpec *params; - HcfPriKey *priKey; + HcfSign *sign = nullptr; + HcfParamsSpec *params = nullptr; + HcfPriKey *priKey = nullptr; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct SignUpdateCtx { @@ -54,7 +55,8 @@ struct SignUpdateCtx { HcfSign *sign; HcfBlob *data; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct SignDoFinalCtx { @@ -69,7 +71,8 @@ struct SignDoFinalCtx { HcfSign *sign; HcfBlob *data; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; HcfBlob returnSignatureData; }; @@ -147,25 +150,22 @@ static bool BuildSignJsInitCtx(napi_env env, napi_callback_info info, SignInitCt napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSign *napiSign = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); - if (status != napi_ok) { + if (status != napi_ok || napiSign == nullptr) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } size_t index = 0; NapiPriKey *napiPriKey = nullptr; status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPriKey)); - if (status != napi_ok) { + if (status != napi_ok || napiPriKey == nullptr) { LOGE("failed to unwrap napi priKey obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PriKey]: param unwarp error.")); return false; } @@ -190,16 +190,14 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSign *napiSign = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); - if (status != napi_ok) { + if (status != napi_ok || napiSign == nullptr) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -207,8 +205,6 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]); if (blob == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } @@ -232,16 +228,14 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSign *napiSign = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); - if (status != napi_ok) { + if (status != napi_ok || napiSign == nullptr) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -253,8 +247,6 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF data = GetBlobFromNapiValue(env, argv[index]); if (data == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } } @@ -273,8 +265,8 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF static void ReturnInitCallbackResult(napi_env env, SignInitCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -290,19 +282,18 @@ static void ReturnInitCallbackResult(napi_env env, SignInitCtx *ctx, napi_value static void ReturnInitPromiseResult(napi_env env, SignInitCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnUpdateCallbackResult(napi_env env, SignUpdateCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -318,19 +309,18 @@ static void ReturnUpdateCallbackResult(napi_env env, SignUpdateCtx *ctx, napi_va static void ReturnUpdatePromiseResult(napi_env env, SignUpdateCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnDoFinalCallbackResult(napi_env env, SignDoFinalCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -346,11 +336,10 @@ static void ReturnDoFinalCallbackResult(napi_env env, SignDoFinalCtx *ctx, napi_ static void ReturnDoFinalPromiseResult(napi_env env, SignDoFinalCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -358,11 +347,10 @@ void SignJsInitAsyncWorkProcess(napi_env env, void *data) { SignInitCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->init(ctx->sign, ctx->params, ctx->priKey); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->init(ctx->sign, ctx->params, ctx->priKey); + if (ctx->errCode != HCF_SUCCESS) { LOGE("sign init fail."); + ctx->errMsg = "sign init fail."; } } @@ -382,11 +370,10 @@ void SignJsUpdateAsyncWorkProcess(napi_env env, void *data) { SignUpdateCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->update(ctx->sign, ctx->data); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->update(ctx->sign, ctx->data); + if (ctx->errCode != HCF_SUCCESS) { LOGE("sign update fail."); + ctx->errMsg = "sign update fail."; } } @@ -406,11 +393,10 @@ void SignJsDoFinalAsyncWorkProcess(napi_env env, void *data) { SignDoFinalCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->sign(ctx->sign, ctx->data, &ctx->returnSignatureData); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->sign(ctx->sign, ctx->data, &ctx->returnSignatureData); + if (ctx->errCode != HCF_SUCCESS) { LOGE("sign doFinal fail."); + ctx->errMsg = "sign doFinal fail."; } } @@ -419,7 +405,7 @@ void SignJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data) SignDoFinalCtx *ctx = static_cast(data); napi_value dataBlob = nullptr; - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { dataBlob = ConvertBlobToNapiValue(env, &ctx->returnSignatureData); } @@ -453,9 +439,7 @@ static napi_value NewSignJsInitAsyncWork(napi_env env, SignInitCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -481,9 +465,7 @@ static napi_value NewSignJsUpdateAsyncWork(napi_env env, SignUpdateCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -509,9 +491,7 @@ static napi_value NewSignJsDoFinalAsyncWork(napi_env env, SignDoFinalCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -532,14 +512,15 @@ HcfSign *NapiSign::GetSign() napi_value NapiSign::JsInit(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignInitCtx *ctx = static_cast(HcfMalloc(sizeof(SignInitCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsInitCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignInitCtx(env, ctx); return nullptr; @@ -550,14 +531,15 @@ napi_value NapiSign::JsInit(napi_env env, napi_callback_info info) napi_value NapiSign::JsUpdate(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignUpdateCtx *ctx = static_cast(HcfMalloc(sizeof(SignUpdateCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsUpdateCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignUpdateCtx(env, ctx); return nullptr; @@ -568,14 +550,15 @@ napi_value NapiSign::JsUpdate(napi_env env, napi_callback_info info) napi_value NapiSign::JsSign(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignDoFinalCtx *ctx = static_cast(HcfMalloc(sizeof(SignDoFinalCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsDoFinalCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignDoFinalCtx(env, ctx); return nullptr; @@ -586,24 +569,38 @@ napi_value NapiSign::JsSign(napi_env env, napi_callback_info info) napi_value NapiSign::SignConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } +static napi_value NapiWrapSign(napi_env env, napi_value instance, NapiSign *napiSign) +{ + napi_status status = napi_wrap( + env, instance, napiSign, + [](napi_env env, void *data, void *hint) { + NapiSign *napiSign = static_cast(data); + delete napiSign; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + LOGE("failed to wrap napiSign obj!"); + delete napiSign; + napiSign = nullptr; + return nullptr; + } + return instance; +} + napi_value NapiSign::CreateJsSign(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = expectedArgc; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } @@ -615,36 +612,151 @@ napi_value NapiSign::CreateJsSign(napi_env env, napi_callback_info info) std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get algName fail.")); return nullptr; } HcfSign *sign = nullptr; - int32_t res = HcfSignCreate(algName.c_str(), &sign); + HcfResult res = HcfSignCreate(algName.c_str(), &sign); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c sign fail.")); LOGE("create c sign fail."); return nullptr; } - NapiSign *napiSign = new NapiSign(sign); - - napi_wrap( - env, instance, napiSign, - [](napi_env env, void *data, void *hint) { - NapiSign *napiSign = static_cast(data); - delete napiSign; - return; - }, - nullptr, - nullptr); + NapiSign *napiSign = new (std::nothrow) NapiSign(sign); + if (napiSign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sign failed")); + LOGE("new napi sign failed"); + HcfObjDestroy(sign); + return nullptr; + } napi_value napiAlgName = nullptr; napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); - LOGI("out ..."); + return NapiWrapSign(env, instance, napiSign); +} + +// sign setSignSpec(itemType :signSpecItem, itemValue : number) +napi_value NapiSign::JsSetSignSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiSign *napiSign = nullptr; + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + // thisVar means the js this argument for the call (sign.() means this = sign) + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!")); + LOGE("get signspecitem failed!"); + return nullptr; + } + int32_t saltLen; + if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpec saltLen failed!")); + LOGE("get signSpec saltLen failed!"); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); + if (status != napi_ok || napiSign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSign obj!")); + LOGE("failed to unwrap napiSign obj!"); + return nullptr; + } + HcfSign *sign = napiSign->GetSign(); + HcfResult res = sign->setSignSpecInt(sign, item, saltLen); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c setSignSpecNumber fail.")); + LOGE("c setSignSpecNumber fail."); + return nullptr; + } + return thisVar; +} + +static napi_value GetSignSpecString(napi_env env, SignSpecItem item, HcfSign *sign) +{ + char *returnString = nullptr; + HcfResult res = sign->getSignSpecString(sign, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getSignSpecString failed.")); + LOGE("c getSignSpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance); + HcfFree(returnString); + return instance; +} + +static napi_value GetSignSpecNumber(napi_env env, SignSpecItem item, HcfSign *sign) +{ + int returnInt; + HcfResult res = sign->getSignSpecInt(sign, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getSignSpecInt failed.")); + LOGE("c getSignSpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_int32(env, returnInt, &instance); return instance; } +napi_value NapiSign::JsGetSignSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiSign *napiSign = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getSignSpecString failed!")); + LOGE("get getSignSpecString failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); + if (status != napi_ok || napiSign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSign obj!")); + LOGE("failed to unwrap napiSign obj!"); + return nullptr; + } + HcfSign *sign = napiSign->GetSign(); + if (sign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get sign obj!")); + LOGE("failed to get sign obj!"); + return nullptr; + } + + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetSignSpecString(env, item, sign); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetSignSpecNumber(env, item, sign); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "SignSpecItem not support!")); + return nullptr; + } +} + void NapiSign::DefineSignJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -656,6 +768,8 @@ void NapiSign::DefineSignJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiSign::JsInit), DECLARE_NAPI_FUNCTION("update", NapiSign::JsUpdate), DECLARE_NAPI_FUNCTION("sign", NapiSign::JsSign), + DECLARE_NAPI_FUNCTION("setSignSpec", NapiSign::JsSetSignSpec), + DECLARE_NAPI_FUNCTION("getSignSpec", NapiSign::JsGetSignSpec), }; napi_value constructor = nullptr; napi_define_class(env, "Sign", NAPI_AUTO_LENGTH, NapiSign::SignConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_sym_key.cpp b/frameworks/js/napi/crypto/src/napi_sym_key.cpp index 0d2af9a..4f0edfb 100644 --- a/frameworks/js/napi/crypto/src/napi_sym_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_sym_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -41,9 +41,14 @@ napi_value NapiSymKey::JsClearMem(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; NapiSymKey *napiSymKey = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiSymKey))); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSymKey)); + if (status != napi_ok || napiSymKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSymKey obj!")); + LOGE("failed to unwrap napiSymKey obj!"); + return nullptr; + } HcfSymKey *key = napiSymKey->GetSymKey(); key->clearMem(key); return nullptr; @@ -52,7 +57,7 @@ napi_value NapiSymKey::JsClearMem(napi_env env, napi_callback_info info) napi_value NapiSymKey::SymKeyConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); return thisVar; } @@ -60,8 +65,8 @@ napi_value NapiSymKey::CreateSymKey(napi_env env) { napi_value instance = nullptr; napi_value constructor = nullptr; - NAPI_CALL(env, napi_get_reference_value(env, classRef_, &constructor)); - NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &instance)); + napi_get_reference_value(env, classRef_, &constructor); + napi_new_instance(env, constructor, 0, nullptr, &instance); return instance; } diff --git a/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp index 870ace0..3a4ee25 100644 --- a/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -34,7 +34,7 @@ struct SymKeyGeneratorFwkCtxT { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - int32_t errCode = 0; + HcfResult errCode = HCF_SUCCESS; HcfSymKey *returnSymKey = nullptr; const char *errMsg = nullptr; @@ -80,15 +80,13 @@ static bool BuildContextForGenerateKey(napi_env env, napi_callback_info info, Sy napi_value argv[ARGS_SIZE_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "generate key failed for wrong argument num.")); LOGE("wrong argument num. require 0 or 1 arguments. [Argc]: %zu!", argc); return false; } - context->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSymKeyGenerator *napiGenerator; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); - if (status != napi_ok) { + if (status != napi_ok || napiGenerator == nullptr) { LOGE("failed to unwrap NapiSymKeyGenerator obj!"); return false; } @@ -114,16 +112,14 @@ static bool BuildContextForConvertKey(napi_env env, napi_callback_info info, Sym napi_value argv[ARGS_SIZE_TWO] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "convert key failed for wrong argument num.")); LOGE("wrong argument num. require 1 or 2 arguments. [Argc]: %zu!", argc); return false; } - context->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSymKeyGenerator *napiGenerator; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); - if (status != napi_ok) { + if (status != napi_ok || napiGenerator == nullptr) { LOGE("failed to unwrap NapiSymKeyGenerator obj!"); return false; } @@ -137,8 +133,6 @@ static bool BuildContextForConvertKey(napi_env env, napi_callback_info info, Sym size_t index = 0; HcfBlob *blob = GetBlobFromNapiValue(env, argv[index++]); if (blob == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "convert key failed for invalid input blob.")); LOGE("get keyMaterial failed!"); return false; } @@ -185,10 +179,9 @@ static void AsyncGenKeyProcess(napi_env env, void *data) HcfSymKeyGenerator *generator = context->generator; HcfSymKey *key = nullptr; - HcfResult res = generator->generateSymKey(generator, &key); - if (res != HCF_SUCCESS) { + context->errCode = generator->generateSymKey(generator, &key); + if (context->errCode != HCF_SUCCESS) { LOGE("generate sym key failed."); - context->errCode = res; context->errMsg = "generate sym key failed."; return; } @@ -214,8 +207,7 @@ static void AsyncKeyReturn(napi_env env, napi_status status, void *data) NapiSymKey *napiSymKey = static_cast(data); delete napiSymKey; return; - }, - nullptr, nullptr); + }, nullptr, nullptr); if (ret != napi_ok) { LOGE("failed to wrap napiSymKey obj!"); context->errCode = HCF_INVALID_PARAMS; @@ -237,15 +229,13 @@ static void AsyncConvertKeyProcess(napi_env env, void *data) HcfSymKeyGenerator *generator = context->generator; HcfSymKey *key = nullptr; - HcfResult res = generator->convertSymKey(generator, &context->keyMaterial, &key); - if (res != HCF_SUCCESS) { + context->errCode = generator->convertSymKey(generator, &context->keyMaterial, &key); + if (context->errCode != HCF_SUCCESS) { LOGE("convertSymKey key failed!"); - context->errCode = res; context->errMsg = "convert sym key failed."; return; } - context->errCode = HCF_SUCCESS; context->returnSymKey = key; } @@ -324,11 +314,13 @@ napi_value NapiSymKeyGenerator::JsGenerateSymKey(napi_env env, napi_callback_inf { SymKeyGeneratorFwkCtx context = static_cast(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0)); if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "Create context failed!")); LOGE("Create context failed!"); return nullptr; } if (!BuildContextForGenerateKey(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Build context fail.")); LOGE("Build context fail."); FreeSymKeyGeneratorFwkCtx(env, context); return nullptr; @@ -347,11 +339,13 @@ napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info in { SymKeyGeneratorFwkCtx context = static_cast(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0)); if (context == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc SymKeyGeneratorFwkCtx failed!")); LOGE("malloc SymKeyGeneratorFwkCtx failed!"); return nullptr; } if (!BuildContextForConvertKey(env, info, context)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "BuildContextForConvertKey failed!")); LOGE("BuildContextForConvertKey failed!"); FreeSymKeyGeneratorFwkCtx(env, context); return nullptr; @@ -369,7 +363,7 @@ napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info in napi_value NapiSymKeyGenerator::SymKeyGeneratorConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); return thisVar; } @@ -388,17 +382,18 @@ napi_value NapiSymKeyGenerator::CreateSymKeyGenerator(napi_env env, napi_callbac napi_value instance; napi_value constructor = nullptr; - NAPI_CALL(env, napi_get_reference_value(env, classRef_, &constructor)); - NAPI_CALL(env, napi_new_instance(env, constructor, argc, argv, &instance)); + napi_get_reference_value(env, classRef_, &constructor); + napi_new_instance(env, constructor, argc, argv, &instance); std::string algoName; if (!GetStringFromJSParams(env, argv[0], algoName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName.")); LOGE("failed to get algoName."); return nullptr; } HcfSymKeyGenerator *generator = nullptr; - int32_t res = HcfSymKeyGeneratorCreate(algoName.c_str(), &generator); + HcfResult res = HcfSymKeyGeneratorCreate(algoName.c_str(), &generator); if (res != HCF_SUCCESS) { napi_throw(env, GenerateBusinessError(env, res, "create C generator fail.")); LOGE("create C generator fail."); @@ -406,7 +401,8 @@ napi_value NapiSymKeyGenerator::CreateSymKeyGenerator(napi_env env, napi_callbac } NapiSymKeyGenerator *napiSymKeyGenerator = new (std::nothrow) NapiSymKeyGenerator(generator); if (napiSymKeyGenerator == nullptr) { - LOGE("new napiSymKeyGenerator failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sym key generator failed.")); + LOGE("new napi sym key generator failed!"); HcfObjDestroy(generator); return nullptr; } @@ -416,10 +412,9 @@ napi_value NapiSymKeyGenerator::CreateSymKeyGenerator(napi_env env, napi_callbac NapiSymKeyGenerator *napiSymKeyGenerator = static_cast(data); delete napiSymKeyGenerator; return; - }, - nullptr, - nullptr); + }, nullptr, nullptr); if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiSymKeyGenerator obj!")); LOGE("failed to wrap napiSymKeyGenerator obj!"); delete napiSymKeyGenerator; return nullptr; @@ -431,8 +426,13 @@ napi_value NapiSymKeyGenerator::JsGetAlgorithm(napi_env env, napi_callback_info { napi_value thisVar = nullptr; NapiSymKeyGenerator *napiSymKeyGenerator = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiSymKeyGenerator))); + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSymKeyGenerator)); + if (status != napi_ok || napiSymKeyGenerator == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSymKeyGenerator obj!")); + LOGE("failed to unwrap napiSymKeyGenerator obj!"); + return nullptr; + } HcfSymKeyGenerator *generator = napiSymKeyGenerator->GetSymKeyGenerator(); const char *algo = generator->getAlgoName(generator); @@ -454,8 +454,9 @@ void NapiSymKeyGenerator::DefineSymKeyGeneratorJSClass(napi_env env, napi_value { .utf8name = "algName", .getter = NapiSymKeyGenerator::JsGetAlgorithm }, }; napi_value constructor = nullptr; - napi_define_class(env, "SymKeyGenerator", NAPI_AUTO_LENGTH, NapiSymKeyGenerator::SymKeyGeneratorConstructor, - nullptr, sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor); + napi_define_class(env, "SymKeyGenerator", NAPI_AUTO_LENGTH, + NapiSymKeyGenerator::SymKeyGeneratorConstructor, nullptr, + sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor); napi_create_reference(env, constructor, 1, &classRef_); } } // CryptoFramework diff --git a/frameworks/js/napi/crypto/src/napi_utils.cpp b/frameworks/js/napi/crypto/src/napi_utils.cpp index c7d1e20..f43b088 100644 --- a/frameworks/js/napi/crypto/src/napi_utils.cpp +++ b/frameworks/js/napi/crypto/src/napi_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -18,16 +18,87 @@ #include "log.h" #include "memory.h" #include "securec.h" -#include "cipher.h" #include "napi_crypto_framework_defines.h" #include "detailed_iv_params.h" #include "detailed_gcm_params.h" #include "detailed_ccm_params.h" +#include "detailed_dsa_key_params.h" +#include "detailed_ecc_key_params.h" +#include "detailed_rsa_key_params.h" namespace OHOS { namespace CryptoFramework { using namespace std; +struct AsyKeySpecItemRelationT { + AsyKeySpecItem item; + int32_t itemType; +}; +using AsyKeySpecItemRelation = AsyKeySpecItemRelationT; + +static const AsyKeySpecItemRelation ASY_KEY_SPEC_RELATION_SET[] = { + { 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 } +}; + +int32_t GetAsyKeySpecType(AsyKeySpecItem targetItemType) +{ + for (uint32_t i = 0; i < sizeof(ASY_KEY_SPEC_RELATION_SET) / sizeof(AsyKeySpecItemRelation); i++) { + if (ASY_KEY_SPEC_RELATION_SET[i].item == targetItemType) { + return ASY_KEY_SPEC_RELATION_SET[i].itemType; + } + } + LOGE("AsyKeySpecItem not support! ItemType: %d", targetItemType); + return -1; +} + +int32_t GetSignSpecType(SignSpecItem targetItemType) +{ + if (targetItemType == PSS_MD_NAME_STR || targetItemType == PSS_MGF_NAME_STR || + targetItemType == PSS_MGF1_MD_STR) { + return SPEC_ITEM_TYPE_STR; + } + if (targetItemType == PSS_SALT_LEN_INT || targetItemType == PSS_TRAILER_FIELD_INT) { + return SPEC_ITEM_TYPE_NUM; + } + LOGE("SignSpecItem not support! ItemType: %d", targetItemType); + return -1; +} + +int32_t GetCipherSpecType(CipherSpecItem targetItemType) +{ + if (targetItemType == OAEP_MD_NAME_STR || targetItemType == OAEP_MGF_NAME_STR || + targetItemType == OAEP_MGF1_MD_STR) { + return SPEC_ITEM_TYPE_STR; + } + if (targetItemType == OAEP_MGF1_PSRC_UINT8ARR) { + return SPEC_ITEM_TYPE_UINT8ARR; + } + LOGE("CipherSpecItem not support! ItemType: %d", targetItemType); + return -1; +} + napi_value NapiGetNull(napi_env env) { napi_value result = nullptr; @@ -42,8 +113,10 @@ HcfBlob *GetBlobFromNapiValue(napi_env env, napi_value arg) return nullptr; } napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_DATA.c_str(), &data); - if ((status != napi_ok) || (data == nullptr)) { + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { LOGE("failed to get valid data property!"); return nullptr; } @@ -77,16 +150,118 @@ HcfBlob *GetBlobFromNapiValue(napi_env env, napi_value arg) HcfFree(newBlob); return nullptr; } - if (memcpy_s(newBlob->data, length, rawData, length) != EOK) { - LOGE("memcpy_s blob data failed!"); - HcfFree(newBlob->data); - HcfFree(newBlob); + (void)memcpy_s(newBlob->data, length, rawData, length); + return newBlob; +} + +HcfBlob *GeneralGetBlobFromNapiValue(napi_env env, napi_value data) +{ + size_t length = 0; + size_t offset = 0; + void *rawData = nullptr; + napi_value arrayBuffer = nullptr; + napi_typedarray_type arrayType; + // Warning: Do not release the rawData returned by this interface because the rawData is managed by VM. + napi_status status = napi_get_typedarray_info(env, data, &arrayType, &length, + reinterpret_cast(&rawData), &arrayBuffer, &offset); + if ((status != napi_ok) || (length == 0) || (rawData == nullptr)) { + LOGE("failed to get valid rawData."); + return nullptr; + } + if (arrayType != napi_uint8_array) { + LOGE("input data is not uint8 array."); return nullptr; } + HcfBlob *newBlob = reinterpret_cast(HcfMalloc(sizeof(HcfBlob), 0)); + if (newBlob == nullptr) { + LOGE("Failed to allocate newBlob memory!"); + return nullptr; + } + newBlob->len = length; + newBlob->data = static_cast(HcfMalloc(length, 0)); + if (newBlob->data == nullptr) { + LOGE("malloc blob data failed!"); + HcfFree(newBlob); + return nullptr; + } + (void)memcpy_s(newBlob->data, length, rawData, length); return newBlob; } +bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt) +{ + if ((env == nullptr) || (arg == nullptr)) { + LOGE("Invalid parmas!"); + return false; + } + + int signBit; + size_t wordCount; + + napi_get_value_bigint_words(env, arg, nullptr, &wordCount, nullptr); + if ((wordCount) == 0 &&(wordCount > (INT_MAX / sizeof(uint64_t)))) { + LOGE("Get big int failed."); + return false; + } + int length = wordCount * sizeof(uint64_t); + uint8_t *retArr = reinterpret_cast(HcfMalloc(length, 0)); + if (retArr == nullptr) { + LOGE("malloc blob data failed!"); + return false; + } + if (napi_get_value_bigint_words(env, arg, &signBit, &wordCount, reinterpret_cast(retArr)) != napi_ok) { + HcfFree(retArr); + LOGE("failed to get valid rawData."); + return false; + } + if (signBit != 0) { + HcfFree(retArr); + LOGE("failed to get gegative rawData."); + return false; + } + bigInt->data = retArr; + bigInt->len = length; + return true; +} + +static bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point) +{ + if ((env == nullptr) || (arg == nullptr)) { + LOGE("Invalid parmas!"); + return false; + } + napi_value dataX = nullptr; + napi_value dataY = nullptr; + napi_valuetype valueType = napi_undefined; + napi_status status = napi_get_named_property(env, arg, "x", &dataX); + napi_typeof(env, dataX, &valueType); + if ((status != napi_ok) || (dataX == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return false; + } + status = napi_get_named_property(env, arg, "y", &dataY); + napi_typeof(env, dataY, &valueType); + if ((status != napi_ok) || (dataY == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return false; + } + + bool ret = GetBigIntFromNapiValue(env, dataX, &point->x); + if (!ret) { + LOGE("get point x failed!"); + return false; + } + ret = GetBigIntFromNapiValue(env, dataY, &point->y); + if (!ret) { + LOGE("get point y failed!"); + HcfFree((point->x).data); + (point->x).data = nullptr; + return false; + } + return true; +} + static const char *GetIvParamsSpecType() { return IV_PARAMS_SPEC.c_str(); @@ -106,9 +281,11 @@ static HcfBlob *GetBlobFromParamsSpec(napi_env env, napi_value arg, const string { napi_value data = nullptr; HcfBlob *blob = nullptr; + napi_valuetype valueType = napi_undefined; napi_status status = napi_get_named_property(env, arg, type.c_str(), &data); - if ((status != napi_ok) || (data == nullptr)) { + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { LOGE("failed to get valid param property!"); return nullptr; } @@ -304,22 +481,648 @@ bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMo } } +static napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, string argName) +{ + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + napi_status status = napi_get_named_property(env, arg, argName.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return nullptr; + } + return data; +} + +static napi_value GetCommSpecNapiValue(napi_env env, napi_value arg) +{ + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + + napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_COMM_PARAMS.c_str(), &data); + napi_typeof(env, data, &valueType); + + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return nullptr; + } + return data; +} + +static bool InitDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfDsaCommParamsSpec *spec) +{ + size_t algNameLen = DSA_ASY_KEY_SPEC.length(); + spec->base.algName = static_cast(HcfMalloc(algNameLen + 1, 0)); + if (spec->base.algName == nullptr) { + LOGE("malloc DSA algName failed!"); + return false; + } + (void)memcpy_s(spec->base.algName, algNameLen+ 1, DSA_ASY_KEY_SPEC.c_str(), algNameLen); + spec->base.specType = HCF_COMMON_PARAMS_SPEC; + + napi_value p = GetDetailAsyKeySpecValue(env, arg, "p"); + napi_value q = GetDetailAsyKeySpecValue(env, arg, "q"); + napi_value g = GetDetailAsyKeySpecValue(env, arg, "g"); + bool ret = GetBigIntFromNapiValue(env, p, &spec->p); + if (!ret) { + HcfFree(spec->base.algName); + spec->base.algName = nullptr; + return false; + } + ret = GetBigIntFromNapiValue(env, q, &spec->q); + if (!ret) { + FreeDsaCommParamsSpec(spec); + return false; + } + ret = GetBigIntFromNapiValue(env, g, &spec->g); + if (!ret) { + FreeDsaCommParamsSpec(spec); + return false; + } + return true; +} + +static bool GetDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfDsaCommParamsSpec *spec = reinterpret_cast(HcfMalloc(sizeof(HcfDsaCommParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + if (!InitDsaCommonAsyKeySpec(env, arg, spec)) { + LOGE("InitDsaCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetDsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfDsaPubKeyParamsSpec *spec = reinterpret_cast( + HcfMalloc(sizeof(HcfDsaPubKeyParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitDsaCommonAsyKeySpec failed."); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_PUBLIC_KEY_SPEC; + + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk); + if (!ret) { + DestroyDsaPubKeySpec(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetDsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfDsaKeyPairParamsSpec *spec = reinterpret_cast( + HcfMalloc(sizeof(HcfDsaKeyPairParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitDsaCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_KEY_PAIR_SPEC; + + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk); + if (!ret) { + FreeDsaCommParamsSpec(reinterpret_cast(spec)); + HcfFree(spec); + return false; + } + napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk"); + ret = GetBigIntFromNapiValue(env, sk, &spec->sk); + if (!ret) { + FreeDsaCommParamsSpec(reinterpret_cast(spec)); + HcfFree(spec->pk.data); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetDsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + + napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return false; + } + HcfAsyKeySpecType asyKeySpecType; + status = napi_get_value_uint32(env, data, reinterpret_cast(&asyKeySpecType)); + if (status != napi_ok) { + LOGE("failed to get valid asyKeySpecType!"); + return false; + } + if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) { + return GetDsaCommonAsyKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) { + return GetDsaPubKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) { + return GetDsaKeyPairAsyKeySpec(env, arg, asyKeySpec); + } else { + return false; + } +} + +static bool GetFpField(napi_env env, napi_value arg, HcfECField **ecField) +{ + HcfECFieldFp *fp = reinterpret_cast(HcfMalloc(sizeof(HcfECFieldFp), 0)); + if (fp == nullptr) { + LOGE("malloc fp failed!"); + return false; + } + + size_t fieldTpyeLen = ECC_FIELD_TYPE_FP.length(); + fp->base.fieldType = static_cast(HcfMalloc(fieldTpyeLen + 1, 0)); + if (fp->base.fieldType == nullptr) { + LOGE("malloc fieldType failed!"); + HcfFree(fp); + return false; + } + (void)memcpy_s(fp->base.fieldType, fieldTpyeLen+ 1, ECC_FIELD_TYPE_FP.c_str(), fieldTpyeLen); + + napi_value p = GetDetailAsyKeySpecValue(env, arg, "p"); + bool ret = GetBigIntFromNapiValue(env, p, &fp->p); + if (!ret) { + HcfFree(fp->base.fieldType); + HcfFree(fp); + return false; + } + *ecField = reinterpret_cast(fp); + return true; +} + +static bool GetField(napi_env env, napi_value arg, HcfECField **ecField) +{ + // get fieldData in { field : fieldData, a : xxx, b : xxx, ... } of ECCCommonParamsSpec first + napi_value fieldData = nullptr; + napi_valuetype valueType = napi_undefined; + napi_status status = napi_get_named_property(env, arg, "field", &fieldData); + napi_typeof(env, fieldData, &valueType); + if ((status != napi_ok) || (fieldData == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid field data!"); + return false; + } + + // get fieldType in { fieldType : fieldTypeData } of ECField + napi_value fieldTypeData = nullptr; + status = napi_get_named_property(env, fieldData, "fieldType", &fieldTypeData); + napi_typeof(env, fieldTypeData, &valueType); + if ((status != napi_ok) || (fieldTypeData == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid fieldType data!"); + return false; + } + string fieldType; + if (!GetStringFromJSParams(env, fieldTypeData, fieldType)) { + LOGE("GetStringFromJSParams failed when extracting fieldType!"); + return false; + } + + // get p in { p : pData } of ECField, and generateECField + if (fieldType.compare("Fp") == 0) { + return GetFpField(env, fieldData, ecField); + } + return false; +} + +static bool InitEccDetailAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec) +{ + napi_value a = GetDetailAsyKeySpecValue(env, arg, "a"); + napi_value b = GetDetailAsyKeySpecValue(env, arg, "b"); + napi_value n = GetDetailAsyKeySpecValue(env, arg, "n"); + napi_value g = GetDetailAsyKeySpecValue(env, arg, "g"); + bool ret = GetBigIntFromNapiValue(env, a, &spec->a); + if (!ret) { + LOGE("get ecc asyKeySpec a failed!"); + return false; + } + ret = GetBigIntFromNapiValue(env, b, &spec->b); + if (!ret) { + LOGE("get ecc asyKeySpec b failed!"); + return false; + } + ret = GetBigIntFromNapiValue(env, n, &spec->n); + if (!ret) { + LOGE("get ecc asyKeySpec n failed!"); + return false; + } + ret = GetPointFromNapiValue(env, g, &spec->g); + if (!ret) { + LOGE("get ecc asyKeySpec g failed!"); + return false; + } + return true; +} + +static bool InitEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec) +{ + size_t algNameLen = ECC_ASY_KEY_SPEC.length(); + spec->base.algName = static_cast(HcfMalloc(algNameLen + 1, 0)); + if (spec->base.algName == nullptr) { + LOGE("malloc ECC algName failed!"); + return false; + } + (void)memcpy_s(spec->base.algName, algNameLen+ 1, ECC_ASY_KEY_SPEC.c_str(), algNameLen); + spec->base.specType = HCF_COMMON_PARAMS_SPEC; + + // get h + napi_value hData = nullptr; + napi_valuetype valueType = napi_undefined; + napi_status status = napi_get_named_property(env, arg, "h", &hData); + napi_typeof(env, hData, &valueType); + if ((status != napi_ok) || (hData == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid h!"); + HcfFree(spec->base.algName); + spec->base.algName = nullptr; + return false; + } + if (!GetInt32FromJSParams(env, hData, spec->h)) { + LOGE("get ecc asyKeySpec h failed!"); + HcfFree(spec->base.algName); + spec->base.algName = nullptr; + return false; + } + // get field + if (!GetField(env, arg, &spec->field)) { + LOGE("GetField failed!"); + HcfFree(spec->base.algName); + spec->base.algName = nullptr; + return false; + } + bool ret = InitEccDetailAsyKeySpec(env, arg, spec); + if (!ret) { + LOGE("get ecc asyKeySpec g failed!"); + FreeEccCommParamsSpec(spec); + return false; + } + return true; +} + +static bool GetEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfEccCommParamsSpec *spec = reinterpret_cast(HcfMalloc(sizeof(HcfEccCommParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + if (!InitEccCommonAsyKeySpec(env, arg, spec)) { + LOGE("InitEccCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetEccPriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfEccPriKeyParamsSpec *spec = + reinterpret_cast(HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitEccCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_PRIVATE_KEY_SPEC; + + napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk"); + bool ret = GetBigIntFromNapiValue(env, sk, &spec->sk); + if (!ret) { + // get big int fail, sk is null + FreeEccCommParamsSpec(reinterpret_cast(spec)); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetEccPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfEccPubKeyParamsSpec *spec = + reinterpret_cast(HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitEccCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_PUBLIC_KEY_SPEC; + + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetPointFromNapiValue(env, pk, &spec->pk); + if (!ret) { + DestroyEccPubKeySpec(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetEccKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfEccKeyPairParamsSpec *spec = + reinterpret_cast(HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitEccCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_KEY_PAIR_SPEC; + + // get big int fail, sk is null + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetPointFromNapiValue(env, pk, &spec->pk); + if (!ret) { + FreeEccCommParamsSpec(reinterpret_cast(spec)); + HcfFree(spec); + return false; + } + napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk"); + ret = GetBigIntFromNapiValue(env, sk, &spec->sk); + if (!ret) { + FreeEccCommParamsSpec(reinterpret_cast(spec)); + HcfFree(spec->pk.x.data); + HcfFree(spec->pk.y.data); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetEccAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + + napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return false; + } + HcfAsyKeySpecType asyKeySpecType; + status = napi_get_value_uint32(env, data, reinterpret_cast(&asyKeySpecType)); + if (status != napi_ok) { + LOGE("failed to get valid asyKeySpecType!"); + return false; + } + if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) { + return GetEccCommonAsyKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) { + return GetEccPriKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) { + return GetEccPubKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) { + return GetEccKeyPairAsyKeySpec(env, arg, asyKeySpec); + } else { + return false; + } +} + +static bool InitRsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfRsaCommParamsSpec *spec) +{ + size_t algNameLen = RSA_ASY_KEY_SPEC.length(); + spec->base.algName = static_cast(HcfMalloc(algNameLen + 1, 0)); + if (spec->base.algName == nullptr) { + LOGE("malloc RSA algName failed!"); + return false; + } + (void)memcpy_s(spec->base.algName, algNameLen+ 1, RSA_ASY_KEY_SPEC.c_str(), algNameLen); + spec->base.specType = HCF_COMMON_PARAMS_SPEC; + + napi_value n = GetDetailAsyKeySpecValue(env, arg, "n"); + + bool ret = GetBigIntFromNapiValue(env, n, &spec->n); + if (!ret) { + LOGE("Rsa asyKeySpec get n failed!"); + HcfFree(spec->base.algName); + spec->base.algName = nullptr; + return false; + } + return true; +} + +static bool GetRsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfRsaPubKeyParamsSpec *spec = + reinterpret_cast(HcfMalloc(sizeof(HcfRsaPubKeyParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitRsaCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_PUBLIC_KEY_SPEC; + + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk); + if (!ret) { + DestroyRsaPubKeySpec(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetRsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + HcfRsaKeyPairParamsSpec *spec = + reinterpret_cast(HcfMalloc(sizeof(HcfRsaKeyPairParamsSpec), 0)); + if (spec == nullptr) { + LOGE("malloc falied!"); + return false; + } + + napi_value commSpecValue = GetCommSpecNapiValue(env, arg); + if (commSpecValue == nullptr) { + LOGE("Get comm spec napi value failed."); + HcfFree(spec); + return false; + } + if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast(spec))) { + LOGE("InitRsaCommonAsyKeySpec failed!"); + HcfFree(spec); + return false; + } + spec->base.base.specType = HCF_KEY_PAIR_SPEC; + + napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk"); + bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk); + if (!ret) { + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec); + return false; + } + napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk"); + ret = GetBigIntFromNapiValue(env, sk, &spec->sk); + if (!ret) { + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + HcfFree(spec); + return false; + } + *asyKeySpec = reinterpret_cast(spec); + return true; +} + +static bool GetRsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + + napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algo name!"); + return false; + } + HcfAsyKeySpecType asyKeySpecType; + status = napi_get_value_uint32(env, data, reinterpret_cast(&asyKeySpecType)); + if (status != napi_ok) { + LOGE("failed to get valid asyKeySpecType!"); + return false; + } + if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) { + LOGE("RSA not support comm key spec"); + return false; + } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) { + return GetRsaPubKeySpec(env, arg, asyKeySpec); + } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) { + return GetRsaKeyPairAsyKeySpec(env, arg, asyKeySpec); + } else { + return false; + } +} + +bool GetAsyKeySpecFromNapiValue(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec) +{ + napi_value data = nullptr; + + if ((env == nullptr) || (arg == nullptr) || (asyKeySpec == nullptr)) { + LOGE("Invalid parmas!"); + return false; + } + + napi_valuetype valueType = napi_undefined; + + napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_ALG_NAME.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid algName!"); + return false; + } + string algName; + if (!GetStringFromJSParams(env, data, algName)) { + LOGE("GetStringFromJSParams failed!"); + return false; + } + if (algName.compare(DSA_ASY_KEY_SPEC) == 0) { + return GetDsaAsyKeySpec(env, arg, asyKeySpec); + } else if (algName.compare(ECC_ASY_KEY_SPEC) == 0) { + return GetEccAsyKeySpec(env, arg, asyKeySpec); + } else if (algName.compare(RSA_ASY_KEY_SPEC) == 0) { + return GetRsaAsyKeySpec(env, arg, asyKeySpec); + } else { + LOGE("GetAsyKeySpecFromNapiValue fialed, algName not support."); + return false; + } +} + napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob) { if (blob == nullptr || blob->data == nullptr || blob->len == 0) { LOGE("Invalid blob!"); - return nullptr; + return NapiGetNull(env); } - uint8_t *buffer = static_cast(HcfMalloc(blob->len, 0)); + uint8_t *buffer = reinterpret_cast(HcfMalloc(blob->len, 0)); if (buffer == nullptr) { LOGE("malloc uint8 array buffer failed!"); - return nullptr; + return NapiGetNull(env); } if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) { LOGE("memcpy_s data to buffer failed!"); HcfFree(buffer); - return nullptr; + return NapiGetNull(env); } napi_value outBuffer = nullptr; @@ -328,7 +1131,7 @@ napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob) if (status != napi_ok) { LOGE("create uint8 array buffer failed!"); HcfFree(buffer); - return nullptr; + return NapiGetNull(env); } buffer = nullptr; @@ -341,13 +1144,93 @@ napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob) return dataBlob; } +napi_value ConvertCipherBlobToNapiValue(napi_env env, HcfBlob *blob) +{ + if (blob == nullptr || blob->data == nullptr || blob->len == 0) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!")); + LOGE("Invalid blob!"); + return NapiGetNull(env); + } + uint8_t *buffer = reinterpret_cast(HcfMalloc(blob->len, 0)); + if (buffer == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!")); + LOGE("malloc uint8 array buffer failed!"); + return NapiGetNull(env); + } + + if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "memcpy_s data to buffer failed!")); + LOGE("memcpy_s data to buffer failed!"); + HcfFree(buffer); + return NapiGetNull(env); + } + + napi_value outBuffer = nullptr; + napi_status status = napi_create_external_arraybuffer( + env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create uint8 array buffer failed!")); + LOGE("create uint8 array buffer failed!"); + HcfFree(buffer); + return NapiGetNull(env); + } + buffer = nullptr; + + napi_value outData = nullptr; + napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData); + return outData; +} + +napi_value ConvertBigIntToNapiValue(napi_env env, HcfBigInteger *blob) +{ + if (blob == nullptr || blob->data == nullptr || blob->len == 0) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!")); + LOGE("Invalid blob!"); + return NapiGetNull(env); + } + size_t wordsCount = (blob->len / sizeof(uint64_t)) + ((blob->len % sizeof(uint64_t)) == 0 ? 0 : 1); + uint64_t *words = reinterpret_cast(HcfMalloc(wordsCount * sizeof(uint64_t), 0)); + if (words == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!")); + LOGE("malloc uint8 array buffer failed!"); + return NapiGetNull(env); + } + + LOGE("uint64_t array words length = %d", wordsCount); + LOGE("uint64_t array words size = %d", wordsCount * sizeof(uint64_t)); + size_t index = 0; + for (size_t i = 0; index < wordsCount; i += sizeof(uint64_t), index++) { + uint64_t tmp = 0; + for (size_t j = 0; j < sizeof(uint64_t); j++) { + if (i + j < blob->len) { + tmp += ((uint64_t)blob->data[i + j] << (sizeof(uint64_t) * j)); + } + } + words[index] = tmp; + } + napi_value bigInt = nullptr; + napi_status status = napi_create_bigint_words(env, 0, wordsCount, words, &bigInt); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create bigint failed!")); + LOGE("create bigint failed!"); + HcfFree(words); + return NapiGetNull(env); + } + if (bigInt == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "bigInt is null!")); + LOGE("bigInt is null!"); + } + HcfFree(words); + words = nullptr; + return bigInt; +} + bool GetStringFromJSParams(napi_env env, napi_value arg, string &returnStr) { napi_valuetype valueType; napi_typeof(env, arg, &valueType); if (valueType != napi_string) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "param type is not string")); - LOGE("wrong argument type. expect string type. [Type]: %d", valueType); + LOGE("wrong argument type. expect string type."); return false; } @@ -370,7 +1253,6 @@ bool GetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt) napi_valuetype valueType; napi_typeof(env, arg, &valueType); if (valueType != napi_number) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "param type is not number")); LOGE("wrong argument type. expect int type. [Type]: %d", valueType); return false; } @@ -387,7 +1269,6 @@ bool GetUint32FromJSParams(napi_env env, napi_value arg, uint32_t &returnInt) napi_valuetype valueType; napi_typeof(env, arg, &valueType); if (valueType != napi_number) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "param type is not number")); LOGE("wrong argument type. expect int type. [Type]: %d", valueType); return false; } @@ -404,7 +1285,6 @@ bool GetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb) napi_valuetype valueType = napi_undefined; napi_typeof(env, arg, &valueType); if (valueType != napi_function) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "param type is not function")); LOGE("wrong argument type. expect callback type. [Type]: %d", valueType); return false; } @@ -413,7 +1293,7 @@ bool GetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb) return true; } -static uint32_t GetJsErrValueByErrCode(int32_t errCode) +static uint32_t GetJsErrValueByErrCode(HcfResult errCode) { switch (errCode) { case HCF_INVALID_PARAMS: @@ -431,7 +1311,7 @@ static uint32_t GetJsErrValueByErrCode(int32_t errCode) } } -napi_value GenerateBusinessError(napi_env env, int32_t errCode, const char *errMsg) +napi_value GenerateBusinessError(napi_env env, HcfResult errCode, const char *errMsg) { napi_value businessError = nullptr; @@ -451,13 +1331,11 @@ bool CheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync { if (isSync) { if (argc != expectedCount) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); LOGE("invalid params count!"); return false; } } else { if ((argc != expectedCount) && (argc != (expectedCount - ARGS_SIZE_ONE))) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); LOGE("invalid params count!"); return false; } @@ -465,6 +1343,19 @@ bool CheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync return true; } +bool isCallback(napi_env env, napi_value argv, size_t argc, size_t expectedArgc) +{ + if (argc == expectedArgc - 1) { + return false; + } + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv, &valueType); + if (valueType == napi_undefined || valueType == napi_null) { + return false; + } + return true; +} + napi_value GetResourceName(napi_env env, const char *name) { napi_value resourceName = nullptr; diff --git a/frameworks/js/napi/crypto/src/napi_verify.cpp b/frameworks/js/napi/crypto/src/napi_verify.cpp index 5d4c1e8..bdc2e89 100644 --- a/frameworks/js/napi/crypto/src/napi_verify.cpp +++ b/frameworks/js/napi/crypto/src/napi_verify.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -35,11 +35,12 @@ struct VerifyInitCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfVerify *verify; - HcfParamsSpec *params; - HcfPubKey *pubKey; + HcfVerify *verify = nullptr; + HcfParamsSpec *params = nullptr; + HcfPubKey *pubKey = nullptr; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct VerifyUpdateCtx { @@ -51,10 +52,11 @@ struct VerifyUpdateCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfVerify *verify; - HcfBlob *data; + HcfVerify *verify = nullptr; + HcfBlob *data = nullptr; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct VerifyDoFinalCtx { @@ -66,11 +68,12 @@ struct VerifyDoFinalCtx { napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - HcfVerify *verify; - HcfBlob *data; - HcfBlob *signatureData; + HcfVerify *verify = nullptr; + HcfBlob *data = nullptr; + HcfBlob *signatureData = nullptr; - int32_t result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; bool isVerifySucc; }; @@ -148,25 +151,22 @@ static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyIn napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiVerify *napiVerify = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); - if (status != napi_ok) { + if (status != napi_ok || napiVerify == nullptr) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } size_t index = 0; NapiPubKey *napiPubKey = nullptr; status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPubKey)); - if (status != napi_ok) { + if (status != napi_ok || napiPubKey == nullptr) { LOGE("failed to unwrap napi pubKey obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PubKey]: param unwarp error.")); return false; } @@ -191,23 +191,20 @@ static bool BuildVerifyJsUpdateCtx(napi_env env, napi_callback_info info, Verify napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiVerify *napiVerify = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); - if (status != napi_ok) { + if (status != napi_ok || napiVerify == nullptr) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } size_t index = 0; HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]); if (blob == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Data]: must be of the DataBlob type.")); return false; } @@ -232,8 +229,6 @@ static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, data = GetBlobFromNapiValue(env, dataValue); if (data == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } } @@ -241,8 +236,6 @@ static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, HcfBlob *signatureData = GetBlobFromNapiValue(env, signatureDataValue); if (signatureData == nullptr) { LOGE("failed to get signature."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[SignatureData]: must be of the DataBlob type.")); HcfBlobDataFree(data); HcfFree(data); return false; @@ -262,16 +255,14 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiVerify *napiVerify = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); - if (status != napi_ok) { + if (status != napi_ok || napiVerify == nullptr) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -284,7 +275,6 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif ctx->verify = napiVerify->GetVerify(); ctx->data = data; ctx->signatureData = signatureData; - ctx->result = HCF_ERR_CRYPTO_OPERATION; if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); @@ -297,8 +287,8 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -314,19 +304,19 @@ static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_valu static void ReturnInitPromiseResult(napi_env env, VerifyInitCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -342,19 +332,19 @@ static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_ static void ReturnUpdatePromiseResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -370,11 +360,11 @@ static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, nap static void ReturnDoFinalPromiseResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, HCF_ERR_CRYPTO_OPERATION, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -382,11 +372,10 @@ void VerifyJsInitAsyncWorkProcess(napi_env env, void *data) { VerifyInitCtx *ctx = static_cast(data); - HcfResult res = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey); + if (ctx->errCode != HCF_SUCCESS) { LOGE("verify init fail."); + ctx->errMsg = "verify init fail."; } } @@ -406,11 +395,10 @@ void VerifyJsUpdateAsyncWorkProcess(napi_env env, void *data) { VerifyUpdateCtx *ctx = static_cast(data); - HcfResult res = ctx->verify->update(ctx->verify, ctx->data); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->verify->update(ctx->verify, ctx->data); + if (ctx->errCode != HCF_SUCCESS) { LOGE("verify update fail."); + ctx->errMsg = "verify update fail."; } } @@ -431,12 +419,13 @@ void VerifyJsDoFinalAsyncWorkProcess(napi_env env, void *data) VerifyDoFinalCtx *ctx = static_cast(data); ctx->isVerifySucc = ctx->verify->verify(ctx->verify, ctx->data, ctx->signatureData); - ctx->result = HCF_SUCCESS; - if (!ctx->isVerifySucc) { LOGE("verify doFinal fail."); + ctx->errCode = HCF_ERR_CRYPTO_OPERATION; + ctx->errMsg = "verify doFinal fail."; return; } + ctx->errCode = HCF_SUCCESS; } void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data) @@ -444,7 +433,7 @@ void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data VerifyDoFinalCtx *ctx = static_cast(data); napi_value result = nullptr; - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_get_boolean(env, ctx->isVerifySucc, &result); } @@ -478,9 +467,7 @@ static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -506,9 +493,7 @@ static napi_value NewVerifyJsUpdateAsyncWork(napi_env env, VerifyUpdateCtx *ctx) if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -534,9 +519,7 @@ static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ct if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -557,14 +540,15 @@ HcfVerify *NapiVerify::GetVerify() napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyInitCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyInitCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsInitCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyInitCtx(env, ctx); return nullptr; @@ -575,14 +559,15 @@ napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info) napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyUpdateCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyUpdateCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsUpdateCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyUpdateCtx(env, ctx); return nullptr; @@ -593,14 +578,15 @@ napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info) napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyDoFinalCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyDoFinalCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsDoFinalCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyDoFinalCtx(env, ctx); return nullptr; @@ -611,24 +597,38 @@ napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info) napi_value NapiVerify::VerifyConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); return thisVar; } +static napi_value NapiWrapVerify(napi_env env, napi_value instance, NapiVerify *napiVerify) +{ + napi_status status = napi_wrap( + env, instance, napiVerify, + [](napi_env env, void *data, void *hint) { + NapiVerify *napiVerify = static_cast(data); + delete napiVerify; + return; + }, nullptr, nullptr); + if (status != napi_ok) { + LOGE("failed to wrap napiVerify obj!"); + delete napiVerify; + napiVerify = nullptr; + return nullptr; + } + return instance; +} + napi_value NapiVerify::CreateJsVerify(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = expectedArgc; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } @@ -640,37 +640,151 @@ napi_value NapiVerify::CreateJsVerify(napi_env env, napi_callback_info info) std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName.")); LOGE("failed to get algoName."); return nullptr; } HcfVerify *verify = nullptr; - int32_t res = HcfVerifyCreate(algName.c_str(), &verify); + HcfResult res = HcfVerifyCreate(algName.c_str(), &verify); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "create c verify fail.")); LOGE("create c verify fail."); return nullptr; } - NapiVerify *napiVerify = new NapiVerify(verify); - - napi_wrap( - env, instance, napiVerify, - [](napi_env env, void *data, void *hint) { - NapiVerify *napiVerify = static_cast(data); - delete napiVerify; - return; - }, - nullptr, - nullptr); + NapiVerify *napiVerify = new (std::nothrow) NapiVerify(verify); + if (napiVerify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi verify failed")); + LOGE("new napi verify failed"); + HcfObjDestroy(verify); + return nullptr; + } napi_value napiAlgName = nullptr; napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); - LOGI("out ..."); + return NapiWrapVerify(env, instance, napiVerify); +} + +// verify setVerifySpec(itemType :VerifySpecItem, itemValue : number) +napi_value NapiVerify::JsSetVerifySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiVerify *napiVerify = nullptr; + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!")); + LOGE("get signspecitem failed!"); + return nullptr; + } + int32_t saltLen; + if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get VerifySpec saltLen failed!")); + LOGE("get VerifySpec saltLen failed!"); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); + if (status != napi_ok || napiVerify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!")); + LOGE("failed to unwrap napiVerify obj!"); + return nullptr; + } + HcfVerify *verify = napiVerify->GetVerify(); + HcfResult res = verify->setVerifySpecInt(verify, item, saltLen); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c setVerifySpecNumber fail.")); + LOGE("c setVerifySpecNumber fail."); + return nullptr; + } + return thisVar; +} + +static napi_value GetVerifySpecString(napi_env env, SignSpecItem item, HcfVerify *verify) +{ + char *returnString = nullptr; + HcfResult res = verify->getVerifySpecString(verify, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecString failed.")); + LOGE("c getVerifySpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance); + HcfFree(returnString); + return instance; +} + +static napi_value GetVerifySpecNumber(napi_env env, SignSpecItem item, HcfVerify *verify) +{ + int returnInt; + HcfResult res = verify->getVerifySpecInt(verify, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecInt failed.")); + LOGE("c getVerifySpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + napi_create_int32(env, returnInt, &instance); return instance; } +napi_value NapiVerify::JsGetVerifySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiVerify *napiVerify = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getVerifySpecString failed!")); + LOGE("get getVerifySpecString failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); + if (status != napi_ok || napiVerify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!")); + LOGE("failed to unwrap napiVerify obj!"); + return nullptr; + } + HcfVerify *verify = napiVerify->GetVerify(); + if (verify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get verify obj!")); + LOGE("failed to get verfiy obj!"); + return nullptr; + } + + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetVerifySpecString(env, item, verify); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetVerifySpecNumber(env, item, verify); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "VerifySpecItem not support!")); + return nullptr; + } +} + void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -682,6 +796,8 @@ void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiVerify::JsInit), DECLARE_NAPI_FUNCTION("update", NapiVerify::JsUpdate), DECLARE_NAPI_FUNCTION("verify", NapiVerify::JsVerify), + DECLARE_NAPI_FUNCTION("setVerifySpec", NapiVerify::JsSetVerifySpec), + DECLARE_NAPI_FUNCTION("getVerifySpec", NapiVerify::JsGetVerifySpec), }; napi_value constructor = nullptr; napi_define_class(env, "Verify", NAPI_AUTO_LENGTH, NapiVerify::VerifyConstructor, nullptr, diff --git a/frameworks/key/asy_key_generator.c b/frameworks/key/asy_key_generator.c index 878eeed..1c3be94 100644 --- a/frameworks/key/asy_key_generator.c +++ b/frameworks/key/asy_key_generator.c @@ -19,6 +19,10 @@ #include "asy_key_generator_spi.h" #include "config.h" +#include "detailed_dsa_key_params.h" +#include "detailed_rsa_key_params.h" +#include "detailed_ecc_key_params.h" +#include "dsa_asy_key_generator_openssl.h" #include "ecc_asy_key_generator_openssl.h" #include "params_parser.h" #include "rsa_asy_key_generator_openssl.h" @@ -26,6 +30,12 @@ #include "memory.h" #include "utils.h" +#define ALG_NAME_DSA "DSA" +#define ALG_NAME_ECC "ECC" +#define ALG_NAME_RSA "RSA" +#define ASY_KEY_GENERATOR_CLASS "HcfAsyKeyGenerator" +#define ASY_KEY_GENERATOR_BY_SPEC_CLASS "HcfAsyKeyGeneratorBySpec" + typedef HcfResult (*HcfAsyKeyGeneratorSpiCreateFunc)(HcfAsyKeyGenParams *, HcfAsyKeyGeneratorSpi **); typedef struct { @@ -37,16 +47,288 @@ typedef struct { } HcfAsyKeyGeneratorImpl; typedef struct { - HCF_ALG_VALUE algo; + HcfAsyKeyGeneratorBySpec base; + + HcfAsyKeyGeneratorSpi *spiObj; + + HcfAsyKeyParamsSpec *paramsSpec; +} HcfAsyKeyGeneratorBySpecImpl; + +typedef struct { + HcfAlgValue algo; HcfAsyKeyGeneratorSpiCreateFunc createSpiFunc; } HcfAsyKeyGenAbility; static const HcfAsyKeyGenAbility ASY_KEY_GEN_ABILITY_SET[] = { { HCF_ALG_RSA, HcfAsyKeyGeneratorSpiRsaCreate }, - { HCF_ALG_ECC, HcfAsyKeyGeneratorSpiEccCreate } + { HCF_ALG_ECC, HcfAsyKeyGeneratorSpiEccCreate }, + { HCF_ALG_DSA, HcfAsyKeyGeneratorSpiDsaCreate } }; +typedef struct { + HcfAlgParaValue value; + int32_t bits; // keyLen + HcfAlgValue algo; // algType +} KeyTypeAlg; + +static const KeyTypeAlg KEY_TYPE_MAP[] = { + { HCF_ALG_ECC_224, HCF_ALG_ECC_224, HCF_ALG_ECC }, + { HCF_ALG_ECC_256, HCF_ALG_ECC_256, HCF_ALG_ECC }, + { HCF_ALG_ECC_384, HCF_ALG_ECC_384, HCF_ALG_ECC }, + { HCF_ALG_ECC_521, HCF_ALG_ECC_521, HCF_ALG_ECC }, + { HCF_OPENSSL_RSA_512, HCF_RSA_KEY_SIZE_512, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_768, HCF_RSA_KEY_SIZE_768, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_1024, HCF_RSA_KEY_SIZE_1024, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_2048, HCF_RSA_KEY_SIZE_2048, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_3072, HCF_RSA_KEY_SIZE_3072, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_4096, HCF_RSA_KEY_SIZE_4096, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_4096, HCF_RSA_KEY_SIZE_4096, HCF_ALG_RSA }, + { HCF_OPENSSL_RSA_8192, HCF_RSA_KEY_SIZE_8192, HCF_ALG_RSA }, + { HCF_ALG_DSA_1024, HCF_DSA_KEY_SIZE_1024, HCF_ALG_DSA }, + { HCF_ALG_DSA_2048, HCF_DSA_KEY_SIZE_2048, HCF_ALG_DSA }, + { HCF_ALG_DSA_3072, HCF_DSA_KEY_SIZE_3072, HCF_ALG_DSA } +}; +static bool IsDsaCommParamsSpecValid(HcfDsaCommParamsSpec *paramsSpec) +{ + if ((paramsSpec->p.data == NULL) || (paramsSpec->p.len == 0)) { + LOGE("BigInteger p is invalid"); + return false; + } + if ((paramsSpec->q.data == NULL) || (paramsSpec->q.len == 0)) { + LOGE("BigInteger q is invalid"); + return false; + } + if ((paramsSpec->g.data == NULL) || (paramsSpec->g.len == 0)) { + LOGE("BigInteger g is invalid"); + return false; + } + return true; +} + +static bool IsDsaPubKeySpecValid(HcfDsaPubKeyParamsSpec *paramsSpec) +{ + if (!IsDsaCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) { + LOGE("BigInteger pk is invalid"); + return false; + } + return true; +} + +static bool IsDsaKeyPairSpecValid(HcfDsaKeyPairParamsSpec *paramsSpec) +{ + if (!IsDsaCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) { + LOGE("BigInteger pk is invalid"); + return false; + } + if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) { + LOGE("BigInteger sk is invalid"); + return false; + } + return true; +} + +static bool IsDsaParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec) +{ + bool ret = false; + switch (paramsSpec->specType) { + case HCF_COMMON_PARAMS_SPEC: + ret = IsDsaCommParamsSpecValid((HcfDsaCommParamsSpec *)paramsSpec); + break; + case HCF_PUBLIC_KEY_SPEC: + ret = IsDsaPubKeySpecValid((HcfDsaPubKeyParamsSpec *)paramsSpec); + break; + case HCF_KEY_PAIR_SPEC: + ret = IsDsaKeyPairSpecValid((HcfDsaKeyPairParamsSpec *)paramsSpec); + break; + default: + LOGE("SpecType not support! [SpecType]: %d", paramsSpec->specType); + break; + } + return ret; +} + +static bool IsEccCommParamsSpecValid(HcfEccCommParamsSpec *paramsSpec) +{ + if ((paramsSpec->a.data == NULL) || (paramsSpec->a.len == 0)) { + LOGE("BigInteger a is invalid"); + return false; + } + if ((paramsSpec->b.data == NULL) || (paramsSpec->b.len == 0)) { + LOGE("BigInteger b is invalid"); + return false; + } + if ((paramsSpec->n.data == NULL) || (paramsSpec->n.len == 0)) { + LOGE("BigInteger n is invalid"); + return false; + } + if ((paramsSpec->g.x.data == NULL) || (paramsSpec->g.x.len == 0) || + (paramsSpec->g.y.data == NULL) || (paramsSpec->g.y.len == 0)) { + LOGE("Point g is invalid"); + return false; + } + if (paramsSpec->field == NULL) { + LOGE("Field is null."); + return false; + } + if (strcmp(paramsSpec->field->fieldType, "Fp") != 0) { + LOGE("Unknown field type."); + return false; + } + HcfECFieldFp *tmp = (HcfECFieldFp *)(paramsSpec->field); + if ((tmp->p.data == NULL) || (tmp->p.len == 0)) { + LOGE("EcFieldFp p is invalid"); + return false; + } + return true; +} + +static bool IsEccPriKeySpecValid(HcfEccPriKeyParamsSpec *paramsSpec) +{ + if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) { + LOGE("BigInteger sk is invalid"); + return false; + } + return true; +} + +static bool IsEccPubKeySpecValid(HcfEccPubKeyParamsSpec *paramsSpec) +{ + if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.x.data == NULL) || (paramsSpec->pk.x.len == 0) || + (paramsSpec->pk.y.data == NULL) || (paramsSpec->pk.y.len == 0)) { + LOGE("Point pk is invalid"); + return false; + } + return true; +} + +static bool IsEccKeyPairSpecValid(HcfEccKeyPairParamsSpec *paramsSpec) +{ + if (!IsEccCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.x.data == NULL) || (paramsSpec->pk.x.len == 0) || + (paramsSpec->pk.y.data == NULL) || (paramsSpec->pk.y.len == 0)) { + LOGE("Point pk is invalid"); + return false; + } + if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) { + LOGE("BigInteger sk is invalid"); + return false; + } + return true; +} + +static bool IsEccParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec) +{ + bool ret = false; + switch (paramsSpec->specType) { + case HCF_COMMON_PARAMS_SPEC: + ret = IsEccCommParamsSpecValid((HcfEccCommParamsSpec *)paramsSpec); + break; + case HCF_PRIVATE_KEY_SPEC: + ret = IsEccPriKeySpecValid((HcfEccPriKeyParamsSpec *)paramsSpec); + break; + case HCF_PUBLIC_KEY_SPEC: + ret = IsEccPubKeySpecValid((HcfEccPubKeyParamsSpec *)paramsSpec); + break; + case HCF_KEY_PAIR_SPEC: + ret = IsEccKeyPairSpecValid((HcfEccKeyPairParamsSpec *)paramsSpec); + break; + default: + LOGE("SpecType not support! [SpecType]: %d", paramsSpec->specType); + break; + } + return ret; +} + +static bool IsRsaCommParamsSpecValid(HcfRsaCommParamsSpec *paramsSpec) +{ + if ((paramsSpec->n.data == NULL) || (paramsSpec->n.len == 0)) { + LOGE("BigInteger n is invalid"); + return false; + } + return true; +} + +static bool IsRsaPubKeySpecValid(HcfRsaPubKeyParamsSpec *paramsSpec) +{ + if (!IsRsaCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) { + LOGE("BigInteger pk is invalid"); + return false; + } + return true; +} + +static bool IsRsaKeyPairSpecValid(HcfRsaKeyPairParamsSpec *paramsSpec) +{ + if (!IsRsaCommParamsSpecValid(&(paramsSpec->base))) { + return false; + } + if ((paramsSpec->pk.data == NULL) || (paramsSpec->pk.len == 0)) { + LOGE("BigInteger pk is invalid"); + return false; + } + if ((paramsSpec->sk.data == NULL) || (paramsSpec->sk.len == 0)) { + LOGE("BigInteger sk is invalid"); + return false; + } + return true; +} + +static bool IsRsaParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec) +{ + bool ret = false; + switch (paramsSpec->specType) { + case HCF_COMMON_PARAMS_SPEC: + ret = IsRsaCommParamsSpecValid((HcfRsaCommParamsSpec *)paramsSpec); + break; + case HCF_PUBLIC_KEY_SPEC: + ret = IsRsaPubKeySpecValid((HcfRsaPubKeyParamsSpec *)paramsSpec); + break; + case HCF_KEY_PAIR_SPEC: + ret = IsRsaKeyPairSpecValid((HcfRsaKeyPairParamsSpec *)paramsSpec); + break; + default: + LOGE("SpecType not support! [SpecType]: %d", paramsSpec->specType); + break; + } + return ret; +} + +static bool IsParamsSpecValid(const HcfAsyKeyParamsSpec *paramsSpec) +{ + if ((paramsSpec == NULL) || (paramsSpec->algName == NULL)) { + LOGE("Params spec is null"); + return false; + } + if (strcmp(paramsSpec->algName, ALG_NAME_DSA) == 0) { + return IsDsaParamsSpecValid(paramsSpec); + } else if (strcmp(paramsSpec->algName, ALG_NAME_ECC) == 0) { + return IsEccParamsSpecValid(paramsSpec); + } else if (strcmp(paramsSpec->algName, ALG_NAME_RSA) == 0) { + return IsRsaParamsSpecValid(paramsSpec); + } else { + LOGE("AlgName not support! [AlgName]: %s", paramsSpec->algName); + return false; + } +} + static HcfAsyKeyGeneratorSpiCreateFunc FindAbility(HcfAsyKeyGenParams *params) { for (uint32_t i = 0; i < sizeof(ASY_KEY_GEN_ABILITY_SET) / sizeof(ASY_KEY_GEN_ABILITY_SET[0]); i++) { @@ -58,7 +340,7 @@ static HcfAsyKeyGeneratorSpiCreateFunc FindAbility(HcfAsyKeyGenParams *params) return NULL; } -static void SetPrimes(HCF_ALG_PARA_VALUE value, HcfAsyKeyGenParams *params) +static void SetPrimes(HcfAlgParaValue value, HcfAsyKeyGenParams *params) { if (params == NULL) { LOGE("params is null."); @@ -82,67 +364,527 @@ static void SetPrimes(HCF_ALG_PARA_VALUE value, HcfAsyKeyGenParams *params) LOGD("user default primes 2"); break; } - LOGD("Set primes:%d\n", params->primes); + LOGD("Set primes:%d!", params->primes); } -static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfAsyKeyGenParams *params) +static void SetKeyType(HcfAlgParaValue value, HcfAsyKeyGenParams *params) { - switch (value) { - case HCF_ALG_ECC_224: - case HCF_ALG_ECC_256: - case HCF_ALG_ECC_384: - case HCF_ALG_ECC_521: - params->bits = value; - params->algo = HCF_ALG_ECC; + for (uint32_t i = 0; i < sizeof(KEY_TYPE_MAP) / sizeof(KEY_TYPE_MAP[0]); i++) { + if (KEY_TYPE_MAP[i].value == value) { + params->bits = KEY_TYPE_MAP[i].bits; + params->algo = KEY_TYPE_MAP[i].algo; + return; + } + } + LOGE("There is not matched algorithm."); +} + +static HcfResult ParseAsyKeyGenParams(const HcfParaConfig* config, void *params) +{ + if (config == NULL || params == NULL) { + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_SUCCESS; + HcfAsyKeyGenParams *paramsObj = (HcfAsyKeyGenParams *)params; + LOGD("Set Parameter: %s", config->tag); + switch (config->paraType) { + case HCF_ALG_KEY_TYPE: + SetKeyType(config->paraValue, paramsObj); break; - case HCF_OPENSSL_RSA_512: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_512; - params->algo = HCF_ALG_RSA; + case HCF_ALG_PRIMES: + SetPrimes(config->paraValue, paramsObj); break; - case HCF_OPENSSL_RSA_768: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_768; - params->algo = HCF_ALG_RSA; + default: + ret = HCF_INVALID_PARAMS; break; - case HCF_OPENSSL_RSA_1024: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_1024; - params->algo = HCF_ALG_RSA; + } + return ret; +} + +static HcfResult CopyAsyKeyParamsSpec(const HcfAsyKeyParamsSpec *srcSpec, HcfAsyKeyParamsSpec *destSpec) +{ + int srcAlgNameLen = strlen(srcSpec->algName); + destSpec->algName = (char *)HcfMalloc(srcAlgNameLen + 1, 0); + if (destSpec->algName == NULL) { + LOGE("Failed to allocate alg name memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(destSpec->algName, srcAlgNameLen, srcSpec->algName, srcAlgNameLen); + destSpec->specType = srcSpec->specType; + return HCF_SUCCESS; +} + +static HcfResult CopyDsaCommonSpec(const HcfDsaCommParamsSpec *srcSpec, HcfDsaCommParamsSpec *destSpec) +{ + if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(destSpec->base)) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + destSpec->p.data = (unsigned char *)HcfMalloc(srcSpec->p.len, 0); + if (destSpec->p.data == NULL) { + LOGE("Failed to allocate p data memory"); + FreeDsaCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + destSpec->q.data = (unsigned char *)HcfMalloc(srcSpec->q.len, 0); + if (destSpec->q.data == NULL) { + LOGE("Failed to allocate q data memory"); + FreeDsaCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + destSpec->g.data = (unsigned char *)HcfMalloc(srcSpec->g.len, 0); + if (destSpec->g.data == NULL) { + LOGE("Failed to allocate g data memory"); + FreeDsaCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(destSpec->p.data, srcSpec->p.len, srcSpec->p.data, srcSpec->p.len); + (void)memcpy_s(destSpec->q.data, srcSpec->q.len, srcSpec->q.data, srcSpec->q.len); + (void)memcpy_s(destSpec->g.data, srcSpec->g.len, srcSpec->g.data, srcSpec->g.len); + destSpec->p.len = srcSpec->p.len; + destSpec->q.len = srcSpec->q.len; + destSpec->g.len = srcSpec->g.len; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaCommonSpecImpl(const HcfDsaCommParamsSpec *srcSpec, HcfDsaCommParamsSpec **destSpec) +{ + HcfDsaCommParamsSpec *spec = (HcfDsaCommParamsSpec *)HcfMalloc(sizeof(HcfDsaCommParamsSpec), 0); + if (spec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + + if (CopyDsaCommonSpec(srcSpec, spec) != HCF_SUCCESS) { + HcfFree(spec); + return HCF_INVALID_PARAMS; + } + + *destSpec = spec; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPubKeySpecImpl(const HcfDsaPubKeyParamsSpec *srcSpec, HcfDsaPubKeyParamsSpec **destSpec) +{ + HcfDsaPubKeyParamsSpec *spec = (HcfDsaPubKeyParamsSpec *)HcfMalloc(sizeof(HcfDsaPubKeyParamsSpec), 0); + if (spec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyDsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) { + HcfFree(spec); + return HCF_INVALID_PARAMS; + } + spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0); + if (spec->pk.data == NULL) { + LOGE("Failed to allocate public key memory"); + FreeDsaCommParamsSpec(&(spec->base)); + HcfFree(spec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len); + spec->pk.len = srcSpec->pk.len; + + *destSpec = spec; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairSpecImpl(const HcfDsaKeyPairParamsSpec *srcSpec, HcfDsaKeyPairParamsSpec **destSpec) +{ + HcfDsaKeyPairParamsSpec *spec = (HcfDsaKeyPairParamsSpec *)HcfMalloc(sizeof(HcfDsaKeyPairParamsSpec), 0); + if (spec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyDsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) { + HcfFree(spec); + return HCF_INVALID_PARAMS; + } + spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0); + if (spec->pk.data == NULL) { + LOGE("Failed to allocate public key memory"); + FreeDsaCommParamsSpec(&(spec->base)); + HcfFree(spec); + return HCF_ERR_MALLOC; + } + spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0); + if (spec->sk.data == NULL) { + LOGE("Failed to allocate private key memory"); + FreeDsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + HcfFree(spec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len); + (void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len); + spec->pk.len = srcSpec->pk.len; + spec->sk.len = srcSpec->sk.len; + + *destSpec = spec; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl) +{ + HcfResult ret = HCF_SUCCESS; + HcfDsaCommParamsSpec *spec = NULL; + switch (paramsSpec->specType) { + case HCF_COMMON_PARAMS_SPEC: + ret = CreateDsaCommonSpecImpl((HcfDsaCommParamsSpec *)paramsSpec, &spec); break; - case HCF_OPENSSL_RSA_2048: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_2048; - params->algo = HCF_ALG_RSA; + case HCF_PUBLIC_KEY_SPEC: + ret = CreateDsaPubKeySpecImpl((HcfDsaPubKeyParamsSpec *)paramsSpec, (HcfDsaPubKeyParamsSpec **)&spec); break; - case HCF_OPENSSL_RSA_3072: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_3072; - params->algo = HCF_ALG_RSA; + case HCF_KEY_PAIR_SPEC: + ret = CreateDsaKeyPairSpecImpl((HcfDsaKeyPairParamsSpec *)paramsSpec, (HcfDsaKeyPairParamsSpec **)&spec); break; - case HCF_OPENSSL_RSA_4096: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_4096; - params->algo = HCF_ALG_RSA; + default: + ret = HCF_INVALID_PARAMS; break; - case HCF_OPENSSL_RSA_8192: - params->bits = (int32_t)HCF_RSA_KEY_SIZE_8192; - params->algo = HCF_ALG_RSA; + } + if (ret == HCF_SUCCESS) { + *impl = (HcfAsyKeyParamsSpec *)spec; + } + return ret; +} + +static HcfResult CopyEcField(const HcfECField *src, HcfECField **dest) +{ + HcfECField *tmpField = (HcfECField *)HcfMalloc(sizeof(HcfECFieldFp), 0); + if (tmpField == NULL) { + LOGE("Alloc memory failed."); + return HCF_ERR_MALLOC; + } + + int32_t srcFieldTypeLen = strlen(src->fieldType); + tmpField->fieldType = (char *)HcfMalloc(srcFieldTypeLen + 1, 0); + if (tmpField->fieldType == NULL) { + LOGE("Failed to allocate field memory."); + HcfFree(tmpField); + return HCF_ERR_MALLOC; + } + HcfECFieldFp *tmpDest = (HcfECFieldFp *)(tmpField); + HcfECFieldFp *tmpSrc = (HcfECFieldFp *)(src); + tmpDest->p.data = (unsigned char *)HcfMalloc(tmpSrc->p.len, 0); + if (tmpDest->p.data == NULL) { + LOGE("Failed to allocate b data memory"); + HcfFree(tmpField->fieldType); + HcfFree(tmpField); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tmpField->fieldType, srcFieldTypeLen, src->fieldType, srcFieldTypeLen); + (void)memcpy_s(tmpDest->p.data, tmpSrc->p.len, tmpSrc->p.data, tmpSrc->p.len); + tmpDest->p.len = tmpSrc->p.len; + + *dest = tmpField; + return HCF_SUCCESS; +} + +static HcfResult CopyPoint(const HcfPoint *src, HcfPoint *dest) +{ + dest->x.data = (unsigned char *)HcfMalloc(src->x.len, 0); + if (dest->x.data == NULL) { + LOGE("Failed to allocate x data memory"); + return HCF_ERR_MALLOC; + } + dest->y.data = (unsigned char *)HcfMalloc(src->y.len, 0); + if (dest->y.data == NULL) { + LOGE("Failed to allocate y data memory"); + HcfFree(dest->x.data); + dest->x.data = NULL; + return HCF_ERR_MALLOC; + } + (void)memcpy_s(dest->x.data, src->x.len, src->x.data, src->x.len); + (void)memcpy_s(dest->y.data, src->y.len, src->y.data, src->y.len); + dest->x.len = src->x.len; + dest->y.len = src->y.len; + return HCF_SUCCESS; +} + +static HcfResult CopyEccCommonSpec(const HcfEccCommParamsSpec *srcSpec, HcfEccCommParamsSpec *destSpec) +{ + if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(destSpec->base)) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + destSpec->a.data = (unsigned char *)HcfMalloc(srcSpec->a.len, 0); + if (destSpec->a.data == NULL) { + LOGE("Failed to allocate a data memory"); + FreeEccCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + destSpec->b.data = (unsigned char *)HcfMalloc(srcSpec->b.len, 0); + if (destSpec->b.data == NULL) { + LOGE("Failed to allocate b data memory"); + FreeEccCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + destSpec->n.data = (unsigned char *)HcfMalloc(srcSpec->n.len, 0); + if (destSpec->n.data == NULL) { + LOGE("Failed to allocate n data memory"); + FreeEccCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + HcfResult res = CopyEcField(srcSpec->field, &(destSpec->field)); + if (res != HCF_SUCCESS) { + LOGE("Failed to allocate field data memory"); + FreeEccCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + res = CopyPoint(&(srcSpec->g), &(destSpec->g)); + if (res != HCF_SUCCESS) { + LOGE("Failed to allocate field data memory"); + FreeEccCommParamsSpec(destSpec); + return HCF_ERR_MALLOC; + } + destSpec->h = srcSpec->h; + (void)memcpy_s(destSpec->a.data, srcSpec->a.len, srcSpec->a.data, srcSpec->a.len); + (void)memcpy_s(destSpec->b.data, srcSpec->b.len, srcSpec->b.data, srcSpec->b.len); + (void)memcpy_s(destSpec->n.data, srcSpec->n.len, srcSpec->n.data, srcSpec->n.len); + destSpec->a.len = srcSpec->a.len; + destSpec->b.len = srcSpec->b.len; + destSpec->n.len = srcSpec->n.len; + return HCF_SUCCESS; +} + +static HcfResult CreateEccCommonSpecImpl(const HcfEccCommParamsSpec *srcSpec, HcfEccCommParamsSpec **destSpec) +{ + HcfEccCommParamsSpec *tmpSpec = (HcfEccCommParamsSpec *)HcfMalloc(sizeof(HcfEccCommParamsSpec), 0); + if (tmpSpec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + + if (CopyEccCommonSpec(srcSpec, tmpSpec) != HCF_SUCCESS) { + HcfFree(tmpSpec); + return HCF_INVALID_PARAMS; + } + + *destSpec = tmpSpec; + return HCF_SUCCESS; +} + +static HcfResult CreateEccPubKeySpecImpl(const HcfEccPubKeyParamsSpec *srcSpec, HcfEccPubKeyParamsSpec **destSpec) +{ + HcfEccPubKeyParamsSpec *tmpSpec = (HcfEccPubKeyParamsSpec *)HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0); + if (tmpSpec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) { + HcfFree(tmpSpec); + return HCF_INVALID_PARAMS; + } + HcfResult res = CopyPoint(&(srcSpec->pk), &(tmpSpec->pk)); + if (res != HCF_SUCCESS) { + LOGE("Failed to allocate public key memory"); + FreeEccCommParamsSpec(&(tmpSpec->base)); + HcfFree(tmpSpec); + return res; + } + + *destSpec = tmpSpec; + return HCF_SUCCESS; +} + +static HcfResult CreateEccPriKeySpecImpl(const HcfEccPriKeyParamsSpec *srcSpec, HcfEccPriKeyParamsSpec **destSpec) +{ + HcfEccPriKeyParamsSpec *tmpSpec = (HcfEccPriKeyParamsSpec *)HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0); + if (tmpSpec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) { + HcfFree(tmpSpec); + return HCF_INVALID_PARAMS; + } + tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0); + if (tmpSpec->sk.data == NULL) { + LOGE("Failed to allocate private key memory"); + FreeEccCommParamsSpec(&(tmpSpec->base)); + HcfFree(tmpSpec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len); + tmpSpec->sk.len = srcSpec->sk.len; + + *destSpec = tmpSpec; + return HCF_SUCCESS; +} + +static HcfResult CreateEccKeyPairSpecImpl(const HcfEccKeyPairParamsSpec *srcSpec, HcfEccKeyPairParamsSpec **destSpec) +{ + HcfEccKeyPairParamsSpec *tmpSpec = (HcfEccKeyPairParamsSpec *)HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0); + if (tmpSpec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyEccCommonSpec(&(srcSpec->base), &(tmpSpec->base)) != HCF_SUCCESS) { + HcfFree(tmpSpec); + return HCF_INVALID_PARAMS; + } + HcfResult res = CopyPoint(&(srcSpec->pk), &(tmpSpec->pk)); + if (res != HCF_SUCCESS) { + LOGE("Failed to allocate public key memory"); + FreeEccCommParamsSpec(&(tmpSpec->base)); + HcfFree(tmpSpec); + return res; + } + tmpSpec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0); + if (tmpSpec->sk.data == NULL) { + LOGE("Failed to allocate private key memory"); + FreeEccCommParamsSpec(&(tmpSpec->base)); + HcfFree(tmpSpec->pk.x.data); + HcfFree(tmpSpec->pk.y.data); + HcfFree(tmpSpec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tmpSpec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len); + tmpSpec->sk.len = srcSpec->sk.len; + + *destSpec = tmpSpec; + return HCF_SUCCESS; +} + +static HcfResult CreateEccParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl) +{ + HcfResult ret = HCF_SUCCESS; + HcfEccCommParamsSpec *spec = NULL; + switch (paramsSpec->specType) { + case HCF_COMMON_PARAMS_SPEC: + ret = CreateEccCommonSpecImpl((HcfEccCommParamsSpec *)paramsSpec, &spec); + break; + case HCF_PUBLIC_KEY_SPEC: + ret = CreateEccPubKeySpecImpl((HcfEccPubKeyParamsSpec *)paramsSpec, (HcfEccPubKeyParamsSpec **)(&spec)); + break; + case HCF_PRIVATE_KEY_SPEC: + ret = CreateEccPriKeySpecImpl((HcfEccPriKeyParamsSpec *)paramsSpec, (HcfEccPriKeyParamsSpec **)(&spec)); + break; + case HCF_KEY_PAIR_SPEC: + ret = CreateEccKeyPairSpecImpl((HcfEccKeyPairParamsSpec *)paramsSpec, (HcfEccKeyPairParamsSpec **)(&spec)); break; default: - LOGE("there is not matched algorithm."); + ret = HCF_INVALID_PARAMS; break; } + if (ret == HCF_SUCCESS) { + *impl = (HcfAsyKeyParamsSpec *)spec; + } + return ret; } -static HcfResult ParseAsyKeyGenParams(const HcfParaConfig* config, void *params) +static HcfResult CopyRsaCommonSpec(const HcfRsaCommParamsSpec *srcSpec, HcfRsaCommParamsSpec *destSpec) { - if (config == NULL || params == NULL) { + if (CopyAsyKeyParamsSpec(&(srcSpec->base), &(destSpec->base)) != HCF_SUCCESS) { return HCF_INVALID_PARAMS; } + destSpec->n.data = (unsigned char *)HcfMalloc(srcSpec->n.len, 0); + if (destSpec->n.data == NULL) { + LOGE("Failed to allocate n data memory"); + HcfFree(destSpec->base.algName); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(destSpec->n.data, srcSpec->n.len, srcSpec->n.data, srcSpec->n.len); + destSpec->n.len = srcSpec->n.len; + return HCF_SUCCESS; +} + +static HcfResult CreateRsaPubKeySpecImpl(const HcfRsaPubKeyParamsSpec *srcSpec, HcfRsaPubKeyParamsSpec **destSpec) +{ + HcfRsaPubKeyParamsSpec *spec = (HcfRsaPubKeyParamsSpec *)HcfMalloc(sizeof(HcfRsaPubKeyParamsSpec), 0); + if (spec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyRsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) { + HcfFree(spec); + return HCF_INVALID_PARAMS; + } + spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0); + if (spec->pk.data == NULL) { + LOGE("Failed to allocate public key memory"); + DestroyRsaPubKeySpec(spec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len); + spec->pk.len = srcSpec->pk.len; + + *destSpec = spec; + return HCF_SUCCESS; +} + +static HcfResult CreateRsaKeyPairSpecImpl(const HcfRsaKeyPairParamsSpec *srcSpec, HcfRsaKeyPairParamsSpec **destSpec) +{ + HcfRsaKeyPairParamsSpec *spec = (HcfRsaKeyPairParamsSpec *)HcfMalloc(sizeof(HcfRsaKeyPairParamsSpec), 0); + if (spec == NULL) { + LOGE("Failed to allocate dest spec memory"); + return HCF_ERR_MALLOC; + } + if (CopyRsaCommonSpec(&(srcSpec->base), &(spec->base)) != HCF_SUCCESS) { + HcfFree(spec); + return HCF_INVALID_PARAMS; + } + spec->pk.data = (unsigned char *)HcfMalloc(srcSpec->pk.len, 0); + if (spec->pk.data == NULL) { + LOGE("Failed to allocate public key memory"); + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec); + return HCF_ERR_MALLOC; + } + spec->sk.data = (unsigned char *)HcfMalloc(srcSpec->sk.len, 0); + if (spec->sk.data == NULL) { + LOGE("Failed to allocate private key memory"); + FreeRsaCommParamsSpec(&(spec->base)); + HcfFree(spec->pk.data); + HcfFree(spec); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(spec->pk.data, srcSpec->pk.len, srcSpec->pk.data, srcSpec->pk.len); + (void)memcpy_s(spec->sk.data, srcSpec->sk.len, srcSpec->sk.data, srcSpec->sk.len); + spec->pk.len = srcSpec->pk.len; + spec->sk.len = srcSpec->sk.len; + + *destSpec = spec; + return HCF_SUCCESS; +} + +static HcfResult CreateRsaParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyParamsSpec **impl) +{ HcfResult ret = HCF_SUCCESS; - HcfAsyKeyGenParams *paramsObj = (HcfAsyKeyGenParams *)params; - LOGI("Set Parameter: %s", config->tag); - switch (config->paraType) { - case HCF_ALG_KEY_TYPE: - SetKeyType(config->paraValue, paramsObj); + HcfRsaCommParamsSpec *spec = NULL; + switch (paramsSpec->specType) { + // commonspe should not be used in RSA + case HCF_COMMON_PARAMS_SPEC: + LOGE("RSA not support comm spec"); + ret = HCF_INVALID_PARAMS; break; - case HCF_ALG_PRIMES: - SetPrimes(config->paraValue, paramsObj); + case HCF_PUBLIC_KEY_SPEC: + ret = CreateRsaPubKeySpecImpl((HcfRsaPubKeyParamsSpec *)paramsSpec, (HcfRsaPubKeyParamsSpec **)&spec); + break; + case HCF_KEY_PAIR_SPEC: + ret = CreateRsaKeyPairSpecImpl((HcfRsaKeyPairParamsSpec *)paramsSpec, (HcfRsaKeyPairParamsSpec **)&spec); + break; + default: + ret = HCF_INVALID_PARAMS; + break; + } + if (ret == HCF_SUCCESS) { + *impl = (HcfAsyKeyParamsSpec *)spec; + } + return ret; +} + +static HcfResult CreateAsyKeyParamsSpecImpl(const HcfAsyKeyParamsSpec *paramsSpec, HcfAlgValue alg, + HcfAsyKeyParamsSpec **impl) +{ + HcfResult ret = HCF_SUCCESS; + switch (alg) { + case HCF_ALG_DSA: + ret = CreateDsaParamsSpecImpl(paramsSpec, impl); + break; + case HCF_ALG_ECC: + ret = CreateEccParamsSpecImpl(paramsSpec, impl); + break; + case HCF_ALG_RSA: + ret = CreateRsaParamsSpecImpl(paramsSpec, impl); break; default: ret = HCF_INVALID_PARAMS; @@ -154,7 +896,12 @@ static HcfResult ParseAsyKeyGenParams(const HcfParaConfig* config, void *params) // export interfaces static const char *GetAsyKeyGeneratorClass(void) { - return "HcfAsyKeyGenerator"; + return ASY_KEY_GENERATOR_CLASS; +} + +static const char *GetAsyKeyGeneratorBySpecClass(void) +{ + return ASY_KEY_GENERATOR_BY_SPEC_CLASS; } static const char *GetAlgoName(HcfAsyKeyGenerator *self) @@ -166,7 +913,21 @@ static const char *GetAlgoName(HcfAsyKeyGenerator *self) if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) { return NULL; } - return ((HcfAsyKeyGeneratorImpl *)self)->algoName; + HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self; + return impl->algoName; +} + +static const char *GetAlgNameBySpec(const HcfAsyKeyGeneratorBySpec *self) +{ + if (self == NULL) { + LOGE("The input self ptr is NULL!"); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) { + return NULL; + } + HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self; + return impl->paramsSpec->algName; } static HcfResult ConvertKey(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, @@ -179,13 +940,14 @@ static HcfResult ConvertKey(HcfAsyKeyGenerator *self, HcfParamsSpec *params, Hcf if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) { return HCF_INVALID_PARAMS; } - return ((HcfAsyKeyGeneratorImpl *)self)->spiObj->engineConvertKey( - ((HcfAsyKeyGeneratorImpl *)self)->spiObj, params, pubKeyBlob, priKeyBlob, returnKeyPair); + HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self; + return impl->spiObj->engineConvertKey(impl->spiObj, params, pubKeyBlob, priKeyBlob, returnKeyPair); } static HcfResult GenerateKeyPair(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfKeyPair **returnKeyPair) { + (void)params; if (self == NULL) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -193,8 +955,47 @@ static HcfResult GenerateKeyPair(HcfAsyKeyGenerator *self, HcfParamsSpec *params if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) { return HCF_INVALID_PARAMS; } - return ((HcfAsyKeyGeneratorImpl *)self)->spiObj->engineGenerateKeyPair( - ((HcfAsyKeyGeneratorImpl *)self)->spiObj, returnKeyPair); + HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self; + return impl->spiObj->engineGenerateKeyPair(impl->spiObj, returnKeyPair); +} + +static HcfResult GenerateKeyPairBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfKeyPair **returnKeyPair) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) { + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self; + return impl->spiObj->engineGenerateKeyPairBySpec(impl->spiObj, impl->paramsSpec, returnKeyPair); +} + +static HcfResult GeneratePubKeyBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfPubKey **returnPubKey) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) { + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self; + return impl->spiObj->engineGeneratePubKeyBySpec(impl->spiObj, impl->paramsSpec, returnPubKey); +} + +static HcfResult GeneratePriKeyBySpec(const HcfAsyKeyGeneratorBySpec *self, HcfPriKey **returnPriKey) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) { + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self; + return impl->spiObj->engineGeneratePriKeyBySpec(impl->spiObj, impl->paramsSpec, returnPriKey); } static void DestroyAsyKeyGenerator(HcfObjectBase *self) @@ -211,6 +1012,22 @@ static void DestroyAsyKeyGenerator(HcfObjectBase *self) HcfFree(impl); } +static void DestroyAsyKeyGeneratorBySpec(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorBySpecClass())) { + return; + } + HcfAsyKeyGeneratorBySpecImpl *impl = (HcfAsyKeyGeneratorBySpecImpl *)self; + HcfObjDestroy(impl->spiObj); + impl->spiObj = NULL; + FreeAsyKeySpec(impl->paramsSpec); + impl->paramsSpec = NULL; + HcfFree(impl); +} + HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **returnObj) { if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { @@ -236,10 +1053,10 @@ HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **re if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnGenerator); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfAsyKeyGeneratorSpi *spiObj = NULL; - int32_t res = HCF_SUCCESS; + HcfResult res = HCF_SUCCESS; res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); @@ -255,3 +1072,50 @@ HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **re *returnObj = (HcfAsyKeyGenerator *)returnGenerator; return HCF_SUCCESS; } + +HcfResult HcfAsyKeyGeneratorBySpecCreate(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyGeneratorBySpec **returnObj) +{ + if ((!IsParamsSpecValid(paramsSpec)) || (returnObj == NULL)) { + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGenParams params = { 0 }; + if (ParseAlgNameToParams(paramsSpec->algName, ¶ms) != HCF_SUCCESS) { + LOGE("Failed to parser parmas!"); + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorSpiCreateFunc createSpiFunc = FindAbility(¶ms); + if (createSpiFunc == NULL) { + return HCF_NOT_SUPPORT; + } + HcfAsyKeyGeneratorBySpecImpl *returnGenerator = + (HcfAsyKeyGeneratorBySpecImpl *)HcfMalloc(sizeof(HcfAsyKeyGeneratorBySpecImpl), 0); + if (returnGenerator == NULL) { + LOGE("Failed to allocate returnGenerator memory!"); + return HCF_ERR_MALLOC; + } + HcfAsyKeyParamsSpec *paramsSpecImpl = NULL; + HcfResult ret = CreateAsyKeyParamsSpecImpl(paramsSpec, params.algo, ¶msSpecImpl); + if (ret != HCF_SUCCESS) { + LOGE("Failed to create asy key params spec impl!"); + HcfFree(returnGenerator); + return ret; + } + HcfAsyKeyGeneratorSpi *spiObj = NULL; + ret = createSpiFunc(¶ms, &spiObj); + if (ret != HCF_SUCCESS) { + LOGE("Failed to create spi object!"); + HcfFree(returnGenerator); + FreeAsyKeySpec(paramsSpecImpl); + return ret; + } + returnGenerator->base.base.destroy = DestroyAsyKeyGeneratorBySpec; + returnGenerator->base.base.getClass = GetAsyKeyGeneratorBySpecClass; + returnGenerator->base.generateKeyPair = GenerateKeyPairBySpec; + returnGenerator->base.generatePubKey = GeneratePubKeyBySpec; + returnGenerator->base.generatePriKey = GeneratePriKeyBySpec; + returnGenerator->base.getAlgName = GetAlgNameBySpec; + returnGenerator->paramsSpec = paramsSpecImpl; + returnGenerator->spiObj = spiObj; + *returnObj = (HcfAsyKeyGeneratorBySpec *)returnGenerator; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/frameworks/key/sym_key_generator.c b/frameworks/key/sym_key_generator.c index b45bd2b..5f75a7b 100644 --- a/frameworks/key/sym_key_generator.c +++ b/frameworks/key/sym_key_generator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -37,7 +37,7 @@ typedef struct { } SymKeyGenFuncSet; typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; SymKeyGenFuncSet funcSet; } SymKeyGenAbility; @@ -66,7 +66,7 @@ static const SymKeyGenFuncSet *FindAbility(SymKeyAttr *attr) return NULL; } -static void SetKeyLength(HCF_ALG_PARA_VALUE value, void *attr) +static void SetKeyLength(HcfAlgParaValue value, void *attr) { SymKeyAttr *keyAttr = (SymKeyAttr *)attr; @@ -100,7 +100,6 @@ static HcfResult OnSetSymKeyParameter(const HcfParaConfig* config, void *attr) HcfResult ret = HCF_SUCCESS; LOGD("Set Parameter:%s\n", config->tag); switch (config->paraType) { - case HCF_ALG_TYPE: case HCF_ALG_KEY_TYPE: SetKeyLength(config->paraValue, attr); break; @@ -200,10 +199,10 @@ HcfResult HcfSymKeyGeneratorCreate(const char *algoName, HcfSymKeyGenerator **re if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName)) { LOGE("Failed to copy algoName!"); HcfFree(returnGenerator); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfSymKeyGeneratorSpi *spiObj = NULL; - int32_t res = funcSet->createFunc(&attr, &spiObj); + HcfResult res = funcSet->createFunc(&attr, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnGenerator); diff --git a/frameworks/spi/asy_key_generator_spi.h b/frameworks/spi/asy_key_generator_spi.h index c88fa4d..de66eb5 100644 --- a/frameworks/spi/asy_key_generator_spi.h +++ b/frameworks/spi/asy_key_generator_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -18,6 +18,7 @@ #include #include "algorithm_parameter.h" +#include "asy_key_params.h" #include "result.h" #include "key_pair.h" @@ -40,6 +41,15 @@ struct HcfAsyKeyGeneratorSpi { HcfResult (*engineConvertKey)(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair); + + HcfResult (*engineGenerateKeyPairBySpec)(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *paramsSpec, + HcfKeyPair **returnKeyPair); + + HcfResult (*engineGeneratePubKeyBySpec)(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *paramsSpec, + HcfPubKey **returnPubKey); + + HcfResult (*engineGeneratePriKeyBySpec)(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *paramsSpec, + HcfPriKey **returnPriKey); }; #endif diff --git a/frameworks/spi/cipher_factory_spi.h b/frameworks/spi/cipher_factory_spi.h index 1806bd9..79ab1cf 100644 --- a/frameworks/spi/cipher_factory_spi.h +++ b/frameworks/spi/cipher_factory_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -35,6 +35,12 @@ struct HcfCipherGeneratorSpi { HcfResult (*update)(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output); HcfResult (*doFinal)(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output); + + HcfResult (*setCipherSpecUint8Array)(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob pSource); + + HcfResult (*getCipherSpecString)(HcfCipherGeneratorSpi *self, CipherSpecItem item, char **returnString); + + HcfResult (*getCipherSpecUint8Array)(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob *returnUint8Array); }; #endif diff --git a/frameworks/spi/rand_spi.h b/frameworks/spi/rand_spi.h index 5825d79..8b554c6 100644 --- a/frameworks/spi/rand_spi.h +++ b/frameworks/spi/rand_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -21,10 +21,14 @@ #include "blob.h" #include "object_base.h" +#define OPENSSL_RAND_ALGORITHM "CTR_DRBG" + typedef struct HcfRandSpi HcfRandSpi; struct HcfRandSpi { HcfObjectBase base; + + const char *(*engineGetAlgoName)(HcfRandSpi *self); HcfResult (*engineGenerateRandom)(HcfRandSpi *self, int32_t numBytes, HcfBlob *random); diff --git a/frameworks/spi/signature_spi.h b/frameworks/spi/signature_spi.h index 971a07a..f1cb9d2 100644 --- a/frameworks/spi/signature_spi.h +++ b/frameworks/spi/signature_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -21,6 +21,7 @@ #include "pri_key.h" #include "pub_key.h" #include "result.h" +#include "signature.h" #define OPENSSL_RSA_SIGN_CLASS "OPENSSL.RSA.SIGN" @@ -36,6 +37,12 @@ struct HcfSignSpi { HcfResult (*engineUpdate)(HcfSignSpi *self, HcfBlob *data); HcfResult (*engineSign)(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData); + + HcfResult (*engineSetSignSpecInt)(HcfSignSpi *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*engineGetSignSpecString)(HcfSignSpi *self, SignSpecItem item, char **returnString); + + HcfResult (*engineGetSignSpecInt)(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt); }; typedef struct HcfVerifySpi HcfVerifySpi; @@ -48,6 +55,12 @@ struct HcfVerifySpi { HcfResult (*engineUpdate)(HcfVerifySpi *self, HcfBlob *data); bool (*engineVerify)(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData); + + HcfResult (*engineSetVerifySpecInt)(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*engineGetVerifySpecString)(HcfVerifySpi *self, SignSpecItem item, char **returnString); + + HcfResult (*engineGetVerifySpecInt)(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt); }; #endif diff --git a/interfaces/innerkits/algorithm_parameter/asy_key_params.h b/interfaces/innerkits/algorithm_parameter/asy_key_params.h new file mode 100644 index 0000000..3f4db80 --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/asy_key_params.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 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 HCF_DETAILED_ASY_KEY_PARAMS_H +#define HCF_DETAILED_ASY_KEY_PARAMS_H + +typedef enum { + HCF_COMMON_PARAMS_SPEC = 0, + HCF_PRIVATE_KEY_SPEC = 1, + HCF_PUBLIC_KEY_SPEC = 2, + HCF_KEY_PAIR_SPEC = 3, +} HcfAsyKeySpecType; + +typedef struct HcfAsyKeyParamsSpec HcfAsyKeyParamsSpec; + +struct HcfAsyKeyParamsSpec { + char *algName; + HcfAsyKeySpecType specType; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void FreeAsyKeySpec(HcfAsyKeyParamsSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h b/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h new file mode 100644 index 0000000..6d560db --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 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 HCF_DETAILED_DSA_KEY_PARAMS_H +#define HCF_DETAILED_DSA_KEY_PARAMS_H + +#include "asy_key_params.h" +#include "big_integer.h" + +typedef struct HcfDsaCommParamsSpec HcfDsaCommParamsSpec; + +struct HcfDsaCommParamsSpec { + HcfAsyKeyParamsSpec base; + HcfBigInteger p; + HcfBigInteger q; + HcfBigInteger g; +}; + +typedef struct HcfDsaPubKeyParamsSpec HcfDsaPubKeyParamsSpec; + +struct HcfDsaPubKeyParamsSpec { + HcfDsaCommParamsSpec base; + HcfBigInteger pk; +}; + +typedef struct HcfDsaKeyPairParamsSpec HcfDsaKeyPairParamsSpec; + +struct HcfDsaKeyPairParamsSpec { + HcfDsaCommParamsSpec base; + HcfBigInteger pk; + HcfBigInteger sk; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void FreeDsaCommParamsSpec(HcfDsaCommParamsSpec *spec); + +void DestroyDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec); + +void DestroyDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h b/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h new file mode 100644 index 0000000..a2af540 --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2023 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 HCF_DETAILED_ECC_KEY_PARAMS_H +#define HCF_DETAILED_ECC_KEY_PARAMS_H + +#include +#include + +#include "asy_key_params.h" +#include "big_integer.h" + +typedef struct HcfECField { + char *fieldType; +} HcfECField; + +typedef struct HcfECFieldFp { + HcfECField base; + HcfBigInteger p; +} HcfECFieldFp; + +typedef struct HcfPoint HcfPoint; +struct HcfPoint { + HcfBigInteger x; + HcfBigInteger y; +}; + +typedef struct HcfEccCommParamsSpec { + HcfAsyKeyParamsSpec base; + HcfECField *field; + HcfBigInteger a; + HcfBigInteger b; + HcfPoint g; + HcfBigInteger n; + int32_t h; +} HcfEccCommParamsSpec; + +typedef struct HcfEccPubKeyParamsSpec { + HcfEccCommParamsSpec base; + HcfPoint pk; +} HcfEccPubKeyParamsSpec; + +typedef struct HcfEccPriKeyParamsSpec { + HcfEccCommParamsSpec base; + HcfBigInteger sk; +} HcfEccPriKeyParamsSpec; + +typedef struct HcfEccKeyPairParamsSpec { + HcfEccCommParamsSpec base; + HcfBigInteger sk; + HcfPoint pk; +} HcfEccKeyPairParamsSpec; +#ifdef __cplusplus +extern "C" { +#endif + +void FreeEccCommParamsSpec(HcfEccCommParamsSpec *spec); + +void DestroyEccPriKeySpec(HcfEccPriKeyParamsSpec *spec); + +void DestroyEccPubKeySpec(HcfEccPubKeyParamsSpec *spec); + +void DestroyEccKeyPairSpec(HcfEccKeyPairParamsSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/interfaces/innerkits/algorithm_parameter/detailed_rsa_key_params.h b/interfaces/innerkits/algorithm_parameter/detailed_rsa_key_params.h new file mode 100644 index 0000000..b1071c0 --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/detailed_rsa_key_params.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 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 HCF_DETAILED_RSA_KEY_PARAMS_H +#define HCF_DETAILED_RSA_KEY_PARAMS_H + +#include "asy_key_params.h" +#include "big_integer.h" + +typedef struct HcfRsaCommParamsSpec HcfRsaCommParamsSpec; + +struct HcfRsaCommParamsSpec { + HcfAsyKeyParamsSpec base; + HcfBigInteger n; +}; + +typedef struct HcfRsaPubKeyParamsSpec HcfRsaPubKeyParamsSpec; + +struct HcfRsaPubKeyParamsSpec { + HcfRsaCommParamsSpec base; + HcfBigInteger pk; +}; + +typedef struct HcfRsaKeyPairParamsSpec HcfRsaKeyPairParamsSpec; + +struct HcfRsaKeyPairParamsSpec { + HcfRsaCommParamsSpec base; + HcfBigInteger pk; + HcfBigInteger sk; +}; +#ifdef __cplusplus +extern "C" { +#endif + +void FreeRsaCommParamsSpec(HcfRsaCommParamsSpec *spec); + +void DestroyRsaPubKeySpec(HcfRsaPubKeyParamsSpec *spec); + +void DestroyRsaKeyPairSpec(HcfRsaKeyPairParamsSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif // HCF_DETAILED_RSA_KEY_PARAMS_H \ No newline at end of file diff --git a/interfaces/innerkits/common/big_integer.h b/interfaces/innerkits/common/big_integer.h new file mode 100644 index 0000000..ac96b22 --- /dev/null +++ b/interfaces/innerkits/common/big_integer.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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 HCF_BIG_INTEGER_H +#define HCF_BIG_INTEGER_H + +#include + +typedef struct HcfBigInteger HcfBigInteger; + +struct HcfBigInteger { + unsigned char *data; + uint32_t len; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void HcfBigIntFree(HcfBigInteger *bigInt); +void HcfBigIntDataFree(HcfBigInteger *bigInt); +void HcfBigIntDataClearAndFree(HcfBigInteger *bigInt); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/interfaces/innerkits/crypto_operation/cipher.h b/interfaces/innerkits/crypto_operation/cipher.h index 885b51e..ea2ed43 100644 --- a/interfaces/innerkits/crypto_operation/cipher.h +++ b/interfaces/innerkits/crypto_operation/cipher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -36,9 +36,16 @@ enum HcfCryptoMode { DECRYPT_MODE = 1, }; +typedef enum { + OAEP_MD_NAME_STR = 100, + OAEP_MGF_NAME_STR = 101, + OAEP_MGF1_MD_STR = 102, + OAEP_MGF1_PSRC_UINT8ARR = 103, +} CipherSpecItem; + typedef struct HcfCipher HcfCipher; /** - * @brief his class provides cipher algorithms for cryptographic operations, + * @brief this class provides cipher algorithms for cryptographic operations, * mainly including encrypt and decrypt. * * @since 9 @@ -55,6 +62,12 @@ struct HcfCipher { HcfResult (*doFinal)(HcfCipher *self, HcfBlob *input, HcfBlob *output); const char *(*getAlgorithm)(HcfCipher *self); + + HcfResult (*setCipherSpecUint8Array)(HcfCipher *self, CipherSpecItem item, HcfBlob pSource); + + HcfResult (*getCipherSpecString)(HcfCipher *self, CipherSpecItem item, char **returnString); + + HcfResult (*getCipherSpecUint8Array)(HcfCipher *self, CipherSpecItem item, HcfBlob *returnUint8Array); }; #ifdef __cplusplus diff --git a/interfaces/innerkits/rand/rand.h b/interfaces/innerkits/crypto_operation/rand.h similarity index 95% rename from interfaces/innerkits/rand/rand.h rename to interfaces/innerkits/crypto_operation/rand.h index d272a09..2f1c77f 100644 --- a/interfaces/innerkits/rand/rand.h +++ b/interfaces/innerkits/crypto_operation/rand.h @@ -27,6 +27,8 @@ typedef struct HcfRand HcfRand; struct HcfRand { HcfObjectBase base; + const char *(*getAlgoName)(HcfRand *self); + HcfResult (*generateRandom)(HcfRand *self, int32_t numBytes, HcfBlob *random); HcfResult (*setSeed)(HcfRand *self, HcfBlob *seed); diff --git a/interfaces/innerkits/crypto_operation/signature.h b/interfaces/innerkits/crypto_operation/signature.h index ea5b2be..9186904 100644 --- a/interfaces/innerkits/crypto_operation/signature.h +++ b/interfaces/innerkits/crypto_operation/signature.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -22,6 +22,14 @@ #include "result.h" #include "key_pair.h" +typedef enum { + PSS_MD_NAME_STR = 100, + PSS_MGF_NAME_STR = 101, + PSS_MGF1_MD_STR = 102, + PSS_SALT_LEN_INT = 103, // warning: PSS_SALT_LEN_NUM in JS + PSS_TRAILER_FIELD_INT = 104, // warning: PSS_TRAILER_FIELD_NUM in JS +} SignSpecItem; + typedef struct HcfSign HcfSign; struct HcfSign { @@ -34,6 +42,12 @@ struct HcfSign { HcfResult (*sign)(HcfSign *self, HcfBlob *data, HcfBlob *returnSignatureData); const char *(*getAlgoName)(HcfSign *self); + + HcfResult (*setSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*getSignSpecString)(HcfSign *self, SignSpecItem item, char **returnString); + + HcfResult (*getSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t *returnInt); }; typedef struct HcfVerify HcfVerify; @@ -48,6 +62,12 @@ struct HcfVerify { bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData); const char *(*getAlgoName)(HcfVerify *self); + + HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*getVerifySpecString)(HcfVerify *self, SignSpecItem item, char **returnString); + + HcfResult (*getVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t *returnInt); }; #ifdef __cplusplus diff --git a/interfaces/innerkits/key/asy_key_generator.h b/interfaces/innerkits/key/asy_key_generator.h index 4c22dd8..198ebcd 100644 --- a/interfaces/innerkits/key/asy_key_generator.h +++ b/interfaces/innerkits/key/asy_key_generator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -18,6 +18,7 @@ #include #include "algorithm_parameter.h" +#include "asy_key_params.h" #include "result.h" #include "key_pair.h" @@ -31,6 +32,12 @@ enum HcfRsaKeySize { HCF_RSA_KEY_SIZE_8192 = 8192, }; +enum HcfDsaKeySize { + HCF_DSA_KEY_SIZE_1024 = 1024, + HCF_DSA_KEY_SIZE_2048 = 2048, + HCF_DSA_KEY_SIZE_3072 = 3072, +}; + enum HcfRsaPrimesSize { HCF_RSA_PRIMES_SIZE_2 = 2, HCF_RSA_PRIMES_SIZE_3 = 3, @@ -52,12 +59,28 @@ struct HcfAsyKeyGenerator { const char *(*getAlgoName)(HcfAsyKeyGenerator *self); }; +typedef struct HcfAsyKeyGeneratorBySpec HcfAsyKeyGeneratorBySpec; + +struct HcfAsyKeyGeneratorBySpec { + HcfObjectBase base; + + HcfResult (*generateKeyPair)(const HcfAsyKeyGeneratorBySpec *self, HcfKeyPair **returnKeyPair); + + HcfResult (*generatePubKey)(const HcfAsyKeyGeneratorBySpec *self, HcfPubKey **returnPubKey); + + HcfResult (*generatePriKey)(const HcfAsyKeyGeneratorBySpec *self, HcfPriKey **returnPriKey); + + const char *(*getAlgName)(const HcfAsyKeyGeneratorBySpec *self); +}; + #ifdef __cplusplus extern "C" { #endif HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **returnObj); +HcfResult HcfAsyKeyGeneratorBySpecCreate(const HcfAsyKeyParamsSpec *paramsSpec, HcfAsyKeyGeneratorBySpec **returnObj); + #ifdef __cplusplus } #endif diff --git a/interfaces/innerkits/key/key.h b/interfaces/innerkits/key/key.h index e19b7d3..7e08c3a 100644 --- a/interfaces/innerkits/key/key.h +++ b/interfaces/innerkits/key/key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -20,6 +20,32 @@ #include "result.h" #include "object_base.h" +typedef enum { + 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_INT = 207, // warning: ECC_H_NUM in JS + ECC_SK_BN = 208, + ECC_PK_X_BN = 209, + ECC_PK_Y_BN = 210, + ECC_FIELD_TYPE_STR = 211, + ECC_FIELD_SIZE_INT = 212, // warning: ECC_FIELD_SIZE_NUM in JS + ECC_CURVE_NAME_STR = 213, + + RSA_N_BN = 301, + RSA_SK_BN = 302, + RSA_PK_BN = 303, +} AsyKeySpecItem; + typedef struct HcfKey HcfKey; struct HcfKey { diff --git a/interfaces/innerkits/key/pri_key.h b/interfaces/innerkits/key/pri_key.h index 7e047ef..72fd9ef 100644 --- a/interfaces/innerkits/key/pri_key.h +++ b/interfaces/innerkits/key/pri_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -16,6 +16,7 @@ #ifndef HCF_PRI_KEY_H #define HCF_PRI_KEY_H +#include "big_integer.h" #include "key.h" typedef struct HcfPriKey HcfPriKey; @@ -23,6 +24,13 @@ typedef struct HcfPriKey HcfPriKey; struct HcfPriKey { HcfKey base; + HcfResult (*getAsyKeySpecBigInteger)(const HcfPriKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger); + + HcfResult (*getAsyKeySpecString)(const HcfPriKey *self, const AsyKeySpecItem item, char **returnString); + + HcfResult (*getAsyKeySpecInt)(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt); + void (*clearMem)(HcfPriKey *self); }; diff --git a/interfaces/innerkits/key/pub_key.h b/interfaces/innerkits/key/pub_key.h index 871e024..3ed35f2 100644 --- a/interfaces/innerkits/key/pub_key.h +++ b/interfaces/innerkits/key/pub_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -16,12 +16,20 @@ #ifndef HCF_PUB_KEY_H #define HCF_PUB_KEY_H +#include "big_integer.h" #include "key.h" typedef struct HcfPubKey HcfPubKey; struct HcfPubKey { HcfKey base; + + HcfResult (*getAsyKeySpecBigInteger)(const HcfPubKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger); + + HcfResult (*getAsyKeySpecString)(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString); + + HcfResult (*getAsyKeySpecInt)(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt); }; #endif diff --git a/plugin/BUILD.gn b/plugin/BUILD.gn index 80986bd..f2a66b8 100644 --- a/plugin/BUILD.gn +++ b/plugin/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -22,7 +22,6 @@ config("plugin_config") { "//base/security/crypto_framework/interfaces/innerkits/common", "//base/security/crypto_framework/interfaces/innerkits/crypto_operation", "//base/security/crypto_framework/interfaces/innerkits/key", - "//base/security/crypto_framework/interfaces/innerkits/rand", "//base/security/crypto_framework/frameworks/spi", ] } diff --git a/plugin/openssl_plugin/certificate/src/x509_certificate_openssl.c b/plugin/openssl_plugin/certificate/src/x509_certificate_openssl.c index 2749b69..8a7fee8 100644 --- a/plugin/openssl_plugin/certificate/src/x509_certificate_openssl.c +++ b/plugin/openssl_plugin/certificate/src/x509_certificate_openssl.c @@ -105,10 +105,26 @@ static const char *GetPubKeyAlgorithm(HcfKey *self) static HcfResult GetPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) { - (void)self; - (void)returnBlob; - LOGD("Not supported!"); - return HCF_NOT_SUPPORT; + if (self == NULL || returnBlob == NULL) { + LOGE("input params is invalid"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetX509CertPubKeyClass())) { + LOGE("Input wrong class type!"); + return HCF_INVALID_PARAMS; + } + X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self; + + unsigned char *pkBytes = NULL; + int32_t pkLen = i2d_PUBKEY(impl->pubKey, &pkBytes); + if (pkLen <= 0) { + LOGE("Failed to convert internal pubkey to der format!"); + CfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = DeepCopyDataToOut((const char *)pkBytes, (uint32_t)pkLen, returnBlob); + OPENSSL_free(pkBytes); + return ret; } static const char *GetPubKeyFormat(HcfKey *self) diff --git a/plugin/openssl_plugin/common/inc/ecc_openssl_common.h b/plugin/openssl_plugin/common/inc/ecc_openssl_common.h new file mode 100644 index 0000000..e05110b --- /dev/null +++ b/plugin/openssl_plugin/common/inc/ecc_openssl_common.h @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2022 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 HCF_ECC_OPENSSL_COMMON_H +#define HCF_ECC_OPENSSL_COMMON_H + +#include "utils.h" + +static const int32_t NID_secp224r1_len = 28; +static const int32_t NID_X9_62_prime256v1_len = 32; +static const int32_t NID_secp384r1_len = 48; +static const int32_t NID_secp521r1_len = 66; + +static unsigned char g_ecc224CorrectBigP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 +}; + +static unsigned char g_ecc224CorrectBigA[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE +}; + +static unsigned char g_ecc224CorrectBigB[] = { + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4 +}; + +static unsigned char g_ecc224CorrectBigGX[] = { + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21 +}; + +static unsigned char g_ecc224CorrectBigGY[] = { + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34 +}; + +static unsigned char g_ecc224CorrectBigN[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D +}; + +static unsigned char g_ecc224CorrectBigSk[] = { + 0x3F, 0x0C, 0x48, 0x8E, 0x98, 0x7C, 0x80, 0xBE, 0x0F, 0xEE, 0x52, 0x1F, + 0x8D, 0x90, 0xBE, 0x60, 0x34, 0xEC, 0x69, 0xAE, 0x11, 0xCA, 0x72, 0xAA, + 0x77, 0x74, 0x81, 0xE8 +}; + +static unsigned char g_ecc224CorrectBigPkX[] = { + 0xE8, 0x4F, 0xB0, 0xB8, 0xE7, 0x00, 0x0C, 0xB6, 0x57, 0xD7, 0x97, 0x3C, + 0xF6, 0xB4, 0x2E, 0xD7, 0x8B, 0x30, 0x16, 0x74, 0x27, 0x6D, 0xF7, 0x44, + 0xAF, 0x13, 0x0B, 0x3E +}; + +static unsigned char g_ecc224CorrectBigPkY[] = { + 0x43, 0x76, 0x67, 0x5C, 0x6F, 0xC5, 0x61, 0x2C, 0x21, 0xA0, 0xFF, 0x2D, + 0x2A, 0x89, 0xD2, 0x98, 0x7D, 0xF7, 0xA2, 0xBC, 0x52, 0x18, 0x3B, 0x59, + 0x82, 0x29, 0x85, 0x55 +}; + +static unsigned char g_ecc224CorrectLittleP[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char g_ecc224CorrectLittleA[] = { + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char g_ecc224CorrectLittleB[] = { + 0xb4, 0xff, 0x55, 0x23, 0x43, 0x39, 0x0b, 0x27, 0xba, 0xd8, 0xbf, 0xd7, + 0xb7, 0xb0, 0x44, 0x50, 0x56, 0x32, 0x41, 0xf5, 0xab, 0xb3, 0x04, 0x0c, + 0x85, 0x0a, 0x05, 0xb4 +}; + +static unsigned char g_ecc224CorrectLittleGX[] = { + 0x21, 0x1d, 0x5c, 0x11, 0xd6, 0x80, 0x32, 0x34, 0x22, 0x11, 0xc2, 0x56, + 0xd3, 0xc1, 0x03, 0x4a, 0xb9, 0x90, 0x13, 0x32, 0x7f, 0xbf, 0xb4, 0x6b, + 0xbd, 0x0c, 0x0e, 0xb7 +}; + +static unsigned char g_ecc224CorrectLittleGY[] = { + 0x34, 0x7e, 0x00, 0x85, 0x99, 0x81, 0xd5, 0x44, 0x64, 0x47, 0x07, 0x5a, + 0xa0, 0x75, 0x43, 0xcd, 0xe6, 0xdf, 0x22, 0x4c, 0xfb, 0x23, 0xf7, 0xb5, + 0x88, 0x63, 0x37, 0xbd +}; + +static unsigned char g_ecc224CorrectLittleN[] = { + 0x3d, 0x2a, 0x5c, 0x5c, 0x45, 0x29, 0xdd, 0x13, 0x3e, 0xf0, 0xb8, 0xe0, + 0xa2, 0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char g_ecc224CorrectLittleSk[] = { + 0xe8, 0x81, 0x74, 0x77, 0xaa, 0x72, 0xca, 0x11, 0xae, 0x69, 0xec, 0x34, + 0x60, 0xbe, 0x90, 0x8d, 0x1f, 0x52, 0xee, 0x0f, 0xbe, 0x80, 0x7c, 0x98, + 0x8e, 0x48, 0x0c, 0x3f +}; + +static unsigned char g_ecc224CorrectLittlePkX[] = { + 0x3e, 0x0b, 0x13, 0xaf, 0x44, 0xf7, 0x6d, 0x27, 0x74, 0x16, 0x30, 0x8b, + 0xd7, 0x2e, 0xb4, 0xf6, 0x3c, 0x97, 0xd7, 0x57, 0xb6, 0x0c, 0x00, 0xe7, + 0xb8, 0xb0, 0x4f, 0xe8 +}; + +static unsigned char g_ecc224CorrectLittlePkY[] = { + 0x55, 0x85, 0x29, 0x82, 0x59, 0x3b, 0x18, 0x52, 0xbc, 0xa2, 0xf7, 0x7d, + 0x98, 0xd2, 0x89, 0x2a, 0x2d, 0xff, 0xa0, 0x21, 0x2c, 0x61, 0xc5, 0x6f, + 0x5c, 0x67, 0x76, 0x43 +}; + +// ECC256 +static unsigned char g_ecc256CorrectBigP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc256CorrectBigA[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC +}; + +static unsigned char g_ecc256CorrectBigB[] = { + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B +}; + +static unsigned char g_ecc256CorrectBigGX[] = { + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 +}; + +static unsigned char g_ecc256CorrectBigGY[] = { + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +static unsigned char g_ecc256CorrectBigN[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 +}; + +static unsigned char g_ecc256CorrectBigSk[] = { + 0xB2, 0x81, 0x28, 0x15, 0x22, 0x43, 0x2D, 0xAB, 0x54, 0x67, 0xC3, 0x0D, + 0x1F, 0x2C, 0x5F, 0xA4, 0x5D, 0x2C, 0xC8, 0x9F, 0x30, 0x47, 0xDC, 0x6E, + 0x8C, 0xEC, 0xBA, 0x1E, 0xBE, 0xC2, 0x05, 0x67 +}; + +static unsigned char g_ecc256CorrectBigPkX[] = { + 0x9C, 0x7A, 0xB7, 0x70, 0xD0, 0x15, 0x29, 0x18, 0xB7, 0xCA, 0x13, 0x76, + 0x66, 0xC6, 0xAA, 0xB7, 0x68, 0x19, 0x4F, 0x0C, 0x15, 0xC5, 0xF2, 0x38, + 0xC5, 0xA7, 0xF1, 0xC6, 0x0E, 0x0B, 0x39, 0x23 +}; + +static unsigned char g_ecc256CorrectBigPkY[] = { + 0xA6, 0x31, 0xB0, 0x15, 0x06, 0x44, 0x82, 0x40, 0xD5, 0x10, 0xA9, 0xF7, + 0xDF, 0x79, 0xC1, 0xDE, 0xBD, 0xE4, 0x7E, 0xC2, 0x4F, 0x7D, 0xAC, 0xFF, + 0xF7, 0x47, 0x4E, 0x1C, 0x9F, 0xBA, 0x48, 0xAA +}; + +static unsigned char g_ecc256CorrectLittleP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc256CorrectLittleA[] = { + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc256CorrectLittleB[] = { + 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B, 0xF6, 0xB0, 0x53, 0xCC, + 0xB0, 0x06, 0x1D, 0x65, 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3, + 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A +}; + +static unsigned char g_ecc256CorrectLittleGX[] = { + 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4, 0xA0, 0x33, 0xEB, 0x2D, + 0x81, 0x7D, 0x03, 0x77, 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8, + 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B +}; + +static unsigned char g_ecc256CorrectLittleGY[] = { + 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB, 0xCE, 0x5E, 0x31, 0x6B, + 0x57, 0x33, 0xCE, 0x2B, 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E, + 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F +}; + +static unsigned char g_ecc256CorrectLittleN[] = { + 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3, 0x84, 0x9E, 0x17, 0xA7, + 0xAD, 0xFA, 0xE6, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc256CorrectLittleSk[] = { + 0x67, 0x05, 0xC2, 0xBE, 0x1E, 0xBA, 0xEC, 0x8C, 0x6E, 0xDC, 0x47, 0x30, + 0x9F, 0xC8, 0x2C, 0x5D, 0xA4, 0x5F, 0x2C, 0x1F, 0x0D, 0xC3, 0x67, 0x54, + 0xAB, 0x2D, 0x43, 0x22, 0x15, 0x28, 0x81, 0xB2 +}; + +static unsigned char g_ecc256CorrectLittlePkX[] = { + 0x23, 0x39, 0x0B, 0x0E, 0xC6, 0xF1, 0xA7, 0xC5, 0x38, 0xF2, 0xC5, 0x15, + 0x0C, 0x4F, 0x19, 0x68, 0xB7, 0xAA, 0xC6, 0x66, 0x76, 0x13, 0xCA, 0xB7, + 0x18, 0x29, 0x15, 0xD0, 0x70, 0xB7, 0x7A, 0x9C +}; + +static unsigned char g_ecc256CorrectLittlePkY[] = { + 0xAA, 0x48, 0xBA, 0x9F, 0x1C, 0x4E, 0x47, 0xF7, 0xFF, 0xAC, 0x7D, 0x4F, + 0xC2, 0x7E, 0xE4, 0xBD, 0xDE, 0xC1, 0x79, 0xDF, 0xF7, 0xA9, 0x10, 0xD5, + 0x40, 0x82, 0x44, 0x06, 0x15, 0xB0, 0x31, 0xA6, +}; + +// ECC384 +static unsigned char g_ecc384CorrectBigP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc384CorrectBigA[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC +}; + +static unsigned char g_ecc384CorrectBigB[] = { + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF +}; + +static unsigned char g_ecc384CorrectBigGX[] = { + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 +}; + +static unsigned char g_ecc384CorrectBigGY[] = { + 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F, +}; + +static unsigned char g_ecc384CorrectBigN[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 +}; + +static unsigned char g_ecc384CorrectBigSk[] = { + 0x93, 0xFA, 0x94, 0x79, 0x43, 0xB2, 0xA4, 0x0B, 0x60, 0xB8, 0x88, 0x51, + 0x45, 0xE5, 0xD7, 0x74, 0x9A, 0x16, 0x10, 0x61, 0x6B, 0xE8, 0xD7, 0x69, + 0xE5, 0x01, 0xF0, 0x8F, 0xED, 0xE3, 0x5B, 0xF2, 0x0E, 0x0A, 0xCC, 0x70, + 0xF6, 0xD7, 0xDF, 0x9A, 0x89, 0x45, 0xB5, 0xCA, 0x34, 0xB2, 0xAA, 0xD8 +}; + +static unsigned char g_ecc384CorrectBigPkX[] = { + 0x66, 0x44, 0xA4, 0x54, 0xF9, 0xC2, 0x3F, 0x47, 0x03, 0xF1, 0xD8, 0x7A, + 0xE4, 0xE9, 0xC5, 0x94, 0xEB, 0x19, 0x99, 0x76, 0x9E, 0x34, 0xD6, 0x3A, + 0x57, 0x89, 0x3F, 0xF2, 0x6B, 0x6F, 0xE7, 0x6E, 0x22, 0x9E, 0x3A, 0x28, + 0x2D, 0xBE, 0x8B, 0x52, 0xFA, 0xDC, 0xE2, 0xB0, 0x5F, 0x5F, 0x82, 0x1A +}; + +static unsigned char g_ecc384CorrectBigPkY[] = { + 0x78, 0x19, 0x7B, 0x9C, 0xD4, 0x13, 0x7B, 0xFB, 0xD5, 0x5B, 0x95, 0x80, + 0xBB, 0xEE, 0x7E, 0x4F, 0x30, 0x7D, 0xA4, 0x66, 0xD5, 0xB9, 0xC3, 0x95, + 0xB5, 0x62, 0x18, 0x9E, 0x48, 0xCB, 0x1B, 0xC9, 0xE6, 0x2B, 0xB5, 0xA0, + 0xF1, 0xCB, 0x2D, 0xFD, 0x13, 0x15, 0x82, 0x7D, 0xF7, 0x3F, 0x69, 0x1A +}; + +static unsigned char g_ecc384CorrectLittleP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc384CorrectLittleA[] = { + 0xFC, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc384CorrectLittleB[] = { + 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A, 0x9D, 0xD1, 0x2E, 0x8A, + 0x8D, 0x39, 0x56, 0xC6, 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03, + 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18, 0x19, 0x2D, 0xF8, 0xE3, + 0x6B, 0x05, 0x8E, 0x98, 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 +}; + +static unsigned char g_ecc384CorrectLittleGX[] = { + 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A, 0x6C, 0x29, 0x55, 0xBF, + 0x5D, 0xF2, 0x02, 0x55, 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59, + 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E, 0x74, 0xAD, 0x20, 0xF3, + 0x1E, 0xC7, 0xB1, 0x8E, 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA +}; + +static unsigned char g_ecc384CorrectLittleGY[] = { + 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A, 0x9D, 0x81, 0x7E, 0x1D, + 0xCE, 0xB1, 0x60, 0x0A, 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9, + 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8, 0x29, 0xDC, 0x92, 0x92, + 0xBF, 0x98, 0x9E, 0x5D, 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 +}; + +static unsigned char g_ecc384CorrectLittleN[] = { + 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC, 0x7A, 0xA7, 0xB0, 0x48, + 0xB2, 0x0D, 0x1A, 0x58, 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc384CorrectLittleSk[] = { + 0xD8, 0xAA, 0xB2, 0x34, 0xCA, 0xB5, 0x45, 0x89, 0x9A, 0xDF, 0xD7, 0xF6, + 0x70, 0xCC, 0x0A, 0x0E, 0xF2, 0x5B, 0xE3, 0xED, 0x8F, 0xF0, 0x01, 0xE5, + 0x69, 0xD7, 0xE8, 0x6B, 0x61, 0x10, 0x16, 0x9A, 0x74, 0xD7, 0xE5, 0x45, + 0x51, 0x88, 0xB8, 0x60, 0x0B, 0xA4, 0xB2, 0x43, 0x79, 0x94, 0xFA, 0x93 +}; + +static unsigned char g_ecc384CorrectLittlePkX[] = { + 0x1A, 0x82, 0x5F, 0x5F, 0xB0, 0xE2, 0xDC, 0xFA, 0x52, 0x8B, 0xBE, 0x2D, + 0x28, 0x3A, 0x9E, 0x22, 0x6E, 0xE7, 0x6F, 0x6B, 0xF2, 0x3F, 0x89, 0x57, + 0x3A, 0xD6, 0x34, 0x9E, 0x76, 0x99, 0x19, 0xEB, 0x94, 0xC5, 0xE9, 0xE4, + 0x7A, 0xD8, 0xF1, 0x03, 0x47, 0x3F, 0xC2, 0xF9, 0x54, 0xA4, 0x44, 0x66 +}; + +static unsigned char g_ecc384CorrectLittlePkY[] = { + 0x1A, 0x69, 0x3F, 0xF7, 0x7D, 0x82, 0x15, 0x13, 0xFD, 0x2D, 0xCB, 0xF1, + 0xA0, 0xB5, 0x2B, 0xE6, 0xC9, 0x1B, 0xCB, 0x48, 0x9E, 0x18, 0x62, 0xB5, + 0x95, 0xC3, 0xB9, 0xD5, 0x66, 0xA4, 0x7D, 0x30, 0x4F, 0x7E, 0xEE, 0xBB, + 0x80, 0x95, 0x5B, 0xD5, 0xFB, 0x7B, 0x13, 0xD4, 0x9C, 0x7B, 0x19, 0x78 +}; + +// ECC521 +static unsigned char g_ecc521CorrectBigP[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static unsigned char g_ecc521CorrectBigA[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC +}; + +static unsigned char g_ecc521CorrectBigB[] = { + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 +}; + +static unsigned char g_ecc521CorrectBigGX[] = { + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 +}; + +static unsigned char g_ecc521CorrectBigGY[] = { + 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 +}; + +static unsigned char g_ecc521CorrectBigN[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 +}; + +static unsigned char g_ecc521CorrectBigSk[] = { + 0x00, 0x89, 0xCE, 0xDE, 0x8D, 0xB8, 0x59, 0x2C, 0x29, 0xD2, 0x0F, 0x8A, + 0x2F, 0x4C, 0xF6, 0x1D, 0x84, 0xC9, 0x46, 0x3B, 0x13, 0xF1, 0x75, 0x41, + 0x83, 0x39, 0x16, 0x5D, 0xA4, 0xD1, 0x66, 0x70, 0xCA, 0x78, 0x18, 0x9D, + 0x52, 0xF5, 0x11, 0x60, 0x12, 0xB1, 0xE1, 0x9E, 0x77, 0x5B, 0xD2, 0x45, + 0x19, 0x53, 0x75, 0x31, 0x40, 0x82, 0x90, 0x8C, 0x71, 0x60, 0xBC, 0x92, + 0x68, 0x98, 0xBD, 0x70, 0xC2, 0x5B +}; + +static unsigned char g_ecc521CorrectBigPkX[] = { + 0x00, 0x8A, 0x43, 0xDD, 0x43, 0x18, 0xE0, 0x03, 0x86, 0x2C, 0xF8, 0x9E, + 0x88, 0xB0, 0x46, 0x44, 0x9E, 0x89, 0x10, 0x61, 0x1F, 0xE8, 0x3C, 0x0A, + 0xBF, 0xB2, 0x80, 0xB5, 0x3F, 0xDC, 0xD1, 0x1A, 0x12, 0xB2, 0x31, 0x2A, + 0xB0, 0x4B, 0xF1, 0x60, 0x98, 0x94, 0x2E, 0xB0, 0xF3, 0x46, 0x5E, 0xB3, + 0x55, 0x10, 0xC4, 0xEC, 0x74, 0x8A, 0xC3, 0xF0, 0x53, 0x25, 0x37, 0x8C, + 0xB2, 0x11, 0x08, 0x66, 0xE3, 0x14 +}; + +static unsigned char g_ecc521CorrectBigPkY[] = { + 0x00, 0x64, 0x25, 0xD3, 0x03, 0x97, 0xF5, 0xC1, 0x59, 0xFE, 0xEC, 0xDF, + 0x24, 0x92, 0x68, 0x2A, 0xBA, 0xE8, 0x8B, 0x8F, 0xD6, 0x28, 0xA8, 0x93, + 0x22, 0x5C, 0x46, 0xF4, 0xE4, 0xA0, 0x48, 0xBD, 0x0D, 0x3F, 0xB2, 0xEA, + 0xAD, 0xB1, 0xD7, 0x08, 0xC7, 0xE2, 0xF3, 0x78, 0x96, 0x33, 0x1D, 0x9F, + 0x84, 0xC8, 0xCE, 0xFB, 0x67, 0xF0, 0x58, 0x2A, 0x1F, 0x7F, 0xBD, 0x82, + 0xA2, 0x59, 0x8F, 0xDC, 0x3E, 0xD5 +}; + +static unsigned char g_ecc521CorrectLittleP[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 +}; + +static unsigned char g_ecc521CorrectLittleA[] = { + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 +}; + +static unsigned char g_ecc521CorrectLittleB[] = { + 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF, 0xF1, 0x34, 0x2C, 0x3D, + 0x88, 0xDF, 0x73, 0x35, 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16, + 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56, 0xE1, 0x09, 0xF1, 0x8E, + 0x91, 0x89, 0xB4, 0xB8, 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2, + 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92, 0x1F, 0x9A, 0x1C, 0x8E, + 0x61, 0xB9, 0x3E, 0x95, 0x51, 0x00 +}; + +static unsigned char g_ecc521CorrectLittleGX[] = { + 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9, 0x9B, 0x42, 0x6A, 0x85, + 0xC1, 0xB3, 0x48, 0x33, 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE, + 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1, 0xBA, 0x3D, 0x4D, 0x6B, + 0x60, 0xAF, 0x28, 0xF8, 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C, + 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E, 0xCD, 0xE9, 0x04, 0x04, + 0xB7, 0x06, 0x8E, 0x85, 0xC6, 0x00 +}; + +static unsigned char g_ecc521CorrectLittleGY[] = { + 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88, 0x40, 0xC2, 0x72, 0xA2, + 0x86, 0x70, 0x3C, 0x35, 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5, + 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97, 0x2C, 0x66, 0x3E, 0x27, + 0x17, 0xBD, 0xAF, 0x17, 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98, + 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C, 0x04, 0xC0, 0x3B, 0x9A, + 0x78, 0x6A, 0x29, 0x39, 0x18, 0x01 +}; + +static unsigned char g_ecc521CorrectLittleN[] = { + 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB, 0xAE, 0x47, 0x9C, 0x89, + 0xB8, 0xC9, 0xB5, 0x3B, 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F, + 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51, 0xFA, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 +}; + +static unsigned char g_ecc521CorrectLittleSk[] = { + 0x5B, 0xC2, 0x70, 0xBD, 0x98, 0x68, 0x92, 0xBC, 0x60, 0x71, 0x8C, 0x90, + 0x82, 0x40, 0x31, 0x75, 0x53, 0x19, 0x45, 0xD2, 0x5B, 0x77, 0x9E, 0xE1, + 0xB1, 0x12, 0x60, 0x11, 0xF5, 0x52, 0x9D, 0x18, 0x78, 0xCA, 0x70, 0x66, + 0xD1, 0xA4, 0x5D, 0x16, 0x39, 0x83, 0x41, 0x75, 0xF1, 0x13, 0x3B, 0x46, + 0xC9, 0x84, 0x1D, 0xF6, 0x4C, 0x2F, 0x8A, 0x0F, 0xD2, 0x29, 0x2C, 0x59, + 0xB8, 0x8D, 0xDE, 0xCE, 0x89, 0x00 +}; + +static unsigned char g_ecc521CorrectLittlePkX[] = { + 0x14, 0xE3, 0x66, 0x08, 0x11, 0xB2, 0x8C, 0x37, 0x25, 0x53, 0xF0, 0xC3, + 0x8A, 0x74, 0xEC, 0xC4, 0x10, 0x55, 0xB3, 0x5E, 0x46, 0xF3, 0xB0, 0x2E, + 0x94, 0x98, 0x60, 0xF1, 0x4B, 0xB0, 0x2A, 0x31, 0xB2, 0x12, 0x1A, 0xD1, + 0xDC, 0x3F, 0xB5, 0x80, 0xB2, 0xBF, 0x0A, 0x3C, 0xE8, 0x1F, 0x61, 0x10, + 0x89, 0x9E, 0x44, 0x46, 0xB0, 0x88, 0x9E, 0xF8, 0x2C, 0x86, 0x03, 0xE0, + 0x18, 0x43, 0xDD, 0x43, 0x8A, 0x00 +}; + +static unsigned char g_ecc521CorrectLittlePkY[] = { + 0xD5, 0x3E, 0xDC, 0x8F, 0x59, 0xA2, 0x82, 0xBD, 0x7F, 0x1F, 0x2A, 0x58, + 0xF0, 0x67, 0xFB, 0xCE, 0xC8, 0x84, 0x9F, 0x1D, 0x33, 0x96, 0x78, 0xF3, + 0xE2, 0xC7, 0x08, 0xD7, 0xB1, 0xAD, 0xEA, 0xB2, 0x3F, 0x0D, 0xBD, 0x48, + 0xA0, 0xE4, 0xF4, 0x46, 0x5C, 0x22, 0x93, 0xA8, 0x28, 0xD6, 0x8F, 0x8B, + 0xE8, 0xBA, 0x2A, 0x68, 0x92, 0x24, 0xDF, 0xEC, 0xFE, 0x59, 0xC1, 0xF5, + 0x97, 0x03, 0xD3, 0x25, 0x64, 0x00 +}; + +#endif diff --git a/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index cd066e8..631a515 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -20,6 +20,10 @@ #include #include #include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -28,10 +32,24 @@ extern "C" { BIGNUM *Openssl_BN_dup(const BIGNUM *a); void Openssl_BN_clear(BIGNUM *a); void Openssl_BN_clear_free(BIGNUM *a); +BIGNUM *Openssl_BN_new(void); +void Openssl_BN_free(BIGNUM *a); +BIGNUM *Openssl_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +BIGNUM *Openssl_BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int Openssl_BN_bn2binpad(const BIGNUM *a, unsigned char *to, int toLen); +int Openssl_BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int toLen); +BN_CTX *Openssl_BN_CTX_new(void); +void Openssl_BN_CTX_free(BN_CTX *ctx); +int Openssl_BN_num_bytes(const BIGNUM *a); +int Openssl_BN_set_word(BIGNUM *a, unsigned int w); +unsigned int Openssl_BN_get_word(const BIGNUM *a); +int Openssl_BN_num_bits(const BIGNUM *a); +int Openssl_BN_hex2bn(BIGNUM **a, const char *str); +int Openssl_BN_cmp(const BIGNUM *a, const BIGNUM *b); EC_KEY *Openssl_EC_KEY_new_by_curve_name(int nid); EC_POINT *Openssl_EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); -int Openssl_EC_KEY_generate_key(EC_KEY *eckey); +int Openssl_EC_KEY_generate_key(EC_KEY *ecKey); int Openssl_EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); int Openssl_EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key); int Openssl_EC_KEY_check_key(const EC_KEY *key); @@ -43,9 +61,31 @@ int Openssl_i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); EC_KEY *Openssl_d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); EC_KEY *Openssl_d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); void Openssl_EC_KEY_set_asn1_flag(EC_KEY *key, int flag); -void Openssl_EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +void Openssl_EC_KEY_set_enc_flags(EC_KEY *ecKey, unsigned int flags); void Openssl_EC_KEY_free(EC_KEY *key); void Openssl_EC_POINT_free(EC_POINT *point); +EC_GROUP *Openssl_EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +void Openssl_EC_GROUP_free(EC_GROUP *group); +EC_POINT *Openssl_EC_POINT_new(const EC_GROUP *group); +int Openssl_EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx); +int Openssl_EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); +EC_KEY *Openssl_EC_KEY_new(void); +EC_KEY *Openssl_EC_KEY_dup(const EC_KEY *ecKey); +int Openssl_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); +int Openssl_EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); +const EC_POINT *Openssl_EC_GROUP_get0_generator(const EC_GROUP *group); +int Openssl_EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); +int Openssl_EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); +int Openssl_EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); +int Openssl_EC_GROUP_get_degree(const EC_GROUP *group); +EC_GROUP *Openssl_EC_GROUP_dup(const EC_GROUP *a); +void Openssl_EC_GROUP_set_curve_name(EC_GROUP *group, int nid); +int Openssl_EC_GROUP_get_curve_name(const EC_GROUP *group); +int Openssl_EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, + const BIGNUM *p_scalar, BN_CTX *ctx); EVP_MD_CTX *Openssl_EVP_MD_CTX_new(void); void Openssl_EVP_MD_CTX_free(EVP_MD_CTX *ctx); @@ -55,6 +95,12 @@ int Openssl_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t * int Openssl_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int Openssl_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t count); int Openssl_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); +int Openssl_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, + size_t tbslen); +int Openssl_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, + size_t tbslen); EVP_PKEY *Openssl_EVP_PKEY_new(void); int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); @@ -66,8 +112,139 @@ int Openssl_EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); int Openssl_EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); void Openssl_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); +// new added +int Openssl_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int Openssl_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int Openssl_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + +EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e); +int Openssl_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); +int Openssl_EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int Openssl_EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int Openssl_EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); +DSA *Openssl_EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +DSA *Openssl_DSA_new(void); +void Openssl_DSA_free(DSA *dsa); +int Openssl_DSA_up_ref(DSA *dsa); +int Openssl_DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); +int Openssl_DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *pri_key); +const BIGNUM *Openssl_DSA_get0_p(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_q(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_g(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_pub_key(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_priv_key(const DSA *dsa); +int Openssl_DSA_generate_key(DSA *a); +DSA *Openssl_d2i_DSA_PUBKEY(DSA **dsa, const unsigned char **ppin, long length); +DSA *Openssl_d2i_DSAPrivateKey(DSA **dsa, const unsigned char **ppin, long length); +int Openssl_i2d_DSA_PUBKEY(DSA *dsa, unsigned char **ppout); +int Openssl_i2d_DSAPrivateKey(DSA *dsa, unsigned char **ppout); + +RSA *Openssl_RSA_new(void); +void Openssl_RSA_free(RSA *rsa); +int Openssl_RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb); +int Openssl_RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int Openssl_RSA_bits(const RSA *rsa); +int Openssl_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +void Openssl_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +const BIGNUM *Openssl_RSA_get0_n(const RSA *d); +const BIGNUM *Openssl_RSA_get0_e(const RSA *d); +const BIGNUM *Openssl_RSA_get0_d(const RSA *d); +void Openssl_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +RSA *Openssl_RSAPublicKey_dup(RSA *rsa); +RSA *Openssl_RSAPrivateKey_dup(RSA *rsa); +RSA *Openssl_d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +int Openssl_i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +int Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); +int Openssl_EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); +int Openssl_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); +int Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int len); +int Openssl_EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label); +EVP_PKEY *Openssl_d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length); +struct rsa_st *Openssl_EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +int Openssl_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +int Openssl_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, struct rsa_st *key); +int Openssl_i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); +// BIO +BIO *Openssl_BIO_new(const BIO_METHOD *type); +const BIO_METHOD *Openssl_BIO_s_mem(void); +int Openssl_BIO_read(BIO *b, void *data, int dlen); +void Openssl_BIO_free_all(BIO *a); + +int Openssl_RAND_priv_bytes(unsigned char *buf, int num); +void Openssl_RAND_seed(const void *buf, int num); + +const EVP_MD *Openssl_EVP_sha1(void); +const EVP_MD *Openssl_EVP_sha224(void); +const EVP_MD *Openssl_EVP_sha256(void); +const EVP_MD *Openssl_EVP_sha384(void); +const EVP_MD *Openssl_EVP_sha512(void); +const EVP_MD *Openssl_EVP_md5(void); +int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); +int Openssl_EVP_MD_CTX_size(const EVP_MD_CTX *ctx); +int Openssl_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); + +int Openssl_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); +int Openssl_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +size_t Openssl_HMAC_size(const HMAC_CTX *ctx); +void Openssl_HMAC_CTX_free(HMAC_CTX *ctx); +HMAC_CTX *Openssl_HMAC_CTX_new(void); + +void Openssl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); +const EVP_CIPHER *Openssl_EVP_aes_128_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_128_gcm(void); +const EVP_CIPHER *Openssl_EVP_aes_192_gcm(void); +const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_ecb(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cbc(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_ofb(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb64(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb1(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb8(void); +EVP_CIPHER_CTX *Openssl_EVP_CIPHER_CTX_new(void); +int Openssl_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc); +int Openssl_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); +int Openssl_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int Openssl_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int Openssl_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); + #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/common/inc/openssl_class.h b/plugin/openssl_plugin/common/inc/openssl_class.h index 2469b91..0847695 100644 --- a/plugin/openssl_plugin/common/inc/openssl_class.h +++ b/plugin/openssl_plugin/common/inc/openssl_class.h @@ -21,6 +21,7 @@ #include "key_pair.h" #include +#include #include #include #include @@ -30,7 +31,9 @@ typedef struct { int32_t curveId; - EC_POINT *pk; + EC_KEY *ecKey; + + char *fieldType; } HcfOpensslEccPubKey; #define HCF_OPENSSL_ECC_PUB_KEY_CLASS "OPENSSL.ECC.PUB_KEY" @@ -39,7 +42,9 @@ typedef struct { int32_t curveId; - BIGNUM *sk; + EC_KEY *ecKey; + + char *fieldType; } HcfOpensslEccPriKey; #define HCF_OPENSSL_ECC_PRI_KEY_CLASS "OPENSSL.ECC.PRI_KEY" @@ -71,6 +76,25 @@ typedef struct { } HcfOpensslRsaKeyPair; #define OPENSSL_RSA_KEYPAIR_CLASS "OPENSSL.RSA.KEY_PAIR" +typedef struct { + HcfPubKey base; + + DSA *pk; +} HcfOpensslDsaPubKey; +#define OPENSSL_DSA_PUBKEY_CLASS "OPENSSL.DSA.PUB_KEY" + +typedef struct { + HcfPriKey base; + + DSA *sk; +} HcfOpensslDsaPriKey; +#define OPENSSL_DSA_PRIKEY_CLASS "OPENSSL.DSA.PRI_KEY" + +typedef struct { + HcfKeyPair base; +} HcfOpensslDsaKeyPair; +#define OPENSSL_DSA_KEYPAIR_CLASS "OPENSSL.DSA.KEY_PAIR" + #define OPENSSL_RSA_CIPHER_CLASS "OPENSSL.RSA.CIPHER" #define OPENSSL_3DES_CIPHER_CLASS "OPENSSL.3DES.CIPHER" #define OPENSSL_AES_CIPHER_CLASS "OPENSSL.AES.CIPHER" diff --git a/plugin/openssl_plugin/common/inc/openssl_common.h b/plugin/openssl_plugin/common/inc/openssl_common.h index e88f37d..75f27db 100644 --- a/plugin/openssl_plugin/common/inc/openssl_common.h +++ b/plugin/openssl_plugin/common/inc/openssl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -17,26 +17,47 @@ #define HCF_OPENSSL_COMMON_H #include +#include #include #include #include #include +#include "big_integer.h" +#include "params_parser.h" +#include "result.h" + #define HCF_OPENSSL_SUCCESS 1 /* openssl return 1: success */ #define HCF_BITS_PER_BYTE 8 +typedef enum { + UNINITIALIZED = 0, + INITIALIZED = 1, + READY = 2, +} CryptoStatus; + #ifdef __cplusplus extern "C" { #endif -int32_t GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId); -const EVP_MD *GetOpensslDigestAlg(uint32_t alg); +HcfResult GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId); +HcfResult GetOpensslDigestAlg(uint32_t alg, EVP_MD **digestAlg); void HcfPrintOpensslError(void); -int32_t GetOpensslPadding(int32_t padding, int32_t *opensslPadding); +HcfResult GetOpensslPadding(int32_t padding, int32_t *opensslPadding); int32_t GetRealPrimes(int32_t primesFlag); +bool IsBigEndian(void); + +HcfResult BigIntegerToBigNum(const HcfBigInteger *src, BIGNUM **dest); + +HcfResult BigNumToBigInteger(const BIGNUM *src, HcfBigInteger *dest); + +HcfResult GetRsaSpecStringMd(const HcfAlgParaValue md, char **returnString); + +HcfResult GetRsaSpecStringMGF(char **returnString); + #ifdef __cplusplus } #endif diff --git a/plugin/openssl_plugin/common/inc/rsa_openssl_common.h b/plugin/openssl_plugin/common/inc/rsa_openssl_common.h index 925c3df..3a18eae 100644 --- a/plugin/openssl_plugin/common/inc/rsa_openssl_common.h +++ b/plugin/openssl_plugin/common/inc/rsa_openssl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -21,15 +21,12 @@ #include "result.h" #include "stdbool.h" -typedef enum { - INITIALIZED, - UNINITIALIZED -} InitFlag; - #ifdef __cplusplus extern "C" { #endif +#define RSA_ALG_NAME "RSA" + HcfResult DuplicateRsa(RSA *rsa, bool needPrivate, RSA **dupRsa); EVP_PKEY *NewEvpPkeyByRsa(RSA *rsa, bool withDuplicate); diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index 4d0b40c..97794ba 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -33,6 +33,76 @@ void Openssl_BN_clear_free(BIGNUM *a) BN_clear_free(a); } +BIGNUM *Openssl_BN_new(void) +{ + return BN_new(); +} + +void Openssl_BN_free(BIGNUM *a) +{ + BN_free(a); +} + +BIGNUM *Openssl_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + return BN_bin2bn(s, len, ret); +} + +BIGNUM *Openssl_BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + return BN_lebin2bn(s, len, ret); +} + +int Openssl_BN_bn2binpad(const BIGNUM *a, unsigned char *to, int toLen) +{ + return BN_bn2binpad(a, to, toLen); +} + +int Openssl_BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int toLen) +{ + return BN_bn2lebinpad(a, to, toLen); +} + +BN_CTX *Openssl_BN_CTX_new(void) +{ + return BN_CTX_new(); +} + +void Openssl_BN_CTX_free(BN_CTX *ctx) +{ + BN_CTX_free(ctx); +} + +int Openssl_BN_num_bytes(const BIGNUM *a) +{ + return BN_num_bytes(a); +} + +int Openssl_BN_set_word(BIGNUM *a, unsigned int w) +{ + return BN_set_word(a, w); +} + +unsigned int Openssl_BN_get_word(const BIGNUM *a) +{ + return BN_get_word(a); +} + +int Openssl_BN_num_bits(const BIGNUM *a) +{ + return BN_num_bits(a); +} + +int Openssl_BN_hex2bn(BIGNUM **a, const char *str) +{ + return BN_hex2bn(a, str); +} + +int Openssl_BN_cmp(const BIGNUM *a, const BIGNUM *b) +{ + return BN_cmp(a, b); +} + EC_KEY *Openssl_EC_KEY_new_by_curve_name(int nid) { return EC_KEY_new_by_curve_name(nid); @@ -43,9 +113,9 @@ EC_POINT *Openssl_EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group) return EC_POINT_dup(src, group); } -int Openssl_EC_KEY_generate_key(EC_KEY *eckey) +int Openssl_EC_KEY_generate_key(EC_KEY *ecKey) { - return EC_KEY_generate_key(eckey); + return EC_KEY_generate_key(ecKey); } int Openssl_EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub) @@ -103,9 +173,9 @@ void Openssl_EC_KEY_set_asn1_flag(EC_KEY *key, int flag) EC_KEY_set_asn1_flag(key, flag); } -void Openssl_EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags) +void Openssl_EC_KEY_set_enc_flags(EC_KEY *ecKey, unsigned int flags) { - EC_KEY_set_enc_flags(eckey, flags); + EC_KEY_set_enc_flags(ecKey, flags); } void Openssl_EC_KEY_free(EC_KEY *key) @@ -118,6 +188,100 @@ void Openssl_EC_POINT_free(EC_POINT *point) EC_POINT_free(point); } +EC_GROUP *Openssl_EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return EC_GROUP_new_curve_GFp(p, a, b, ctx); +} + +void Openssl_EC_GROUP_free(EC_GROUP *group) +{ + EC_GROUP_free(group); +} + +EC_POINT *Openssl_EC_POINT_new(const EC_GROUP *group) +{ + return EC_POINT_new(group); +} + +int Openssl_EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx); +} + +int Openssl_EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, + const BIGNUM *cofactor) +{ + return EC_GROUP_set_generator(group, generator, order, cofactor); +} + +EC_KEY *Openssl_EC_KEY_new(void) +{ + return EC_KEY_new(); +} + +EC_KEY *Openssl_EC_KEY_dup(const EC_KEY *ecKey) +{ + return EC_KEY_dup(ecKey); +} + +int Openssl_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) +{ + return EC_KEY_set_group(key, group); +} + +int Openssl_EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +{ + return EC_GROUP_get_curve_GFp(group, p, a, b, ctx); +} + +const EC_POINT *Openssl_EC_GROUP_get0_generator(const EC_GROUP *group) +{ + return EC_GROUP_get0_generator(group); +} + +int Openssl_EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx); +} + +int Openssl_EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) +{ + return EC_GROUP_get_order(group, order, ctx); +} + +int Openssl_EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) +{ + return EC_GROUP_get_cofactor(group, cofactor, ctx); +} + +int Openssl_EC_GROUP_get_degree(const EC_GROUP *group) +{ + return EC_GROUP_get_degree(group); +} + +EC_GROUP *Openssl_EC_GROUP_dup(const EC_GROUP *a) +{ + return EC_GROUP_dup(a); +} + +void Openssl_EC_GROUP_set_curve_name(EC_GROUP *group, int nid) +{ + EC_GROUP_set_curve_name(group, nid); +} + +int Openssl_EC_GROUP_get_curve_name(const EC_GROUP *group) +{ + return EC_GROUP_get_curve_name(group); +} + +int Openssl_EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, + const BIGNUM *p_scalar, BN_CTX *ctx) +{ + return EC_POINT_mul(group, r, g_scalar, point, p_scalar, ctx); +} + EVP_MD_CTX *Openssl_EVP_MD_CTX_new(void) { return EVP_MD_CTX_new(); @@ -158,6 +322,28 @@ int Openssl_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, siz return EVP_DigestVerifyFinal(ctx, sig, siglen); } +int Openssl_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_sign_init(ctx); +} + +int Openssl_EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + return EVP_PKEY_sign(ctx, sig, siglen, tbs, tbslen); +} + +int Openssl_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_verify_init(ctx); +} + +int Openssl_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, + size_t tbslen) +{ + return EVP_PKEY_verify(ctx, sig, siglen, tbs, tbslen); +} + EVP_PKEY *Openssl_EVP_PKEY_new(void) { return EVP_PKEY_new(); @@ -196,4 +382,594 @@ int Openssl_EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keyle void Openssl_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { EVP_PKEY_CTX_free(ctx); +} + +int Openssl_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + return EVP_PKEY_encrypt(ctx, out, outlen, in, inlen); +} + +int Openssl_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + return EVP_PKEY_decrypt(ctx, out, outlen, in, inlen); +} + +int Openssl_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_encrypt_init(ctx); +} + +int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_decrypt_init(ctx); +} + +EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e) +{ + return EVP_PKEY_CTX_new_id(id, e); +} + +int Openssl_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_paramgen_init(ctx); +} + +int Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) +{ + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); +} + +int Openssl_EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + return EVP_PKEY_paramgen(ctx, ppkey); +} + +int Openssl_EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_keygen_init(ctx); +} + +int Openssl_EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + return EVP_PKEY_keygen(ctx, ppkey); +} + +int Openssl_EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) +{ + return EVP_PKEY_set1_DSA(pkey, key); +} + +DSA *Openssl_EVP_PKEY_get1_DSA(EVP_PKEY *pkey) +{ + return EVP_PKEY_get1_DSA(pkey); +} + +DSA *Openssl_DSA_new(void) +{ + return DSA_new(); +} + +void Openssl_DSA_free(DSA *dsa) +{ + DSA_free(dsa); +} + +int Openssl_DSA_up_ref(DSA *dsa) +{ + return DSA_up_ref(dsa); +} + +int Openssl_DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + return DSA_set0_pqg(dsa, p, q, g); +} + +int Openssl_DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *pri_key) +{ + return DSA_set0_key(dsa, pub_key, pri_key); +} + +const BIGNUM *Openssl_DSA_get0_p(const DSA *dsa) +{ + return DSA_get0_p(dsa); +} + +const BIGNUM *Openssl_DSA_get0_q(const DSA *dsa) +{ + return DSA_get0_q(dsa); +} + +const BIGNUM *Openssl_DSA_get0_g(const DSA *dsa) +{ + return DSA_get0_g(dsa); +} + +const BIGNUM *Openssl_DSA_get0_pub_key(const DSA *dsa) +{ + return DSA_get0_pub_key(dsa); +} + +const BIGNUM *Openssl_DSA_get0_priv_key(const DSA *dsa) +{ + return DSA_get0_priv_key(dsa); +} + +int Openssl_DSA_generate_key(DSA *a) +{ + return DSA_generate_key(a); +} + +DSA *Openssl_d2i_DSA_PUBKEY(DSA **dsa, const unsigned char **ppin, long length) +{ + return d2i_DSA_PUBKEY(dsa, ppin, length); +} + +DSA *Openssl_d2i_DSAPrivateKey(DSA **dsa, const unsigned char **ppin, long length) +{ + return d2i_DSAPrivateKey(dsa, ppin, length); +} + +int Openssl_i2d_DSA_PUBKEY(DSA *dsa, unsigned char **ppout) +{ + return i2d_DSA_PUBKEY(dsa, ppout); +} + +int Openssl_i2d_DSAPrivateKey(DSA *dsa, unsigned char **ppout) +{ + return i2d_DSAPrivateKey(dsa, ppout); +} + +RSA *Openssl_RSA_new(void) +{ + return RSA_new(); +} + +void Openssl_RSA_free(RSA *rsa) +{ + RSA_free(rsa); +} + +int Openssl_RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb) +{ + return RSA_generate_multi_prime_key(rsa, bits, primes, e, cb); +} + +int Openssl_RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) +{ + return RSA_generate_key_ex(rsa, bits, e, cb); +} + +int Openssl_RSA_bits(const RSA *rsa) +{ + return RSA_bits(rsa); +} + +int Openssl_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + return RSA_set0_key(r, n, e, d); +} + +void Openssl_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + RSA_get0_key(r, n, e, d); +} + +const BIGNUM *Openssl_RSA_get0_n(const RSA *d) +{ + return RSA_get0_n(d); +} + +const BIGNUM *Openssl_RSA_get0_e(const RSA *d) +{ + return RSA_get0_e(d); +} + +const BIGNUM *Openssl_RSA_get0_d(const RSA *d) +{ + return RSA_get0_d(d); +} + +void Openssl_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + RSA_get0_factors(r, p, q); +} + +RSA *Openssl_RSAPublicKey_dup(RSA *rsa) +{ + return RSAPublicKey_dup(rsa); +} + +RSA *Openssl_RSAPrivateKey_dup(RSA *rsa) +{ + return RSAPrivateKey_dup(rsa); +} + +RSA *Openssl_d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) +{ + return d2i_RSA_PUBKEY(a, pp, length); +} + +int Openssl_i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) +{ + return i2d_RSA_PUBKEY(a, pp); +} + +int Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen) +{ + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); +} + +int Openssl_EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen) +{ + return EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, saltlen); +} + +int Openssl_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad) +{ + return EVP_PKEY_CTX_set_rsa_padding(ctx, pad); +} + +int Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); +} + +int Openssl_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); +} + +int Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int len) +{ + return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label, len); +} + +int Openssl_EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) +{ + return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, label); +} + +EVP_PKEY *Openssl_d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length) +{ + return d2i_AutoPrivateKey(a, pp, length); +} + +struct rsa_st *Openssl_EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +{ + return EVP_PKEY_get1_RSA(pkey); +} + +int Openssl_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key) +{ + return EVP_PKEY_set1_RSA(pkey, key); +} + +int Openssl_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, struct rsa_st *key) +{ + return EVP_PKEY_assign_RSA(pkey, key); +} + +int Openssl_i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return i2d_PKCS8PrivateKey_bio(bp, x, enc, kstr, klen, cb, u); +} + +BIO *Openssl_BIO_new(const BIO_METHOD *type) +{ + return BIO_new(type); +} + +const BIO_METHOD *Openssl_BIO_s_mem(void) +{ + return BIO_s_mem(); +} + +int Openssl_BIO_read(BIO *b, void *data, int dlen) +{ + return BIO_read(b, data, dlen); +} + +void Openssl_BIO_free_all(BIO *a) +{ + return BIO_free_all(a); +} + +int Openssl_RAND_priv_bytes(unsigned char *buf, int num) +{ + return RAND_priv_bytes(buf, num); +} + +void Openssl_RAND_seed(const void *buf, int num) +{ + RAND_seed(buf, num); +} + +const EVP_MD *Openssl_EVP_sha1(void) +{ + return EVP_sha1(); +} + +const EVP_MD *Openssl_EVP_sha224(void) +{ + return EVP_sha224(); +} + +const EVP_MD *Openssl_EVP_sha256(void) +{ + return EVP_sha256(); +} + +const EVP_MD *Openssl_EVP_sha384(void) +{ + return EVP_sha384(); +} + +const EVP_MD *Openssl_EVP_sha512(void) +{ + return EVP_sha512(); +} + +const EVP_MD *Openssl_EVP_md5(void) +{ + return EVP_md5(); +} + +int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + return EVP_DigestFinal_ex(ctx, md, size); +} + +int Openssl_EVP_MD_CTX_size(const EVP_MD_CTX *ctx) +{ + return EVP_MD_CTX_size(ctx); +} + +int Openssl_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +{ + return EVP_DigestInit_ex(ctx, type, impl); +} + +int Openssl_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) +{ + return HMAC_Init_ex(ctx, key, len, md, impl); +} + +int Openssl_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) +{ + return HMAC_Final(ctx, md, len); +} + +size_t Openssl_HMAC_size(const HMAC_CTX *ctx) +{ + return HMAC_size(ctx); +} + +void Openssl_HMAC_CTX_free(HMAC_CTX *ctx) +{ + HMAC_CTX_free(ctx); +} + +HMAC_CTX *Openssl_HMAC_CTX_new(void) +{ + return HMAC_CTX_new(); +} + +void Openssl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_free(ctx); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_ecb(void) +{ + return EVP_aes_128_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_ecb(void) +{ + return EVP_aes_192_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_ecb(void) +{ + return EVP_aes_256_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_cbc(void) +{ + return EVP_aes_128_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_cbc(void) +{ + return EVP_aes_192_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_cbc(void) +{ + return EVP_aes_256_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_ctr(void) +{ + return EVP_aes_128_ctr(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_ctr(void) +{ + return EVP_aes_192_ctr(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_ctr(void) +{ + return EVP_aes_256_ctr(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_ofb(void) +{ + return EVP_aes_128_ofb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_ofb(void) +{ + return EVP_aes_192_ofb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_ofb(void) +{ + return EVP_aes_256_ofb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_cfb(void) +{ + return EVP_aes_128_cfb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_cfb(void) +{ + return EVP_aes_192_cfb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_cfb(void) +{ + return EVP_aes_256_cfb(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_cfb1(void) +{ + return EVP_aes_128_cfb1(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_cfb1(void) +{ + return EVP_aes_192_cfb1(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_cfb1(void) +{ + return EVP_aes_256_cfb1(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_cfb128(void) +{ + return EVP_aes_128_cfb128(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_cfb128(void) +{ + return EVP_aes_192_cfb128(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_cfb128(void) +{ + return EVP_aes_256_cfb128(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_cfb8(void) +{ + return EVP_aes_128_cfb8(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_cfb8(void) +{ + return EVP_aes_192_cfb8(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_cfb8(void) +{ + return EVP_aes_256_cfb8(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_ccm(void) +{ + return EVP_aes_128_ccm(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_ccm(void) +{ + return EVP_aes_192_ccm(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_ccm(void) +{ + return EVP_aes_256_ccm(); +} + +const EVP_CIPHER *Openssl_EVP_aes_128_gcm(void) +{ + return EVP_aes_128_gcm(); +} + +const EVP_CIPHER *Openssl_EVP_aes_192_gcm(void) +{ + return EVP_aes_192_gcm(); +} + +const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void) +{ + return EVP_aes_256_gcm(); +} + +EVP_CIPHER_CTX *Openssl_EVP_CIPHER_CTX_new(void) +{ + return EVP_CIPHER_CTX_new(); +} + +int Openssl_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + return EVP_CipherInit(ctx, cipher, key, iv, enc); +} + +int Openssl_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) +{ + return EVP_CIPHER_CTX_set_padding(ctx, pad); +} + +int Openssl_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + return EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr); +} + +int Openssl_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + return EVP_CipherFinal_ex(ctx, out, outl); +} + +int Openssl_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) +{ + return EVP_CipherUpdate(ctx, out, outl, in, inl); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_ecb(void) +{ + return EVP_des_ede3_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_cbc(void) +{ + return EVP_des_ede3_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_ofb(void) +{ + return EVP_des_ede3_ofb(); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb64(void) +{ + return EVP_des_ede3_cfb64(); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb1(void) +{ + return EVP_des_ede3_cfb1(); +} + +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb8(void) +{ + return EVP_des_ede3_cfb8(); } \ No newline at end of file diff --git a/plugin/openssl_plugin/common/src/openssl_common.c b/plugin/openssl_plugin/common/src/openssl_common.c index 167ce50..764d238 100644 --- a/plugin/openssl_plugin/common/src/openssl_common.c +++ b/plugin/openssl_plugin/common/src/openssl_common.c @@ -15,10 +15,14 @@ #include "openssl_common.h" +#include "securec.h" + #include #include #include "config.h" #include "log.h" +#include "memory.h" +#include "openssl_adapter.h" #include "result.h" #include "params_parser.h" @@ -27,7 +31,18 @@ #define PRIMES_4 4 #define PRIMES_5 5 -int32_t GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId) +#define HCF_OPENSSL_DIGEST_NONE_STR "NONE" +#define HCF_OPENSSL_DIGEST_MD5_STR "MD5" +#define HCF_OPENSSL_DIGEST_SHA1_STR "SHA1" +#define HCF_OPENSSL_DIGEST_SHA224_STR "SHA224" +#define HCF_OPENSSL_DIGEST_SHA256_STR "SHA256" +#define HCF_OPENSSL_DIGEST_SHA384_STR "SHA384" +#define HCF_OPENSSL_DIGEST_SHA512_STR "SHA512" +#define HCF_OPENSSL_MGF1 "MGF1" + +static const uint32_t ASCII_CODE_ZERO = 48; + +HcfResult GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId) { switch (keyLen) { case HCF_ALG_ECC_224: @@ -50,33 +65,97 @@ int32_t GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId) return HCF_SUCCESS; } -const EVP_MD *GetOpensslDigestAlg(uint32_t alg) +HcfResult GetOpensslDigestAlg(uint32_t alg, EVP_MD **digestAlg) { + if (digestAlg == NULL) { + LOGE("Invalid MD pointer"); + return HCF_INVALID_PARAMS; + } switch (alg) { case HCF_OPENSSL_DIGEST_NONE: - return NULL; + *digestAlg = NULL; + break; case HCF_OPENSSL_DIGEST_MD5: - LOGI("set EVP_md5"); - return EVP_md5(); + *digestAlg = (EVP_MD *)EVP_md5(); + break; case HCF_OPENSSL_DIGEST_SHA1: - LOGI("set EVP_sha1"); - return EVP_sha1(); + *digestAlg = (EVP_MD *)EVP_sha1(); + break; case HCF_OPENSSL_DIGEST_SHA224: - LOGI("set EVP_sha224"); - return EVP_sha224(); + *digestAlg = (EVP_MD *)EVP_sha224(); + break; case HCF_OPENSSL_DIGEST_SHA256: - LOGI("set EVP_sha256"); - return EVP_sha256(); + *digestAlg = (EVP_MD *)EVP_sha256(); + break; case HCF_OPENSSL_DIGEST_SHA384: - LOGI("set EVP_sha384"); - return EVP_sha384(); + *digestAlg = (EVP_MD *)EVP_sha384(); + break; case HCF_OPENSSL_DIGEST_SHA512: - LOGI("set EVP_sha512"); - return EVP_sha512(); + *digestAlg = (EVP_MD *)EVP_sha512(); + break; default: LOGE("Invalid digest num is %u.", alg); - return NULL; + return HCF_INVALID_PARAMS; } + return HCF_SUCCESS; +} + +HcfResult GetRsaSpecStringMd(const HcfAlgParaValue md, char **returnString) +{ + if (returnString == NULL) { + LOGE("return string is null"); + return HCF_INVALID_PARAMS; + } + char *tmp = NULL; + switch (md) { + case HCF_OPENSSL_DIGEST_MD5: + tmp = HCF_OPENSSL_DIGEST_MD5_STR; + break; + case HCF_OPENSSL_DIGEST_SHA1: + tmp = HCF_OPENSSL_DIGEST_SHA1_STR; + break; + case HCF_OPENSSL_DIGEST_SHA224: + tmp = HCF_OPENSSL_DIGEST_SHA224_STR; + break; + case HCF_OPENSSL_DIGEST_SHA256: + tmp = HCF_OPENSSL_DIGEST_SHA256_STR; + break; + case HCF_OPENSSL_DIGEST_SHA384: + tmp = HCF_OPENSSL_DIGEST_SHA384_STR; + break; + case HCF_OPENSSL_DIGEST_SHA512: + tmp = HCF_OPENSSL_DIGEST_SHA512_STR; + break; + default: + LOGE("Invalid digest num is %u.", md); + return HCF_INVALID_PARAMS; + } + size_t mdLen = strlen(tmp); + char *mdStr = (char *)HcfMalloc(mdLen + 1, 0); + if (mdStr == NULL) { + LOGE("Failed to allocate md name memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(mdStr, mdLen, tmp, mdLen); + *returnString = mdStr; + return HCF_SUCCESS; +} + +HcfResult GetRsaSpecStringMGF(char **returnString) +{ + if (returnString == NULL) { + LOGE("return string is null"); + return HCF_INVALID_PARAMS; + } + uint32_t mgf1Len = strlen(HCF_OPENSSL_MGF1); + char *mgf1Str = (char *)HcfMalloc(mgf1Len + 1, 0); + if (mgf1Str == NULL) { + LOGE("Failed to allocate mgf1 name memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(mgf1Str, mgf1Len, HCF_OPENSSL_MGF1, mgf1Len); + *returnString = mgf1Str; + return HCF_SUCCESS; } void HcfPrintOpensslError(void) @@ -90,26 +169,26 @@ void HcfPrintOpensslError(void) LOGE("[Openssl]: engine fail, error code = %lu, error string = %s", errCode, szErr); } -int32_t GetOpensslPadding(int32_t padding, int32_t *opensslPadding) +HcfResult GetOpensslPadding(int32_t padding, int32_t *opensslPadding) { + if (opensslPadding == NULL) { + LOGE("return openssl padding pointer is null"); + return HCF_INVALID_PARAMS; + } switch (padding) { case HCF_ALG_NOPADDING: - LOGI("set RSA_NO_PADDING"); *opensslPadding = RSA_NO_PADDING; return HCF_SUCCESS; case HCF_OPENSSL_RSA_PKCS1_PADDING: - LOGI("set RSA_PKCS1_PADDING"); *opensslPadding = RSA_PKCS1_PADDING; return HCF_SUCCESS; case HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING: - LOGI("set RSA_PKCS1_OAEP_PADDING"); *opensslPadding = RSA_PKCS1_OAEP_PADDING; return HCF_SUCCESS; case HCF_OPENSSL_RSA_PSS_PADDING: - LOGI("set RSA_PKCS1_PSS_PADDING"); *opensslPadding = RSA_PKCS1_PSS_PADDING; return HCF_SUCCESS; @@ -123,16 +202,12 @@ int32_t GetRealPrimes(int32_t primesFlag) { switch (primesFlag) { case HCF_OPENSSL_PRIMES_2: - LOGI("set primes 2"); return PRIMES_2; case HCF_OPENSSL_PRIMES_3: - LOGI("set primes 3"); return PRIMES_3; case HCF_OPENSSL_PRIMES_4: - LOGI("set primes 4"); return PRIMES_4; case HCF_OPENSSL_PRIMES_5: - LOGI("set primes 5"); return PRIMES_5; default: LOGI("set default primes 2"); @@ -140,3 +215,72 @@ int32_t GetRealPrimes(int32_t primesFlag) } } +bool IsBigEndian(void) +{ + uint32_t *pointer = (uint32_t *)&ASCII_CODE_ZERO; + char firstChar = *((char *)pointer); + if (firstChar == '0') { + return false; + } else { + return true; + } +} + +HcfResult BigIntegerToBigNum(const HcfBigInteger *src, BIGNUM **dest) +{ + if (src == NULL || dest == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (IsBigEndian()) { + *dest = Openssl_BN_bin2bn((src->data), (src->len), NULL); + } else { + *dest = Openssl_BN_lebin2bn((src->data), (src->len), NULL); + } + + if (*dest == NULL) { + LOGE("translate BigInteger to BIGNUM failed."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +HcfResult BigNumToBigInteger(const BIGNUM *src, HcfBigInteger *dest) +{ + if (src == NULL || dest == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + int32_t len = Openssl_BN_num_bytes(src); + if (len <= 0) { + LOGE("Invalid input parameter."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + dest->data = (unsigned char *)HcfMalloc(len, 0); + if (dest->data == NULL) { + LOGE("Alloc dest->data memeory failed."); + return HCF_ERR_MALLOC; + } + dest->len = len; + + int32_t resLen = -1; + if (IsBigEndian()) { + resLen = Openssl_BN_bn2binpad(src, dest->data, dest->len); + } else { + resLen = Openssl_BN_bn2lebinpad(src, dest->data, dest->len); + } + + if (resLen != dest->len) { + LOGE("translate BIGNUM to BigInteger failed."); + HcfPrintOpensslError(); + HcfFree(dest->data); + dest->data = NULL; + dest->len = 0; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} diff --git a/plugin/openssl_plugin/common/src/rsa_openssl_common.c b/plugin/openssl_plugin/common/src/rsa_openssl_common.c index 1a9e0b5..4c77cc4 100644 --- a/plugin/openssl_plugin/common/src/rsa_openssl_common.c +++ b/plugin/openssl_plugin/common/src/rsa_openssl_common.c @@ -14,6 +14,7 @@ */ #include "rsa_openssl_common.h" #include "log.h" +#include "openssl_adapter.h" #include "openssl_common.h" HcfResult DuplicateRsa(RSA *rsa, bool needPrivate, RSA **dupRsa) @@ -24,9 +25,9 @@ HcfResult DuplicateRsa(RSA *rsa, bool needPrivate, RSA **dupRsa) return HCF_INVALID_PARAMS; } if (needPrivate) { - retRSA = RSAPrivateKey_dup(rsa); + retRSA = Openssl_RSAPrivateKey_dup(rsa); } else { - retRSA = RSAPublicKey_dup(rsa); + retRSA = Openssl_RSAPublicKey_dup(rsa); } if (retRSA == NULL) { LOGE("Duplicate RSA fail."); @@ -43,24 +44,24 @@ EVP_PKEY *NewEvpPkeyByRsa(RSA *rsa, bool withDuplicate) LOGE("RSA is NULL"); return NULL; } - EVP_PKEY *pKey = EVP_PKEY_new(); + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); if (pKey == NULL) { LOGE("EVP_PKEY_new fail"); HcfPrintOpensslError(); return NULL; } if (withDuplicate) { - if (EVP_PKEY_set1_RSA(pKey, rsa) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_PKEY_set1_RSA(pKey, rsa) != HCF_OPENSSL_SUCCESS) { LOGE("EVP_PKEY_set1_RSA fail"); HcfPrintOpensslError(); - EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_free(pKey); return NULL; } } else { - if (EVP_PKEY_assign_RSA(pKey, rsa) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_PKEY_assign_RSA(pKey, rsa) != HCF_OPENSSL_SUCCESS) { LOGE("EVP_PKEY_assign_RSA fail"); HcfPrintOpensslError(); - EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_free(pKey); return NULL; } } diff --git a/plugin/openssl_plugin/crypto_operation/aes/inc/aes_openssl.h b/plugin/openssl_plugin/crypto_operation/cipher/inc/aes_openssl.h similarity index 100% rename from plugin/openssl_plugin/crypto_operation/aes/inc/aes_openssl.h rename to plugin/openssl_plugin/crypto_operation/cipher/inc/aes_openssl.h diff --git a/plugin/openssl_plugin/crypto_operation/rsa/inc/cipher_rsa_openssl.h b/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_rsa_openssl.h similarity index 100% rename from plugin/openssl_plugin/crypto_operation/rsa/inc/cipher_rsa_openssl.h rename to plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_rsa_openssl.h diff --git a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_3des_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_3des_openssl.c similarity index 81% rename from plugin/openssl_plugin/crypto_operation/aes/src/cipher_3des_openssl.c rename to plugin/openssl_plugin/crypto_operation/cipher/src/cipher_3des_openssl.c index 5968fad..701eec3 100644 --- a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_3des_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_3des_openssl.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include #include "log.h" #include "blob.h" #include "memory.h" @@ -22,6 +21,7 @@ #include "securec.h" #include "aes_openssl_common.h" #include "sym_common_defines.h" +#include "openssl_adapter.h" #include "openssl_common.h" #include "openssl_class.h" @@ -41,25 +41,25 @@ static const char *GetDesGeneratorClass(void) static const EVP_CIPHER *DefaultCipherType(void) { - return EVP_des_ede3_ecb(); + return Openssl_EVP_des_ede3_ecb(); } static const EVP_CIPHER *GetCipherType(HcfCipherDesGeneratorSpiOpensslImpl *impl) { switch (impl->attr.mode) { case HCF_ALG_MODE_ECB: - return EVP_des_ede3_ecb(); + return Openssl_EVP_des_ede3_ecb(); case HCF_ALG_MODE_CBC: - return EVP_des_ede3_cbc(); + return Openssl_EVP_des_ede3_cbc(); case HCF_ALG_MODE_OFB: - return EVP_des_ede3_ofb(); + return Openssl_EVP_des_ede3_ofb(); case HCF_ALG_MODE_CFB: case HCF_ALG_MODE_CFB64: - return EVP_des_ede3_cfb64(); + return Openssl_EVP_des_ede3_cfb64(); case HCF_ALG_MODE_CFB1: - return EVP_des_ede3_cfb1(); + return Openssl_EVP_des_ede3_cfb1(); case HCF_ALG_MODE_CFB8: - return EVP_des_ede3_cfb8(); + return Openssl_EVP_des_ede3_cfb8(); default: break; } @@ -72,15 +72,15 @@ static HcfResult InitCipherData(enum HcfCryptoMode opMode, CipherData **cipherDa *cipherData = (CipherData *)HcfMalloc(sizeof(CipherData), 0); if (*cipherData == NULL) { - LOGE("malloc failed!"); + LOGE("malloc failed."); return HCF_ERR_MALLOC; } (*cipherData)->enc = opMode; - (*cipherData)->ctx = EVP_CIPHER_CTX_new(); + (*cipherData)->ctx = Openssl_EVP_CIPHER_CTX_new(); if ((*cipherData)->ctx == NULL) { HcfPrintOpensslError(); - LOGE("Failed to allocate ctx memroy!"); + LOGE("Failed to allocate ctx memroy."); goto clearup; } @@ -95,7 +95,7 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMod HcfKey *key, HcfParamsSpec *params) { if ((self == NULL) || (key == NULL)) { /* params maybe is null */ - LOGE("Invalid input parameter!"); + LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } if (!IsClassMatch((const HcfObjectBase *)self, GetDesGeneratorClass())) { @@ -121,20 +121,20 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMod } HcfResult ret = HCF_ERR_CRYPTO_OPERATION; CipherData *data = cipherImpl->cipherData; - if (EVP_CipherInit(data->ctx, GetCipherType(cipherImpl), NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CipherInit(data->ctx, GetCipherType(cipherImpl), NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("cipher init failed!"); + LOGE("Cipher init failed."); goto clearup; } - if (EVP_CipherInit(data->ctx, NULL, keyImpl->keyMaterial.data, GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CipherInit(data->ctx, NULL, keyImpl->keyMaterial.data, GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("cipher init key and iv failed!"); + LOGE("Cipher init key and iv failed."); goto clearup; } int32_t padding = (cipherImpl->attr.paddingMode == HCF_ALG_NOPADDING) ? 0 : EVP_PADDING_PKCS7; - if (EVP_CIPHER_CTX_set_padding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CIPHER_CTX_set_padding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("set padding!"); + LOGE("Set padding failed."); goto clearup; } return HCF_SUCCESS; @@ -151,7 +151,7 @@ static HcfResult AllocateOutput(HcfBlob *input, HcfBlob *output) } output->data = (uint8_t *)HcfMalloc(outLen, 0); if (output->data == NULL) { - LOGE("malloc output failed!"); + LOGE("Malloc output failed."); return HCF_ERR_MALLOC; } output->len = outLen; @@ -161,7 +161,7 @@ static HcfResult AllocateOutput(HcfBlob *input, HcfBlob *output) static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) { if ((self == NULL) || (input == NULL) || (output == NULL)) { - LOGE("Invalid input parameter!"); + LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } if (!IsClassMatch((const HcfObjectBase *)self, GetDesGeneratorClass())) { @@ -172,20 +172,20 @@ static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBl HcfCipherDesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherDesGeneratorSpiOpensslImpl *)self; CipherData *data = cipherImpl->cipherData; if (data == NULL) { - LOGE("cipherData is null!"); + LOGE("CipherData is null."); return HCF_INVALID_PARAMS; } HcfResult res = AllocateOutput(input, output); if (res != HCF_SUCCESS) { - LOGE("AllocateOutput failed!"); + LOGE("AllocateOutput failed."); goto clearup; } - int32_t ret = EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, + int32_t ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("cipher update failed!"); + LOGE("Cipher update failed."); res = HCF_ERR_CRYPTO_OPERATION; goto clearup; } @@ -206,19 +206,19 @@ static HcfResult DesDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output) uint32_t len = 0; if (IsBlobValid(input)) { - ret = EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, + ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("cipher update failed!"); + LOGE("Cipher update failed."); return HCF_ERR_CRYPTO_OPERATION; } len += output->len; } - ret = EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); + ret = Openssl_EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGE("cipher final filed!"); + LOGE("Cipher final filed."); return HCF_ERR_CRYPTO_OPERATION; } output->len += len; @@ -228,7 +228,7 @@ static HcfResult DesDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output) static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) { if ((self == NULL) || (output == NULL)) { /* input maybe is null */ - LOGE("Invalid input parameter!"); + LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } if (!IsClassMatch((const HcfObjectBase *)self, GetDesGeneratorClass())) { @@ -238,18 +238,18 @@ static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfB HcfCipherDesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherDesGeneratorSpiOpensslImpl *)self; CipherData *data = cipherImpl->cipherData; if (data == NULL) { - LOGE("cipherData is null!"); + LOGE("CipherData is null."); return HCF_INVALID_PARAMS; } HcfResult res = AllocateOutput(input, output); if (res != HCF_SUCCESS) { - LOGE("AllocateOutput failed!"); + LOGE("AllocateOutput failed."); goto clearup; } res = DesDoFinal(data, input, output); if (res != HCF_SUCCESS) { - LOGE("DesDoFinal failed!"); + LOGE("DesDoFinal failed."); } clearup: if (res != HCF_SUCCESS) { @@ -278,13 +278,13 @@ static void EngineDesGeneratorDestroy(HcfObjectBase *self) HcfResult HcfCipherDesGeneratorSpiCreate(CipherAttr *attr, HcfCipherGeneratorSpi **generator) { if ((attr == NULL) || (generator == NULL)) { - LOGE("Invalid input parameter!"); + LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } HcfCipherDesGeneratorSpiOpensslImpl *returnImpl = (HcfCipherDesGeneratorSpiOpensslImpl *)HcfMalloc( sizeof(HcfCipherDesGeneratorSpiOpensslImpl), 0); if (returnImpl == NULL) { - LOGE("Failed to allocate returnImpl memroy!"); + LOGE("Failed to allocate returnImpl memroy."); return HCF_ERR_MALLOC; } (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), attr, sizeof(CipherAttr)); diff --git a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_common.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c similarity index 96% rename from plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_common.c rename to plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c index 933e307..ef62d00 100644 --- a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_common.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c @@ -18,6 +18,7 @@ #include "log.h" #include "memory.h" #include "result.h" +#include "openssl_adapter.h" const unsigned char *GetIv(HcfParamsSpec *params) { @@ -55,7 +56,7 @@ void FreeCipherData(CipherData **data) return; } if ((*data)->ctx != NULL) { - EVP_CIPHER_CTX_free((*data)->ctx); + Openssl_EVP_CIPHER_CTX_free((*data)->ctx); (*data)->ctx = NULL; } if ((*data)->aad != NULL) { diff --git a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c similarity index 74% rename from plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_openssl.c rename to plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c index ac74eb2..2642b46 100644 --- a/plugin/openssl_plugin/crypto_operation/aes/src/cipher_aes_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c @@ -21,6 +21,7 @@ #include "utils.h" #include "aes_openssl_common.h" #include "sym_common_defines.h" +#include "openssl_adapter.h" #include "openssl_common.h" #include "openssl_class.h" @@ -46,189 +47,189 @@ static const char *GetAesGeneratorClass(void) return OPENSSL_AES_CIPHER_CLASS; } -static const EVP_CIPHER *CipherEcbType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherEcbType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_ecb(); - case HCF_ALG_AES_192:; - return EVP_aes_192_ecb(); - case HCF_ALG_AES_256: - return EVP_aes_256_ecb(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_ecb(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_ecb(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_ecb(); default: break; } - return EVP_aes_128_ecb(); + return Openssl_EVP_aes_128_ecb(); } -static const EVP_CIPHER *CipherCbcType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCbcType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_cbc(); - case HCF_ALG_AES_192:; - return EVP_aes_192_cbc(); - case HCF_ALG_AES_256: - return EVP_aes_256_cbc(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_cbc(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_cbc(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_cbc(); default: break; } - return EVP_aes_128_cbc(); + return Openssl_EVP_aes_128_cbc(); } -static const EVP_CIPHER *CipherCtrType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCtrType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_ctr(); - case HCF_ALG_AES_192:; - return EVP_aes_192_ctr(); - case HCF_ALG_AES_256: - return EVP_aes_256_ctr(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_ctr(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_ctr(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_ctr(); default: break; } - return EVP_aes_128_ctr(); + return Openssl_EVP_aes_128_ctr(); } -static const EVP_CIPHER *CipherOfbType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherOfbType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_ofb(); - case HCF_ALG_AES_192:; - return EVP_aes_192_ofb(); - case HCF_ALG_AES_256: - return EVP_aes_256_ofb(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_ofb(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_ofb(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_ofb(); default: break; } - return EVP_aes_128_ofb(); + return Openssl_EVP_aes_128_ofb(); } -static const EVP_CIPHER *CipherCfbType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCfbType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_cfb(); - case HCF_ALG_AES_192:; - return EVP_aes_192_cfb(); - case HCF_ALG_AES_256: - return EVP_aes_256_cfb(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_cfb(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_cfb(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_cfb(); default: break; } - return EVP_aes_128_cfb(); + return Openssl_EVP_aes_128_cfb(); } -static const EVP_CIPHER *CipherCfb1Type(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCfb1Type(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_cfb1(); - case HCF_ALG_AES_192:; - return EVP_aes_192_cfb1(); - case HCF_ALG_AES_256: - return EVP_aes_256_cfb1(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_cfb1(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_cfb1(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_cfb1(); default: break; } - return EVP_aes_128_cfb1(); + return Openssl_EVP_aes_128_cfb1(); } -static const EVP_CIPHER *CipherCfb128Type(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCfb128Type(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_cfb128(); - case HCF_ALG_AES_192:; - return EVP_aes_192_cfb128(); - case HCF_ALG_AES_256: - return EVP_aes_256_cfb128(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_cfb128(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_cfb128(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_cfb128(); default: break; } - return EVP_aes_128_cfb128(); + return Openssl_EVP_aes_128_cfb128(); } -static const EVP_CIPHER *CipherCfb8Type(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCfb8Type(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_cfb8(); - case HCF_ALG_AES_192:; - return EVP_aes_192_cfb8(); - case HCF_ALG_AES_256: - return EVP_aes_256_cfb8(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_cfb8(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_cfb8(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_cfb8(); default: break; } - return EVP_aes_128_cfb8(); + return Openssl_EVP_aes_128_cfb8(); } -static const EVP_CIPHER *CipherCcmType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherCcmType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_ccm(); - case HCF_ALG_AES_192:; - return EVP_aes_192_ccm(); - case HCF_ALG_AES_256: - return EVP_aes_256_ccm(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_ccm(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_ccm(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_ccm(); default: break; } - return EVP_aes_128_ccm(); + return Openssl_EVP_aes_128_ccm(); } -static const EVP_CIPHER *CipherGcmType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *CipherGcmType(SymKeyImpl *symKey) { - switch (value) { - case HCF_ALG_AES_128: - return EVP_aes_128_gcm(); - case HCF_ALG_AES_192:; - return EVP_aes_192_gcm(); - case HCF_ALG_AES_256: - return EVP_aes_256_gcm(); + switch (symKey->keyMaterial.len) { + case AES_SIZE_128: + return Openssl_EVP_aes_128_gcm(); + case AES_SIZE_192: + return Openssl_EVP_aes_192_gcm(); + case AES_SIZE_256: + return Openssl_EVP_aes_256_gcm(); default: break; } - return EVP_aes_128_gcm(); + return Openssl_EVP_aes_128_gcm(); } -static const EVP_CIPHER *DefaultCiherType(HCF_ALG_PARA_VALUE value) +static const EVP_CIPHER *DefaultCiherType(SymKeyImpl *symKey) { - return CipherEcbType(value); + return CipherEcbType(symKey); } -static const EVP_CIPHER *GetCipherType(HcfCipherAesGeneratorSpiOpensslImpl *impl) +static const EVP_CIPHER *GetCipherType(HcfCipherAesGeneratorSpiOpensslImpl *impl, SymKeyImpl *symKey) { switch (impl->attr.mode) { case HCF_ALG_MODE_ECB: - return CipherEcbType(impl->attr.keySize); + return CipherEcbType(symKey); case HCF_ALG_MODE_CBC: - return CipherCbcType(impl->attr.keySize); + return CipherCbcType(symKey); case HCF_ALG_MODE_CTR: - return CipherCtrType(impl->attr.keySize); + return CipherCtrType(symKey); case HCF_ALG_MODE_OFB: - return CipherOfbType(impl->attr.keySize); + return CipherOfbType(symKey); case HCF_ALG_MODE_CFB: - return CipherCfbType(impl->attr.keySize); + return CipherCfbType(symKey); case HCF_ALG_MODE_CFB1: - return CipherCfb1Type(impl->attr.keySize); + return CipherCfb1Type(symKey); case HCF_ALG_MODE_CFB8: - return CipherCfb8Type(impl->attr.keySize); + return CipherCfb8Type(symKey); case HCF_ALG_MODE_CFB128: - return CipherCfb128Type(impl->attr.keySize); + return CipherCfb128Type(symKey); case HCF_ALG_MODE_CCM: - return CipherCcmType(impl->attr.keySize); + return CipherCcmType(symKey); case HCF_ALG_MODE_GCM: - return CipherGcmType(impl->attr.keySize); + return CipherGcmType(symKey); default: break; } - return DefaultCiherType(impl->attr.keySize); + return DefaultCiherType(symKey); } static bool IsGcmParamsValid(HcfGcmParamsSpec *params) @@ -343,10 +344,10 @@ static HcfResult InitCipherData(HcfCipherGeneratorSpi *self, enum HcfCryptoMode return ret; } HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self; - HCF_ALG_PARA_VALUE mode = cipherImpl->attr.mode; + HcfAlgParaValue mode = cipherImpl->attr.mode; (*cipherData)->enc = opMode; - (*cipherData)->ctx = EVP_CIPHER_CTX_new(); + (*cipherData)->ctx = Openssl_EVP_CIPHER_CTX_new(); if ((*cipherData)->ctx == NULL) { HcfPrintOpensslError(); LOGE("Failed to allocate ctx memory!"); @@ -369,22 +370,6 @@ clearup: return ret; } -static HcfResult IsKeySizeMatchCipher(SymKeyImpl *keyImpl, HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl) -{ - size_t keySize = keyImpl->keyMaterial.len; - HCF_ALG_PARA_VALUE cipherValue = cipherImpl->attr.keySize; - switch (cipherValue) { - case HCF_ALG_AES_128: - return (keySize < AES_SIZE_128) ? HCF_INVALID_PARAMS : HCF_SUCCESS; - case HCF_ALG_AES_192: - return (keySize < AES_SIZE_192) ? HCF_INVALID_PARAMS : HCF_SUCCESS; - case HCF_ALG_AES_256: - return (keySize < AES_SIZE_256) ? HCF_INVALID_PARAMS : HCF_SUCCESS; - default: - return HCF_INVALID_PARAMS; - } -} - static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode, HcfKey *key, HcfParamsSpec *params) { @@ -400,10 +385,7 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMod HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self; SymKeyImpl *keyImpl = (SymKeyImpl *)key; int enc = (opMode == ENCRYPT_MODE) ? 1 : 0; - if (IsKeySizeMatchCipher(keyImpl, cipherImpl) != HCF_SUCCESS) { - LOGE("Init failed, key size is smaller than cipher size."); - return HCF_INVALID_PARAMS; - } + cipherImpl->attr.keySize = keyImpl->keyMaterial.len; if (InitCipherData(self, opMode, params, &(cipherImpl->cipherData)) != HCF_SUCCESS) { LOGE("InitCipherData failed!"); return HCF_INVALID_PARAMS; @@ -411,15 +393,15 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMod CipherData *data = cipherImpl->cipherData; HcfResult ret = HCF_ERR_CRYPTO_OPERATION; - if (EVP_CipherInit(data->ctx, GetCipherType(cipherImpl), keyImpl->keyMaterial.data, GetIv(params), enc) != - HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CipherInit(data->ctx, GetCipherType(cipherImpl, keyImpl), keyImpl->keyMaterial.data, + GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("EVP_CipherInit failed!"); goto clearup; } int32_t padding = (cipherImpl->attr.paddingMode == HCF_ALG_NOPADDING) ? 0 : EVP_PADDING_PKCS7; - if (EVP_CIPHER_CTX_set_padding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CIPHER_CTX_set_padding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("set padding failed!"); goto clearup; @@ -429,8 +411,8 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMod return HCF_SUCCESS; } /* ccm decrypt need set tag */ - if (EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, GetCcmTagLen(params), GetCcmTag(params)) != - HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, GetCcmTagLen(params), + GetCcmTag(params)) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("set AuthTag failed!"); goto clearup; @@ -443,7 +425,7 @@ clearup: static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output) { - int32_t ret = EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, + int32_t ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); @@ -453,23 +435,23 @@ static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output) return HCF_SUCCESS; } -static HcfResult AeadUpdate(CipherData *data, HCF_ALG_PARA_VALUE mode, HcfBlob *input, HcfBlob *output) +static HcfResult AeadUpdate(CipherData *data, HcfAlgParaValue mode, HcfBlob *input, HcfBlob *output) { if (mode == HCF_ALG_MODE_CCM) { - if (EVP_CipherUpdate(data->ctx, NULL, (int *)&output->len, NULL, input->len) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_CipherUpdate(data->ctx, NULL, (int *)&output->len, NULL, input->len) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("ccm cipher update failed!"); return HCF_ERR_CRYPTO_OPERATION; } } - int32_t ret = EVP_CipherUpdate(data->ctx, NULL, (int *)&output->len, data->aad, data->aadLen); + int32_t ret = Openssl_EVP_CipherUpdate(data->ctx, NULL, (int *)&output->len, data->aad, data->aadLen); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("aad cipher update failed!"); return HCF_ERR_CRYPTO_OPERATION; } - ret = EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); + ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("gcm cipher update failed!"); @@ -543,14 +525,14 @@ static HcfResult CommonDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output return res; } if (isUpdateInput) { - ret = EVP_CipherUpdate(data->ctx, output->data, (int32_t *)&len, input->data, input->len); + ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int32_t *)&len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("EVP_CipherUpdate failed!"); return HCF_ERR_CRYPTO_OPERATION; } } - ret = EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); + ret = Openssl_EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("EVP_CipherFinal_ex failed!"); @@ -595,7 +577,7 @@ static HcfResult CcmDecryptDoFinal(HcfBlob *output, bool isUpdateInput) static HcfResult CcmEncryptDoFinal(CipherData *data, HcfBlob *output, uint32_t len) { - int32_t ret = EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, output->data + len); + int32_t ret = Openssl_EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, output->data + len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("get AuthTag failed!"); @@ -637,13 +619,13 @@ static HcfResult GcmDecryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *ou LOGE("gcm decrypt has not AuthTag!"); return HCF_INVALID_PARAMS; } - int32_t ret = EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, data->tagLen, (void *)data->tag); + int32_t ret = Openssl_EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, data->tagLen, (void *)data->tag); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("gcm decrypt set AuthTag failed!"); return HCF_ERR_CRYPTO_OPERATION; } - ret = EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); + ret = Openssl_EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("EVP_CipherFinal_ex failed!"); @@ -655,14 +637,14 @@ static HcfResult GcmDecryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *ou static HcfResult GcmEncryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len) { - int32_t ret = EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); + int32_t ret = Openssl_EVP_CipherFinal_ex(data->ctx, output->data + len, (int *)&output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); LOGE("EVP_CipherFinal_ex failed!"); return HCF_ERR_CRYPTO_OPERATION; } output->len += len; - ret = EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, + ret = Openssl_EVP_CIPHER_CTX_ctrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, output->data + output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); @@ -735,7 +717,7 @@ static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfB HcfResult ret = HCF_ERR_CRYPTO_OPERATION; HcfCipherAesGeneratorSpiOpensslImpl *cipherImpl = (HcfCipherAesGeneratorSpiOpensslImpl *)self; CipherData *data = cipherImpl->cipherData; - HCF_ALG_PARA_VALUE mode = cipherImpl->attr.mode; + HcfAlgParaValue mode = cipherImpl->attr.mode; if (data == NULL) { LOGE("cipherData is null!"); return HCF_INVALID_PARAMS; diff --git a/plugin/openssl_plugin/crypto_operation/rsa/src/cipher_rsa_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_rsa_openssl.c similarity index 45% rename from plugin/openssl_plugin/crypto_operation/rsa/src/cipher_rsa_openssl.c rename to plugin/openssl_plugin/crypto_operation/cipher/src/cipher_rsa_openssl.c index 6326164..1304c97 100644 --- a/plugin/openssl_plugin/crypto_operation/rsa/src/cipher_rsa_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_rsa_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -19,6 +19,7 @@ #include "rsa_openssl_common.h" #include "log.h" #include "memory.h" +#include "openssl_adapter.h" #include "openssl_class.h" #include "openssl_common.h" #include "stdbool.h" @@ -32,9 +33,11 @@ typedef struct { CipherAttr attr; - InitFlag initFlag; + CryptoStatus initFlag; EVP_PKEY_CTX *ctx; + + HcfBlob pSource; } HcfCipherRsaGeneratorSpiImpl; static HcfResult CheckCipherInitParams(enum HcfCryptoMode opMode, HcfKey *key) @@ -66,14 +69,39 @@ static HcfResult DuplicateRsaFromKey(HcfKey *key, enum HcfCryptoMode opMode, RSA if (opMode == ENCRYPT_MODE) { ret = DuplicateRsa(((HcfOpensslRsaPubKey *)key)->pk, false, dupRsa); if (ret != HCF_SUCCESS) { - LOGE("dup pub rsa fail."); + LOGE("dup pub RSA fail."); return ret; } + LOGE("dup pub RSA success."); } else if (opMode == DECRYPT_MODE) { ret = DuplicateRsa(((HcfOpensslRsaPriKey *)key)->sk, true, dupRsa); if (ret != HCF_SUCCESS) { - LOGE("dup pri rsa fail."); - return ret; + RSA *tmp = Openssl_RSA_new(); + if (tmp == NULL) { + LOGE("malloc RSA failed"); + return HCF_ERR_MALLOC; + } + const BIGNUM *n = NULL; + const BIGNUM *e = NULL; + const BIGNUM *d = NULL; + Openssl_RSA_get0_key(((HcfOpensslRsaPriKey *)key)->sk, &n, &e, &d); + if (n == NULL || e == NULL || d == NULL) { + LOGE("get key attribute fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + BIGNUM *dupN = Openssl_BN_dup(n); + BIGNUM *dupE = Openssl_BN_dup(e); + BIGNUM *dupD = Openssl_BN_dup(d); + if (RSA_set0_key(tmp, dupN, dupE, dupD) != HCF_OPENSSL_SUCCESS) { + LOGE("assign RSA n, e, d failed"); + Openssl_BN_clear_free(dupN); + Openssl_BN_clear_free(dupE); + Openssl_BN_clear_free(dupD); + return HCF_ERR_CRYPTO_OPERATION; + } + *dupRsa = tmp; + ret = HCF_SUCCESS; + LOGE("dup pri RSA success."); } } else { LOGE("OpMode not match."); @@ -95,72 +123,236 @@ static HcfResult InitEvpPkeyCtx(HcfCipherRsaGeneratorSpiImpl *impl, HcfKey *key, if (pkey == NULL) { LOGE("NewEvpPkeyByRsa fail"); HcfPrintOpensslError(); - RSA_free(rsa); + Openssl_RSA_free(rsa); return HCF_ERR_CRYPTO_OPERATION; } impl->ctx = EVP_PKEY_CTX_new(pkey, NULL); if (impl->ctx == NULL) { LOGE("EVP_PKEY_CTX_new fail"); HcfPrintOpensslError(); - EVP_PKEY_free(pkey); + Openssl_EVP_PKEY_free(pkey); return HCF_ERR_CRYPTO_OPERATION; } int32_t sslRet = HCF_OPENSSL_SUCCESS; if (opMode == ENCRYPT_MODE) { - sslRet = EVP_PKEY_encrypt_init(impl->ctx); + sslRet = Openssl_EVP_PKEY_encrypt_init(impl->ctx); } else { - sslRet = EVP_PKEY_decrypt_init(impl->ctx); + sslRet = Openssl_EVP_PKEY_decrypt_init(impl->ctx); } if (sslRet != HCF_OPENSSL_SUCCESS) { LOGE("Init EVP_PKEY fail"); HcfPrintOpensslError(); - EVP_PKEY_free(pkey); - EVP_PKEY_CTX_free(impl->ctx); + Openssl_EVP_PKEY_free(pkey); + Openssl_EVP_PKEY_CTX_free(impl->ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pkey); + return HCF_SUCCESS; +} + +static HcfResult SetPsourceFromBlob(HcfBlob pSource, EVP_PKEY_CTX *ctx) +{ + // If pSource is NULL or len is 0, the pSource will be cleared. + if (pSource.data == NULL || pSource.len == 0) { + if (Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, NULL, 0) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl Set psource fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + } + // deep copy from pSource + uint8_t *opensslPsource = (uint8_t *)HcfMalloc(pSource.len, 0); + if (opensslPsource == NULL) { + LOGE("Failed to allocate openssl pSource data memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(opensslPsource, pSource.len, pSource.data, pSource.len); + + if (Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, opensslPsource, pSource.len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl Set psource fail"); + HcfPrintOpensslError(); + HcfFree(opensslPsource); return HCF_ERR_CRYPTO_OPERATION; } - EVP_PKEY_free(pkey); return HCF_SUCCESS; } +// all parmas have been checked in CheckRsaCipherParams, this function does not need check. static HcfResult SetDetailParams(HcfCipherRsaGeneratorSpiImpl *impl) { CipherAttr attr = impl->attr; - const EVP_MD *md = GetOpensslDigestAlg(attr.md); - if (md == NULL && attr.paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { - LOGE("md is NULL."); + int32_t opensslPadding = 0; + (void)GetOpensslPadding(attr.paddingMode, &opensslPadding); + if (Openssl_EVP_PKEY_CTX_set_rsa_padding(impl->ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { + LOGE("Cipher set padding fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { + return HCF_SUCCESS; + } + // pkcs oaep + EVP_MD *md = NULL; + EVP_MD *mgf1md = NULL; + (void)GetOpensslDigestAlg(attr.md, &md); + (void)GetOpensslDigestAlg(attr.mgf1md, &mgf1md); + // set md and mgf1md + if (Openssl_EVP_PKEY_CTX_set_rsa_oaep_md(impl->ctx, md) != HCF_OPENSSL_SUCCESS + || Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(impl->ctx, mgf1md) != HCF_OPENSSL_SUCCESS) { + LOGE("Set md or mgf1md fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + // default EVP pSource is NULL, need not set. + if (impl->pSource.data != NULL && impl->pSource.len > 0) { + HcfResult ret = SetPsourceFromBlob(impl->pSource, impl->ctx); + if (ret != HCF_SUCCESS) { + // check if clean the pSource when init fail at it. + HcfFree(impl->pSource.data); + impl->pSource.data = NULL; + LOGE("Set pSource fail, clean the pSource"); + return ret; + } + } + return HCF_SUCCESS; +} + +// The EVP_PKEY_CTX_set0_rsa_oaep_label() macro sets the RSA OAEP label to label and its length to len. +// https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html +static HcfResult SetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob pSource) +{ + // If pSource is NULL or len is 0, the pSource will be cleared. + if (self == NULL) { + LOGE("Param is invalid."); return HCF_INVALID_PARAMS; } - const EVP_MD *mgf1md = GetOpensslDigestAlg(attr.mgf1md); - if (mgf1md == NULL && attr.paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { - LOGE("mgf1md is NULL."); + if (item != OAEP_MGF1_PSRC_UINT8ARR) { + LOGE("Invalid cipher spec item"); return HCF_INVALID_PARAMS; } - int32_t opensslPadding = 0; - if (GetOpensslPadding(attr.paddingMode, &opensslPadding) != HCF_SUCCESS) { - LOGE("Padding is dismatch."); + if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { + LOGE("Class not match"); return HCF_INVALID_PARAMS; } - if (EVP_PKEY_CTX_set_rsa_padding(impl->ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { - LOGE("Cipher set padding fail."); - HcfPrintOpensslError(); - return HCF_ERR_CRYPTO_OPERATION; + HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self; + CipherAttr attr = impl->attr; + if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { + LOGE("Psource is not supported."); + return HCF_INVALID_PARAMS; } - if (attr.paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { - // set md and mgf1md - if (EVP_PKEY_CTX_set_rsa_oaep_md(impl->ctx, md) != HCF_OPENSSL_SUCCESS - || EVP_PKEY_CTX_set_rsa_mgf1_md(impl->ctx, mgf1md) != HCF_OPENSSL_SUCCESS) { - LOGE("Set md or mgf1md fail"); - HcfPrintOpensslError(); - return HCF_ERR_CRYPTO_OPERATION; + // if it has pSource from previous set, it should be free at first; + if (impl->pSource.data != NULL) { + HcfFree(impl->pSource.data); + impl->pSource.data = NULL; + } + // If pSource is NULL or len is 0, the pSource will be cleared. + if (pSource.data == NULL || pSource.len == 0) { + impl->pSource.data = NULL; + impl->pSource.len = 0; + } else { + // deep copy two pSource, one for impl struct and one for openssl. + impl->pSource.data = (uint8_t *)HcfMalloc(pSource.len, 0); + if (impl->pSource.data == NULL) { + LOGE("Failed to allocate pSource data memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(impl->pSource.data, pSource.len, pSource.data, pSource.len); + impl->pSource.len = pSource.len; + } + // if uninitliszed, pSource should only be stored in the struct. + // if initliszed, pSource should have another copy and set the copy to the evp ctx. + if (impl->initFlag == INITIALIZED) { + HcfResult ret = SetPsourceFromBlob(impl->pSource, impl->ctx); + if (ret != HCF_SUCCESS) { + LOGE("Set pSource fail"); + HcfFree(impl->pSource.data); + impl->pSource.data = NULL; + return ret; } } return HCF_SUCCESS; } +static HcfResult GetRsaCipherSpecUint8Array(HcfCipherGeneratorSpi *self, CipherSpecItem item, HcfBlob* returnPSource) +{ + if (self == NULL || returnPSource == NULL) { + LOGE("Param is invalid."); + return HCF_INVALID_PARAMS; + } + if (item != OAEP_MGF1_PSRC_UINT8ARR) { + LOGE("Invalid cipher spec item"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self; + CipherAttr attr = impl->attr; + if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { + LOGE("Psource is not supported."); + return HCF_INVALID_PARAMS; + } + // use the pSource from struct at first. + if (impl->pSource.data != NULL && impl->pSource.len > 0) { + uint8_t *pSource = (uint8_t *)HcfMalloc(impl->pSource.len, 0); + if (pSource == NULL) { + LOGE("Failed to allocate pSource memory!"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(pSource, impl->pSource.len, impl->pSource.data, impl->pSource.len); + returnPSource->data = pSource; + returnPSource->len = impl->pSource.len; + return HCF_SUCCESS; + } + // without pSource in the struct, use the default get func of openssl after init. + // default situation, the pSource is NULL and len is 0, return fail. + return HCF_INVALID_PARAMS; +} + +static HcfResult GetRsaCipherSpecString(HcfCipherGeneratorSpi *self, CipherSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Param is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)self; + CipherAttr attr = impl->attr; + if (attr.paddingMode != HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { + LOGE("cipher spec string is not supported."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_INVALID_PARAMS; + switch (item) { + case OAEP_MD_NAME_STR: + ret = GetRsaSpecStringMd(attr.md, returnString); + break; + case OAEP_MGF_NAME_STR: + // only support mgf1 + ret = GetRsaSpecStringMGF(returnString); + break; + case OAEP_MGF1_MD_STR: + ret = GetRsaSpecStringMd(attr.mgf1md, returnString); + break; + default: + LOGE("Invalid input cipher spec"); + return HCF_INVALID_PARAMS; + } + return ret; +} + static HcfResult EngineInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode, HcfKey *key, HcfParamsSpec *params) { - LOGI("EngineInit start"); + (void)params; + if (self == NULL || key == NULL) { + LOGE("Param is invalid."); + return HCF_INVALID_PARAMS; + } if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { LOGE("Class not match"); return HCF_INVALID_PARAMS; @@ -183,16 +375,16 @@ static HcfResult EngineInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMo } if (SetDetailParams(impl) != HCF_SUCCESS) { - EVP_PKEY_CTX_free(impl->ctx); + Openssl_EVP_PKEY_CTX_free(impl->ctx); + impl->ctx = NULL; LOGE("SetDetailParams fail."); return HCF_ERR_CRYPTO_OPERATION; } impl->initFlag = INITIALIZED; - LOGI("EngineInit end"); return HCF_SUCCESS; } -static HcfResult EngineUpdata(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) +static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) { LOGE("Openssl don't support update"); (void)self; @@ -205,14 +397,15 @@ static HcfResult DoRsaCrypt(EVP_PKEY_CTX *ctx, HcfBlob *input, HcfBlob *output, { int32_t ret = HCF_OPENSSL_SUCCESS; if (mode == ENCRYPT_MODE) { - ret = EVP_PKEY_encrypt(ctx, output->data, &output->len, input->data, input->len); + ret = Openssl_EVP_PKEY_encrypt(ctx, output->data, &output->len, input->data, input->len); } else if (mode == DECRYPT_MODE) { - ret = EVP_PKEY_decrypt(ctx, output->data, &output->len, input->data, input->len); + ret = Openssl_EVP_PKEY_decrypt(ctx, output->data, &output->len, input->data, input->len); } else { LOGE("OpMode is invalid."); return HCF_INVALID_PARAMS; } if (ret != HCF_OPENSSL_SUCCESS) { + LOGE("RSA openssl error"); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } @@ -221,7 +414,6 @@ static HcfResult DoRsaCrypt(EVP_PKEY_CTX *ctx, HcfBlob *input, HcfBlob *output, static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) { - LOGI("EngineDoFinal start"); if (self == NULL || input == NULL || input->data == NULL) { LOGE("Param is invalid."); return HCF_INVALID_PARAMS; @@ -243,7 +435,7 @@ static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfB LOGE("GetOutLen fail."); return HCF_ERR_CRYPTO_OPERATION; } - LOGI("ouput data len is %zu.", output->len); + LOGD("ouput data len is %zu.", output->len); output->data = (uint8_t *)HcfMalloc(sizeof(uint8_t) * output->len, 0); ret = DoRsaCrypt(impl->ctx, input, output, attr.mode); @@ -253,7 +445,6 @@ static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfB output->len = 0; return HCF_ERR_CRYPTO_OPERATION; } - LOGI("EngineDoFinal end"); return HCF_SUCCESS; } @@ -267,9 +458,12 @@ static void EngineDestroySpiImpl(HcfObjectBase *generator) return; } HcfCipherRsaGeneratorSpiImpl *impl = (HcfCipherRsaGeneratorSpiImpl *)generator; - EVP_PKEY_CTX_free(impl->ctx); + Openssl_EVP_PKEY_CTX_free(impl->ctx); impl->ctx = NULL; + HcfFree(impl->pSource.data); + impl->pSource.data = NULL; HcfFree(impl); + impl = NULL; } static const char *EngineGetClass(void) @@ -285,29 +479,33 @@ static HcfResult CheckRsaCipherParams(CipherAttr *params) return HCF_INVALID_PARAMS; } if (GetOpensslPadding(params->paddingMode, &opensslPadding) != HCF_SUCCESS) { - LOGE("Cipher create without padding"); + LOGE("Cipher create without padding mode"); return HCF_INVALID_PARAMS; } - if (params->paddingMode == HCF_ALG_NOPADDING && (GetOpensslDigestAlg(params->md) != NULL || - GetOpensslDigestAlg(params->mgf1md) != NULL)) { - LOGE("Nopadding don't need md or mgf1md"); - return HCF_INVALID_PARAMS; - } - - if (params->paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING && GetOpensslDigestAlg(params->md) == NULL) { - LOGE("md is NULL"); + // cannot use pss padding mode in RSA cipher. + if (opensslPadding == RSA_PKCS1_PSS_PADDING) { + LOGE("Cipher cannot use PSS mode"); return HCF_INVALID_PARAMS; } - if (params->paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING && GetOpensslDigestAlg(params->mgf1md) == NULL) { - LOGE("Use pkcs1_oaep padding, but mgf1md is NULL"); - return HCF_INVALID_PARAMS; + if (params->paddingMode == HCF_OPENSSL_RSA_PKCS1_OAEP_PADDING) { + EVP_MD *md = NULL; + EVP_MD *mgf1md = NULL; + (void)GetOpensslDigestAlg(params->md, &md); + (void)GetOpensslDigestAlg(params->mgf1md, &mgf1md); + if (md == NULL) { + LOGE("Use pkcs1_oaep padding, but md is NULL"); + return HCF_INVALID_PARAMS; + } + if (mgf1md == NULL) { + LOGE("Use pkcs1_oaep padding, but mgf1md is NULL"); + return HCF_INVALID_PARAMS; + } } return HCF_SUCCESS; } HcfResult HcfCipherRsaCipherSpiCreate(CipherAttr *params, HcfCipherGeneratorSpi **generator) { - LOGI("Start create rsa cipher spiObj."); if (generator == NULL || params == NULL) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -327,12 +525,15 @@ HcfResult HcfCipherRsaCipherSpiCreate(CipherAttr *params, HcfCipherGeneratorSpi } returnImpl->super.init = EngineInit; - returnImpl->super.update = EngineUpdata; + returnImpl->super.update = EngineUpdate; returnImpl->super.doFinal = EngineDoFinal; + returnImpl->super.setCipherSpecUint8Array = SetRsaCipherSpecUint8Array; + returnImpl->super.getCipherSpecString = GetRsaCipherSpecString; + returnImpl->super.getCipherSpecUint8Array = GetRsaCipherSpecUint8Array; returnImpl->super.base.destroy = EngineDestroySpiImpl; returnImpl->super.base.getClass = EngineGetClass; returnImpl->initFlag = UNINITIALIZED; *generator = (HcfCipherGeneratorSpi *)returnImpl; - LOGI("Rsa Cipher create success."); + LOGD("Rsa Cipher create success."); return HCF_SUCCESS; -} +} \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c index 958ffa9..98f66bd 100644 --- a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c @@ -15,6 +15,7 @@ #include "mac_openssl.h" +#include "openssl_adapter.h" #include "sym_common_defines.h" #include "openssl_common.h" #include "securec.h" @@ -23,8 +24,6 @@ #include "config.h" #include "utils.h" -#include - typedef struct { HcfMacSpi base; @@ -50,15 +49,15 @@ static HMAC_CTX *OpensslGetMacCtx(HcfMacSpi *self) static const EVP_MD *OpensslGetMacAlgoFromString(const char *mdName) { if (strcmp(mdName, "SHA1") == 0) { - return EVP_sha1(); + return Openssl_EVP_sha1(); } else if (strcmp(mdName, "SHA224") == 0) { - return EVP_sha224(); + return Openssl_EVP_sha224(); } else if (strcmp(mdName, "SHA256") == 0) { - return EVP_sha256(); + return Openssl_EVP_sha256(); } else if (strcmp(mdName, "SHA384") == 0) { - return EVP_sha384(); + return Openssl_EVP_sha384(); } else if (strcmp(mdName, "SHA512") == 0) { - return EVP_sha512(); + return Openssl_EVP_sha512(); } return NULL; } @@ -83,7 +82,7 @@ static HcfResult OpensslEngineInitMac(HcfMacSpi *self, const HcfSymKey *key) return HCF_INVALID_PARAMS; } const EVP_MD *mdfunc = OpensslGetMacAlgoFromString(((HcfMacSpiImpl *)self)->opensslAlgoName); - int32_t ret = HMAC_Init_ex(OpensslGetMacCtx(self), keyBlob.data, keyBlob.len, mdfunc, NULL); + int32_t ret = Openssl_HMAC_Init_ex(OpensslGetMacCtx(self), keyBlob.data, keyBlob.len, mdfunc, NULL); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("HMAC_Init_ex return error!"); HcfPrintOpensslError(); @@ -114,7 +113,7 @@ static HcfResult OpensslEngineDoFinalMac(HcfMacSpi *self, HcfBlob *output) } unsigned char outputBuf[EVP_MAX_MD_SIZE]; uint32_t outputLen; - int32_t ret = HMAC_Final(OpensslGetMacCtx(self), outputBuf, &outputLen); + int32_t ret = Openssl_HMAC_Final(OpensslGetMacCtx(self), outputBuf, &outputLen); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("HMAC_Final return error!"); HcfPrintOpensslError(); @@ -136,7 +135,7 @@ static uint32_t OpensslEngineGetMacLength(HcfMacSpi *self) LOGE("The CTX is NULL!"); return HCF_OPENSSL_INVALID_MAC_LEN; } - return HMAC_size(OpensslGetMacCtx(self)); + return Openssl_HMAC_size(OpensslGetMacCtx(self)); } static void OpensslDestroyMac(HcfObjectBase *self) @@ -150,7 +149,7 @@ static void OpensslDestroyMac(HcfObjectBase *self) return; } if (OpensslGetMacCtx((HcfMacSpi *)self) != NULL) { - HMAC_CTX_free(OpensslGetMacCtx((HcfMacSpi *)self)); + Openssl_HMAC_CTX_free(OpensslGetMacCtx((HcfMacSpi *)self)); } HcfFree(self); } @@ -169,9 +168,9 @@ HcfResult OpensslMacSpiCreate(const char *opensslAlgoName, HcfMacSpi **spiObj) if (strcpy_s(returnSpiImpl->opensslAlgoName, HCF_MAX_ALGO_NAME_LEN, opensslAlgoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnSpiImpl); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } - returnSpiImpl->ctx = HMAC_CTX_new(); + returnSpiImpl->ctx = Openssl_HMAC_CTX_new(); if (returnSpiImpl->ctx == NULL) { LOGE("Failed to create ctx!"); HcfFree(returnSpiImpl); diff --git a/plugin/openssl_plugin/crypto_operation/key_agreement/src/ecdh_openssl.c b/plugin/openssl_plugin/crypto_operation/key_agreement/src/ecdh_openssl.c index 2ab284a..ba8af2d 100644 --- a/plugin/openssl_plugin/crypto_operation/key_agreement/src/ecdh_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/key_agreement/src/ecdh_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -28,62 +28,47 @@ typedef struct { HcfKeyAgreementSpi base; - - int32_t curveId; } HcfKeyAgreementSpiEcdhOpensslImpl; -static EVP_PKEY *NewPKeyByEccPubKey(int32_t curveId, HcfOpensslEccPubKey *publicKey) +static EVP_PKEY *AssignEcKeyToPkey(EC_KEY *ecKey) { - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(curveId); - if (ecKey == NULL) { - HcfPrintOpensslError(); - return NULL; - } - if (Openssl_EC_KEY_set_public_key(ecKey, (publicKey->pk)) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return NULL; - } EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); if (pKey == NULL) { HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); return NULL; } if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); Openssl_EVP_PKEY_free(pKey); - Openssl_EC_KEY_free(ecKey); return NULL; } return pKey; } -static EVP_PKEY *NewPKeyByEccPriKey(int32_t curveId, HcfOpensslEccPriKey *privateKey) +static EVP_PKEY *NewPKeyByEccPubKey(HcfOpensslEccPubKey *publicKey) { - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(curveId); + EC_KEY *ecKey = Openssl_EC_KEY_dup(publicKey->ecKey); if (ecKey == NULL) { - HcfPrintOpensslError(); return NULL; } - if (Openssl_EC_KEY_set_private_key(ecKey, (privateKey->sk)) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - EC_KEY_free(ecKey); - return NULL; - } - EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); - if (pKey == NULL) { - HcfPrintOpensslError(); + EVP_PKEY *res = AssignEcKeyToPkey(ecKey); + if (res == NULL) { Openssl_EC_KEY_free(ecKey); + } + return res; +} + +static EVP_PKEY *NewPKeyByEccPriKey(HcfOpensslEccPriKey *privateKey) +{ + EC_KEY *ecKey = Openssl_EC_KEY_dup(privateKey->ecKey); + if (ecKey == NULL) { return NULL; } - if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - Openssl_EVP_PKEY_free(pKey); + EVP_PKEY *res = AssignEcKeyToPkey(ecKey); + if (res == NULL) { Openssl_EC_KEY_free(ecKey); - return NULL; } - return pKey; + return res; } static HcfResult EcdhDerive(EVP_PKEY *priPKey, EVP_PKEY *pubPKey, HcfBlob *returnSecret) @@ -130,11 +115,10 @@ static HcfResult EcdhDerive(EVP_PKEY *priPKey, EVP_PKEY *pubPKey, HcfBlob *retur } returnSecret->data = secretData; - returnSecret->len = (uint32_t)actualLen; + returnSecret->len = actualLen; return HCF_SUCCESS; } -// export interfaces static const char *GetEcdhClass(void) { return "HcfKeyAgreement.HcfKeyAgreementSpiEcdhOpensslImpl"; @@ -154,7 +138,6 @@ static void DestroyEcdh(HcfObjectBase *self) static HcfResult EngineGenerateSecret(HcfKeyAgreementSpi *self, HcfPriKey *priKey, HcfPubKey *pubKey, HcfBlob *returnSecret) { - LOGI("start ..."); if ((self == NULL) || (priKey == NULL) || (pubKey == NULL) || (returnSecret == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -165,21 +148,21 @@ static HcfResult EngineGenerateSecret(HcfKeyAgreementSpi *self, HcfPriKey *priKe return HCF_INVALID_PARAMS; } - HcfKeyAgreementSpiEcdhOpensslImpl *impl = (HcfKeyAgreementSpiEcdhOpensslImpl *)self; - EVP_PKEY *priPKey = NewPKeyByEccPriKey(impl->curveId, (HcfOpensslEccPriKey *)priKey); + EVP_PKEY *priPKey = NewPKeyByEccPriKey((HcfOpensslEccPriKey *)priKey); if (priPKey == NULL) { + LOGE("Gen EVP_PKEY priKey failed"); return HCF_ERR_CRYPTO_OPERATION; } - EVP_PKEY *pubPKey = NewPKeyByEccPubKey(impl->curveId, (HcfOpensslEccPubKey *)pubKey); + EVP_PKEY *pubPKey = NewPKeyByEccPubKey((HcfOpensslEccPubKey *)pubKey); if (pubPKey == NULL) { + LOGE("Gen EVP_PKEY pubKey failed"); EVP_PKEY_free(priPKey); return HCF_ERR_CRYPTO_OPERATION; } - int32_t res = EcdhDerive(priPKey, pubPKey, returnSecret); + HcfResult res = EcdhDerive(priPKey, pubPKey, returnSecret); Openssl_EVP_PKEY_free(priPKey); Openssl_EVP_PKEY_free(pubPKey); - LOGI("end ..."); return res; } @@ -189,10 +172,6 @@ HcfResult HcfKeyAgreementSpiEcdhCreate(HcfKeyAgreementParams *params, HcfKeyAgre LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } - int32_t curveId; - if (GetOpensslCurveId(params->keyLen, &curveId) != HCF_SUCCESS) { - return HCF_INVALID_PARAMS; - } HcfKeyAgreementSpiEcdhOpensslImpl *returnImpl = (HcfKeyAgreementSpiEcdhOpensslImpl *)HcfMalloc( sizeof(HcfKeyAgreementSpiEcdhOpensslImpl), 0); @@ -203,7 +182,6 @@ HcfResult HcfKeyAgreementSpiEcdhCreate(HcfKeyAgreementParams *params, HcfKeyAgre returnImpl->base.base.getClass = GetEcdhClass; returnImpl->base.base.destroy = DestroyEcdh; returnImpl->base.engineGenerateSecret = EngineGenerateSecret; - returnImpl->curveId = curveId; *returnObj = (HcfKeyAgreementSpi *)returnImpl; return HCF_SUCCESS; diff --git a/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c b/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c index a7aa197..f0f8607 100644 --- a/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c @@ -15,6 +15,7 @@ #include "md_openssl.h" +#include "openssl_adapter.h" #include "openssl_common.h" #include "securec.h" #include "log.h" @@ -22,8 +23,6 @@ #include "config.h" #include "utils.h" -#include - typedef struct { HcfMdSpi base; @@ -49,17 +48,17 @@ static EVP_MD_CTX *OpensslGetMdCtx(HcfMdSpi *self) static const EVP_MD *OpensslGetMdAlgoFromString(const char *mdName) { if (strcmp(mdName, "SHA1") == 0) { - return EVP_sha1(); + return Openssl_EVP_sha1(); } else if (strcmp(mdName, "SHA224") == 0) { - return EVP_sha224(); + return Openssl_EVP_sha224(); } else if (strcmp(mdName, "SHA256") == 0) { - return EVP_sha256(); + return Openssl_EVP_sha256(); } else if (strcmp(mdName, "SHA384") == 0) { - return EVP_sha384(); + return Openssl_EVP_sha384(); } else if (strcmp(mdName, "SHA512") == 0) { - return EVP_sha512(); + return Openssl_EVP_sha512(); } else if (strcmp(mdName, "MD5") == 0) { - return EVP_md5(); + return Openssl_EVP_md5(); } return NULL; } @@ -87,7 +86,7 @@ static HcfResult OpensslEngineDoFinalMd(HcfMdSpi *self, HcfBlob *output) } unsigned char outputBuf[EVP_MAX_MD_SIZE]; uint32_t outputLen; - int32_t ret = EVP_DigestFinal_ex(localCtx, outputBuf, &outputLen); + int32_t ret = Openssl_EVP_DigestFinal_ex(localCtx, outputBuf, &outputLen); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("EVP_DigestFinal_ex return error!"); HcfPrintOpensslError(); @@ -109,7 +108,7 @@ static uint32_t OpensslEngineGetMdLength(HcfMdSpi *self) LOGE("The CTX is NULL!"); return HCF_OPENSSL_INVALID_MD_LEN; } - int32_t size = EVP_MD_CTX_size(OpensslGetMdCtx(self)); + int32_t size = Openssl_EVP_MD_CTX_size(OpensslGetMdCtx(self)); if (size < 0) { LOGE("Get the overflow path length in openssl!"); return HCF_OPENSSL_INVALID_MD_LEN; @@ -128,7 +127,7 @@ static void OpensslDestroyMd(HcfObjectBase *self) return; } if (OpensslGetMdCtx((HcfMdSpi *)self) != NULL) { - EVP_MD_CTX_free(OpensslGetMdCtx((HcfMdSpi *)self)); + Openssl_EVP_MD_CTX_free(OpensslGetMdCtx((HcfMdSpi *)self)); } HcfFree(self); } @@ -144,18 +143,18 @@ HcfResult OpensslMdSpiCreate(const char *opensslAlgoName, HcfMdSpi **spiObj) LOGE("Failed to allocate returnImpl memory!"); return HCF_ERR_MALLOC; } - returnSpiImpl->ctx = EVP_MD_CTX_new(); + returnSpiImpl->ctx = Openssl_EVP_MD_CTX_new(); if (returnSpiImpl->ctx == NULL) { LOGE("Failed to create ctx!"); HcfFree(returnSpiImpl); return HCF_ERR_MALLOC; } const EVP_MD *mdfunc = OpensslGetMdAlgoFromString(opensslAlgoName); - int32_t ret = EVP_DigestInit_ex(returnSpiImpl->ctx, mdfunc, NULL); + int32_t ret = Openssl_EVP_DigestInit_ex(returnSpiImpl->ctx, mdfunc, NULL); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("Failed to init MD!"); HcfFree(returnSpiImpl); - EVP_MD_CTX_free(returnSpiImpl->ctx); + Openssl_EVP_MD_CTX_free(returnSpiImpl->ctx); return HCF_ERR_CRYPTO_OPERATION; } returnSpiImpl->base.base.getClass = OpensslGetMdClass; diff --git a/plugin/openssl_plugin/rand/inc/rand_openssl.h b/plugin/openssl_plugin/crypto_operation/rand/inc/rand_openssl.h similarity index 100% rename from plugin/openssl_plugin/rand/inc/rand_openssl.h rename to plugin/openssl_plugin/crypto_operation/rand/inc/rand_openssl.h diff --git a/plugin/openssl_plugin/rand/src/rand_openssl.c b/plugin/openssl_plugin/crypto_operation/rand/src/rand_openssl.c similarity index 81% rename from plugin/openssl_plugin/rand/src/rand_openssl.c rename to plugin/openssl_plugin/crypto_operation/rand/src/rand_openssl.c index 91c0a3b..dff9713 100644 --- a/plugin/openssl_plugin/rand/src/rand_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/rand/src/rand_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -15,14 +15,13 @@ #include "rand_openssl.h" +#include "openssl_adapter.h" #include "openssl_common.h" #include "securec.h" #include "log.h" #include "memory.h" #include "utils.h" -#include - typedef struct { HcfRandSpi base; } HcfRandSpiImpl; @@ -35,7 +34,7 @@ static const char *GetRandOpenSSLClass(void) static HcfResult OpensslGenerateRandom(HcfRandSpi *self, int32_t numBytes, HcfBlob *random) { unsigned char randBuf[numBytes]; - int32_t ret = RAND_priv_bytes(randBuf, numBytes); + int32_t ret = Openssl_RAND_priv_bytes(randBuf, numBytes); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("RAND_bytes return error!"); HcfPrintOpensslError(); @@ -51,9 +50,23 @@ static HcfResult OpensslGenerateRandom(HcfRandSpi *self, int32_t numBytes, HcfBl return HCF_SUCCESS; } +static const char *GetRandAlgoName(HcfRandSpi *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetRandOpenSSLClass())) { + LOGE("Class is not match."); + return NULL; + } + + return OPENSSL_RAND_ALGORITHM; +} + static void OpensslSetSeed(HcfRandSpi *self, HcfBlob *seed) { - RAND_seed(seed->data, seed->len); + Openssl_RAND_seed(seed->data, seed->len); } static void DestroyRandOpenssl(HcfObjectBase *self) @@ -84,6 +97,7 @@ HcfResult HcfRandSpiCreate(HcfRandSpi **spiObj) returnSpiImpl->base.base.destroy = DestroyRandOpenssl; returnSpiImpl->base.engineGenerateRandom = OpensslGenerateRandom; returnSpiImpl->base.engineSetSeed = OpensslSetSeed; + returnSpiImpl->base.engineGetAlgoName = GetRandAlgoName; *spiObj = (HcfRandSpi *)returnSpiImpl; return HCF_SUCCESS; } \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h b/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h new file mode 100644 index 0000000..04158d8 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 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 HCF_DSA_OPENSSL_H +#define HCF_DSA_OPENSSL_H + +#include "signature_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfSignSpiDsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj); +HcfResult HcfVerifySpiDsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/signature/inc/signature_rsa_openssl.h b/plugin/openssl_plugin/crypto_operation/signature/inc/signature_rsa_openssl.h index 512e588..b58f0df 100644 --- a/plugin/openssl_plugin/crypto_operation/signature/inc/signature_rsa_openssl.h +++ b/plugin/openssl_plugin/crypto_operation/signature/inc/signature_rsa_openssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c new file mode 100644 index 0000000..a3af017 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c @@ -0,0 +1,623 @@ +/* + * Copyright (C) 2023 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 "dsa_openssl.h" + +#include + +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_common.h" +#include "openssl_class.h" +#include "utils.h" + +#define OPENSSL_DSA_SIGN_CLASS "OPENSSL.DSA.SIGN" +#define OPENSSL_DSA_VERIFY_CLASS "OPENSSL.DSA.VERIFY" + +typedef struct { + HcfSignSpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *mdCtx; + + EVP_PKEY_CTX *pkeyCtx; + + CryptoStatus status; +} HcfSignSpiDsaOpensslImpl; + +typedef struct { + HcfVerifySpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *mdCtx; + + EVP_PKEY_CTX *pkeyCtx; + + CryptoStatus status; +} HcfVerifySpiDsaOpensslImpl; + +static const char *GetDsaSignClass(void) +{ + return OPENSSL_DSA_SIGN_CLASS; +} + +static const char *GetDsaVerifyClass(void) +{ + return OPENSSL_DSA_VERIFY_CLASS; +} + +static bool IsSignInitInputValid(HcfSignSpi *self, HcfPriKey *privateKey) +{ + if ((self == NULL) || (privateKey == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) || + (!IsClassMatch((HcfObjectBase *)privateKey, OPENSSL_DSA_PRIKEY_CLASS))) { + return false; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return false; + } + return true; +} + +static bool IsVerifyInitInputValid(HcfVerifySpi *self, HcfPubKey *publicKey) +{ + if ((self == NULL) || (publicKey == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) || + (!IsClassMatch((HcfObjectBase *)publicKey, OPENSSL_DSA_PUBKEY_CLASS))) { + return false; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return false; + } + return true; +} + +static bool IsSignDoFinalInputValid(HcfSignSpi *self, HcfBlob *returnSignatureData) +{ + if ((self == NULL) || (returnSignatureData == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) { + return false; + } + return true; +} + +static bool IsVerifyDoFinalInputValid(HcfVerifySpi *self, HcfBlob *signatureData) +{ + if ((self == NULL) || (!IsBlobValid(signatureData))) { + LOGE("Invalid input parameter."); + return false; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) { + return false; + } + return true; +} + +static void DestroyDsaSign(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + + if (!IsClassMatch(self, GetDsaSignClass())) { + return; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->mdCtx != NULL) { + Openssl_EVP_MD_CTX_free(impl->mdCtx); + impl->mdCtx = NULL; + } + if (impl->pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + } + HcfFree(impl); +} + +static void DestroyDsaVerify(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaVerifyClass())) { + return; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->mdCtx != NULL) { + Openssl_EVP_MD_CTX_free(impl->mdCtx); + impl->mdCtx = NULL; + } + if (impl->pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + } + HcfFree(impl); +} + +static EVP_PKEY *CreateDsaEvpKeyByDsa(HcfKey *key, bool isSign) +{ + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); + if (pKey == NULL) { + LOGE("EVP_PKEY_new fail"); + HcfPrintOpensslError(); + return NULL; + } + DSA *dsa = isSign ? ((HcfOpensslDsaPriKey *)key)->sk : ((HcfOpensslDsaPubKey *)key)->pk; + if (Openssl_EVP_PKEY_set1_DSA(pKey, dsa) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP_PKEY_set1_DSA fail"); + HcfPrintOpensslError(); + EVP_PKEY_free(pKey); + return NULL; + } + return pKey; +} + +static HcfResult EngineDsaSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) +{ + (void)params; + if (!IsSignInitInputValid(self, privateKey)) { + return HCF_INVALID_PARAMS; + } + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (Openssl_EVP_DigestSignInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) +{ + (void)params; + if (!IsSignInitInputValid(self, privateKey)) { + return HCF_INVALID_PARAMS; + } + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + + impl->pkeyCtx = Openssl_EVP_PKEY_CTX_new(pKey, NULL); + if (impl->pkeyCtx == NULL) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_sign_init(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) +{ + (void)params; + if (!IsVerifyInitInputValid(self, publicKey)) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_DigestVerifyInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyWithoutDigestInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) +{ + (void)params; + if (!IsVerifyInitInputValid(self, publicKey)) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false); + if (pKey == NULL) { + LOGE("Create dsa evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->pkeyCtx = Openssl_EVP_PKEY_CTX_new(pKey, NULL); + if (impl->pkeyCtx == NULL) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_verify_init(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignUpdate(HcfSignSpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Sign object has not been initialized."); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestUpdate(HcfSignSpi *self, HcfBlob *data) +{ + (void)self; + (void)data; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Verify object has not been initialized."); + return HCF_INVALID_PARAMS; + } + + if (Openssl_EVP_DigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyWithoutDigestUpdate(HcfVerifySpi *self, HcfBlob *data) +{ + (void)self; + (void)data; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if (!IsSignDoFinalInputValid(self, returnSignatureData)) { + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return HCF_INVALID_PARAMS; + } + size_t maxLen; + if (Openssl_EVP_DigestSignFinal(impl->mdCtx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0); + if (signatureData == NULL) { + LOGE("Failed to allocate signatureData memory!"); + return HCF_ERR_MALLOC; + } + size_t actualLen = maxLen; + if (Openssl_EVP_DigestSignFinal(impl->mdCtx, signatureData, &actualLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + if (actualLen > maxLen) { + LOGE("Signature data too long."); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + + returnSignatureData->data = signatureData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if (!IsSignDoFinalInputValid(self, returnSignatureData)) { + return HCF_INVALID_PARAMS; + } + if (!IsBlobValid(data)) { + LOGE("Src data is invalid."); + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status != READY) { + LOGE("Not init yet."); + return HCF_INVALID_PARAMS; + } + size_t maxLen; + if (Openssl_EVP_PKEY_sign(impl->pkeyCtx, NULL, &maxLen, + (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0); + if (signatureData == NULL) { + LOGE("Failed to allocate signatureData memory!"); + return HCF_ERR_MALLOC; + } + size_t actualLen = maxLen; + if (Openssl_EVP_PKEY_sign(impl->pkeyCtx, signatureData, &actualLen, + (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + if (actualLen > maxLen) { + LOGE("Signature data too long."); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + + returnSignatureData->data = signatureData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static bool EngineDsaVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) +{ + if (!IsVerifyDoFinalInputValid(self, signatureData)) { + return false; + } + + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl update failed."); + HcfPrintOpensslError(); + return false; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return false; + } + + if (Openssl_EVP_DigestVerifyFinal(impl->mdCtx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + return true; +} + +static bool EngineDsaVerifyWithoutDigestDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) +{ + if (!IsVerifyDoFinalInputValid(self, signatureData)) { + return false; + } + if (!IsBlobValid(data)) { + LOGE("Src data is invalid."); + return false; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status != READY) { + LOGE("Not init yet."); + return false; + } + + if (Openssl_EVP_PKEY_verify(impl->pkeyCtx, signatureData->data, + signatureData->len, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + return true; +} + +HcfResult EngineSetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen) +{ + (void)self; + (void)item; + (void)saltLen; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineSetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen) +{ + (void)self; + (void)item; + (void)saltLen; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt) +{ + (void)self; + (void)item; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt) +{ + (void)self; + (void)item; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetSignDsaSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString) +{ + (void)self; + (void)item; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetVerifyDsaSpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString) +{ + (void)self; + (void)item; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +HcfResult HcfSignSpiDsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfSignSpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate impl memroy!"); + return HCF_ERR_MALLOC; + } + + EVP_MD *digestAlg = NULL; + + if (params->md == HCF_OPENSSL_DIGEST_NONE) { + impl->base.engineInit = EngineDsaSignWithoutDigestInit; + impl->base.engineUpdate = EngineDsaSignWithoutDigestUpdate; + impl->base.engineSign = EngineDsaSignWithoutDigestDoFinal; + } else { + HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg); + if (ret != HCF_SUCCESS) { + HcfFree(impl); + return HCF_INVALID_PARAMS; + } + impl->base.engineInit = EngineDsaSignInit; + impl->base.engineUpdate = EngineDsaSignUpdate; + impl->base.engineSign = EngineDsaSignDoFinal; + impl->mdCtx = Openssl_EVP_MD_CTX_new(); + if (impl->mdCtx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(impl); + return HCF_ERR_MALLOC; + } + } + impl->base.base.getClass = GetDsaSignClass; + impl->base.base.destroy = DestroyDsaSign; + impl->base.engineSetSignSpecInt = EngineSetSignDsaSpecInt; + impl->base.engineGetSignSpecInt = EngineGetSignDsaSpecInt; + impl->base.engineGetSignSpecString = EngineGetSignDsaSpecString; + impl->status = UNINITIALIZED; + impl->digestAlg = digestAlg; + *returnObj = (HcfSignSpi *)impl; + return HCF_SUCCESS; +} + +HcfResult HcfVerifySpiDsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfVerifySpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate impl memroy!"); + return HCF_ERR_MALLOC; + } + + EVP_MD *digestAlg = NULL; + if (params->md == HCF_OPENSSL_DIGEST_NONE) { + impl->base.engineInit = EngineDsaVerifyWithoutDigestInit; + impl->base.engineUpdate = EngineDsaVerifyWithoutDigestUpdate; + impl->base.engineVerify = EngineDsaVerifyWithoutDigestDoFinal; + } else { + HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg); + if (ret != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + impl->base.engineInit = EngineDsaVerifyInit; + impl->base.engineUpdate = EngineDsaVerifyUpdate; + impl->base.engineVerify = EngineDsaVerifyDoFinal; + impl->mdCtx = Openssl_EVP_MD_CTX_new(); + if (impl->mdCtx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(impl); + return HCF_ERR_MALLOC; + } + } + impl->base.base.getClass = GetDsaVerifyClass; + impl->base.base.destroy = DestroyDsaVerify; + impl->base.engineSetVerifySpecInt = EngineSetVerifyDsaSpecInt; + impl->base.engineGetVerifySpecInt = EngineGetVerifyDsaSpecInt; + impl->base.engineGetVerifySpecString = EngineGetVerifyDsaSpecString; + impl->digestAlg = digestAlg; + impl->status = UNINITIALIZED; + + *returnObj = (HcfVerifySpi *)impl; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c index 8701015..43214bb 100644 --- a/plugin/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c @@ -29,12 +29,6 @@ #define OPENSSL_ECC_SIGN_CLASS "OPENSSL.ECC.SIGN" #define OPENSSL_ECC_VERIFY_CLASS "OPENSSL.ECC.VERIFY" -typedef enum { - UNINITIALIZED = 0, - INITIALIZED = 1, - READY = 2, -} EcdsaStatus; - typedef struct { HcfSignSpi base; @@ -42,9 +36,7 @@ typedef struct { EVP_MD_CTX *ctx; - int32_t curveId; - - EcdsaStatus status; + CryptoStatus status; } HcfSignSpiEcdsaOpensslImpl; typedef struct { @@ -54,15 +46,14 @@ typedef struct { EVP_MD_CTX *ctx; - int32_t curveId; - - EcdsaStatus status; + CryptoStatus status; } HcfVerifySpiEcdsaOpensslImpl; static bool IsDigestAlgValid(uint32_t alg) { - if ((alg == HCF_OPENSSL_DIGEST_SHA1) || (alg == HCF_OPENSSL_DIGEST_SHA224) || (alg == HCF_OPENSSL_DIGEST_SHA256) || - (alg == HCF_OPENSSL_DIGEST_SHA384) || (alg == HCF_OPENSSL_DIGEST_SHA512)) { + if ((alg == HCF_OPENSSL_DIGEST_SHA1) || (alg == HCF_OPENSSL_DIGEST_SHA224) || + (alg == HCF_OPENSSL_DIGEST_SHA256) ||(alg == HCF_OPENSSL_DIGEST_SHA384) || + (alg == HCF_OPENSSL_DIGEST_SHA512)) { return true; } else { LOGE("Invalid digest num is %u.", alg); @@ -111,7 +102,6 @@ static void DestroyEcdsaVerify(HcfObjectBase *self) static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) { - LOGI("start ..."); (void)params; if ((self == NULL) || (privateKey == NULL)) { LOGE("Invalid input parameter."); @@ -127,16 +117,11 @@ static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriK LOGE("Repeated initialization is not allowed."); return HCF_INVALID_PARAMS; } - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(impl->curveId); + EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslEccPriKey *)privateKey)->ecKey); if (ecKey == NULL) { HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - if (Openssl_EC_KEY_set_private_key(ecKey, ((HcfOpensslEccPriKey *)privateKey)->sk) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; - } EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); if (pKey == NULL) { HcfPrintOpensslError(); @@ -145,8 +130,8 @@ static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriK } if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - Openssl_EVP_PKEY_free(pKey); Openssl_EC_KEY_free(ecKey); + Openssl_EVP_PKEY_free(pKey); return HCF_ERR_CRYPTO_OPERATION; } if (Openssl_EVP_DigestSignInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { @@ -156,13 +141,11 @@ static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriK } Openssl_EVP_PKEY_free(pKey); impl->status = INITIALIZED; - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) { - LOGI("start ..."); if ((self == NULL) || (!IsBlobValid(data))) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -180,13 +163,11 @@ static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) return HCF_ERR_CRYPTO_OPERATION; } impl->status = READY; - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) { - LOGI("start ..."); if ((self == NULL) || (returnSignatureData == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -231,13 +212,11 @@ static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *ret returnSignatureData->data = outData; returnSignatureData->len = (uint32_t)actualLen; - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) { - LOGI("start ..."); (void)params; if ((self == NULL) || (publicKey == NULL)) { LOGE("Invalid input parameter."); @@ -253,16 +232,11 @@ static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, Hcf LOGE("Repeated initialization is not allowed."); return HCF_INVALID_PARAMS; } - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(impl->curveId); + EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslEccPubKey *)publicKey)->ecKey); if (ecKey == NULL) { HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - if (Openssl_EC_KEY_set_public_key(ecKey, ((HcfOpensslEccPubKey *)publicKey)->pk) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; - } EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); if (pKey == NULL) { HcfPrintOpensslError(); @@ -271,8 +245,8 @@ static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, Hcf } if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - Openssl_EVP_PKEY_free(pKey); Openssl_EC_KEY_free(ecKey); + Openssl_EVP_PKEY_free(pKey); return HCF_ERR_CRYPTO_OPERATION; } if (Openssl_EVP_DigestVerifyInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { @@ -282,13 +256,11 @@ static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, Hcf } Openssl_EVP_PKEY_free(pKey); impl->status = INITIALIZED; - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) { - LOGI("start ..."); if ((self == NULL) || (!IsBlobValid(data))) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -307,13 +279,11 @@ static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) return HCF_ERR_CRYPTO_OPERATION; } impl->status = READY; - LOGI("end ..."); return HCF_SUCCESS; } static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) { - LOGI("start ..."); if ((self == NULL) || (!IsBlobValid(signatureData))) { LOGE("Invalid input parameter."); return false; @@ -338,7 +308,6 @@ static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *sign HcfPrintOpensslError(); return false; } - LOGI("end ..."); return true; } @@ -348,14 +317,15 @@ HcfResult HcfSignSpiEcdsaCreate(HcfSignatureParams *params, HcfSignSpi **returnO LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } - int32_t curveId; - if (GetOpensslCurveId(params->keyLen, &curveId) != HCF_SUCCESS) { + if (!IsDigestAlgValid(params->md)) { return HCF_INVALID_PARAMS; } - if (!IsDigestAlgValid(params->md)) { + EVP_MD *opensslAlg = NULL; + int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg); + if (ret != HCF_SUCCESS || opensslAlg == NULL) { + LOGE("Failed to Invalid digest!"); return HCF_INVALID_PARAMS; } - const EVP_MD *opensslAlg = GetOpensslDigestAlg(params->md); HcfSignSpiEcdsaOpensslImpl *returnImpl = (HcfSignSpiEcdsaOpensslImpl *)HcfMalloc( sizeof(HcfSignSpiEcdsaOpensslImpl), 0); @@ -368,7 +338,6 @@ HcfResult HcfSignSpiEcdsaCreate(HcfSignatureParams *params, HcfSignSpi **returnO returnImpl->base.engineInit = EngineSignInit; returnImpl->base.engineUpdate = EngineSignUpdate; returnImpl->base.engineSign = EngineSignDoFinal; - returnImpl->curveId = curveId; returnImpl->digestAlg = opensslAlg; returnImpl->status = UNINITIALIZED; returnImpl->ctx = Openssl_EVP_MD_CTX_new(); @@ -388,14 +357,15 @@ HcfResult HcfVerifySpiEcdsaCreate(HcfSignatureParams *params, HcfVerifySpi **ret LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } - int32_t curveId; - if (GetOpensslCurveId(params->keyLen, &curveId) != HCF_SUCCESS) { + if (!IsDigestAlgValid(params->md)) { return HCF_INVALID_PARAMS; } - if (!IsDigestAlgValid(params->md)) { + EVP_MD *opensslAlg = NULL; + int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg); + if (ret != HCF_SUCCESS || opensslAlg == NULL) { + LOGE("Failed to Invalid digest!"); return HCF_INVALID_PARAMS; } - const EVP_MD *opensslAlg = GetOpensslDigestAlg(params->md); HcfVerifySpiEcdsaOpensslImpl *returnImpl = (HcfVerifySpiEcdsaOpensslImpl *)HcfMalloc( sizeof(HcfVerifySpiEcdsaOpensslImpl), 0); @@ -408,7 +378,6 @@ HcfResult HcfVerifySpiEcdsaCreate(HcfSignatureParams *params, HcfVerifySpi **ret returnImpl->base.engineInit = EngineVerifyInit; returnImpl->base.engineUpdate = EngineVerifyUpdate; returnImpl->base.engineVerify = EngineVerifyDoFinal; - returnImpl->curveId = curveId; returnImpl->digestAlg = opensslAlg; returnImpl->status = UNINITIALIZED; returnImpl->ctx = Openssl_EVP_MD_CTX_new(); diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c index a07148a..c6389f9 100644 --- a/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -14,29 +14,41 @@ */ #include "signature_rsa_openssl.h" + #include + #include +#include "securec.h" + #include "algorithm_parameter.h" #include "log.h" #include "memory.h" +#include "openssl_adapter.h" #include "openssl_class.h" #include "openssl_common.h" #include "rsa_openssl_common.h" #include "utils.h" +#define PSS_TRAILER_FIELD_SUPPORTED_INT 1 +#define PSS_SALTLEN_INVALID_INIT (-9) + typedef struct { HcfSignSpi base; EVP_MD_CTX *mdctx; + EVP_PKEY_CTX *ctx; + int32_t padding; int32_t md; int32_t mgf1md; - InitFlag initFlag; + CryptoStatus initFlag; + + int32_t saltLen; } HcfSignSpiRsaOpensslImpl; typedef struct { @@ -44,13 +56,17 @@ typedef struct { EVP_MD_CTX *mdctx; + EVP_PKEY_CTX *ctx; + int32_t padding; int32_t md; int32_t mgf1md; - InitFlag initFlag; + CryptoStatus initFlag; + + int32_t saltLen; } HcfVerifySpiRsaOpensslImpl; static const char *GetRsaSignClass(void) @@ -74,11 +90,12 @@ static void DestroyRsaSign(HcfObjectBase *self) return; } HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; - EVP_MD_CTX_destroy(impl->mdctx); + Openssl_EVP_MD_CTX_free(impl->mdctx); impl->mdctx = NULL; + // ctx will be freed with mdctx HcfFree(impl); impl = NULL; - LOGI("DestroyRsaSign success."); + LOGD("DestroyRsaSign success."); } static void DestroyRsaVerify(HcfObjectBase *self) @@ -92,11 +109,11 @@ static void DestroyRsaVerify(HcfObjectBase *self) return; } HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; - EVP_MD_CTX_destroy(impl->mdctx); + Openssl_EVP_MD_CTX_free(impl->mdctx); impl->mdctx = NULL; HcfFree(impl); impl = NULL; - LOGI("DestroyRsaVerify success."); + LOGD("DestroyRsaVerify success."); } static HcfResult CheckInitKeyType(HcfKey *key, bool signing) @@ -118,11 +135,40 @@ static HcfResult CheckInitKeyType(HcfKey *key, bool signing) static EVP_PKEY *InitRsaEvpKey(const HcfKey *key, bool signing) { RSA *rsa = NULL; - if (DuplicateRsa(signing ? ((HcfOpensslRsaPriKey *)key)->sk : ((HcfOpensslRsaPubKey *)key)->pk, signing, &rsa) - != HCF_SUCCESS) { - LOGE("dup pub rsa fail."); + if (signing == true) { + if (DuplicateRsa(((HcfOpensslRsaPriKey *)key)->sk, signing, &rsa) != HCF_SUCCESS) { + RSA *tmp = Openssl_RSA_new(); + if (tmp == NULL) { + LOGE("malloc rsa failed"); + return NULL; + } + const BIGNUM *n = NULL; + const BIGNUM *e = NULL; + const BIGNUM *d = NULL; + Openssl_RSA_get0_key(((HcfOpensslRsaPriKey *)key)->sk, &n, &e, &d); + if (n == NULL || e == NULL || d == NULL) { + LOGE("get key attribute fail"); + return NULL; + } + BIGNUM *dupN = Openssl_BN_dup(n); + BIGNUM *dupE = Openssl_BN_dup(e); + BIGNUM *dupD = Openssl_BN_dup(d); + if (Openssl_RSA_set0_key(tmp, dupN, dupE, dupD) != HCF_OPENSSL_SUCCESS) { + LOGE("assign RSA n, e, d failed"); + Openssl_BN_clear_free(dupN); + Openssl_BN_clear_free(dupE); + Openssl_BN_clear_free(dupD); + return NULL; + } + LOGE("duplicate RSA pri key success"); + rsa = tmp; + } + } else if (signing == false) { + if (DuplicateRsa(((HcfOpensslRsaPubKey *)key)->pk, signing, &rsa) != HCF_SUCCESS) { + LOGE("dup pub RSA fail"); return NULL; } + } if (rsa == NULL) { LOGE("The Key has lost."); return NULL; @@ -131,27 +177,27 @@ static EVP_PKEY *InitRsaEvpKey(const HcfKey *key, bool signing) if (pkey == NULL) { LOGE("New evp pkey failed"); HcfPrintOpensslError(); - RSA_free(rsa); + Openssl_RSA_free(rsa); return NULL; } return pkey; } +// the params has been checked in the CheckSignatureParams static HcfResult SetPaddingAndDigest(EVP_PKEY_CTX *ctx, int32_t hcfPadding, int32_t md, int32_t mgf1md) { int32_t opensslPadding = 0; - if (GetOpensslPadding(hcfPadding, &opensslPadding) != HCF_SUCCESS) { - LOGE("getpadding fail."); - return HCF_INVALID_PARAMS; - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_PKEY_CTX_set_rsa_padding fail"); + (void)GetOpensslPadding(hcfPadding, &opensslPadding); + if (Openssl_EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_PKEY_CTX_set_rsa_padding fail"); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } if (hcfPadding == HCF_OPENSSL_RSA_PSS_PADDING) { - LOGI("padding is pss, set mgf1 md"); - if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, GetOpensslDigestAlg(mgf1md)) != HCF_OPENSSL_SUCCESS) { + LOGD("padding is pss, set mgf1 md"); + EVP_MD *opensslAlg = NULL; + (void)GetOpensslDigestAlg(mgf1md, &opensslAlg); + if (Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, opensslAlg) != HCF_OPENSSL_SUCCESS) { LOGE("EVP_PKEY_CTX_set_rsa_mgf1_md fail"); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; @@ -169,23 +215,35 @@ static HcfResult SetSignParams(HcfSignSpiRsaOpensslImpl *impl, HcfPriKey *privat return HCF_ERR_CRYPTO_OPERATION; } EVP_PKEY_CTX *ctx = NULL; - if (EVP_DigestSignInit(impl->mdctx, &ctx, GetOpensslDigestAlg(impl->md), NULL, dupKey) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestSignInit fail."); - EVP_PKEY_free(dupKey); + EVP_MD *opensslAlg = NULL; + (void)GetOpensslDigestAlg(impl->md, &opensslAlg); + if (opensslAlg == NULL) { + LOGE("Get openssl digest alg fail"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestSignInit(impl->mdctx, &ctx, opensslAlg, NULL, dupKey) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestSignInit fail."); + Openssl_EVP_PKEY_free(dupKey); return HCF_ERR_CRYPTO_OPERATION; } if (SetPaddingAndDigest(ctx, impl->padding, impl->md, impl->mgf1md) != HCF_SUCCESS) { LOGE("set padding and digest fail"); - EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_free(dupKey); return HCF_ERR_CRYPTO_OPERATION; } - EVP_PKEY_free(dupKey); + if (impl->saltLen != PSS_SALTLEN_INVALID_INIT) { + if (Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, impl->saltLen) != HCF_OPENSSL_SUCCESS) { + LOGE("get saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + } + impl->ctx = ctx; + Openssl_EVP_PKEY_free(dupKey); return HCF_SUCCESS; } static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) { - LOGI("EngineSignInit start"); if (self == NULL || privateKey == NULL) { LOGE("Invalid input params"); return HCF_INVALID_PARAMS; @@ -208,7 +266,6 @@ static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriK return HCF_ERR_CRYPTO_OPERATION; } impl->initFlag = INITIALIZED; - LOGI("EngineSignInit end"); return HCF_SUCCESS; } @@ -220,24 +277,36 @@ static HcfResult SetVerifyParams(HcfVerifySpiRsaOpensslImpl *impl, HcfPubKey *pu LOGE("InitRsaEvpKey fail."); return HCF_ERR_CRYPTO_OPERATION; } - if (EVP_DigestVerifyInit(impl->mdctx, &ctx, GetOpensslDigestAlg(impl->md), NULL, dupKey) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestVerifyInit fail."); + EVP_MD *opensslAlg = NULL; + (void)GetOpensslDigestAlg(impl->md, &opensslAlg); + if (opensslAlg == NULL) { + LOGE("Get openssl digest alg fail"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestVerifyInit(impl->mdctx, &ctx, opensslAlg, NULL, dupKey) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestVerifyInit fail."); HcfPrintOpensslError(); - EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_free(dupKey); return HCF_ERR_CRYPTO_OPERATION; } if (SetPaddingAndDigest(ctx, impl->padding, impl->md, impl->mgf1md) != HCF_SUCCESS) { LOGE("set padding and digest fail"); - EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_free(dupKey); return HCF_ERR_CRYPTO_OPERATION; } - EVP_PKEY_free(dupKey); + if (impl->saltLen != PSS_SALTLEN_INVALID_INIT) { + if (Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, impl->saltLen) != HCF_OPENSSL_SUCCESS) { + LOGE("get saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + } + impl->ctx = ctx; + Openssl_EVP_PKEY_free(dupKey); return HCF_SUCCESS; } static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) { - LOGI("EngineVerifyInit start"); if (self == NULL || publicKey == NULL) { LOGE("Invalid input params."); return HCF_INVALID_PARAMS; @@ -260,13 +329,11 @@ static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, Hcf return HCF_ERR_CRYPTO_OPERATION; } impl->initFlag = INITIALIZED; - LOGI("EngineVerifyInit end"); return HCF_SUCCESS; } static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) { - LOGI("start ..."); if ((self == NULL) || (data == NULL) || (data->data == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -280,17 +347,15 @@ static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) LOGE("The Sign has not been init"); return HCF_INVALID_PARAMS; } - if (EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestSignUpdate fail"); + if (Openssl_EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestSignUpdate fail"); return HCF_ERR_CRYPTO_OPERATION; } - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) { - LOGI("start ..."); if ((self == NULL) || (data == NULL) || (data->data == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -304,17 +369,15 @@ static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) LOGE("The Sign has not been init"); return HCF_INVALID_PARAMS; } - if (EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestSignUpdate fail"); + if (Openssl_EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestSignUpdate fail"); return HCF_ERR_CRYPTO_OPERATION; } - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) { - LOGI("EngineSign start"); if (self == NULL || returnSignatureData == NULL) { LOGE("Invalid input params."); return HCF_INVALID_PARAMS; @@ -329,25 +392,27 @@ static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSign return HCF_INVALID_PARAMS; } if (data != NULL && data->data != NULL) { - if (EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + if (Openssl_EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { LOGE("Dofinal update data fail."); return HCF_ERR_CRYPTO_OPERATION; } } size_t maxLen; - if (EVP_DigestSignFinal(impl->mdctx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestSignFinal fail"); + if (Openssl_EVP_DigestSignFinal(impl->mdctx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestSignFinal fail"); return HCF_ERR_CRYPTO_OPERATION; } + LOGD("sign maxLen is %d", maxLen); uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0); if (outData == NULL) { LOGE("Failed to allocate outData memory!"); return HCF_ERR_MALLOC; } size_t actualLen = maxLen; - if (EVP_DigestSignFinal(impl->mdctx, outData, &actualLen) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestSignFinal fail"); + if (Openssl_EVP_DigestSignFinal(impl->mdctx, outData, &actualLen) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestSignFinal fail"); HcfFree(outData); + HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } if (actualLen > maxLen) { @@ -359,13 +424,11 @@ static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSign returnSignatureData->data = outData; returnSignatureData->len = (uint32_t)actualLen; - LOGI("EngineSign end"); return HCF_SUCCESS; } static bool EngineVerify(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) { - LOGI("EngineVerify start"); if (self == NULL || signatureData == NULL || signatureData->data == NULL) { LOGE("Invalid input params"); return false; @@ -381,35 +444,269 @@ static bool EngineVerify(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureDa return false; } if (data != NULL && data->data != NULL) { - if (EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestVerifyUpdate fail"); + if (Openssl_EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestVerifyUpdate fail"); return false; } } - if (EVP_DigestVerifyFinal(impl->mdctx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) { - LOGE("EVP_DigestVerifyFinal fail"); + if (Openssl_EVP_DigestVerifyFinal(impl->mdctx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_DigestVerifyFinal fail"); return false; } - LOGI("EngineVerify end"); return true; } static HcfResult CheckSignatureParams(HcfSignatureParams *params) { - if (GetOpensslDigestAlg(params->md) == NULL) { + int32_t opensslPadding = 0; + if (GetOpensslPadding(params->padding, &opensslPadding) != HCF_SUCCESS) { + LOGE("getpadding fail."); + return HCF_INVALID_PARAMS; + } + if (opensslPadding != RSA_PKCS1_PADDING && opensslPadding != RSA_PKCS1_PSS_PADDING) { + LOGE("signature cannot use that padding mode"); + return HCF_INVALID_PARAMS; + } + EVP_MD *md = NULL; + (void)GetOpensslDigestAlg(params->md, &md); + if (md == NULL) { LOGE("Md is NULL"); return HCF_INVALID_PARAMS; } - if (params->padding == HCF_OPENSSL_RSA_PSS_PADDING && GetOpensslDigestAlg(params->mgf1md) == NULL) { - LOGE("Use pss padding, but mgf1md is NULL"); + if (params->padding == HCF_OPENSSL_RSA_PSS_PADDING) { + EVP_MD *mgf1md = NULL; + (void)GetOpensslDigestAlg(params->mgf1md, &mgf1md); + if (mgf1md == NULL) { + LOGE("Use pss padding, but mgf1md is NULL"); + return HCF_INVALID_PARAMS; + } + } + return HCF_SUCCESS; +} + +static HcfResult EngineSetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter"); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT) { + LOGE("Invalid sign spec item"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_SIGN_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (saltLen < 0) { + // RSA_PSS_SALTLEN_MAX_SIGN: max sign is old compatible max salt length for sign only + if (saltLen != RSA_PSS_SALTLEN_DIGEST && saltLen != RSA_PSS_SALTLEN_MAX_SIGN && + saltLen != RSA_PSS_SALTLEN_MAX) { + LOGE("Invalid salt Len %d", saltLen); + return HCF_INVALID_PARAMS; + } + } + HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + impl->saltLen = saltLen; + if (impl->initFlag == INITIALIZED) { + if (Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(impl->ctx, saltLen) != HCF_OPENSSL_SUCCESS) { + LOGE("set saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + } + LOGD("Set sign saltLen success"); + return HCF_SUCCESS; +} + +static HcfResult EngineGetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_SIGN_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_TRAILER_FIELD_INT && item != PSS_SALT_LEN_INT) { + LOGE("Invalid input spec"); + return HCF_INVALID_PARAMS; + } + HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + if (item == PSS_TRAILER_FIELD_INT) { + *returnInt = PSS_TRAILER_FIELD_SUPPORTED_INT; + return HCF_SUCCESS; + } + if (impl->saltLen != PSS_SALTLEN_INVALID_INIT) { + *returnInt = impl->saltLen; + return HCF_SUCCESS; + } + if (impl->initFlag == INITIALIZED) { + if (Openssl_EVP_PKEY_CTX_get_rsa_pss_saltlen(impl->ctx, returnInt) != HCF_OPENSSL_SUCCESS) { + LOGE("get saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; + } else { + LOGE("No set saltLen and not init!"); + return HCF_INVALID_PARAMS; + } +} + +static HcfResult EngineGetSignSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter"); return HCF_INVALID_PARAMS; } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_SIGN_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_INVALID_PARAMS; + switch (item) { + case PSS_MD_NAME_STR: + ret = GetRsaSpecStringMd(impl->md, returnString); + break; + case PSS_MGF_NAME_STR: + // only support mgf1 + ret = GetRsaSpecStringMGF(returnString); + break; + case PSS_MGF1_MD_STR: + ret = GetRsaSpecStringMd(impl->mgf1md, returnString); + break; + default: + LOGE("Invalid input sign spec item"); + return HCF_INVALID_PARAMS; + } + return ret; +} + +static HcfResult EngineSetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter"); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT) { + LOGE("Invalid verify spec item"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_VERIFY_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (saltLen < 0) { + // RSA_PSS_SALTLEN_AUTO: Verify only: auto detect salt length(only support verify) + if (saltLen != RSA_PSS_SALTLEN_DIGEST && saltLen != RSA_PSS_SALTLEN_AUTO && + saltLen != RSA_PSS_SALTLEN_MAX) { + LOGE("Invalid salt Len %d", saltLen); + return HCF_INVALID_PARAMS; + } + } + HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + impl->saltLen = saltLen; + if (impl->initFlag == INITIALIZED) { + if (Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(impl->ctx, saltLen) != HCF_OPENSSL_SUCCESS) { + LOGE("set saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + } return HCF_SUCCESS; } +static HcfResult EngineGetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_VERIFY_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_TRAILER_FIELD_INT && item != PSS_SALT_LEN_INT) { + LOGE("Invalid input sign spec item"); + return HCF_INVALID_PARAMS; + } + HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + if (item == PSS_TRAILER_FIELD_INT) { + *returnInt = PSS_TRAILER_FIELD_SUPPORTED_INT; + return HCF_SUCCESS; + } + if (impl->saltLen != PSS_SALTLEN_INVALID_INIT) { + *returnInt = impl->saltLen; + return HCF_SUCCESS; + } + if (impl->initFlag == INITIALIZED) { + if (Openssl_EVP_PKEY_CTX_get_rsa_pss_saltlen(impl->ctx, returnInt) != HCF_OPENSSL_SUCCESS) { + LOGE("get saltLen fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; + } else { + LOGE("No set saltLen and not init!"); + return HCF_INVALID_PARAMS; + } +} + +static HcfResult EngineGetVerifySpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_VERIFY_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; + if (impl->padding != HCF_OPENSSL_RSA_PSS_PADDING) { + LOGE("Only support pss parameter"); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_INVALID_PARAMS; + switch (item) { + case PSS_MD_NAME_STR: + ret = GetRsaSpecStringMd(impl->md, returnString); + break; + case PSS_MGF_NAME_STR: + // only support mgf1 + ret = GetRsaSpecStringMGF(returnString); + break; + case PSS_MGF1_MD_STR: + ret = GetRsaSpecStringMd(impl->mgf1md, returnString); + break; + default: + LOGE("Invalid input sign spec item"); + return HCF_INVALID_PARAMS; + } + return ret; +} + HcfResult HcfSignSpiRsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj) { - LOGI("HcfSignSpiRsaCreate start"); if (params == NULL || returnObj == NULL) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -428,20 +725,22 @@ HcfResult HcfSignSpiRsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj returnImpl->base.engineInit = EngineSignInit; returnImpl->base.engineUpdate = EngineSignUpdate; returnImpl->base.engineSign = EngineSign; + returnImpl->base.engineSetSignSpecInt = EngineSetSignSpecInt; + returnImpl->base.engineGetSignSpecInt = EngineGetSignSpecInt; + returnImpl->base.engineGetSignSpecString = EngineGetSignSpecString; returnImpl->md = params->md; returnImpl->padding = params->padding; returnImpl->mgf1md = params->mgf1md; returnImpl->mdctx = EVP_MD_CTX_create(); returnImpl->initFlag = UNINITIALIZED; + returnImpl->saltLen = PSS_SALTLEN_INVALID_INIT; *returnObj = (HcfSignSpi *)returnImpl; - LOGI("HcfSignSpiRsaCreate end"); return HCF_SUCCESS; } HcfResult HcfVerifySpiRsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj) { - LOGI("HcfSignSpiRsaCreate start"); if (params == NULL || returnObj == NULL) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -460,13 +759,16 @@ HcfResult HcfVerifySpiRsaCreate(HcfSignatureParams *params, HcfVerifySpi **retur returnImpl->base.engineInit = EngineVerifyInit; returnImpl->base.engineUpdate = EngineVerifyUpdate; returnImpl->base.engineVerify = EngineVerify; + returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt; + returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt; + returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString; returnImpl->md = params->md; returnImpl->padding = params->padding; returnImpl->mgf1md = params->mgf1md; returnImpl->mdctx = EVP_MD_CTX_create(); returnImpl->initFlag = UNINITIALIZED; + returnImpl->saltLen = PSS_SALTLEN_INVALID_INIT; *returnObj = (HcfVerifySpi *)returnImpl; - LOGI("HcfSignSpiRsaCreate end"); return HCF_SUCCESS; -} +} \ No newline at end of file diff --git a/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h b/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h new file mode 100644 index 0000000..c42c36b --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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 HCF_DSA_ASY_KEY_GENERATOR_OPENSSL_H +#define HCF_DSA_ASY_KEY_GENERATOR_OPENSSL_H + +#include "asy_key_generator_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfAsyKeyGeneratorSpiDsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c new file mode 100644 index 0000000..0c82e32 --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c @@ -0,0 +1,966 @@ +/* + * Copyright (C) 2023 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 "dsa_asy_key_generator_openssl.h" + +#include +#include +#include + +#include "detailed_dsa_key_params.h" +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" +#include "utils.h" + +#define OPENSSL_DSA_GENERATOR_CLASS "OPENSSL.DSA.KEYGENERATOR" +#define OPENSSL_DSA_PUBKEY_FORMAT "X.509" +#define OPENSSL_DSA_PRIKEY_FORMAT "PKCS#8" +#define ALGORITHM_NAME_DSA "DSA" + +typedef struct { + HcfAsyKeyGeneratorSpi base; + + int32_t bits; +} HcfAsyKeyGeneratorSpiDsaOpensslImpl; + +static void FreeCtx(EVP_PKEY_CTX *paramsCtx, EVP_PKEY *paramsPkey, EVP_PKEY_CTX *pkeyCtx) +{ + if (paramsCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(paramsCtx); + } + if (paramsPkey != NULL) { + Openssl_EVP_PKEY_free(paramsPkey); + } + if (pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(pkeyCtx); + } +} + +static void FreeCommSpecBn(BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if (p != NULL) { + Openssl_BN_free(p); + } + if (q != NULL) { + Openssl_BN_free(q); + } + if (g != NULL) { + Openssl_BN_free(g); + } +} + +static const char *GetDsaKeyGeneratorSpiClass(void) +{ + return OPENSSL_DSA_GENERATOR_CLASS; +} + +static const char *GetDsaKeyPairClass(void) +{ + return OPENSSL_DSA_KEYPAIR_CLASS; +} + +static const char *GetDsaPubKeyClass(void) +{ + return OPENSSL_DSA_PUBKEY_CLASS; +} + +static const char *GetDsaPriKeyClass(void) +{ + return OPENSSL_DSA_PRIKEY_CLASS; +} + +static void DestroyDsaKeyGeneratorSpiImpl(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaKeyGeneratorSpiClass())) { + return; + } + HcfFree(self); +} + +static void DestroyDsaPubKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaPubKeyClass())) { + return; + } + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + Openssl_DSA_free(impl->pk); + impl->pk = NULL; + HcfFree(impl); +} + +static void DestroyDsaPriKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaPriKeyClass())) { + return; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + Openssl_DSA_free(impl->sk); + impl->sk = NULL; + HcfFree(impl); +} + +static void DestroyDsaKeyPair(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaKeyPairClass())) { + return; + } + HcfOpensslDsaKeyPair *impl = (HcfOpensslDsaKeyPair *)self; + DestroyDsaPubKey((HcfObjectBase *)impl->base.pubKey); + impl->base.pubKey = NULL; + DestroyDsaPriKey((HcfObjectBase *)impl->base.priKey); + impl->base.priKey = NULL; + HcfFree(self); +} + +static const char *GetDsaPubKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return NULL; + } + return ALGORITHM_NAME_DSA; +} + +static const char *GetDsaPriKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return NULL; + } + return ALGORITHM_NAME_DSA; +} + +static HcfResult GetDsaPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return HCF_INVALID_PARAMS; + } + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + unsigned char *returnData = NULL; + int len = Openssl_i2d_DSA_PUBKEY(impl->pk, &returnData); + if (len <= 0) { + LOGE("Call i2d_DSA_PUBKEY failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = len; + return HCF_SUCCESS; +} + +static HcfResult GetDsaPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return HCF_INVALID_PARAMS; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + unsigned char *returnData = NULL; + int len = Openssl_i2d_DSAPrivateKey(impl->sk, &returnData); + if (len <= 0) { + LOGE("Call i2d_DSAPrivateKey failed."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = len; + return HCF_SUCCESS; +} + +static const char *GetDsaPubKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return NULL; + } + return OPENSSL_DSA_PUBKEY_FORMAT; +} + +static const char *GetDsaPriKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return NULL; + } + return OPENSSL_DSA_PRIKEY_FORMAT; +} + +static HcfResult GetBigIntegerSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + LOGE("Invalid class of self."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_SUCCESS; + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + DSA *dsaPk = impl->pk; + if (dsaPk == NULL) { + return HCF_INVALID_PARAMS; + } + switch (item) { + case DSA_P_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_p(dsaPk), returnBigInteger); + break; + case DSA_Q_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_q(dsaPk), returnBigInteger); + break; + case DSA_G_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_g(dsaPk), returnBigInteger); + break; + case DSA_PK_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_pub_key(dsaPk), returnBigInteger); + break; + default: + LOGE("Input item is invalid"); + ret = HCF_INVALID_PARAMS; + break; + } + return ret; +} + +static HcfResult GetBigIntegerSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + LOGE("Invalid class of self."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_SUCCESS; + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + DSA *dsaSk = impl->sk; + if (dsaSk == NULL) { + return HCF_INVALID_PARAMS; + } + switch (item) { + case DSA_P_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_p(dsaSk), returnBigInteger); + break; + case DSA_Q_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_q(dsaSk), returnBigInteger); + break; + case DSA_G_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_g(dsaSk), returnBigInteger); + break; + case DSA_SK_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_priv_key(dsaSk), returnBigInteger); + break; + default: + LOGE("Input item is invalid"); + ret = HCF_INVALID_PARAMS; + break; + } + return ret; +} + +static HcfResult GetIntSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt) +{ + (void)self; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetIntSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt) +{ + (void)self; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetStrSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString) +{ + (void)self; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetStrSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, char **returnString) +{ + (void)self; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +static void ClearDsaPriKeyMem(HcfPriKey *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + Openssl_DSA_free(impl->sk); + impl->sk = NULL; +} + +static HcfResult GenerateDsaEvpKey(int32_t keyLen, EVP_PKEY **ppkey) +{ + EVP_PKEY_CTX *paramsCtx = NULL; + EVP_PKEY *paramsPkey = NULL; + EVP_PKEY_CTX *pkeyCtx = NULL; + HcfResult ret = HCF_SUCCESS; + do { + paramsCtx = Openssl_EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if (paramsCtx == NULL) { + LOGE("Create params ctx failed."); + ret = HCF_ERR_MALLOC; + break; + } + if (Openssl_EVP_PKEY_paramgen_init(paramsCtx) != HCF_OPENSSL_SUCCESS) { + LOGE("Params ctx generate init failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(paramsCtx, keyLen) <= 0) { + LOGE("Set length of bits to params ctx failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_paramgen(paramsCtx, ¶msPkey) != HCF_OPENSSL_SUCCESS) { + LOGE("Generate params pkey failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + pkeyCtx = Openssl_EVP_PKEY_CTX_new(paramsPkey, NULL); + if (pkeyCtx == NULL) { + LOGE("Create pkey ctx failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_keygen_init(pkeyCtx) != HCF_OPENSSL_SUCCESS) { + LOGE("Key ctx generate init failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_keygen(pkeyCtx, ppkey) != HCF_OPENSSL_SUCCESS) { + LOGE("Generate pkey failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + } while (0); + FreeCtx(paramsCtx, paramsPkey, pkeyCtx); + return ret; +} + +static void FillOpensslDsaPubKeyFunc(HcfOpensslDsaPubKey *pk) +{ + pk->base.base.base.destroy = DestroyDsaPubKey; + pk->base.base.base.getClass = GetDsaPubKeyClass; + pk->base.base.getAlgorithm = GetDsaPubKeyAlgorithm; + pk->base.base.getEncoded = GetDsaPubKeyEncoded; + pk->base.base.getFormat = GetDsaPubKeyFormat; + pk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDsaPubKey; + pk->base.getAsyKeySpecInt = GetIntSpecFromDsaPubKey; + pk->base.getAsyKeySpecString = GetStrSpecFromDsaPubKey; +} + +static void FillOpensslDsaPriKeyFunc(HcfOpensslDsaPriKey *sk) +{ + sk->base.base.base.destroy = DestroyDsaPriKey; + sk->base.base.base.getClass = GetDsaPriKeyClass; + sk->base.base.getAlgorithm = GetDsaPriKeyAlgorithm; + sk->base.base.getEncoded = GetDsaPriKeyEncoded; + sk->base.base.getFormat = GetDsaPriKeyFormat; + sk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDsaPriKey; + sk->base.getAsyKeySpecInt = GetIntSpecFromDsaPriKey; + sk->base.getAsyKeySpecString = GetStrSpecFromDsaPriKey; + sk->base.clearMem = ClearDsaPriKeyMem; +} + +static HcfResult CreateDsaPubKey(DSA *pk, HcfOpensslDsaPubKey **returnPubKey) +{ + HcfOpensslDsaPubKey *dsaPubKey = (HcfOpensslDsaPubKey *)HcfMalloc(sizeof(HcfOpensslDsaPubKey), 0); + if (dsaPubKey == NULL) { + LOGE("Failed to allocate DSA public key memory."); + return HCF_ERR_MALLOC; + } + FillOpensslDsaPubKeyFunc(dsaPubKey); + dsaPubKey->pk = pk; + + *returnPubKey = dsaPubKey; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPriKey(DSA *sk, HcfOpensslDsaPriKey **returnPriKey) +{ + HcfOpensslDsaPriKey *dsaPriKey = (HcfOpensslDsaPriKey *)HcfMalloc(sizeof(HcfOpensslDsaPriKey), 0); + if (dsaPriKey == NULL) { + LOGE("Failed to allocate DSA private key memory."); + return HCF_ERR_MALLOC; + } + FillOpensslDsaPriKeyFunc(dsaPriKey); + dsaPriKey->sk = sk; + + *returnPriKey = dsaPriKey; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPair(const HcfOpensslDsaPubKey *pubKey, const HcfOpensslDsaPriKey *priKey, + HcfKeyPair **returnKeyPair) +{ + HcfOpensslDsaKeyPair *keyPair = (HcfOpensslDsaKeyPair *)HcfMalloc(sizeof(HcfOpensslDsaKeyPair), 0); + if (keyPair == NULL) { + LOGE("Failed to allocate keyPair memory."); + return HCF_ERR_MALLOC; + } + keyPair->base.base.getClass = GetDsaKeyPairClass; + keyPair->base.base.destroy = DestroyDsaKeyPair; + keyPair->base.pubKey = (HcfPubKey *)pubKey; + keyPair->base.priKey = (HcfPriKey *)priKey; + + *returnKeyPair = (HcfKeyPair *)keyPair; + return HCF_SUCCESS; +} + +static HcfResult GeneratePubKeyByPkey(EVP_PKEY *pkey, HcfOpensslDsaPubKey **returnPubKey) +{ + DSA *pk = Openssl_EVP_PKEY_get1_DSA(pkey); + if (pk == NULL) { + LOGE("Get das public key from pkey failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPubKey(pk, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key failed"); + Openssl_DSA_free(pk); + } + return ret; +} + +static HcfResult GeneratePriKeyByPkey(EVP_PKEY *pkey, HcfOpensslDsaPriKey **returnPriKey) +{ + DSA *sk = Openssl_EVP_PKEY_get1_DSA(pkey); + if (sk == NULL) { + LOGE("Get DSA private key from pkey failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPriKey(sk, returnPriKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key failed"); + Openssl_DSA_free(sk); + } + return ret; +} + +static HcfResult GenerateDsaPubAndPriKey(int32_t keyLen, HcfOpensslDsaPubKey **returnPubKey, + HcfOpensslDsaPriKey **returnPriKey) +{ + EVP_PKEY *pkey = NULL; + HcfResult ret = GenerateDsaEvpKey(keyLen, &pkey); + if (ret != HCF_SUCCESS) { + LOGE("Generate DSA EVP_PKEY failed."); + return ret; + } + + ret = GeneratePubKeyByPkey(pkey, returnPubKey); + if (ret != HCF_SUCCESS) { + Openssl_EVP_PKEY_free(pkey); + return ret; + } + + ret = GeneratePriKeyByPkey(pkey, returnPriKey); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(*returnPubKey); + *returnPubKey = NULL; + Openssl_EVP_PKEY_free(pkey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pkey); + return ret; +} + +static HcfResult ConvertCommSpec2Bn(const HcfDsaCommParamsSpec *paramsSpec, BIGNUM **p, BIGNUM **q, BIGNUM **g) +{ + if (BigIntegerToBigNum(&(paramsSpec->p), p) != HCF_SUCCESS) { + LOGE("Get openssl BN p failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->q), q) != HCF_SUCCESS) { + LOGE("Get openssl BN q failed"); + Openssl_BN_free(*p); + *p = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->g), g) != HCF_SUCCESS) { + LOGE("Get openssl BN g failed"); + Openssl_BN_free(*p); + *p = NULL; + Openssl_BN_free(*q); + *q = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult CreateOpensslDsaKey(const HcfDsaCommParamsSpec *paramsSpec, BIGNUM *pk, BIGNUM *sk, DSA **returnDsa) +{ + BIGNUM *p = NULL; + BIGNUM *q = NULL; + BIGNUM *g = NULL; + if (ConvertCommSpec2Bn(paramsSpec, &p, &q, &g)!= HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + DSA *dsa = Openssl_DSA_new(); + if (dsa == NULL) { + FreeCommSpecBn(p, q, g); + LOGE("Openssl DSA new failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_DSA_set0_pqg(dsa, p, q, g) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA set pqg failed"); + FreeCommSpecBn(p, q, g); + HcfPrintOpensslError(); + Openssl_DSA_free(dsa); + return HCF_ERR_CRYPTO_OPERATION; + } + if ((pk == NULL) && (sk == NULL)) { + *returnDsa = dsa; + return HCF_SUCCESS; + } + if (Openssl_DSA_set0_key(dsa, pk, sk) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA set pqg failed"); + HcfPrintOpensslError(); + Openssl_DSA_free(dsa); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnDsa = dsa; + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByCommSpec(const HcfDsaCommParamsSpec *paramsSpec, DSA **returnDsa) +{ + if (CreateOpensslDsaKey(paramsSpec, NULL, NULL, returnDsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_DSA_generate_key(*returnDsa) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA generate key failed"); + HcfPrintOpensslError(); + Openssl_DSA_free(*returnDsa); + *returnDsa = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByPubKeySpec(const HcfDsaPubKeyParamsSpec *paramsSpec, DSA **returnDsa) +{ + BIGNUM *pubKey = NULL; + if (BigIntegerToBigNum(&(paramsSpec->pk), &pubKey) != HCF_SUCCESS) { + LOGE("Get openssl BN pk failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (CreateOpensslDsaKey(&(paramsSpec->base), pubKey, NULL, returnDsa) != HCF_SUCCESS) { + Openssl_BN_free(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, DSA **returnDsa) +{ + BIGNUM *pubKey = NULL; + BIGNUM *priKey = NULL; + if (BigIntegerToBigNum(&(paramsSpec->pk), &pubKey) != HCF_SUCCESS) { + LOGE("Get openssl BN pk failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->sk), &priKey) != HCF_SUCCESS) { + LOGE("Get openssl BN sk failed"); + Openssl_BN_free(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateOpensslDsaKey(&(paramsSpec->base), pubKey, priKey, returnDsa) != HCF_SUCCESS) { + Openssl_BN_free(pubKey); + Openssl_BN_free(priKey); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairByCommSpec(const HcfDsaCommParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByCommSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslDsaPubKey *pubKey = NULL; + if (CreateDsaPubKey(dsa, &pubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + + if (Openssl_DSA_up_ref(dsa) != HCF_OPENSSL_SUCCESS) { + LOGE("Dup DSA failed."); + HcfPrintOpensslError(); + HcfObjDestroy(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfOpensslDsaPriKey *priKey = NULL; + if (CreateDsaPriKey(dsa, &priKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + HcfObjDestroy(pubKey); + return HCF_ERR_MALLOC; + } + + if (CreateDsaKeyPair(pubKey, priKey, returnKeyPair) != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPubKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, + HcfOpensslDsaPubKey **returnPubKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByKeyPairSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateDsaPubKey(dsa, returnPubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPriKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, + HcfOpensslDsaPriKey **returnPriKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByKeyPairSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateDsaPriKey(dsa, returnPriKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + HcfOpensslDsaPubKey *pubKey = NULL; + HcfResult ret = CreateDsaPubKeyByKeyPairSpec(paramsSpec, &pubKey); + if (ret != HCF_SUCCESS) { + return ret; + } + + HcfOpensslDsaPriKey *priKey = NULL; + ret = CreateDsaPriKeyByKeyPairSpec(paramsSpec, &priKey); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + return ret; + } + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return ret; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairBySpec(const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + if (paramsSpec->specType == HCF_COMMON_PARAMS_SPEC) { + return CreateDsaKeyPairByCommSpec((const HcfDsaCommParamsSpec *)paramsSpec, returnKeyPair); + } else { + return CreateDsaKeyPairByKeyPairSpec((const HcfDsaKeyPairParamsSpec *)paramsSpec, returnKeyPair); + } +} + +static HcfResult CreateDsaPubKeyByPubKeySpec(const HcfDsaPubKeyParamsSpec *paramsSpec, HcfPubKey **returnPubKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByPubKeySpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfOpensslDsaPubKey *pubKey = NULL; + if (CreateDsaPubKey(dsa, &pubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + *returnPubKey = (HcfPubKey *)pubKey; + return HCF_SUCCESS; +} + +static HcfResult ConvertDsaPubKey(const HcfBlob *pubKeyBlob, HcfOpensslDsaPubKey **returnPubKey) +{ + const unsigned char *tmpData = (const unsigned char *)(pubKeyBlob->data); + DSA *dsa = Openssl_d2i_DSA_PUBKEY(NULL, &tmpData, pubKeyBlob->len); + if (dsa == NULL) { + LOGE("D2i_DSA_PUBKEY fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPubKey(dsa, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key failed"); + Openssl_DSA_free(dsa); + } + return ret; +} + +static HcfResult ConvertDsaPriKey(const HcfBlob *priKeyBlob, HcfOpensslDsaPriKey **returnPriKey) +{ + const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); + DSA *dsa = Openssl_d2i_DSAPrivateKey(NULL, &tmpData, priKeyBlob->len); + if (dsa == NULL) { + LOGE("D2i_DSADSAPrivateKey fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPriKey(dsa, returnPriKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key failed"); + Openssl_DSA_free(dsa); + } + return ret; +} + +static HcfResult ConvertDsaPubAndPriKey(const HcfBlob *pubKeyBlob, const HcfBlob *priKeyBlob, + HcfOpensslDsaPubKey **returnPubKey, HcfOpensslDsaPriKey **returnPriKey) +{ + if (pubKeyBlob != NULL) { + if (ConvertDsaPubKey(pubKeyBlob, returnPubKey) != HCF_SUCCESS) { + LOGE("Convert DSA public key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + } + if (priKeyBlob != NULL) { + if (ConvertDsaPriKey(priKeyBlob, returnPriKey) != HCF_SUCCESS) { + LOGE("Convert DSA private key failed."); + HcfObjDestroy(*returnPubKey); + *returnPubKey = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + } + return HCF_SUCCESS; +} + +static HcfResult EngineGenerateDsaKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **returnKeyPair) +{ + if (self == NULL || returnKeyPair == NULL) { + LOGE("Invalid params."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorSpiDsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiDsaOpensslImpl *)self; + + HcfOpensslDsaPubKey *pubKey = NULL; + HcfOpensslDsaPriKey *priKey = NULL; + HcfResult ret = GenerateDsaPubAndPriKey(impl->bits, &pubKey, &priKey); + if (ret != HCF_SUCCESS) { + LOGE("Generate DSA pk and sk by openssl failed."); + return ret; + } + + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return ret; + } + return HCF_SUCCESS; +} + +static HcfResult EngineConvertDsaKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, + HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair) +{ + (void)params; + if ((self == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + bool pubKeyValid = IsBlobValid(pubKeyBlob); + bool priKeyValid = IsBlobValid(priKeyBlob); + if ((!pubKeyValid) && (!priKeyValid)) { + LOGE("The private key and public key cannot both be NULL."); + return HCF_INVALID_PARAMS; + } + + HcfOpensslDsaPubKey *pubKey = NULL; + HcfOpensslDsaPriKey *priKey = NULL; + HcfBlob *inputPk = pubKeyValid ? pubKeyBlob : NULL; + HcfBlob *inputSk = priKeyValid ? priKeyBlob : NULL; + HcfResult ret = ConvertDsaPubAndPriKey(inputPk, inputSk, &pubKey, &priKey); + if (ret != HCF_SUCCESS) { + return ret; + } + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + } + return ret; +} + +static HcfResult EngineGenerateDsaKeyPairBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || + ((paramsSpec->specType != HCF_COMMON_PARAMS_SPEC) && (paramsSpec->specType != HCF_KEY_PAIR_SPEC))) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = CreateDsaKeyPairBySpec(paramsSpec, returnKeyPair); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA key pair by spec falied."); + } + return ret; +} + +static HcfResult EngineGenerateDsaPubKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPubKey **returnPubKey) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnPubKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || + ((paramsSpec->specType != HCF_PUBLIC_KEY_SPEC) && (paramsSpec->specType != HCF_KEY_PAIR_SPEC))) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + + HcfResult ret = CreateDsaPubKeyByPubKeySpec((const HcfDsaPubKeyParamsSpec *)paramsSpec, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key by spec falied."); + } + return ret; +} + +static HcfResult EngineGenerateDsaPriKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPriKey **returnPriKey) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnPriKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || (paramsSpec->specType != HCF_KEY_PAIR_SPEC)) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + + HcfOpensslDsaPriKey *dsaSk = NULL; + HcfResult ret = CreateDsaPriKeyByKeyPairSpec((const HcfDsaKeyPairParamsSpec *)paramsSpec, &dsaSk); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key by spec falied."); + } else { + *returnPriKey = (HcfPriKey *)dsaSk; + } + return ret; +} + +HcfResult HcfAsyKeyGeneratorSpiDsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnSpi) +{ + if (params == NULL || returnSpi == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorSpiDsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiDsaOpensslImpl *)HcfMalloc( + sizeof(HcfAsyKeyGeneratorSpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate generator impl memroy."); + return HCF_ERR_MALLOC; + } + impl->bits = params->bits; + impl->base.base.getClass = GetDsaKeyGeneratorSpiClass; + impl->base.base.destroy = DestroyDsaKeyGeneratorSpiImpl; + impl->base.engineGenerateKeyPair = EngineGenerateDsaKeyPair; + impl->base.engineConvertKey = EngineConvertDsaKey; + impl->base.engineGenerateKeyPairBySpec = EngineGenerateDsaKeyPairBySpec; + impl->base.engineGeneratePubKeyBySpec = EngineGenerateDsaPubKeyBySpec; + impl->base.engineGeneratePriKeyBySpec = EngineGenerateDsaPriKeyBySpec; + + *returnSpi = (HcfAsyKeyGeneratorSpi *)impl; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c index 981d7e1..af8be93 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -17,7 +17,8 @@ #include "securec.h" -#include "algorithm_parameter.h" +#include "detailed_ecc_key_params.h" +#include "ecc_openssl_common.h" #include "log.h" #include "memory.h" #include "openssl_adapter.h" @@ -29,14 +30,19 @@ #define OPENSSL_ECC_ALGORITHM "EC" #define OPENSSL_ECC_PUB_KEY_FORMAT "X.509" #define OPENSSL_ECC_PRI_KEY_FORMAT "PKCS#8" +#define OPENSSL_ECC224_BITS 224 +#define OPENSSL_ECC256_BITS 256 +#define OPENSSL_ECC384_BITS 384 +#define OPENSSL_ECC521_BITS 521 +static const char *g_eccGenerateFieldType = "Fp"; typedef struct { HcfAsyKeyGeneratorSpi base; int32_t curveId; } HcfAsyKeyGeneratorSpiOpensslEccImpl; -static HcfResult NewEcKeyPairByOpenssl(int32_t curveId, EC_POINT **returnPubKey, BIGNUM **returnPriKey) +static HcfResult NewEcKeyPair(int32_t curveId, EC_KEY **returnEcKey) { EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(curveId); if (ecKey == NULL) { @@ -53,35 +59,531 @@ static HcfResult NewEcKeyPairByOpenssl(int32_t curveId, EC_POINT **returnPubKey, Openssl_EC_KEY_free(ecKey); return HCF_ERR_CRYPTO_OPERATION; } - const EC_POINT *pubKey = Openssl_EC_KEY_get0_public_key(ecKey); - const BIGNUM *priKey = Openssl_EC_KEY_get0_private_key(ecKey); + *returnEcKey = ecKey; + return HCF_SUCCESS; +} + +static void FreeCurveBigNum(BIGNUM *pStd, BIGNUM *bStd, BIGNUM *xStd, BIGNUM *yStd) +{ + Openssl_BN_free(pStd); + Openssl_BN_free(bStd); + Openssl_BN_free(xStd); + Openssl_BN_free(yStd); +} + +static HcfResult CheckEc224CurveId(BIGNUM *p, BIGNUM *b, BIGNUM *x, BIGNUM *y) +{ + BIGNUM *pStd = NULL, *bStd = NULL, *xStd = NULL, *yStd = NULL; + pStd = Openssl_BN_bin2bn(g_ecc224CorrectBigP, NID_secp224r1_len, NULL); + bStd = Openssl_BN_bin2bn(g_ecc224CorrectBigB, NID_secp224r1_len, NULL); + xStd = Openssl_BN_bin2bn(g_ecc224CorrectBigGX, NID_secp224r1_len, NULL); + yStd = Openssl_BN_bin2bn(g_ecc224CorrectBigGY, NID_secp224r1_len, NULL); + if ((pStd == NULL) || (bStd == NULL) || (xStd == NULL) || (yStd == NULL)) { + LOGE("EC 224 Curve convert to BN fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_ERR_CRYPTO_OPERATION; + } + if (!Openssl_BN_cmp(p, pStd) && !Openssl_BN_cmp(b, bStd) && + !Openssl_BN_cmp(x, xStd) && !Openssl_BN_cmp(y, yStd)) { + LOGE("EC 224 compare fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_SUCCESS; + } + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_INVALID_PARAMS; +} + +static HcfResult CheckEc256CurveId(BIGNUM *p, BIGNUM *b, BIGNUM *x, BIGNUM *y) +{ + BIGNUM *pStd = NULL, *bStd = NULL, *xStd = NULL, *yStd = NULL; + pStd = Openssl_BN_bin2bn(g_ecc256CorrectBigP, NID_X9_62_prime256v1_len, NULL); + bStd = Openssl_BN_bin2bn(g_ecc256CorrectBigB, NID_X9_62_prime256v1_len, NULL); + xStd = Openssl_BN_bin2bn(g_ecc256CorrectBigGX, NID_X9_62_prime256v1_len, NULL); + yStd = Openssl_BN_bin2bn(g_ecc256CorrectBigGY, NID_X9_62_prime256v1_len, NULL); + if ((pStd == NULL) || (bStd == NULL) || (xStd == NULL) || (yStd == NULL)) { + LOGE("EC 256 Curve convert to BN fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_ERR_CRYPTO_OPERATION; + } + if (!Openssl_BN_cmp(p, pStd) && !Openssl_BN_cmp(b, bStd) && + !Openssl_BN_cmp(x, xStd) && !Openssl_BN_cmp(y, yStd)) { + LOGE("EC 256 compare fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_SUCCESS; + } + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_INVALID_PARAMS; +} + +static HcfResult CheckEc384CurveId(BIGNUM *p, BIGNUM *b, BIGNUM *x, BIGNUM *y) +{ + BIGNUM *pStd = NULL, *bStd = NULL, *xStd = NULL, *yStd = NULL; + pStd = Openssl_BN_bin2bn(g_ecc384CorrectBigP, NID_secp384r1_len, NULL); + bStd = Openssl_BN_bin2bn(g_ecc384CorrectBigB, NID_secp384r1_len, NULL); + xStd = Openssl_BN_bin2bn(g_ecc384CorrectBigGX, NID_secp384r1_len, NULL); + yStd = Openssl_BN_bin2bn(g_ecc384CorrectBigGY, NID_secp384r1_len, NULL); + if ((pStd == NULL) || (bStd == NULL) || (xStd == NULL) || (yStd == NULL)) { + LOGE("EC 384 Curve convert to BN fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_ERR_CRYPTO_OPERATION; + } + if (!Openssl_BN_cmp(p, pStd) && !Openssl_BN_cmp(b, bStd) && + !Openssl_BN_cmp(x, xStd) && !Openssl_BN_cmp(y, yStd)) { + LOGE("EC 384 compare fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_SUCCESS; + } + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_INVALID_PARAMS; +} + +static HcfResult CheckEc521CurveId(BIGNUM *p, BIGNUM *b, BIGNUM *x, BIGNUM *y) +{ + BIGNUM *pStd = NULL, *bStd = NULL, *xStd = NULL, *yStd = NULL; + pStd = Openssl_BN_bin2bn(g_ecc521CorrectBigP, NID_secp521r1_len, NULL); + bStd = Openssl_BN_bin2bn(g_ecc521CorrectBigB, NID_secp521r1_len, NULL); + xStd = Openssl_BN_bin2bn(g_ecc521CorrectBigGX, NID_secp521r1_len, NULL); + yStd = Openssl_BN_bin2bn(g_ecc521CorrectBigGY, NID_secp521r1_len, NULL); + if ((pStd == NULL) || (bStd == NULL) || (xStd == NULL) || (yStd == NULL)) { + LOGE("EC 521 Curve convert to BN fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_ERR_CRYPTO_OPERATION; + } + if (!Openssl_BN_cmp(p, pStd) && !Openssl_BN_cmp(b, bStd) && + !Openssl_BN_cmp(x, xStd) && !Openssl_BN_cmp(y, yStd)) { + LOGE("EC 521 compare fail"); + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_SUCCESS; + } + FreeCurveBigNum(pStd, bStd, xStd, yStd); + return HCF_INVALID_PARAMS; +} + +static HcfResult CheckParamsSpecToGetCurveId(const HcfEccCommParamsSpec *ecParams, int32_t *curveId) +{ + BIGNUM *p = NULL, *b = NULL, *x = NULL, *y = NULL; + HcfECFieldFp *field = (HcfECFieldFp *)(ecParams->field); + if (BigIntegerToBigNum(&(field->p), &p) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->b), &b) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->g.x), &x) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->g.y), &y) != HCF_SUCCESS) { + LOGE("BigIntegerToBigNum failed."); + FreeCurveBigNum(p, b, x, y); + return HCF_ERR_CRYPTO_OPERATION; + } + + int32_t bitLenP = Openssl_BN_num_bits(p); + HcfResult res = HCF_INVALID_PARAMS; + switch (bitLenP) { + case OPENSSL_ECC224_BITS: + res = CheckEc224CurveId(p, b, x, y); + if (res == HCF_SUCCESS) { + *curveId = NID_secp224r1; + } + break; + case OPENSSL_ECC256_BITS: + res = CheckEc256CurveId(p, b, x, y); + if (res == HCF_SUCCESS) { + *curveId = NID_X9_62_prime256v1; + } + break; + case OPENSSL_ECC384_BITS: + res = CheckEc384CurveId(p, b, x, y); + if (res == HCF_SUCCESS) { + *curveId = NID_secp384r1; + } + break; + case OPENSSL_ECC521_BITS: + res = CheckEc521CurveId(p, b, x, y); + if (res == HCF_SUCCESS) { + *curveId = NID_secp521r1; + } + break; + default: + LOGE("Find no bit len"); + break; + } + FreeCurveBigNum(p, b, x, y); + return res; +} + +static HcfResult NewGroupFromCurveGFp(const HcfEccCommParamsSpec *ecParams, EC_GROUP **ecGroup, BN_CTX *ctx) +{ + HcfResult res = HCF_SUCCESS; + HcfECFieldFp *field = (HcfECFieldFp *)(ecParams->field); + BIGNUM *p = NULL, *a = NULL, *b = NULL; + EC_GROUP *group = NULL; + do { + if (BigIntegerToBigNum(&(field->p), &p) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->a), &a) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->b), &b) != HCF_SUCCESS) { + LOGE("BigInteger to BigNum failed"); + res = HCF_ERR_CRYPTO_OPERATION; + break; + } + group = Openssl_EC_GROUP_new_curve_GFp(p, a, b, ctx); + if (group == NULL) { + LOGE("Alloc group memory failed."); + res = HCF_ERR_CRYPTO_OPERATION; + break; + } + } while (0); + Openssl_BN_free(p); + Openssl_BN_free(a); + Openssl_BN_free(b); + + if (res == HCF_SUCCESS) { + *ecGroup = group; + return res; + } + Openssl_EC_GROUP_free(group); + return res; +} + +static HcfResult SetEcPointToGroup(const HcfEccCommParamsSpec *ecParams, EC_GROUP *group, BN_CTX *ctx) +{ + HcfResult res = HCF_SUCCESS; + BIGNUM *x = NULL, *y = NULL; + BIGNUM *order = NULL, *cofactor = NULL; + EC_POINT *generator = NULL; + cofactor = Openssl_BN_new(); + if (cofactor == NULL) { + LOGE("Alloc cofactor memory failed."); + return HCF_ERR_MALLOC; + } + do { + if (BigIntegerToBigNum(&(ecParams->g.x), &x) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->g.y), &y) != HCF_SUCCESS || + BigIntegerToBigNum(&(ecParams->n), &order) != HCF_SUCCESS || + !Openssl_BN_set_word(cofactor, (uint32_t)ecParams->h)) { + LOGE("BigInteger to BigNum failed."); + res = HCF_ERR_CRYPTO_OPERATION; + break; + } + generator = Openssl_EC_POINT_new(group); + if (generator == NULL) { + LOGE("Alloc group memory failed."); + res = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (!Openssl_EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) { + LOGE("Openssl_EC_POINT_set_affine_coordinates_GFp failed."); + res = HCF_ERR_CRYPTO_OPERATION; + HcfPrintOpensslError(); + break; + } + + if (!Openssl_EC_GROUP_set_generator(group, generator, order, cofactor)) { + LOGE("Openssl_EC_GROUP_set_generator failed."); + res = HCF_ERR_CRYPTO_OPERATION; + HcfPrintOpensslError(); + break; + } + } while (0); + Openssl_BN_free(x); + Openssl_BN_free(y); + Openssl_BN_free(order); + Openssl_BN_free(cofactor); + Openssl_EC_POINT_free(generator); + return res; +} + +static HcfResult GenerateEcGroupWithParamsSpec(const HcfEccCommParamsSpec *ecParams, EC_GROUP **ecGroup) +{ + if (ecGroup == NULL) { + LOGE("Invalid input parameters."); + return HCF_INVALID_PARAMS; + } + HcfResult res = HCF_SUCCESS; + EC_GROUP *group = NULL; + BN_CTX *ctx = NULL; + ctx = Openssl_BN_CTX_new(); + if (ctx == NULL) { + LOGE("Alloc ctx memory failed."); + res = HCF_ERR_MALLOC; + return res; + } + res = NewGroupFromCurveGFp(ecParams, &group, ctx); + if (res != HCF_SUCCESS) { + LOGE("New Ec group fail"); + Openssl_BN_CTX_free(ctx); + return res; + } + res = SetEcPointToGroup(ecParams, group, ctx); + if (res != HCF_SUCCESS) { + Openssl_BN_CTX_free(ctx); + Openssl_EC_GROUP_free(group); + LOGE("Set Ec point fail"); + return res; + } + *ecGroup = group; + return res; +} + +static HcfResult GenerateEcKeyWithParmasSpec(const HcfEccCommParamsSpec *ecParams, EC_KEY **returnKey) +{ + EC_KEY *ecKey = NULL; + int32_t curveId = 0; + HcfResult res = CheckParamsSpecToGetCurveId(ecParams, &curveId); + if (res == HCF_SUCCESS && curveId != 0) { + ecKey = Openssl_EC_KEY_new_by_curve_name(curveId); + LOGE("generate EC_KEY by curve name"); + if (ecKey == NULL) { + LOGE("new ec key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + } else { + EC_GROUP *group = NULL; + res = GenerateEcGroupWithParamsSpec(ecParams, &group); + if (res != HCF_SUCCESS) { + LOGE("GenerateEcGroupWithParamsSpec failed."); + return res; + } + ecKey = Openssl_EC_KEY_new(); + if (ecKey == NULL) { + LOGE("Openssl_EC_KEY_new failed."); + Openssl_EC_GROUP_free(group); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EC_KEY_set_group(ecKey, group) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_KEY_set_group failed."); + Openssl_EC_GROUP_free(group); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EC_GROUP_free(group); + LOGD("generate EC_KEY by group spec parmas"); + } + // all exceptions have been returned above. + *returnKey = ecKey; + return HCF_SUCCESS; +} + +static HcfResult InitEcKeyByPubKey(const HcfPoint *pubKey, EC_KEY *ecKey) +{ const EC_GROUP *group = Openssl_EC_KEY_get0_group(ecKey); - if ((pubKey == NULL) || (priKey == NULL) || (group == NULL)) { - LOGE("ec key is invalid."); + if (group == NULL) { + LOGE("Not find group from ecKey."); + return HCF_ERR_CRYPTO_OPERATION; + } + EC_POINT *point = Openssl_EC_POINT_new(group); + if (point == NULL) { + LOGE("New ec point failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + BIGNUM *pkX = NULL, *pkY = NULL; + if (BigIntegerToBigNum(&(pubKey->x), &pkX) != HCF_SUCCESS || + BigIntegerToBigNum(&(pubKey->y), &pkY) != HCF_SUCCESS) { + LOGE("BigInteger to BigNum failed."); + Openssl_EC_POINT_free(point); + Openssl_BN_free(pkX); + Openssl_BN_free(pkY); + return HCF_ERR_CRYPTO_OPERATION; + } + + // only support fp point. + // can use EC_POINT_set_affine_coordinates() set x and y by group, deep copy. + int32_t res = Openssl_EC_POINT_set_affine_coordinates_GFp(group, point, pkX, pkY, NULL); + Openssl_BN_free(pkX); + Openssl_BN_free(pkY); + + if (res != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_POINT_set_affine_coordinates_GFp failed."); + Openssl_EC_POINT_free(point); + return HCF_ERR_CRYPTO_OPERATION; + } + res = Openssl_EC_KEY_set_public_key(ecKey, point); + if (res != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_KEY_set_public_key failed."); + Openssl_EC_POINT_free(point); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EC_POINT_free(point); + return HCF_SUCCESS; +} + +static HcfResult InitEcKeyByPriKey(const HcfBigInteger *priKey, EC_KEY *ecKey) +{ + BIGNUM *sk = NULL; + if (BigIntegerToBigNum(priKey, &sk) != HCF_SUCCESS) { + LOGE("BigInteger to BigNum failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + int32_t res = Openssl_EC_KEY_set_private_key(ecKey, sk); + if (res != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_KEY_set_private_key failed."); + Openssl_BN_free(sk); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_BN_free(sk); + return HCF_SUCCESS; +} + +static HcfResult SetEcPubKeyFromPriKey(const HcfBigInteger *priKey, EC_KEY *ecKey) +{ + const EC_GROUP *group = Openssl_EC_KEY_get0_group(ecKey); + if (group == NULL) { + LOGE("Not find group from ecKey."); + return HCF_ERR_CRYPTO_OPERATION; + } + BIGNUM *sk = NULL; + if (BigIntegerToBigNum(priKey, &sk) != HCF_SUCCESS) { + LOGE("BigInteger to BigNum failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + EC_POINT *point = Openssl_EC_POINT_new(group); + if (point == NULL) { + LOGE("Openssl_EC_POINT_new failed."); + Openssl_BN_free(sk); + return HCF_ERR_CRYPTO_OPERATION; + } + if (!Openssl_EC_POINT_mul(group, point, sk, NULL, NULL, NULL)) { + LOGE("Openssl_EC_POINT_new or Openssl_EC_POINT_mul failed."); + Openssl_EC_POINT_free(point); + Openssl_BN_free(sk); + return HCF_ERR_CRYPTO_OPERATION; + } + int32_t res = Openssl_EC_KEY_set_public_key(ecKey, point); + if (res != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_KEY_set_public_key failed."); + Openssl_EC_POINT_free(point); + Openssl_BN_free(sk); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EC_POINT_free(point); + Openssl_BN_free(sk); + return HCF_SUCCESS; +} + +static HcfResult SetEcKey(const HcfPoint *pubKey, const HcfBigInteger *priKey, EC_KEY *ecKey) +{ + HcfResult res = HCF_SUCCESS; + if (pubKey != NULL) { + res = InitEcKeyByPubKey(pubKey, ecKey); + if (res != HCF_SUCCESS) { + LOGE("InitEcKeyByPubKey failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + } + if (priKey != NULL) { + res = InitEcKeyByPriKey(priKey, ecKey); + if (res != HCF_SUCCESS) { + LOGE("InitEcKeyByPriKey failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (pubKey == NULL) { + res = SetEcPubKeyFromPriKey(priKey, ecKey); + if (res != HCF_SUCCESS) { + LOGE("SetEcPubKeyFromPriKey failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + } + } + return res; +} + +static HcfResult NewEcKeyPairWithCommSpec(const HcfEccCommParamsSpec *ecParams, EC_KEY **returnEckey) +{ + LOGD("start gen EC key by comm spec"); + EC_KEY *ecKey = NULL; + HcfResult res = GenerateEcKeyWithParmasSpec(ecParams, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("generate EC key fails"); + return res; + } + if (Openssl_EC_KEY_generate_key(ecKey) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_KEY_generate_key failed."); Openssl_EC_KEY_free(ecKey); return HCF_ERR_CRYPTO_OPERATION; } - EC_POINT *newPubKey = Openssl_EC_POINT_dup(pubKey, group); - if (newPubKey == NULL) { - LOGE("copy pubKey fail."); + + if (Openssl_EC_KEY_check_key(ecKey) <= 0) { + LOGE("Check key fail."); Openssl_EC_KEY_free(ecKey); return HCF_ERR_CRYPTO_OPERATION; } - BIGNUM *newPriKey = Openssl_BN_dup(priKey); - if (newPriKey == NULL) { - LOGE("copy priKey fail."); + LOGD("Gen EC_key and check success"); + *returnEckey = ecKey; + return res; +} + +static HcfResult NewEcPubKeyWithPubSpec(const HcfEccPubKeyParamsSpec *ecParams, EC_KEY **returnEcKey) +{ + EC_KEY *ecKey = NULL; + HcfResult res = GenerateEcKeyWithParmasSpec((HcfEccCommParamsSpec *)ecParams, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("generate EC key fails"); + return res; + } + res = SetEcKey(&(ecParams->pk), NULL, ecKey); + if (res != HCF_SUCCESS) { + LOGE("Set pub ecKey failed."); Openssl_EC_KEY_free(ecKey); - Openssl_EC_POINT_free(newPubKey); return HCF_ERR_CRYPTO_OPERATION; } - *returnPubKey = newPubKey; - *returnPriKey = newPriKey; - Openssl_EC_KEY_free(ecKey); - return HCF_SUCCESS; + if (Openssl_EC_KEY_check_key(ecKey) <= 0) { + LOGE("Check key fail."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnEcKey = ecKey; + return res; +} + +static HcfResult NewEcPriKeyWithPriSpec(const HcfEccPriKeyParamsSpec *ecParams, EC_KEY **returnEcKey) +{ + EC_KEY *ecKey = NULL; + HcfResult res = GenerateEcKeyWithParmasSpec((HcfEccCommParamsSpec *)ecParams, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("generate EC key fails"); + return res; + } + res = SetEcKey(NULL, &(ecParams->sk), ecKey); + if (res != HCF_SUCCESS) { + LOGE("Set pri ecKey failed."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_KEY_check_key(ecKey) <= 0) { + LOGE("Check key fail."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnEcKey = ecKey; + return res; +} + +static HcfResult NewEcKeyWithKeyPairSpec(const HcfEccKeyPairParamsSpec *ecParams, EC_KEY **returnEcKey, + const bool needPrivate) +{ + EC_KEY *ecKey = NULL; + HcfResult res = GenerateEcKeyWithParmasSpec((HcfEccCommParamsSpec *)ecParams, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("generate EC key fails"); + return res; + } + if (needPrivate) { + res = SetEcKey(&(ecParams->pk), &(ecParams->sk), ecKey); + } else { + res = SetEcKey(&(ecParams->pk), NULL, ecKey); + } + if (res != HCF_SUCCESS) { + LOGE("SetEcKey failed."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_KEY_check_key(ecKey) <= 0) { + LOGE("Check key fail."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnEcKey = ecKey; + return res; } -// export interfaces static const char *GetEccKeyPairGeneratorClass(void) { return OPENSSL_ECC_KEY_GENERATOR_CLASS; @@ -122,8 +624,10 @@ static void DestroyEccPubKey(HcfObjectBase *self) return; } HcfOpensslEccPubKey *impl = (HcfOpensslEccPubKey *)self; - EC_POINT_free(impl->pk); - impl->pk = NULL; + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; + HcfFree(impl->fieldType); + impl->fieldType = NULL; HcfFree(impl); } @@ -136,8 +640,10 @@ static void DestroyEccPriKey(HcfObjectBase *self) return; } HcfOpensslEccPriKey *impl = (HcfOpensslEccPriKey *)self; - BN_clear_free(impl->sk); - impl->sk = NULL; + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; + HcfFree(impl->fieldType); + impl->fieldType = NULL; HcfFree(impl); } @@ -161,11 +667,6 @@ static void DestroyEccKeyPair(HcfObjectBase *self) HcfFree(impl); } -static void DestroyKey(HcfObjectBase *self) -{ - LOGI("Process DestroyKey"); -} - static const char *GetEccPubKeyAlgorithm(HcfKey *self) { if (self == NULL) { @@ -216,7 +717,6 @@ static const char *GetEccPriKeyFormat(HcfKey *self) static HcfResult GetEccPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) { - LOGI("start ..."); if ((self == NULL) || (returnBlob == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -226,35 +726,30 @@ static HcfResult GetEccPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) } HcfOpensslEccPubKey *impl = (HcfOpensslEccPubKey *)self; - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(impl->curveId); - if (ecKey == NULL) { - LOGE("EC_KEY_new_by_curve_name fail."); - HcfPrintOpensslError(); - return HCF_ERR_CRYPTO_OPERATION; - } - if (Openssl_EC_KEY_set_public_key(ecKey, impl->pk) <= 0) { - LOGE("EC_KEY_set_public_key fail."); - HcfPrintOpensslError(); - EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; + if (impl->curveId != 0) { + LOGE("have a curveId"); + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); + } else { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); } + unsigned char *returnData = NULL; - int returnDataLen = Openssl_i2d_EC_PUBKEY(ecKey, &returnData); - Openssl_EC_KEY_free(ecKey); + LOGE("Begin trans"); + int returnDataLen = Openssl_i2d_EC_PUBKEY(impl->ecKey, &returnData); + LOGE("ECC i2d complete"); if (returnDataLen <= 0) { LOGE("i2d_EC_PUBKEY fail"); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } + LOGD("ECC pubKey i2d success"); returnBlob->data = returnData; returnBlob->len = returnDataLen; - LOGI("end ..."); return HCF_SUCCESS; } static HcfResult GetEccPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) { - LOGI("start ..."); if ((self == NULL) || (returnBlob == NULL)) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; @@ -264,31 +759,26 @@ static HcfResult GetEccPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) } HcfOpensslEccPriKey *impl = (HcfOpensslEccPriKey *)self; - EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(impl->curveId); - if (ecKey == NULL) { - LOGE("EC_KEY_new_by_curve_name fail."); - HcfPrintOpensslError(); - return HCF_ERR_CRYPTO_OPERATION; + if (impl->curveId != 0) { + LOGD("have a curveId"); + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); + } else { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); } - if (Openssl_EC_KEY_set_private_key(ecKey, (impl->sk)) != HCF_OPENSSL_SUCCESS) { - LOGE("EC_KEY_set_private_key fail."); - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; - } - Openssl_EC_KEY_set_asn1_flag(ecKey, OPENSSL_EC_NAMED_CURVE); - Openssl_EC_KEY_set_enc_flags(ecKey, EC_PKEY_NO_PUBKEY); + // keep consistence of 3.2 + Openssl_EC_KEY_set_enc_flags(impl->ecKey, EC_PKEY_NO_PUBKEY); + // if the convert key has no pubKey, it will generate pub key automatically, + // and set the no pubKey flag to ensure the consistency of blob. unsigned char *returnData = NULL; - int returnDataLen = Openssl_i2d_ECPrivateKey(ecKey, &returnData); - Openssl_EC_KEY_free(ecKey); + int returnDataLen = Openssl_i2d_ECPrivateKey(impl->ecKey, &returnData); if (returnDataLen <= 0) { LOGE("i2d_ECPrivateKey fail."); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } + LOGD("ECC priKey i2d success"); returnBlob->data = returnData; returnBlob->len = returnDataLen; - LOGI("end ..."); return HCF_SUCCESS; } @@ -301,49 +791,491 @@ static void EccPriKeyClearMem(HcfPriKey *self) return; } HcfOpensslEccPriKey *impl = (HcfOpensslEccPriKey *)self; - Openssl_BN_clear(impl->sk); + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; +} + +static HcfResult GetCurveGFp(const EC_GROUP *group, const AsyKeySpecItem item, HcfBigInteger *returnBigInteger) +{ + BIGNUM *p = Openssl_BN_new(); + BIGNUM *a = Openssl_BN_new(); + BIGNUM *b = Openssl_BN_new(); + if (p == NULL || a == NULL || b == NULL) { + LOGE("new BN failed."); + Openssl_BN_free(p); + Openssl_BN_free(a); + Openssl_BN_free(b); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_GROUP_get_curve_GFp(group, p, a, b, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_GROUP_get_curve_GFp failed."); + Openssl_BN_free(p); + Openssl_BN_free(a); + Openssl_BN_free(b); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfResult res = HCF_INVALID_PARAMS; + switch (item) { + case ECC_FP_P_BN: + res = BigNumToBigInteger(p, returnBigInteger); + break; + case ECC_A_BN: + res = BigNumToBigInteger(a, returnBigInteger); + break; + case ECC_B_BN: + res = BigNumToBigInteger(b, returnBigInteger); + break; + default: + break; + } + Openssl_BN_free(p); + Openssl_BN_free(a); + Openssl_BN_free(b); + return res; +} + +static HcfResult GetGenerator(const EC_GROUP *group, const AsyKeySpecItem item, HcfBigInteger *returnBigInteger) +{ + const EC_POINT *generator = Openssl_EC_GROUP_get0_generator(group); + if (generator == NULL) { + LOGE("Openssl_EC_GROUP_get0_generator failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + + BIGNUM *gX = Openssl_BN_new(); + BIGNUM *gY = Openssl_BN_new(); + if (gX == NULL || gY == NULL) { + LOGE("new BN failed."); + Openssl_BN_free(gX); + Openssl_BN_free(gY); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_POINT_get_affine_coordinates_GFp(group, generator, gX, gY, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_POINT_get_affine_coordinates_GFp failed."); + Openssl_BN_free(gX); + Openssl_BN_free(gY); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfResult res = HCF_INVALID_PARAMS; + switch (item) { + case ECC_G_X_BN: + res = BigNumToBigInteger(gX, returnBigInteger); + break; + case ECC_G_Y_BN: + res = BigNumToBigInteger(gY, returnBigInteger); + break; + default: + break; + } + Openssl_BN_free(gX); + Openssl_BN_free(gY); + return res; +} + +static HcfResult GetOrder(const EC_GROUP *group, HcfBigInteger *returnBigInteger) +{ + BIGNUM *order = Openssl_BN_new(); + if (order == NULL) { + LOGE("new BN failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_GROUP_get_order(group, order, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_POINT_get_affine_coordinates_GFp failed."); + Openssl_BN_free(order); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfResult res = BigNumToBigInteger(order, returnBigInteger); + Openssl_BN_free(order); + return res; +} + +static HcfResult GetCofactor(const EC_GROUP *group, int *returnCofactor) +{ + BIGNUM *cofactor = Openssl_BN_new(); + if (cofactor == NULL) { + LOGE("new BN failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_GROUP_get_cofactor(group, cofactor, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_POINT_get_affine_coordinates_GFp failed."); + Openssl_BN_free(cofactor); + return HCF_ERR_CRYPTO_OPERATION; + } + + *returnCofactor = (int)(Openssl_BN_get_word(cofactor)); + // cofactor should not be zero. + if (*returnCofactor == 0) { + LOGE("Openssl_BN_get_word failed."); + Openssl_BN_free(cofactor); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_BN_free(cofactor); + return HCF_SUCCESS; +} + +static HcfResult GetFieldSize(const EC_GROUP *group, int32_t *fieldSize) +{ + *fieldSize = Openssl_EC_GROUP_get_degree(group); + if (*fieldSize == 0) { + LOGE("Openssl_EC_GROUP_get_degree failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; } -static HcfResult CreateEccPubKey(int32_t curveId, EC_POINT *pubKey, HcfOpensslEccPubKey **returnObj) +static HcfResult GetPubKeyXOrY(const EC_GROUP *group, const EC_POINT *point, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + BIGNUM *pkX = Openssl_BN_new(); + BIGNUM *pkY = Openssl_BN_new(); + if (pkX == NULL || pkY == NULL) { + LOGE("new BN failed."); + Openssl_BN_free(pkX); + Openssl_BN_free(pkY); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EC_POINT_get_affine_coordinates_GFp(group, point, pkX, pkY, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EC_POINT_get_affine_coordinates_GFp failed."); + Openssl_BN_free(pkX); + Openssl_BN_free(pkY); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfResult res = HCF_INVALID_PARAMS; + switch (item) { + case ECC_PK_X_BN: + res = BigNumToBigInteger(pkX, returnBigInteger); + break; + case ECC_PK_Y_BN: + res = BigNumToBigInteger(pkY, returnBigInteger); + break; + default: + break; + } + Openssl_BN_free(pkX); + Openssl_BN_free(pkY); + return res; +} + +static HcfResult GetFieldType(const HcfKey *self, const bool isPrivate, char **returnString) +{ + char *fieldType = NULL; + if (isPrivate) { + fieldType = ((HcfOpensslEccPriKey *)self)->fieldType; + } else { + fieldType = ((HcfOpensslEccPubKey *)self)->fieldType; + } + + if (fieldType == NULL) { + LOGE("No fieldType in EccPubKey struct."); + return HCF_INVALID_PARAMS; + } + + int32_t len = strlen(fieldType); + *returnString = (char *)HcfMalloc(len + 1, 0); + if (*returnString == NULL) { + LOGE("Alloc returnString memory failed."); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(*returnString, len, fieldType, len); + + return HCF_SUCCESS; +} + +static HcfResult GetCurveName(const HcfKey *self, const bool isPriavte, char **returnString) +{ + int32_t curveId = 0; + if (isPriavte) { + curveId = ((HcfOpensslEccPriKey *)self)->curveId; + } else { + curveId = ((HcfOpensslEccPubKey *)self)->curveId; + } + + char *tmp = NULL; + switch (curveId) { + case NID_secp224r1: + tmp = "NID_secp224r1"; + break; + case NID_X9_62_prime256v1: + tmp = "NID_X9_62_prime256v1"; + break; + case NID_secp384r1: + tmp = "NID_secp384r1"; + break; + case NID_secp521r1: + tmp = "NID_secp521r1"; + break; + default: + LOGE("No curve name."); + return HCF_ERR_CRYPTO_OPERATION; + break; + } + + int32_t len = strlen(tmp); + *returnString = (char *)HcfMalloc(len + 1, 0); + if (*returnString == NULL) { + LOGE("Alloc returnString memory failed."); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(*returnString, len, tmp, len); + return HCF_SUCCESS; +} + +static HcfResult CheckEcKeySelf(const HcfKey *self, bool *isPrivate) +{ + if (IsClassMatch((HcfObjectBase *)self, GetEccPubKeyClass())) { + *isPrivate = false; + return HCF_SUCCESS; + } else if (IsClassMatch((HcfObjectBase *)self, GetEccPriKeyClass())) { + *isPrivate = true; + return HCF_SUCCESS; + } else { + return HCF_INVALID_PARAMS; + } +} + +static HcfResult GetPkSkBigInteger(const HcfKey *self, const bool isPrivate, + const AsyKeySpecItem item, HcfBigInteger *returnBigInteger) +{ + HcfResult res = HCF_INVALID_PARAMS; + if (item == ECC_SK_BN) { + if (!isPrivate) { + LOGE("ecc pub key has no private key spec item"); + return res; + } + res = BigNumToBigInteger(Openssl_EC_KEY_get0_private_key(((HcfOpensslEccPriKey *)self)->ecKey), + returnBigInteger); + } else { + if (isPrivate) { + LOGE("ecc pri key cannot get pub key spec item"); + return res; + } + res = GetPubKeyXOrY(Openssl_EC_KEY_get0_group(((HcfOpensslEccPubKey *)self)->ecKey), + Openssl_EC_KEY_get0_public_key(((HcfOpensslEccPubKey *)self)->ecKey), item, returnBigInteger); + } + return res; +} + +static HcfResult GetEcKeySpecBigInteger(const HcfKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + bool isPrivate; + HcfResult res = CheckEcKeySelf(self, &isPrivate); + if (res != HCF_SUCCESS) { + LOGE("Invalid input key"); + return HCF_INVALID_PARAMS; + } + const EC_GROUP *group = NULL; + if (isPrivate) { + group = Openssl_EC_KEY_get0_group(((HcfOpensslEccPriKey *)self)->ecKey); + } else { + group = Openssl_EC_KEY_get0_group(((HcfOpensslEccPubKey *)self)->ecKey); + } + switch (item) { + case ECC_FP_P_BN: + case ECC_A_BN: + case ECC_B_BN: + res = GetCurveGFp(group, item, returnBigInteger); + break; + case ECC_G_X_BN: + case ECC_G_Y_BN: + res = GetGenerator(group, item, returnBigInteger); + break; + case ECC_N_BN: + res = GetOrder(group, returnBigInteger); + break; + case ECC_SK_BN: + case ECC_PK_X_BN: + case ECC_PK_Y_BN: + res = GetPkSkBigInteger(self, isPrivate, item, returnBigInteger); + break; + default: + LOGE("Invalid ecc key big number spec!"); + res = HCF_INVALID_PARAMS; + break; + } + return res; +} + +static HcfResult GetEcKeySpecString(const HcfKey *self, const AsyKeySpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + bool isPrivate; + HcfResult res = CheckEcKeySelf(self, &isPrivate); + if (res != HCF_SUCCESS) { + LOGE("Invalid input key"); + return HCF_INVALID_PARAMS; + } + + switch (item) { + case ECC_FIELD_TYPE_STR: + res = GetFieldType(self, isPrivate, returnString); + break; + case ECC_CURVE_NAME_STR: + res = GetCurveName(self, isPrivate, returnString); + break; + default: + res = HCF_INVALID_PARAMS; + LOGE("Invalid spec of ec string"); + break; + } + return res; +} + +static HcfResult GetEcKeySpecInt(const HcfKey *self, const AsyKeySpecItem item, int *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + bool isPrivate; + HcfResult res = CheckEcKeySelf(self, &isPrivate); + if (res != HCF_SUCCESS) { + LOGE("Invalid input key"); + return HCF_INVALID_PARAMS; + } + const EC_GROUP *group = NULL; + if (isPrivate) { + group = Openssl_EC_KEY_get0_group(((HcfOpensslEccPriKey *)self)->ecKey); + } else { + group = Openssl_EC_KEY_get0_group(((HcfOpensslEccPubKey *)self)->ecKey); + } + switch (item) { + case ECC_H_INT: + res = GetCofactor(group, returnInt); + break; + case ECC_FIELD_SIZE_INT: + res = GetFieldSize(group, returnInt); + break; + default: + res = HCF_INVALID_PARAMS; + LOGE("invalid ec key int spec"); + break; + } + return res; +} + +static HcfResult GetECPubKeySpecBigInteger(const HcfPubKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + return GetEcKeySpecBigInteger((HcfKey *)self, item, returnBigInteger); +} + +static HcfResult GetECPubKeySpecString(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString) +{ + return GetEcKeySpecString((HcfKey *)self, item, returnString); +} + +static HcfResult GetECPubKeySpecInt(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt) +{ + return GetEcKeySpecInt((HcfKey *)self, item, returnInt); +} + +static HcfResult GetECPriKeySpecBigInteger(const HcfPriKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + return GetEcKeySpecBigInteger((HcfKey *)self, item, returnBigInteger); +} + +static HcfResult GetECPriKeySpecString(const HcfPriKey *self, const AsyKeySpecItem item, char **returnString) +{ + return GetEcKeySpecString((HcfKey *)self, item, returnString); +} + +static HcfResult GetECPriKeySpecInt(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt) +{ + return GetEcKeySpecInt((HcfKey *)self, item, returnInt); +} + +static HcfResult PackEccPubKey(int32_t curveId, EC_KEY *ecKey, const char *fieldType, + HcfOpensslEccPubKey **returnObj) { HcfOpensslEccPubKey *returnPubKey = (HcfOpensslEccPubKey *)HcfMalloc(sizeof(HcfOpensslEccPubKey), 0); if (returnPubKey == NULL) { LOGE("Failed to allocate returnPubKey memory!"); return HCF_ERR_MALLOC; } - returnPubKey->base.base.base.destroy = DestroyKey; + char *tmpFieldType = NULL; + if (fieldType != NULL) { + int32_t len = strlen(fieldType); + tmpFieldType = (char *)HcfMalloc(len + 1, 0); + if (tmpFieldType == NULL) { + LOGE("Alloc tmpFieldType memory failed."); + HcfFree(returnPubKey); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tmpFieldType, len, fieldType, len); + } + + returnPubKey->base.base.base.destroy = DestroyEccPubKey; returnPubKey->base.base.base.getClass = GetEccPubKeyClass; returnPubKey->base.base.getAlgorithm = GetEccPubKeyAlgorithm; returnPubKey->base.base.getEncoded = GetEccPubKeyEncoded; returnPubKey->base.base.getFormat = GetEccPubKeyFormat; + returnPubKey->base.getAsyKeySpecBigInteger = GetECPubKeySpecBigInteger; + returnPubKey->base.getAsyKeySpecString = GetECPubKeySpecString; + returnPubKey->base.getAsyKeySpecInt = GetECPubKeySpecInt; returnPubKey->curveId = curveId; - returnPubKey->pk = pubKey; + returnPubKey->ecKey = ecKey; + returnPubKey->fieldType = tmpFieldType; *returnObj = returnPubKey; return HCF_SUCCESS; } -static HcfResult CreateEccPriKey(int32_t curveId, BIGNUM *priKey, HcfOpensslEccPriKey **returnObj) +static HcfResult PackEccPriKey(int32_t curveId, EC_KEY *ecKey, const char *fieldType, + HcfOpensslEccPriKey **returnObj) { HcfOpensslEccPriKey *returnPriKey = (HcfOpensslEccPriKey *)HcfMalloc(sizeof(HcfOpensslEccPriKey), 0); if (returnPriKey == NULL) { LOGE("Failed to allocate returnPriKey memory!"); return HCF_ERR_MALLOC; } - returnPriKey->base.base.base.destroy = DestroyKey; + char *tmpFieldType = NULL; + if (fieldType != NULL) { + int32_t len = strlen(fieldType); + tmpFieldType = (char *)HcfMalloc(len + 1, 0); + if (tmpFieldType == NULL) { + LOGE("Alloc tmpFieldType memory failed."); + HcfFree(returnPriKey); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tmpFieldType, len, fieldType, len); + } + + returnPriKey->base.base.base.destroy = DestroyEccPriKey; returnPriKey->base.base.base.getClass = GetEccPriKeyClass; returnPriKey->base.base.getAlgorithm = GetEccPriKeyAlgorithm; returnPriKey->base.base.getEncoded = GetEccPriKeyEncoded; returnPriKey->base.base.getFormat = GetEccPriKeyFormat; returnPriKey->base.clearMem = EccPriKeyClearMem; + returnPriKey->base.getAsyKeySpecBigInteger = GetECPriKeySpecBigInteger; + returnPriKey->base.getAsyKeySpecString = GetECPriKeySpecString; + returnPriKey->base.getAsyKeySpecInt = GetECPriKeySpecInt; returnPriKey->curveId = curveId; - returnPriKey->sk = priKey; + returnPriKey->ecKey = ecKey; + returnPriKey->fieldType = tmpFieldType; *returnObj = returnPriKey; return HCF_SUCCESS; } -static HcfResult CreateEccKeyPair(HcfOpensslEccPubKey *pubKey, HcfOpensslEccPriKey *priKey, +static HcfResult PackEccKeyPair(HcfOpensslEccPubKey *pubKey, HcfOpensslEccPriKey *priKey, HcfOpensslEccKeyPair **returnObj) { HcfOpensslEccKeyPair *returnKeyPair = (HcfOpensslEccKeyPair *)HcfMalloc(sizeof(HcfOpensslEccKeyPair), 0); @@ -360,7 +1292,7 @@ static HcfResult CreateEccKeyPair(HcfOpensslEccPubKey *pubKey, HcfOpensslEccPriK return HCF_SUCCESS; } -static HcfResult ConvertEcPubKeyByOpenssl(int32_t curveId, HcfBlob *pubKeyBlob, HcfOpensslEccPubKey **returnPubKey) +static HcfResult ConvertEcPubKey(int32_t curveId, HcfBlob *pubKeyBlob, HcfOpensslEccPubKey **returnPubKey) { const unsigned char *tmpData = (const unsigned char *)(pubKeyBlob->data); EC_KEY *ecKey = Openssl_d2i_EC_PUBKEY(NULL, &tmpData, pubKeyBlob->len); @@ -369,29 +1301,16 @@ static HcfResult ConvertEcPubKeyByOpenssl(int32_t curveId, HcfBlob *pubKeyBlob, HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - const EC_POINT *pubKey = Openssl_EC_KEY_get0_public_key(ecKey); - const EC_GROUP *group = Openssl_EC_KEY_get0_group(ecKey); - if (pubKey == NULL || group == NULL) { - LOGE("ec key is invalid."); - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; - } - EC_POINT *newPubKey = Openssl_EC_POINT_dup(pubKey, group); - Openssl_EC_KEY_free(ecKey); - if (newPubKey == NULL) { - LOGE("copy pubKey fail."); - return HCF_ERR_CRYPTO_OPERATION; - } - int32_t res = CreateEccPubKey(curveId, newPubKey, returnPubKey); + HcfResult res = PackEccPubKey(curveId, ecKey, g_eccGenerateFieldType, returnPubKey); if (res != HCF_SUCCESS) { - Openssl_EC_POINT_free(newPubKey); + LOGE("PackEccPubKey failed."); + Openssl_EC_KEY_free(ecKey); return res; } return HCF_SUCCESS; } -static HcfResult ConvertEcPriKeyByOpenssl(int32_t curveId, HcfBlob *priKeyBlob, HcfOpensslEccPriKey **returnPriKey) +static HcfResult ConvertEcPriKey(int32_t curveId, HcfBlob *priKeyBlob, HcfOpensslEccPriKey **returnPriKey) { const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); EC_KEY *ecKey = Openssl_d2i_ECPrivateKey(NULL, &tmpData, priKeyBlob->len); @@ -400,22 +1319,10 @@ static HcfResult ConvertEcPriKeyByOpenssl(int32_t curveId, HcfBlob *priKeyBlob, HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - const BIGNUM *priKey = Openssl_EC_KEY_get0_private_key(ecKey); - if (priKey == NULL) { - LOGE("ec key is invalid."); - HcfPrintOpensslError(); - Openssl_EC_KEY_free(ecKey); - return HCF_ERR_CRYPTO_OPERATION; - } - BIGNUM *newPriKey = Openssl_BN_dup(priKey); - Openssl_EC_KEY_free(ecKey); - if (newPriKey == NULL) { - LOGE("copy priKey fail."); - return HCF_ERR_CRYPTO_OPERATION; - } - int32_t res = CreateEccPriKey(curveId, newPriKey, returnPriKey); + HcfResult res = PackEccPriKey(curveId, ecKey, g_eccGenerateFieldType, returnPriKey); if (res != HCF_SUCCESS) { - Openssl_BN_clear_free(newPriKey); + LOGE("PackEccPriKey failed."); + Openssl_EC_KEY_free(ecKey); return res; } return HCF_SUCCESS; @@ -424,7 +1331,6 @@ static HcfResult ConvertEcPriKeyByOpenssl(int32_t curveId, HcfBlob *priKeyBlob, static HcfResult EngineConvertEccKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair) { - LOGI("start ..."); (void)params; if ((self == NULL) || (returnKeyPair == NULL)) { LOGE("Invalid input parameter."); @@ -441,24 +1347,24 @@ static HcfResult EngineConvertEccKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec } HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; - int32_t res = HCF_SUCCESS; + HcfResult res = HCF_SUCCESS; HcfOpensslEccPubKey *pubKey = NULL; HcfOpensslEccPriKey *priKey = NULL; HcfOpensslEccKeyPair *keyPair = NULL; do { if (pubKeyValid) { - res = ConvertEcPubKeyByOpenssl(impl->curveId, pubKeyBlob, &pubKey); + res = ConvertEcPubKey(impl->curveId, pubKeyBlob, &pubKey); if (res != HCF_SUCCESS) { break; } } if (priKeyValid) { - res = ConvertEcPriKeyByOpenssl(impl->curveId, priKeyBlob, &priKey); + res = ConvertEcPriKey(impl->curveId, priKeyBlob, &priKey); if (res != HCF_SUCCESS) { break; } } - res = CreateEccKeyPair(pubKey, priKey, &keyPair); + res = PackEccKeyPair(pubKey, priKey, &keyPair); } while (0); if (res != HCF_SUCCESS) { HcfObjDestroy(pubKey); @@ -467,42 +1373,61 @@ static HcfResult EngineConvertEccKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec } *returnKeyPair = (HcfKeyPair *)keyPair; - LOGI("end ..."); return HCF_SUCCESS; } -static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **returnObj) +static HcfResult PackAndAssignPubKey(const HcfAsyKeyGeneratorSpiOpensslEccImpl *impl, const char *fieldType, + EC_KEY *ecKey, HcfPubKey **returnObj) { - LOGI("start ..."); - if ((self == NULL) || (returnObj == NULL)) { - LOGE("Invalid input parameter."); - return HCF_INVALID_PARAMS; - } - if (!IsClassMatch((HcfObjectBase *)self, GetEccKeyPairGeneratorClass())) { - return HCF_INVALID_PARAMS; + HcfOpensslEccPubKey *pubKey = NULL; + HcfResult res = PackEccPubKey(impl->curveId, ecKey, fieldType, &pubKey); + if (res != HCF_SUCCESS) { + return res; } + *returnObj = (HcfPubKey *)pubKey; + return HCF_SUCCESS; +} - HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; - EC_POINT *ecPubKey = NULL; - BIGNUM *ecPriKey = NULL; - int32_t res = NewEcKeyPairByOpenssl(impl->curveId, &ecPubKey, &ecPriKey); +static HcfResult PackAndAssignPriKey(const HcfAsyKeyGeneratorSpiOpensslEccImpl *impl, const char *fieldType, + EC_KEY *ecKey, HcfPriKey **returnObj) +{ + HcfOpensslEccPriKey *priKey = NULL; + HcfResult res = PackEccPriKey(impl->curveId, ecKey, fieldType, &priKey); if (res != HCF_SUCCESS) { return res; } - HcfOpensslEccPubKey *pubKey = NULL; - res = CreateEccPubKey(impl->curveId, ecPubKey, &pubKey); + *returnObj = (HcfPriKey *)priKey; + return HCF_SUCCESS; +} + +static HcfResult CreateAndAssignKeyPair(const HcfAsyKeyGeneratorSpiOpensslEccImpl *impl, const char *fieldType, + EC_KEY *ecKey, HcfKeyPair **returnObj) +{ + EC_KEY *ecPriKey = EC_KEY_dup(ecKey); + if (ecPriKey == NULL) { + LOGE("copy ecKey fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslEccPriKey *priKey = NULL; + HcfResult res = PackEccPriKey(impl->curveId, ecPriKey, fieldType, &priKey); if (res != HCF_SUCCESS) { - Openssl_EC_POINT_free(ecPubKey); - Openssl_BN_clear_free(ecPriKey); + Openssl_EC_KEY_free(ecPriKey); return res; } - HcfOpensslEccPriKey *priKey = NULL; - res = CreateEccPriKey(impl->curveId, ecPriKey, &priKey); + HcfOpensslEccPubKey *pubKey = NULL; + EC_KEY *ecPubKey = EC_KEY_dup(ecKey); + if (ecPubKey == NULL) { + LOGE("copy ecKey fail."); + HcfObjDestroy(priKey); + return HCF_ERR_CRYPTO_OPERATION; + } + res = PackEccPubKey(impl->curveId, ecPubKey, fieldType, &pubKey); if (res != HCF_SUCCESS) { - HcfObjDestroy(pubKey); - Openssl_BN_clear_free(ecPriKey); + HcfObjDestroy(priKey); + Openssl_EC_KEY_free(ecPubKey); return res; } + HcfOpensslEccKeyPair *returnKeyPair = (HcfOpensslEccKeyPair *)HcfMalloc(sizeof(HcfOpensslEccKeyPair), 0); if (returnKeyPair == NULL) { LOGE("Failed to allocate returnKeyPair memory!"); @@ -516,7 +1441,183 @@ static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair * returnKeyPair->base.priKey = (HcfPriKey *)priKey; *returnObj = (HcfKeyPair *)returnKeyPair; - LOGI("end ..."); + return HCF_SUCCESS; +} + +static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **returnObj) +{ + if ((self == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetEccKeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; + EC_KEY *ecKey = NULL; + HcfResult res = NewEcKeyPair(impl->curveId, &ecKey); + if (res != HCF_SUCCESS) { + return res; + } + res = CreateAndAssignKeyPair(impl, g_eccGenerateFieldType, ecKey, returnObj); + Openssl_EC_KEY_free(ecKey); + if (res != HCF_SUCCESS) { + LOGE("CreateAndAssignKeyPair failed."); + return res; + } + return HCF_SUCCESS; +} + +static HcfResult GenKeyPairEcKeyBySpec(const HcfAsyKeyParamsSpec *params, EC_KEY **ecKey) +{ + HcfResult res = HCF_INVALID_PARAMS; + switch (params->specType) { + case HCF_COMMON_PARAMS_SPEC: + res = NewEcKeyPairWithCommSpec((HcfEccCommParamsSpec *)params, ecKey); + break; + case HCF_KEY_PAIR_SPEC: + res = NewEcKeyWithKeyPairSpec((HcfEccKeyPairParamsSpec *)params, ecKey, true); + break; + default: + LOGE("Invaild input spec to gen key pair."); + break; + } + return res; +} + +static HcfResult GenPubKeyEcKeyBySpec(const HcfAsyKeyParamsSpec *params, EC_KEY **ecKey) +{ + HcfResult res = HCF_INVALID_PARAMS; + switch (params->specType) { + case HCF_PUBLIC_KEY_SPEC: + res = NewEcPubKeyWithPubSpec((HcfEccPubKeyParamsSpec *)params, ecKey); + break; + case HCF_KEY_PAIR_SPEC: + res = NewEcKeyWithKeyPairSpec((HcfEccKeyPairParamsSpec *)params, ecKey, false); + break; + default: + LOGE("Invaild input spec to gen pub key"); + break; + } + return res; +} + +static HcfResult GenPriKeyEcKeyBySpec(const HcfAsyKeyParamsSpec *params, EC_KEY **ecKey) +{ + HcfResult res = HCF_INVALID_PARAMS; + switch (params->specType) { + case HCF_PRIVATE_KEY_SPEC: + res = NewEcPriKeyWithPriSpec((HcfEccPriKeyParamsSpec *)params, ecKey); + break; + case HCF_KEY_PAIR_SPEC: + res = NewEcKeyWithKeyPairSpec((HcfEccKeyPairParamsSpec *)params, ecKey, true); + break; + default: + LOGE("Invaild input spec to gen pri key"); + break; + } + return res; +} + +static HcfResult EngineGenerateKeyPairBySpec(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *params, + HcfKeyPair **returnKeyPair) +{ + if ((self == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetEccKeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; + EC_KEY *ecKey = NULL; + HcfResult res = GenKeyPairEcKeyBySpec(params, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("Gen ec key pair with spec failed."); + return res; + } + + // curveId == 0 means no curve to match. + int32_t curveId = Openssl_EC_GROUP_get_curve_name(Openssl_EC_KEY_get0_group(ecKey)); + if (curveId != 0) { + impl->curveId = curveId; + } + // deep copy of ecKey, free ecKey whether it succeed or failed. + res = CreateAndAssignKeyPair(impl, ((HcfEccCommParamsSpec *)params)->field->fieldType, ecKey, returnKeyPair); + Openssl_EC_KEY_free(ecKey); + if (res != HCF_SUCCESS) { + LOGE("CreateAndAssignKeyPair failed."); + return res; + } + + return HCF_SUCCESS; +} + +static HcfResult EngineGeneratePubKeyBySpec(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *params, + HcfPubKey **returnPubKey) +{ + if ((self == NULL) || (returnPubKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetEccKeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; + EC_KEY *ecKey = NULL; + HcfResult res = GenPubKeyEcKeyBySpec(params, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("Gen ec pubKey with spec failed."); + return res; + } + int32_t curveId = Openssl_EC_GROUP_get_curve_name(Openssl_EC_KEY_get0_group(ecKey)); + if (curveId != 0) { + impl->curveId = curveId; + } + res = PackAndAssignPubKey(impl, ((HcfEccCommParamsSpec *)params)->field->fieldType, ecKey, returnPubKey); + if (res != HCF_SUCCESS) { + LOGE("PackAndAssignPubKey failed."); + Openssl_EC_KEY_free(ecKey); + return res; + } + + return HCF_SUCCESS; +} + +static HcfResult EngineGeneratePriKeyBySpec(const HcfAsyKeyGeneratorSpi *self, const HcfAsyKeyParamsSpec *params, + HcfPriKey **returnPriKey) +{ + if ((self == NULL) || (returnPriKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetEccKeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslEccImpl *impl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)self; + EC_KEY *ecKey = NULL; + HcfResult res = GenPriKeyEcKeyBySpec(params, &ecKey); + if (res != HCF_SUCCESS) { + LOGE("Gen ec pubKey with spec failed."); + return res; + } + + int32_t curveId = Openssl_EC_GROUP_get_curve_name(Openssl_EC_KEY_get0_group(ecKey)); + if (curveId != 0) { + impl->curveId = curveId; + } + + res = PackAndAssignPriKey(impl, ((HcfEccCommParamsSpec *)params)->field->fieldType, ecKey, returnPriKey); + if (res != HCF_SUCCESS) { + LOGE("PackAndAssignPriKey failed."); + Openssl_EC_KEY_free(ecKey); + return res; + } + return HCF_SUCCESS; } @@ -526,10 +1627,13 @@ HcfResult HcfAsyKeyGeneratorSpiEccCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGe LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } - int32_t curveId; - if (GetOpensslCurveId(params->bits, &curveId) != HCF_SUCCESS) { - return HCF_INVALID_PARAMS; + int32_t curveId = 0; + if (params->bits != 0) { + if (GetOpensslCurveId(params->bits, &curveId) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } } + HcfAsyKeyGeneratorSpiOpensslEccImpl *returnImpl = (HcfAsyKeyGeneratorSpiOpensslEccImpl *)HcfMalloc( sizeof(HcfAsyKeyGeneratorSpiOpensslEccImpl), 0); if (returnImpl == NULL) { @@ -540,6 +1644,9 @@ HcfResult HcfAsyKeyGeneratorSpiEccCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGe returnImpl->base.base.destroy = DestroyEccKeyPairGenerator; returnImpl->base.engineConvertKey = EngineConvertEccKey; returnImpl->base.engineGenerateKeyPair = EngineGenerateKeyPair; + returnImpl->base.engineGenerateKeyPairBySpec = EngineGenerateKeyPairBySpec; + returnImpl->base.engineGeneratePubKeyBySpec = EngineGeneratePubKeyBySpec; + returnImpl->base.engineGeneratePriKeyBySpec = EngineGeneratePriKeyBySpec; returnImpl->curveId = curveId; *returnObj = (HcfAsyKeyGeneratorSpi *)returnImpl; diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c index 66c08ae..7caa9ea 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -13,20 +13,25 @@ * limitations under the License. */ -#include "rsa_asy_key_generator_openssl.h" +#include "securec.h" +#include "string.h" + +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" #include "openssl/pem.h" #include "openssl/x509.h" + #include "algorithm_parameter.h" #include "asy_key_generator_spi.h" +#include "detailed_rsa_key_params.h" #include "log.h" #include "memory.h" -#include "openssl_class.h" -#include "openssl_common.h" #include "rsa_openssl_common.h" -#include "securec.h" -#include "string.h" #include "utils.h" +#include "rsa_asy_key_generator_openssl.h" + #define OPENSSL_BITS_PER_BYTE 8 #define OPENSSL_RSA_KEYPAIR_CNT 3 #define OPENSSL_RSA_KEYGEN_DEFAULT_PRIMES 2 @@ -34,6 +39,7 @@ #define MIN_KEY_SIZE 512 enum OpensslRsaKeySize { + OPENSSL_RSA_KEY_SIZE_BY_SPEC = 0, OPENSSL_RSA_KEY_SIZE_512 = 512, OPENSSL_RSA_KEY_SIZE_768 = 768, OPENSSL_RSA_KEY_SIZE_1024 = 1024, @@ -65,6 +71,8 @@ typedef struct { static HcfResult CheckRsaKeyGenParams(HcfAsyKeyGenSpiRsaParams *params) { switch (params->bits) { + case OPENSSL_RSA_KEY_SIZE_BY_SPEC: + break; case OPENSSL_RSA_KEY_SIZE_512: case OPENSSL_RSA_KEY_SIZE_768: if (params->primes != OPENSSL_RSA_PRIMES_SIZE_2) { @@ -110,6 +118,126 @@ static const char *GetOpensslKeyPairClass(void) return OPENSSL_RSA_KEYPAIR_CLASS; } +static HcfResult GetRsaPubKeySpecString(const HcfPubKey *self, const AsyKeySpecItem item, + char **returnString) +{ + (void)self; + (void)returnString; + LOGE("Rsa has no string attribute"); + return HCF_NOT_SUPPORT; +} + +static HcfResult GetRsaPubKeySpecInt(const HcfPubKey *self, const AsyKeySpecItem item, + int *returnInt) +{ + (void)self; + (void)returnInt; + LOGE("Rsa has no integer attribute"); + return HCF_NOT_SUPPORT; +} + +static HcfResult GetRsaPriKeySpecString(const HcfPriKey *self, const AsyKeySpecItem item, + char **returnString) +{ + (void)self; + (void)returnString; + LOGE("Rsa has no string attribute"); + return HCF_NOT_SUPPORT; +} + +static HcfResult GetRsaPriKeySpecInt(const HcfPriKey *self, const AsyKeySpecItem item, + int *returnInt) +{ + (void)self; + (void)returnInt; + LOGE("Rsa has no integer attribute"); + return HCF_NOT_SUPPORT; +} + +static HcfResult GetRsaPriKeySpecBigInteger(const HcfPriKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Input params is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_PRIKEY_CLASS)) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfOpensslRsaPriKey *impl = (HcfOpensslRsaPriKey *)self; + HcfResult ret = HCF_INVALID_PARAMS; + if (item == RSA_N_BN) { + const BIGNUM *n = Openssl_RSA_get0_n(impl->sk); + if (n == NULL) { + LOGE("fail to get n"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = BigNumToBigInteger(n, returnBigInteger); + if (ret != HCF_SUCCESS) { + LOGE("fail get RSA Big Integer n"); + return ret; + } + } else if (item == RSA_SK_BN) { + const BIGNUM *d = Openssl_RSA_get0_d(impl->sk); + if (d == NULL) { + LOGE("fail to get sk"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = BigNumToBigInteger(d, returnBigInteger); + if (ret != HCF_SUCCESS) { + LOGE("fail get RSA Big Integer d"); + return ret; + } + } else { + LOGE("Invalid RSA pri key spec"); + return HCF_INVALID_PARAMS; + } + return ret; +} + +static HcfResult GetRsaPubKeySpecBigInteger(const HcfPubKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Input params is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_PUBKEY_CLASS)) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfOpensslRsaPubKey *impl = (HcfOpensslRsaPubKey *)self; + HcfResult ret = HCF_INVALID_PARAMS; + if (item == RSA_N_BN) { + const BIGNUM *n = Openssl_RSA_get0_n(impl->pk); + if (n == NULL) { + LOGE("fail to get n"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = BigNumToBigInteger(n, returnBigInteger); + if (ret != HCF_SUCCESS) { + LOGE("fail get RSA Big Integer n"); + return ret; + } + } else if (item == RSA_PK_BN) { + const BIGNUM *e = Openssl_RSA_get0_e(impl->pk); + if (e == NULL) { + LOGE("fail to get pk"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = BigNumToBigInteger(e, returnBigInteger); + if (ret != HCF_SUCCESS) { + LOGE("fail get RSA Big Integer e"); + return ret; + } + } else { + LOGE("Invalid RSA pub key spec"); + return HCF_INVALID_PARAMS; + } + return ret; +} + static void DestroyPubKey(HcfObjectBase *self) { if (self == NULL) { @@ -121,7 +249,7 @@ static void DestroyPubKey(HcfObjectBase *self) return; } HcfOpensslRsaPubKey *impl = (HcfOpensslRsaPubKey *)self; - RSA_free(impl->pk); + Openssl_RSA_free(impl->pk); impl->pk = NULL; HcfFree(self); } @@ -137,16 +265,12 @@ static void DestroyPriKey(HcfObjectBase *self) return; } HcfOpensslRsaPriKey *impl = (HcfOpensslRsaPriKey*)self; - RSA_free(impl->sk); + // RSA_free func will clear private information + Openssl_RSA_free(impl->sk); impl->sk = NULL; HcfFree(self); } -static void DestroyKey(HcfObjectBase *self) -{ - LOGI("process DestroyKey"); -} - static void DestroyKeyPair(HcfObjectBase *self) { if (self == NULL) { @@ -158,10 +282,14 @@ static void DestroyKeyPair(HcfObjectBase *self) return; } HcfOpensslRsaKeyPair *impl = (HcfOpensslRsaKeyPair*)self; - DestroyPriKey((HcfObjectBase *)impl->base.priKey); - impl->base.priKey = NULL; - DestroyPubKey((HcfObjectBase *)impl->base.pubKey); - impl->base.pubKey = NULL; + if (impl->base.pubKey != NULL) { + DestroyPubKey((HcfObjectBase *)impl->base.pubKey); + impl->base.pubKey = NULL; + } + if (impl->base.priKey != NULL) { + DestroyPriKey((HcfObjectBase *)impl->base.priKey); + impl->base.priKey = NULL; + } HcfFree(self); } @@ -183,7 +311,7 @@ static HcfResult CopyMemFromBIO(BIO *bio, HcfBlob *outBlob) LOGE("Malloc mem for blob fail."); return HCF_ERR_MALLOC; } - if (BIO_read(bio, blob.data, blob.len) <= 0) { + if (Openssl_BIO_read(bio, blob.data, blob.len) <= 0) { LOGE("Bio read fail"); HcfPrintOpensslError(); HcfFree(blob.data); @@ -197,7 +325,7 @@ static HcfResult CopyMemFromBIO(BIO *bio, HcfBlob *outBlob) static HcfResult ConvertPubKeyFromX509(HcfBlob *x509Blob, RSA **rsa) { uint8_t *temp = x509Blob->data; - RSA *tempRsa = d2i_RSA_PUBKEY(NULL, (const unsigned char **)&temp, x509Blob->len); + RSA *tempRsa = Openssl_d2i_RSA_PUBKEY(NULL, (const unsigned char **)&temp, x509Blob->len); if (tempRsa == NULL) { LOGE("d2i_RSA_PUBKEY fail."); return HCF_ERR_CRYPTO_OPERATION; @@ -208,29 +336,29 @@ static HcfResult ConvertPubKeyFromX509(HcfBlob *x509Blob, RSA **rsa) static HcfResult ConvertPriKeyFromPKCS8(HcfBlob *pkcs8Blob, RSA **rsa) { - uint8_t *temp = pkcs8Blob->data; - EVP_PKEY *pKey = d2i_AutoPrivateKey(NULL, (const unsigned char **)&temp, pkcs8Blob->len); + const unsigned char *temp = (const unsigned char *)pkcs8Blob->data; + EVP_PKEY *pKey = Openssl_d2i_AutoPrivateKey(NULL, &temp, pkcs8Blob->len); if (pKey == NULL) { LOGE("d2i_AutoPrivateKey fail."); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - RSA *tmpRsa = EVP_PKEY_get1_RSA(pKey); + RSA *tmpRsa = Openssl_EVP_PKEY_get1_RSA(pKey); if (tmpRsa == NULL) { - LOGE("EVP_PKEY_get0_RSA fail"); + LOGE("EVP_PKEY_get1_RSA fail"); HcfPrintOpensslError(); - EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_free(pKey); return HCF_ERR_CRYPTO_OPERATION; } *rsa = tmpRsa; - EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_free(pKey); return HCF_SUCCESS; } static HcfResult EncodePubKeyToX509(RSA *rsa, HcfBlob *returnBlob) { unsigned char *tempData = NULL; - int len = i2d_RSA_PUBKEY(rsa, &tempData); + int len = Openssl_i2d_RSA_PUBKEY(rsa, &tempData); if (len <= 0) { LOGE("i2d_RSA_PUBKEY fail"); HcfPrintOpensslError(); @@ -249,14 +377,14 @@ static HcfResult EncodePriKeyToPKCS8(RSA *rsa, HcfBlob *returnBlob) return HCF_ERR_CRYPTO_OPERATION; } HcfResult ret = HCF_SUCCESS; - BIO *bio = BIO_new(BIO_s_mem()); + BIO *bio = Openssl_BIO_new(Openssl_BIO_s_mem()); if (bio == NULL) { LOGE("BIO new fail."); HcfPrintOpensslError(); ret = HCF_ERR_CRYPTO_OPERATION; goto ERR2; } - if (i2d_PKCS8PrivateKey_bio(bio, pKey, NULL, NULL, 0, NULL, NULL) != HCF_OPENSSL_SUCCESS) { + if (Openssl_i2d_PKCS8PrivateKey_bio(bio, pKey, NULL, NULL, 0, NULL, NULL) != HCF_OPENSSL_SUCCESS) { LOGE("i2b_PrivateKey_bio fail."); HcfPrintOpensslError(); ret = HCF_ERR_CRYPTO_OPERATION; @@ -268,9 +396,9 @@ static HcfResult EncodePriKeyToPKCS8(RSA *rsa, HcfBlob *returnBlob) goto ERR1; } ERR1: - BIO_free_all(bio); + Openssl_BIO_free_all(bio); ERR2: - EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_free(pKey); return ret; } @@ -300,6 +428,13 @@ static HcfResult GetPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) return HCF_INVALID_PARAMS; } HcfOpensslRsaPriKey *impl = (HcfOpensslRsaPriKey *)self; + const BIGNUM *p = NULL; + const BIGNUM *q = NULL; + Openssl_RSA_get0_factors(impl->sk, &p, &q); + if (p == NULL || q == NULL) { + LOGE("RSA private key missing p, q, not support to get encoded PK"); + return HCF_NOT_SUPPORT; + } return EncodePriKeyToPKCS8(impl->sk, returnBlob); } @@ -361,8 +496,9 @@ static void ClearPriKeyMem(HcfPriKey *self) LOGE("Class not match"); return; } - RSA_free(((HcfOpensslRsaPriKey *)self)->sk); - ((HcfOpensslRsaPriKey *)self)->sk = NULL; + HcfOpensslRsaPriKey *impl = (HcfOpensslRsaPriKey *)self; + Openssl_RSA_free(impl->sk); + impl->sk = NULL; } static HcfResult PackPubKey(RSA *rsaPubKey, HcfOpensslRsaPubKey **retPubKey) @@ -377,15 +513,19 @@ static HcfResult PackPubKey(RSA *rsaPubKey, HcfOpensslRsaPubKey **retPubKey) return HCF_ERR_MALLOC; } (*retPubKey)->pk = rsaPubKey; - (*retPubKey)->bits = RSA_bits(rsaPubKey); + (*retPubKey)->bits = Openssl_RSA_bits(rsaPubKey); (*retPubKey)->base.base.getAlgorithm = GetPubKeyAlgorithm; (*retPubKey)->base.base.getEncoded = GetPubKeyEncoded; (*retPubKey)->base.base.getFormat = GetPubKeyFormat; (*retPubKey)->base.base.base.getClass = GetOpensslPubkeyClass; - (*retPubKey)->base.base.base.destroy = DestroyKey; + (*retPubKey)->base.base.base.destroy = DestroyPubKey; + (*retPubKey)->base.getAsyKeySpecBigInteger = GetRsaPubKeySpecBigInteger; + (*retPubKey)->base.getAsyKeySpecString = GetRsaPubKeySpecString; + (*retPubKey)->base.getAsyKeySpecInt = GetRsaPubKeySpecInt; return HCF_SUCCESS; } +// spec中,prikey只有n,e,d,没有p, q static HcfResult PackPriKey(RSA *rsaPriKey, HcfOpensslRsaPriKey **retPriKey) { if (retPriKey == NULL || rsaPriKey == NULL) { @@ -398,13 +538,16 @@ static HcfResult PackPriKey(RSA *rsaPriKey, HcfOpensslRsaPriKey **retPriKey) return HCF_ERR_MALLOC; } (*retPriKey)->sk = rsaPriKey; - (*retPriKey)->bits = RSA_bits(rsaPriKey); + (*retPriKey)->bits = Openssl_RSA_bits(rsaPriKey); (*retPriKey)->base.clearMem = ClearPriKeyMem; (*retPriKey)->base.base.getAlgorithm = GetPriKeyAlgorithm; (*retPriKey)->base.base.getEncoded = GetPriKeyEncoded; (*retPriKey)->base.base.getFormat = GetPriKeyFormat; (*retPriKey)->base.base.base.getClass = GetOpensslPrikeyClass; - (*retPriKey)->base.base.base.destroy = DestroyKey; + (*retPriKey)->base.base.base.destroy = DestroyPriKey; + (*retPriKey)->base.getAsyKeySpecBigInteger = GetRsaPriKeySpecBigInteger; + (*retPriKey)->base.getAsyKeySpecString = GetRsaPriKeySpecString; + (*retPriKey)->base.getAsyKeySpecInt = GetRsaPriKeySpecInt; return HCF_SUCCESS; } @@ -420,7 +563,7 @@ static HcfResult DuplicatePkAndSkFromRSA(RSA *rsa, RSA **pubKey, RSA **priKey) } if (DuplicateRsa(rsa, true, priKey) != HCF_SUCCESS) { LOGE("Duplicate prikey rsa fail"); - RSA_free(*pubKey); + Openssl_RSA_free(*pubKey); *pubKey = NULL; return HCF_ERR_CRYPTO_OPERATION; } @@ -442,8 +585,8 @@ static HcfResult PackKeyPair(RSA *rsa, uint32_t realBits, HcfOpensslRsaKeyPair * *retKeyPair = (HcfOpensslRsaKeyPair *)HcfMalloc(sizeof(HcfOpensslRsaKeyPair), 0); if (*retKeyPair == NULL) { LOGE("Malloc keypair fail"); - RSA_free(pubKey); - RSA_free(priKey); + Openssl_RSA_free(pubKey); + Openssl_RSA_free(priKey); return HCF_ERR_MALLOC; } HcfOpensslRsaPriKey *priKeyImpl = NULL; @@ -466,14 +609,14 @@ static HcfResult PackKeyPair(RSA *rsa, uint32_t realBits, HcfOpensslRsaKeyPair * ERR1: HcfFree(pubKeyImpl); ERR2: - RSA_free(pubKey); - RSA_free(priKey); + Openssl_RSA_free(pubKey); + Openssl_RSA_free(priKey); HcfFree(*retKeyPair); *retKeyPair = NULL; return ret; } -static HcfResult GenerateKeyPairByOpenssl(HcfAsyKeyGenSpiRsaParams *params, HcfKeyPair **keyPair) +static HcfResult GenerateKeyPair(HcfAsyKeyGenSpiRsaParams *params, HcfKeyPair **keyPair) { // check input params is valid HcfResult res = CheckRsaKeyGenParams(params); @@ -482,25 +625,25 @@ static HcfResult GenerateKeyPairByOpenssl(HcfAsyKeyGenSpiRsaParams *params, HcfK return HCF_INVALID_PARAMS; } // Generate keyPair RSA - RSA *rsa = RSA_new(); + RSA *rsa = Openssl_RSA_new(); if (rsa == NULL) { LOGE("new RSA fail."); return HCF_ERR_MALLOC; } - LOGI("keygen bits is %d, primes is %d", params->bits, GetRealPrimes(params->primes)); + LOGD("keygen bits is %d, primes is %d", params->bits, GetRealPrimes(params->primes)); if (GetRealPrimes(params->primes) != OPENSSL_RSA_KEYGEN_DEFAULT_PRIMES) { if (RSA_generate_multi_prime_key(rsa, params->bits, GetRealPrimes(params->primes), params->pubExp, NULL) != HCF_OPENSSL_SUCCESS) { LOGE("Generate multi-primes rsa key fail"); HcfPrintOpensslError(); - RSA_free(rsa); + Openssl_RSA_free(rsa); return HCF_ERR_CRYPTO_OPERATION; } } else { if (RSA_generate_key_ex(rsa, params->bits, params->pubExp, NULL) != HCF_OPENSSL_SUCCESS) { LOGE("Generate rsa key fail"); HcfPrintOpensslError(); - RSA_free(rsa); + Openssl_RSA_free(rsa); return HCF_ERR_CRYPTO_OPERATION; } } @@ -510,18 +653,17 @@ static HcfResult GenerateKeyPairByOpenssl(HcfAsyKeyGenSpiRsaParams *params, HcfK res = PackKeyPair(rsa, params->bits, &keyPairImpl); if (res != HCF_SUCCESS) { LOGE("Generate keyPair fail."); - RSA_free(rsa); + Openssl_RSA_free(rsa); return res; } *keyPair = (HcfKeyPair *)keyPairImpl; - RSA_free(rsa); - LOGI("Generate keypair success."); + Openssl_RSA_free(rsa); + LOGD("Generate keypair success."); return res; } static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **keyPair) { - LOGI("EngineGenerateKeyPair start"); if (self == NULL || keyPair == NULL) { LOGE("Invalid params."); return HCF_INVALID_PARAMS; @@ -531,7 +673,7 @@ static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair * return HCF_INVALID_PARAMS; } HcfAsyKeyGeneratorSpiRsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiRsaOpensslImpl *)self; - return GenerateKeyPairByOpenssl(impl->params, keyPair); + return GenerateKeyPair(impl->params, keyPair); } static const char *GetKeyGeneratorClass(void) @@ -541,7 +683,6 @@ static const char *GetKeyGeneratorClass(void) static void DestroyKeyGeneratorSpiImpl(HcfObjectBase *self) { - LOGI("DestroyKeyGeneratorSpiImpl start."); if (self == NULL) { LOGE("DestroyKeyGeneratorSpiImpl is null"); return; @@ -553,12 +694,11 @@ static void DestroyKeyGeneratorSpiImpl(HcfObjectBase *self) // destroy pubExp first. HcfAsyKeyGeneratorSpiRsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiRsaOpensslImpl *)self; if (impl->params != NULL && impl->params->pubExp != NULL) { - BN_free(impl->params->pubExp); + Openssl_BN_free(impl->params->pubExp); } HcfFree(impl->params); impl->params = NULL; HcfFree(self); - LOGI("DestroyKeyGeneratorSpiImpl end."); } static HcfResult ConvertPubKey(HcfBlob *pubKeyBlob, HcfOpensslRsaPubKey **pubkeyRet) @@ -577,7 +717,7 @@ static HcfResult ConvertPubKey(HcfBlob *pubKeyBlob, HcfOpensslRsaPubKey **pubkey *pubkeyRet = pubKey; return ret; ERR: - RSA_free(rsaPk); + Openssl_RSA_free(rsaPk); return ret; } @@ -597,14 +737,13 @@ static HcfResult ConvertPriKey(HcfBlob *priKeyBlob, HcfOpensslRsaPriKey **priKey *priKeyRet = priKey; return ret; ERR: - RSA_free(rsaSk); + Openssl_RSA_free(rsaSk); return ret; } static HcfResult EngineConvertKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair) { - LOGI("EngineConvertKey start"); (void)params; if ((self == NULL) || (returnKeyPair == NULL) || ((pubKeyBlob == NULL) && (priKeyBlob == NULL))) { LOGE("ConvertKeyParams is invalid."); @@ -645,32 +784,267 @@ static HcfResult EngineConvertKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *pa keyPair->base.base.getClass = GetOpensslKeyPairClass; keyPair->base.base.destroy = DestroyKeyPair; *returnKeyPair = (HcfKeyPair *)keyPair; - LOGI("EngineConvertKey end"); return HCF_SUCCESS; } -static HcfResult SetDefaultValue(HcfAsyKeyGenSpiRsaParams *params) +static HcfResult ParseRsaBnFromBin(const HcfAsyKeyParamsSpec *paramsSpec, BIGNUM **n, + BIGNUM **e, BIGNUM **d) { - if (params->primes == 0) { - LOGI("set default primes 2"); - params->primes = OPENSSL_RSA_PRIMES_SIZE_2; + // when meeting the fail situation, the BIGNUM will be NULL and other BIGNUM will be freeed in InitRsaStructByBin(); + if (BigIntegerToBigNum(&((HcfRsaCommParamsSpec *)paramsSpec)->n, n) != HCF_SUCCESS) { + LOGE("Rsa new BN n fail."); + return HCF_ERR_CRYPTO_OPERATION; } - if (params->pubExp == NULL) { - BIGNUM *e = BN_new(); - if (e == NULL) { - LOGE("Rsa new BN fail."); + if (paramsSpec->specType == HCF_KEY_PAIR_SPEC) { + if (BigIntegerToBigNum(&((HcfRsaKeyPairParamsSpec *)paramsSpec)->pk, e) != HCF_SUCCESS) { + LOGE("Rsa new BN e fail."); + Openssl_BN_free(*n); + *n = NULL; return HCF_ERR_CRYPTO_OPERATION; } - if (BN_set_word(e, RSA_F4) != HCF_OPENSSL_SUCCESS) { - LOGE("Rsa keygen Bn_set_word fail."); - BN_free(e); + if (BigIntegerToBigNum(&((HcfRsaKeyPairParamsSpec *)paramsSpec)->sk, d) != HCF_SUCCESS) { + LOGE("Rsa new BN d fail."); + Openssl_BN_free(*n); + *n = NULL; + Openssl_BN_free(*e); + *e = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + } + if (paramsSpec->specType == HCF_PUBLIC_KEY_SPEC) { + if (BigIntegerToBigNum(&((HcfRsaPubKeyParamsSpec *)paramsSpec)->pk, e) != HCF_SUCCESS) { + LOGE("Rsa new BN e fail."); + Openssl_BN_free(*n); + *n = NULL; return HCF_ERR_CRYPTO_OPERATION; } - params->pubExp = e; } return HCF_SUCCESS; } +static RSA *InitRsaStructByBin(const HcfAsyKeyParamsSpec *paramsSpec) +{ + BIGNUM *n = NULL; + BIGNUM *e = NULL; + BIGNUM *d = NULL; + RSA *rsa = NULL; + + if (ParseRsaBnFromBin(paramsSpec, &n, &e, &d) != HCF_SUCCESS) { + LOGE("ParseRsaBnFromBin fail"); + return rsa; + } + rsa = Openssl_RSA_new(); + if (rsa == NULL) { + Openssl_BN_free(n); + Openssl_BN_free(e); + Openssl_BN_clear_free(d); + LOGE("new RSA fail"); + return rsa; + } + // if set0 success, RSA object will take the owner of n, e, d and will free them. + // as a new RSA object, in RSA_set0_key(), n and e cannot be NULL. + if (Openssl_RSA_set0_key(rsa, n, e, d) != HCF_OPENSSL_SUCCESS) { + LOGE("set RSA fail"); + HcfPrintOpensslError(); + Openssl_BN_free(n); + Openssl_BN_free(e); + Openssl_BN_clear_free(d); + Openssl_RSA_free(rsa); + rsa = NULL; + return rsa; + } + return rsa; +} + +static HcfResult GenerateKeyPairBySpec(const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **keyPair) +{ + // Generate keyPair RSA by spec + RSA *rsa = InitRsaStructByBin(paramsSpec); + if (rsa == NULL) { + LOGE("Generate RSA fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslRsaKeyPair *keyPairImpl = (HcfOpensslRsaKeyPair *)HcfMalloc(sizeof(HcfOpensslRsaKeyPair), 0); + if (keyPairImpl == NULL) { + LOGE("Malloc keyPair fail."); + Openssl_RSA_free(rsa); + return HCF_ERR_MALLOC; + } + // devided to pk and sk; + HcfOpensslRsaPubKey *pubKeyImpl = NULL; + HcfOpensslRsaPriKey *priKeyImpl = NULL; + + RSA *pubKeyRsa = NULL; + if (DuplicateRsa(rsa, false, &pubKeyRsa) != HCF_SUCCESS) { + LOGE("Duplicate pubKey rsa fail"); + Openssl_RSA_free(rsa); + HcfFree(keyPairImpl); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfResult res = PackPubKey(pubKeyRsa, &pubKeyImpl); + if (res != HCF_SUCCESS) { + LOGE("pack pup key fail."); + Openssl_RSA_free(rsa); + Openssl_RSA_free(pubKeyRsa); + HcfFree(keyPairImpl); + return res; + } + + res = PackPriKey(rsa, &priKeyImpl); + if (res != HCF_SUCCESS) { + LOGE("pack pri key fail."); + Openssl_RSA_free(rsa); + Openssl_RSA_free(pubKeyRsa); + HcfFree(keyPairImpl); + HcfFree(pubKeyImpl); + return res; + } + keyPairImpl->base.priKey = (HcfPriKey *)priKeyImpl; + keyPairImpl->base.pubKey = (HcfPubKey *)pubKeyImpl; + keyPairImpl->base.base.getClass = GetOpensslKeyPairClass; + keyPairImpl->base.base.destroy = DestroyKeyPair; + *keyPair = (HcfKeyPair *)keyPairImpl; + LOGD("Generate keypair success."); + return res; +} + +static HcfResult GeneratePubKeyBySpec(const HcfAsyKeyParamsSpec *paramsSpec, HcfPubKey **pubKey) +{ + RSA *rsa = InitRsaStructByBin(paramsSpec); + if (rsa == NULL) { + LOGE("Generate RSA fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + RSA *pubKeyRsa = NULL; + if (DuplicateRsa(rsa, false, &pubKeyRsa) != HCF_SUCCESS) { + LOGE("Duplicate pubKey rsa fail"); + Openssl_RSA_free(rsa); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslRsaPubKey *pubKeyImpl = NULL; + HcfResult res = PackPubKey(pubKeyRsa, &pubKeyImpl); + if (res != HCF_SUCCESS) { + LOGE("pack pup key fail."); + Openssl_RSA_free(rsa); + Openssl_RSA_free(pubKeyRsa); + return res; + } + *pubKey = (HcfPubKey *)pubKeyImpl; + Openssl_RSA_free(rsa); + LOGD("Generate pub key success."); + return res; +} + +static HcfResult GeneratePriKeyBySpec(const HcfAsyKeyParamsSpec *paramsSpec, HcfPriKey **priKey) +{ + RSA *rsa = InitRsaStructByBin(paramsSpec); + if (rsa == NULL) { + LOGE("Generate RSA fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslRsaPriKey *priKeyImpl = NULL; + HcfResult res = PackPriKey(rsa, &priKeyImpl); + if (res != HCF_SUCCESS) { + LOGE("pack pri key fail."); + Openssl_RSA_free(rsa); + return res; + } + *priKey = (HcfPriKey *)priKeyImpl; + LOGD("Generate pri key success."); + return res; +} + +static HcfResult EngineGenerateKeyPairBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + if ((self == NULL) || (returnKeyPair == NULL) || (paramsSpec == NULL)) { + LOGE("GenerateKeyPairBySpec Params is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_GENERATOR_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (strcmp(paramsSpec->algName, RSA_ALG_NAME) != 0) { + LOGE("Spec alg not match."); + return HCF_INVALID_PARAMS; + } + if (paramsSpec->specType != HCF_KEY_PAIR_SPEC) { + LOGE("Spec type not match."); + return HCF_INVALID_PARAMS; + } + return GenerateKeyPairBySpec(paramsSpec, returnKeyPair); +} + +static HcfResult EngineGeneratePubKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPubKey **returnPubKey) +{ + if ((self == NULL) || (returnPubKey == NULL) || (paramsSpec == NULL)) { + LOGE("GeneratePubKeyBySpec Params is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_GENERATOR_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (strcmp(paramsSpec->algName, RSA_ALG_NAME) != 0) { + LOGE("Spec alg not match."); + return HCF_INVALID_PARAMS; + } + if (paramsSpec->specType != HCF_PUBLIC_KEY_SPEC && paramsSpec->specType != HCF_KEY_PAIR_SPEC) { + LOGE("Spec not match."); + return HCF_INVALID_PARAMS; + } + return GeneratePubKeyBySpec(paramsSpec, returnPubKey); +} + +static HcfResult EngineGeneratePriKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPriKey **returnPriKey) +{ + if ((self == NULL) || (returnPriKey == NULL) || (paramsSpec == NULL)) { + LOGE("GeneratePriKeyBySpec Params is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_GENERATOR_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + if (strcmp(paramsSpec->algName, RSA_ALG_NAME) != 0) { + LOGE("Spec alg not match."); + return HCF_INVALID_PARAMS; + } + if (paramsSpec->specType != HCF_KEY_PAIR_SPEC) { + LOGE("Spec not match."); + return HCF_INVALID_PARAMS; + } + return GeneratePriKeyBySpec(paramsSpec, returnPriKey); +} + +static HcfResult SetDefaultValue(HcfAsyKeyGenSpiRsaParams *params) +{ + if (params->primes == 0) { + LOGD("set default primes 2"); + params->primes = OPENSSL_RSA_PRIMES_SIZE_2; + } + if (params->pubExp != NULL) { + LOGE("RSA has pubKey default unexpectedly."); + return HCF_SUCCESS; + } + BIGNUM *e = Openssl_BN_new(); + if (e == NULL) { + LOGE("RSA new BN fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_BN_set_word(e, RSA_F4) != HCF_OPENSSL_SUCCESS) { + LOGE("RSA keygen Bn_set_word fail."); + Openssl_BN_free(e); + return HCF_ERR_CRYPTO_OPERATION; + } + params->pubExp = e; + return HCF_SUCCESS; +} + static HcfResult DecodeParams(HcfAsyKeyGenParams *from, HcfAsyKeyGenSpiRsaParams **to) { *to = (HcfAsyKeyGenSpiRsaParams *)HcfMalloc(sizeof(HcfAsyKeyGenSpiRsaParams), 0); @@ -700,7 +1074,6 @@ static HcfResult DecodeParams(HcfAsyKeyGenParams *from, HcfAsyKeyGenSpiRsaParams HcfResult HcfAsyKeyGeneratorSpiRsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **generator) { - LOGI("HcfAsyKeyGeneratorSpiRsaCreate start."); if (params == NULL || generator == NULL) { LOGE("Invalid input, params is invalid or generator is null."); return HCF_INVALID_PARAMS; @@ -720,7 +1093,9 @@ HcfResult HcfAsyKeyGeneratorSpiRsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGe impl->base.base.destroy = DestroyKeyGeneratorSpiImpl; impl->base.engineGenerateKeyPair = EngineGenerateKeyPair; impl->base.engineConvertKey = EngineConvertKey; + impl->base.engineGenerateKeyPairBySpec = EngineGenerateKeyPairBySpec; + impl->base.engineGeneratePubKeyBySpec = EngineGeneratePubKeyBySpec; + impl->base.engineGeneratePriKeyBySpec = EngineGeneratePriKeyBySpec; *generator = (HcfAsyKeyGeneratorSpi *)impl; - LOGI("HcfAsyKeyGeneratorSpiRsaCreate end."); return HCF_SUCCESS; } diff --git a/plugin/openssl_plugin/key/sym_key_generator/inc/sym_common_defines.h b/plugin/openssl_plugin/key/sym_key_generator/inc/sym_common_defines.h index ec8d3a0..9cae020 100644 --- a/plugin/openssl_plugin/key/sym_key_generator/inc/sym_common_defines.h +++ b/plugin/openssl_plugin/key/sym_key_generator/inc/sym_common_defines.h @@ -21,7 +21,7 @@ #include "params_parser.h" typedef struct { - HCF_ALG_VALUE algo; + HcfAlgValue algo; int keySize; } SymKeyAttr; diff --git a/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c b/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c index 9580590..3e1ed3e 100644 --- a/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c +++ b/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c @@ -13,13 +13,13 @@ * limitations under the License. */ -#include #include "log.h" #include "memory.h" #include "result.h" #include "securec.h" #include "utils.h" #include "sym_common_defines.h" +#include "openssl_adapter.h" #include "openssl_common.h" #define MAX_KEY_STR_SIZE 12 @@ -119,7 +119,7 @@ static HcfResult RandomSymmKey(int32_t keyLen, HcfBlob *symmKey) LOGE("keyMaterial malloc failed!"); return HCF_ERR_MALLOC; } - int ret = RAND_priv_bytes(keyMaterial, keyLen); + int ret = Openssl_RAND_priv_bytes(keyMaterial, keyLen); if (ret != HCF_OPENSSL_SUCCESS) { LOGE("RAND_bytes failed!"); HcfPrintOpensslError(); @@ -137,7 +137,7 @@ static HcfResult HcfSymmKeySpiCreate(int32_t keyLen, SymKeyImpl *symKey) LOGE("Invalid input parameter!"); return HCF_INVALID_PARAMS; } - int32_t res = RandomSymmKey(keyLen, &symKey->keyMaterial); + HcfResult res = RandomSymmKey(keyLen, &symKey->keyMaterial); if (res != HCF_SUCCESS) { LOGE("RandomSymmKey failed!"); return res; @@ -197,7 +197,7 @@ static char *GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl *impl) } int32_t aesSize = strlen(AES_ALG_NAME); int32_t desSize = strlen(DES_ALG_NAME); - HCF_ALG_VALUE type = impl->attr.algo; + HcfAlgValue type = impl->attr.algo; if (type == HCF_ALG_AES) { if (strcpy_s(algoName, MAX_KEY_STR_SIZE, AES_ALG_NAME) != EOK) { LOGE("aes algoName strcpy_s failed!"); @@ -259,7 +259,7 @@ static HcfResult GenerateSymmKey(HcfSymKeyGeneratorSpi *self, HcfSymKey **symmKe return HCF_ERR_MALLOC; } HcfSymKeyGeneratorSpiOpensslImpl *impl = (HcfSymKeyGeneratorSpiOpensslImpl *)self; - int32_t res = HcfSymmKeySpiCreate(impl->attr.keySize / KEY_BIT, returnSymmKey); + HcfResult res = HcfSymmKeySpiCreate(impl->attr.keySize / KEY_BIT, returnSymmKey); if (res != HCF_SUCCESS) { HcfFree(returnSymmKey); return res; @@ -297,7 +297,7 @@ static HcfResult ConvertSymmKey(HcfSymKeyGeneratorSpi *self, const HcfBlob *key, LOGE("Failed to allocate returnKeyPair memory!"); return HCF_ERR_MALLOC; } - int32_t res = CopySymmKey(key, &returnSymmKey->keyMaterial); + HcfResult res = CopySymmKey(key, &returnSymmKey->keyMaterial); if (res != HCF_SUCCESS) { HcfFree(returnSymmKey); return res; diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 84947f6..528d9c9 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022-2023 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 @@ -20,18 +20,18 @@ plugin_inc_path = [ "${plugin_path}/openssl_plugin/common/inc", "${plugin_path}/openssl_plugin/key/asy_key_generator/inc", "${plugin_path}/openssl_plugin/key/sym_key_generator/inc", - "${plugin_path}/openssl_plugin/crypto_operation/aes/inc", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/inc", "${plugin_path}/openssl_plugin/crypto_operation/hmac/inc", "${plugin_path}/openssl_plugin/crypto_operation/key_agreement/inc", "${plugin_path}/openssl_plugin/crypto_operation/signature/inc", "${plugin_path}/openssl_plugin/crypto_operation/md/inc", - "${plugin_path}/openssl_plugin/crypto_operation/rsa/inc", - "${plugin_path}/openssl_plugin/rand/inc", + "${plugin_path}/openssl_plugin/crypto_operation/rand/inc", "//base/security/crypto_framework/frameworks/spi", "//base/security/crypto_framework/common/inc", ] plugin_signature_files = [ + "${plugin_path}/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c", ] @@ -43,6 +43,7 @@ plugin_common_files = [ ] plugin_asy_key_generator_files = [ + "${plugin_path}/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c", "${plugin_path}/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c", "${plugin_path}/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c", ] @@ -54,16 +55,17 @@ plugin_sym_key_files = [ ] plugin_cipher_files = [ - "${plugin_path}/openssl_plugin/crypto_operation/rsa/src/cipher_rsa_openssl.c", - "${plugin_path}/openssl_plugin/crypto_operation/aes/src/cipher_3des_openssl.c", - "${plugin_path}/openssl_plugin/crypto_operation/aes/src/cipher_aes_openssl.c", - "${plugin_path}/openssl_plugin/crypto_operation/aes/src/cipher_aes_common.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_rsa_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_3des_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c", ] plugin_hmac_files = [ "${plugin_path}/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c" ] -plugin_rand_files = [ "${plugin_path}/openssl_plugin/rand/src/rand_openssl.c" ] +plugin_rand_files = + [ "${plugin_path}/openssl_plugin/crypto_operation/rand/src/rand_openssl.c" ] plugin_md_files = [ "${plugin_path}/openssl_plugin/crypto_operation/md/src/md_openssl.c" ] diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn index b72ab87..fd6cdc1 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022 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 diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/corpus/init b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/corpus/init index c49c21a..2be750d 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/corpus/init +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/corpus/init @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (C) 2022 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 diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp index addfee1..f37d85a 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022 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 diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.h b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.h index b614394..d23ca79 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.h +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022 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 diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/project.xml b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/project.xml index 6e8ad2c..5e3b584 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/project.xml +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/project.xml @@ -1,5 +1,5 @@ -