From 0b4308b948aa29e30208cd116b2989dbdd87714d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 25 Aug 2022 22:42:11 -0700 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9License?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cmake.yml | 74 +- .github/workflows/cygwin.yml | 62 +- .gitignore | 433 +- CMakeLists.txt | 552 +- LICENSE | 352 +- README.md | 110 +- certs/README.md | 8 +- ...t Financial Certification Authority S1.pem | 36 +- certs/ca/TJCA.pem | 36 +- certs/ca/Taier CA.pem | 32 +- certs/rootca/Civil Servant ROOT.pem | 24 +- certs/rootca/Device ROOT.pem | 24 +- certs/rootca/ROOTCA.pem | 24 +- demos/cademo.sh | 44 +- demos/certdemo.sh | 68 +- demos/cmsdemo.sh | 34 +- demos/pbkdf2demo.sh | 10 +- demos/reqdemo.sh | 38 +- demos/sm2/Makefile | 36 +- demos/sm2/sm2_encrypt_demo.c | 63 +- demos/sm2/sm2_keygen_demo.c | 41 +- demos/sm2/sm2_private_key_demo.c | 47 +- demos/sm2/sm2_private_key_parse_demo.c | 67 +- demos/sm2/sm2_public_key_demo.c | 51 +- demos/sm2/sm2_sign_ctx_demo.c | 109 +- demos/sm2/sm2_sign_demo.c | 71 +- demos/sm2/sm2keyparse.c | 69 +- demos/sm2demo.sh | 20 +- demos/sm3/CMakeLists.txt | 24 +- demos/sm3/Makefile | 18 +- demos/sm3/sm3_demo.c | 57 +- demos/sm3/sm3_hmac_demo.c | 87 +- demos/sm3/sm3_kdf_demo.c | 59 +- demos/sm3demo.sh | 20 +- demos/sm4/Makefile | 44 +- demos/sm4/sm4_cbc_decrypt_update_demo.c | 87 +- demos/sm4/sm4_cbc_demo.c | 129 +- demos/sm4/sm4_cbc_encrypt_update_demo.c | 87 +- demos/sm4/sm4_cbc_padding_demo.c | 195 +- demos/sm4/sm4_ctr_demo.c | 137 +- demos/sm4/sm4_ctr_encrypt_update_demo.c | 87 +- demos/sm4/sm4_demo.c | 113 +- demos/sm4/sm4_gcm_demo.c | 165 +- demos/sm4demo.sh | 24 +- demos/sm9/Makefile | 20 +- demos/sm9/sm9_encrypt_demo.c | 79 +- demos/sm9/sm9_keygen_demo.c | 55 +- demos/sm9/sm9_sign_demo.c | 91 +- demos/sm9demo.sh | 24 +- demos/tlcp/Makefile | 16 +- demos/tlcp/tlcp_get.c | 203 +- demos/tlcp/tlcp_post.c | 213 +- demos/tlcp/url_parser.c | 817 +-- demos/tlcp/url_parser.h | 45 +- demos/tlcp_client.sh | 16 +- demos/tlcp_server.sh | 78 +- demos/tlcpdemo.sh | 72 +- demos/tls12demo.sh | 60 +- demos/tls13demo.sh | 60 +- demos/zuc/Makefile | 16 +- demos/zuc/zuc_demo.c | 85 +- demos/zucdemo.sh | 20 +- include/gmssl/aes.h | 165 +- include/gmssl/asn1.h | 539 +- include/gmssl/base64.h | 129 +- include/gmssl/block_cipher.h | 133 +- include/gmssl/chacha20.h | 99 +- include/gmssl/cms.h | 1089 ++-- include/gmssl/des.h | 101 +- include/gmssl/digest.h | 147 +- include/gmssl/ec.h | 113 +- include/gmssl/endian.h | 141 +- include/gmssl/error.h | 113 +- include/gmssl/gcm.h | 103 +- include/gmssl/gf128.h | 91 +- include/gmssl/hash_drbg.h | 143 +- include/gmssl/hex.h | 49 +- include/gmssl/hkdf.h | 75 +- include/gmssl/hmac.h | 79 +- include/gmssl/md5.h | 81 +- include/gmssl/mem.h | 39 +- include/gmssl/oid.h | 411 +- include/gmssl/pbkdf2.h | 93 +- include/gmssl/pem.h | 51 +- include/gmssl/pkcs8.h | 323 +- include/gmssl/rand.h | 61 +- include/gmssl/rc4.h | 65 +- include/gmssl/rsa.h | 97 +- include/gmssl/sdf.h | 123 +- include/gmssl/sha1.h | 75 +- include/gmssl/sha2.h | 189 +- include/gmssl/sha3.h | 169 +- include/gmssl/skf.h | 217 +- include/gmssl/sm2.h | 733 +-- include/gmssl/sm3.h | 161 +- include/gmssl/sm4.h | 247 +- include/gmssl/sm9.h | 1123 ++-- include/gmssl/tls.h | 1745 +++--- include/gmssl/version.h | 55 +- include/gmssl/x509.h | 707 +-- include/gmssl/x509_alg.h | 123 +- include/gmssl/x509_crl.h | 537 +- include/gmssl/x509_ext.h | 1073 ++-- include/gmssl/x509_oid.h | 207 +- include/gmssl/x509_req.h | 195 +- include/gmssl/x509_str.h | 119 +- include/gmssl/zuc.h | 275 +- src/aes.c | 871 +-- src/aes_modes.c | 401 +- src/asn1.c | 2769 ++++----- src/base64.c | 741 +-- src/block_cipher.c | 149 +- src/chacha20.c | 155 +- src/cms.c | 4945 +++++++-------- src/debug.c | 209 +- src/des.c | 443 +- src/digest.c | 987 +-- src/ec.c | 265 +- src/gcm.c | 217 +- src/gf128.c | 339 +- src/hash_drbg.c | 587 +- src/hex.c | 423 +- src/hkdf.c | 395 +- src/hmac.c | 243 +- src/md5.c | 347 +- src/pbkdf2.c | 361 +- src/pem.c | 167 +- src/pkcs8.c | 895 +-- src/rand.c | 77 +- src/rc4.c | 143 +- src/rdrand.c | 87 +- src/rsa.c | 69 +- src/sdf/sdf.c | 411 +- src/sdf/sdf.h | 3 +- src/sdf/sdf_dummy.c | 1443 ++--- src/sdf/sdf_ext.c | 509 +- src/sdf/sdf_ext.h | 93 +- src/sdf/sdf_int.h | 827 +-- src/sdf/sdf_lib.c | 2921 ++++----- src/sdf/sdf_meth.c | 195 +- src/sdf/sdf_sansec.c | 517 +- src/sdf/sdf_sansec.h | 291 +- src/sgd.h | 779 +-- src/sha1.c | 323 +- src/sha256.c | 413 +- src/sha512.c | 447 +- src/skf/skf.c | 1549 ++--- src/skf/skf.h | 1403 ++--- src/skf/skf_dummy.c | 3 +- src/skf/skf_ext.c | 1121 ++-- src/skf/skf_ext.h | 173 +- src/skf/skf_int.h | 1141 ++-- src/skf/skf_lib.c | 5461 +++++++++-------- src/skf/skf_meth.c | 259 +- src/skf/skf_prn.c | 557 +- src/skf/skf_wisec.c | 277 +- src/skf/skf_wisec.h | 219 +- src/sm2_alg.c | 2367 +++---- src/sm2_key.c | 1247 ++-- src/sm2_lib.c | 1373 ++--- src/sm3.c | 735 +-- src/sm3_hmac.c | 157 +- src/sm3_kdf.c | 93 +- src/sm4_common.c | 213 +- src/sm4_enc.c | 161 +- src/sm4_lcl.h | 105 +- src/sm4_modes.c | 789 +-- src/sm4_setkey.c | 143 +- src/sm9_alg.c | 4675 +++++++------- src/sm9_key.c | 2293 +++---- src/sm9_lib.c | 981 +-- src/tlcp.c | 2021 +++--- src/tls.c | 4601 +++++++------- src/tls12.c | 2165 +++---- src/tls13.c | 4661 +++++++------- src/tls_ext.c | 1929 +++--- src/tls_trace.c | 2359 +++---- src/version.c | 29 +- src/x509_alg.c | 1163 ++-- src/x509_cer.c | 3405 +++++----- src/x509_crl.c | 2393 ++++---- src/x509_ext.c | 3561 +++++------ src/x509_oid.c | 809 +-- src/x509_req.c | 675 +- src/x509_str.c | 455 +- src/zuc.c | 1193 ++-- src/zuc_modes.c | 269 +- tests/aestest.c | 737 +-- tests/asn1test.c | 1183 ++-- tests/base64test.c | 129 +- tests/block_ciphertest.c | 23 +- tests/chacha20test.c | 103 +- tests/cmstest.c | 2071 +++---- tests/destest.c | 31 +- tests/digesttest.c | 79 +- tests/ectest.c | 227 +- tests/gcmtest.c | 371 +- tests/gf128test.c | 201 +- tests/hash_drbgtest.c | 169 +- tests/hextest.c | 23 +- tests/hkdftest.c | 417 +- tests/hmactest.c | 225 +- tests/md5test.c | 123 +- tests/pbkdf2test.c | 257 +- tests/pemtest.c | 23 +- tests/pkcs8test.c | 823 +-- tests/rc4test.c | 763 +-- tests/sha1test.c | 129 +- tests/sha224test.c | 173 +- tests/sha256test.c | 171 +- tests/sha384test.c | 183 +- tests/sha512test.c | 185 +- tests/sm2test.c | 1697 ++--- tests/sm3test.c | 353 +- tests/sm4test.c | 1085 ++-- tests/sm9test.c | 1239 ++-- tests/tls13test.c | 147 +- tests/tlstest.c | 677 +- tests/x509_algtest.c | 381 +- tests/x509_crltest.c | 289 +- tests/x509_exttest.c | 1705 ++--- tests/x509_oidtest.c | 559 +- tests/x509_reqtest.c | 421 +- tests/x509_strtest.c | 143 +- tests/x509test.c | 783 +-- tests/zuctest.c | 951 +-- tools/README.md | 82 +- tools/certgen.c | 405 +- tools/certparse.c | 151 +- tools/certverify.c | 335 +- tools/cmsdecrypt.c | 339 +- tools/cmsencrypt.c | 449 +- tools/cmsparse.c | 161 +- tools/cmssign.c | 401 +- tools/cmsverify.c | 263 +- tools/copyright.sh | 4 +- tools/crlparse.c | 201 +- tools/crlverify.c | 297 +- tools/gmssl.c | 405 +- tools/pbkdf2.c | 269 +- tools/rand.c | 225 +- tools/reqgen.c | 303 +- tools/reqparse.c | 143 +- tools/reqsign.c | 475 +- tools/sdfutil.c | 417 +- tools/skfutil.c | 499 +- tools/sm2decrypt.c | 223 +- tools/sm2encrypt.c | 273 +- tools/sm2keygen.c | 169 +- tools/sm2sign.c | 247 +- tools/sm2verify.c | 307 +- tools/sm3.c | 261 +- tools/sm3hmac.c | 231 +- tools/sm4.c | 437 +- tools/sm9decrypt.c | 219 +- tools/sm9encrypt.c | 203 +- tools/sm9keygen.c | 247 +- tools/sm9setup.c | 263 +- tools/sm9sign.c | 239 +- tools/sm9verify.c | 241 +- tools/tlcp_client.c | 391 +- tools/tlcp_server.c | 385 +- tools/tls12_client.c | 385 +- tools/tls12_server.c | 353 +- tools/tls13_client.c | 381 +- tools/tls13_server.c | 353 +- tools/version.c | 27 +- tools/zuc.c | 273 +- 268 files changed, 67247 insertions(+), 67015 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 9941c76e..ff759eac 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,37 +1,37 @@ -name: CMake - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - - name: Test - working-directory: ${{github.workspace}}/build - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C ${{env.BUILD_TYPE}} - +name: CMake + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: Test + working-directory: ${{github.workspace}}/build + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -C ${{env.BUILD_TYPE}} + diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 10636ba8..c78897cc 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -1,31 +1,31 @@ -name: Cygwin -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: windows-latest - - env: - SHELLOPTS: igncr - defaults: - run: - shell: C:\tools\cygwin\bin\bash.exe --login '{0}' - steps: - - uses: actions/checkout@v3 - - name: Set up Cygwin - uses: egor-tensin/setup-cygwin@v3 - with: - platform: x64 - packages: cmake gcc-g++ - +name: Cygwin +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: windows-latest + + env: + SHELLOPTS: igncr + defaults: + run: + shell: C:\tools\cygwin\bin\bash.exe --login '{0}' + steps: + - uses: actions/checkout@v3 + - name: Set up Cygwin + uses: egor-tensin/setup-cygwin@v3 + with: + platform: x64 + packages: cmake gcc-g++ + diff --git a/.gitignore b/.gitignore index cd2c6f1b..9d86c542 100644 --- a/.gitignore +++ b/.gitignore @@ -1,216 +1,217 @@ -# Ignore editor artefacts -/.dir-locals.el - -# Top level excludes -/Makefile.orig -/MINFO -/TABLE -/*.a -/*.pc -/rehash.time -/inc.* -/makefile.* -/out.* -/tmp.* -/configdata.pm -/build -/Makefile - -# *all* Makefiles -#Makefile -*.tmp - -# Java -/java/*.class -/java/Makefile* - -# Links under apps -/apps/CA.pl -/apps/tsget -/apps/tsget.pl -/apps/md4.c - -# Auto generated headers -/crypto/buildinf.h -/crypto/include/internal/*_conf.h -/openssl/include/opensslconf.h -/util/domd - -# Executables -/apps/openssl -/test/sha256t -/test/sha512t -/test/gost2814789t -/test/ssltest_old -/test/*test -/test/fips_aesavs -/test/fips_desmovs -/test/fips_dhvs -/test/fips_drbgvs -/test/fips_dssvs -/test/fips_ecdhvs -/test/fips_ecdsavs -/test/fips_rngvs -/test/fips_test_suite -/test/ssltest_old -/test/x509aux -/test/v3ext - -# Certain files that get created by tests on the fly -/test/*.ss -/test/*.srl -/test/.rnd -/test/test*.pem -/test/newkey.pem -/test/*.log -/test/buildtest_* -/test/*.p -/test/*.dd -/test/*.dp -/test/*.pd -/test/*.p - -/util/shlib_wrap.sh - -# Fuzz stuff. -# Anything without an extension is an executable on Unix, so we keep files -# with extensions. And we keep the corpora subddir versioned as well. -# Anything more generic with extensions that should be ignored will be taken -# care of by general ignores for those extensions (*.o, *.obj, *.exe, ...) -/fuzz/* -!/fuzz/README* -!/fuzz/corpora -!/fuzz/*.* - -# Misc auto generated files -/include/openssl/opensslconf.h -/tools/c_rehash -/tools/c_rehash.pl -/tags -/TAGS -/crypto.map -/ssl.map - -# Windows (legacy) -/tmp32 -/tmp32.dbg -/tmp32dll -/tmp32dll.dbg -/out32 -/out32.dbg -/out32dll -/out32dll.dbg -/inc32 -/MINFO -/ms/.rnd -/ms/bcb.mak -/ms/libeay32.def -/ms/nt.mak -/ms/ntdll.mak -/ms/ssleay32.def -/ms/version32.rc - -# Files created on other branches that are not held in git, and are not -# needed on this branch -/include/openssl/asn1_mac.h -/include/openssl/des_old.h -/include/openssl/fips.h -/include/openssl/fips_rand.h -/include/openssl/krb5_asn.h -/include/openssl/kssl.h -/include/openssl/pq_compat.h -/include/openssl/ssl23.h -/include/openssl/tmdiff.h -/include/openssl/ui_compat.h -/test/fips_aesavs.c -/test/fips_desmovs.c -/test/fips_dsatest.c -/test/fips_dssvs.c -/test/fips_hmactest.c -/test/fips_randtest.c -/test/fips_rngvs.c -/test/fips_rsagtest.c -/test/fips_rsastest.c -/test/fips_rsavtest.c -/test/fips_shatest.c -/test/fips_test_suite.c -/test/shatest.c - -##### Generic patterns -# Auto generated assembly language source files -*.s -!/crypto/*/asm/*.s -/crypto/arm*.S -/crypto/*/*.S -*.asm -!/crypto/*/asm/*.asm - -# Object files -*.o -*.obj - -# editor artefacts -*.swp -.#* -\#*# -*~ - -# Certificate symbolic links -*.0 - -# All kinds of executables -*.so -*.so.* -*.dylib -*.dylib.* -*.dll -*.dll.* -*.exe -*.pyc -*.exp -*.lib -*.pdb -*.ilk -*.def -*.rc -*.res - -# Misc generated stuff -Makefile.save -/crypto/**/lib -/engines/**/lib -/ssl/**/lib -*.bak -cscope.* -*.d - -# macOS -.DS_Store -*.tar.gz - -# add by LiTianjue for GmSSL -# auto create by Configure -crypto/opensslconf.h -tool/c_rehash -# exec file -apps/gmssl -apps/gmca/.ca - -# gmtls -/ssl/ssl_load.c - - -# engines -/engines/e_skf* -/engines/e_sdf* -/engines/sdf -/engines/skf - - -include/openssl/srp.h - -/*.sh - -/rust -/python -/build +# Ignore editor artefacts +/.dir-locals.el + +# Top level excludes +/Makefile.orig +/MINFO +/TABLE +/*.a +/*.pc +/rehash.time +/inc.* +/makefile.* +/out.* +/tmp.* +/configdata.pm +/build +/Makefile + +# *all* Makefiles +#Makefile +*.tmp + +# Java +/java/*.class +/java/Makefile* + +# Links under apps +/apps/CA.pl +/apps/tsget +/apps/tsget.pl +/apps/md4.c + +# Auto generated headers +/crypto/buildinf.h +/crypto/include/internal/*_conf.h +/openssl/include/opensslconf.h +/util/domd + +# Executables +/apps/openssl +/test/sha256t +/test/sha512t +/test/gost2814789t +/test/ssltest_old +/test/*test +/test/fips_aesavs +/test/fips_desmovs +/test/fips_dhvs +/test/fips_drbgvs +/test/fips_dssvs +/test/fips_ecdhvs +/test/fips_ecdsavs +/test/fips_rngvs +/test/fips_test_suite +/test/ssltest_old +/test/x509aux +/test/v3ext + +# Certain files that get created by tests on the fly +/test/*.ss +/test/*.srl +/test/.rnd +/test/test*.pem +/test/newkey.pem +/test/*.log +/test/buildtest_* +/test/*.p +/test/*.dd +/test/*.dp +/test/*.pd +/test/*.p +/demos/*.pem + +/util/shlib_wrap.sh + +# Fuzz stuff. +# Anything without an extension is an executable on Unix, so we keep files +# with extensions. And we keep the corpora subddir versioned as well. +# Anything more generic with extensions that should be ignored will be taken +# care of by general ignores for those extensions (*.o, *.obj, *.exe, ...) +/fuzz/* +!/fuzz/README* +!/fuzz/corpora +!/fuzz/*.* + +# Misc auto generated files +/include/openssl/opensslconf.h +/tools/c_rehash +/tools/c_rehash.pl +/tags +/TAGS +/crypto.map +/ssl.map + +# Windows (legacy) +/tmp32 +/tmp32.dbg +/tmp32dll +/tmp32dll.dbg +/out32 +/out32.dbg +/out32dll +/out32dll.dbg +/inc32 +/MINFO +/ms/.rnd +/ms/bcb.mak +/ms/libeay32.def +/ms/nt.mak +/ms/ntdll.mak +/ms/ssleay32.def +/ms/version32.rc + +# Files created on other branches that are not held in git, and are not +# needed on this branch +/include/openssl/asn1_mac.h +/include/openssl/des_old.h +/include/openssl/fips.h +/include/openssl/fips_rand.h +/include/openssl/krb5_asn.h +/include/openssl/kssl.h +/include/openssl/pq_compat.h +/include/openssl/ssl23.h +/include/openssl/tmdiff.h +/include/openssl/ui_compat.h +/test/fips_aesavs.c +/test/fips_desmovs.c +/test/fips_dsatest.c +/test/fips_dssvs.c +/test/fips_hmactest.c +/test/fips_randtest.c +/test/fips_rngvs.c +/test/fips_rsagtest.c +/test/fips_rsastest.c +/test/fips_rsavtest.c +/test/fips_shatest.c +/test/fips_test_suite.c +/test/shatest.c + +##### Generic patterns +# Auto generated assembly language source files +*.s +!/crypto/*/asm/*.s +/crypto/arm*.S +/crypto/*/*.S +*.asm +!/crypto/*/asm/*.asm + +# Object files +*.o +*.obj + +# editor artefacts +*.swp +.#* +\#*# +*~ + +# Certificate symbolic links +*.0 + +# All kinds of executables +*.so +*.so.* +*.dylib +*.dylib.* +*.dll +*.dll.* +*.exe +*.pyc +*.exp +*.lib +*.pdb +*.ilk +*.def +*.rc +*.res + +# Misc generated stuff +Makefile.save +/crypto/**/lib +/engines/**/lib +/ssl/**/lib +*.bak +cscope.* +*.d + +# macOS +.DS_Store +*.tar.gz + +# add by LiTianjue for GmSSL +# auto create by Configure +crypto/opensslconf.h +tool/c_rehash +# exec file +apps/gmssl +apps/gmca/.ca + +# gmtls +/ssl/ssl_load.c + + +# engines +/engines/e_skf* +/engines/e_sdf* +/engines/sdf +/engines/skf + + +include/openssl/srp.h + +/*.sh + +/rust +/python +/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ae17b7f..2fc6c3dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,276 +1,276 @@ -cmake_minimum_required(VERSION 3.0) -project(GmSSL) - -#set(CMAKE_MACOSX_RPATH 1) -SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) -SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) - -if (CMAKE_VERSION VERSION_LESS "3.1") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}") - endif () -else () - set (CMAKE_C_STANDARD 99) -endif () - -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdrnd -mrdseed") - -include_directories(include) - -add_library( - gmssl - SHARED - src/version.c - src/debug.c - src/sm4_common.c - src/sm4_enc.c - src/sm4_modes.c - src/sm4_setkey.c - src/sm3.c - src/sm3_hmac.c - src/sm3_kdf.c - src/sm2_alg.c - src/sm2_key.c - src/sm2_lib.c - src/sm9_alg.c - src/sm9_key.c - src/sm9_lib.c - src/zuc.c - src/zuc_modes.c - src/aes.c - src/aes_modes.c - src/sha256.c - src/sha512.c - src/chacha20.c - src/des.c - src/sha1.c - src/md5.c - src/rc4.c - src/rand.c - src/hash_drbg.c -# src/rdrand.c - src/block_cipher.c - src/digest.c - src/hmac.c - src/hkdf.c - src/pbkdf2.c - src/gf128.c - src/gcm.c - src/pkcs8.c - src/ec.c - src/rsa.c - src/asn1.c - src/hex.c - src/base64.c - src/pem.c - src/x509_oid.c - src/x509_alg.c - src/x509_str.c - src/x509_cer.c - src/x509_ext.c - src/x509_req.c - src/x509_crl.c - src/cms.c - src/sdf/sdf.c - src/sdf/sdf_lib.c - src/sdf/sdf_meth.c - src/sdf/sdf_ext.c - src/sdf/sdf_sansec.c - src/skf/skf.c - src/skf/skf_lib.c - src/skf/skf_meth.c - src/skf/skf_ext.c - src/skf/skf_prn.c - src/skf/skf_wisec.c - src/tls.c - src/tls_ext.c - src/tls_trace.c - src/tlcp.c - src/tls12.c - src/tls13.c -) - -target_link_libraries(gmssl dl) -SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3) - -add_library(sdf_dummy SHARED src/sdf/sdf_dummy.c) -SET_TARGET_PROPERTIES(sdf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) - -add_library(skf_dummy SHARED src/skf/skf_dummy.c) -SET_TARGET_PROPERTIES(skf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) - - -add_executable( - gmssl-bin - tools/gmssl.c - tools/version.c - tools/sm4.c - tools/sm3.c - tools/sm3hmac.c - tools/sm2keygen.c - tools/sm2sign.c - tools/sm2verify.c - tools/sm2encrypt.c - tools/sm2decrypt.c - tools/sm9setup.c - tools/sm9keygen.c - tools/sm9sign.c - tools/sm9verify.c - tools/sm9encrypt.c - tools/sm9decrypt.c - tools/zuc.c - tools/rand.c - tools/pbkdf2.c - tools/certgen.c - tools/certparse.c - tools/certverify.c - tools/reqgen.c - tools/reqparse.c - tools/reqsign.c - tools/crlparse.c - tools/crlverify.c - tools/cmssign.c - tools/cmsverify.c - tools/cmsencrypt.c - tools/cmsdecrypt.c - tools/cmsparse.c - tools/sdfutil.c - tools/skfutil.c - tools/tlcp_client.c - tools/tlcp_server.c - tools/tls12_client.c - tools/tls12_server.c - tools/tls13_client.c - tools/tls13_server.c -) - -target_link_libraries (gmssl-bin LINK_PUBLIC gmssl) -set_target_properties (gmssl-bin PROPERTIES RUNTIME_OUTPUT_NAME gmssl) - -enable_testing() - -add_test(NAME sm4 COMMAND sm4test) -add_test(NAME sm3 COMMAND sm3test) -add_test(NAME sm2 COMMAND sm2test) -add_test(NAME sm9 COMMAND sm9test) -add_test(NAME zuc COMMAND zuctest) -add_test(NAME aes COMMAND aestest) -add_test(NAME sha224 COMMAND sha224test) -add_test(NAME sha256 COMMAND sha256test) -add_test(NAME sha384 COMMAND sha384test) -add_test(NAME sha512 COMMAND sha512test) -add_test(NAME chacha20 COMMAND chacha20test) -add_test(NAME des COMMAND destest) -add_test(NAME sha1 COMMAND sha1test) -add_test(NAME md5 COMMAND md5test) -add_test(NAME rc4 COMMAND rc4test) -add_test(NAME hash_drbg COMMAND hash_drbgtest) -add_test(NAME block_cipher COMMAND block_ciphertest) -add_test(NAME digest COMMAND digesttest) -add_test(NAME hmac COMMAND hmactest) -add_test(NAME hkdf COMMAND hkdftest) -add_test(NAME pbkdf2 COMMAND pbkdf2test) -add_test(NAME gf128 COMMAND gf128test) -add_test(NAME gcm COMMAND gcmtest) -add_test(NAME pkcs8 COMMAND pkcs8test) -add_test(NAME ec COMMAND ectest) -add_test(NAME asn1 COMMAND asn1test) -add_test(NAME hex COMMAND hextest) -add_test(NAME base64 COMMAND base64test) -add_test(NAME pem COMMAND pemtest) -add_test(NAME x509 COMMAND x509test) -add_test(NAME x509_oid COMMAND x509_oidtest) -add_test(NAME x509_alg COMMAND x509_algtest) -add_test(NAME x509_str COMMAND x509_strtest) -add_test(NAME x509_ext COMMAND x509_exttest) -add_test(NAME x509_req COMMAND x509_reqtest) -add_test(NAME x509_crl COMMAND x509_crltest) -add_test(NAME cms COMMAND cmstest) -add_test(NAME tls COMMAND tlstest) -add_test(NAME tls13 COMMAND tls13test) - - -add_executable(sm4test tests/sm4test.c) -target_link_libraries (sm4test LINK_PUBLIC gmssl) -add_executable(sm3test tests/sm3test.c) -target_link_libraries (sm3test LINK_PUBLIC gmssl) -add_executable(sm2test tests/sm2test.c) -target_link_libraries (sm2test LINK_PUBLIC gmssl) -add_executable(sm9test tests/sm9test.c) -target_link_libraries (sm9test LINK_PUBLIC gmssl) -add_executable(zuctest tests/zuctest.c) -target_link_libraries (zuctest LINK_PUBLIC gmssl) -add_executable(aestest tests/aestest.c) -target_link_libraries (aestest LINK_PUBLIC gmssl) -add_executable(sha224test tests/sha224test.c) -target_link_libraries (sha224test LINK_PUBLIC gmssl) -add_executable(sha256test tests/sha256test.c) -target_link_libraries (sha256test LINK_PUBLIC gmssl) -add_executable(sha384test tests/sha384test.c) -target_link_libraries (sha384test LINK_PUBLIC gmssl) -add_executable(sha512test tests/sha512test.c) -target_link_libraries (sha512test LINK_PUBLIC gmssl) -add_executable(chacha20test tests/chacha20test.c) -target_link_libraries (chacha20test LINK_PUBLIC gmssl) -add_executable(destest tests/destest.c) -target_link_libraries (destest LINK_PUBLIC gmssl) -add_executable(sha1test tests/sha1test.c) -target_link_libraries (sha1test LINK_PUBLIC gmssl) -add_executable(md5test tests/md5test.c) -target_link_libraries (md5test LINK_PUBLIC gmssl) -add_executable(rc4test tests/rc4test.c) -target_link_libraries (rc4test LINK_PUBLIC gmssl) -add_executable(hash_drbgtest tests/hash_drbgtest.c) -target_link_libraries (hash_drbgtest LINK_PUBLIC gmssl) -add_executable(block_ciphertest tests/block_ciphertest.c) -target_link_libraries (block_ciphertest LINK_PUBLIC gmssl) -add_executable(digesttest tests/digesttest.c) -target_link_libraries (digesttest LINK_PUBLIC gmssl) -add_executable(hmactest tests/hmactest.c) -target_link_libraries (hmactest LINK_PUBLIC gmssl) -add_executable(hkdftest tests/hkdftest.c) -target_link_libraries (hkdftest LINK_PUBLIC gmssl) -add_executable(pbkdf2test tests/pbkdf2test.c) -target_link_libraries (pbkdf2test LINK_PUBLIC gmssl) -add_executable(gf128test tests/gf128test.c) -target_link_libraries (gf128test LINK_PUBLIC gmssl) -add_executable(gcmtest tests/gcmtest.c) -target_link_libraries (gcmtest LINK_PUBLIC gmssl) -add_executable(pkcs8test tests/pkcs8test.c) -target_link_libraries (pkcs8test LINK_PUBLIC gmssl) -add_executable(ectest tests/ectest.c) -target_link_libraries (ectest LINK_PUBLIC gmssl) -add_executable(asn1test tests/asn1test.c) -target_link_libraries (asn1test LINK_PUBLIC gmssl) -add_executable(hextest tests/hextest.c) -target_link_libraries (hextest LINK_PUBLIC gmssl) -add_executable(base64test tests/base64test.c) -target_link_libraries (base64test LINK_PUBLIC gmssl) -add_executable(pemtest tests/pemtest.c) -target_link_libraries (pemtest LINK_PUBLIC gmssl) -add_executable(x509test tests/x509test.c) -target_link_libraries (x509test LINK_PUBLIC gmssl) -add_executable(x509_oidtest tests/x509_oidtest.c) -target_link_libraries (x509_oidtest LINK_PUBLIC gmssl) -add_executable(x509_algtest tests/x509_algtest.c) -target_link_libraries (x509_algtest LINK_PUBLIC gmssl) -add_executable(x509_strtest tests/x509_strtest.c) -target_link_libraries (x509_strtest LINK_PUBLIC gmssl) -add_executable(x509_exttest tests/x509_exttest.c) -target_link_libraries (x509_exttest LINK_PUBLIC gmssl) -add_executable(x509_reqtest tests/x509_reqtest.c) -target_link_libraries (x509_reqtest LINK_PUBLIC gmssl) -add_executable(x509_crltest tests/x509_crltest.c) -target_link_libraries (x509_crltest LINK_PUBLIC gmssl) -add_executable(cmstest tests/cmstest.c) -target_link_libraries (cmstest LINK_PUBLIC gmssl) -add_executable(tlstest tests/tlstest.c) -target_link_libraries (tlstest LINK_PUBLIC gmssl) -add_executable(tls13test tests/tls13test.c) -target_link_libraries (tls13test LINK_PUBLIC gmssl) - - -INSTALL(TARGETS gmssl ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) -INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/gmssl DESTINATION include) -INSTALL(TARGETS gmssl-bin RUNTIME DESTINATION bin) - +cmake_minimum_required(VERSION 3.0) +project(GmSSL) + +#set(CMAKE_MACOSX_RPATH 1) +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) + +if (CMAKE_VERSION VERSION_LESS "3.1") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}") + endif () +else () + set (CMAKE_C_STANDARD 99) +endif () + +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdrnd -mrdseed") + +include_directories(include) + +add_library( + gmssl + SHARED + src/version.c + src/debug.c + src/sm4_common.c + src/sm4_enc.c + src/sm4_modes.c + src/sm4_setkey.c + src/sm3.c + src/sm3_hmac.c + src/sm3_kdf.c + src/sm2_alg.c + src/sm2_key.c + src/sm2_lib.c + src/sm9_alg.c + src/sm9_key.c + src/sm9_lib.c + src/zuc.c + src/zuc_modes.c + src/aes.c + src/aes_modes.c + src/sha256.c + src/sha512.c + src/chacha20.c + src/des.c + src/sha1.c + src/md5.c + src/rc4.c + src/rand.c + src/hash_drbg.c +# src/rdrand.c + src/block_cipher.c + src/digest.c + src/hmac.c + src/hkdf.c + src/pbkdf2.c + src/gf128.c + src/gcm.c + src/pkcs8.c + src/ec.c + src/rsa.c + src/asn1.c + src/hex.c + src/base64.c + src/pem.c + src/x509_oid.c + src/x509_alg.c + src/x509_str.c + src/x509_cer.c + src/x509_ext.c + src/x509_req.c + src/x509_crl.c + src/cms.c + src/sdf/sdf.c + src/sdf/sdf_lib.c + src/sdf/sdf_meth.c + src/sdf/sdf_ext.c + src/sdf/sdf_sansec.c + src/skf/skf.c + src/skf/skf_lib.c + src/skf/skf_meth.c + src/skf/skf_ext.c + src/skf/skf_prn.c + src/skf/skf_wisec.c + src/tls.c + src/tls_ext.c + src/tls_trace.c + src/tlcp.c + src/tls12.c + src/tls13.c +) + +target_link_libraries(gmssl dl) +SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3) + +add_library(sdf_dummy SHARED src/sdf/sdf_dummy.c) +SET_TARGET_PROPERTIES(sdf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) + +add_library(skf_dummy SHARED src/skf/skf_dummy.c) +SET_TARGET_PROPERTIES(skf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) + + +add_executable( + gmssl-bin + tools/gmssl.c + tools/version.c + tools/sm4.c + tools/sm3.c + tools/sm3hmac.c + tools/sm2keygen.c + tools/sm2sign.c + tools/sm2verify.c + tools/sm2encrypt.c + tools/sm2decrypt.c + tools/sm9setup.c + tools/sm9keygen.c + tools/sm9sign.c + tools/sm9verify.c + tools/sm9encrypt.c + tools/sm9decrypt.c + tools/zuc.c + tools/rand.c + tools/pbkdf2.c + tools/certgen.c + tools/certparse.c + tools/certverify.c + tools/reqgen.c + tools/reqparse.c + tools/reqsign.c + tools/crlparse.c + tools/crlverify.c + tools/cmssign.c + tools/cmsverify.c + tools/cmsencrypt.c + tools/cmsdecrypt.c + tools/cmsparse.c + tools/sdfutil.c + tools/skfutil.c + tools/tlcp_client.c + tools/tlcp_server.c + tools/tls12_client.c + tools/tls12_server.c + tools/tls13_client.c + tools/tls13_server.c +) + +target_link_libraries (gmssl-bin LINK_PUBLIC gmssl) +set_target_properties (gmssl-bin PROPERTIES RUNTIME_OUTPUT_NAME gmssl) + +enable_testing() + +add_test(NAME sm4 COMMAND sm4test) +add_test(NAME sm3 COMMAND sm3test) +add_test(NAME sm2 COMMAND sm2test) +add_test(NAME sm9 COMMAND sm9test) +add_test(NAME zuc COMMAND zuctest) +add_test(NAME aes COMMAND aestest) +add_test(NAME sha224 COMMAND sha224test) +add_test(NAME sha256 COMMAND sha256test) +add_test(NAME sha384 COMMAND sha384test) +add_test(NAME sha512 COMMAND sha512test) +add_test(NAME chacha20 COMMAND chacha20test) +add_test(NAME des COMMAND destest) +add_test(NAME sha1 COMMAND sha1test) +add_test(NAME md5 COMMAND md5test) +add_test(NAME rc4 COMMAND rc4test) +add_test(NAME hash_drbg COMMAND hash_drbgtest) +add_test(NAME block_cipher COMMAND block_ciphertest) +add_test(NAME digest COMMAND digesttest) +add_test(NAME hmac COMMAND hmactest) +add_test(NAME hkdf COMMAND hkdftest) +add_test(NAME pbkdf2 COMMAND pbkdf2test) +add_test(NAME gf128 COMMAND gf128test) +add_test(NAME gcm COMMAND gcmtest) +add_test(NAME pkcs8 COMMAND pkcs8test) +add_test(NAME ec COMMAND ectest) +add_test(NAME asn1 COMMAND asn1test) +add_test(NAME hex COMMAND hextest) +add_test(NAME base64 COMMAND base64test) +add_test(NAME pem COMMAND pemtest) +add_test(NAME x509 COMMAND x509test) +add_test(NAME x509_oid COMMAND x509_oidtest) +add_test(NAME x509_alg COMMAND x509_algtest) +add_test(NAME x509_str COMMAND x509_strtest) +add_test(NAME x509_ext COMMAND x509_exttest) +add_test(NAME x509_req COMMAND x509_reqtest) +add_test(NAME x509_crl COMMAND x509_crltest) +add_test(NAME cms COMMAND cmstest) +add_test(NAME tls COMMAND tlstest) +add_test(NAME tls13 COMMAND tls13test) + + +add_executable(sm4test tests/sm4test.c) +target_link_libraries (sm4test LINK_PUBLIC gmssl) +add_executable(sm3test tests/sm3test.c) +target_link_libraries (sm3test LINK_PUBLIC gmssl) +add_executable(sm2test tests/sm2test.c) +target_link_libraries (sm2test LINK_PUBLIC gmssl) +add_executable(sm9test tests/sm9test.c) +target_link_libraries (sm9test LINK_PUBLIC gmssl) +add_executable(zuctest tests/zuctest.c) +target_link_libraries (zuctest LINK_PUBLIC gmssl) +add_executable(aestest tests/aestest.c) +target_link_libraries (aestest LINK_PUBLIC gmssl) +add_executable(sha224test tests/sha224test.c) +target_link_libraries (sha224test LINK_PUBLIC gmssl) +add_executable(sha256test tests/sha256test.c) +target_link_libraries (sha256test LINK_PUBLIC gmssl) +add_executable(sha384test tests/sha384test.c) +target_link_libraries (sha384test LINK_PUBLIC gmssl) +add_executable(sha512test tests/sha512test.c) +target_link_libraries (sha512test LINK_PUBLIC gmssl) +add_executable(chacha20test tests/chacha20test.c) +target_link_libraries (chacha20test LINK_PUBLIC gmssl) +add_executable(destest tests/destest.c) +target_link_libraries (destest LINK_PUBLIC gmssl) +add_executable(sha1test tests/sha1test.c) +target_link_libraries (sha1test LINK_PUBLIC gmssl) +add_executable(md5test tests/md5test.c) +target_link_libraries (md5test LINK_PUBLIC gmssl) +add_executable(rc4test tests/rc4test.c) +target_link_libraries (rc4test LINK_PUBLIC gmssl) +add_executable(hash_drbgtest tests/hash_drbgtest.c) +target_link_libraries (hash_drbgtest LINK_PUBLIC gmssl) +add_executable(block_ciphertest tests/block_ciphertest.c) +target_link_libraries (block_ciphertest LINK_PUBLIC gmssl) +add_executable(digesttest tests/digesttest.c) +target_link_libraries (digesttest LINK_PUBLIC gmssl) +add_executable(hmactest tests/hmactest.c) +target_link_libraries (hmactest LINK_PUBLIC gmssl) +add_executable(hkdftest tests/hkdftest.c) +target_link_libraries (hkdftest LINK_PUBLIC gmssl) +add_executable(pbkdf2test tests/pbkdf2test.c) +target_link_libraries (pbkdf2test LINK_PUBLIC gmssl) +add_executable(gf128test tests/gf128test.c) +target_link_libraries (gf128test LINK_PUBLIC gmssl) +add_executable(gcmtest tests/gcmtest.c) +target_link_libraries (gcmtest LINK_PUBLIC gmssl) +add_executable(pkcs8test tests/pkcs8test.c) +target_link_libraries (pkcs8test LINK_PUBLIC gmssl) +add_executable(ectest tests/ectest.c) +target_link_libraries (ectest LINK_PUBLIC gmssl) +add_executable(asn1test tests/asn1test.c) +target_link_libraries (asn1test LINK_PUBLIC gmssl) +add_executable(hextest tests/hextest.c) +target_link_libraries (hextest LINK_PUBLIC gmssl) +add_executable(base64test tests/base64test.c) +target_link_libraries (base64test LINK_PUBLIC gmssl) +add_executable(pemtest tests/pemtest.c) +target_link_libraries (pemtest LINK_PUBLIC gmssl) +add_executable(x509test tests/x509test.c) +target_link_libraries (x509test LINK_PUBLIC gmssl) +add_executable(x509_oidtest tests/x509_oidtest.c) +target_link_libraries (x509_oidtest LINK_PUBLIC gmssl) +add_executable(x509_algtest tests/x509_algtest.c) +target_link_libraries (x509_algtest LINK_PUBLIC gmssl) +add_executable(x509_strtest tests/x509_strtest.c) +target_link_libraries (x509_strtest LINK_PUBLIC gmssl) +add_executable(x509_exttest tests/x509_exttest.c) +target_link_libraries (x509_exttest LINK_PUBLIC gmssl) +add_executable(x509_reqtest tests/x509_reqtest.c) +target_link_libraries (x509_reqtest LINK_PUBLIC gmssl) +add_executable(x509_crltest tests/x509_crltest.c) +target_link_libraries (x509_crltest LINK_PUBLIC gmssl) +add_executable(cmstest tests/cmstest.c) +target_link_libraries (cmstest LINK_PUBLIC gmssl) +add_executable(tlstest tests/tlstest.c) +target_link_libraries (tlstest LINK_PUBLIC gmssl) +add_executable(tls13test tests/tls13test.c) +target_link_libraries (tls13test LINK_PUBLIC gmssl) + + +INSTALL(TARGETS gmssl ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/gmssl DESTINATION include) +INSTALL(TARGETS gmssl-bin RUNTIME DESTINATION bin) + diff --git a/LICENSE b/LICENSE index d9a10c0d..7cd40e55 100644 --- a/LICENSE +++ b/LICENSE @@ -1,176 +1,176 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/README.md b/README.md index 6cc494c2..2444a52c 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,55 @@ -# GmSSL 3.0 - -[![CMake](https://github.com/guanzhi/GmSSL/workflows/CMake/badge.svg)](https://github.com/guanzhi/GmSSL/actions/workflows/cmake.yml) - -GmSSL的2.x版本的开发始于2016年,目前主分支在功能上实现了对主要国密算法、标准和协议的覆盖,并成功应用于多种互联网场景中。但是随着GmSSL在物联网、区块链等新场景中的应用,及在密码产品合规检测过程中的实践,我们发现应用对GmSSL提出了一些新的需求。由于很难在基于OpenSSL的GmSSL 2.x版本上满足新需求,因此我们重新设计了GmSSL的架构,GmSSL也迎来第三个大版本——GmSSL 3.0。 - -## 主要特性 - -* 超轻量:GmSSL 3.0大幅度降低了内存需求和二进制代码体积,不依赖动态内存,可以用于无操作系统的低功耗嵌入式环境(MCU、SOC等),开发者也可以更容易地将国密算法和SSL协议嵌入到现有的项目中。 -* 更合规:GmSSL 3.0 可以配置为仅包含国密算法和国密协议(TLCP协议),依赖GmSSL 的密码应用更容易满足密码产品型号检测的要求,避免由于混杂非国密算法、不安全算法等导致的安全问题和合规问题。 -* 更安全:TLS 1.3在安全性和通信延迟上相对之前的TLS协议有巨大的提升,GmSSL 3.0支持TLS 1.3协议和RFC 8998的国密套件。GmSSL 3.0默认支持密钥的加密保护,提升了密码算法的抗侧信道攻击能力。 -* 跨平台:GmSSL 3.0更容易跨平台,构建系统不再依赖Perl,默认的CMake构建系统可以容易地和Visual Studio、Android NDK等默认编译工具配合使用,开发者也可以手工编写Makefile在特殊环境中编译、剪裁。 - -## 编译与安装 - -GmSSL 3.0 采用了cmake构建系统。下载源代码后将其解压缩,进入源码目录,执行: - -```bash -mkdir build -cd build -cmake .. -make -make test -sudo make install -``` - -## 主要功能 - -### 密码算法 - -* 分组密码:SM4 (CBC/CTR/GCM), AES (CBC/CTR/GCM) -* 序列密码:ZUC/ZUC-256, ChaCha20, RC4 -* 哈希函数: SM3, SHA-224/256/384/512, SHA-1, MD5 -* 公钥密码:SM2加密/签名, SM9加密/签名 -* MAC算法:HMAC, GHASH -* 密钥导出函数:PBKDF2、HKDF -* 随机数生成器:Intel RDRAND, HASH_DRBG (NIST.SP.800-90A) - -### 证书和数字信封 - -* 数字证书:X.509证书, CRL证书注销列表, CSR (PKCS #10) 证书签名请求 -* 私钥加密:基于SM4/SM3口令加密的PEM格式私钥 (PKCS #8) -* 数字信封:SM2密码消息 (GM/T 0010-2012) - -### SSL协议 - -* TLCP 1.1,支持密码套`TLS_ECC_SM4_CBC_SM3 {0xE0,0x13}` (GB/T 38636-2020、GM/T 0024-2014) -* TLS 1.2,支持密码套件`TLS_ECDHE_SM4_CBC_SM3 {0xE0,0x11}` (GB/T 38636-2020、GM/T 0024-2014) -* TLS 1.3,支持密码套件`TLS_SM4_GCM_SM3 {0x00,0xC6}` (RFC 8998) - -## 典型应用 - -#### Nginx-with-GmSSL3.0 - -GmSSL支持Nginx的适配,并提供了Docker实现,具体参见[Nginx-with-GmSSL3.0](https://github.com/zhaoxiaomeng/Nginx-with-GmSSLv3) 项目。 +# GmSSL 3.0 + +[![CMake](https://github.com/guanzhi/GmSSL/workflows/CMake/badge.svg)](https://github.com/guanzhi/GmSSL/actions/workflows/cmake.yml) + +GmSSL的2.x版本的开发始于2016年,目前主分支在功能上实现了对主要国密算法、标准和协议的覆盖,并成功应用于多种互联网场景中。但是随着GmSSL在物联网、区块链等新场景中的应用,及在密码产品合规检测过程中的实践,我们发现应用对GmSSL提出了一些新的需求。由于很难在基于OpenSSL的GmSSL 2.x版本上满足新需求,因此我们重新设计了GmSSL的架构,GmSSL也迎来第三个大版本——GmSSL 3.0。 + +## 主要特性 + +* 超轻量:GmSSL 3.0大幅度降低了内存需求和二进制代码体积,不依赖动态内存,可以用于无操作系统的低功耗嵌入式环境(MCU、SOC等),开发者也可以更容易地将国密算法和SSL协议嵌入到现有的项目中。 +* 更合规:GmSSL 3.0 可以配置为仅包含国密算法和国密协议(TLCP协议),依赖GmSSL 的密码应用更容易满足密码产品型号检测的要求,避免由于混杂非国密算法、不安全算法等导致的安全问题和合规问题。 +* 更安全:TLS 1.3在安全性和通信延迟上相对之前的TLS协议有巨大的提升,GmSSL 3.0支持TLS 1.3协议和RFC 8998的国密套件。GmSSL 3.0默认支持密钥的加密保护,提升了密码算法的抗侧信道攻击能力。 +* 跨平台:GmSSL 3.0更容易跨平台,构建系统不再依赖Perl,默认的CMake构建系统可以容易地和Visual Studio、Android NDK等默认编译工具配合使用,开发者也可以手工编写Makefile在特殊环境中编译、剪裁。 + +## 编译与安装 + +GmSSL 3.0 采用了cmake构建系统。下载源代码后将其解压缩,进入源码目录,执行: + +```bash +mkdir build +cd build +cmake .. +make +make test +sudo make install +``` + +## 主要功能 + +### 密码算法 + +* 分组密码:SM4 (CBC/CTR/GCM), AES (CBC/CTR/GCM) +* 序列密码:ZUC/ZUC-256, ChaCha20, RC4 +* 哈希函数: SM3, SHA-224/256/384/512, SHA-1, MD5 +* 公钥密码:SM2加密/签名, SM9加密/签名 +* MAC算法:HMAC, GHASH +* 密钥导出函数:PBKDF2、HKDF +* 随机数生成器:Intel RDRAND, HASH_DRBG (NIST.SP.800-90A) + +### 证书和数字信封 + +* 数字证书:X.509证书, CRL证书注销列表, CSR (PKCS #10) 证书签名请求 +* 私钥加密:基于SM4/SM3口令加密的PEM格式私钥 (PKCS #8) +* 数字信封:SM2密码消息 (GM/T 0010-2012) + +### SSL协议 + +* TLCP 1.1,支持密码套`TLS_ECC_SM4_CBC_SM3 {0xE0,0x13}` (GB/T 38636-2020、GM/T 0024-2014) +* TLS 1.2,支持密码套件`TLS_ECDHE_SM4_CBC_SM3 {0xE0,0x11}` (GB/T 38636-2020、GM/T 0024-2014) +* TLS 1.3,支持密码套件`TLS_SM4_GCM_SM3 {0x00,0xC6}` (RFC 8998) + +## 典型应用 + +#### Nginx-with-GmSSL3.0 + +GmSSL支持Nginx的适配,并提供了Docker实现,具体参见[Nginx-with-GmSSL3.0](https://github.com/zhaoxiaomeng/Nginx-with-GmSSLv3) 项目。 diff --git a/certs/README.md b/certs/README.md index 8e441f5f..7b8f7102 100644 --- a/certs/README.md +++ b/certs/README.md @@ -1,4 +1,4 @@ -# 国密证书库 - - - +# 国密证书库 + + + diff --git a/certs/ca/Ant Financial Certification Authority S1.pem b/certs/ca/Ant Financial Certification Authority S1.pem index 5c7326b4..4e38ddc5 100644 --- a/certs/ca/Ant Financial Certification Authority S1.pem +++ b/certs/ca/Ant Financial Certification Authority S1.pem @@ -1,18 +1,18 @@ ------BEGIN CERTIFICATE----- -MIICzjCCAnKgAwIBAgIQZMsSZdRKbxEiVT+tvsQxfzAMBggqgRzPVQGDdQUAMC4x -CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X -DTE4MDMwNTA3MDEwOFoXDTM4MDIyODA3MDEwOFowejELMAkGA1UEBhMCQ04xFjAU -BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IFMxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEGmfMCs2ZerI5lvrO -bxfY8HJyIcTwfMtXb3R1KgqJmUTmsdlb3g13lkvkp2GwqGOpptUOxE09hZAeF4tY -QzSkSaOCASIwggEeMB8GA1UdIwQYMBaAFEwysZfZMxvEpgXBxuWLYlvwl3ZYMA8G -A1UdEwEB/wQFMAMBAf8wgboGA1UdHwSBsjCBrzBBoD+gPaQ7MDkxCzAJBgNVBAYT -AkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoGA1UECwwDQVJMMQwwCgYDVQQDDANhcmww -KqAooCaGJGh0dHA6Ly93d3cucm9vdGNhLmdvdi5jbi9hcmwvYXJsLmNybDA+oDyg -OoY4bGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjozODkvQ049YXJsLE9VPUFSTCxP -PU5SQ0FDLEM9Q04wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ3NFyrGaAF5BAy -72g+BP4NTGdGEzAMBggqgRzPVQGDdQUAA0gAMEUCIQCXq5uO1PaKFI764ak1Ah5R -5vc7E6WGBsO7Jv8+GM8xFgIgbCi8GfqKKiAAhJ3grv5vbQy5kPeC5I/8X3igW4k5 -1Tc= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICzjCCAnKgAwIBAgIQZMsSZdRKbxEiVT+tvsQxfzAMBggqgRzPVQGDdQUAMC4x +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X +DTE4MDMwNTA3MDEwOFoXDTM4MDIyODA3MDEwOFowejELMAkGA1UEBhMCQ04xFjAU +BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IFMxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEGmfMCs2ZerI5lvrO +bxfY8HJyIcTwfMtXb3R1KgqJmUTmsdlb3g13lkvkp2GwqGOpptUOxE09hZAeF4tY +QzSkSaOCASIwggEeMB8GA1UdIwQYMBaAFEwysZfZMxvEpgXBxuWLYlvwl3ZYMA8G +A1UdEwEB/wQFMAMBAf8wgboGA1UdHwSBsjCBrzBBoD+gPaQ7MDkxCzAJBgNVBAYT +AkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoGA1UECwwDQVJMMQwwCgYDVQQDDANhcmww +KqAooCaGJGh0dHA6Ly93d3cucm9vdGNhLmdvdi5jbi9hcmwvYXJsLmNybDA+oDyg +OoY4bGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjozODkvQ049YXJsLE9VPUFSTCxP +PU5SQ0FDLEM9Q04wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ3NFyrGaAF5BAy +72g+BP4NTGdGEzAMBggqgRzPVQGDdQUAA0gAMEUCIQCXq5uO1PaKFI764ak1Ah5R +5vc7E6WGBsO7Jv8+GM8xFgIgbCi8GfqKKiAAhJ3grv5vbQy5kPeC5I/8X3igW4k5 +1Tc= +-----END CERTIFICATE----- diff --git a/certs/ca/TJCA.pem b/certs/ca/TJCA.pem index cdf512a5..a3247922 100644 --- a/certs/ca/TJCA.pem +++ b/certs/ca/TJCA.pem @@ -1,18 +1,18 @@ ------BEGIN CERTIFICATE----- -MIIC7jCCApKgAwIBAgIQS66cxft/wk8MdWCL2qSImjAMBggqgRzPVQGDdQUAMDox -CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy -dmFudCBST09UMB4XDTE3MTIwNjAyNTczMFoXDTM3MTIwMTAyNTczMFowVjELMAkG -A1UEBhMCQ04xEjAQBgNVBAgMCeWkqea0peW4gjEkMCIGA1UECgwb5aSp5rSl5biC -55S15a2Q6K6k6K+B5Lit5b+DMQ0wCwYDVQQDDARUSkNBMFkwEwYHKoZIzj0CAQYI -KoEcz1UBgi0DQgAE2GJUeLtgaq271GSkgvmvBHJVxrg6K8Nx6AogQxNB/qoQjup4 -YDw9odBrYiqdTbOgYL5I+iiPCXJg+6xKL3VA6aOCAVowggFWMB8GA1UdIwQYMBaA -FJ/cX1elCW5m8PJ1du0BYnAE/PpUMA8GA1UdEwEB/wQFMAMBAf8wgfIGA1UdHwSB -6jCB5zBPoE2gS6RJMEcxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoG -A1UECwwDQVJMMRowGAYDVQQDDBFDaXZpbF9TZXJ2YW50X0FSTDBGoESgQoZAaHR0 -cDovL3d3dy5yb290Y2EuZ292LmNuL0NpdmlsX1NlcnZhbnRfYXJsL0NpdmlsX1Nl -cnZhbnRfQVJMLmNybDBMoEqgSIZGbGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjoz -OTAvQ049Q2l2aWxfU2VydmFudF9BUkwsT1U9QVJMLE89TlJDQUMsQz1DTjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFE6BR1+l7EDGRDMxpkHLpByil04oMAwGCCqB -HM9VAYN1BQADSAAwRQIgC79X9bYZNHi88AOzS1mcL8iMOTnuOhISxkw6Hbou9bIC -IQCGFTlCuEYGX3Qc+HlufzqyKjyYyUCTb0FkfhOfhcEU+g== ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC7jCCApKgAwIBAgIQS66cxft/wk8MdWCL2qSImjAMBggqgRzPVQGDdQUAMDox +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy +dmFudCBST09UMB4XDTE3MTIwNjAyNTczMFoXDTM3MTIwMTAyNTczMFowVjELMAkG +A1UEBhMCQ04xEjAQBgNVBAgMCeWkqea0peW4gjEkMCIGA1UECgwb5aSp5rSl5biC +55S15a2Q6K6k6K+B5Lit5b+DMQ0wCwYDVQQDDARUSkNBMFkwEwYHKoZIzj0CAQYI +KoEcz1UBgi0DQgAE2GJUeLtgaq271GSkgvmvBHJVxrg6K8Nx6AogQxNB/qoQjup4 +YDw9odBrYiqdTbOgYL5I+iiPCXJg+6xKL3VA6aOCAVowggFWMB8GA1UdIwQYMBaA +FJ/cX1elCW5m8PJ1du0BYnAE/PpUMA8GA1UdEwEB/wQFMAMBAf8wgfIGA1UdHwSB +6jCB5zBPoE2gS6RJMEcxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoG +A1UECwwDQVJMMRowGAYDVQQDDBFDaXZpbF9TZXJ2YW50X0FSTDBGoESgQoZAaHR0 +cDovL3d3dy5yb290Y2EuZ292LmNuL0NpdmlsX1NlcnZhbnRfYXJsL0NpdmlsX1Nl +cnZhbnRfQVJMLmNybDBMoEqgSIZGbGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjoz +OTAvQ049Q2l2aWxfU2VydmFudF9BUkwsT1U9QVJMLE89TlJDQUMsQz1DTjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFE6BR1+l7EDGRDMxpkHLpByil04oMAwGCCqB +HM9VAYN1BQADSAAwRQIgC79X9bYZNHi88AOzS1mcL8iMOTnuOhISxkw6Hbou9bIC +IQCGFTlCuEYGX3Qc+HlufzqyKjyYyUCTb0FkfhOfhcEU+g== +-----END CERTIFICATE----- diff --git a/certs/ca/Taier CA.pem b/certs/ca/Taier CA.pem index 40ed0965..ba8986a6 100644 --- a/certs/ca/Taier CA.pem +++ b/certs/ca/Taier CA.pem @@ -1,16 +1,16 @@ ------BEGIN CERTIFICATE----- -MIIChDCCAiigAwIBAgIQLXrZ9QK+bZE4WSoVyuo7GzAMBggqgRzPVQGDdQUAMC4x -CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X -DTE2MDcxMzA4MjQ1NFoXDTM2MDcwODA4MjQ1NFowMDELMAkGA1UEBhMCQ04xDjAM -BgNVBAoMBUNBSUNUMREwDwYDVQQDDAhUYWllciBDQTBZMBMGByqGSM49AgEGCCqB -HM9VAYItA0IABAxbfsHfqwv8GmfhJYnj0R+fFFqkegyvdZgzRtnnnEDmoy4GNwQa -kVNElUTsMFIJDOEbXTfYazvOghVNsR1UFRujggEiMIIBHjAfBgNVHSMEGDAWgBRM -MrGX2TMbxKYFwcbli2Jb8Jd2WDAPBgNVHRMBAf8EBTADAQH/MIG6BgNVHR8EgbIw -ga8wQaA/oD2kOzA5MQswCQYDVQQGEwJDTjEOMAwGA1UECgwFTlJDQUMxDDAKBgNV -BAsMA0FSTDEMMAoGA1UEAwwDYXJsMCqgKKAmhiRodHRwOi8vd3d3LnJvb3RjYS5n -b3YuY24vYXJsL2FybC5jcmwwPqA8oDqGOGxkYXA6Ly9sZGFwLnJvb3RjYS5nb3Yu -Y246Mzg5L0NOPWFybCxPVT1BUkwsTz1OUkNBQyxDPUNOMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUi2kQa6VC3y6m96DZs4ykCLs9UDkwDAYIKoEcz1UBg3UFAANI -ADBFAiAnOTxqRKjk7+RlMuu6dRIoncmZPPkmVytXeGkvxmN8zAIhAI4zYqRtqy4e -754IdYX8fZDRQi9Mf2ZIkEEgIy9o1+Gf ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIChDCCAiigAwIBAgIQLXrZ9QK+bZE4WSoVyuo7GzAMBggqgRzPVQGDdQUAMC4x +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4X +DTE2MDcxMzA4MjQ1NFoXDTM2MDcwODA4MjQ1NFowMDELMAkGA1UEBhMCQ04xDjAM +BgNVBAoMBUNBSUNUMREwDwYDVQQDDAhUYWllciBDQTBZMBMGByqGSM49AgEGCCqB +HM9VAYItA0IABAxbfsHfqwv8GmfhJYnj0R+fFFqkegyvdZgzRtnnnEDmoy4GNwQa +kVNElUTsMFIJDOEbXTfYazvOghVNsR1UFRujggEiMIIBHjAfBgNVHSMEGDAWgBRM +MrGX2TMbxKYFwcbli2Jb8Jd2WDAPBgNVHRMBAf8EBTADAQH/MIG6BgNVHR8EgbIw +ga8wQaA/oD2kOzA5MQswCQYDVQQGEwJDTjEOMAwGA1UECgwFTlJDQUMxDDAKBgNV +BAsMA0FSTDEMMAoGA1UEAwwDYXJsMCqgKKAmhiRodHRwOi8vd3d3LnJvb3RjYS5n +b3YuY24vYXJsL2FybC5jcmwwPqA8oDqGOGxkYXA6Ly9sZGFwLnJvb3RjYS5nb3Yu +Y246Mzg5L0NOPWFybCxPVT1BUkwsTz1OUkNBQyxDPUNOMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUi2kQa6VC3y6m96DZs4ykCLs9UDkwDAYIKoEcz1UBg3UFAANI +ADBFAiAnOTxqRKjk7+RlMuu6dRIoncmZPPkmVytXeGkvxmN8zAIhAI4zYqRtqy4e +754IdYX8fZDRQi9Mf2ZIkEEgIy9o1+Gf +-----END CERTIFICATE----- diff --git a/certs/rootca/Civil Servant ROOT.pem b/certs/rootca/Civil Servant ROOT.pem index eff2c5ed..66be6a3b 100644 --- a/certs/rootca/Civil Servant ROOT.pem +++ b/certs/rootca/Civil Servant ROOT.pem @@ -1,12 +1,12 @@ ------BEGIN CERTIFICATE----- -MIIB0jCCAXegAwIBAgIQEdZMMEt/UB6aBlClCPrHdDAMBggqgRzPVQGDdQUAMDox -CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy -dmFudCBST09UMB4XDTE0MDcxNTA2NDg1NloXDTQ0MDcwNzA2NDg1NlowOjELMAkG -A1UEBhMCQ04xDjAMBgNVBAoMBU5SQ0FDMRswGQYDVQQDDBJDaXZpbCBTZXJ2YW50 -IFJPT1QwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAR1whSysIMDakj11nL+KgJ1 -J+HtXJU2D/EhV+QC1b+/yDXWdcZay7X79wC/g4vJdUIAdyZfLVy3lYYFc3aJ2smr -o10wWzAfBgNVHSMEGDAWgBSf3F9XpQluZvDydXbtAWJwBPz6VDAMBgNVHRMEBTAD -AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUn9xfV6UJbmbw8nV27QFicAT8+lQw -DAYIKoEcz1UBg3UFAANHADBEAiAkrV4rtXx+4fdJBIVSxHFKh2znz2vnSgk/eBIl -gNQK7AIgNVusahBBOxafSdIB1cX8zJCnq+OcCNLRezYSbXQ45Jg= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB0jCCAXegAwIBAgIQEdZMMEt/UB6aBlClCPrHdDAMBggqgRzPVQGDdQUAMDox +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEbMBkGA1UEAwwSQ2l2aWwgU2Vy +dmFudCBST09UMB4XDTE0MDcxNTA2NDg1NloXDTQ0MDcwNzA2NDg1NlowOjELMAkG +A1UEBhMCQ04xDjAMBgNVBAoMBU5SQ0FDMRswGQYDVQQDDBJDaXZpbCBTZXJ2YW50 +IFJPT1QwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAR1whSysIMDakj11nL+KgJ1 +J+HtXJU2D/EhV+QC1b+/yDXWdcZay7X79wC/g4vJdUIAdyZfLVy3lYYFc3aJ2smr +o10wWzAfBgNVHSMEGDAWgBSf3F9XpQluZvDydXbtAWJwBPz6VDAMBgNVHRMEBTAD +AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUn9xfV6UJbmbw8nV27QFicAT8+lQw +DAYIKoEcz1UBg3UFAANHADBEAiAkrV4rtXx+4fdJBIVSxHFKh2znz2vnSgk/eBIl +gNQK7AIgNVusahBBOxafSdIB1cX8zJCnq+OcCNLRezYSbXQ45Jg= +-----END CERTIFICATE----- diff --git a/certs/rootca/Device ROOT.pem b/certs/rootca/Device ROOT.pem index 101e4acc..03d426f4 100644 --- a/certs/rootca/Device ROOT.pem +++ b/certs/rootca/Device ROOT.pem @@ -1,12 +1,12 @@ ------BEGIN CERTIFICATE----- -MIIBxjCCAWmgAwIBAgIQVWEAYiD7bkTypcG5eLcUIzAMBggqgRzPVQGDdQUAMDMx -CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEUMBIGA1UEAwwLRGV2aWNlIFJP -T1QwHhcNMTQwNzE1MDY0OTE0WhcNNDQwNzA3MDY0OTE0WjAzMQswCQYDVQQGEwJD -TjEOMAwGA1UECgwFTlJDQUMxFDASBgNVBAMMC0RldmljZSBST09UMFkwEwYHKoZI -zj0CAQYIKoEcz1UBgi0DQgAErrT3rKewd5fIH38K5dUcB6dxxYcFCqHlklxWnwiU -n39eP3O8D3h7gncGBJoxX5XToyqwy4saICZq3MEIBf6XKqNdMFswHwYDVR0jBBgw -FoAUodkX9LXKzt+c9s0ZP86nFwz5gPUwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC -AQYwHQYDVR0OBBYEFKHZF/S1ys7fnPbNGT/OpxcM+YD1MAwGCCqBHM9VAYN1BQAD -SQAwRgIhAO6XHWXfSyMUt/fn6yB5vPH9bHofYkylecmwqbN7jNlBAiEA2b8vR1TR -u1rh597JnGgp8tdjAiBbPWYjHcJDRBGcljA= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBxjCCAWmgAwIBAgIQVWEAYiD7bkTypcG5eLcUIzAMBggqgRzPVQGDdQUAMDMx +CzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEUMBIGA1UEAwwLRGV2aWNlIFJP +T1QwHhcNMTQwNzE1MDY0OTE0WhcNNDQwNzA3MDY0OTE0WjAzMQswCQYDVQQGEwJD +TjEOMAwGA1UECgwFTlJDQUMxFDASBgNVBAMMC0RldmljZSBST09UMFkwEwYHKoZI +zj0CAQYIKoEcz1UBgi0DQgAErrT3rKewd5fIH38K5dUcB6dxxYcFCqHlklxWnwiU +n39eP3O8D3h7gncGBJoxX5XToyqwy4saICZq3MEIBf6XKqNdMFswHwYDVR0jBBgw +FoAUodkX9LXKzt+c9s0ZP86nFwz5gPUwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwHQYDVR0OBBYEFKHZF/S1ys7fnPbNGT/OpxcM+YD1MAwGCCqBHM9VAYN1BQAD +SQAwRgIhAO6XHWXfSyMUt/fn6yB5vPH9bHofYkylecmwqbN7jNlBAiEA2b8vR1TR +u1rh597JnGgp8tdjAiBbPWYjHcJDRBGcljA= +-----END CERTIFICATE----- diff --git a/certs/rootca/ROOTCA.pem b/certs/rootca/ROOTCA.pem index ae04bf53..f7c97e7b 100644 --- a/certs/rootca/ROOTCA.pem +++ b/certs/rootca/ROOTCA.pem @@ -1,12 +1,12 @@ ------BEGIN CERTIFICATE----- -MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG -EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw -MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO -UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE -MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT -V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti -W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ -MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b -53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI -pDoiVhsLwg== ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG +EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw +MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO +UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE +MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT +V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti +W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ +MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b +53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI +pDoiVhsLwg== +-----END CERTIFICATE----- diff --git a/demos/cademo.sh b/demos/cademo.sh index 6ccd5db3..ed1953ec 100755 --- a/demos/cademo.sh +++ b/demos/cademo.sh @@ -1,22 +1,22 @@ -#!/bin/bash - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -gmssl sm2keygen -pass 1234 -out enckey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem -gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem -gmssl certparse -in enccert.pem - +#!/bin/bash + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + diff --git a/demos/certdemo.sh b/demos/certdemo.sh index 2c8337b3..879ea520 100755 --- a/demos/certdemo.sh +++ b/demos/certdemo.sh @@ -1,34 +1,34 @@ -#!/bin/bash - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -gmssl sm2keygen -pass 1234 -out enckey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem -gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem -gmssl certparse -in enccert.pem - - -cat signcert.pem > certs.pem -cat cacert.pem >> certs.pem -gmssl certverify -in certs.pem -cacert rootcacert.pem - - -cat signcert.pem > dbl_certs.pem -cat enccert.pem >> dbl_certs.pem -cat cacert.pem >> dbl_certs.pem -gmssl certverify -double_certs -in dbl_certs.pem -cacert rootcacert.pem - - +#!/bin/bash + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + + +cat signcert.pem > certs.pem +cat cacert.pem >> certs.pem +gmssl certverify -in certs.pem -cacert rootcacert.pem + + +cat signcert.pem > dbl_certs.pem +cat enccert.pem >> dbl_certs.pem +cat cacert.pem >> dbl_certs.pem +gmssl certverify -double_certs -in dbl_certs.pem -cacert rootcacert.pem + + diff --git a/demos/cmsdemo.sh b/demos/cmsdemo.sh index e37c9340..620c03cd 100755 --- a/demos/cmsdemo.sh +++ b/demos/cmsdemo.sh @@ -1,17 +1,17 @@ -#!/bin/bash - - -gmssl sm2keygen -pass 1234 -out key.pem -pubout keypub.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -key_usage dataEncipherment -days 365 -key key.pem -pass 1234 -out cert.pem - -echo "The plaintext message." > plain.txt - -gmssl cmsencrypt -in plain.txt -rcptcert cert.pem -out enveloped_data.pem -gmssl cmsparse -in enveloped_data.pem -gmssl cmsdecrypt -key key.pem -pass 1234 -cert cert.pem -in enveloped_data.pem - -gmssl cmssign -key key.pem -pass 1234 -cert cert.pem -in plain.txt -out signed_data.pem -gmssl cmsparse -in signed_data.pem -gmssl cmsverify -in signed_data.pem -out signed_data.txt -cat signed_data.txt - +#!/bin/bash + + +gmssl sm2keygen -pass 1234 -out key.pem -pubout keypub.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -key_usage dataEncipherment -days 365 -key key.pem -pass 1234 -out cert.pem + +echo "The plaintext message." > plain.txt + +gmssl cmsencrypt -in plain.txt -rcptcert cert.pem -out enveloped_data.pem +gmssl cmsparse -in enveloped_data.pem +gmssl cmsdecrypt -key key.pem -pass 1234 -cert cert.pem -in enveloped_data.pem + +gmssl cmssign -key key.pem -pass 1234 -cert cert.pem -in plain.txt -out signed_data.pem +gmssl cmsparse -in signed_data.pem +gmssl cmsverify -in signed_data.pem -out signed_data.txt +cat signed_data.txt + diff --git a/demos/pbkdf2demo.sh b/demos/pbkdf2demo.sh index 844faa70..23e07b9c 100755 --- a/demos/pbkdf2demo.sh +++ b/demos/pbkdf2demo.sh @@ -1,5 +1,5 @@ -#!/bin/bash - - -gmssl pbkdf2 -pass 1234 -salt 1122334455667788 -iter 60000 -outlen 16 - +#!/bin/bash + + +gmssl pbkdf2 -pass 1234 -salt 1122334455667788 -iter 60000 -outlen 16 + diff --git a/demos/reqdemo.sh b/demos/reqdemo.sh index 3b8217a2..01d6c6c2 100755 --- a/demos/reqdemo.sh +++ b/demos/reqdemo.sh @@ -1,19 +1,19 @@ -#!/bin/bash -x - -# generate self-signed CA certificate -gmssl sm2keygen -pass 1234 -out cakey.pem -pubout pubkey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN CA -days 365 -key cakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -# generate a req and sign by CA certificate -gmssl sm2keygen -pass 1234 -out signkey.pem -pubout pubkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -# sign a encryption certificate with the same DN, different KeyUsage extension -gmssl sm2keygen -pass 1234 -out enckey.pem -pubout pubkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -days 365 -key enckey.pem -pass 1234 -out encreq.pem -gmssl reqsign -in encreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem -gmssl certparse -in enccert.pem - +#!/bin/bash -x + +# generate self-signed CA certificate +gmssl sm2keygen -pass 1234 -out cakey.pem -pubout pubkey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN CA -days 365 -key cakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +# generate a req and sign by CA certificate +gmssl sm2keygen -pass 1234 -out signkey.pem -pubout pubkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +# sign a encryption certificate with the same DN, different KeyUsage extension +gmssl sm2keygen -pass 1234 -out enckey.pem -pubout pubkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Alice -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + diff --git a/demos/sm2/Makefile b/demos/sm2/Makefile index 851b0cc9..e5cf996e 100644 --- a/demos/sm2/Makefile +++ b/demos/sm2/Makefile @@ -1,18 +1,18 @@ -all: - cc sm2_keygen_demo.c -lgmssl -o sm2_keygen_demo - cc sm2_private_key_demo.c -lgmssl -o sm2_private_key_demo - cc sm2_private_key_parse_demo.c -lgmssl -o sm2_private_key_parse_demo - cc sm2_public_key_demo.c -lgmssl -o sm2_public_key_demo - cc sm2_sign_demo.c -lgmssl -o sm2_sign_demo - cc sm2_sign_ctx_demo.c -lgmssl -o sm2_sign_ctx_demo - cc sm2_encrypt_demo.c -lgmssl -o sm2_encrypt_demo - -clear: - rm -fr sm2_keygen_demo - rm -fr sm2_private_key_demo - rm -fr sm2_private_key_parse_demo - rm -fr sm2_public_key_demo - rm -fr sm2_sign_demo - rm -fr sm2_sign_ctx_demo - rm -fr sm2_encrypt_demo - +all: + cc sm2_keygen_demo.c -lgmssl -o sm2_keygen_demo + cc sm2_private_key_demo.c -lgmssl -o sm2_private_key_demo + cc sm2_private_key_parse_demo.c -lgmssl -o sm2_private_key_parse_demo + cc sm2_public_key_demo.c -lgmssl -o sm2_public_key_demo + cc sm2_sign_demo.c -lgmssl -o sm2_sign_demo + cc sm2_sign_ctx_demo.c -lgmssl -o sm2_sign_ctx_demo + cc sm2_encrypt_demo.c -lgmssl -o sm2_encrypt_demo + +clear: + rm -fr sm2_keygen_demo + rm -fr sm2_private_key_demo + rm -fr sm2_private_key_parse_demo + rm -fr sm2_public_key_demo + rm -fr sm2_sign_demo + rm -fr sm2_sign_ctx_demo + rm -fr sm2_encrypt_demo + diff --git a/demos/sm2/sm2_encrypt_demo.c b/demos/sm2/sm2_encrypt_demo.c index bd6ec212..e9ca7ea6 100644 --- a/demos/sm2/sm2_encrypt_demo.c +++ b/demos/sm2/sm2_encrypt_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,33 +7,34 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM2_KEY sm2_key; - SM2_KEY pub_key; - unsigned char plaintext[SM2_MAX_PLAINTEXT_SIZE]; - unsigned char ciphertext[SM2_MAX_CIPHERTEXT_SIZE]; - size_t len; - - sm2_key_generate(&sm2_key); - memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); - - sm2_encrypt(&pub_key, (uint8_t *)"hello world", strlen("hello world"), ciphertext, &len); - format_bytes(stdout, 0, 0, "ciphertext", ciphertext, len); - - if (sm2_decrypt(&sm2_key, ciphertext, len, plaintext, &len) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - plaintext[len] = 0; - printf("plaintext: %s\n", plaintext); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM2_KEY sm2_key; + SM2_KEY pub_key; + unsigned char plaintext[SM2_MAX_PLAINTEXT_SIZE]; + unsigned char ciphertext[SM2_MAX_CIPHERTEXT_SIZE]; + size_t len; + + sm2_key_generate(&sm2_key); + memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); + + sm2_encrypt(&pub_key, (uint8_t *)"hello world", strlen("hello world"), ciphertext, &len); + format_bytes(stdout, 0, 0, "ciphertext", ciphertext, len); + + if (sm2_decrypt(&sm2_key, ciphertext, len, plaintext, &len) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + plaintext[len] = 0; + printf("plaintext: %s\n", plaintext); + + return 0; +} diff --git a/demos/sm2/sm2_keygen_demo.c b/demos/sm2/sm2_keygen_demo.c index 813c8fc9..2c3585d8 100644 --- a/demos/sm2/sm2_keygen_demo.c +++ b/demos/sm2/sm2_keygen_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,22 +7,23 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - -int main(void) -{ - SM2_KEY sm2_key; - - if (sm2_key_generate(&sm2_key) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - - sm2_key_print(stdout, 0, 0, "SM2PrivateKey", &sm2_key); - sm2_public_key_print(stdout, 0, 0, "SM2PublicKey", &sm2_key); - - return 0; -} + +#include +#include +#include +#include + +int main(void) +{ + SM2_KEY sm2_key; + + if (sm2_key_generate(&sm2_key) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + + sm2_key_print(stdout, 0, 0, "SM2PrivateKey", &sm2_key); + sm2_public_key_print(stdout, 0, 0, "SM2PublicKey", &sm2_key); + + return 0; +} diff --git a/demos/sm2/sm2_private_key_demo.c b/demos/sm2/sm2_private_key_demo.c index 4e675991..a49e609e 100644 --- a/demos/sm2/sm2_private_key_demo.c +++ b/demos/sm2/sm2_private_key_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,25 +7,26 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - -int main(void) -{ - SM2_KEY sm2_key; - char *password = "123456"; - - if (sm2_key_generate(&sm2_key) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - - if (sm2_private_key_info_encrypt_to_pem(&sm2_key, password, stdout) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - - return 0; -} + +#include +#include +#include +#include + +int main(void) +{ + SM2_KEY sm2_key; + char *password = "123456"; + + if (sm2_key_generate(&sm2_key) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + + if (sm2_private_key_info_encrypt_to_pem(&sm2_key, password, stdout) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + + return 0; +} diff --git a/demos/sm2/sm2_private_key_parse_demo.c b/demos/sm2/sm2_private_key_parse_demo.c index b1544af7..010daea7 100644 --- a/demos/sm2/sm2_private_key_parse_demo.c +++ b/demos/sm2/sm2_private_key_parse_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,35 +7,36 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM2_KEY sm2_key; - char *password = "123456"; - unsigned char buf[512]; - unsigned char *p; - size_t len; - - printf("Read SM2 private key file (PEM) from stdin ...\n"); - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, password, stdin) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - - p = buf; - len = 0; - if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - fwrite(buf, 1, len, stdout); - - gmssl_secure_clear(&sm2_key, sizeof(sm2_key)); - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM2_KEY sm2_key; + char *password = "123456"; + unsigned char buf[512]; + unsigned char *p; + size_t len; + + printf("Read SM2 private key file (PEM) from stdin ...\n"); + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, password, stdin) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + + p = buf; + len = 0; + if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + fwrite(buf, 1, len, stdout); + + gmssl_secure_clear(&sm2_key, sizeof(sm2_key)); + return 0; +} diff --git a/demos/sm2/sm2_public_key_demo.c b/demos/sm2/sm2_public_key_demo.c index ccb44cbe..462a074c 100644 --- a/demos/sm2/sm2_public_key_demo.c +++ b/demos/sm2/sm2_public_key_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,27 +7,28 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM2_KEY sm2_key; - char *password = "123456"; - - printf("Read SM2 private key file (PEM) from stdin ...\n"); - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, password, stdin) != 1) { - fprintf(stderr, "error\n"); - return 1; - } - - // openssl ec -pubin -in sm2pub.pem -text - sm2_public_key_info_to_pem(&sm2_key, stdout); - - gmssl_secure_clear(&sm2_key, sizeof(sm2_key)); - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM2_KEY sm2_key; + char *password = "123456"; + + printf("Read SM2 private key file (PEM) from stdin ...\n"); + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, password, stdin) != 1) { + fprintf(stderr, "error\n"); + return 1; + } + + // openssl ec -pubin -in sm2pub.pem -text + sm2_public_key_info_to_pem(&sm2_key, stdout); + + gmssl_secure_clear(&sm2_key, sizeof(sm2_key)); + return 0; +} diff --git a/demos/sm2/sm2_sign_ctx_demo.c b/demos/sm2/sm2_sign_ctx_demo.c index 57642b92..2fde4293 100644 --- a/demos/sm2/sm2_sign_ctx_demo.c +++ b/demos/sm2/sm2_sign_ctx_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,56 +7,57 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM2_KEY sm2_key; - SM2_KEY pub_key; - SM2_SIGN_CTX sign_ctx; - unsigned char dgst[32]; - unsigned char sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - int ret; - - sm2_key_generate(&sm2_key); - - memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); - - // sign without signer ID (and Z value) - sm2_sign_init(&sign_ctx, &sm2_key, NULL, 0); - sm2_sign_update(&sign_ctx, (unsigned char *)"hello ", strlen("hello ")); - sm2_sign_update(&sign_ctx, (unsigned char *)"world", strlen("world")); - sm2_sign_finish(&sign_ctx, sig, &siglen); - format_bytes(stdout, 0, 0, "signature", sig, siglen); - - // digest and verify - sm3_digest((unsigned char *)"hello world", strlen("hello world"), dgst); - ret = sm2_verify(&pub_key, dgst, sig, siglen); - printf("verify result: %s\n", ret == 1 ? "success" : "failure"); - - // use verify update API - sm2_verify_init(&sign_ctx, &pub_key, NULL, 0); - sm2_verify_update(&sign_ctx, (unsigned char *)"hello world", strlen("hello world")); - ret = sm2_verify_finish(&sign_ctx, sig, siglen); - printf("verify result: %s\n", ret == 1 ? "success" : "failure"); - - // sign use default signer ID - sm2_sign_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_sign_update(&sign_ctx, (unsigned char *)"hello ", strlen("hello ")); - sm2_sign_update(&sign_ctx, (unsigned char *)"world", strlen("world")); - sm2_sign_finish(&sign_ctx, sig, &siglen); - format_bytes(stdout, 0, 0, "signature", sig, siglen); - - sm2_verify_init(&sign_ctx, &pub_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_verify_update(&sign_ctx, (unsigned char *)"hello world", strlen("hello world")); - ret = sm2_verify_finish(&sign_ctx, sig, siglen); - printf("verify result: %s\n", ret == 1 ? "success" : "failure"); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM2_KEY sm2_key; + SM2_KEY pub_key; + SM2_SIGN_CTX sign_ctx; + unsigned char dgst[32]; + unsigned char sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + int ret; + + sm2_key_generate(&sm2_key); + + memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); + + // sign without signer ID (and Z value) + sm2_sign_init(&sign_ctx, &sm2_key, NULL, 0); + sm2_sign_update(&sign_ctx, (unsigned char *)"hello ", strlen("hello ")); + sm2_sign_update(&sign_ctx, (unsigned char *)"world", strlen("world")); + sm2_sign_finish(&sign_ctx, sig, &siglen); + format_bytes(stdout, 0, 0, "signature", sig, siglen); + + // digest and verify + sm3_digest((unsigned char *)"hello world", strlen("hello world"), dgst); + ret = sm2_verify(&pub_key, dgst, sig, siglen); + printf("verify result: %s\n", ret == 1 ? "success" : "failure"); + + // use verify update API + sm2_verify_init(&sign_ctx, &pub_key, NULL, 0); + sm2_verify_update(&sign_ctx, (unsigned char *)"hello world", strlen("hello world")); + ret = sm2_verify_finish(&sign_ctx, sig, siglen); + printf("verify result: %s\n", ret == 1 ? "success" : "failure"); + + // sign use default signer ID + sm2_sign_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_sign_update(&sign_ctx, (unsigned char *)"hello ", strlen("hello ")); + sm2_sign_update(&sign_ctx, (unsigned char *)"world", strlen("world")); + sm2_sign_finish(&sign_ctx, sig, &siglen); + format_bytes(stdout, 0, 0, "signature", sig, siglen); + + sm2_verify_init(&sign_ctx, &pub_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_verify_update(&sign_ctx, (unsigned char *)"hello world", strlen("hello world")); + ret = sm2_verify_finish(&sign_ctx, sig, siglen); + printf("verify result: %s\n", ret == 1 ? "success" : "failure"); + + return 0; +} diff --git a/demos/sm2/sm2_sign_demo.c b/demos/sm2/sm2_sign_demo.c index 26208be8..f169c13a 100644 --- a/demos/sm2/sm2_sign_demo.c +++ b/demos/sm2/sm2_sign_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,37 +7,38 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM2_KEY sm2_key; - SM2_KEY pub_key; - unsigned char dgst[32]; - unsigned char sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - int ret; - - sm3_digest((unsigned char *)"hello world", strlen("hello world"), dgst); - format_bytes(stdout, 0, 0, "to be signed digest", dgst, sizeof(dgst)); - - sm2_key_generate(&sm2_key); - - sm2_sign(&sm2_key, dgst, sig, &siglen); - format_bytes(stdout, 0, 0, "signature", sig, siglen); - - memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); - - if ((ret = sm2_verify(&pub_key, dgst, sig, siglen)) != 1) { - fprintf(stderr, "verify failed\n"); - } else { - printf("verify success\n"); - } - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM2_KEY sm2_key; + SM2_KEY pub_key; + unsigned char dgst[32]; + unsigned char sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + int ret; + + sm3_digest((unsigned char *)"hello world", strlen("hello world"), dgst); + format_bytes(stdout, 0, 0, "to be signed digest", dgst, sizeof(dgst)); + + sm2_key_generate(&sm2_key); + + sm2_sign(&sm2_key, dgst, sig, &siglen); + format_bytes(stdout, 0, 0, "signature", sig, siglen); + + memcpy(&pub_key, &sm2_key, sizeof(SM2_POINT)); + + if ((ret = sm2_verify(&pub_key, dgst, sig, siglen)) != 1) { + fprintf(stderr, "verify failed\n"); + } else { + printf("verify success\n"); + } + + return 0; +} diff --git a/demos/sm2/sm2keyparse.c b/demos/sm2/sm2keyparse.c index c4382823..386e5788 100644 --- a/demos/sm2/sm2keyparse.c +++ b/demos/sm2/sm2keyparse.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,36 +7,37 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - - -int main(int argc, char **argv) -{ - uint8_t buf[4096]; - ssize_t len; - uint8_t dgst[32]; - int i; - - - for (i = 0; i < sizeof(dgst); i++) { - printf("%02x", dgst[i]); - } - printf("\n"); - return 0; -} - - - - - - - - - - - - + + +#include +#include +#include +#include + + +int main(int argc, char **argv) +{ + uint8_t buf[4096]; + ssize_t len; + uint8_t dgst[32]; + int i; + + + for (i = 0; i < sizeof(dgst); i++) { + printf("%02x", dgst[i]); + } + printf("\n"); + return 0; +} + + + + + + + + + + + + diff --git a/demos/sm2demo.sh b/demos/sm2demo.sh index efee77d8..ca42b7c6 100755 --- a/demos/sm2demo.sh +++ b/demos/sm2demo.sh @@ -1,10 +1,10 @@ -#!/bin/bash - -gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem - -echo hello | gmssl sm2sign -key sm2.pem -pass 1234 -out sm2.sig #-id 1234567812345678 -echo hello | gmssl sm2verify -pubkey sm2pub.pem -sig sm2.sig -id 1234567812345678 - -echo hello | gmssl sm2encrypt -pubkey sm2pub.pem -out sm2.der -gmssl sm2decrypt -key sm2.pem -pass 1234 -in sm2.der - +#!/bin/bash + +gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem + +echo hello | gmssl sm2sign -key sm2.pem -pass 1234 -out sm2.sig #-id 1234567812345678 +echo hello | gmssl sm2verify -pubkey sm2pub.pem -sig sm2.sig -id 1234567812345678 + +echo hello | gmssl sm2encrypt -pubkey sm2pub.pem -out sm2.der +gmssl sm2decrypt -key sm2.pem -pass 1234 -in sm2.der + diff --git a/demos/sm3/CMakeLists.txt b/demos/sm3/CMakeLists.txt index 27daa262..c6957814 100644 --- a/demos/sm3/CMakeLists.txt +++ b/demos/sm3/CMakeLists.txt @@ -1,12 +1,12 @@ -cmake_minimum_required(VERSION 3.0) -project(sm3demo) - -include_directories(/usr/local/include) -link_directories(/usr/local/lib) - -add_executable(sm3_demo sm3_demo.c) -add_executable(sm3_hmac_demo sm3_hmac_demo.c) -add_executable(sm3_kdf_demo sm3_kdf_demo.c) -target_link_libraries(sm3_demo gmssl) -target_link_libraries(sm3_hmac_demo gmssl) -target_link_libraries(sm3_kdf_demo gmssl) +cmake_minimum_required(VERSION 3.0) +project(sm3demo) + +include_directories(/usr/local/include) +link_directories(/usr/local/lib) + +add_executable(sm3_demo sm3_demo.c) +add_executable(sm3_hmac_demo sm3_hmac_demo.c) +add_executable(sm3_kdf_demo sm3_kdf_demo.c) +target_link_libraries(sm3_demo gmssl) +target_link_libraries(sm3_hmac_demo gmssl) +target_link_libraries(sm3_kdf_demo gmssl) diff --git a/demos/sm3/Makefile b/demos/sm3/Makefile index 1c31e1ce..f7e41e49 100644 --- a/demos/sm3/Makefile +++ b/demos/sm3/Makefile @@ -1,9 +1,9 @@ -all: - cc sm3_demo.c -lgmssl -o sm3_demo - cc sm3_hmac_demo.c -lgmssl -o sm3_hmac_demo - cc sm3_kdf_demo.c -lgmssl -o sm3_kdf_demo -clean: - rm -fr sm3_demo - rm -fr sm3_hmac_demo - rm -fr sm3_kdf_demo - +all: + cc sm3_demo.c -lgmssl -o sm3_demo + cc sm3_hmac_demo.c -lgmssl -o sm3_hmac_demo + cc sm3_kdf_demo.c -lgmssl -o sm3_kdf_demo +clean: + rm -fr sm3_demo + rm -fr sm3_hmac_demo + rm -fr sm3_kdf_demo + diff --git a/demos/sm3/sm3_demo.c b/demos/sm3/sm3_demo.c index 82e350ac..f5c1d242 100644 --- a/demos/sm3/sm3_demo.c +++ b/demos/sm3/sm3_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,30 +7,31 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - - -int main(int argc, char **argv) -{ - SM3_CTX sm3_ctx; - uint8_t buf[4096]; - ssize_t len; - uint8_t dgst[32]; - int i; - - sm3_init(&sm3_ctx); - while ((len = fread(buf, 1, sizeof(buf), stdin)) > 0) { - sm3_update(&sm3_ctx, buf, len); - } - sm3_finish(&sm3_ctx, dgst); - - for (i = 0; i < sizeof(dgst); i++) { - printf("%02x", dgst[i]); - } - printf("\n"); - return 0; -} + + +#include +#include +#include +#include + + +int main(int argc, char **argv) +{ + SM3_CTX sm3_ctx; + uint8_t buf[4096]; + ssize_t len; + uint8_t dgst[32]; + int i; + + sm3_init(&sm3_ctx); + while ((len = fread(buf, 1, sizeof(buf), stdin)) > 0) { + sm3_update(&sm3_ctx, buf, len); + } + sm3_finish(&sm3_ctx, dgst); + + for (i = 0; i < sizeof(dgst); i++) { + printf("%02x", dgst[i]); + } + printf("\n"); + return 0; +} diff --git a/demos/sm3/sm3_hmac_demo.c b/demos/sm3/sm3_hmac_demo.c index 4cd6b959..86855bd0 100644 --- a/demos/sm3/sm3_hmac_demo.c +++ b/demos/sm3/sm3_hmac_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,45 +7,46 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - - -int main(void) -{ - SM3_HMAC_CTX hmac_ctx; - unsigned char key[16] = { - 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x01,0xf2,0x03,0x04,0x05,0x06,0x07,0x08, - }; - unsigned char mbuf[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char hmac[32] = {0}; - int i; - - - sm3_hmac_init(&hmac_ctx, key, sizeof(key)); - sm3_hmac_update(&hmac_ctx, mbuf, sizeof(mbuf)); - sm3_hmac_finish(&hmac_ctx, hmac); - - printf("hmac: "); - for (i = 0; i < sizeof(hmac); i++) { - printf("%02X", hmac[i]); - } - printf("\n"); - - memset(hmac, 0, sizeof(hmac)); - sm3_hmac(key, sizeof(key), mbuf, sizeof(mbuf), hmac); - - printf("hmac: "); - for (i = 0; i < sizeof(hmac); i++) { - printf("%02X", hmac[i]); - } - printf("\n"); - - return 0; -} + +#include +#include +#include +#include + + +int main(void) +{ + SM3_HMAC_CTX hmac_ctx; + unsigned char key[16] = { + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x01,0xf2,0x03,0x04,0x05,0x06,0x07,0x08, + }; + unsigned char mbuf[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char hmac[32] = {0}; + int i; + + + sm3_hmac_init(&hmac_ctx, key, sizeof(key)); + sm3_hmac_update(&hmac_ctx, mbuf, sizeof(mbuf)); + sm3_hmac_finish(&hmac_ctx, hmac); + + printf("hmac: "); + for (i = 0; i < sizeof(hmac); i++) { + printf("%02X", hmac[i]); + } + printf("\n"); + + memset(hmac, 0, sizeof(hmac)); + sm3_hmac(key, sizeof(key), mbuf, sizeof(mbuf), hmac); + + printf("hmac: "); + for (i = 0; i < sizeof(hmac); i++) { + printf("%02X", hmac[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm3/sm3_kdf_demo.c b/demos/sm3/sm3_kdf_demo.c index f07343bb..8c48b014 100644 --- a/demos/sm3/sm3_kdf_demo.c +++ b/demos/sm3/sm3_kdf_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,31 +7,32 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - - -int main(void) -{ - SM3_KDF_CTX kdf_ctx; - unsigned char key[16] = {0}; - unsigned char raw[32] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - int i; - - sm3_kdf_init(&kdf_ctx, sizeof(key)); - sm3_kdf_update(&kdf_ctx, raw, sizeof(raw)); - sm3_kdf_finish(&kdf_ctx, key); - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - return 0; -} + +#include +#include +#include +#include + + +int main(void) +{ + SM3_KDF_CTX kdf_ctx; + unsigned char key[16] = {0}; + unsigned char raw[32] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + int i; + + sm3_kdf_init(&kdf_ctx, sizeof(key)); + sm3_kdf_update(&kdf_ctx, raw, sizeof(raw)); + sm3_kdf_finish(&kdf_ctx, key); + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm3demo.sh b/demos/sm3demo.sh index de6e044b..1efb5e06 100755 --- a/demos/sm3demo.sh +++ b/demos/sm3demo.sh @@ -1,10 +1,10 @@ -#!/bin/bash - -echo -n abc | gmssl sm3 - -gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem -echo -n abc | gmssl sm3 -pubkey sm2pub.pem -id 1234567812345678 - - -echo -n abc | gmssl sm3hmac -key 11223344556677881122334455667788 - +#!/bin/bash + +echo -n abc | gmssl sm3 + +gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem +echo -n abc | gmssl sm3 -pubkey sm2pub.pem -id 1234567812345678 + + +echo -n abc | gmssl sm3hmac -key 11223344556677881122334455667788 + diff --git a/demos/sm4/Makefile b/demos/sm4/Makefile index f3adb612..f603ca08 100644 --- a/demos/sm4/Makefile +++ b/demos/sm4/Makefile @@ -1,22 +1,22 @@ -all: - cc sm4_demo.c -lgmssl -o sm4_demo - cc sm4_cbc_demo.c -lgmssl -o sm4_cbc_demo - cc sm4_cbc_padding_demo.c -lgmssl -o sm4_cbc_padding_demo - cc sm4_ctr_demo.c -lgmssl -o sm4_ctr_demo - cc sm4_gcm_demo.c -lgmssl -o sm4_gcm_demo - cc sm4_cbc_encrypt_update_demo.c -lgmssl -o sm4_cbc_encrypt_update_demo - cc sm4_cbc_decrypt_update_demo.c -lgmssl -o sm4_cbc_decrypt_update_demo - cc sm4_ctr_encrypt_update_demo.c -lgmssl -o sm4_ctr_encrypt_update_demo - cc sm4_ctr_encrypt_update_demo.c -lgmssl -o sm4_ctr_decrypt_update_demo - -clean: - rm -fr sm4_demo - rm -fr sm4_cbc_demo - rm -fr sm4_cbc_padding_demo - rm -fr sm4_ctr_demo - rm -fr sm4_gcm_demo - rm -fr sm4_cbc_encrypt_update_demo - rm -fr sm4_cbc_decrypt_update_demo - rm -fr sm4_ctr_encrypt_update_demo - rm -fr sm4_ctr_decrypt_update_demo - +all: + cc sm4_demo.c -lgmssl -o sm4_demo + cc sm4_cbc_demo.c -lgmssl -o sm4_cbc_demo + cc sm4_cbc_padding_demo.c -lgmssl -o sm4_cbc_padding_demo + cc sm4_ctr_demo.c -lgmssl -o sm4_ctr_demo + cc sm4_gcm_demo.c -lgmssl -o sm4_gcm_demo + cc sm4_cbc_encrypt_update_demo.c -lgmssl -o sm4_cbc_encrypt_update_demo + cc sm4_cbc_decrypt_update_demo.c -lgmssl -o sm4_cbc_decrypt_update_demo + cc sm4_ctr_encrypt_update_demo.c -lgmssl -o sm4_ctr_encrypt_update_demo + cc sm4_ctr_encrypt_update_demo.c -lgmssl -o sm4_ctr_decrypt_update_demo + +clean: + rm -fr sm4_demo + rm -fr sm4_cbc_demo + rm -fr sm4_cbc_padding_demo + rm -fr sm4_ctr_demo + rm -fr sm4_gcm_demo + rm -fr sm4_cbc_encrypt_update_demo + rm -fr sm4_cbc_decrypt_update_demo + rm -fr sm4_ctr_encrypt_update_demo + rm -fr sm4_ctr_decrypt_update_demo + diff --git a/demos/sm4/sm4_cbc_decrypt_update_demo.c b/demos/sm4/sm4_cbc_decrypt_update_demo.c index 035fb8d0..628c90fd 100644 --- a/demos/sm4/sm4_cbc_decrypt_update_demo.c +++ b/demos/sm4/sm4_cbc_decrypt_update_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,45 +7,46 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_CBC_CTX cbc_ctx; - unsigned char key[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char iv[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char inbuf[1024]; - unsigned char outbuf[1024 + 32]; - ssize_t inlen; - size_t outlen; - - if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { - if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - } - if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_CBC_CTX cbc_ctx; + unsigned char key[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char iv[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char inbuf[1024]; + unsigned char outbuf[1024 + 32]; + ssize_t inlen; + size_t outlen; + + if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { + if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + } + if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + + return 0; +} diff --git a/demos/sm4/sm4_cbc_demo.c b/demos/sm4/sm4_cbc_demo.c index bde0e9dc..6d8c3db5 100644 --- a/demos/sm4/sm4_cbc_demo.c +++ b/demos/sm4/sm4_cbc_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,66 +7,67 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_KEY sm4_key; - unsigned char key[16]; - unsigned char iv[16]; - unsigned char mbuf[32] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char cbuf[32] = {0}; - unsigned char pbuf[32] = {0}; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - printf("iv: "); - for (i = 0; i < sizeof(iv); i++) { - printf("%02X", iv[i]); - } - printf("\n"); - - printf("plaintext: "); - for (i = 0; i < sizeof(mbuf); i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_encrypt(&sm4_key, iv, mbuf, sizeof(mbuf)/SM4_BLOCK_SIZE, cbuf); - - printf("ciphertext: "); - for (i = 0; i < sizeof(cbuf); i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - sm4_set_decrypt_key(&sm4_key, key); - sm4_cbc_decrypt(&sm4_key, iv, cbuf, sizeof(cbuf)/SM4_BLOCK_SIZE, pbuf); - - printf("decrypted: "); - for (i = 0; i < sizeof(pbuf); i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_KEY sm4_key; + unsigned char key[16]; + unsigned char iv[16]; + unsigned char mbuf[32] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char cbuf[32] = {0}; + unsigned char pbuf[32] = {0}; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + printf("iv: "); + for (i = 0; i < sizeof(iv); i++) { + printf("%02X", iv[i]); + } + printf("\n"); + + printf("plaintext: "); + for (i = 0; i < sizeof(mbuf); i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_encrypt(&sm4_key, iv, mbuf, sizeof(mbuf)/SM4_BLOCK_SIZE, cbuf); + + printf("ciphertext: "); + for (i = 0; i < sizeof(cbuf); i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + sm4_set_decrypt_key(&sm4_key, key); + sm4_cbc_decrypt(&sm4_key, iv, cbuf, sizeof(cbuf)/SM4_BLOCK_SIZE, pbuf); + + printf("decrypted: "); + for (i = 0; i < sizeof(pbuf); i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm4/sm4_cbc_encrypt_update_demo.c b/demos/sm4/sm4_cbc_encrypt_update_demo.c index 3faa445e..9a4c02c4 100644 --- a/demos/sm4/sm4_cbc_encrypt_update_demo.c +++ b/demos/sm4/sm4_cbc_encrypt_update_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,45 +7,46 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_CBC_CTX cbc_ctx; - unsigned char key[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char iv[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char inbuf[1024]; - unsigned char outbuf[1024 + 32]; - ssize_t inlen; - size_t outlen; - - if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { - if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - } - if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_CBC_CTX cbc_ctx; + unsigned char key[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char iv[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char inbuf[1024]; + unsigned char outbuf[1024 + 32]; + ssize_t inlen; + size_t outlen; + + if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { + if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + } + if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + + return 0; +} diff --git a/demos/sm4/sm4_cbc_padding_demo.c b/demos/sm4/sm4_cbc_padding_demo.c index 2f0bdda3..797fe933 100644 --- a/demos/sm4/sm4_cbc_padding_demo.c +++ b/demos/sm4/sm4_cbc_padding_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,99 +7,100 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_KEY sm4_key; - unsigned char key[16]; - unsigned char iv[16]; - unsigned char mbuf[32] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char cbuf[32] = {0}; - unsigned char pbuf[32] = {0}; - size_t mlen1 = 20, mlen2 = 16; - size_t clen1, clen2; - size_t plen1, plen2; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - printf("iv: "); - for (i = 0; i < sizeof(iv); i++) { - printf("%02X", iv[i]); - } - printf("\n"); - - - printf("sm4_cbc_pading encrypt %zu bytes\n", mlen1); - - printf("plaintext: "); - for (i = 0; i < mlen1; i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen1, cbuf, &clen1); - - printf("ciphertext: "); - for (i = 0; i < clen1; i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - sm4_set_decrypt_key(&sm4_key, key); - sm4_cbc_padding_decrypt(&sm4_key, iv, cbuf, clen1, pbuf, &plen1); - - printf("decrypted: "); - for (i = 0; i < plen1; i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - printf("sm4_cbc_pading encrypt %zu bytes\n", mlen2); - - printf("plaintext: "); - for (i = 0; i < mlen2; i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen2, cbuf, &clen2); - - printf("ciphertext: "); - for (i = 0; i < clen2; i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - sm4_set_decrypt_key(&sm4_key, key); - sm4_cbc_padding_decrypt(&sm4_key, iv, cbuf, clen2, pbuf, &plen2); - - printf("decrypted: "); - for (i = 0; i < plen2; i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_KEY sm4_key; + unsigned char key[16]; + unsigned char iv[16]; + unsigned char mbuf[32] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char cbuf[32] = {0}; + unsigned char pbuf[32] = {0}; + size_t mlen1 = 20, mlen2 = 16; + size_t clen1, clen2; + size_t plen1, plen2; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + printf("iv: "); + for (i = 0; i < sizeof(iv); i++) { + printf("%02X", iv[i]); + } + printf("\n"); + + + printf("sm4_cbc_pading encrypt %zu bytes\n", mlen1); + + printf("plaintext: "); + for (i = 0; i < mlen1; i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen1, cbuf, &clen1); + + printf("ciphertext: "); + for (i = 0; i < clen1; i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + sm4_set_decrypt_key(&sm4_key, key); + sm4_cbc_padding_decrypt(&sm4_key, iv, cbuf, clen1, pbuf, &plen1); + + printf("decrypted: "); + for (i = 0; i < plen1; i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + printf("sm4_cbc_pading encrypt %zu bytes\n", mlen2); + + printf("plaintext: "); + for (i = 0; i < mlen2; i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen2, cbuf, &clen2); + + printf("ciphertext: "); + for (i = 0; i < clen2; i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + sm4_set_decrypt_key(&sm4_key, key); + sm4_cbc_padding_decrypt(&sm4_key, iv, cbuf, clen2, pbuf, &plen2); + + printf("decrypted: "); + for (i = 0; i < plen2; i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + + return 0; +} diff --git a/demos/sm4/sm4_ctr_demo.c b/demos/sm4/sm4_ctr_demo.c index 6c0d6492..9e760d35 100644 --- a/demos/sm4/sm4_ctr_demo.c +++ b/demos/sm4/sm4_ctr_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,70 +7,71 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_KEY sm4_key; - unsigned char key[16]; - unsigned char iv[16]; - unsigned char ctr[16]; - unsigned char mbuf[20] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34, - }; - unsigned char cbuf[20] = {0}; - unsigned char pbuf[20] = {0}; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - printf("ctr: "); - for (i = 0; i < sizeof(iv); i++) { - printf("%02X", iv[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - - printf("sm4 ctr encrypt %zu bytes\n", sizeof(mbuf)); - - printf("plaintext: "); - for (i = 0; i < sizeof(mbuf); i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - memcpy(ctr, iv, 16); - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, sizeof(mbuf), cbuf); - - printf("ciphertext: "); - for (i = 0; i < sizeof(cbuf); i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - memcpy(ctr, iv, 16); - sm4_ctr_decrypt(&sm4_key, ctr, cbuf, sizeof(cbuf), pbuf); - - printf("decrypted: "); - for (i = 0; i < sizeof(pbuf); i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_KEY sm4_key; + unsigned char key[16]; + unsigned char iv[16]; + unsigned char ctr[16]; + unsigned char mbuf[20] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34, + }; + unsigned char cbuf[20] = {0}; + unsigned char pbuf[20] = {0}; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + printf("ctr: "); + for (i = 0; i < sizeof(iv); i++) { + printf("%02X", iv[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + + printf("sm4 ctr encrypt %zu bytes\n", sizeof(mbuf)); + + printf("plaintext: "); + for (i = 0; i < sizeof(mbuf); i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + memcpy(ctr, iv, 16); + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, sizeof(mbuf), cbuf); + + printf("ciphertext: "); + for (i = 0; i < sizeof(cbuf); i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + memcpy(ctr, iv, 16); + sm4_ctr_decrypt(&sm4_key, ctr, cbuf, sizeof(cbuf), pbuf); + + printf("decrypted: "); + for (i = 0; i < sizeof(pbuf); i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm4/sm4_ctr_encrypt_update_demo.c b/demos/sm4/sm4_ctr_encrypt_update_demo.c index fabdb4bc..96ec757d 100644 --- a/demos/sm4/sm4_ctr_encrypt_update_demo.c +++ b/demos/sm4/sm4_ctr_encrypt_update_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,45 +7,46 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_CTR_CTX cbc_ctx; - unsigned char key[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char ctr[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char inbuf[1024]; - unsigned char outbuf[1024 + 32]; - ssize_t inlen; - size_t outlen; - - if (sm4_ctr_encrypt_init(&cbc_ctx, key, ctr) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { - if (sm4_ctr_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - } - if (sm4_ctr_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_CTR_CTX cbc_ctx; + unsigned char key[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char ctr[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char inbuf[1024]; + unsigned char outbuf[1024 + 32]; + ssize_t inlen; + size_t outlen; + + if (sm4_ctr_encrypt_init(&cbc_ctx, key, ctr) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { + if (sm4_ctr_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + } + if (sm4_ctr_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + + return 0; +} diff --git a/demos/sm4/sm4_demo.c b/demos/sm4/sm4_demo.c index 14934c86..198a4ae8 100644 --- a/demos/sm4/sm4_demo.c +++ b/demos/sm4/sm4_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,58 +7,59 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -// sm4 demo1: encrypt and decrypt a block of message (16 bytes) - -#include -#include -#include -#include - - -int main(void) -{ - SM4_KEY sm4_key; - unsigned char key[16] = { - 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x01,0xf2,0x03,0x04,0x05,0x06,0x07,0x08, - }; - unsigned char mbuf[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char cbuf[16]; - unsigned char pbuf[16]; - int i; - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - printf("plaintext: "); - for (i = 0; i < sizeof(mbuf); i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - sm4_encrypt(&sm4_key, mbuf, cbuf); - - printf("ciphertext: "); - for (i = 0; i < sizeof(cbuf); i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - sm4_set_decrypt_key(&sm4_key, key); - sm4_decrypt(&sm4_key, cbuf, pbuf); - - printf("decrypted: "); - for (i = 0; i < sizeof(pbuf); i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - return 0; -} + +// sm4 demo1: encrypt and decrypt a block of message (16 bytes) + +#include +#include +#include +#include + + +int main(void) +{ + SM4_KEY sm4_key; + unsigned char key[16] = { + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x01,0xf2,0x03,0x04,0x05,0x06,0x07,0x08, + }; + unsigned char mbuf[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char cbuf[16]; + unsigned char pbuf[16]; + int i; + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + printf("plaintext: "); + for (i = 0; i < sizeof(mbuf); i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + sm4_encrypt(&sm4_key, mbuf, cbuf); + + printf("ciphertext: "); + for (i = 0; i < sizeof(cbuf); i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + sm4_set_decrypt_key(&sm4_key, key); + sm4_decrypt(&sm4_key, cbuf, pbuf); + + printf("decrypted: "); + for (i = 0; i < sizeof(pbuf); i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm4/sm4_gcm_demo.c b/demos/sm4/sm4_gcm_demo.c index 57d53bc9..d1e58eee 100644 --- a/demos/sm4/sm4_gcm_demo.c +++ b/demos/sm4/sm4_gcm_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,84 +7,85 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM4_KEY sm4_key; - unsigned char key[16]; - unsigned char iv[16]; - unsigned char aad[20]; - unsigned char mbuf[64] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34, - }; - unsigned char cbuf[64] = {0}; - unsigned char pbuf[64] = {0}; - unsigned char tag[16]; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - printf("key: "); - for (i = 0; i < sizeof(key); i++) { - printf("%02X", key[i]); - } - printf("\n"); - - printf("iv: "); - for (i = 0; i < sizeof(iv); i++) { - printf("%02X", iv[i]); - } - printf("\n"); - - sm4_set_encrypt_key(&sm4_key, key); - - printf("sm4 gcm encrypt\n"); - - printf("auth-only data: "); - for (i = 0; i < sizeof(aad); i++) { - printf("%02X", aad[i]); - } - printf("\n"); - - printf("plaintext: "); - for (i = 0; i < sizeof(mbuf); i++) { - printf("%02X", mbuf[i]); - } - printf("\n"); - - sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), mbuf, sizeof(mbuf), cbuf, sizeof(tag), tag); - - printf("ciphertext: "); - for (i = 0; i < sizeof(cbuf); i++) { - printf("%02X", cbuf[i]); - } - printf("\n"); - - printf("mac-tag: "); - for (i = 0; i < sizeof(tag); i++) { - printf("%02X", tag[i]); - } - printf("\n"); - - if (sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), cbuf, sizeof(mbuf), tag, sizeof(tag), pbuf) != 1) { - fprintf(stderr, "sm4 gcm decrypt failed\n"); - return 1; - } - - printf("decrypted: "); - for (i = 0; i < sizeof(pbuf); i++) { - printf("%02X", pbuf[i]); - } - printf("\n"); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM4_KEY sm4_key; + unsigned char key[16]; + unsigned char iv[16]; + unsigned char aad[20]; + unsigned char mbuf[64] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34, + }; + unsigned char cbuf[64] = {0}; + unsigned char pbuf[64] = {0}; + unsigned char tag[16]; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + printf("key: "); + for (i = 0; i < sizeof(key); i++) { + printf("%02X", key[i]); + } + printf("\n"); + + printf("iv: "); + for (i = 0; i < sizeof(iv); i++) { + printf("%02X", iv[i]); + } + printf("\n"); + + sm4_set_encrypt_key(&sm4_key, key); + + printf("sm4 gcm encrypt\n"); + + printf("auth-only data: "); + for (i = 0; i < sizeof(aad); i++) { + printf("%02X", aad[i]); + } + printf("\n"); + + printf("plaintext: "); + for (i = 0; i < sizeof(mbuf); i++) { + printf("%02X", mbuf[i]); + } + printf("\n"); + + sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), mbuf, sizeof(mbuf), cbuf, sizeof(tag), tag); + + printf("ciphertext: "); + for (i = 0; i < sizeof(cbuf); i++) { + printf("%02X", cbuf[i]); + } + printf("\n"); + + printf("mac-tag: "); + for (i = 0; i < sizeof(tag); i++) { + printf("%02X", tag[i]); + } + printf("\n"); + + if (sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), cbuf, sizeof(mbuf), tag, sizeof(tag), pbuf) != 1) { + fprintf(stderr, "sm4 gcm decrypt failed\n"); + return 1; + } + + printf("decrypted: "); + for (i = 0; i < sizeof(pbuf); i++) { + printf("%02X", pbuf[i]); + } + printf("\n"); + + return 0; +} diff --git a/demos/sm4demo.sh b/demos/sm4demo.sh index baa5af84..8bf76533 100755 --- a/demos/sm4demo.sh +++ b/demos/sm4demo.sh @@ -1,12 +1,12 @@ -#!/bin/bash - - -KEY=11223344556677881122334455667788 -IV=11223344556677881122334455667788 - -echo hello | gmssl sm4 -cbc -encrypt -key $KEY -iv $IV -out sm4.cbc -gmssl sm4 -cbc -decrypt -key $KEY -iv $IV -in sm4.cbc - -echo hello | gmssl sm4 -ctr -encrypt -key $KEY -iv $IV -out sm4.ctr -gmssl sm4 -ctr -decrypt -key $KEY -iv $IV -in sm4.ctr - +#!/bin/bash + + +KEY=11223344556677881122334455667788 +IV=11223344556677881122334455667788 + +echo hello | gmssl sm4 -cbc -encrypt -key $KEY -iv $IV -out sm4.cbc +gmssl sm4 -cbc -decrypt -key $KEY -iv $IV -in sm4.cbc + +echo hello | gmssl sm4 -ctr -encrypt -key $KEY -iv $IV -out sm4.ctr +gmssl sm4 -ctr -decrypt -key $KEY -iv $IV -in sm4.ctr + diff --git a/demos/sm9/Makefile b/demos/sm9/Makefile index 96e469f3..f31b5677 100644 --- a/demos/sm9/Makefile +++ b/demos/sm9/Makefile @@ -1,10 +1,10 @@ -all: - cc sm9_keygen_demo.c -lgmssl -o sm9_keygen_demo - cc sm9_sign_demo.c -lgmssl -o sm9_sign_demo - cc sm9_encrypt_demo.c -lgmssl -o sm9_encrypt_demo - -clean: - rm -fr sm9_keygen_demo - rm -fr sm9_sign_demo - rm -fr sm9_encrypt_demo - +all: + cc sm9_keygen_demo.c -lgmssl -o sm9_keygen_demo + cc sm9_sign_demo.c -lgmssl -o sm9_sign_demo + cc sm9_encrypt_demo.c -lgmssl -o sm9_encrypt_demo + +clean: + rm -fr sm9_keygen_demo + rm -fr sm9_sign_demo + rm -fr sm9_encrypt_demo + diff --git a/demos/sm9/sm9_encrypt_demo.c b/demos/sm9/sm9_encrypt_demo.c index 488bd4a1..14aeb625 100644 --- a/demos/sm9/sm9_encrypt_demo.c +++ b/demos/sm9/sm9_encrypt_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,41 +7,42 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM9_ENC_MASTER_KEY master; - SM9_ENC_MASTER_KEY master_public; - SM9_ENC_KEY key; - const char *id = "Alice"; - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len; - char mbuf[256]; - size_t mlen; - int ret; - - sm9_enc_master_key_generate(&master); - sm9_enc_master_key_extract_key(&master, id, strlen(id), &key); - - sm9_enc_master_public_key_to_der(&master, &p, &len); - sm9_enc_master_public_key_from_der(&master_public, &cp, &len); - - sm9_encrypt(&master_public, id, strlen(id), (uint8_t *)"hello", strlen("hello"), buf, &len); - ret = sm9_decrypt(&key, id, strlen(id), buf, len, (uint8_t *)mbuf, &mlen); - if (ret != 1) { - fprintf(stderr, "decrypt failed\n"); - return 1; - } - mbuf[mlen] = 0; - printf("decrypt result: %s\n", mbuf); - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM9_ENC_MASTER_KEY master; + SM9_ENC_MASTER_KEY master_public; + SM9_ENC_KEY key; + const char *id = "Alice"; + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len; + char mbuf[256]; + size_t mlen; + int ret; + + sm9_enc_master_key_generate(&master); + sm9_enc_master_key_extract_key(&master, id, strlen(id), &key); + + sm9_enc_master_public_key_to_der(&master, &p, &len); + sm9_enc_master_public_key_from_der(&master_public, &cp, &len); + + sm9_encrypt(&master_public, id, strlen(id), (uint8_t *)"hello", strlen("hello"), buf, &len); + ret = sm9_decrypt(&key, id, strlen(id), buf, len, (uint8_t *)mbuf, &mlen); + if (ret != 1) { + fprintf(stderr, "decrypt failed\n"); + return 1; + } + mbuf[mlen] = 0; + printf("decrypt result: %s\n", mbuf); + + return 0; +} diff --git a/demos/sm9/sm9_keygen_demo.c b/demos/sm9/sm9_keygen_demo.c index 3d4512aa..c996aa14 100644 --- a/demos/sm9/sm9_keygen_demo.c +++ b/demos/sm9/sm9_keygen_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,29 +7,30 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - - -int main(void) -{ - SM9_SIGN_MASTER_KEY sign_master; - SM9_SIGN_KEY sign_key; - - sm9_sign_master_key_generate(&sign_master); - - printf("SM9 Master Secret\n"); - sm9_sign_master_key_info_encrypt_to_pem(&sign_master, "P@ssw0rd", stdout); - - printf("SM9 Public Parameters\n"); - sm9_sign_master_public_key_to_pem(&sign_master, stdout); - - sm9_sign_master_key_extract_key(&sign_master, "alice", strlen("alice"), &sign_key); - - printf("SM9 private key for ID '%s'\n", "alice"); - sm9_sign_key_info_encrypt_to_pem(&sign_key, "123456", stdout); - - return 0; -} + +#include +#include +#include +#include + + +int main(void) +{ + SM9_SIGN_MASTER_KEY sign_master; + SM9_SIGN_KEY sign_key; + + sm9_sign_master_key_generate(&sign_master); + + printf("SM9 Master Secret\n"); + sm9_sign_master_key_info_encrypt_to_pem(&sign_master, "P@ssw0rd", stdout); + + printf("SM9 Public Parameters\n"); + sm9_sign_master_public_key_to_pem(&sign_master, stdout); + + sm9_sign_master_key_extract_key(&sign_master, "alice", strlen("alice"), &sign_key); + + printf("SM9 private key for ID '%s'\n", "alice"); + sm9_sign_key_info_encrypt_to_pem(&sign_key, "123456", stdout); + + return 0; +} diff --git a/demos/sm9/sm9_sign_demo.c b/demos/sm9/sm9_sign_demo.c index c97849fc..b82898fb 100644 --- a/demos/sm9/sm9_sign_demo.c +++ b/demos/sm9/sm9_sign_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,47 +7,48 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include - - -int main(void) -{ - SM9_SIGN_MASTER_KEY sign_master; - SM9_SIGN_MASTER_KEY sign_master_public; - SM9_SIGN_KEY sign_key; - SM9_SIGN_CTX sign_ctx; - const char *id = "Alice"; - uint8_t sig[SM9_SIGNATURE_SIZE]; - size_t siglen; - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len; - int ret; - - sm9_sign_master_key_generate(&sign_master); - - sm9_sign_master_key_extract_key(&sign_master, id, strlen(id), &sign_key); - - sm9_sign_init(&sign_ctx); - sm9_sign_update(&sign_ctx, (uint8_t *)"hello world", strlen("hello world")); - sm9_sign_finish(&sign_ctx, &sign_key, sig, &siglen); - - format_bytes(stdout, 0, 0, "signature", sig, siglen); - - - sm9_sign_master_public_key_to_der(&sign_master, &p, &len); - sm9_sign_master_public_key_from_der(&sign_master_public, &cp, &len); - - sm9_verify_init(&sign_ctx); - sm9_verify_update(&sign_ctx, (uint8_t *)"hello world", strlen("hello world")); - ret = sm9_verify_finish(&sign_ctx, sig, siglen, &sign_master_public, id, strlen(id)); - printf("verify %s\n", ret == 1 ? "success" : "failure"); - - - return 0; -} + +#include +#include +#include +#include +#include + + +int main(void) +{ + SM9_SIGN_MASTER_KEY sign_master; + SM9_SIGN_MASTER_KEY sign_master_public; + SM9_SIGN_KEY sign_key; + SM9_SIGN_CTX sign_ctx; + const char *id = "Alice"; + uint8_t sig[SM9_SIGNATURE_SIZE]; + size_t siglen; + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len; + int ret; + + sm9_sign_master_key_generate(&sign_master); + + sm9_sign_master_key_extract_key(&sign_master, id, strlen(id), &sign_key); + + sm9_sign_init(&sign_ctx); + sm9_sign_update(&sign_ctx, (uint8_t *)"hello world", strlen("hello world")); + sm9_sign_finish(&sign_ctx, &sign_key, sig, &siglen); + + format_bytes(stdout, 0, 0, "signature", sig, siglen); + + + sm9_sign_master_public_key_to_der(&sign_master, &p, &len); + sm9_sign_master_public_key_from_der(&sign_master_public, &cp, &len); + + sm9_verify_init(&sign_ctx); + sm9_verify_update(&sign_ctx, (uint8_t *)"hello world", strlen("hello world")); + ret = sm9_verify_finish(&sign_ctx, sig, siglen, &sign_master_public, id, strlen(id)); + printf("verify %s\n", ret == 1 ? "success" : "failure"); + + + return 0; +} diff --git a/demos/sm9demo.sh b/demos/sm9demo.sh index 0cce6e4d..aaf109fe 100755 --- a/demos/sm9demo.sh +++ b/demos/sm9demo.sh @@ -1,12 +1,12 @@ -#!/bin/bash - -gmssl sm9setup -alg sm9sign -pass 1234 -out sign_msk.pem -pubout sign_mpk.pem -gmssl sm9keygen -alg sm9sign -in sign_msk.pem -inpass 1234 -id alice -out alice.pem -outpass 1234 -echo hello | gmssl sm9sign -key alice.pem -pass 1234 -out hello.sig -echo hello | gmssl sm9verify -pubmaster sign_mpk.pem -id alice -sig hello.sig - -gmssl sm9setup -alg sm9encrypt -pass 1234 -out enc_msk.pem -pubout enc_mpk.pem -gmssl sm9keygen -alg sm9encrypt -in enc_msk.pem -inpass 1234 -id bob -out bob.pem -outpass 1234 -echo hello | gmssl sm9encrypt -pubmaster enc_mpk.pem -id bob -out hello.der -gmssl sm9decrypt -key bob.pem -pass 1234 -id bob -in hello.der - +#!/bin/bash + +gmssl sm9setup -alg sm9sign -pass 1234 -out sign_msk.pem -pubout sign_mpk.pem +gmssl sm9keygen -alg sm9sign -in sign_msk.pem -inpass 1234 -id alice -out alice.pem -outpass 1234 +echo hello | gmssl sm9sign -key alice.pem -pass 1234 -out hello.sig +echo hello | gmssl sm9verify -pubmaster sign_mpk.pem -id alice -sig hello.sig + +gmssl sm9setup -alg sm9encrypt -pass 1234 -out enc_msk.pem -pubout enc_mpk.pem +gmssl sm9keygen -alg sm9encrypt -in enc_msk.pem -inpass 1234 -id bob -out bob.pem -outpass 1234 +echo hello | gmssl sm9encrypt -pubmaster enc_mpk.pem -id bob -out hello.der +gmssl sm9decrypt -key bob.pem -pass 1234 -id bob -in hello.der + diff --git a/demos/tlcp/Makefile b/demos/tlcp/Makefile index 44462eec..a53507aa 100644 --- a/demos/tlcp/Makefile +++ b/demos/tlcp/Makefile @@ -1,8 +1,8 @@ -all: - cc tlcp_get.c url_parser.c -lgmssl -o tlcp_get - cc tlcp_post.c url_parser.c -lgmssl -o tlcp_post - -clean: - rm -fr tlcp_get - rm -fr tlcp_post - +all: + cc tlcp_get.c url_parser.c -lgmssl -o tlcp_get + cc tlcp_post.c url_parser.c -lgmssl -o tlcp_post + +clean: + rm -fr tlcp_get + rm -fr tlcp_post + diff --git a/demos/tlcp/tlcp_get.c b/demos/tlcp/tlcp_get.c index f9726e66..843eff96 100644 --- a/demos/tlcp/tlcp_get.c +++ b/demos/tlcp/tlcp_get.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,103 +7,104 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "url_parser.h" - - -int main(int argc, char *argv[]) -{ - int ret = -1; - char *prog = argv[0]; - const int cipher = TLS_cipher_ecc_sm4_cbc_sm3; - URL_COMPONENTS *url; - struct hostent *hp; - int port = 443; - struct sockaddr_in server; - int sock; - TLS_CTX ctx; - TLS_CONNECT conn; - char request[1024]; - uint8_t buf[16800]; - char *p; - size_t len; - - if (argc != 2) { - fprintf(stderr, "example: tlcp_get https://sm2only.ovssl.cn\n"); - return 1; - } - - if (!(url = parse_url(argv[1]))) { - fprintf(stderr, "parse url '%s' failure\n", argv[1]); - return 1; - } - if (!(hp = gethostbyname(url->host))) { - herror("tlcp_client: '-host' invalid"); - goto end; - } - if (url->port != -1) { - port = url->port; - } - - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - goto end; - } - if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - perror("connect"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode); - tls_ctx_set_cipher_suites(&ctx, &cipher, 1); - tls_init(&conn, &ctx); - tls_set_socket(&conn, sock); - - if (tls_do_handshake(&conn) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - snprintf(request, sizeof(request)-1, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", - url->path ? url->path : "/", - url->host); - - tls_send(&conn, (uint8_t *)request, strlen(request), &len); - - if (tls_recv(&conn, buf, sizeof(buf), &len) != 1) { - fprintf(stderr, "recv failure\n"); - goto end; - } - buf[len] = 0; - - p = strstr((char *)buf, "\r\n\r\n"); - if (p) { - printf("%s", p + 4); - fflush(stdout); - } - -end: - free_url_components(url); - close(sock); - tls_ctx_cleanup(&ctx); - tls_cleanup(&conn); - return 0; -} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "url_parser.h" + + +int main(int argc, char *argv[]) +{ + int ret = -1; + char *prog = argv[0]; + const int cipher = TLS_cipher_ecc_sm4_cbc_sm3; + URL_COMPONENTS *url; + struct hostent *hp; + int port = 443; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; + TLS_CONNECT conn; + char request[1024]; + uint8_t buf[16800]; + char *p; + size_t len; + + if (argc != 2) { + fprintf(stderr, "example: tlcp_get https://sm2only.ovssl.cn\n"); + return 1; + } + + if (!(url = parse_url(argv[1]))) { + fprintf(stderr, "parse url '%s' failure\n", argv[1]); + return 1; + } + if (!(hp = gethostbyname(url->host))) { + herror("tlcp_client: '-host' invalid"); + goto end; + } + if (url->port != -1) { + port = url->port; + } + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + perror("connect"); + goto end; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode); + tls_ctx_set_cipher_suites(&ctx, &cipher, 1); + tls_init(&conn, &ctx); + tls_set_socket(&conn, sock); + + if (tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + snprintf(request, sizeof(request)-1, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", + url->path ? url->path : "/", + url->host); + + tls_send(&conn, (uint8_t *)request, strlen(request), &len); + + if (tls_recv(&conn, buf, sizeof(buf), &len) != 1) { + fprintf(stderr, "recv failure\n"); + goto end; + } + buf[len] = 0; + + p = strstr((char *)buf, "\r\n\r\n"); + if (p) { + printf("%s", p + 4); + fflush(stdout); + } + +end: + free_url_components(url); + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); + return 0; +} diff --git a/demos/tlcp/tlcp_post.c b/demos/tlcp/tlcp_post.c index 4d4a3d2e..ef1d591a 100644 --- a/demos/tlcp/tlcp_post.c +++ b/demos/tlcp/tlcp_post.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,108 +7,109 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "url_parser.h" - - -int main(int argc, char *argv[]) -{ - int ret = -1; - char *prog = argv[0]; - const int cipher = TLS_cipher_ecc_sm4_cbc_sm3; - URL_COMPONENTS *url; - struct hostent *hp; - int port = 443; - struct sockaddr_in server; - int sock; - TLS_CTX ctx; - TLS_CONNECT conn; - char request[1024]; - uint8_t buf[16800]; - char *p; - size_t len; - - if (argc != 2) { - fprintf(stderr, "example: echo \"key=word\" | tlcp_post https://sm2only.ovssl.cn\n"); - return 1; - } - - if (!(url = parse_url(argv[1]))) { - fprintf(stderr, "parse url '%s' failure\n", argv[1]); - return 1; - } - if (!(hp = gethostbyname(url->host))) { - herror("tlcp_client: '-host' invalid"); - goto end; - } - if (url->port != -1) { - port = url->port; - } - - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - goto end; - } - if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - perror("connect"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode); - tls_ctx_set_cipher_suites(&ctx, &cipher, 1); - tls_init(&conn, &ctx); - tls_set_socket(&conn, sock); - - if (tls_do_handshake(&conn) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - snprintf(request, sizeof(request)-1, "POST %s HTTP/1.1\r\nHost: %s\r\n\r\n", - url->path ? url->path : "/", - url->host); - - tls_send(&conn, (uint8_t *)request, strlen(request), &len); - - len = fread(buf, 1, sizeof(buf), stdin); - if (len) { - tls_send(&conn, buf, len, &len); - } - - if (tls_recv(&conn, buf, sizeof(buf), &len) != 1) { - fprintf(stderr, "recv failure\n"); - goto end; - } - buf[len] = 0; - - p = strstr((char *)buf, "\r\n\r\n"); - if (p) { - printf("%s", p + 4); - fflush(stdout); - } - -end: - free_url_components(url); - close(sock); - tls_ctx_cleanup(&ctx); - tls_cleanup(&conn); - return 0; -} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "url_parser.h" + + +int main(int argc, char *argv[]) +{ + int ret = -1; + char *prog = argv[0]; + const int cipher = TLS_cipher_ecc_sm4_cbc_sm3; + URL_COMPONENTS *url; + struct hostent *hp; + int port = 443; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; + TLS_CONNECT conn; + char request[1024]; + uint8_t buf[16800]; + char *p; + size_t len; + + if (argc != 2) { + fprintf(stderr, "example: echo \"key=word\" | tlcp_post https://sm2only.ovssl.cn\n"); + return 1; + } + + if (!(url = parse_url(argv[1]))) { + fprintf(stderr, "parse url '%s' failure\n", argv[1]); + return 1; + } + if (!(hp = gethostbyname(url->host))) { + herror("tlcp_client: '-host' invalid"); + goto end; + } + if (url->port != -1) { + port = url->port; + } + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + perror("connect"); + goto end; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode); + tls_ctx_set_cipher_suites(&ctx, &cipher, 1); + tls_init(&conn, &ctx); + tls_set_socket(&conn, sock); + + if (tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + snprintf(request, sizeof(request)-1, "POST %s HTTP/1.1\r\nHost: %s\r\n\r\n", + url->path ? url->path : "/", + url->host); + + tls_send(&conn, (uint8_t *)request, strlen(request), &len); + + len = fread(buf, 1, sizeof(buf), stdin); + if (len) { + tls_send(&conn, buf, len, &len); + } + + if (tls_recv(&conn, buf, sizeof(buf), &len) != 1) { + fprintf(stderr, "recv failure\n"); + goto end; + } + buf[len] = 0; + + p = strstr((char *)buf, "\r\n\r\n"); + if (p) { + printf("%s", p + 4); + fflush(stdout); + } + +end: + free_url_components(url); + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); + return 0; +} diff --git a/demos/tlcp/url_parser.c b/demos/tlcp/url_parser.c index 0a505412..e5832619 100644 --- a/demos/tlcp/url_parser.c +++ b/demos/tlcp/url_parser.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,410 +7,411 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include "url_parser.h" -#include -#include -#include - -static const char *_strnstr(const char *s, size_t s_len, const char *needle) -{ - const char *end = s + s_len; - size_t needle_len = strlen(needle); - const char *p; - - p = s; - while (p < end - needle_len + 1) { - if (strncmp(p, needle, needle_len) == 0) { - return p; - } - p++; - } - - return NULL; -} - -static const char *find_chars(const char *s, size_t s_len, const char *chars) -{ - const char *end = s + s_len; - size_t chars_n = strlen(chars); - const char *p; - int i; - - p = s; - while (p < end) { - for (i = 0 ; i < chars_n ; i++) { - if (*p == chars[i]) { - return p; - } - } - p++; - } - - return NULL; -} - -static const char *find_chars_reverse(const char *s, size_t s_len, const char *chars) -{ - const char *end = s + s_len; - size_t chars_n = strlen(chars); - const char *p; - int i; - - p = end - 1; - while (p >= s) { - for (i = 0 ; i < chars_n ; i++) { - if (*p == chars[i]) { - return p; - } - } - p--; - } - - return NULL; -} - -static int is_alpha(char c) -{ - if ((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z')) { - return 1; - } - return 0; -} - -static int is_digit(char c) -{ - if (c >= '0' && c <= '9') { - return 1; - } - return 0; -} - -static int is_control(char c) -{ - if ((c >= 0x00 && c <= 0x1f) || - c == 0x7f) { - return 1; - } - return 0; -} - -static const char *lookup_scheme(const char *s) -{ - const char *p = s; - char c; - - if (strlen(s) == 0) { - return NULL; - } - - if (!is_alpha(*p)) { - return NULL; - } - p++; - - while (*p != '\0') { - c = *p; - if (c == ':') { - return p; - } - if (!is_alpha(c) && - !is_digit(c) && - c != '+' && - c != '-' && - c != '.') { - return NULL; - } - p++; - } - return NULL; -} - -static int parse_user_password(const char *s, size_t s_len, URL_COMPONENTS *c) -{ - const char *end = s + s_len; - const char *found; - - found = _strnstr(s, s_len, ":"); - if (found) { - c->user = strndup(s, found - s); - if (c->user == NULL) { - return -1; /* ENOMEM */ - } - c->password = strndup(found + 1, end - found - 1); - if (c->password == NULL) { - return -1; /* ENOMEM */ - } - } else { - c->user = strndup(s, s_len); - if (c->user == NULL) { - return -1; /* ENOMEM */ - } - } - - return 0; -} - -static int parse_authority(const char *s, size_t s_len, URL_COMPONENTS *c) -{ - const char *end = s + s_len; - const char *p, *found, *host_start, *host_end; - int port; - - c->port = -1; - - if (s_len == 0) { /* empty authority */ - return 0; - } - - found = _strnstr(s, s_len, "@"); - if (found) { - if (parse_user_password(s, found - s, c) == -1) { - return -1; - } - - host_start = found + 1; - } else { - host_start = s; - } - - if (*host_start == '[') { - /* IP-literal host */ - if (find_chars(host_start + 1, end - host_start - 1, "[")) { - errno = EINVAL; - return -1; - } - host_end = find_chars(host_start + 1, end - host_start - 1, "]"); - if (!host_end) { - errno = EINVAL; - return -1; - } - /* The next character of ']' is termination or ':'. */ - if (host_end + 1 != end && host_end[1] != ':') { - errno = EINVAL; - return -1; - } - host_end++; - } else { - /* IPv4address / reg-name host */ - host_end = find_chars_reverse(host_start, end - host_start, ":"); - if (host_end == NULL) { - host_end = end; - } - if (find_chars(host_start, host_end - host_start, "[]")) { - errno = EINVAL; - return -1; - } - } - if (find_chars(host_start, host_end - host_start, " ")) { - errno = EINVAL; - return -1; - } - - /* ASSERT: host_end == end or *host_end == ':' */ - - if (host_end == end) { - /* without port number */ - if (host_start == end) { /* empty host */ - errno = EINVAL; - return -1; - } - c->host = strndup(host_start, end - host_start); - if (c->host == NULL) { - return -1; /* ENOMEM */ - } - return 0; - } - - /* ASSERT: *host_end == ':' */ - - /* host and port */ - - if (host_start == host_end) { /* empty host */ - errno = EINVAL; - return -1; - } - - if (host_end + 1 < end) { - p = host_end + 1; - port = 0; - while (p < end) { - if (*p < '0' || *p > '9') { - errno = EINVAL; - return -1; - } - - port = port * 10 + *p - '0'; - if (port > 65535) { - errno = EINVAL; - return -1; - } - - p++; - } - } else { - /* empty port number */ - port = -1; - } - - c->host = strndup(host_start, (size_t) (host_end - host_start)); - if (c->host == NULL) { - return -1; /* ENOMEM */ - } - c->port = port; - - return 0; -} - -URL_COMPONENTS *parse_url(const char *url) -{ - URL_COMPONENTS *c; - const char *p; - const char *end = url + strlen(url); - const char *found; - size_t len; - - for (p = url ; p < end ; p++) { - if (is_control(*p)) { - errno = EINVAL; - return NULL; - } - } - - c = malloc(sizeof(URL_COMPONENTS)); - if (!c) { - return NULL; - } - memset(c, 0, sizeof(URL_COMPONENTS)); - c->port = -1; - - p = url; - - /* lookup scheme */ - found = lookup_scheme(p); - if (found) { - c->scheme = strndup(url, (size_t) (found - p)); - if (c->scheme == NULL) { - goto error; - } - p = found + 1; /* skip a colon */ - if (p >= end) { - return c; - } - } - - if (strlen(p) >= 2 && - p[0] == '/' && p[1] == '/') { - /* authority */ - p = p + 2; - found = find_chars(p, strlen(p), "/?#"); - if (found == NULL) { - len = strlen(p); - } else { - len = (size_t) (found - p); - } - if (parse_authority(p, len, c) == -1) { - goto error; /* ENOMEM,EINVAL */ - } - - if (!found) { - return c; - } - - p = found; - } - - if (*p != '?' && *p != '#') { - /* path */ - found = find_chars(p, strlen(p), "?#"); - found = NULL; - if (found == NULL) { - c->path = strdup(p); - if (c->path == NULL) { - goto error; - } - } else - { - if (found != p) { - c->path = strndup(p, (size_t) (found - p)); - if (c->path == NULL) { - goto error; - } - } - } - - if (!found) { - return c; - } - - p = found; - } - - /* ASSERT: *p is '?' or '#' */ -#if 0 - if (*p == '?') { - /* query */ - p = p + 1; - found = find_chars(p, strlen(p), "#"); - if (found == NULL) { - c->query = strdup(p); - } else { - c->query = strndup(p, (size_t) (found - p)); - } - - if (c->query == NULL) { - goto error; - } - - if (!found) { - return c; - } - - p = found; - } -#endif - - /* ASSERT: *p is '#' */ - - /* fragment */ - p = p + 1; - c->fragment = strdup(p); - if (c->fragment == NULL) { - goto error; - } - - return c; - -error: - free(c); - - return NULL; -} - -void free_url_components(URL_COMPONENTS *c) -{ - if (c->scheme) { - free(c->scheme); - } - if (c->user) { - free(c->user); - } - if (c->password) { - free(c->password); - } - if (c->host) { - free(c->host); - } - if (c->path) { - free(c->path); - } - if (c->query) { - free(c->query); - } - if (c->fragment) { - free(c->fragment); - } - free(c); -} - + + +#include "url_parser.h" +#include +#include +#include + +static const char *_strnstr(const char *s, size_t s_len, const char *needle) +{ + const char *end = s + s_len; + size_t needle_len = strlen(needle); + const char *p; + + p = s; + while (p < end - needle_len + 1) { + if (strncmp(p, needle, needle_len) == 0) { + return p; + } + p++; + } + + return NULL; +} + +static const char *find_chars(const char *s, size_t s_len, const char *chars) +{ + const char *end = s + s_len; + size_t chars_n = strlen(chars); + const char *p; + int i; + + p = s; + while (p < end) { + for (i = 0 ; i < chars_n ; i++) { + if (*p == chars[i]) { + return p; + } + } + p++; + } + + return NULL; +} + +static const char *find_chars_reverse(const char *s, size_t s_len, const char *chars) +{ + const char *end = s + s_len; + size_t chars_n = strlen(chars); + const char *p; + int i; + + p = end - 1; + while (p >= s) { + for (i = 0 ; i < chars_n ; i++) { + if (*p == chars[i]) { + return p; + } + } + p--; + } + + return NULL; +} + +static int is_alpha(char c) +{ + if ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z')) { + return 1; + } + return 0; +} + +static int is_digit(char c) +{ + if (c >= '0' && c <= '9') { + return 1; + } + return 0; +} + +static int is_control(char c) +{ + if ((c >= 0x00 && c <= 0x1f) || + c == 0x7f) { + return 1; + } + return 0; +} + +static const char *lookup_scheme(const char *s) +{ + const char *p = s; + char c; + + if (strlen(s) == 0) { + return NULL; + } + + if (!is_alpha(*p)) { + return NULL; + } + p++; + + while (*p != '\0') { + c = *p; + if (c == ':') { + return p; + } + if (!is_alpha(c) && + !is_digit(c) && + c != '+' && + c != '-' && + c != '.') { + return NULL; + } + p++; + } + return NULL; +} + +static int parse_user_password(const char *s, size_t s_len, URL_COMPONENTS *c) +{ + const char *end = s + s_len; + const char *found; + + found = _strnstr(s, s_len, ":"); + if (found) { + c->user = strndup(s, found - s); + if (c->user == NULL) { + return -1; /* ENOMEM */ + } + c->password = strndup(found + 1, end - found - 1); + if (c->password == NULL) { + return -1; /* ENOMEM */ + } + } else { + c->user = strndup(s, s_len); + if (c->user == NULL) { + return -1; /* ENOMEM */ + } + } + + return 0; +} + +static int parse_authority(const char *s, size_t s_len, URL_COMPONENTS *c) +{ + const char *end = s + s_len; + const char *p, *found, *host_start, *host_end; + int port; + + c->port = -1; + + if (s_len == 0) { /* empty authority */ + return 0; + } + + found = _strnstr(s, s_len, "@"); + if (found) { + if (parse_user_password(s, found - s, c) == -1) { + return -1; + } + + host_start = found + 1; + } else { + host_start = s; + } + + if (*host_start == '[') { + /* IP-literal host */ + if (find_chars(host_start + 1, end - host_start - 1, "[")) { + errno = EINVAL; + return -1; + } + host_end = find_chars(host_start + 1, end - host_start - 1, "]"); + if (!host_end) { + errno = EINVAL; + return -1; + } + /* The next character of ']' is termination or ':'. */ + if (host_end + 1 != end && host_end[1] != ':') { + errno = EINVAL; + return -1; + } + host_end++; + } else { + /* IPv4address / reg-name host */ + host_end = find_chars_reverse(host_start, end - host_start, ":"); + if (host_end == NULL) { + host_end = end; + } + if (find_chars(host_start, host_end - host_start, "[]")) { + errno = EINVAL; + return -1; + } + } + if (find_chars(host_start, host_end - host_start, " ")) { + errno = EINVAL; + return -1; + } + + /* ASSERT: host_end == end or *host_end == ':' */ + + if (host_end == end) { + /* without port number */ + if (host_start == end) { /* empty host */ + errno = EINVAL; + return -1; + } + c->host = strndup(host_start, end - host_start); + if (c->host == NULL) { + return -1; /* ENOMEM */ + } + return 0; + } + + /* ASSERT: *host_end == ':' */ + + /* host and port */ + + if (host_start == host_end) { /* empty host */ + errno = EINVAL; + return -1; + } + + if (host_end + 1 < end) { + p = host_end + 1; + port = 0; + while (p < end) { + if (*p < '0' || *p > '9') { + errno = EINVAL; + return -1; + } + + port = port * 10 + *p - '0'; + if (port > 65535) { + errno = EINVAL; + return -1; + } + + p++; + } + } else { + /* empty port number */ + port = -1; + } + + c->host = strndup(host_start, (size_t) (host_end - host_start)); + if (c->host == NULL) { + return -1; /* ENOMEM */ + } + c->port = port; + + return 0; +} + +URL_COMPONENTS *parse_url(const char *url) +{ + URL_COMPONENTS *c; + const char *p; + const char *end = url + strlen(url); + const char *found; + size_t len; + + for (p = url ; p < end ; p++) { + if (is_control(*p)) { + errno = EINVAL; + return NULL; + } + } + + c = malloc(sizeof(URL_COMPONENTS)); + if (!c) { + return NULL; + } + memset(c, 0, sizeof(URL_COMPONENTS)); + c->port = -1; + + p = url; + + /* lookup scheme */ + found = lookup_scheme(p); + if (found) { + c->scheme = strndup(url, (size_t) (found - p)); + if (c->scheme == NULL) { + goto error; + } + p = found + 1; /* skip a colon */ + if (p >= end) { + return c; + } + } + + if (strlen(p) >= 2 && + p[0] == '/' && p[1] == '/') { + /* authority */ + p = p + 2; + found = find_chars(p, strlen(p), "/?#"); + if (found == NULL) { + len = strlen(p); + } else { + len = (size_t) (found - p); + } + if (parse_authority(p, len, c) == -1) { + goto error; /* ENOMEM,EINVAL */ + } + + if (!found) { + return c; + } + + p = found; + } + + if (*p != '?' && *p != '#') { + /* path */ + found = find_chars(p, strlen(p), "?#"); + found = NULL; + if (found == NULL) { + c->path = strdup(p); + if (c->path == NULL) { + goto error; + } + } else + { + if (found != p) { + c->path = strndup(p, (size_t) (found - p)); + if (c->path == NULL) { + goto error; + } + } + } + + if (!found) { + return c; + } + + p = found; + } + + /* ASSERT: *p is '?' or '#' */ +#if 0 + if (*p == '?') { + /* query */ + p = p + 1; + found = find_chars(p, strlen(p), "#"); + if (found == NULL) { + c->query = strdup(p); + } else { + c->query = strndup(p, (size_t) (found - p)); + } + + if (c->query == NULL) { + goto error; + } + + if (!found) { + return c; + } + + p = found; + } +#endif + + /* ASSERT: *p is '#' */ + + /* fragment */ + p = p + 1; + c->fragment = strdup(p); + if (c->fragment == NULL) { + goto error; + } + + return c; + +error: + free(c); + + return NULL; +} + +void free_url_components(URL_COMPONENTS *c) +{ + if (c->scheme) { + free(c->scheme); + } + if (c->user) { + free(c->user); + } + if (c->password) { + free(c->password); + } + if (c->host) { + free(c->host); + } + if (c->path) { + free(c->path); + } + if (c->query) { + free(c->query); + } + if (c->fragment) { + free(c->fragment); + } + free(c); +} + diff --git a/demos/tlcp/url_parser.h b/demos/tlcp/url_parser.h index 12596cc9..3dc62818 100644 --- a/demos/tlcp/url_parser.h +++ b/demos/tlcp/url_parser.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,24 +7,25 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef URL_PARSER_H -#define URL_PARSER_H - -#define URL_PARSER_VERSION 0x00000300 /* 0.0.3 */ - -typedef struct url_components { - char *scheme; - char *user; - char *password; - char *host; - int port; - char *path; - char *query; - char *fragment; -} URL_COMPONENTS; - -extern URL_COMPONENTS *parse_url(const char *url); -extern void free_url_components(URL_COMPONENTS *c); - -#endif + + +#ifndef URL_PARSER_H +#define URL_PARSER_H + +#define URL_PARSER_VERSION 0x00000300 /* 0.0.3 */ + +typedef struct url_components { + char *scheme; + char *user; + char *password; + char *host; + int port; + char *path; + char *query; + char *fragment; +} URL_COMPONENTS; + +extern URL_COMPONENTS *parse_url(const char *url); +extern void free_url_components(URL_COMPONENTS *c); + +#endif diff --git a/demos/tlcp_client.sh b/demos/tlcp_client.sh index 226c037d..0a413750 100755 --- a/demos/tlcp_client.sh +++ b/demos/tlcp_client.sh @@ -1,8 +1,8 @@ -#!/bin/bash -x - - -# https://ebssec.boc.cn -gmssl tlcp_client -host 123.124.191.183 - -# https://zffw.jxzwfww.gov.cn -gmssl tlcp_client -host 218.87.21.62 +#!/bin/bash -x + + +# https://ebssec.boc.cn +gmssl tlcp_client -host 123.124.191.183 + +# https://zffw.jxzwfww.gov.cn +gmssl tlcp_client -host 218.87.21.62 diff --git a/demos/tlcp_server.sh b/demos/tlcp_server.sh index 42623698..338b372b 100755 --- a/demos/tlcp_server.sh +++ b/demos/tlcp_server.sh @@ -1,39 +1,39 @@ -#!/bin/bash -x - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -gmssl sm2keygen -pass 1234 -out enckey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem -gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem -gmssl certparse -in enccert.pem - -cat signcert.pem > double_certs.pem -cat enccert.pem >> double_certs.pem -cat cacert.pem >> double_certs.pem - -sudo gmssl tlcp_server -port 443 -cert double_certs.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & -sleep 3 - -gmssl sm2keygen -pass 1234 -out clientkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem -gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem -gmssl certparse -in clientcert.pem - -# build and install BabaSSL 8.3.1 -openssl version -openssl s_client -enable_ntls -ntls -connect localhost:443 -no_ticket -CAfile rootcacert.pem - - +#!/bin/bash -x + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + +cat signcert.pem > double_certs.pem +cat enccert.pem >> double_certs.pem +cat cacert.pem >> double_certs.pem + +sudo gmssl tlcp_server -port 443 -cert double_certs.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & +sleep 3 + +gmssl sm2keygen -pass 1234 -out clientkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem +gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem +gmssl certparse -in clientcert.pem + +# build and install BabaSSL 8.3.1 +openssl version +openssl s_client -enable_ntls -ntls -connect localhost:443 -no_ticket -CAfile rootcacert.pem + + diff --git a/demos/tlcpdemo.sh b/demos/tlcpdemo.sh index 7e53ca86..45fd8d94 100755 --- a/demos/tlcpdemo.sh +++ b/demos/tlcpdemo.sh @@ -1,36 +1,36 @@ -#!/bin/bash -x - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -gmssl sm2keygen -pass 1234 -out enckey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem -gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem -gmssl certparse -in enccert.pem - -cat signcert.pem > double_certs.pem -cat enccert.pem >> double_certs.pem -cat cacert.pem >> double_certs.pem - -sudo gmssl tlcp_server -port 443 -cert double_certs.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & -sleep 3 - -gmssl sm2keygen -pass 1234 -out clientkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem -gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem -gmssl certparse -in clientcert.pem - -gmssl tlcp_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 - +#!/bin/bash -x + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + +cat signcert.pem > double_certs.pem +cat enccert.pem >> double_certs.pem +cat cacert.pem >> double_certs.pem + +sudo gmssl tlcp_server -port 443 -cert double_certs.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & +sleep 3 + +gmssl sm2keygen -pass 1234 -out clientkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem +gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem +gmssl certparse -in clientcert.pem + +gmssl tlcp_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 + diff --git a/demos/tls12demo.sh b/demos/tls12demo.sh index 676fb4a4..e24eb7de 100755 --- a/demos/tls12demo.sh +++ b/demos/tls12demo.sh @@ -1,30 +1,30 @@ -#!/bin/bash -x - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -cat signcert.pem > certs.pem -cat cacert.pem >> certs.pem - -sudo gmssl tls12_server -port 443 -cert certs.pem -key signkey.pem -pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & -sleep 3 - -gmssl sm2keygen -pass 1234 -out clientkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem -gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem -gmssl certparse -in clientcert.pem - -gmssl tls12_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 - +#!/bin/bash -x + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +cat signcert.pem > certs.pem +cat cacert.pem >> certs.pem + +sudo gmssl tls12_server -port 443 -cert certs.pem -key signkey.pem -pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & +sleep 3 + +gmssl sm2keygen -pass 1234 -out clientkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem +gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem +gmssl certparse -in clientcert.pem + +gmssl tls12_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 + diff --git a/demos/tls13demo.sh b/demos/tls13demo.sh index d36c9582..79524a18 100755 --- a/demos/tls13demo.sh +++ b/demos/tls13demo.sh @@ -1,30 +1,30 @@ -#!/bin/bash -x - - -gmssl sm2keygen -pass 1234 -out rootcakey.pem -gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign -gmssl certparse -in rootcacert.pem - -gmssl sm2keygen -pass 1234 -out cakey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem -gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem -gmssl certparse -in cacert.pem - -gmssl sm2keygen -pass 1234 -out signkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem -gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem -gmssl certparse -in signcert.pem - -cat signcert.pem > certs.pem -cat cacert.pem >> certs.pem - -sudo gmssl tls13_server -port 443 -cert certs.pem -key signkey.pem -pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & -sleep 3 - -gmssl sm2keygen -pass 1234 -out clientkey.pem -gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem -gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem -gmssl certparse -in clientcert.pem - -gmssl tls13_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 - +#!/bin/bash -x + + +gmssl sm2keygen -pass 1234 -out rootcakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 -key rootcakey.pem -pass 1234 -out rootcacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in rootcacert.pem + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN "Sub CA" -days 3650 -key cakey.pem -pass 1234 -out careq.pem +gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -path_len_constraint 0 -cacert rootcacert.pem -key rootcakey.pem -pass 1234 -out cacert.pem +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +cat signcert.pem > certs.pem +cat cacert.pem >> certs.pem + +sudo gmssl tls13_server -port 443 -cert certs.pem -key signkey.pem -pass 1234 -cacert cacert.pem 1>/dev/null 2>/dev/null & +sleep 3 + +gmssl sm2keygen -pass 1234 -out clientkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN Client -days 365 -key clientkey.pem -pass 1234 -out clientreq.pem +gmssl reqsign -in clientreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out clientcert.pem +gmssl certparse -in clientcert.pem + +gmssl tls13_client -host 127.0.0.1 -cacert rootcacert.pem -cert clientcert.pem -key clientkey.pem -pass 1234 + diff --git a/demos/zuc/Makefile b/demos/zuc/Makefile index 18e178f8..16c6fc82 100644 --- a/demos/zuc/Makefile +++ b/demos/zuc/Makefile @@ -1,8 +1,8 @@ -all: - cc zuc_demo.c -lgmssl -o zuc_encrypt_demo - cc zuc_demo.c -lgmssl -o zuc_decrypt_demo - -clean: - rm -fr zuc_encrypt_demo - rm -fr zuc_decrypt_demo - +all: + cc zuc_demo.c -lgmssl -o zuc_encrypt_demo + cc zuc_demo.c -lgmssl -o zuc_decrypt_demo + +clean: + rm -fr zuc_encrypt_demo + rm -fr zuc_decrypt_demo + diff --git a/demos/zuc/zuc_demo.c b/demos/zuc/zuc_demo.c index 3ddd57c3..daf83e39 100644 --- a/demos/zuc/zuc_demo.c +++ b/demos/zuc/zuc_demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,44 +7,45 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include -#include -#include -#include - - -int main(void) -{ - ZUC_CTX zuc_ctx; - unsigned char key[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char iv[16] = { - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - }; - unsigned char inbuf[1024]; - unsigned char outbuf[1024 + 32]; - ssize_t inlen; - size_t outlen; - - if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { - if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - } - if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return 1; - } - fwrite(outbuf, 1, outlen, stdout); - - return 0; -} + +#include +#include +#include +#include + + +int main(void) +{ + ZUC_CTX zuc_ctx; + unsigned char key[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char iv[16] = { + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + }; + unsigned char inbuf[1024]; + unsigned char outbuf[1024 + 32]; + ssize_t inlen; + size_t outlen; + + if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), stdin)) > 0) { + if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + } + if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return 1; + } + fwrite(outbuf, 1, outlen, stdout); + + return 0; +} diff --git a/demos/zucdemo.sh b/demos/zucdemo.sh index 777f6a00..d19ad490 100755 --- a/demos/zucdemo.sh +++ b/demos/zucdemo.sh @@ -1,10 +1,10 @@ -#!/bin/bash - - -KEY=11223344556677881122334455667788 -IV=11223344556677881122334455667788 - -echo hello | gmssl zuc -key $KEY -iv $IV -out zuc.bin -gmssl zuc -key $KEY -iv $IV -in zuc.bin - - +#!/bin/bash + + +KEY=11223344556677881122334455667788 +IV=11223344556677881122334455667788 + +echo hello | gmssl zuc -key $KEY -iv $IV -out zuc.bin +gmssl zuc -key $KEY -iv $IV -in zuc.bin + + diff --git a/include/gmssl/aes.h b/include/gmssl/aes.h index 56eb5a90..3c513fb8 100644 --- a/include/gmssl/aes.h +++ b/include/gmssl/aes.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,84 +7,85 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_AES_H -#define GMSSL_AES_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define AES128_KEY_BITS 128 -#define AES192_KEY_BITS 192 -#define AES256_KEY_BITS 256 - -#define AES128_KEY_SIZE (AES128_KEY_BITS/8) -#define AES192_KEY_SIZE (AES192_KEY_BITS/8) -#define AES256_KEY_SIZE (AES256_KEY_BITS/8) - -#define AES_BLOCK_SIZE 16 - -#define AES128_ROUNDS 10 -#define AES192_ROUNDS 12 -#define AES256_ROUNDS 14 -#define AES_MAX_ROUNDS AES256_ROUNDS - - -typedef struct { - uint32_t rk[4 * (AES_MAX_ROUNDS + 1)]; - size_t rounds; -} AES_KEY; - -int aes_set_encrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); -int aes_set_decrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); -void aes_encrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); -void aes_decrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); - - -void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], - const uint8_t *in, size_t nblocks, uint8_t *out); -void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], - const uint8_t *in, size_t nblocks, uint8_t *out); -int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); -int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[AES_BLOCK_SIZE], - const uint8_t *in, size_t inlen, uint8_t *out); -#define aes_ctr_decrypt(key,ctr,in,inlen,out) aes_ctr_encrypt(key,ctr,in,inlen,out) - - -#define AES_GCM_IV_MIN_SIZE 1 -#define AES_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) -#define AES_GCM_IV_DEFAULT_BITS 96 -#define AES_GCM_IV_DEFAULT_SIZE 12 - -#define AES_GCM_MIN_AAD_SIZE 0 -#define AES_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) - -#define AES_GCM_MIN_PLAINTEXT_SIZE 0 -#define AES_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) - -#define AES_GCM_MAX_TAG_SIZE 16 - -int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag); -int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_AES_H +#define GMSSL_AES_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define AES128_KEY_BITS 128 +#define AES192_KEY_BITS 192 +#define AES256_KEY_BITS 256 + +#define AES128_KEY_SIZE (AES128_KEY_BITS/8) +#define AES192_KEY_SIZE (AES192_KEY_BITS/8) +#define AES256_KEY_SIZE (AES256_KEY_BITS/8) + +#define AES_BLOCK_SIZE 16 + +#define AES128_ROUNDS 10 +#define AES192_ROUNDS 12 +#define AES256_ROUNDS 14 +#define AES_MAX_ROUNDS AES256_ROUNDS + + +typedef struct { + uint32_t rk[4 * (AES_MAX_ROUNDS + 1)]; + size_t rounds; +} AES_KEY; + +int aes_set_encrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); +int aes_set_decrypt_key(AES_KEY *key, const uint8_t *raw_key, size_t raw_key_len); +void aes_encrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); +void aes_decrypt(const AES_KEY *key, const uint8_t in[AES_BLOCK_SIZE], uint8_t out[AES_BLOCK_SIZE]); + + +void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); +int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[AES_BLOCK_SIZE], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); + +void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[AES_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out); +#define aes_ctr_decrypt(key,ctr,in,inlen,out) aes_ctr_encrypt(key,ctr,in,inlen,out) + + +#define AES_GCM_IV_MIN_SIZE 1 +#define AES_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) +#define AES_GCM_IV_DEFAULT_BITS 96 +#define AES_GCM_IV_DEFAULT_SIZE 12 + +#define AES_GCM_MIN_AAD_SIZE 0 +#define AES_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) + +#define AES_GCM_MIN_PLAINTEXT_SIZE 0 +#define AES_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) + +#define AES_GCM_MAX_TAG_SIZE 16 + +int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag); +int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/asn1.h b/include/gmssl/asn1.h index 5ccbc024..e6e7ef71 100644 --- a/include/gmssl/asn1.h +++ b/include/gmssl/asn1.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,271 +7,272 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_ASN1_H -#define GMSSL_ASN1_H - -#include -#include -#include - -#if __cplusplus -extern "C" { -#endif - - -#define ASN1_TAG_UNIVERSAL 0x00 -#define ASN1_TAG_APPLICATION 0x40 -#define ASN1_TAG_CONTENT_SPECIFIC 0x80 -#define ASN1_TAG_PRIVATE 0xC0 -#define ASN1_TAG_PRIMITIVE 0x00 -#define ASN1_TAG_CONSTRUCTED 0x20 - -#define ASN1_TAG_IMPLICIT(index) (ASN1_TAG_CONTENT_SPECIFIC|(index)) -#define ASN1_TAG_EXPLICIT(index) ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index)) - - -#define ASN1_FMT_FULL 0x01 - - -enum ASN1_TAG { - ASN1_TAG_BOOLEAN = 1, - ASN1_TAG_INTEGER = 2, - ASN1_TAG_BIT_STRING = 3, - ASN1_TAG_OCTET_STRING = 4, - ASN1_TAG_NULL = 5, - ASN1_TAG_OBJECT_IDENTIFIER = 6, - ASN1_TAG_ObjectDescriptor = 7, - ASN1_TAG_EXTERNAL = 8, - ASN1_TAG_REAL = 9, - ASN1_TAG_ENUMERATED = 10, // 0x0A - ASN1_TAG_EMBEDDED = 11, // 0x0B - ASN1_TAG_UTF8String = 12, // 0x0C - ASN1_TAG_RELATIVE_OID = 13, // 0x0D - ASN1_TAG_NumericString = 18, // 0x12 - ASN1_TAG_PrintableString = 19, // 0x13, printable subset of ascii - ASN1_TAG_TeletexString = 20, // 0x14, T61String - ASN1_TAG_VideotexString = 21, // 0x15 - ASN1_TAG_IA5String = 22, // 0x16, 7-bit ascii - ASN1_TAG_UTCTime = 23, // 0x17 - ASN1_TAG_GeneralizedTime = 24, // 0x18 - ASN1_TAG_GraphicString = 25, // 0x19 - ASN1_TAG_VisibleString = 26, // 0x20 - ASN1_TAG_GeneralString = 27, // 0x21 - ASN1_TAG_UniversalString = 28, // 0x22 - ASN1_TAG_CHARACTER_STRING = 29, // 0x23 - ASN1_TAG_BMPString = 30, // 0x24, 2-byte unicode with zeros - ASN1_TAG_SEQUENCE = 0x30, - ASN1_TAG_SET = 0x31, - ASN1_TAG_EXPLICIT = 0xa0, -}; - -const char *asn1_tag_name(int tag); -int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen); -int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen); -int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen); -int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen); // 尝试读取下一个tag,但是并不修改in,inlen -int asn1_tag_is_cstring(int tag); -int asn1_length_to_der(size_t dlen, uint8_t **out, size_t *outlen); -int asn1_length_from_der(size_t *dlen, const uint8_t **in, size_t *inlen); -int asn1_length_is_zero(size_t len); -int asn1_length_le(size_t len1, size_t len2); // less than -int asn1_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_data_from_der(const uint8_t **d, size_t dlen, const uint8_t **in, size_t *inlen); - -int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int asn1_any_type_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int asn1_any_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); // 调用方应保证a,alen为TLV -int asn1_any_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); // 该函数会检查输入是否为TLV - -const char *asn1_boolean_name(int val); -int asn1_boolean_from_name(int *val, const char *name); -int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); -int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); -#define asn1_boolean_to_der(val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,val,out,outlen) -#define asn1_boolean_from_der(val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,val,in,inlen) -#define asn1_implicit_boolean_to_der(i,val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) -#define asn1_implicit_boolean_from_der(i,val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) - -// asn1_integer_ 不支持负数编解码 -int asn1_integer_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_integer_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define asn1_integer_to_der(d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,d,dlen,out,outlen) -#define asn1_integer_from_der(d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,d,dlen,in,inlen) -#define asn1_implicit_integer_to_der(i,d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_integer_from_der(i,d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -// asn1_int_ 只支持小的无符号整数的编解码,不支持负数 -int asn1_int_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); // 当 val == -1 时,不输出,返回 0 -int asn1_int_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); // 不支持负数,返回0时 *val 设置为 -1 -#define asn1_int_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_INTEGER,val,out,outlen) -#define asn1_int_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_INTEGER,val,in,inlen) -#define asn1_implicit_int_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) -#define asn1_implicit_int_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) - -// 比特长度不必须为8的整数倍 -int asn1_bit_string_to_der_ex(int tag, const uint8_t *d, size_t nbits, uint8_t **out, size_t *outlen); -int asn1_bit_string_from_der_ex(int tag, const uint8_t **d, size_t *nbits, const uint8_t **in, size_t *inlen); -#define asn1_bit_string_to_der(d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,d,nbits,out,outlen) -#define asn1_bit_string_from_der(d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,d,nbits,in,inlen) -#define asn1_implicit_bit_string_to_der(i,d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,out,outlen) -#define asn1_implicit_bit_string_from_der(i,d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,in,inlen) - -// 比特长度必须为8的整数倍,因此使用字节长度 -int asn1_bit_octets_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_bit_octets_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define asn1_bit_octets_to_der(d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen) -#define asn1_bit_octets_from_der(d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_BIT_STRING,d,dlen,in,inlen) -#define asn1_implicit_bit_octets_to_der(i,d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_bit_octets_from_der(i,d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -// bits == -1 不编码,只支持较少的比特数量 -int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen); -int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen); -#define asn1_bits_to_der(bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,bits,out,outlen) -#define asn1_bits_from_der(bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,bits,in,inlen) -#define asn1_implicit_bits_to_der(i,bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(i),bits,out,outlen) -#define asn1_implicit_bits_from_der(i,bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(i),bits,in,inlen) -// names[i]对应第i个比特 -int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits); - -#define asn1_octet_string_to_der_ex(tag,d,dlen,out,outlen) asn1_type_to_der(tag,d,dlen,out,outlen) -#define asn1_octet_string_from_der_ex(tag,d,dlen,in,inlen) asn1_type_from_der(tag,d,dlen,in,inlen) -#define asn1_octet_string_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_OCTET_STRING,d,dlen,out,outlen) -#define asn1_octet_string_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_OCTET_STRING,d,dlen,in,inlen) -#define asn1_implicit_octet_string_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_octet_string_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -const char *asn1_null_name(void); -int asn1_null_to_der(uint8_t **out, size_t *outlen); -int asn1_null_from_der(const uint8_t **in, size_t *inlen); - -#define ASN1_OID_MAX_NODES 32 -int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen); -int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen); - -int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt); -int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen); -int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen); -#define asn1_object_identifier_to_der(nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,out,outlen) -#define asn1_object_identifier_from_der(nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,in,inlen) -#define asn1_implicit_object_identifier_to_der(i,nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,out,outlen) -#define asn1_implicit_object_identifier_from_der(i,nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,in,inlen) -int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label, const char *name, - const uint32_t *nodes, size_t nodes_cnt); - -#define asn1_enumerated_to_der_ex(tag,val,out,outlen) asn1_int_to_der_ex(tag,val,out,outlen) -#define asn1_enumerated_from_der_ex(tag,val,in,inlen) asn1_int_from_der_ex(tag,val,in,inlen) -#define asn1_enumerated_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen) -#define asn1_enumerated_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_ENUMERATED,val,in,inlen) -#define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) -#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) - -int asn1_utf8_string_check(const char *d, size_t dlen); -int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen) -#define asn1_utf8_string_from_der(d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,d,dlen,in,inlen) -#define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_utf8_string_from_der(i,d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -int asn1_printable_string_check(const char *d, size_t dlen); -int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define asn1_printable_string_to_der(d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,d,dlen,out,outlen) -#define asn1_printable_string_from_der(d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,d,dlen,in,inlen) -#define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_printable_string_from_der(i,d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -int asn1_ia5_string_check(const char *d, size_t dlen); -int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); -int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen) -#define asn1_ia5_string_from_der(d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,d,dlen,in,inlen) -#define asn1_implicit_ia5_string_to_der(i,d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_ia5_string_from_der(i,d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); - -#define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1) -#define ASN1_GENERALIZED_TIME_LEN (sizeof("YYYYMMDDHHMMSSZ")-1) - -int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); -int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); -#define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen) -#define asn1_utc_time_from_der(tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,tv,in,inlen) -#define asn1_implicit_utc_time_to_der(i,tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen) -#define asn1_implicit_utc_time_from_der(i,tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen) - -int asn1_generalized_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); -int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); -#define asn1_generalized_time_to_der(tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,tv,out,outlen) -#define asn1_generalized_time_from_der(tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,tv,in,inlen) -#define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen) -#define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen) - -#define asn1_sequence_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen) -#define asn1_sequence_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen) -#define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) - -#define asn1_set_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SET,d,dlen,out,outlen) -#define asn1_set_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SET,d,dlen,in,inlen) -#define asn1_implicit_set_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_set_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) - -#define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) -#define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) - -int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen); -#define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) - -#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen) - -#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen) -#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) - -#define asn1_set_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SET,dlen,out,outlen) -#define asn1_implicit_set_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) - -#define asn1_explicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) - -#define asn1_explicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) -#define asn1_explicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) - -// d,dlen 是 SEQUENCE OF, SET OF 中的值 -int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt); -int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag, - int index, const uint8_t **item_d, size_t *item_dlen); - -int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen); -int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen); -int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -typedef struct { - int oid; - char *name; - uint32_t *nodes; - size_t nodes_cnt; - int flags; - char *description; -} ASN1_OID_INFO; - -const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name); -const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid); -int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt, - const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen); -int asn1_oid_info_from_der(const ASN1_OID_INFO **info, - const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen); - - -int asn1_check(int expr); - - -#if __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_ASN1_H +#define GMSSL_ASN1_H + +#include +#include +#include + +#if __cplusplus +extern "C" { +#endif + + +#define ASN1_TAG_UNIVERSAL 0x00 +#define ASN1_TAG_APPLICATION 0x40 +#define ASN1_TAG_CONTENT_SPECIFIC 0x80 +#define ASN1_TAG_PRIVATE 0xC0 +#define ASN1_TAG_PRIMITIVE 0x00 +#define ASN1_TAG_CONSTRUCTED 0x20 + +#define ASN1_TAG_IMPLICIT(index) (ASN1_TAG_CONTENT_SPECIFIC|(index)) +#define ASN1_TAG_EXPLICIT(index) ASN1_TAG_IMPLICIT(ASN1_TAG_CONSTRUCTED|(index)) + + +#define ASN1_FMT_FULL 0x01 + + +enum ASN1_TAG { + ASN1_TAG_BOOLEAN = 1, + ASN1_TAG_INTEGER = 2, + ASN1_TAG_BIT_STRING = 3, + ASN1_TAG_OCTET_STRING = 4, + ASN1_TAG_NULL = 5, + ASN1_TAG_OBJECT_IDENTIFIER = 6, + ASN1_TAG_ObjectDescriptor = 7, + ASN1_TAG_EXTERNAL = 8, + ASN1_TAG_REAL = 9, + ASN1_TAG_ENUMERATED = 10, // 0x0A + ASN1_TAG_EMBEDDED = 11, // 0x0B + ASN1_TAG_UTF8String = 12, // 0x0C + ASN1_TAG_RELATIVE_OID = 13, // 0x0D + ASN1_TAG_NumericString = 18, // 0x12 + ASN1_TAG_PrintableString = 19, // 0x13, printable subset of ascii + ASN1_TAG_TeletexString = 20, // 0x14, T61String + ASN1_TAG_VideotexString = 21, // 0x15 + ASN1_TAG_IA5String = 22, // 0x16, 7-bit ascii + ASN1_TAG_UTCTime = 23, // 0x17 + ASN1_TAG_GeneralizedTime = 24, // 0x18 + ASN1_TAG_GraphicString = 25, // 0x19 + ASN1_TAG_VisibleString = 26, // 0x20 + ASN1_TAG_GeneralString = 27, // 0x21 + ASN1_TAG_UniversalString = 28, // 0x22 + ASN1_TAG_CHARACTER_STRING = 29, // 0x23 + ASN1_TAG_BMPString = 30, // 0x24, 2-byte unicode with zeros + ASN1_TAG_SEQUENCE = 0x30, + ASN1_TAG_SET = 0x31, + ASN1_TAG_EXPLICIT = 0xa0, +}; + +const char *asn1_tag_name(int tag); +int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen); +int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen); +int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen); +int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen); // 尝试读取下一个tag,但是并不修改in,inlen +int asn1_tag_is_cstring(int tag); +int asn1_length_to_der(size_t dlen, uint8_t **out, size_t *outlen); +int asn1_length_from_der(size_t *dlen, const uint8_t **in, size_t *inlen); +int asn1_length_is_zero(size_t len); +int asn1_length_le(size_t len1, size_t len2); // less than +int asn1_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_data_from_der(const uint8_t **d, size_t dlen, const uint8_t **in, size_t *inlen); + +int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int asn1_any_type_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int asn1_any_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); // 调用方应保证a,alen为TLV +int asn1_any_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); // 该函数会检查输入是否为TLV + +const char *asn1_boolean_name(int val); +int asn1_boolean_from_name(int *val, const char *name); +int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); +int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); +#define asn1_boolean_to_der(val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_BOOLEAN,val,out,outlen) +#define asn1_boolean_from_der(val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_BOOLEAN,val,in,inlen) +#define asn1_implicit_boolean_to_der(i,val,out,outlen) asn1_boolean_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_boolean_from_der(i,val,in,inlen) asn1_boolean_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) + +// asn1_integer_ 不支持负数编解码 +int asn1_integer_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_integer_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_integer_to_der(d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_INTEGER,d,dlen,out,outlen) +#define asn1_integer_from_der(d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_INTEGER,d,dlen,in,inlen) +#define asn1_implicit_integer_to_der(i,d,dlen,out,outlen) asn1_integer_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_integer_from_der(i,d,dlen,in,inlen) asn1_integer_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +// asn1_int_ 只支持小的无符号整数的编解码,不支持负数 +int asn1_int_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen); // 当 val == -1 时,不输出,返回 0 +int asn1_int_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen); // 不支持负数,返回0时 *val 设置为 -1 +#define asn1_int_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_INTEGER,val,out,outlen) +#define asn1_int_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_INTEGER,val,in,inlen) +#define asn1_implicit_int_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_int_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) + +// 比特长度不必须为8的整数倍 +int asn1_bit_string_to_der_ex(int tag, const uint8_t *d, size_t nbits, uint8_t **out, size_t *outlen); +int asn1_bit_string_from_der_ex(int tag, const uint8_t **d, size_t *nbits, const uint8_t **in, size_t *inlen); +#define asn1_bit_string_to_der(d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_BIT_STRING,d,nbits,out,outlen) +#define asn1_bit_string_from_der(d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_BIT_STRING,d,nbits,in,inlen) +#define asn1_implicit_bit_string_to_der(i,d,nbits,out,outlen) asn1_bit_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,out,outlen) +#define asn1_implicit_bit_string_from_der(i,d,nbits,in,inlen) asn1_bit_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,nbits,in,inlen) + +// 比特长度必须为8的整数倍,因此使用字节长度 +int asn1_bit_octets_to_der_ex(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_bit_octets_from_der_ex(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_bit_octets_to_der(d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_BIT_STRING,d,dlen,out,outlen) +#define asn1_bit_octets_from_der(d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_BIT_STRING,d,dlen,in,inlen) +#define asn1_implicit_bit_octets_to_der(i,d,dlen,out,outlen) asn1_bit_octets_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_bit_octets_from_der(i,d,dlen,in,inlen) asn1_bit_octets_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +// bits == -1 不编码,只支持较少的比特数量 +int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen); +int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen); +#define asn1_bits_to_der(bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_BIT_STRING,bits,out,outlen) +#define asn1_bits_from_der(bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_BIT_STRING,bits,in,inlen) +#define asn1_implicit_bits_to_der(i,bits,out,outlen) asn1_bits_to_der_ex(ASN1_TAG_IMPLICIT(i),bits,out,outlen) +#define asn1_implicit_bits_from_der(i,bits,in,inlen) asn1_bits_from_der_ex(ASN1_TAG_IMPLICIT(i),bits,in,inlen) +// names[i]对应第i个比特 +int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits); + +#define asn1_octet_string_to_der_ex(tag,d,dlen,out,outlen) asn1_type_to_der(tag,d,dlen,out,outlen) +#define asn1_octet_string_from_der_ex(tag,d,dlen,in,inlen) asn1_type_from_der(tag,d,dlen,in,inlen) +#define asn1_octet_string_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_OCTET_STRING,d,dlen,out,outlen) +#define asn1_octet_string_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_OCTET_STRING,d,dlen,in,inlen) +#define asn1_implicit_octet_string_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_octet_string_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +const char *asn1_null_name(void); +int asn1_null_to_der(uint8_t **out, size_t *outlen); +int asn1_null_from_der(const uint8_t **in, size_t *inlen); + +#define ASN1_OID_MAX_NODES 32 +int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen); +int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen); + +int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt); +int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen); +int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen); +#define asn1_object_identifier_to_der(nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,out,outlen) +#define asn1_object_identifier_from_der(nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_OBJECT_IDENTIFIER,nodes,nodes_cnt,in,inlen) +#define asn1_implicit_object_identifier_to_der(i,nodes,nodes_cnt,out,outlen) asn1_object_identifier_to_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,out,outlen) +#define asn1_implicit_object_identifier_from_der(i,nodes,nodes_cnt,in,inlen) asn1_object_identifier_from_der_ex(ASN1_TAG_IMPLICIT(i),nodes,nodes_cnt,in,inlen) +int asn1_object_identifier_print(FILE *fp, int fmt, int ind, const char *label, const char *name, + const uint32_t *nodes, size_t nodes_cnt); + +#define asn1_enumerated_to_der_ex(tag,val,out,outlen) asn1_int_to_der_ex(tag,val,out,outlen) +#define asn1_enumerated_from_der_ex(tag,val,in,inlen) asn1_int_from_der_ex(tag,val,in,inlen) +#define asn1_enumerated_to_der(val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_ENUMERATED,val,out,outlen) +#define asn1_enumerated_from_der(val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_ENUMERATED,val,in,inlen) +#define asn1_implicit_enumerated_to_der(i,val,out,outlen) asn1_int_to_der_ex(ASN1_TAG_IMPLICIT(i),val,out,outlen) +#define asn1_implicit_enumerated_from_der(i,val,in,inlen) asn1_int_from_der_ex(ASN1_TAG_IMPLICIT(i),val,in,inlen) + +int asn1_utf8_string_check(const char *d, size_t dlen); +int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_utf8_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_utf8_string_to_der(d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_UTF8String,d,dlen,out,outlen) +#define asn1_utf8_string_from_der(d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_UTF8String,d,dlen,in,inlen) +#define asn1_implicit_utf8_string_to_der(i,d,dlen,out,outlen) asn1_utf8_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_utf8_string_from_der(i,d,dlen,in,inlen) asn1_utf8_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +int asn1_printable_string_check(const char *d, size_t dlen); +int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_printable_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_printable_string_to_der(d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_PrintableString,d,dlen,out,outlen) +#define asn1_printable_string_from_der(d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_PrintableString,d,dlen,in,inlen) +#define asn1_implicit_printable_string_to_der(i,d,dlen,out,outlen) asn1_printable_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_printable_string_from_der(i,d,dlen,in,inlen) asn1_printable_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +int asn1_ia5_string_check(const char *d, size_t dlen); +int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen); +int asn1_ia5_string_from_der_ex(int tag, const char **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define asn1_ia5_string_to_der(d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IA5String,d,dlen,out,outlen) +#define asn1_ia5_string_from_der(d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IA5String,d,dlen,in,inlen) +#define asn1_implicit_ia5_string_to_der(i,d,dlen,out,outlen) asn1_ia5_string_to_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_ia5_string_from_der(i,d,dlen,in,inlen) asn1_ia5_string_from_der_ex(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + +#define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1) +#define ASN1_GENERALIZED_TIME_LEN (sizeof("YYYYMMDDHHMMSSZ")-1) + +int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); +int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); +#define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen) +#define asn1_utc_time_from_der(tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_UTCTime,tv,in,inlen) +#define asn1_implicit_utc_time_to_der(i,tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen) +#define asn1_implicit_utc_time_from_der(i,tv,in,inlen) asn1_utc_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen) + +int asn1_generalized_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); +int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); +#define asn1_generalized_time_to_der(tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_GeneralizedTime,tv,out,outlen) +#define asn1_generalized_time_from_der(tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_GeneralizedTime,tv,in,inlen) +#define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen) +#define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen) + +#define asn1_sequence_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen) +#define asn1_sequence_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen) +#define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) + +#define asn1_set_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SET,d,dlen,out,outlen) +#define asn1_set_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SET,d,dlen,in,inlen) +#define asn1_implicit_set_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_set_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) + +#define asn1_implicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_IMPLICIT(i),d,dlen,out,outlen) +#define asn1_implicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_IMPLICIT(i),d,dlen,in,inlen) + +int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen); +#define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) + +#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen) + +#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen) +#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) + +#define asn1_set_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SET,dlen,out,outlen) +#define asn1_implicit_set_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) + +#define asn1_explicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen) + +#define asn1_explicit_to_der(i,d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen) +#define asn1_explicit_from_der(i,d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen) + +// d,dlen 是 SEQUENCE OF, SET OF 中的值 +int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt); +int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag, + int index, const uint8_t **item_d, size_t *item_dlen); + +int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen); +int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen); +int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +typedef struct { + int oid; + char *name; + uint32_t *nodes; + size_t nodes_cnt; + int flags; + char *description; +} ASN1_OID_INFO; + +const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name); +const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid); +int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt, + const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen); +int asn1_oid_info_from_der(const ASN1_OID_INFO **info, + const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen); + + +int asn1_check(int expr); + + +#if __cplusplus +} +#endif +#endif diff --git a/include/gmssl/base64.h b/include/gmssl/base64.h index f9a369db..cb7f6b83 100644 --- a/include/gmssl/base64.h +++ b/include/gmssl/base64.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,66 +7,67 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_BASE64_H -#define GMSSL_BASE64_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -BASE64 Public API - - BASE64_CTX - base64_encode_init - base64_encode_update - base64_encode_finish - base64_decode_init - base64_decode_update - base64_decode_finish - -*/ - - -typedef struct { - /* number saved in a partial encode/decode */ - int num; - /* - * The length is either the output line length (in input bytes) or the - * shortest input line length that is ok. Once decoding begins, the - * length is adjusted up each time a longer line is decoded - */ - int length; - /* data to encode */ - unsigned char enc_data[80]; - /* number read on current line */ - int line_num; - int expect_nl; -} BASE64_CTX; - -# define BASE64_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) -# define BASE64_DECODE_LENGTH(l) ((l+3)/4*3+80) - - -void base64_encode_init(BASE64_CTX *ctx); -int base64_encode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen); -void base64_encode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen); - -void base64_decode_init(BASE64_CTX *ctx); -int base64_decode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen); -int base64_decode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen); - - -int base64_encode_block(unsigned char *t, const unsigned char *f, int dlen); -int base64_decode_block(unsigned char *t, const unsigned char *f, int n); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_BASE64_H +#define GMSSL_BASE64_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +BASE64 Public API + + BASE64_CTX + base64_encode_init + base64_encode_update + base64_encode_finish + base64_decode_init + base64_decode_update + base64_decode_finish + +*/ + + +typedef struct { + /* number saved in a partial encode/decode */ + int num; + /* + * The length is either the output line length (in input bytes) or the + * shortest input line length that is ok. Once decoding begins, the + * length is adjusted up each time a longer line is decoded + */ + int length; + /* data to encode */ + unsigned char enc_data[80]; + /* number read on current line */ + int line_num; + int expect_nl; +} BASE64_CTX; + +# define BASE64_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +# define BASE64_DECODE_LENGTH(l) ((l+3)/4*3+80) + + +void base64_encode_init(BASE64_CTX *ctx); +int base64_encode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen); +void base64_encode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen); + +void base64_decode_init(BASE64_CTX *ctx); +int base64_decode_update(BASE64_CTX *ctx, const uint8_t *in, int inlen, uint8_t *out, int *outlen); +int base64_decode_finish(BASE64_CTX *ctx, uint8_t *out, int *outlen); + + +int base64_encode_block(unsigned char *t, const unsigned char *f, int dlen); +int base64_decode_block(unsigned char *t, const unsigned char *f, int n); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/block_cipher.h b/include/gmssl/block_cipher.h index c98dfefa..4341549b 100644 --- a/include/gmssl/block_cipher.h +++ b/include/gmssl/block_cipher.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,68 +7,69 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - - -#ifndef GMSSL_BLOCK_CIPHER_H -#define GMSSL_BLOCK_CIPHER_H - - -#include -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define BLOCK_CIPHER_BLOCK_SIZE 16 -#define BLOCK_CIPHER_MIN_KEY_SIZE 16 -#define BLOCK_CIPHER_MAX_KEY_SIZE 32 - - -typedef struct BLOCK_CIPHER BLOCK_CIPHER; -typedef struct BLOCK_CIPHER_KEY BLOCK_CIPHER_KEY; - -struct BLOCK_CIPHER_KEY { - union { - SM4_KEY sm4_key; - AES_KEY aes_key; - } u; - const BLOCK_CIPHER *cipher; -}; - -typedef void (*block_cipher_set_encrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key); -typedef void (*block_cipher_set_decrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key); -typedef void (*block_cipher_encrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); -typedef void (*block_cipher_decrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); - -struct BLOCK_CIPHER { - int oid; - size_t key_size; - size_t block_size; - block_cipher_set_encrypt_key_func set_encrypt_key; - block_cipher_set_decrypt_key_func set_decrypt_key; - block_cipher_encrypt_func encrypt; - block_cipher_decrypt_func decrypt; -}; - -const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void); -const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void); - -const BLOCK_CIPHER *block_cipher_from_name(const char *name); -const char *block_cipher_name(const BLOCK_CIPHER *cipher); -int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); -int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); -int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); -int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + + + +#ifndef GMSSL_BLOCK_CIPHER_H +#define GMSSL_BLOCK_CIPHER_H + + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define BLOCK_CIPHER_BLOCK_SIZE 16 +#define BLOCK_CIPHER_MIN_KEY_SIZE 16 +#define BLOCK_CIPHER_MAX_KEY_SIZE 32 + + +typedef struct BLOCK_CIPHER BLOCK_CIPHER; +typedef struct BLOCK_CIPHER_KEY BLOCK_CIPHER_KEY; + +struct BLOCK_CIPHER_KEY { + union { + SM4_KEY sm4_key; + AES_KEY aes_key; + } u; + const BLOCK_CIPHER *cipher; +}; + +typedef void (*block_cipher_set_encrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key); +typedef void (*block_cipher_set_decrypt_key_func)(BLOCK_CIPHER_KEY *key, const uint8_t *raw_key); +typedef void (*block_cipher_encrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); +typedef void (*block_cipher_decrypt_func)(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); + +struct BLOCK_CIPHER { + int oid; + size_t key_size; + size_t block_size; + block_cipher_set_encrypt_key_func set_encrypt_key; + block_cipher_set_decrypt_key_func set_decrypt_key; + block_cipher_encrypt_func encrypt; + block_cipher_decrypt_func decrypt; +}; + +const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void); +const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void); + +const BLOCK_CIPHER *block_cipher_from_name(const char *name); +const char *block_cipher_name(const BLOCK_CIPHER *cipher); +int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); +int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); +int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); +int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/chacha20.h b/include/gmssl/chacha20.h index 9a92dd51..136c570d 100644 --- a/include/gmssl/chacha20.h +++ b/include/gmssl/chacha20.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,51 +7,52 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* RFC 8439 "ChaCha20 and Poly1305 for IETF Protocols" */ - -#ifndef GMSSL_CHACHA20_H -#define GMSSL_CHACHA20_H - -#define CHACHA20_IS_BIG_ENDIAN 0 - -#include -#include - -#include - -#define CHACHA20_KEY_BITS 256 -#define CHACHA20_NONCE_BITS 96 -#define CHACHA20_COUNTER_BITS 32 - -#define CHACHA20_KEY_SIZE (CHACHA20_KEY_BITS/8) -#define CHACHA20_NONCE_SIZE (CHACHA20_NONCE_BITS/8) -#define CHACHA20_COUNTER_SIZE (CHACHA20_COUNTER_BITS/8) - -#define CHACHA20_KEY_WORDS (CHACHA20_KEY_SIZE/sizeof(uint32_t)) -#define CHACHA20_NONCE_WORDS (CHACHA20_NONCE_SIZE/sizeof(uint32_t)) -#define CHACHA20_COUNTER_WORDS (CHACHA20_COUNTER_SIZE/sizeof(uint32_t)) - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct { - uint32_t d[16]; -} CHACHA20_STATE; - - -void chacha20_init(CHACHA20_STATE *state, - const uint8_t key[CHACHA20_KEY_SIZE], - const uint8_t nonce[CHACHA20_NONCE_SIZE], uint32_t counter); - -void chacha20_generate_keystream(CHACHA20_STATE *state, - size_t counts, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + +/* RFC 8439 "ChaCha20 and Poly1305 for IETF Protocols" */ + +#ifndef GMSSL_CHACHA20_H +#define GMSSL_CHACHA20_H + +#define CHACHA20_IS_BIG_ENDIAN 0 + +#include +#include + +#include + +#define CHACHA20_KEY_BITS 256 +#define CHACHA20_NONCE_BITS 96 +#define CHACHA20_COUNTER_BITS 32 + +#define CHACHA20_KEY_SIZE (CHACHA20_KEY_BITS/8) +#define CHACHA20_NONCE_SIZE (CHACHA20_NONCE_BITS/8) +#define CHACHA20_COUNTER_SIZE (CHACHA20_COUNTER_BITS/8) + +#define CHACHA20_KEY_WORDS (CHACHA20_KEY_SIZE/sizeof(uint32_t)) +#define CHACHA20_NONCE_WORDS (CHACHA20_NONCE_SIZE/sizeof(uint32_t)) +#define CHACHA20_COUNTER_WORDS (CHACHA20_COUNTER_SIZE/sizeof(uint32_t)) + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint32_t d[16]; +} CHACHA20_STATE; + + +void chacha20_init(CHACHA20_STATE *state, + const uint8_t key[CHACHA20_KEY_SIZE], + const uint8_t nonce[CHACHA20_NONCE_SIZE], uint32_t counter); + +void chacha20_generate_keystream(CHACHA20_STATE *state, + size_t counts, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/cms.h b/include/gmssl/cms.h index 34d0924a..b49c28f4 100644 --- a/include/gmssl/cms.h +++ b/include/gmssl/cms.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,546 +7,547 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* -References: - 1. GM/T 0010-2012 SM2 Cryptography Message Syntax Specification - 2. RFC 2315 PKCS #7 Cryptographic Message Syntax Version 1.5 - 3. RFC 5652 Cryptographic Message Syntax (CMS) -*/ - -#ifndef GMSSL_CMS_H -#define GMSSL_CMS_H - - -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - CMS_version_v1 = 1, -}; - - -/* -ContentType: - OID_cms_data - OID_cms_signed_data - OID_cms_enveloped_data - OID_cms_signed_and_enveloped_data - OID_cms_encrypted_data - OID_cms_key_agreement_info -*/ -const char *cms_content_type_name(int oid); -int cms_content_type_from_name(const char *name); -int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen); -int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen); - -/* -ContentInfo ::= SEQUENCE { - contentType OBJECT IDENTIFIER, - content [0] EXPLICIT ANY OPTIONAL } -*/ -int cms_content_info_header_to_der( - int content_type, size_t content_len, - uint8_t **out, size_t *outlen); -int cms_content_info_to_der( - int content_type, - const uint8_t *content, size_t content_len, - uint8_t **out, size_t *outlen); -int cms_content_info_from_der( - int *content_type, - const uint8_t **content, size_t *content_len, // 这里获得的是完整的TLV - const uint8_t **in, size_t *inlen); -int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -Data ::= OCTET STRING -*/ -#define cms_data_to_der(d,dlen,out,outlen) asn1_octet_string_to_der(d,dlen,out,outlen) -#define cms_data_from_der(d,dlen,in,inlen) asn1_octet_string_from_der(d,dlen,in,inlen) -#define cms_data_print(fp,fmt,ind,label,d,dlen) format_bytes(fp,fmt,ind,label,d,dlen) - -/* -EncryptedContentInfo ::= SEQUENCE { - contentType OBJECT IDENTIFIER, - contentEncryptionAlgorithm AlgorithmIdentifier, - encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL, - sharedInfo1 [1] IMPLICIT OCTET STRING OPTIONAL, - sharedInfo2 [2] IMPLICIT OCTET STRING OPTIONAL } -*/ -int cms_enced_content_info_to_der( - int content_type, - int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_enced_content_info_from_der( - int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); -int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_enced_content_info_encrypt_to_der( - int enc_algor, - const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_enced_content_info_decrypt_from_der( - int *enc_algor, - const uint8_t *key, size_t keylen, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - -/* -EncryptedData ::= SEQUENCE { - version INTEGER (1), - encryptedContentInfo EncryptedContentInfo } -*/ -int cms_encrypted_data_to_der( - int version, - int content_type, - int enc_algor, const uint8_t *iv, size_t ivlen, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_encrypted_data_from_der( - int *version, - int *content_type, - int *enc_algor, const uint8_t **iv, size_t *ivlen, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); -int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_encrypted_data_encrypt_to_der( - int enc_algor, - const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_encrypted_data_decrypt_from_der( - int *enc_algor, - const uint8_t *key, size_t keylen, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - -/* -IssuerAndSerialNumber ::= SEQUENCE { - isser Name, - serialNumber INTEGER } -*/ -int cms_issuer_and_serial_number_to_der( - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - uint8_t **out, size_t *outlen); -int cms_issuer_and_serial_number_from_der( - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - const uint8_t **in, size_t *inlen); -int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -SignerInfo ::= SEQUENCE { - version INTEGER (1), - issuerAndSerialNumber IssuerAndSerialNumber, - digestAlgorithm AlgorithmIdentifier, - authenticatedAttributes [0] IMPLICIT SET OF Attribute OPTINOAL, - digestEncryptionAlgorithm AlgorithmIdentifier, - encryptedDigest OCTET STRING, - unauthenticatedAttributes [1] IMPLICIT SET OF Attribute OPTINOAL, } -*/ -int cms_signer_info_to_der( - int version, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - int digest_algor, - const uint8_t *authed_attrs, size_t authed_attrs_len, - int signature_algor, - const uint8_t *enced_digest, size_t enced_digest_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen); -int cms_signer_info_from_der( - int *version, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - int *digest_algor, - const uint8_t **authed_attrs, size_t *authed_attrs_len, - int *signature_algor, - const uint8_t **enced_digest, size_t *enced_digest_len, - const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, - const uint8_t **in, size_t *inlen); -int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_signer_info_sign_to_der( - const SM3_CTX *sm3_ctx, const SM2_KEY *sm2_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen); -int cms_signer_info_verify_from_der( - const SM3_CTX *sm3_ctx, const uint8_t *certs, size_t certslen, - const uint8_t **cert, size_t *certlen, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial, size_t *serial_len, - const uint8_t **authed_attrs, size_t *authed_attrs_len, - const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, - const uint8_t **in, size_t *inlen); -/* -SignerInfos ::= SET OF SignerInfo; -*/ -int cms_signer_infos_add_signer_info( - uint8_t *d, size_t *dlen, size_t maxlen, - const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len); -#define cms_signer_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) -#define cms_signer_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) -int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_digest_algors_to_der(const int *digest_algors, size_t digest_algors_cnt, uint8_t **out, size_t *outlen); -int cms_digest_algors_from_der(int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - const uint8_t **in, size_t *inlen); -int cms_digest_algors_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -SignedData ::= SEQUENCE { - version INTEGER (1), - digestAlgorithms SET OF AlgorithmIdentifier, - contentInfo ContentInfo, - certificates [0] IMPLICIT SET OF Certificate OPTIONAL, - crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, - signerInfos SET OF SignerInfo } -*/ -int cms_signed_data_to_der( - int version, - const int *digest_algors, size_t digest_algors_cnt, - const int content_type, const uint8_t *content, const size_t content_len, - const uint8_t *certs, size_t certs_len, - const uint8_t *crls, const size_t crls_len, - const uint8_t *signer_infos, size_t signer_infos_len, - uint8_t **out, size_t *outlen); -int cms_signed_data_from_der( - int *version, - int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen); -int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -typedef struct { - uint8_t *certs; - size_t certs_len; - SM2_KEY *sign_key; -} CMS_CERTS_AND_KEY; - -int cms_signed_data_sign_to_der( - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - int content_type, const uint8_t *data, size_t datalen, // 当OID_cms_data时为raw data - const uint8_t *crls, size_t crls_len, // 可以为空 - uint8_t **out, size_t *outlen); -int cms_signed_data_verify_from_der( - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - int *content_type, const uint8_t **content, size_t *content_len, // 是否应该返回raw data呢? - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen); - - -/* -RecipientInfo ::= SEQUENCE { - version INTEGER (1), - issuerAndSerialNumber IssuerAndSerialNumber, - keyEncryptionAlgorithm AlgorithmIdentifier, - encryptedKey OCTET STRING -- DER-encoding of SM2Cipher -} -由于encryptedKey的类型为SM2Cipher, 而SM2Cipher中有2个INTEGER,因此长度是不固定的。 -因此不能预先确定输出长度 -*/ -int cms_recipient_info_to_der( - int version, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - int public_key_enc_algor, - const uint8_t *enced_key, size_t enced_key_len, - uint8_t **out, size_t *outlen); -int cms_recipient_info_from_der( - int *version, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - int *pke_algor, const uint8_t **params, size_t *params_len,// SM2加密只使用SM3,没有默认参数,但是ECIES可能有 - const uint8_t **enced_key, size_t *enced_key_len, - const uint8_t **in, size_t *inlen); -int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -int cms_recipient_info_encrypt_to_der( - const SM2_KEY *public_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - const uint8_t *in, size_t inlen, - uint8_t **out, size_t *outlen); -int cms_recipient_info_decrypt_from_der( - const SM2_KEY *sm2_key, - const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, - const uint8_t *rcpt_serial, size_t rcpt_serial_len, - uint8_t *out, size_t *outlen, size_t maxlen, - const uint8_t **in, size_t *inlen); - -int cms_recipient_infos_add_recipient_info( - uint8_t *d, size_t *dlen, size_t maxlen, - const SM2_KEY *public_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - const uint8_t *in, size_t inlen); -#define cms_recipient_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) -#define cms_recipient_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) -int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -EnvelopedData ::= SEQUENCE { - version Version, - recipientInfos SET OF RecipientInfo, - encryptedContentInfo EncryptedContentInfo } -*/ -int cms_enveloped_data_to_der( - int version, - const uint8_t *rcpt_infos, size_t rcpt_infos_len, - int content_type, - int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_enveloped_data_from_der( - int *version, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **enced_content_info, size_t *enced_content_info_len, - const uint8_t **in, size_t *inlen); -int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_enveloped_data_encrypt_to_der( - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_enveloped_data_decrypt_from_der( - const SM2_KEY *sm2_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen); - -/* -SignedAndEnvelopedData ::= SEQUENCE { - version INTEGER (1), - recipientInfos SET OF RecipientInfo, - digestAlgorithms SET OF AlgorithmIdentifier, - encryptedContentInfo EncryptedContentInfo, - certificates [0] IMPLICIT SET OF Certificate OPTIONAL, - crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, - signerInfos SET OF SignerInfo } -*/ -int cms_signed_and_enveloped_data_to_der( - int version, - const uint8_t *rcpt_infos, size_t rcpt_infos_len, - const int *digest_algors, size_t digest_algors_cnt, - int content_type, - int enc_algor, const uint8_t *iv, size_t ivlen, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - const uint8_t *certs, size_t certs_len, - const uint8_t *crls, size_t crls_len, - const uint8_t *signer_infos, size_t signer_infos_len, - uint8_t **out, size_t *outlen); -int cms_signed_and_enveloped_data_from_der( - int *version, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - const uint8_t **enced_content_info, size_t *enced_content_info_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen); -int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int cms_signed_and_enveloped_data_encipher_to_der( - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *signers_crls, size_t signers_crls_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen); -int cms_signed_and_enveloped_data_decipher_from_der( - const SM2_KEY *rcpt_key, - const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, - const uint8_t *rcpt_serial, size_t rcpt_serial_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **prcpt_infos, size_t *prcpt_infos_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **psigner_infos, size_t *psigner_infos_len, - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - const uint8_t **in, size_t *inlen); - -/* -KeyAgreementInfo ::= SEQUENCE { - version INTEGER (1), - tempPublicKeyR SM2PublicKey, - userCertificate Certificate, - userID OCTET STRING } -*/ -int cms_key_agreement_info_to_der( - int version, - const SM2_KEY *temp_public_key_r, - const uint8_t *user_cert, size_t user_cert_len, - const uint8_t *user_id, size_t user_id_len, - uint8_t **out, size_t *outlen); -int cms_key_agreement_info_from_der( - int *version, - SM2_KEY *temp_public_key_r, - const uint8_t **user_cert, size_t *user_cert_len, - const uint8_t **user_id, size_t *user_id_len, - const uint8_t **in, size_t *inlen); -int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - - -// 下面是公开API -// 公开API的设计考虑: -// 1. 不需要调用其他函数 -// 2. 在逻辑上容易理解 -// 3. 将cms,cmslen看做对象 - - -// 生成ContentInfo, type == data -int cms_set_data(uint8_t *cms, size_t *cmslen, - const uint8_t *d, size_t dlen); - -int cms_encrypt( - uint8_t *cms, size_t *cmslen, // 输出的ContentInfo (type encryptedData) - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法、密钥和IV - int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 - const uint8_t *shared_info1, size_t shared_info1_len, // 附加信息 - const uint8_t *shared_info2, size_t shared_info2_len); - -int cms_decrypt( - const uint8_t *cms, size_t cmslen, // 输入的ContentInfo (type encryptedData) - int *enc_algor, const uint8_t *key, size_t keylen, // 解密密钥(我们不知道解密算法) - int *content_type, uint8_t *content, size_t *content_len, // 输出的解密数据类型及数据 - const uint8_t **shared_info1, size_t *shared_info1_len, // 附加信息 - const uint8_t **shared_info2, size_t *shared_info2_len); - -int cms_sign( - uint8_t *cms, size_t *cms_len, - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, // 签名者的签名私钥和证书 - int content_type, const uint8_t *content, size_t content_len, // 待签名的输入数据 - const uint8_t *crls, size_t crls_len); - -int cms_verify( - const uint8_t *cms, size_t cms_len, - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len); - -int cms_envelop( - uint8_t *cms, size_t *cms_len, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, // 接收方证书,注意这个参数的类型可以容纳多个证书,但是只有在一个接受者时对调用方最方便 - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法及参数 - int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 - const uint8_t *shared_info1, size_t shared_info1_len, // 附加输入信息 - const uint8_t *shared_info2, size_t shared_info2_len); - -int cms_deenvelop( - const uint8_t *cms, size_t cms_len, - const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, // 接收方的解密私钥和对应的证书,注意只需要一个解密方 - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, // 解析得到,用于显示 - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len); - -int cms_sign_and_envelop( - uint8_t *cms, size_t *cms_len, - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *signers_crls, size_t signers_crls_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len); - -int cms_deenvelop_and_verify( - const uint8_t *cms, size_t cms_len, - const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, - const uint8_t *extra_signer_certs, size_t extra_signer_certs_len, - const uint8_t *extra_signer_crls, size_t extra_signer_crls_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **signer_certs, size_t *signer_certs_len, - const uint8_t **signer_crls, size_t *signer_crls_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len); - -// 生成ContentInfo, type == keyAgreementInfo -int cms_set_key_agreement_info( - uint8_t *cms, size_t *cms_len, - const SM2_KEY *temp_public_key_r, - const uint8_t *user_cert, size_t user_cert_len, - const uint8_t *user_id, size_t user_id_len); - -#define PEM_CMS "CMS" -int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp); -int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp); - - -int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); - - -#ifdef __cplusplus -} -#endif -#endif + + +/* +References: + 1. GM/T 0010-2012 SM2 Cryptography Message Syntax Specification + 2. RFC 2315 PKCS #7 Cryptographic Message Syntax Version 1.5 + 3. RFC 5652 Cryptographic Message Syntax (CMS) +*/ + +#ifndef GMSSL_CMS_H +#define GMSSL_CMS_H + + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + CMS_version_v1 = 1, +}; + + +/* +ContentType: + OID_cms_data + OID_cms_signed_data + OID_cms_enveloped_data + OID_cms_signed_and_enveloped_data + OID_cms_encrypted_data + OID_cms_key_agreement_info +*/ +const char *cms_content_type_name(int oid); +int cms_content_type_from_name(const char *name); +int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen); +int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen); + +/* +ContentInfo ::= SEQUENCE { + contentType OBJECT IDENTIFIER, + content [0] EXPLICIT ANY OPTIONAL } +*/ +int cms_content_info_header_to_der( + int content_type, size_t content_len, + uint8_t **out, size_t *outlen); +int cms_content_info_to_der( + int content_type, + const uint8_t *content, size_t content_len, + uint8_t **out, size_t *outlen); +int cms_content_info_from_der( + int *content_type, + const uint8_t **content, size_t *content_len, // 这里获得的是完整的TLV + const uint8_t **in, size_t *inlen); +int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +Data ::= OCTET STRING +*/ +#define cms_data_to_der(d,dlen,out,outlen) asn1_octet_string_to_der(d,dlen,out,outlen) +#define cms_data_from_der(d,dlen,in,inlen) asn1_octet_string_from_der(d,dlen,in,inlen) +#define cms_data_print(fp,fmt,ind,label,d,dlen) format_bytes(fp,fmt,ind,label,d,dlen) + +/* +EncryptedContentInfo ::= SEQUENCE { + contentType OBJECT IDENTIFIER, + contentEncryptionAlgorithm AlgorithmIdentifier, + encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL, + sharedInfo1 [1] IMPLICIT OCTET STRING OPTIONAL, + sharedInfo2 [2] IMPLICIT OCTET STRING OPTIONAL } +*/ +int cms_enced_content_info_to_der( + int content_type, + int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_enced_content_info_from_der( + int *content_type, + int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); +int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_enced_content_info_encrypt_to_der( + int enc_algor, + const uint8_t *key, size_t keylen, + const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_enced_content_info_decrypt_from_der( + int *enc_algor, + const uint8_t *key, size_t keylen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); + +/* +EncryptedData ::= SEQUENCE { + version INTEGER (1), + encryptedContentInfo EncryptedContentInfo } +*/ +int cms_encrypted_data_to_der( + int version, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_encrypted_data_from_der( + int *version, + int *content_type, + int *enc_algor, const uint8_t **iv, size_t *ivlen, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); +int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_encrypted_data_encrypt_to_der( + int enc_algor, + const uint8_t *key, size_t keylen, + const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_encrypted_data_decrypt_from_der( + int *enc_algor, + const uint8_t *key, size_t keylen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); + +/* +IssuerAndSerialNumber ::= SEQUENCE { + isser Name, + serialNumber INTEGER } +*/ +int cms_issuer_and_serial_number_to_der( + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + uint8_t **out, size_t *outlen); +int cms_issuer_and_serial_number_from_der( + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + const uint8_t **in, size_t *inlen); +int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SignerInfo ::= SEQUENCE { + version INTEGER (1), + issuerAndSerialNumber IssuerAndSerialNumber, + digestAlgorithm AlgorithmIdentifier, + authenticatedAttributes [0] IMPLICIT SET OF Attribute OPTINOAL, + digestEncryptionAlgorithm AlgorithmIdentifier, + encryptedDigest OCTET STRING, + unauthenticatedAttributes [1] IMPLICIT SET OF Attribute OPTINOAL, } +*/ +int cms_signer_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int digest_algor, + const uint8_t *authed_attrs, size_t authed_attrs_len, + int signature_algor, + const uint8_t *enced_digest, size_t enced_digest_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + uint8_t **out, size_t *outlen); +int cms_signer_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *digest_algor, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + int *signature_algor, + const uint8_t **enced_digest, size_t *enced_digest_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t **in, size_t *inlen); +int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_signer_info_sign_to_der( + const SM3_CTX *sm3_ctx, const SM2_KEY *sm2_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + uint8_t **out, size_t *outlen); +int cms_signer_info_verify_from_der( + const SM3_CTX *sm3_ctx, const uint8_t *certs, size_t certslen, + const uint8_t **cert, size_t *certlen, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial, size_t *serial_len, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t **in, size_t *inlen); +/* +SignerInfos ::= SET OF SignerInfo; +*/ +int cms_signer_infos_add_signer_info( + uint8_t *d, size_t *dlen, size_t maxlen, + const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len); +#define cms_signer_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) +#define cms_signer_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) +int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_digest_algors_to_der(const int *digest_algors, size_t digest_algors_cnt, uint8_t **out, size_t *outlen); +int cms_digest_algors_from_der(int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + const uint8_t **in, size_t *inlen); +int cms_digest_algors_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SignedData ::= SEQUENCE { + version INTEGER (1), + digestAlgorithms SET OF AlgorithmIdentifier, + contentInfo ContentInfo, + certificates [0] IMPLICIT SET OF Certificate OPTIONAL, + crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, + signerInfos SET OF SignerInfo } +*/ +int cms_signed_data_to_der( + int version, + const int *digest_algors, size_t digest_algors_cnt, + const int content_type, const uint8_t *content, const size_t content_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, const size_t crls_len, + const uint8_t *signer_infos, size_t signer_infos_len, + uint8_t **out, size_t *outlen); +int cms_signed_data_from_der( + int *version, + int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen); +int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +typedef struct { + uint8_t *certs; + size_t certs_len; + SM2_KEY *sign_key; +} CMS_CERTS_AND_KEY; + +int cms_signed_data_sign_to_der( + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + int content_type, const uint8_t *data, size_t datalen, // 当OID_cms_data时为raw data + const uint8_t *crls, size_t crls_len, // 可以为空 + uint8_t **out, size_t *outlen); +int cms_signed_data_verify_from_der( + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + int *content_type, const uint8_t **content, size_t *content_len, // 是否应该返回raw data呢? + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen); + + +/* +RecipientInfo ::= SEQUENCE { + version INTEGER (1), + issuerAndSerialNumber IssuerAndSerialNumber, + keyEncryptionAlgorithm AlgorithmIdentifier, + encryptedKey OCTET STRING -- DER-encoding of SM2Cipher +} +由于encryptedKey的类型为SM2Cipher, 而SM2Cipher中有2个INTEGER,因此长度是不固定的。 +因此不能预先确定输出长度 +*/ +int cms_recipient_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int public_key_enc_algor, + const uint8_t *enced_key, size_t enced_key_len, + uint8_t **out, size_t *outlen); +int cms_recipient_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *pke_algor, const uint8_t **params, size_t *params_len,// SM2加密只使用SM3,没有默认参数,但是ECIES可能有 + const uint8_t **enced_key, size_t *enced_key_len, + const uint8_t **in, size_t *inlen); +int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +int cms_recipient_info_encrypt_to_der( + const SM2_KEY *public_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + const uint8_t *in, size_t inlen, + uint8_t **out, size_t *outlen); +int cms_recipient_info_decrypt_from_der( + const SM2_KEY *sm2_key, + const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, + const uint8_t *rcpt_serial, size_t rcpt_serial_len, + uint8_t *out, size_t *outlen, size_t maxlen, + const uint8_t **in, size_t *inlen); + +int cms_recipient_infos_add_recipient_info( + uint8_t *d, size_t *dlen, size_t maxlen, + const SM2_KEY *public_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + const uint8_t *in, size_t inlen); +#define cms_recipient_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen) +#define cms_recipient_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen) +int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +EnvelopedData ::= SEQUENCE { + version Version, + recipientInfos SET OF RecipientInfo, + encryptedContentInfo EncryptedContentInfo } +*/ +int cms_enveloped_data_to_der( + int version, + const uint8_t *rcpt_infos, size_t rcpt_infos_len, + int content_type, + int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_enveloped_data_from_der( + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **enced_content_info, size_t *enced_content_info_len, + const uint8_t **in, size_t *inlen); +int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_enveloped_data_encrypt_to_der( + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_enveloped_data_decrypt_from_der( + const SM2_KEY *sm2_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen); + +/* +SignedAndEnvelopedData ::= SEQUENCE { + version INTEGER (1), + recipientInfos SET OF RecipientInfo, + digestAlgorithms SET OF AlgorithmIdentifier, + encryptedContentInfo EncryptedContentInfo, + certificates [0] IMPLICIT SET OF Certificate OPTIONAL, + crls [1] IMPLICIT SET OF CertificateRevocationList OPTIONAL, + signerInfos SET OF SignerInfo } +*/ +int cms_signed_and_enveloped_data_to_der( + int version, + const uint8_t *rcpt_infos, size_t rcpt_infos_len, + const int *digest_algors, size_t digest_algors_cnt, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, size_t crls_len, + const uint8_t *signer_infos, size_t signer_infos_len, + uint8_t **out, size_t *outlen); +int cms_signed_and_enveloped_data_from_der( + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + const uint8_t **enced_content_info, size_t *enced_content_info_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen); +int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int cms_signed_and_enveloped_data_encipher_to_der( + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *signers_crls, size_t signers_crls_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen); +int cms_signed_and_enveloped_data_decipher_from_der( + const SM2_KEY *rcpt_key, + const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, + const uint8_t *rcpt_serial, size_t rcpt_serial_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **prcpt_infos, size_t *prcpt_infos_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **psigner_infos, size_t *psigner_infos_len, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + const uint8_t **in, size_t *inlen); + +/* +KeyAgreementInfo ::= SEQUENCE { + version INTEGER (1), + tempPublicKeyR SM2PublicKey, + userCertificate Certificate, + userID OCTET STRING } +*/ +int cms_key_agreement_info_to_der( + int version, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len, + uint8_t **out, size_t *outlen); +int cms_key_agreement_info_from_der( + int *version, + SM2_KEY *temp_public_key_r, + const uint8_t **user_cert, size_t *user_cert_len, + const uint8_t **user_id, size_t *user_id_len, + const uint8_t **in, size_t *inlen); +int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + + +// 下面是公开API +// 公开API的设计考虑: +// 1. 不需要调用其他函数 +// 2. 在逻辑上容易理解 +// 3. 将cms,cmslen看做对象 + + +// 生成ContentInfo, type == data +int cms_set_data(uint8_t *cms, size_t *cmslen, + const uint8_t *d, size_t dlen); + +int cms_encrypt( + uint8_t *cms, size_t *cmslen, // 输出的ContentInfo (type encryptedData) + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法、密钥和IV + int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 + const uint8_t *shared_info1, size_t shared_info1_len, // 附加信息 + const uint8_t *shared_info2, size_t shared_info2_len); + +int cms_decrypt( + const uint8_t *cms, size_t cmslen, // 输入的ContentInfo (type encryptedData) + int *enc_algor, const uint8_t *key, size_t keylen, // 解密密钥(我们不知道解密算法) + int *content_type, uint8_t *content, size_t *content_len, // 输出的解密数据类型及数据 + const uint8_t **shared_info1, size_t *shared_info1_len, // 附加信息 + const uint8_t **shared_info2, size_t *shared_info2_len); + +int cms_sign( + uint8_t *cms, size_t *cms_len, + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, // 签名者的签名私钥和证书 + int content_type, const uint8_t *content, size_t content_len, // 待签名的输入数据 + const uint8_t *crls, size_t crls_len); + +int cms_verify( + const uint8_t *cms, size_t cms_len, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len); + +int cms_envelop( + uint8_t *cms, size_t *cms_len, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, // 接收方证书,注意这个参数的类型可以容纳多个证书,但是只有在一个接受者时对调用方最方便 + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, // 对称加密算法及参数 + int content_type, const uint8_t *content, size_t content_len, // 待加密的输入数据 + const uint8_t *shared_info1, size_t shared_info1_len, // 附加输入信息 + const uint8_t *shared_info2, size_t shared_info2_len); + +int cms_deenvelop( + const uint8_t *cms, size_t cms_len, + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, // 接收方的解密私钥和对应的证书,注意只需要一个解密方 + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, // 解析得到,用于显示 + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len); + +int cms_sign_and_envelop( + uint8_t *cms, size_t *cms_len, + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *signers_crls, size_t signers_crls_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len); + +int cms_deenvelop_and_verify( + const uint8_t *cms, size_t cms_len, + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, + const uint8_t *extra_signer_certs, size_t extra_signer_certs_len, + const uint8_t *extra_signer_crls, size_t extra_signer_crls_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **signer_certs, size_t *signer_certs_len, + const uint8_t **signer_crls, size_t *signer_crls_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len); + +// 生成ContentInfo, type == keyAgreementInfo +int cms_set_key_agreement_info( + uint8_t *cms, size_t *cms_len, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len); + +#define PEM_CMS "CMS" +int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp); +int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp); + + +int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/des.h b/include/gmssl/des.h index 4e6a8263..d8d20ed0 100644 --- a/include/gmssl/des.h +++ b/include/gmssl/des.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,52 +7,53 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* FIPS PUB 46-3 "Data Encryption Standard (DES)" */ - -#ifndef GMSSL_DES_H -#define GMSSL_DES_H - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define DES_KEY_BITS 56 -#define DES_BLOCK_BITS 64 -#define DES_KEY_SIZE ((DES_KEY_BITS)/7) -#define DES_BLOCK_SIZE (DES_BLOCK_BITS/8) - -#define DES_RK_BITS 48 -#define DES_RK_SIZE (DES_RK_BITS/8) -#define DES_ROUNDS 16 - -#define DES_EDE_KEY_SIZE (DES_KEY_SIZE * 3) - -typedef struct { - uint64_t rk[DES_ROUNDS]; -} DES_KEY; - -void des_set_encrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); -void des_set_decrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); -void des_encrypt(DES_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); - - -typedef struct { - DES_KEY K[3]; -} DES_EDE_KEY; - -void des_ede_set_encrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); -void des_ede_set_decrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); -void des_ede_encrypt(DES_EDE_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); - - -#ifdef __cplusplus -} -#endif -#endif + + +/* FIPS PUB 46-3 "Data Encryption Standard (DES)" */ + +#ifndef GMSSL_DES_H +#define GMSSL_DES_H + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define DES_KEY_BITS 56 +#define DES_BLOCK_BITS 64 +#define DES_KEY_SIZE ((DES_KEY_BITS)/7) +#define DES_BLOCK_SIZE (DES_BLOCK_BITS/8) + +#define DES_RK_BITS 48 +#define DES_RK_SIZE (DES_RK_BITS/8) +#define DES_ROUNDS 16 + +#define DES_EDE_KEY_SIZE (DES_KEY_SIZE * 3) + +typedef struct { + uint64_t rk[DES_ROUNDS]; +} DES_KEY; + +void des_set_encrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); +void des_set_decrypt_key(DES_KEY *key, const uint8_t raw_key[DES_KEY_SIZE]); +void des_encrypt(DES_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); + + +typedef struct { + DES_KEY K[3]; +} DES_EDE_KEY; + +void des_ede_set_encrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); +void des_ede_set_decrypt_key(DES_EDE_KEY *key, const uint8_t raw_key[DES_EDE_KEY_SIZE]); +void des_ede_encrypt(DES_EDE_KEY *key, const uint8_t in[DES_BLOCK_SIZE], uint8_t out[DES_BLOCK_SIZE]); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/digest.h b/include/gmssl/digest.h index 0cdf4d50..6ac086bc 100644 --- a/include/gmssl/digest.h +++ b/include/gmssl/digest.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,75 +7,76 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_DIGEST_H -#define GMSSL_DIGEST_H - - -#include -#include -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct DIGEST DIGEST; -typedef struct DIGEST_CTX DIGEST_CTX; - - -#define DIGEST_MAX_SIZE 64 -#define DIGEST_MAX_BLOCK_SIZE (1024/8) - - -struct DIGEST_CTX { - union { - SM3_CTX sm3_ctx; -// MD5_CTX md5_ctx; - SHA1_CTX sha1_ctx; - SHA224_CTX sha224_ctx; - SHA256_CTX sha256_ctx; - SHA384_CTX sha384_ctx; - SHA512_CTX sha512_ctx; - } u; - const DIGEST *digest; -}; - -struct DIGEST { - int oid; - size_t digest_size; - size_t block_size; - size_t ctx_size; - int (*init)(DIGEST_CTX *ctx); - int (*update)(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); - int (*finish)(DIGEST_CTX *ctx, uint8_t *dgst); -}; - -const DIGEST *DIGEST_sm3(void); -//const DIGEST *DIGEST_md5(void); -const DIGEST *DIGEST_sha1(void); -const DIGEST *DIGEST_sha224(void); -const DIGEST *DIGEST_sha256(void); -const DIGEST *DIGEST_sha384(void); -const DIGEST *DIGEST_sha512(void); -const DIGEST *DIGEST_sha512_224(void); -const DIGEST *DIGEST_sha512_256(void); - -const DIGEST *digest_from_name(const char *name); -const char *digest_name(const DIGEST *digest); -int digest_init(DIGEST_CTX *ctx, const DIGEST *algor); -int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); -int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen); -int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, uint8_t *dgst, size_t *dgstlen); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_DIGEST_H +#define GMSSL_DIGEST_H + + +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct DIGEST DIGEST; +typedef struct DIGEST_CTX DIGEST_CTX; + + +#define DIGEST_MAX_SIZE 64 +#define DIGEST_MAX_BLOCK_SIZE (1024/8) + + +struct DIGEST_CTX { + union { + SM3_CTX sm3_ctx; +// MD5_CTX md5_ctx; + SHA1_CTX sha1_ctx; + SHA224_CTX sha224_ctx; + SHA256_CTX sha256_ctx; + SHA384_CTX sha384_ctx; + SHA512_CTX sha512_ctx; + } u; + const DIGEST *digest; +}; + +struct DIGEST { + int oid; + size_t digest_size; + size_t block_size; + size_t ctx_size; + int (*init)(DIGEST_CTX *ctx); + int (*update)(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); + int (*finish)(DIGEST_CTX *ctx, uint8_t *dgst); +}; + +const DIGEST *DIGEST_sm3(void); +//const DIGEST *DIGEST_md5(void); +const DIGEST *DIGEST_sha1(void); +const DIGEST *DIGEST_sha224(void); +const DIGEST *DIGEST_sha256(void); +const DIGEST *DIGEST_sha384(void); +const DIGEST *DIGEST_sha512(void); +const DIGEST *DIGEST_sha512_224(void); +const DIGEST *DIGEST_sha512_256(void); + +const DIGEST *digest_from_name(const char *name); +const char *digest_name(const DIGEST *digest); +int digest_init(DIGEST_CTX *ctx, const DIGEST *algor); +int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen); +int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen); +int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, uint8_t *dgst, size_t *dgstlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/ec.h b/include/gmssl/ec.h index c11ff4fe..eec93c9c 100644 --- a/include/gmssl/ec.h +++ b/include/gmssl/ec.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,58 +7,59 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_EC_H -#define GMSSL_EC_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -NamedCurve: - OID_sm2 - OID_prime192v1 - OID_prime256v1 - OID_secp256k1 - OID_secp384r1 - OID_secp521r1 -*/ -const char *ec_named_curve_name(int curve); -int ec_named_curve_from_name(const char *name); -int ec_named_curve_to_der(int curve, uint8_t **out, size_t *outlen); -int ec_named_curve_from_der(int *curve, const uint8_t **in, size_t *inlen); - -/* -ECPoint ::= OCTET STRING -- uncompressed point -*/ -int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -ECPrivateKey ::= SEQUENCE { - version INTEGER, -- value MUST be (1) - privateKey OCTET STRING, -- big endian encoding of integer - parameters [0] EXPLICIT OBJECT IDENTIFIER OPTIONAL, -- namedCurve - publicKey [1] EXPLICIT BIT STRING OPTIONAL -- ECPoint -} -*/ - -enum { - EC_private_key_version = 1, -}; - -int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_EC_H +#define GMSSL_EC_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +NamedCurve: + OID_sm2 + OID_prime192v1 + OID_prime256v1 + OID_secp256k1 + OID_secp384r1 + OID_secp521r1 +*/ +const char *ec_named_curve_name(int curve); +int ec_named_curve_from_name(const char *name); +int ec_named_curve_to_der(int curve, uint8_t **out, size_t *outlen); +int ec_named_curve_from_der(int *curve, const uint8_t **in, size_t *inlen); + +/* +ECPoint ::= OCTET STRING -- uncompressed point +*/ +int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ECPrivateKey ::= SEQUENCE { + version INTEGER, -- value MUST be (1) + privateKey OCTET STRING, -- big endian encoding of integer + parameters [0] EXPLICIT OBJECT IDENTIFIER OPTIONAL, -- namedCurve + publicKey [1] EXPLICIT BIT STRING OPTIONAL -- ECPoint +} +*/ + +enum { + EC_private_key_version = 1, +}; + +int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/endian.h b/include/gmssl/endian.h index d84b93ea..4e5f2e6a 100644 --- a/include/gmssl/endian.h +++ b/include/gmssl/endian.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,72 +7,73 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_ENDIAN_H -#define GMSSL_ENDIAN_H - - -/* Big Endian R/W */ - -#define GETU16(p) \ - ((uint16_t)(p)[0] << 8 | \ - (uint16_t)(p)[1]) - -#define GETU32(p) \ - ((uint32_t)(p)[0] << 24 | \ - (uint32_t)(p)[1] << 16 | \ - (uint32_t)(p)[2] << 8 | \ - (uint32_t)(p)[3]) - -#define GETU64(p) \ - ((uint64_t)(p)[0] << 56 | \ - (uint64_t)(p)[1] << 48 | \ - (uint64_t)(p)[2] << 40 | \ - (uint64_t)(p)[3] << 32 | \ - (uint64_t)(p)[4] << 24 | \ - (uint64_t)(p)[5] << 16 | \ - (uint64_t)(p)[6] << 8 | \ - (uint64_t)(p)[7]) - - -// 注意:PUTU32(buf, val++) 会出错! -#define PUTU16(p,V) \ - ((p)[0] = (uint8_t)((V) >> 8), \ - (p)[1] = (uint8_t)(V)) - -#define PUTU32(p,V) \ - ((p)[0] = (uint8_t)((V) >> 24), \ - (p)[1] = (uint8_t)((V) >> 16), \ - (p)[2] = (uint8_t)((V) >> 8), \ - (p)[3] = (uint8_t)(V)) - -#define PUTU64(p,V) \ - ((p)[0] = (uint8_t)((V) >> 56), \ - (p)[1] = (uint8_t)((V) >> 48), \ - (p)[2] = (uint8_t)((V) >> 40), \ - (p)[3] = (uint8_t)((V) >> 32), \ - (p)[4] = (uint8_t)((V) >> 24), \ - (p)[5] = (uint8_t)((V) >> 16), \ - (p)[6] = (uint8_t)((V) >> 8), \ - (p)[7] = (uint8_t)(V)) - -/* Little Endian R/W */ - -#define GETU16_LE(p) (*(const uint16_t *)(p)) -#define GETU32_LE(p) (*(const uint32_t *)(p)) -#define GETU64_LE(p) (*(const uint64_t *)(p)) - -#define PUTU16_LE(p,V) *(uint16_t *)(p) = (V) -#define PUTU32_LE(p,V) *(uint32_t *)(p) = (V) -#define PUTU64_LE(p,V) *(uint64_t *)(p) = (V) - -/* Rotate */ - -#define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n)))) - -#define ROR32(a,n) ROL32((a),32-(n)) -#define ROR64(a,n) ROL64(a,64-n) - - -#endif + + +#ifndef GMSSL_ENDIAN_H +#define GMSSL_ENDIAN_H + + +/* Big Endian R/W */ + +#define GETU16(p) \ + ((uint16_t)(p)[0] << 8 | \ + (uint16_t)(p)[1]) + +#define GETU32(p) \ + ((uint32_t)(p)[0] << 24 | \ + (uint32_t)(p)[1] << 16 | \ + (uint32_t)(p)[2] << 8 | \ + (uint32_t)(p)[3]) + +#define GETU64(p) \ + ((uint64_t)(p)[0] << 56 | \ + (uint64_t)(p)[1] << 48 | \ + (uint64_t)(p)[2] << 40 | \ + (uint64_t)(p)[3] << 32 | \ + (uint64_t)(p)[4] << 24 | \ + (uint64_t)(p)[5] << 16 | \ + (uint64_t)(p)[6] << 8 | \ + (uint64_t)(p)[7]) + + +// 注意:PUTU32(buf, val++) 会出错! +#define PUTU16(p,V) \ + ((p)[0] = (uint8_t)((V) >> 8), \ + (p)[1] = (uint8_t)(V)) + +#define PUTU32(p,V) \ + ((p)[0] = (uint8_t)((V) >> 24), \ + (p)[1] = (uint8_t)((V) >> 16), \ + (p)[2] = (uint8_t)((V) >> 8), \ + (p)[3] = (uint8_t)(V)) + +#define PUTU64(p,V) \ + ((p)[0] = (uint8_t)((V) >> 56), \ + (p)[1] = (uint8_t)((V) >> 48), \ + (p)[2] = (uint8_t)((V) >> 40), \ + (p)[3] = (uint8_t)((V) >> 32), \ + (p)[4] = (uint8_t)((V) >> 24), \ + (p)[5] = (uint8_t)((V) >> 16), \ + (p)[6] = (uint8_t)((V) >> 8), \ + (p)[7] = (uint8_t)(V)) + +/* Little Endian R/W */ + +#define GETU16_LE(p) (*(const uint16_t *)(p)) +#define GETU32_LE(p) (*(const uint32_t *)(p)) +#define GETU64_LE(p) (*(const uint64_t *)(p)) + +#define PUTU16_LE(p,V) *(uint16_t *)(p) = (V) +#define PUTU32_LE(p,V) *(uint32_t *)(p) = (V) +#define PUTU64_LE(p,V) *(uint64_t *)(p) = (V) + +/* Rotate */ + +#define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n)))) + +#define ROR32(a,n) ROL32((a),32-(n)) +#define ROR64(a,n) ROL64(a,64-n) + + +#endif diff --git a/include/gmssl/error.h b/include/gmssl/error.h index 7bd94d17..3e35756f 100644 --- a/include/gmssl/error.h +++ b/include/gmssl/error.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,58 +7,59 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_ERROR_H -#define GMSSL_ERROR_H - - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define GMSSL_FMT_BIN 1 -#define GMSSL_FMT_HEX 2 -#define GMSSL_FMT_DER 4 -#define GMSSL_FMT_PEM 8 - - - -#define DEBUG 1 - -#define error_print() \ - do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0) - -#define error_print_msg(fmt, ...) \ - do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); } while (0) - -#define error_puts(str) \ - do { if (DEBUG) fprintf(stderr, "%s: %d: %s: %s", __FILE__, __LINE__, __func__, str); } while (0) - - -void print_der(const uint8_t *in, size_t inlen); -void print_bytes(const uint8_t *in, size_t inlen); -void print_nodes(const uint32_t *in, size_t inlen); - -#define FMT_CARRAY 0x80 - - -int format_print(FILE *fp, int format, int indent, const char *str, ...); -int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); -int format_string(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); - - - -//int tls_trace(int format, int indent, const char *str, ...); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_ERROR_H +#define GMSSL_ERROR_H + + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define GMSSL_FMT_BIN 1 +#define GMSSL_FMT_HEX 2 +#define GMSSL_FMT_DER 4 +#define GMSSL_FMT_PEM 8 + + + +#define DEBUG 1 + +#define error_print() \ + do { if (DEBUG) fprintf(stderr, "%s:%d:%s():\n",__FILE__, __LINE__, __func__); } while (0) + +#define error_print_msg(fmt, ...) \ + do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); } while (0) + +#define error_puts(str) \ + do { if (DEBUG) fprintf(stderr, "%s: %d: %s: %s", __FILE__, __LINE__, __func__, str); } while (0) + + +void print_der(const uint8_t *in, size_t inlen); +void print_bytes(const uint8_t *in, size_t inlen); +void print_nodes(const uint32_t *in, size_t inlen); + +#define FMT_CARRAY 0x80 + + +int format_print(FILE *fp, int format, int indent, const char *str, ...); +int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); +int format_string(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen); + + + +//int tls_trace(int format, int indent, const char *str, ...); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/gcm.h b/include/gmssl/gcm.h index faa30be5..ac4259f5 100644 --- a/include/gmssl/gcm.h +++ b/include/gmssl/gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,53 +7,54 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_GCM_H -#define GMSSL_GCM_H - - -#include -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#define GCM_IV_MIN_SIZE 1 -#define GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) -#define GCM_IV_DEFAULT_BITS 96 -#define GCM_IV_DEFAULT_SIZE 12 - -#define GCM_MIN_AAD_SIZE 0 -#define GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) - -#define GCM_MIN_PLAINTEXT_SIZE 0 -#define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) - - -#define GHASH_SIZE (16) - - -#define GCM_IS_LITTLE_ENDIAN 1 - - -void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, - const uint8_t *c, size_t clen, uint8_t out[16]); - -int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag); - -int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_GCM_H +#define GMSSL_GCM_H + + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define GCM_IV_MIN_SIZE 1 +#define GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) +#define GCM_IV_DEFAULT_BITS 96 +#define GCM_IV_DEFAULT_SIZE 12 + +#define GCM_MIN_AAD_SIZE 0 +#define GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) + +#define GCM_MIN_PLAINTEXT_SIZE 0 +#define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) + + +#define GHASH_SIZE (16) + + +#define GCM_IS_LITTLE_ENDIAN 1 + + +void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, + const uint8_t *c, size_t clen, uint8_t out[16]); + +int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag); + +int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/gf128.h b/include/gmssl/gf128.h index bb0faa84..fa156b1d 100644 --- a/include/gmssl/gf128.h +++ b/include/gmssl/gf128.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,47 +7,48 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1 - * A + B mod f(x) = a xor b - * A * 2 mod f(x) - */ - -#ifndef GMSSL_GF128_H -#define GMSSL_GF128_H - - -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -//typedef unsigned __int128 gf128_t; - -typedef struct { - uint64_t hi; - uint64_t lo; -} gf128_t; - - -// Note: send by value is comptabile with uint128_t and sse2 -gf128_t gf128_from_hex(const char *s); -int gf128_equ_hex(gf128_t a, const char *s); -gf128_t gf128_zero(void); -gf128_t gf128_add(gf128_t a, gf128_t b); -gf128_t gf128_mul(gf128_t a, gf128_t b); -gf128_t gf128_mul2(gf128_t a); -gf128_t gf128_from_bytes(const uint8_t p[16]); -void gf128_to_bytes(gf128_t a, uint8_t p[16]); -int gf128_print(FILE *fp, int fmt ,int ind, const char *label, gf128_t a); - - -#ifdef __cplusplus -} -#endif -#endif + + +/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1 + * A + B mod f(x) = a xor b + * A * 2 mod f(x) + */ + +#ifndef GMSSL_GF128_H +#define GMSSL_GF128_H + + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +//typedef unsigned __int128 gf128_t; + +typedef struct { + uint64_t hi; + uint64_t lo; +} gf128_t; + + +// Note: send by value is comptabile with uint128_t and sse2 +gf128_t gf128_from_hex(const char *s); +int gf128_equ_hex(gf128_t a, const char *s); +gf128_t gf128_zero(void); +gf128_t gf128_add(gf128_t a, gf128_t b); +gf128_t gf128_mul(gf128_t a, gf128_t b); +gf128_t gf128_mul2(gf128_t a); +gf128_t gf128_from_bytes(const uint8_t p[16]); +void gf128_to_bytes(gf128_t a, uint8_t p[16]); +int gf128_print(FILE *fp, int fmt ,int ind, const char *label, gf128_t a); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/hash_drbg.h b/include/gmssl/hash_drbg.h index f7e9ffa7..0026346e 100644 --- a/include/gmssl/hash_drbg.h +++ b/include/gmssl/hash_drbg.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,73 +7,74 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* NIST SP800-90A Rev.1 "Recommendation for Random Number Generation - * Using Deterministic Random Bit Generators", 10.1.1 Hash_DRBG */ - -#ifndef GMSSL_HASH_DRBG_H -#define GMSSL_HASH_DRBG_H - - -#include -#include -#include - - -/* seedlen for hash_drgb, table 2 of nist sp 800-90a rev.1 */ -#define HASH_DRBG_SM3_SEED_BITS 440 /* 55 bytes */ -#define HASH_DRBG_SHA1_SEED_BITS 440 -#define HASH_DRBG_SHA224_SEED_BITS 440 -#define HASH_DRBG_SHA512_224_SEED_BITS 440 -#define HASH_DRBG_SHA256_SEED_BITS 440 -#define HASH_DRBG_SHA512_256_SEED_BITS 440 -#define HASH_DRBG_SHA384_SEED_BITS 888 /* 110 bytes */ -#define HASH_DRBG_SHA512_SEED_BITS 888 -#define HASH_DRBG_MAX_SEED_BITS 888 - -#define HASH_DRBG_SM3_SEED_SIZE (HASH_DRBG_SM3_SEED_BITS/8) -#define HASH_DRBG_SHA1_SEED_SIZE (HASH_DRBG_SHA1_SEED_BITS/8) -#define HASH_DRBG_SHA224_SEED_SIZE (HASH_DRBG_SHA224_SEED_BITS/8) -#define HASH_DRBG_SHA512_224_SEED_SIZE (HASH_DRBG_SHA512_224_SEED_BITS/8) -#define HASH_DRBG_SHA256_SEED_SIZE (HASH_DRBG_SHA256_SEED_BITS/8) -#define HASH_DRBG_SHA512_256_SEED_SIZE (HASH_DRBG_SHA512_256_SEED_BITS/8) -#define HASH_DRBG_SHA384_SEED_SIZE (HASH_DRBG_SHA384_SEED_BITS/8) -#define HASH_DRBG_SHA512_SEED_SIZE (HASH_DRBG_SHA512_SEED_BITS/8) -#define HASH_DRBG_MAX_SEED_SIZE (HASH_DRBG_MAX_SEED_BITS/8) - -#define HASH_DRBG_RESEED_INTERVAL ((uint64_t)1 << 48) - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct { - const DIGEST *digest; - uint8_t V[HASH_DRBG_MAX_SEED_SIZE]; - uint8_t C[HASH_DRBG_MAX_SEED_SIZE]; - size_t seedlen; - uint64_t reseed_counter; -} HASH_DRBG; - - -int hash_drbg_init(HASH_DRBG *drbg, - const DIGEST *digest, - const uint8_t *entropy, size_t entropy_len, - const uint8_t *nonce, size_t nonce_len, - const uint8_t *personalstr, size_t personalstr_len); - -int hash_drbg_reseed(HASH_DRBG *drbg, - const uint8_t *entropy, size_t entropy_len, - const uint8_t *additional, size_t additional_len); - -int hash_drbg_generate(HASH_DRBG *drbg, - const uint8_t *additional, size_t additional_len, - size_t outlen, uint8_t *out); - - - -#ifdef __cplusplus -} -#endif -#endif + + +/* NIST SP800-90A Rev.1 "Recommendation for Random Number Generation + * Using Deterministic Random Bit Generators", 10.1.1 Hash_DRBG */ + +#ifndef GMSSL_HASH_DRBG_H +#define GMSSL_HASH_DRBG_H + + +#include +#include +#include + + +/* seedlen for hash_drgb, table 2 of nist sp 800-90a rev.1 */ +#define HASH_DRBG_SM3_SEED_BITS 440 /* 55 bytes */ +#define HASH_DRBG_SHA1_SEED_BITS 440 +#define HASH_DRBG_SHA224_SEED_BITS 440 +#define HASH_DRBG_SHA512_224_SEED_BITS 440 +#define HASH_DRBG_SHA256_SEED_BITS 440 +#define HASH_DRBG_SHA512_256_SEED_BITS 440 +#define HASH_DRBG_SHA384_SEED_BITS 888 /* 110 bytes */ +#define HASH_DRBG_SHA512_SEED_BITS 888 +#define HASH_DRBG_MAX_SEED_BITS 888 + +#define HASH_DRBG_SM3_SEED_SIZE (HASH_DRBG_SM3_SEED_BITS/8) +#define HASH_DRBG_SHA1_SEED_SIZE (HASH_DRBG_SHA1_SEED_BITS/8) +#define HASH_DRBG_SHA224_SEED_SIZE (HASH_DRBG_SHA224_SEED_BITS/8) +#define HASH_DRBG_SHA512_224_SEED_SIZE (HASH_DRBG_SHA512_224_SEED_BITS/8) +#define HASH_DRBG_SHA256_SEED_SIZE (HASH_DRBG_SHA256_SEED_BITS/8) +#define HASH_DRBG_SHA512_256_SEED_SIZE (HASH_DRBG_SHA512_256_SEED_BITS/8) +#define HASH_DRBG_SHA384_SEED_SIZE (HASH_DRBG_SHA384_SEED_BITS/8) +#define HASH_DRBG_SHA512_SEED_SIZE (HASH_DRBG_SHA512_SEED_BITS/8) +#define HASH_DRBG_MAX_SEED_SIZE (HASH_DRBG_MAX_SEED_BITS/8) + +#define HASH_DRBG_RESEED_INTERVAL ((uint64_t)1 << 48) + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + const DIGEST *digest; + uint8_t V[HASH_DRBG_MAX_SEED_SIZE]; + uint8_t C[HASH_DRBG_MAX_SEED_SIZE]; + size_t seedlen; + uint64_t reseed_counter; +} HASH_DRBG; + + +int hash_drbg_init(HASH_DRBG *drbg, + const DIGEST *digest, + const uint8_t *entropy, size_t entropy_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *personalstr, size_t personalstr_len); + +int hash_drbg_reseed(HASH_DRBG *drbg, + const uint8_t *entropy, size_t entropy_len, + const uint8_t *additional, size_t additional_len); + +int hash_drbg_generate(HASH_DRBG *drbg, + const uint8_t *additional, size_t additional_len, + size_t outlen, uint8_t *out); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/hex.h b/include/gmssl/hex.h index 734fcaf5..8a4a796d 100644 --- a/include/gmssl/hex.h +++ b/include/gmssl/hex.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,26 +7,27 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_HEX_H -#define GMSSL_HEX_H - - -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_HEX_H +#define GMSSL_HEX_H + + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/hkdf.h b/include/gmssl/hkdf.h index 045a36ff..34f9e256 100644 --- a/include/gmssl/hkdf.h +++ b/include/gmssl/hkdf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,39 +7,40 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -// RFC 5869 - -#ifndef GMSSL_HKDF_H -#define GMSSL_HKDF_H - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -int hkdf_extract(const DIGEST *digest, const uint8_t *salt, size_t saltlen, - const uint8_t *ikm, size_t ikmlen, - uint8_t *prk, size_t *prklen); - -int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen, - const uint8_t *opt_info, size_t opt_infolen, - size_t L, uint8_t *okm); - -int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen, - const uint8_t *ikm, size_t ikmlen, - uint8_t *prk, size_t *prklen); - -int sm3_hkdf_expand(const uint8_t *prk, size_t prklen, - const uint8_t *opt_info, size_t opt_infolen, - size_t L, uint8_t *okm); - - -#ifdef __cplusplus -} -#endif -#endif + +// RFC 5869 + +#ifndef GMSSL_HKDF_H +#define GMSSL_HKDF_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +int hkdf_extract(const DIGEST *digest, const uint8_t *salt, size_t saltlen, + const uint8_t *ikm, size_t ikmlen, + uint8_t *prk, size_t *prklen); + +int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen, + const uint8_t *opt_info, size_t opt_infolen, + size_t L, uint8_t *okm); + +int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen, + const uint8_t *ikm, size_t ikmlen, + uint8_t *prk, size_t *prklen); + +int sm3_hkdf_expand(const uint8_t *prk, size_t prklen, + const uint8_t *opt_info, size_t opt_infolen, + size_t L, uint8_t *okm); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/hmac.h b/include/gmssl/hmac.h index b6c4b9df..42a502e6 100644 --- a/include/gmssl/hmac.h +++ b/include/gmssl/hmac.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,41 +7,42 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_HMAC_H -#define GMSSL_HMAC_H - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#define HMAC_MAX_SIZE (DIGEST_MAX_SIZE) - - -typedef struct hmac_ctx_st { - const DIGEST *digest; - DIGEST_CTX digest_ctx; - DIGEST_CTX i_ctx; - DIGEST_CTX o_ctx; -} HMAC_CTX; - - -size_t hmac_size(const HMAC_CTX *ctx); - -int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen); -int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen); -int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen); - -int hmac(const DIGEST *md, const uint8_t *key, size_t keylen, - const uint8_t *data, size_t dlen, - uint8_t *mac, size_t *maclen); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_HMAC_H +#define GMSSL_HMAC_H + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define HMAC_MAX_SIZE (DIGEST_MAX_SIZE) + + +typedef struct hmac_ctx_st { + const DIGEST *digest; + DIGEST_CTX digest_ctx; + DIGEST_CTX i_ctx; + DIGEST_CTX o_ctx; +} HMAC_CTX; + + +size_t hmac_size(const HMAC_CTX *ctx); + +int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen); +int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen); +int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen); + +int hmac(const DIGEST *md, const uint8_t *key, size_t keylen, + const uint8_t *data, size_t dlen, + uint8_t *mac, size_t *maclen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/md5.h b/include/gmssl/md5.h index f345e91a..dc73e8c4 100644 --- a/include/gmssl/md5.h +++ b/include/gmssl/md5.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,42 +7,43 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_MD5_H -#define GMSSL_MD5_H - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define MD5_IS_BIG_ENDIAN 0 - -#define MD5_DIGEST_SIZE 16 -#define MD5_BLOCK_SIZE 64 -#define MD5_STATE_WORDS (MD5_BLOCK_SIZE/sizeof(uint32_t)) - -typedef struct { - uint32_t state[MD5_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[MD5_BLOCK_SIZE]; - size_t num; -} MD5_CTX; - - -void md5_init(MD5_CTX *ctx); -void md5_update(MD5_CTX *ctx, const uint8_t *data, size_t datalen); -void md5_finish(MD5_CTX *ctx, uint8_t dgst[MD5_DIGEST_SIZE]); -void md5_digest(const uint8_t *data, size_t datalen, uint8_t dgst[MD5_DIGEST_SIZE]); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_MD5_H +#define GMSSL_MD5_H + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define MD5_IS_BIG_ENDIAN 0 + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 +#define MD5_STATE_WORDS (MD5_BLOCK_SIZE/sizeof(uint32_t)) + +typedef struct { + uint32_t state[MD5_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[MD5_BLOCK_SIZE]; + size_t num; +} MD5_CTX; + + +void md5_init(MD5_CTX *ctx); +void md5_update(MD5_CTX *ctx, const uint8_t *data, size_t datalen); +void md5_finish(MD5_CTX *ctx, uint8_t dgst[MD5_DIGEST_SIZE]); +void md5_digest(const uint8_t *data, size_t datalen, uint8_t dgst[MD5_DIGEST_SIZE]); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/mem.h b/include/gmssl/mem.h index 5479fb2c..6d3cb3d4 100644 --- a/include/gmssl/mem.h +++ b/include/gmssl/mem.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,21 +7,22 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_MEM_H -#define GMSSL_MEM_H - -#include -#include // where size_t from - - -void memxor(void *r, const void *a, size_t len); -void gmssl_memxor(void *r, const void *a, const void *b, size_t len); - -int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len); -void gmssl_secure_clear(void *ptr, size_t len); - -int mem_is_zero(const uint8_t *buf, size_t len); // FIXME: uint8_t * to void * - -#endif - + + +#ifndef GMSSL_MEM_H +#define GMSSL_MEM_H + +#include +#include // where size_t from + + +void memxor(void *r, const void *a, size_t len); +void gmssl_memxor(void *r, const void *a, const void *b, size_t len); + +int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len); +void gmssl_secure_clear(void *ptr, size_t len); + +int mem_is_zero(const uint8_t *buf, size_t len); // FIXME: uint8_t * to void * + +#endif + diff --git a/include/gmssl/oid.h b/include/gmssl/oid.h index 43a3a43d..1dd6b0a9 100644 --- a/include/gmssl/oid.h +++ b/include/gmssl/oid.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,207 +7,208 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_OID_H -#define GMSSL_OID_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - OID_undef = 0, - - // ShangMi schemes in GM/T 0006-2012 - OID_sm1, - OID_ssf33, - OID_sm4, - OID_zuc, - OID_sm2, - OID_sm2sign, - OID_sm2keyagreement, - OID_sm2encrypt, - OID_sm9, - OID_sm9sign, - OID_sm9keyagreement, - OID_sm9encrypt, - OID_sm3, - OID_sm3_keyless, - OID_hmac_sm3, - OID_sm2sign_with_sm3, - OID_rsasign_with_sm3, - OID_ec_public_key, // X9.62 ecPublicKey - OID_prime192v1, - OID_prime256v1, - OID_secp256k1, - OID_secp192k1, - OID_secp224k1, - OID_secp224r1, - OID_secp384r1, - OID_secp521r1, - - OID_at_name, - OID_at_surname, - OID_at_given_name, - OID_at_initials, - OID_at_generation_qualifier, - OID_at_common_name, - OID_at_locality_name, - OID_at_state_or_province_name, - OID_at_organization_name, - OID_at_organizational_unit_name, - OID_at_title, - OID_at_dn_qualifier, - OID_at_country_name, - OID_at_serial_number, - OID_at_pseudonym, - OID_domain_component, - OID_email_address, - - // Cert Extensions - OID_ce_authority_key_identifier, - OID_ce_subject_key_identifier, - OID_ce_key_usage, - OID_ce_certificate_policies, - OID_ce_policy_mappings, - OID_ce_subject_alt_name, - OID_ce_issuer_alt_name, - OID_ce_subject_directory_attributes, - OID_ce_basic_constraints, - OID_ce_name_constraints, - OID_ce_policy_constraints, - OID_ce_ext_key_usage, - OID_ce_crl_distribution_points, - OID_ce_inhibit_any_policy, - OID_ce_freshest_crl, - OID_netscape_cert_type, - OID_netscape_cert_comment, - OID_cert_authority_info_access, - OID_ct_precertificate_scts, - - // CRL Extensions - //OID_ce_authority_key_identifier, - //OID_ce_issuer_alt_name, - OID_ce_crl_number, - OID_ce_delta_crl_indicator, - OID_ce_issuing_distribution_point, - //OID_ce_freshest_crl, - OID_pe_authority_info_access, - - // CRL Entry Extensions - OID_ce_crl_reasons, - OID_ce_invalidity_date, - OID_ce_certificate_issuer, - - // X.509 KeyPropuseID - OID_kp_server_auth, - OID_kp_client_auth, - OID_kp_code_signing, - OID_kp_email_protection, - OID_kp_time_stamping, - OID_kp_ocsp_signing, - - OID_qt_cps, - OID_qt_unotice, - - OID_md5, - OID_sha1, - OID_sha224, - OID_sha256, - OID_sha384, - OID_sha512, - OID_sha512_224, - OID_sha512_256, - - - OID_hmac_sha1, - OID_hmac_sha224, - OID_hmac_sha256, - OID_hmac_sha384, - OID_hmac_sha512, - OID_hmac_sha512_224, - OID_hmac_sha512_256, - - OID_pbkdf2, // {pkcs-5 12} - OID_pbes2, // {pkcs-5 13} - - - - OID_sm4_ecb, // 1 2 156 10197 1 104 1 - OID_sm4_cbc, // 1 2 156 10197 1 104 2 - - OID_aes, - OID_aes128_cbc, - OID_aes192_cbc, - OID_aes256_cbc, - - OID_aes128, // 没有OID - - OID_ecdsa_with_sha1, - OID_ecdsa_with_sha224, - OID_ecdsa_with_sha256, - OID_ecdsa_with_sha384, - OID_ecdsa_with_sha512, - - OID_rsasign_with_md5, - OID_rsasign_with_sha1, - OID_rsasign_with_sha224, - OID_rsasign_with_sha256, - OID_rsasign_with_sha384, - OID_rsasign_with_sha512, - - OID_rsa_encryption, - OID_rsaes_oaep, - - OID_any_policy, - - OID_cms_data, - OID_cms_signed_data, - OID_cms_enveloped_data, - OID_cms_signed_and_enveloped_data, - OID_cms_encrypted_data, - OID_cms_key_agreement_info, -}; - -// {iso(1) org(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7)} -#define oid_pkix 1,3,6,1,5,5,7 - -#define oid_pe oid_pkix,1 -#define oid_qt oid_pkix,2 -#define oid_kp oid_pkix,3 -#define oid_ad oid_pkix,48 - -// {iso(1) member-body(2) us(840) rsadsi(113549)} -#define oid_rsadsi 1,2,840,113549 -#define oid_pkcs oid_rsadsi,1 -#define oid_pkcs5 oid_pkcs,5 - -// {iso(1) member-body(2) us(840) ansi-x962(10045)} -#define oid_x9_62 1,2,840,10045 - - - -#define oid_at 2,5,4 -#define oid_ce 2,5,29 - - -#define oid_sm 1,2,156,10197 -#define oid_sm_algors oid_sm,1 -#define oid_sm2_cms oid_sm,6,1,4,2 - - - - - -#define oid_cnt(nodes) (sizeof(nodes)/sizeof(int)) - - - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_OID_H +#define GMSSL_OID_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + OID_undef = 0, + + // ShangMi schemes in GM/T 0006-2012 + OID_sm1, + OID_ssf33, + OID_sm4, + OID_zuc, + OID_sm2, + OID_sm2sign, + OID_sm2keyagreement, + OID_sm2encrypt, + OID_sm9, + OID_sm9sign, + OID_sm9keyagreement, + OID_sm9encrypt, + OID_sm3, + OID_sm3_keyless, + OID_hmac_sm3, + OID_sm2sign_with_sm3, + OID_rsasign_with_sm3, + OID_ec_public_key, // X9.62 ecPublicKey + OID_prime192v1, + OID_prime256v1, + OID_secp256k1, + OID_secp192k1, + OID_secp224k1, + OID_secp224r1, + OID_secp384r1, + OID_secp521r1, + + OID_at_name, + OID_at_surname, + OID_at_given_name, + OID_at_initials, + OID_at_generation_qualifier, + OID_at_common_name, + OID_at_locality_name, + OID_at_state_or_province_name, + OID_at_organization_name, + OID_at_organizational_unit_name, + OID_at_title, + OID_at_dn_qualifier, + OID_at_country_name, + OID_at_serial_number, + OID_at_pseudonym, + OID_domain_component, + OID_email_address, + + // Cert Extensions + OID_ce_authority_key_identifier, + OID_ce_subject_key_identifier, + OID_ce_key_usage, + OID_ce_certificate_policies, + OID_ce_policy_mappings, + OID_ce_subject_alt_name, + OID_ce_issuer_alt_name, + OID_ce_subject_directory_attributes, + OID_ce_basic_constraints, + OID_ce_name_constraints, + OID_ce_policy_constraints, + OID_ce_ext_key_usage, + OID_ce_crl_distribution_points, + OID_ce_inhibit_any_policy, + OID_ce_freshest_crl, + OID_netscape_cert_type, + OID_netscape_cert_comment, + OID_cert_authority_info_access, + OID_ct_precertificate_scts, + + // CRL Extensions + //OID_ce_authority_key_identifier, + //OID_ce_issuer_alt_name, + OID_ce_crl_number, + OID_ce_delta_crl_indicator, + OID_ce_issuing_distribution_point, + //OID_ce_freshest_crl, + OID_pe_authority_info_access, + + // CRL Entry Extensions + OID_ce_crl_reasons, + OID_ce_invalidity_date, + OID_ce_certificate_issuer, + + // X.509 KeyPropuseID + OID_kp_server_auth, + OID_kp_client_auth, + OID_kp_code_signing, + OID_kp_email_protection, + OID_kp_time_stamping, + OID_kp_ocsp_signing, + + OID_qt_cps, + OID_qt_unotice, + + OID_md5, + OID_sha1, + OID_sha224, + OID_sha256, + OID_sha384, + OID_sha512, + OID_sha512_224, + OID_sha512_256, + + + OID_hmac_sha1, + OID_hmac_sha224, + OID_hmac_sha256, + OID_hmac_sha384, + OID_hmac_sha512, + OID_hmac_sha512_224, + OID_hmac_sha512_256, + + OID_pbkdf2, // {pkcs-5 12} + OID_pbes2, // {pkcs-5 13} + + + + OID_sm4_ecb, // 1 2 156 10197 1 104 1 + OID_sm4_cbc, // 1 2 156 10197 1 104 2 + + OID_aes, + OID_aes128_cbc, + OID_aes192_cbc, + OID_aes256_cbc, + + OID_aes128, // 没有OID + + OID_ecdsa_with_sha1, + OID_ecdsa_with_sha224, + OID_ecdsa_with_sha256, + OID_ecdsa_with_sha384, + OID_ecdsa_with_sha512, + + OID_rsasign_with_md5, + OID_rsasign_with_sha1, + OID_rsasign_with_sha224, + OID_rsasign_with_sha256, + OID_rsasign_with_sha384, + OID_rsasign_with_sha512, + + OID_rsa_encryption, + OID_rsaes_oaep, + + OID_any_policy, + + OID_cms_data, + OID_cms_signed_data, + OID_cms_enveloped_data, + OID_cms_signed_and_enveloped_data, + OID_cms_encrypted_data, + OID_cms_key_agreement_info, +}; + +// {iso(1) org(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7)} +#define oid_pkix 1,3,6,1,5,5,7 + +#define oid_pe oid_pkix,1 +#define oid_qt oid_pkix,2 +#define oid_kp oid_pkix,3 +#define oid_ad oid_pkix,48 + +// {iso(1) member-body(2) us(840) rsadsi(113549)} +#define oid_rsadsi 1,2,840,113549 +#define oid_pkcs oid_rsadsi,1 +#define oid_pkcs5 oid_pkcs,5 + +// {iso(1) member-body(2) us(840) ansi-x962(10045)} +#define oid_x9_62 1,2,840,10045 + + + +#define oid_at 2,5,4 +#define oid_ce 2,5,29 + + +#define oid_sm 1,2,156,10197 +#define oid_sm_algors oid_sm,1 +#define oid_sm2_cms oid_sm,6,1,4,2 + + + + + +#define oid_cnt(nodes) (sizeof(nodes)/sizeof(int)) + + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/pbkdf2.h b/include/gmssl/pbkdf2.h index c63f0e1b..d66d2ce5 100644 --- a/include/gmssl/pbkdf2.h +++ b/include/gmssl/pbkdf2.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,48 +7,49 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_PBKDF2_H -#define GMSSL_PBKDF2_H - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -PBKDF2 Public API - - PBKDF2_MIN_ITER - PBKDF2_DEFAULT_SALT_SIZE - PBKDF2_MAX_SALT_SIZE - - pbkdf2_hmac_sm3_genkey -*/ - - -#define PBKDF2_MIN_ITER 10000 -#define PBKDF2_MAX_ITER (INT_MAX) -#define PBKDF2_MAX_SALT_SIZE 64 -#define PBKDF2_DEFAULT_SALT_SIZE 8 - - -int pbkdf2_genkey(const DIGEST *digest, - const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter, - size_t outlen, uint8_t *out); - -int pbkdf2_hmac_sm3_genkey( - const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter, - size_t outlen, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_PBKDF2_H +#define GMSSL_PBKDF2_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +PBKDF2 Public API + + PBKDF2_MIN_ITER + PBKDF2_DEFAULT_SALT_SIZE + PBKDF2_MAX_SALT_SIZE + + pbkdf2_hmac_sm3_genkey +*/ + + +#define PBKDF2_MIN_ITER 10000 +#define PBKDF2_MAX_ITER (INT_MAX) +#define PBKDF2_MAX_SALT_SIZE 64 +#define PBKDF2_DEFAULT_SALT_SIZE 8 + + +int pbkdf2_genkey(const DIGEST *digest, + const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter, + size_t outlen, uint8_t *out); + +int pbkdf2_hmac_sm3_genkey( + const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, size_t iter, + size_t outlen, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/pem.h b/include/gmssl/pem.h index de08790b..43337532 100644 --- a/include/gmssl/pem.h +++ b/include/gmssl/pem.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,27 +7,28 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_PEM_H -#define GMSSL_PEM_H - - -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -int pem_read(FILE *fp, const char *name, uint8_t *out, size_t *outlen, size_t maxlen); -int pem_write(FILE *fp, const char *name, const uint8_t *in, size_t inlen); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_PEM_H +#define GMSSL_PEM_H + + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +int pem_read(FILE *fp, const char *name, uint8_t *out, size_t *outlen, size_t maxlen); +int pem_write(FILE *fp, const char *name, const uint8_t *in, size_t inlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/pkcs8.h b/include/gmssl/pkcs8.h index 6cd38e5e..0f387166 100644 --- a/include/gmssl/pkcs8.h +++ b/include/gmssl/pkcs8.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,163 +7,164 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -// RFC 5208: PKCS #8: Private-Key Information Syntax Specification version 1.2 - - -#ifndef GMSSL_PKCS8_H -#define GMSSL_PKCS8_H - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} - -PBKDF2-params ::= SEQUENCE { - salt CHOICE { - specified OCTET STRING, - otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} - }, - iterationCount INTEGER (1..MAX), - keyLength INTEGER (1..MAX) OPTIONAL, -- 这个参数可以由函数指定 - prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 -} - -prf must be OID_hmac_sm3 -cipher must be OID_sm4_cbc -*/ -int pbkdf2_params_to_der(const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, - uint8_t **out, size_t *outlen); -int pbkdf2_params_from_der(const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, - const uint8_t **in, size_t *inlen); -int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int pbkdf2_algor_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - uint8_t **out, size_t *outlen); -int pbkdf2_algor_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - const uint8_t **in, size_t *inlen); -int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -/* -id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} - -PBES2-params ::= SEQUENCE { - keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, -- id-PBKDF2 - encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}} - -PBES2-Encs: - AES-CBC-Pad [RFC2898] - RC5-CBC-Pad - DES-CBC-Pad legacy - DES-EDE3-CBC-Pad legacy - RC2-CBC-Pad legacy -*/ - -int pbes2_enc_algor_to_der( - int cipher, - const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen); -int pbes2_enc_algor_from_der( - int *cipher, - const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen); -int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -int pbes2_params_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen); -int pbes2_params_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen); -int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -int pbes2_algor_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen); -int pbes2_algor_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen); -int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -from [RFC 5208] - -EncryptedPrivateKeyInfo ::= SEQUENCE { - encryptionAlgorithm EncryptionAlgorithmIdentifier, - encryptedData OCTET STRING } - -encryptionAlgorithm: - id-PBES2 - -PrivateKeyInfo ::= SEQUENCE { - version INTEGER { v1(0) }, - privateKeyAlgorithm AlgorithmIdentifier, - privateKey OCTET STRING, - attributes [0] Attributes OPTIONAL } -*/ - -int pkcs8_enced_private_key_info_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - int cipher, - const uint8_t *iv, size_t ivlen, - const uint8_t *enced, size_t encedlen, - uint8_t **out, size_t *outlen); -int pkcs8_enced_private_key_info_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - int *cipher, - const uint8_t **iv, size_t *ivlen, - const uint8_t **enced, size_t *encedlen, - const uint8_t **in, size_t *inlen); -int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -#ifdef __cplusplus -} -#endif -#endif + +// RFC 5208: PKCS #8: Private-Key Information Syntax Specification version 1.2 + + +#ifndef GMSSL_PKCS8_H +#define GMSSL_PKCS8_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} + +PBKDF2-params ::= SEQUENCE { + salt CHOICE { + specified OCTET STRING, + otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} + }, + iterationCount INTEGER (1..MAX), + keyLength INTEGER (1..MAX) OPTIONAL, -- 这个参数可以由函数指定 + prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 +} + +prf must be OID_hmac_sm3 +cipher must be OID_sm4_cbc +*/ +int pbkdf2_params_to_der(const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + uint8_t **out, size_t *outlen); +int pbkdf2_params_from_der(const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + const uint8_t **in, size_t *inlen); +int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int pbkdf2_algor_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + uint8_t **out, size_t *outlen); +int pbkdf2_algor_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + const uint8_t **in, size_t *inlen); +int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +/* +id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} + +PBES2-params ::= SEQUENCE { + keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, -- id-PBKDF2 + encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}} + +PBES2-Encs: + AES-CBC-Pad [RFC2898] + RC5-CBC-Pad + DES-CBC-Pad legacy + DES-EDE3-CBC-Pad legacy + RC2-CBC-Pad legacy +*/ + +int pbes2_enc_algor_to_der( + int cipher, + const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen); +int pbes2_enc_algor_from_der( + int *cipher, + const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen); +int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +int pbes2_params_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + int cipher, + const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen); +int pbes2_params_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + int *cipher, + const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen); +int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +int pbes2_algor_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + int cipher, + const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen); +int pbes2_algor_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + int *cipher, + const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen); +int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +from [RFC 5208] + +EncryptedPrivateKeyInfo ::= SEQUENCE { + encryptionAlgorithm EncryptionAlgorithmIdentifier, + encryptedData OCTET STRING } + +encryptionAlgorithm: + id-PBES2 + +PrivateKeyInfo ::= SEQUENCE { + version INTEGER { v1(0) }, + privateKeyAlgorithm AlgorithmIdentifier, + privateKey OCTET STRING, + attributes [0] Attributes OPTIONAL } +*/ + +int pkcs8_enced_private_key_info_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + int cipher, + const uint8_t *iv, size_t ivlen, + const uint8_t *enced, size_t encedlen, + uint8_t **out, size_t *outlen); +int pkcs8_enced_private_key_info_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + int *cipher, + const uint8_t **iv, size_t *ivlen, + const uint8_t **enced, size_t *encedlen, + const uint8_t **in, size_t *inlen); +int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/rand.h b/include/gmssl/rand.h index 8a16003c..2c581f8f 100644 --- a/include/gmssl/rand.h +++ b/include/gmssl/rand.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,32 +7,33 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_RAND_H -#define GMSSL_RAND_H - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Rand Public API - - rand_bytes - -*/ - -int rand_bytes(uint8_t *buf, size_t buflen); - -int rdrand_bytes(uint8_t *buf, size_t buflen); -int rdseed_bytes(uint8_t *buf, size_t buflen); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_RAND_H +#define GMSSL_RAND_H + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Rand Public API + + rand_bytes + +*/ + +int rand_bytes(uint8_t *buf, size_t buflen); + +int rdrand_bytes(uint8_t *buf, size_t buflen); +int rdseed_bytes(uint8_t *buf, size_t buflen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/rc4.h b/include/gmssl/rc4.h index e3596f07..b2a115cf 100644 --- a/include/gmssl/rc4.h +++ b/include/gmssl/rc4.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,34 +7,35 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_RC4_H -#define GMSSL_RC4_H - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define RC4_MIN_KEY_BITS 40 -#define RC4_STATE_NUM_WORDS 256 - - -typedef struct { - uint8_t d[RC4_STATE_NUM_WORDS]; -} RC4_STATE; - -void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen); -void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_RC4_H +#define GMSSL_RC4_H + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define RC4_MIN_KEY_BITS 40 +#define RC4_STATE_NUM_WORDS 256 + + +typedef struct { + uint8_t d[RC4_STATE_NUM_WORDS]; +} RC4_STATE; + +void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen); +void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/rsa.h b/include/gmssl/rsa.h index 84eab8a5..887987e9 100644 --- a/include/gmssl/rsa.h +++ b/include/gmssl/rsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,50 +7,51 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_RSA_H -#define GMSSL_RSA_H - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -RSAPublicKey ::= SEQUENCE { - modulus INTEGER, -- n - publicExponent INTEGER -- e -} - -RSAPrivateKey ::= SEQUENCE { - version INTEGER, -- 0 - modulus INTEGER, -- n - publicExponent INTEGER, -- e - privateExponent INTEGER, -- d - prime1 INTEGER, -- p - prime2 INTEGER, -- q - exponent1 INTEGER, -- d mod (p-1) - exponent2 INTEGER, -- d mod (q-1) - coefficient INTEGER -- q^-1 mod p -} -*/ - - -int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - - - - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_RSA_H +#define GMSSL_RSA_H + + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER -- e +} + +RSAPrivateKey ::= SEQUENCE { + version INTEGER, -- 0 + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER -- q^-1 mod p +} +*/ + + +int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + + + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sdf.h b/include/gmssl/sdf.h index e92343c4..a95118d8 100644 --- a/include/gmssl/sdf.h +++ b/include/gmssl/sdf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,63 +7,64 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SDF_H -#define GMSSL_SDF_H - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -/* -SDF Public API - - sdf_load_library - sdf_unload_library - - SDF_DEVICE - sdf_open_device - sdf_close_device - sdf_print_device_info - sdf_rand_bytes - sdf_load_sign_key - - SDF_KEY - sdf_sign - sdf_release_key -*/ - -typedef struct { - void *handle; - char issuer[41]; - char name[17]; - char serial[17]; -} SDF_DEVICE; - -typedef struct { - SM2_KEY public_key; - void *session; - int index; -} SDF_KEY; - - -int sdf_load_library(const char *so_path, const char *vendor); -int sdf_open_device(SDF_DEVICE *dev); -int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev); -int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len); -int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass); -int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); -int sdf_release_key(SDF_KEY *key); -int sdf_close_device(SDF_DEVICE *dev); -void sdf_unload_library(void); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_SDF_H +#define GMSSL_SDF_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +SDF Public API + + sdf_load_library + sdf_unload_library + + SDF_DEVICE + sdf_open_device + sdf_close_device + sdf_print_device_info + sdf_rand_bytes + sdf_load_sign_key + + SDF_KEY + sdf_sign + sdf_release_key +*/ + +typedef struct { + void *handle; + char issuer[41]; + char name[17]; + char serial[17]; +} SDF_DEVICE; + +typedef struct { + SM2_KEY public_key; + void *session; + int index; +} SDF_KEY; + + +int sdf_load_library(const char *so_path, const char *vendor); +int sdf_open_device(SDF_DEVICE *dev); +int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev); +int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len); +int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass); +int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); +int sdf_release_key(SDF_KEY *key); +int sdf_close_device(SDF_DEVICE *dev); +void sdf_unload_library(void); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sha1.h b/include/gmssl/sha1.h index 288e7866..36fa140f 100644 --- a/include/gmssl/sha1.h +++ b/include/gmssl/sha1.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,39 +7,40 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SHA1_H -#define GMSSL_SHA1_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SHA1_IS_BIG_ENDIAN 1 - -#define SHA1_DIGEST_SIZE 20 -#define SHA1_BLOCK_SIZE 64 -#define SHA1_STATE_WORDS (SHA1_DIGEST_SIZE/sizeof(uint32_t)) - - -typedef struct { - uint32_t state[SHA1_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SHA1_BLOCK_SIZE]; - size_t num; -} SHA1_CTX; - -void sha1_init(SHA1_CTX *ctx); -void sha1_update(SHA1_CTX *ctx, const uint8_t *data, size_t datalen); -void sha1_finish(SHA1_CTX *ctx, uint8_t dgst[SHA1_DIGEST_SIZE]); -void sha1_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SHA1_DIGEST_SIZE]); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_SHA1_H +#define GMSSL_SHA1_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SHA1_IS_BIG_ENDIAN 1 + +#define SHA1_DIGEST_SIZE 20 +#define SHA1_BLOCK_SIZE 64 +#define SHA1_STATE_WORDS (SHA1_DIGEST_SIZE/sizeof(uint32_t)) + + +typedef struct { + uint32_t state[SHA1_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SHA1_BLOCK_SIZE]; + size_t num; +} SHA1_CTX; + +void sha1_init(SHA1_CTX *ctx); +void sha1_update(SHA1_CTX *ctx, const uint8_t *data, size_t datalen); +void sha1_finish(SHA1_CTX *ctx, uint8_t dgst[SHA1_DIGEST_SIZE]); +void sha1_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SHA1_DIGEST_SIZE]); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sha2.h b/include/gmssl/sha2.h index 43722bc0..fb801edb 100644 --- a/include/gmssl/sha2.h +++ b/include/gmssl/sha2.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,96 +7,97 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_SHA2_H -#define GMSSL_SHA2_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SHA2_IS_BIG_ENDIAN 1 - - -#define SHA224_DIGEST_SIZE 28 -#define SHA224_BLOCK_SIZE 64 -#define SHA224_STATE_WORDS 8 - -typedef struct { - uint32_t state[SHA224_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SHA224_BLOCK_SIZE]; - int num; -} SHA224_CTX; - -void sha224_init(SHA224_CTX *ctx); -void sha224_update(SHA224_CTX *ctx, const uint8_t* data, size_t datalen); -void sha224_finish(SHA224_CTX *ctx, uint8_t dgst[SHA224_DIGEST_SIZE]); -void sha224_digest(const uint8_t *data, size_t datalen, - uint8_t dgst[SHA224_DIGEST_SIZE]); - - -#define SHA256_DIGEST_SIZE 32 -#define SHA256_BLOCK_SIZE 64 -#define SHA256_STATE_WORDS 8 - -typedef struct { - uint32_t state[SHA256_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SHA256_BLOCK_SIZE]; - int num; -} SHA256_CTX; - -void sha256_init(SHA256_CTX *ctx); -void sha256_update(SHA256_CTX *ctx, const uint8_t* data, size_t datalen); -void sha256_finish(SHA256_CTX *ctx, uint8_t dgst[SHA256_DIGEST_SIZE]); -void sha256_digest(const uint8_t *data, size_t datalen, - uint8_t dgst[SHA256_DIGEST_SIZE]); - - -#define SHA384_DIGEST_SIZE 48 -#define SHA384_BLOCK_SIZE 128 -#define SHA384_STATE_WORDS 8 - -typedef struct { - uint64_t state[SHA384_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SHA384_BLOCK_SIZE]; - int num; -} SHA384_CTX; - -void sha384_init(SHA384_CTX *ctx); -void sha384_update(SHA384_CTX *ctx, const uint8_t* data, size_t datalen); -void sha384_finish(SHA384_CTX *ctx, uint8_t dgst[SHA384_DIGEST_SIZE]); -void sha384_digest(const uint8_t *data, size_t datalen, - uint8_t dgst[SHA384_DIGEST_SIZE]); - - -#define SHA512_DIGEST_SIZE 64 -#define SHA512_BLOCK_SIZE 128 -#define SHA512_STATE_WORDS 8 - -typedef struct { - uint64_t state[SHA512_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SHA512_BLOCK_SIZE]; - int num; -} SHA512_CTX; - -void sha512_init(SHA512_CTX *ctx); -void sha512_update(SHA512_CTX *ctx, const uint8_t* data, size_t datalen); -void sha512_finish(SHA512_CTX *ctx, uint8_t dgst[SHA512_DIGEST_SIZE]); -void sha512_digest(const uint8_t *data, size_t datalen, - uint8_t dgst[SHA512_DIGEST_SIZE]); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_SHA2_H +#define GMSSL_SHA2_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SHA2_IS_BIG_ENDIAN 1 + + +#define SHA224_DIGEST_SIZE 28 +#define SHA224_BLOCK_SIZE 64 +#define SHA224_STATE_WORDS 8 + +typedef struct { + uint32_t state[SHA224_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SHA224_BLOCK_SIZE]; + int num; +} SHA224_CTX; + +void sha224_init(SHA224_CTX *ctx); +void sha224_update(SHA224_CTX *ctx, const uint8_t* data, size_t datalen); +void sha224_finish(SHA224_CTX *ctx, uint8_t dgst[SHA224_DIGEST_SIZE]); +void sha224_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA224_DIGEST_SIZE]); + + +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 +#define SHA256_STATE_WORDS 8 + +typedef struct { + uint32_t state[SHA256_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SHA256_BLOCK_SIZE]; + int num; +} SHA256_CTX; + +void sha256_init(SHA256_CTX *ctx); +void sha256_update(SHA256_CTX *ctx, const uint8_t* data, size_t datalen); +void sha256_finish(SHA256_CTX *ctx, uint8_t dgst[SHA256_DIGEST_SIZE]); +void sha256_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA256_DIGEST_SIZE]); + + +#define SHA384_DIGEST_SIZE 48 +#define SHA384_BLOCK_SIZE 128 +#define SHA384_STATE_WORDS 8 + +typedef struct { + uint64_t state[SHA384_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SHA384_BLOCK_SIZE]; + int num; +} SHA384_CTX; + +void sha384_init(SHA384_CTX *ctx); +void sha384_update(SHA384_CTX *ctx, const uint8_t* data, size_t datalen); +void sha384_finish(SHA384_CTX *ctx, uint8_t dgst[SHA384_DIGEST_SIZE]); +void sha384_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA384_DIGEST_SIZE]); + + +#define SHA512_DIGEST_SIZE 64 +#define SHA512_BLOCK_SIZE 128 +#define SHA512_STATE_WORDS 8 + +typedef struct { + uint64_t state[SHA512_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SHA512_BLOCK_SIZE]; + int num; +} SHA512_CTX; + +void sha512_init(SHA512_CTX *ctx); +void sha512_update(SHA512_CTX *ctx, const uint8_t* data, size_t datalen); +void sha512_finish(SHA512_CTX *ctx, uint8_t dgst[SHA512_DIGEST_SIZE]); +void sha512_digest(const uint8_t *data, size_t datalen, + uint8_t dgst[SHA512_DIGEST_SIZE]); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sha3.h b/include/gmssl/sha3.h index ed35c5a6..0a7f80fd 100644 --- a/include/gmssl/sha3.h +++ b/include/gmssl/sha3.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,86 +7,87 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_SHA3_H -#define GMSSL_SHA3_H - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SHA3_KECCAK_P_SIZE (1600/8) - -#define SHA3_224_DIGEST_SIZE (224/8) -#define SHA3_256_DIGEST_SIZE (256/8) -#define SHA3_384_DIGEST_SIZE (384/8) -#define SHA3_512_DIGEST_SIZE (512/8) - -#define SHA3_224_CAPACITY (SHA3_224_DIGEST_SIZE * 2) -#define SHA3_256_CAPACITY (SHA3_256_DIGEST_SIZE * 2) -#define SHA3_384_CAPACITY (SHA3_384_DIGEST_SIZE * 2) -#define SHA3_512_CAPACITY (SHA3_512_DIGEST_SIZE * 2) - -#define SHA3_224_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 144 -#define SHA3_256_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 136 -#define SHA3_384_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 104 -#define SHA3_512_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 72 - - -typedef struct { - uint64_t A[5][5]; - uint8_t buf[SHA3_224_BLOCK_SIZE]; - int num; -} SHA3_224_CTX; - -void sha3_224_init(SHA3_224_CTX *ctx); -void sha3_224_update(SHA3_224_CTX *ctx, const uint8_t *data, size_t datalen); -void sha3_224_finish(SHA3_224_CTX *ctx, uint8_t dgst[SHA3_224_DIGEST_SIZE]); - -typedef struct { - uint64_t A[5][5]; - uint8_t buf[SHA3_256_BLOCK_SIZE]; - int num; -} SHA3_256_CTX; - -void sha3_256_init(SHA3_256_CTX *ctx); -void sha3_256_update(SHA3_256_CTX *ctx, const uint8_t *data, size_t datalen); -void sha3_256_finish(SHA3_256_CTX *ctx, uint8_t dgst[SHA3_256_DIGEST_SIZE]); - -typedef struct { - uint64_t A[5][5]; - uint8_t buf[SHA3_384_BLOCK_SIZE]; - int num; -} SHA3_384_CTX; - -void sha3_384_init(SHA3_384_CTX *ctx); -void sha3_384_update(SHA3_384_CTX *ctx, const uint8_t *data, size_t datalen); -void sha3_384_finish(SHA3_384_CTX *ctx, uint8_t dgst[SHA3_384_DIGEST_SIZE]); - -typedef struct { - uint64_t A[5][5]; - uint8_t buf[SHA3_512_BLOCK_SIZE]; - int num; -} SHA3_512_CTX; - -void sha3_512_init(SHA3_512_CTX *ctx); -void sha3_512_update(SHA3_512_CTX *ctx, const uint8_t *data, size_t datalen); -void sha3_512_finish(SHA3_512_CTX *ctx, uint8_t dgst[SHA3_512_DIGEST_SIZE]); - -void sha3_shake128(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out); -void sha3_shake256(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out); -void sha3_keccak_p(uint8_t state[SHA3_KECCAK_P_SIZE]); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_SHA3_H +#define GMSSL_SHA3_H + + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SHA3_KECCAK_P_SIZE (1600/8) + +#define SHA3_224_DIGEST_SIZE (224/8) +#define SHA3_256_DIGEST_SIZE (256/8) +#define SHA3_384_DIGEST_SIZE (384/8) +#define SHA3_512_DIGEST_SIZE (512/8) + +#define SHA3_224_CAPACITY (SHA3_224_DIGEST_SIZE * 2) +#define SHA3_256_CAPACITY (SHA3_256_DIGEST_SIZE * 2) +#define SHA3_384_CAPACITY (SHA3_384_DIGEST_SIZE * 2) +#define SHA3_512_CAPACITY (SHA3_512_DIGEST_SIZE * 2) + +#define SHA3_224_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 144 +#define SHA3_256_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 136 +#define SHA3_384_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 104 +#define SHA3_512_BLOCK_SIZE (SHA3_KECCAK_P_SIZE - SHA3_224_CAPACITY) // 72 + + +typedef struct { + uint64_t A[5][5]; + uint8_t buf[SHA3_224_BLOCK_SIZE]; + int num; +} SHA3_224_CTX; + +void sha3_224_init(SHA3_224_CTX *ctx); +void sha3_224_update(SHA3_224_CTX *ctx, const uint8_t *data, size_t datalen); +void sha3_224_finish(SHA3_224_CTX *ctx, uint8_t dgst[SHA3_224_DIGEST_SIZE]); + +typedef struct { + uint64_t A[5][5]; + uint8_t buf[SHA3_256_BLOCK_SIZE]; + int num; +} SHA3_256_CTX; + +void sha3_256_init(SHA3_256_CTX *ctx); +void sha3_256_update(SHA3_256_CTX *ctx, const uint8_t *data, size_t datalen); +void sha3_256_finish(SHA3_256_CTX *ctx, uint8_t dgst[SHA3_256_DIGEST_SIZE]); + +typedef struct { + uint64_t A[5][5]; + uint8_t buf[SHA3_384_BLOCK_SIZE]; + int num; +} SHA3_384_CTX; + +void sha3_384_init(SHA3_384_CTX *ctx); +void sha3_384_update(SHA3_384_CTX *ctx, const uint8_t *data, size_t datalen); +void sha3_384_finish(SHA3_384_CTX *ctx, uint8_t dgst[SHA3_384_DIGEST_SIZE]); + +typedef struct { + uint64_t A[5][5]; + uint8_t buf[SHA3_512_BLOCK_SIZE]; + int num; +} SHA3_512_CTX; + +void sha3_512_init(SHA3_512_CTX *ctx); +void sha3_512_update(SHA3_512_CTX *ctx, const uint8_t *data, size_t datalen); +void sha3_512_finish(SHA3_512_CTX *ctx, uint8_t dgst[SHA3_512_DIGEST_SIZE]); + +void sha3_shake128(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out); +void sha3_shake256(const uint8_t *in, size_t *inlen, size_t outlen, uint8_t *out); +void sha3_keccak_p(uint8_t state[SHA3_KECCAK_P_SIZE]); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/skf.h b/include/gmssl/skf.h index b855b6f7..9f89be0d 100644 --- a/include/gmssl/skf.h +++ b/include/gmssl/skf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,110 +7,111 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SKF_H -#define GMSSL_SKF_H - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -SKF Public API - - skf_load_library - skf_unload_library - skf_list_devices - skf_print_device_info - - SKF_DEVICE - skf_open_device - skf_close_deivce - skf_set_label - skf_change_authkey - skf_list_apps - skf_create_app - skf_delete_app - skf_change_app_admin_pin - skf_change_app_user_pin - skf_unblock_user_pin - skf_list_objects - skf_import_object - skf_export_object - skf_delete_object - skf_list_containers - skf_create_container - skf_delete_container - skf_import_sign_cert - skf_export_sign_cert - skf_rand_bytes - skf_load_sign_key - - SKF_KEY - skf_sign - skf_release_key -*/ - -typedef struct { - void *handle; - char manufacturer[65]; - char issuer[65]; - char label[33]; - char serial[33]; - uint8_t hardware_version[2]; - uint8_t firmware_version[2]; -} SKF_DEVICE; - -typedef struct { - SM2_KEY public_key; - void *app_handle; - char app_name[65]; - void *container_handle; - char container_name[65]; -} SKF_KEY; - -int skf_load_library(const char *so_path, const char *vendor); -void skf_unload_library(void); - -int skf_list_devices(FILE *fp, int fmt, int ind, const char *label); -int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname); -int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]); -int skf_set_label(SKF_DEVICE *dev, const char *label); -int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]); -int skf_close_device(SKF_DEVICE *dev); - -int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp); -int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin); -int skf_delete_app(SKF_DEVICE *dev, const char *appname); -int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); -int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); -int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin); - -int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); -int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, const uint8_t *data, size_t datalen); -int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, uint8_t *out, size_t *outlen); -int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname); - -int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); -int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); -int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); -int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, const uint8_t *cert, size_t certlen); -int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, uint8_t *cert, size_t *certlen); - -int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len); -int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key); -int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); -int skf_release_key(SKF_KEY *key); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_SKF_H +#define GMSSL_SKF_H + + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +SKF Public API + + skf_load_library + skf_unload_library + skf_list_devices + skf_print_device_info + + SKF_DEVICE + skf_open_device + skf_close_deivce + skf_set_label + skf_change_authkey + skf_list_apps + skf_create_app + skf_delete_app + skf_change_app_admin_pin + skf_change_app_user_pin + skf_unblock_user_pin + skf_list_objects + skf_import_object + skf_export_object + skf_delete_object + skf_list_containers + skf_create_container + skf_delete_container + skf_import_sign_cert + skf_export_sign_cert + skf_rand_bytes + skf_load_sign_key + + SKF_KEY + skf_sign + skf_release_key +*/ + +typedef struct { + void *handle; + char manufacturer[65]; + char issuer[65]; + char label[33]; + char serial[33]; + uint8_t hardware_version[2]; + uint8_t firmware_version[2]; +} SKF_DEVICE; + +typedef struct { + SM2_KEY public_key; + void *app_handle; + char app_name[65]; + void *container_handle; + char container_name[65]; +} SKF_KEY; + +int skf_load_library(const char *so_path, const char *vendor); +void skf_unload_library(void); + +int skf_list_devices(FILE *fp, int fmt, int ind, const char *label); +int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname); +int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]); +int skf_set_label(SKF_DEVICE *dev, const char *label); +int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]); +int skf_close_device(SKF_DEVICE *dev); + +int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp); +int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin); +int skf_delete_app(SKF_DEVICE *dev, const char *appname); +int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); +int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); +int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin); + +int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); +int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, const uint8_t *data, size_t datalen); +int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, uint8_t *out, size_t *outlen); +int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname); + +int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); +int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); +int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); +int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, const uint8_t *cert, size_t certlen); +int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, uint8_t *cert, size_t *certlen); + +int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len); +int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key); +int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); +int skf_release_key(SKF_KEY *key); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index decfeab9..7f39343d 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,368 +7,369 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_SM2_H -#define GMSSL_SM2_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -SM2 Public API - - SM2_DEFAULT_ID - SM2_MAX_ID_LENGTH - SM2_MAX_SIGNATURE_SIZE - SM2_MAX_PLAINTEXT_SIZE - SM2_MAX_CIPHERTEXT_SIZE - - SM2_KEY - sm2_key_generate - sm2_private_key_info_encrypt_to_der - sm2_private_key_info_decrypt_from_der - sm2_private_key_info_encrypt_to_pem - sm2_private_key_info_decrypt_from_pem - sm2_public_key_info_to_der - sm2_public_key_info_from_der - sm2_public_key_info_to_pem - sm2_public_key_info_from_pem - - sm2_sign - sm2_verify - sm2_encrypt - sm2_decrypt - sm2_ecdh - - SM2_SIGN_CTX - sm2_sign_init - sm2_sign_update - sm2_sign_finish - sm2_verify_init - sm2_verify_update - sm2_verify_finish -*/ - -typedef uint64_t SM2_BN[8]; - -int sm2_bn_is_zero(const SM2_BN a); -int sm2_bn_is_one(const SM2_BN a); -int sm2_bn_is_odd(const SM2_BN a); -int sm2_bn_cmp(const SM2_BN a, const SM2_BN b); -int sm2_bn_from_hex(SM2_BN r, const char hex[64]); -int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen); -int sm2_bn_equ_hex(const SM2_BN a, const char *hex); -int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a); - -void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]); -void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]); -void sm2_bn_to_hex(const SM2_BN a, char hex[64]); -void sm2_bn_to_bits(const SM2_BN a, char bits[256]); -void sm2_bn_set_word(SM2_BN r, uint32_t a); -void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b); -void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b); -void sm2_bn_rand_range(SM2_BN r, const SM2_BN range); // 这个函数需要修改一下,从外部引入随机数 - -#define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN)) -#define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN)) -#define sm2_bn_set_one(r) sm2_bn_set_word((r),1) -#define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN)) -#define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN)) - - -// GF(p) -typedef SM2_BN SM2_Fp; - -void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); -void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); -void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); -void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e); -void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a); -void sm2_fp_tri(SM2_Fp r, const SM2_Fp a); -void sm2_fp_div2(SM2_Fp r, const SM2_Fp a); -void sm2_fp_neg(SM2_Fp r, const SM2_Fp a); -void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a); -void sm2_fp_inv(SM2_Fp r, const SM2_Fp a); -void sm2_fp_rand(SM2_Fp r); // 外部提供随机性,如果满足条件就输出,如果不满足条件就哈希一下再输出 - -#define sm2_fp_init(r) sm2_bn_init(r) -#define sm2_fp_set_zero(r) sm2_bn_set_zero(r) -#define sm2_fp_set_one(r) sm2_bn_set_one(r) -#define sm2_fp_copy(r,a) sm2_bn_copy(r,a) -#define sm2_fp_clean(r) sm2_bn_clean(r) - -// GF(n) -typedef SM2_BN SM2_Fn; - -void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); -void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); -void sm2_fn_mul(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); -void sm2_fn_exp(SM2_Fn r, const SM2_Fn a, const SM2_Fn e); -void sm2_fn_neg(SM2_Fn r, const SM2_Fn a); -void sm2_fn_sqr(SM2_Fn r, const SM2_Fn a); -void sm2_fn_inv(SM2_Fn r, const SM2_Fn a); -void sm2_fn_rand(SM2_Fn r); - -#define sm2_fn_init(r) sm2_bn_init(r) -#define sm2_fn_set_zero(r) sm2_bn_set_zero(r) -#define sm2_fn_set_one(r) sm2_bn_set_one(r) -#define sm2_fn_copy(r,a) sm2_bn_copy(r,a) -#define sm2_fn_clean(r) sm2_bn_clean(r) - - -typedef struct { - SM2_BN X; - SM2_BN Y; - SM2_BN Z; -} SM2_JACOBIAN_POINT; - -void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R); -void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); // 应该返回错误 -void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y); -void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); -void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); -void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q); -void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q); -void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P); -void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]); -void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]); -void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k); -void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); // 应该返回错误 -void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // 应该返回错误 - -int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P); -int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P); -int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]); -int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P); - -#define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R) -#define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT)) - - - -/* -SM2 Public API - -SM2接口有两个层次,基本的和ASN.1/PKI的 -基本的接口不依赖ASN.1编码,可以直接将结构体的内存输出(endian一致即可) -基本的接口也不进行输入的格式检查,调用方应保证输入不为空 -*/ - - -// 这里应该用#define 给出常量的值 -extern const SM2_BN SM2_P; -//extern const SM2_BN SM2_A; -extern const SM2_BN SM2_B; -extern const SM2_BN SM2_N; -extern const SM2_BN SM2_ONE; -extern const SM2_BN SM2_TWO; -extern const SM2_BN SM2_THREE; -extern const SM2_BN SM2_U_PLUS_ONE; -extern const SM2_JACOBIAN_POINT *SM2_G; // 应该同时给出Affine的 - - -typedef struct { - uint8_t x[32]; - uint8_t y[32]; -} SM2_POINT; - -void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]); -void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]); -int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen); - - -int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y); -int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]); -int sm2_point_is_on_curve(const SM2_POINT *P); -int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P); -int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]); -int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G - -/* -RFC 5480 Elliptic Curve Cryptography Subject Public Key Information -ECPoint ::= OCTET STRING -*/ -#define SM2_POINT_MAX_SIZE (2 + 65) -int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen); -int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen); -int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P); - - -typedef struct { - SM2_POINT public_key; - uint8_t private_key[32]; -} SM2_KEY; - - -int sm2_key_generate(SM2_KEY *key); -int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // 自动生成公钥 -int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // 自动清空私钥,不要和set_private_key同时用 -int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key); - -int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key); -//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // 这个函数的逻辑不清楚 -int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]); -int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); // 和private_key_print参数不一致 - -/* -from RFC 5915 - -ECPrivateKey ::= SEQUENCE { - version INTEGER, -- value MUST be (1) - privateKey OCTET STRING, -- big endian encoding of integer 这里不是以INTEGER编码的,因此长度固定 - parameters [0] EXPLICIT ECParameters OPTIONAL, - -- ONLY namedCurve OID is permitted, by RFC 5480 - -- MUST always include this field, by RFC 5915 - publicKey [1] EXPLICIT BIT STRING OPTIONAL -- compressed_point - -- SHOULD always include this field, by RFC 5915 } - -ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER } -*/ -#define SM2_PRIVATE_KEY_DEFAULT_SIZE 120 // generated -#define SM2_PRIVATE_KEY_BUF_SIZE 512 // MUST >= SM2_PRIVATE_KEY_DEFAULT_SIZE - -int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); -int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen); -int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -//int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp); -//int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp); - -/* -AlgorithmIdentifier ::= { - algorithm OBJECT IDENTIFIER { id-ecPublicKey }, - parameters OBJECT IDENTIFIER { id-sm2 } } -*/ -int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen); -int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen); - -/* -X.509 SubjectPublicKeyInfo from RFC 5280 - -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING -- uncompressed octets of ECPoint } -*/ -int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen); -int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen); -int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp); -int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp); - -/* -PKCS #8 PrivateKeyInfo from RFC 5208 - -PrivateKeyInfo ::= SEQUENCE { - version Version { v1(0) }, - privateKeyAlgorithm AlgorithmIdentifier, - privateKey OCTET STRING, -- DER-encoding of ECPrivateKey - attributes [0] IMPLICIT SET OF Attribute OPTIONAL } -*/ -enum { - PKCS8_private_key_info_version = 0, -}; - -int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); -int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen); -int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -//int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp); -//int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp); - -/* -EncryptedPrivateKeyInfo ::= SEQUENCE { - encryptionAlgorithm EncryptionAlgorithmIdentifier, -- id-PBES2 - encryptedData OCTET STRING } -*/ -int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key, - const char *pass, uint8_t **out, size_t *outlen); -int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrs_len, - const char *pass, const uint8_t **in, size_t *inlen); -int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp); -int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp); - - -typedef struct { - uint8_t r[32]; - uint8_t s[32]; -} SM2_SIGNATURE; - -int sm2_do_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], SM2_SIGNATURE *sig); -int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); -int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); - -#define SM2_MIN_SIGNATURE_SIZE 8 -#define SM2_MAX_SIGNATURE_SIZE 72 -int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen); -int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen); -int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); -int sm2_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); -int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); -int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen); - - -#define SM2_DEFAULT_ID "1234567812345678" -#define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) // LENGTH for string and SIZE for bytes -#define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8) -#define SM2_MAX_ID_BITS 65535 -#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8) - -int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen); - - -typedef struct { - SM3_CTX sm3_ctx; - SM2_KEY key; -} SM2_SIGN_CTX; - -int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); -int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); - -int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); -int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen); - -/* -SM2Cipher ::= SEQUENCE { - XCoordinate INTEGER, - YCoordinate INTEGER, - HASH OCTET STRING SIZE(32), - CipherText OCTET STRING } -*/ -#define SM2_MIN_PLAINTEXT_SIZE 1 // re-compute SM2_MIN_CIPHERTEXT_SIZE when modify -#define SM2_MAX_PLAINTEXT_SIZE 255 // re-compute SM2_MAX_CIPHERTEXT_SIZE when modify - -typedef struct { - SM2_POINT point; - uint8_t hash[32]; - uint8_t ciphertext_size; - uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE]; -} SM2_CIPHERTEXT; - -int sm2_do_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); -int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); -int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen); - -#define SM2_MIN_CIPHERTEXT_SIZE 45 // dependes on SM2_MIN_PLAINTEXT_SIZE -#define SM2_MAX_CIPHERTEXT_SIZE 366 // depends on SM2_MAX_PLAINTEXT_SIZE -int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen); -int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen); -int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); -int sm2_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); - - -int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out); - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_SM2_H +#define GMSSL_SM2_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +SM2 Public API + + SM2_DEFAULT_ID + SM2_MAX_ID_LENGTH + SM2_MAX_SIGNATURE_SIZE + SM2_MAX_PLAINTEXT_SIZE + SM2_MAX_CIPHERTEXT_SIZE + + SM2_KEY + sm2_key_generate + sm2_private_key_info_encrypt_to_der + sm2_private_key_info_decrypt_from_der + sm2_private_key_info_encrypt_to_pem + sm2_private_key_info_decrypt_from_pem + sm2_public_key_info_to_der + sm2_public_key_info_from_der + sm2_public_key_info_to_pem + sm2_public_key_info_from_pem + + sm2_sign + sm2_verify + sm2_encrypt + sm2_decrypt + sm2_ecdh + + SM2_SIGN_CTX + sm2_sign_init + sm2_sign_update + sm2_sign_finish + sm2_verify_init + sm2_verify_update + sm2_verify_finish +*/ + +typedef uint64_t SM2_BN[8]; + +int sm2_bn_is_zero(const SM2_BN a); +int sm2_bn_is_one(const SM2_BN a); +int sm2_bn_is_odd(const SM2_BN a); +int sm2_bn_cmp(const SM2_BN a, const SM2_BN b); +int sm2_bn_from_hex(SM2_BN r, const char hex[64]); +int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen); +int sm2_bn_equ_hex(const SM2_BN a, const char *hex); +int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a); + +void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]); +void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]); +void sm2_bn_to_hex(const SM2_BN a, char hex[64]); +void sm2_bn_to_bits(const SM2_BN a, char bits[256]); +void sm2_bn_set_word(SM2_BN r, uint32_t a); +void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b); +void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b); +void sm2_bn_rand_range(SM2_BN r, const SM2_BN range); // 这个函数需要修改一下,从外部引入随机数 + +#define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN)) +#define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN)) +#define sm2_bn_set_one(r) sm2_bn_set_word((r),1) +#define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN)) +#define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN)) + + +// GF(p) +typedef SM2_BN SM2_Fp; + +void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); +void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); +void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b); +void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e); +void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a); +void sm2_fp_tri(SM2_Fp r, const SM2_Fp a); +void sm2_fp_div2(SM2_Fp r, const SM2_Fp a); +void sm2_fp_neg(SM2_Fp r, const SM2_Fp a); +void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a); +void sm2_fp_inv(SM2_Fp r, const SM2_Fp a); +void sm2_fp_rand(SM2_Fp r); // 外部提供随机性,如果满足条件就输出,如果不满足条件就哈希一下再输出 + +#define sm2_fp_init(r) sm2_bn_init(r) +#define sm2_fp_set_zero(r) sm2_bn_set_zero(r) +#define sm2_fp_set_one(r) sm2_bn_set_one(r) +#define sm2_fp_copy(r,a) sm2_bn_copy(r,a) +#define sm2_fp_clean(r) sm2_bn_clean(r) + +// GF(n) +typedef SM2_BN SM2_Fn; + +void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); +void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); +void sm2_fn_mul(SM2_Fn r, const SM2_Fn a, const SM2_Fn b); +void sm2_fn_exp(SM2_Fn r, const SM2_Fn a, const SM2_Fn e); +void sm2_fn_neg(SM2_Fn r, const SM2_Fn a); +void sm2_fn_sqr(SM2_Fn r, const SM2_Fn a); +void sm2_fn_inv(SM2_Fn r, const SM2_Fn a); +void sm2_fn_rand(SM2_Fn r); + +#define sm2_fn_init(r) sm2_bn_init(r) +#define sm2_fn_set_zero(r) sm2_bn_set_zero(r) +#define sm2_fn_set_one(r) sm2_bn_set_one(r) +#define sm2_fn_copy(r,a) sm2_bn_copy(r,a) +#define sm2_fn_clean(r) sm2_bn_clean(r) + + +typedef struct { + SM2_BN X; + SM2_BN Y; + SM2_BN Z; +} SM2_JACOBIAN_POINT; + +void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R); +void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); // 应该返回错误 +void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y); +void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); +void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P); +void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q); +void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q); +void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P); +void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]); +void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]); +void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k); +void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); // 应该返回错误 +void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // 应该返回错误 + +int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P); +int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P); +int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]); +int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P); + +#define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R) +#define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT)) + + + +/* +SM2 Public API + +SM2接口有两个层次,基本的和ASN.1/PKI的 +基本的接口不依赖ASN.1编码,可以直接将结构体的内存输出(endian一致即可) +基本的接口也不进行输入的格式检查,调用方应保证输入不为空 +*/ + + +// 这里应该用#define 给出常量的值 +extern const SM2_BN SM2_P; +//extern const SM2_BN SM2_A; +extern const SM2_BN SM2_B; +extern const SM2_BN SM2_N; +extern const SM2_BN SM2_ONE; +extern const SM2_BN SM2_TWO; +extern const SM2_BN SM2_THREE; +extern const SM2_BN SM2_U_PLUS_ONE; +extern const SM2_JACOBIAN_POINT *SM2_G; // 应该同时给出Affine的 + + +typedef struct { + uint8_t x[32]; + uint8_t y[32]; +} SM2_POINT; + +void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]); +void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]); +int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen); + + +int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y); +int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]); +int sm2_point_is_on_curve(const SM2_POINT *P); +int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P); +int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]); +int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G + +/* +RFC 5480 Elliptic Curve Cryptography Subject Public Key Information +ECPoint ::= OCTET STRING +*/ +#define SM2_POINT_MAX_SIZE (2 + 65) +int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen); +int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen); +int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P); + + +typedef struct { + SM2_POINT public_key; + uint8_t private_key[32]; +} SM2_KEY; + + +int sm2_key_generate(SM2_KEY *key); +int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // 自动生成公钥 +int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // 自动清空私钥,不要和set_private_key同时用 +int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key); + +int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key); +//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // 这个函数的逻辑不清楚 +int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]); +int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); // 和private_key_print参数不一致 + +/* +from RFC 5915 + +ECPrivateKey ::= SEQUENCE { + version INTEGER, -- value MUST be (1) + privateKey OCTET STRING, -- big endian encoding of integer 这里不是以INTEGER编码的,因此长度固定 + parameters [0] EXPLICIT ECParameters OPTIONAL, + -- ONLY namedCurve OID is permitted, by RFC 5480 + -- MUST always include this field, by RFC 5915 + publicKey [1] EXPLICIT BIT STRING OPTIONAL -- compressed_point + -- SHOULD always include this field, by RFC 5915 } + +ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER } +*/ +#define SM2_PRIVATE_KEY_DEFAULT_SIZE 120 // generated +#define SM2_PRIVATE_KEY_BUF_SIZE 512 // MUST >= SM2_PRIVATE_KEY_DEFAULT_SIZE + +int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); +int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen); +int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +//int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp); +//int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp); + +/* +AlgorithmIdentifier ::= { + algorithm OBJECT IDENTIFIER { id-ecPublicKey }, + parameters OBJECT IDENTIFIER { id-sm2 } } +*/ +int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen); +int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen); + +/* +X.509 SubjectPublicKeyInfo from RFC 5280 + +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING -- uncompressed octets of ECPoint } +*/ +int sm2_public_key_info_to_der(const SM2_KEY *a, uint8_t **out, size_t *outlen); +int sm2_public_key_info_from_der(SM2_KEY *a, const uint8_t **in, size_t *inlen); +int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp); +int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp); + +/* +PKCS #8 PrivateKeyInfo from RFC 5208 + +PrivateKeyInfo ::= SEQUENCE { + version Version { v1(0) }, + privateKeyAlgorithm AlgorithmIdentifier, + privateKey OCTET STRING, -- DER-encoding of ECPrivateKey + attributes [0] IMPLICIT SET OF Attribute OPTIONAL } +*/ +enum { + PKCS8_private_key_info_version = 0, +}; + +int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen); +int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen); +int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +//int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp); +//int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp); + +/* +EncryptedPrivateKeyInfo ::= SEQUENCE { + encryptionAlgorithm EncryptionAlgorithmIdentifier, -- id-PBES2 + encryptedData OCTET STRING } +*/ +int sm2_private_key_info_encrypt_to_der(const SM2_KEY *key, + const char *pass, uint8_t **out, size_t *outlen); +int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrs_len, + const char *pass, const uint8_t **in, size_t *inlen); +int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp); +int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp); + + +typedef struct { + uint8_t r[32]; + uint8_t s[32]; +} SM2_SIGNATURE; + +int sm2_do_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], SM2_SIGNATURE *sig); +int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); +int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); + +#define SM2_MIN_SIGNATURE_SIZE 8 +#define SM2_MAX_SIGNATURE_SIZE 72 +int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen); +int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen); +int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); +int sm2_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); +int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); +int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen); + + +#define SM2_DEFAULT_ID "1234567812345678" +#define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) // LENGTH for string and SIZE for bytes +#define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8) +#define SM2_MAX_ID_BITS 65535 +#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8) + +int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen); + + +typedef struct { + SM3_CTX sm3_ctx; + SM2_KEY key; +} SM2_SIGN_CTX; + +int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); +int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); + +int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); +int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen); + +/* +SM2Cipher ::= SEQUENCE { + XCoordinate INTEGER, + YCoordinate INTEGER, + HASH OCTET STRING SIZE(32), + CipherText OCTET STRING } +*/ +#define SM2_MIN_PLAINTEXT_SIZE 1 // re-compute SM2_MIN_CIPHERTEXT_SIZE when modify +#define SM2_MAX_PLAINTEXT_SIZE 255 // re-compute SM2_MAX_CIPHERTEXT_SIZE when modify + +typedef struct { + SM2_POINT point; + uint8_t hash[32]; + uint8_t ciphertext_size; + uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE]; +} SM2_CIPHERTEXT; + +int sm2_do_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); +int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out); +int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen); + +#define SM2_MIN_CIPHERTEXT_SIZE 45 // dependes on SM2_MIN_PLAINTEXT_SIZE +#define SM2_MAX_CIPHERTEXT_SIZE 366 // depends on SM2_MAX_PLAINTEXT_SIZE +int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen); +int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen); +int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); +int sm2_encrypt_ex(const SM2_KEY *key, int flags, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); + + +int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm3.h b/include/gmssl/sm3.h index 82d62bb4..e9d9dd79 100644 --- a/include/gmssl/sm3.h +++ b/include/gmssl/sm3.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,82 +7,83 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SM3_H -#define GMSSL_SM3_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -SM3 Public API - - SM3_DIGEST_SIZE - SM3_HMAC_SIZE - - SM3_CTX - sm3_init - sm3_update - sm3_finish - - SM3_HMAC_CTX - sm3_hmac_init - sm3_hmac_update - sm3_hmac_finish - - sm3_digest - sm3_hmac -*/ - -#define SM3_IS_BIG_ENDIAN 1 - -#define SM3_DIGEST_SIZE 32 -#define SM3_BLOCK_SIZE 64 -#define SM3_STATE_WORDS 8 -#define SM3_HMAC_SIZE (SM3_DIGEST_SIZE) - - -typedef struct { - uint32_t digest[SM3_STATE_WORDS]; - uint64_t nblocks; - uint8_t block[SM3_BLOCK_SIZE]; - size_t num; -} SM3_CTX; - -void sm3_init(SM3_CTX *ctx); -void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t datalen); -void sm3_finish(SM3_CTX *ctx, uint8_t dgst[SM3_DIGEST_SIZE]); -void sm3_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SM3_DIGEST_SIZE]); - - -typedef struct { - SM3_CTX sm3_ctx; - unsigned char key[SM3_BLOCK_SIZE]; -} SM3_HMAC_CTX; - -void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t keylen); -void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t datalen); -void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE]); -void sm3_hmac(const uint8_t *key, size_t keylen, - const uint8_t *data, size_t datalen, - uint8_t mac[SM3_HMAC_SIZE]); - - -typedef struct { - SM3_CTX sm3_ctx; - size_t outlen; -} SM3_KDF_CTX; - -void sm3_kdf_init(SM3_KDF_CTX *ctx, size_t outlen); -void sm3_kdf_update(SM3_KDF_CTX *ctx, const uint8_t *data, size_t datalen); -void sm3_kdf_finish(SM3_KDF_CTX *ctx, uint8_t *out); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_SM3_H +#define GMSSL_SM3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +SM3 Public API + + SM3_DIGEST_SIZE + SM3_HMAC_SIZE + + SM3_CTX + sm3_init + sm3_update + sm3_finish + + SM3_HMAC_CTX + sm3_hmac_init + sm3_hmac_update + sm3_hmac_finish + + sm3_digest + sm3_hmac +*/ + +#define SM3_IS_BIG_ENDIAN 1 + +#define SM3_DIGEST_SIZE 32 +#define SM3_BLOCK_SIZE 64 +#define SM3_STATE_WORDS 8 +#define SM3_HMAC_SIZE (SM3_DIGEST_SIZE) + + +typedef struct { + uint32_t digest[SM3_STATE_WORDS]; + uint64_t nblocks; + uint8_t block[SM3_BLOCK_SIZE]; + size_t num; +} SM3_CTX; + +void sm3_init(SM3_CTX *ctx); +void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t datalen); +void sm3_finish(SM3_CTX *ctx, uint8_t dgst[SM3_DIGEST_SIZE]); +void sm3_digest(const uint8_t *data, size_t datalen, uint8_t dgst[SM3_DIGEST_SIZE]); + + +typedef struct { + SM3_CTX sm3_ctx; + unsigned char key[SM3_BLOCK_SIZE]; +} SM3_HMAC_CTX; + +void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t keylen); +void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t datalen); +void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE]); +void sm3_hmac(const uint8_t *key, size_t keylen, + const uint8_t *data, size_t datalen, + uint8_t mac[SM3_HMAC_SIZE]); + + +typedef struct { + SM3_CTX sm3_ctx; + size_t outlen; +} SM3_KDF_CTX; + +void sm3_kdf_init(SM3_KDF_CTX *ctx, size_t outlen); +void sm3_kdf_update(SM3_KDF_CTX *ctx, const uint8_t *data, size_t datalen); +void sm3_kdf_finish(SM3_KDF_CTX *ctx, uint8_t *out); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index 24f41e42..8ccd11b6 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,125 +7,126 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SM4_H -#define GMSSL_SM4_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -SM4 Public API - - SM4_KEY_SIZE - SM4_BLOCK_SIZE - - SM4_CBC_CTX - sm4_cbc_encrypt_init - sm4_cbc_encrypt_update - sm4_cbc_encrypt_finish - sm4_cbc_decrypt_init - sm4_cbc_decrypt_update - sm4_cbc_decrypt_finish - - SM4_CTR_CTX - sm4_ctr_encrypt_init - sm4_ctr_encrypt_update - sm4_ctr_encrypt_finish - sm4_ctr_decrypt_init - sm4_ctr_decrypt_update - sm4_ctr_decrypt_finish -*/ - -#define SM4_KEY_SIZE (16) -#define SM4_BLOCK_SIZE (16) -#define SM4_NUM_ROUNDS (32) - - -typedef struct { - uint32_t rk[SM4_NUM_ROUNDS]; -} SM4_KEY; - -void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); -void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); -void sm4_encrypt(const SM4_KEY *key, const uint8_t in[SM4_BLOCK_SIZE], uint8_t out[SM4_BLOCK_SIZE]); -#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out) - - -void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], - const uint8_t *in, size_t nblocks, uint8_t *out); -void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], - const uint8_t *in, size_t nblocks, uint8_t *out); -int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); - - -void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE], - const uint8_t *in, size_t inlen, uint8_t *out); -#define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out) - - -#define SM4_GCM_IV_MIN_SIZE 1 -#define SM4_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) -#define SM4_GCM_IV_DEFAULT_BITS 96 -#define SM4_GCM_IV_DEFAULT_SIZE 12 - -#define SM4_GCM_MIN_AAD_SIZE 0 -#define SM4_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) - -#define SM4_GCM_MIN_PLAINTEXT_SIZE 0 -#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) - -#define SM4_GCM_MAX_TAG_SIZE 16 - -int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag); -int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out); - - -typedef struct { - SM4_KEY sm4_key; - uint8_t iv[SM4_BLOCK_SIZE]; - uint8_t block[SM4_BLOCK_SIZE]; - size_t block_nbytes; -} SM4_CBC_CTX; - -int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); -int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); - -int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); -int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); - - -typedef struct { - SM4_KEY sm4_key; - uint8_t ctr[SM4_BLOCK_SIZE]; - uint8_t block[SM4_BLOCK_SIZE]; - size_t block_nbytes; -} SM4_CTR_CTX; - -int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]); -int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen); - -#define sm4_ctr_decrypt_init(ctx,key,ctr) sm4_ctr_encrypt_init(ctx,key,ctr) -#define sm4_ctr_decrypt_update(ctx,in,inlen,out,outlen) sm4_ctr_encrypt_update(ctx,in,inlen,out,outlen) -#define sm4_ctr_decrypt_finish(ctx,out,outlen) sm4_ctr_encrypt_finish(ctx,out,outlen) - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_SM4_H +#define GMSSL_SM4_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +SM4 Public API + + SM4_KEY_SIZE + SM4_BLOCK_SIZE + + SM4_CBC_CTX + sm4_cbc_encrypt_init + sm4_cbc_encrypt_update + sm4_cbc_encrypt_finish + sm4_cbc_decrypt_init + sm4_cbc_decrypt_update + sm4_cbc_decrypt_finish + + SM4_CTR_CTX + sm4_ctr_encrypt_init + sm4_ctr_encrypt_update + sm4_ctr_encrypt_finish + sm4_ctr_decrypt_init + sm4_ctr_decrypt_update + sm4_ctr_decrypt_finish +*/ + +#define SM4_KEY_SIZE (16) +#define SM4_BLOCK_SIZE (16) +#define SM4_NUM_ROUNDS (32) + + +typedef struct { + uint32_t rk[SM4_NUM_ROUNDS]; +} SM4_KEY; + +void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); +void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); +void sm4_encrypt(const SM4_KEY *key, const uint8_t in[SM4_BLOCK_SIZE], uint8_t out[SM4_BLOCK_SIZE]); +#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out) + + +void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t nblocks, uint8_t *out); +int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); + + +void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE], + const uint8_t *in, size_t inlen, uint8_t *out); +#define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out) + + +#define SM4_GCM_IV_MIN_SIZE 1 +#define SM4_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) +#define SM4_GCM_IV_DEFAULT_BITS 96 +#define SM4_GCM_IV_DEFAULT_SIZE 12 + +#define SM4_GCM_MIN_AAD_SIZE 0 +#define SM4_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) + +#define SM4_GCM_MIN_PLAINTEXT_SIZE 0 +#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) + +#define SM4_GCM_MAX_TAG_SIZE 16 + +int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag); +int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out); + + +typedef struct { + SM4_KEY sm4_key; + uint8_t iv[SM4_BLOCK_SIZE]; + uint8_t block[SM4_BLOCK_SIZE]; + size_t block_nbytes; +} SM4_CBC_CTX; + +int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); +int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); + +int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); +int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); + + +typedef struct { + SM4_KEY sm4_key; + uint8_t ctr[SM4_BLOCK_SIZE]; + uint8_t block[SM4_BLOCK_SIZE]; + size_t block_nbytes; +} SM4_CTR_CTX; + +int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]); +int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen); + +#define sm4_ctr_decrypt_init(ctx,key,ctr) sm4_ctr_encrypt_init(ctx,key,ctr) +#define sm4_ctr_decrypt_update(ctx,in,inlen,out,outlen) sm4_ctr_encrypt_update(ctx,in,inlen,out,outlen) +#define sm4_ctr_decrypt_finish(ctx,out,outlen) sm4_ctr_encrypt_finish(ctx,out,outlen) + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm9.h b/include/gmssl/sm9.h index fd5ac151..6bee3a2e 100644 --- a/include/gmssl/sm9.h +++ b/include/gmssl/sm9.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,563 +7,564 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -#ifndef GMSSL_SM9_H -#define GMSSL_SM9_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* -SM9 Public API - - SM9_SIGNATURE_SIZE - SM9_MAX_PLAINTEXT_SIZE - SM9_MAX_CIPHERTEXT_SIZE - - SM9_SIGN_MASTER_KEY - sm9_sign_master_key_generate - sm9_sign_master_key_extract_key - sm9_sign_master_key_info_encrypt_to_der - sm9_sign_master_key_info_decrypt_from_der - sm9_sign_master_key_info_encrypt_to_pem - sm9_sign_master_key_info_decrypt_from_pem - sm9_sign_master_public_key_to_der - sm9_sign_master_public_key_from_der - sm9_sign_master_public_key_to_pem - sm9_sign_master_public_key_from_pem - - SM9_SIGN_KEY - sm9_sign_key_info_encrypt_to_der - sm9_sign_key_info_decrypt_from_der - sm9_sign_key_info_encrypt_to_pem - sm9_sign_key_info_decrypt_from_pem - - SM9_SIGN_CTX - sm9_sign_init - sm9_sign_update - sm9_sign_finish - sm9_verify_init - sm9_verify_update - sm9_verify_finish - - SM9_ENC_MASTER_KEY - sm9_enc_master_key_generate - sm9_enc_master_key_extract_key - sm9_enc_master_key_info_encrypt_to_der - sm9_enc_master_key_info_decrypt_from_der - sm9_enc_master_key_info_encrypt_to_pem - sm9_enc_master_key_info_decrypt_from_pem - sm9_enc_master_public_key_to_der - sm9_enc_master_public_key_from_der - sm9_enc_master_public_key_to_pem - sm9_enc_master_public_key_from_pem - - SM9_ENC_KEY - sm9_enc_key_info_encrypt_to_der - sm9_enc_key_info_decrypt_from_der - sm9_enc_key_info_encrypt_to_pem - sm9_enc_key_info_decrypt_from_pem - - sm9_encrypt - sm9_decrypt -*/ - -#define SM9_HEX_SEP '\n' - -typedef uint64_t sm9_bn_t[8]; -extern const sm9_bn_t SM9_ZERO; -extern const sm9_bn_t SM9_ONE; -extern const sm9_bn_t SM9_P; -extern const sm9_bn_t SM9_N; - -#define sm9_bn_init(r) sm9_bn_set_zero(r) -#define sm9_bn_clean(r) sm9_bn_set_zero(r) -#define sm9_bn_set_zero(r) sm9_bn_copy((r), SM9_ZERO) -#define sm9_bn_set_one(r) sm9_bn_copy((r), SM9_ONE) -#define sm9_bn_is_zero(a) (sm9_bn_cmp((a), SM9_ZERO) == 0) -#define sm9_bn_is_one(a) (sm9_bn_cmp((a), SM9_ONE) == 0) - -void sm9_bn_set_word(sm9_bn_t r, uint32_t a); -void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a); -int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range); -int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b); -int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b); -void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b); -void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b); -void sm9_bn_to_bits(const sm9_bn_t a, char bits[256]); -void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32]); -void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32]); -void sm9_bn_to_hex(const sm9_bn_t a, char hex[64]); -int sm9_bn_from_hex(sm9_bn_t r, const char hex[64]); -int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a); -void sm9_print_bn(const char *prefix, const sm9_bn_t a); // 标准打印格式 - - -typedef sm9_bn_t sm9_fp_t; - -#define sm9_fp_init(r) sm9_fp_set_zero(r) -#define sm9_fp_clean(f) sm9_fp_set_zero(r) -#define sm9_fp_set_zero(r) sm9_bn_set_zero(r) -#define sm9_fp_set_one(r) sm9_bn_set_one(r) -#define sm9_fp_copy(r,a) sm9_bn_copy((r),(a)) -#define sm9_fp_rand(r) sm9_bn_rand_range((r), SM9_P) -#define sm9_fp_is_zero(a) sm9_bn_is_zero(a) -#define sm9_fp_is_one(a) sm9_bn_is_one(a) -#define sm9_fp_equ(a,b) sm9_bn_equ((a),(b)) -#define sm9_fp_to_bytes(a,buf) sm9_bn_to_bytes((a),(buf)) -#define sm9_fp_to_hex(a,s) sm9_bn_to_hex((a),(s)) -#define sm9_fp_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a) - -void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); -void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); -void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a); -void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a); -void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a); -void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); -void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a); -void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e); -void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a); -void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a); -int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32]); -int sm9_fp_from_hex(sm9_fp_t r, const char hex[64]); - - -typedef sm9_bn_t sm9_fn_t; - -#define sm9_fn_init(r) sm9_fn_set_zero(r) -#define sm9_fn_clean(f) sm9_fn_set_zero(r) -#define sm9_fn_set_zero(r) sm9_bn_set_zero(r) -#define sm9_fn_set_one(r) sm9_bn_set_one(r) -#define sm9_fn_copy(r,a) sm9_bn_copy((r),(a)) -#define sm9_fn_rand(r) sm9_bn_rand_range((r), SM9_N) -#define sm9_fn_is_zero(a) sm9_bn_is_zero(a) -#define sm9_fn_is_one(a) sm9_bn_is_one(a) -#define sm9_fn_equ(a,b) sm9_bn_equ((a),(b)) -#define sm9_fn_to_bytes(a,out) sm9_bn_to_bytes((a),(out)) -#define sm9_fn_to_hex(a,s) sm9_bn_to_hex((a),(s)) -#define sm9_fn_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a) - -void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); -void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); -void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); -void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e); -void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a); -void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40]); -int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32]); -int sm9_fn_from_hex(sm9_fn_t r, const char hex[64]); - - -typedef uint64_t sm9_barrett_bn_t[9]; - -int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); -void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); -void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); - - -typedef sm9_fp_t sm9_fp2_t[2]; -extern const sm9_fp2_t SM9_FP2_ZERO; -extern const sm9_fp2_t SM9_FP2_ONE; -extern const sm9_fp2_t SM9_FP2_U; - -#define sm9_fp2_init(a) sm9_fp2_set_zero(a) -#define sm9_fp2_clean(a) sm9_fp2_set_zero(a) -#define sm9_fp2_set_zero(a) sm9_fp2_copy((a), SM9_FP2_ZERO) -#define sm9_fp2_set_one(a) sm9_fp2_copy((a), SM9_FP2_ONE) -#define sm9_fp2_set_u(a) sm9_fp2_copy((a), SM9_FP2_U) -#define sm9_fp2_is_zero(a) sm9_fp2_equ((a), SM9_FP2_ZERO) -#define sm9_fp2_is_one(a) sm9_fp2_equ((a), SM9_FP2_ONE) - -void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a); -void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1); -void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a); -int sm9_fp2_rand(sm9_fp2_t r); -int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k); -void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); -void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129]); -int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129]); -int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a); - - -typedef sm9_fp2_t sm9_fp4_t[2]; -extern const sm9_fp4_t SM9_FP4_ZERO; -extern const sm9_fp4_t SM9_FP4_ONE; -extern const sm9_fp4_t SM9_FP4_U; -extern const sm9_fp4_t SM9_FP4_V; - -#define sm9_fp4_init(a) sm9_fp4_set_zero(a) -#define sm9_fp4_clean(a) sm9_fp4_set_zero(a) -#define sm9_fp4_set_zero(a) sm9_fp4_copy((a), SM9_FP4_ZERO) -#define sm9_fp4_set_one(a) sm9_fp4_copy((a), SM9_FP4_ONE) -#define sm9_fp4_is_zero(a) sm9_fp4_equ((a), SM9_FP4_ZERO) -#define sm9_fp4_is_one(a) sm9_fp4_equ((a), SM9_FP4_ONE) - -void sm9_fp4_set_u(sm9_fp4_t r); -void sm9_fp4_set_v(sm9_fp4_t r); -void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a); -void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a); -void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1); -void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a); -int sm9_fp4_rand(sm9_fp4_t r); -int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b); -void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); -void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); -void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); -void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k); -void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0); -void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); -void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128]); -int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128]); -void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259]); -int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[259]); - - -typedef sm9_fp4_t sm9_fp12_t[3]; - -#define sm9_fp12_init(r) sm9_fp12_set_zero(a) -#define sm9_fp12_clean(r) sm9_fp12_set_zero(a) - -void sm9_fp12_set_zero(sm9_fp12_t r); -void sm9_fp12_set_one(sm9_fp12_t r); -void sm9_fp12_set_u(sm9_fp12_t r); -void sm9_fp12_set_v(sm9_fp12_t r); -void sm9_fp12_set_w(sm9_fp12_t r); -void sm9_fp12_set_w_sqr(sm9_fp12_t r); -void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a); -void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a); -void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a); -void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2); -void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a); -int sm9_fp12_rand(sm9_fp12_t r); -int sm9_fp12_is_one(const sm9_fp12_t a); -int sm9_fp12_is_zero(const sm9_fp12_t a); -int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b); -void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); -void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a); -void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a); -void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); -void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a); -void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); -void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a); -void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a); -void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k); -void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12]); -int sm9_fp12_from_bytes(sm9_fp12_t r, const uint8_t in[32 * 12]); -void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12]); -int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12]); // 这个明显是不对的 -void sm9_fp12_print(const char *prefix, const sm9_fp12_t a); - - -void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a); -void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a); -void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x); -void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x); -void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x); -void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x); - - -typedef struct { - sm9_fp_t X; - sm9_fp_t Y; - sm9_fp_t Z; -} SM9_POINT; -extern const SM9_POINT *SM9_P1; - -#define sm9_point_init(R) sm9_point_set_infinity(R) -#define sm9_point_clean(R) sm9_point_set_infinity(R) - -void sm9_point_set_infinity(SM9_POINT *R); -void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P); -void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y); -int sm9_point_is_at_infinity(const SM9_POINT *P); -int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q); -int sm9_point_is_on_curve(const SM9_POINT *P); -void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P); -void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q); -void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P); -void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q); -void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P); -void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k); -void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2]); -int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65]); -int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65]); -int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P); - - -typedef struct { - sm9_fp2_t X; - sm9_fp2_t Y; - sm9_fp2_t Z; -} SM9_TWIST_POINT; - -extern const SM9_TWIST_POINT *SM9_P2; -extern const SM9_TWIST_POINT *SM9_Ppubs; - -#define sm9_twist_point_copy(R, P) memcpy((R), (P), sizeof(SM9_TWIST_POINT)) - -int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129]); -int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129]); - - -void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4]); -int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P); -void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R); -void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y); - -int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); -int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P); -void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); -void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); -void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); -void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); -void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); -void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P); -void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k); -int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P); - - - -void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q); -void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q); -void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); -void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); -void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); -void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f); -void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f); -void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P); - - -/* private key extract algorithms */ -#define SM9_HID_SIGN 0x01 -#define SM9_HID_EXCH 0x02 -#define SM9_HID_ENC 0x03 - -#define SM9_HASH1_PREFIX 0x01 -#define SM9_HASH2_PREFIX 0x02 - -int sm9_hash1(sm9_bn_t h1, const char *id, size_t idlen, uint8_t hid); - - -const char *sm9_oid_name(int oid); -int sm9_oid_from_name(const char *name); -int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen); -int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen); -int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen); -int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen); - - -#define PEM_SM9_SIGN_MASTER_KEY "ENCRYPTED SM9 SIGN MASTER KEY" -#define PEM_SM9_SIGN_MASTER_PUBLIC_KEY "SM9 SIGN MASTER PUBLIC KEY" -#define PEM_SM9_SIGN_PRIVATE_KEY "ENCRYPTED SM9 SIGN PRIVATE KEY" -#define PEM_SM9_ENC_MASTER_KEY "ENCRYPTED SM9 ENC MASTER KEY" -#define PEM_SM9_ENC_MASTER_PUBLIC_KEY "SM9 ENC MASTER PUBLIC KEY" -#define PEM_SM9_ENC_PRIVATE_KEY "ENCRYPTED SM9 ENC PRIVATE KEY" - - -#define SM9_MAX_ID_SIZE (SM2_MAX_ID_SIZE) - -/* -SM9SignMasterKey ::= SEQUENCE { - ks INTEGER, - Ppubs BIT STRING -- uncompressed octets of twisted point } - -SM9SignMasterPublicKey ::= SEQUENCE { - Ppubs BIT STRING -- uncompressed octets of twisted point } - -SM9SignPrivateKey ::= SEQUENCE { - ds BIT STRING, -- uncompressed octets of ECPoint - Ppubs BIT STRING -- uncompressed octets of twisted point } -*/ -typedef struct { - SM9_TWIST_POINT Ppubs; // Ppubs = ks * P2 - sm9_fn_t ks; -} SM9_SIGN_MASTER_KEY; - -typedef struct { - SM9_TWIST_POINT Ppubs; - SM9_POINT ds; -} SM9_SIGN_KEY; - -int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master); -int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key); - -// algorthm,parameters = sm9,sm9sign -#define SM9_SIGN_MASTER_KEY_MAX_SIZE 171 -int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen); -int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); -int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); -int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk); - -#define SM9_SIGN_MASTER_PUBLIC_KEY_SIZE 136 -int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); -int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); -int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp); -int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp); -int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk); - -// algorithm,parameters = sm9sign, -#define SM9_SIGN_KEY_SIZE 204 -int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen); -int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen); -int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen); -int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp); -int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp); -int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key); - -/* -from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification -SM9Signature ::= SEQUENCE { - h OCTET STRING, - S BIT STRING -- uncompressed octets of ECPoint } -*/ -typedef struct { - sm9_fn_t h; - SM9_POINT S; -} SM9_SIGNATURE; - -int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig); -int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, const SM3_CTX *sm3_ctx, const SM9_SIGNATURE *sig); - -#define SM9_SIGNATURE_SIZE 104 -int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen); -int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen); -int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); - -typedef struct { - SM3_CTX sm3_ctx; -} SM9_SIGN_CTX; - -int sm9_sign_init(SM9_SIGN_CTX *ctx); -int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen); -int sm9_verify_init(SM9_SIGN_CTX *ctx); -int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, - const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen); - - -/* -SM9EncMasterKey ::= SEQUENCE { - de INTEGER, - Ppube BIT STRING -- uncompressed octets of ECPoint } - -SM9EncMasterPublicKey ::= SEQUENCE { - Ppube BIT STRING -- uncompressed octets of ECPoint } - -SM9EncPrivateKey ::= SEQUENCE { - de BIT STRING, -- uncompressed octets of twisted point - Ppube BIT STRING -- uncompressed octets of ECPoint } -*/ - -typedef struct { - SM9_POINT Ppube; // Ppube = ke * P1 - sm9_fn_t ke; -} SM9_ENC_MASTER_KEY; - -typedef struct { - SM9_POINT Ppube; - SM9_TWIST_POINT de; -} SM9_ENC_KEY; - -int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master); -int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key); - -// algorithm,parameters = sm9,sm9encrypt -#define SM9_ENC_MASTER_KEY_MAX_SIZE 105 -int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen); -int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); -int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); -int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk); - -#define SM9_ENC_MASTER_PUBLIC_KEY_SIZE 70 -int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); -int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); -int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp); -int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp); -int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk); - -// algorithm,parameters = sm9encrypt, -#define SM9_ENC_KEY_SIZE 204 -int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen); -int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen); -int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen); -int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp); -int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp); -int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key); - -#define SM9_MAX_PRIVATE_KEY_SIZE (SM9_SIGN_KEY_SIZE) // MAX(SIGN_MASTER_KEY, SIGN_KEY, ENC_MASTER_KEY, ENC_KEY) -#define SM9_MAX_PRIVATE_KEY_INFO_SIZE 512 -#define SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE 1024 - -/* -from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification -SM9Cipher ::= SEQUENCE { - EnType INTEGER, -- 0 for XOR - C1 BIT STRING, -- uncompressed octets of ECPoint - C3 OCTET STRING, -- 32 bytes HMAC-SM3 tag - CipherText OCTET STRING } -*/ - -int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, size_t klen, uint8_t *kbuf, SM9_POINT *C); -int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const SM9_POINT *C, size_t klen, uint8_t *kbuf); -int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, SM9_POINT *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]); -int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, - const SM9_POINT *C1, const uint8_t *c2, size_t c2len, const uint8_t c3[SM3_HMAC_SIZE], uint8_t *out); - -#define SM9_MAX_PLAINTEXT_SIZE 255 -#define SM9_MAX_CIPHERTEXT_SIZE 367 // calculated in test_sm9_ciphertext() -int sm9_ciphertext_to_der(const SM9_POINT *C1, const uint8_t *c2, size_t c2len, - const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen); -int sm9_ciphertext_from_der(SM9_POINT *C1, const uint8_t **c2, size_t *c2len, - const uint8_t *c3[SM3_HMAC_SIZE], const uint8_t **in, size_t *inlen); -int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); -int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); - - - -#ifdef __cplusplus -} -#endif -#endif + + +#include +#include +#include +#include +#include +#include + + +#ifndef GMSSL_SM9_H +#define GMSSL_SM9_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +SM9 Public API + + SM9_SIGNATURE_SIZE + SM9_MAX_PLAINTEXT_SIZE + SM9_MAX_CIPHERTEXT_SIZE + + SM9_SIGN_MASTER_KEY + sm9_sign_master_key_generate + sm9_sign_master_key_extract_key + sm9_sign_master_key_info_encrypt_to_der + sm9_sign_master_key_info_decrypt_from_der + sm9_sign_master_key_info_encrypt_to_pem + sm9_sign_master_key_info_decrypt_from_pem + sm9_sign_master_public_key_to_der + sm9_sign_master_public_key_from_der + sm9_sign_master_public_key_to_pem + sm9_sign_master_public_key_from_pem + + SM9_SIGN_KEY + sm9_sign_key_info_encrypt_to_der + sm9_sign_key_info_decrypt_from_der + sm9_sign_key_info_encrypt_to_pem + sm9_sign_key_info_decrypt_from_pem + + SM9_SIGN_CTX + sm9_sign_init + sm9_sign_update + sm9_sign_finish + sm9_verify_init + sm9_verify_update + sm9_verify_finish + + SM9_ENC_MASTER_KEY + sm9_enc_master_key_generate + sm9_enc_master_key_extract_key + sm9_enc_master_key_info_encrypt_to_der + sm9_enc_master_key_info_decrypt_from_der + sm9_enc_master_key_info_encrypt_to_pem + sm9_enc_master_key_info_decrypt_from_pem + sm9_enc_master_public_key_to_der + sm9_enc_master_public_key_from_der + sm9_enc_master_public_key_to_pem + sm9_enc_master_public_key_from_pem + + SM9_ENC_KEY + sm9_enc_key_info_encrypt_to_der + sm9_enc_key_info_decrypt_from_der + sm9_enc_key_info_encrypt_to_pem + sm9_enc_key_info_decrypt_from_pem + + sm9_encrypt + sm9_decrypt +*/ + +#define SM9_HEX_SEP '\n' + +typedef uint64_t sm9_bn_t[8]; +extern const sm9_bn_t SM9_ZERO; +extern const sm9_bn_t SM9_ONE; +extern const sm9_bn_t SM9_P; +extern const sm9_bn_t SM9_N; + +#define sm9_bn_init(r) sm9_bn_set_zero(r) +#define sm9_bn_clean(r) sm9_bn_set_zero(r) +#define sm9_bn_set_zero(r) sm9_bn_copy((r), SM9_ZERO) +#define sm9_bn_set_one(r) sm9_bn_copy((r), SM9_ONE) +#define sm9_bn_is_zero(a) (sm9_bn_cmp((a), SM9_ZERO) == 0) +#define sm9_bn_is_one(a) (sm9_bn_cmp((a), SM9_ONE) == 0) + +void sm9_bn_set_word(sm9_bn_t r, uint32_t a); +void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a); +int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range); +int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b); +int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b); +void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b); +void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b); +void sm9_bn_to_bits(const sm9_bn_t a, char bits[256]); +void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32]); +void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32]); +void sm9_bn_to_hex(const sm9_bn_t a, char hex[64]); +int sm9_bn_from_hex(sm9_bn_t r, const char hex[64]); +int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a); +void sm9_print_bn(const char *prefix, const sm9_bn_t a); // 标准打印格式 + + +typedef sm9_bn_t sm9_fp_t; + +#define sm9_fp_init(r) sm9_fp_set_zero(r) +#define sm9_fp_clean(f) sm9_fp_set_zero(r) +#define sm9_fp_set_zero(r) sm9_bn_set_zero(r) +#define sm9_fp_set_one(r) sm9_bn_set_one(r) +#define sm9_fp_copy(r,a) sm9_bn_copy((r),(a)) +#define sm9_fp_rand(r) sm9_bn_rand_range((r), SM9_P) +#define sm9_fp_is_zero(a) sm9_bn_is_zero(a) +#define sm9_fp_is_one(a) sm9_bn_is_one(a) +#define sm9_fp_equ(a,b) sm9_bn_equ((a),(b)) +#define sm9_fp_to_bytes(a,buf) sm9_bn_to_bytes((a),(buf)) +#define sm9_fp_to_hex(a,s) sm9_bn_to_hex((a),(s)) +#define sm9_fp_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a) + +void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); +void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); +void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a); +void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a); +void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a); +void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b); +void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a); +void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e); +void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a); +void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a); +int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32]); +int sm9_fp_from_hex(sm9_fp_t r, const char hex[64]); + + +typedef sm9_bn_t sm9_fn_t; + +#define sm9_fn_init(r) sm9_fn_set_zero(r) +#define sm9_fn_clean(f) sm9_fn_set_zero(r) +#define sm9_fn_set_zero(r) sm9_bn_set_zero(r) +#define sm9_fn_set_one(r) sm9_bn_set_one(r) +#define sm9_fn_copy(r,a) sm9_bn_copy((r),(a)) +#define sm9_fn_rand(r) sm9_bn_rand_range((r), SM9_N) +#define sm9_fn_is_zero(a) sm9_bn_is_zero(a) +#define sm9_fn_is_one(a) sm9_bn_is_one(a) +#define sm9_fn_equ(a,b) sm9_bn_equ((a),(b)) +#define sm9_fn_to_bytes(a,out) sm9_bn_to_bytes((a),(out)) +#define sm9_fn_to_hex(a,s) sm9_bn_to_hex((a),(s)) +#define sm9_fn_print(fp,fmt,ind,label,a) sm9_bn_print(fp,fmt,ind,label,a) + +void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); +void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); +void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b); +void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e); +void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a); +void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40]); +int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32]); +int sm9_fn_from_hex(sm9_fn_t r, const char hex[64]); + + +typedef uint64_t sm9_barrett_bn_t[9]; + +int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); +void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); +void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b); + + +typedef sm9_fp_t sm9_fp2_t[2]; +extern const sm9_fp2_t SM9_FP2_ZERO; +extern const sm9_fp2_t SM9_FP2_ONE; +extern const sm9_fp2_t SM9_FP2_U; + +#define sm9_fp2_init(a) sm9_fp2_set_zero(a) +#define sm9_fp2_clean(a) sm9_fp2_set_zero(a) +#define sm9_fp2_set_zero(a) sm9_fp2_copy((a), SM9_FP2_ZERO) +#define sm9_fp2_set_one(a) sm9_fp2_copy((a), SM9_FP2_ONE) +#define sm9_fp2_set_u(a) sm9_fp2_copy((a), SM9_FP2_U) +#define sm9_fp2_is_zero(a) sm9_fp2_equ((a), SM9_FP2_ZERO) +#define sm9_fp2_is_one(a) sm9_fp2_equ((a), SM9_FP2_ONE) + +void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a); +void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1); +void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a); +int sm9_fp2_rand(sm9_fp2_t r); +int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k); +void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b); +void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129]); +int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129]); +int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a); + + +typedef sm9_fp2_t sm9_fp4_t[2]; +extern const sm9_fp4_t SM9_FP4_ZERO; +extern const sm9_fp4_t SM9_FP4_ONE; +extern const sm9_fp4_t SM9_FP4_U; +extern const sm9_fp4_t SM9_FP4_V; + +#define sm9_fp4_init(a) sm9_fp4_set_zero(a) +#define sm9_fp4_clean(a) sm9_fp4_set_zero(a) +#define sm9_fp4_set_zero(a) sm9_fp4_copy((a), SM9_FP4_ZERO) +#define sm9_fp4_set_one(a) sm9_fp4_copy((a), SM9_FP4_ONE) +#define sm9_fp4_is_zero(a) sm9_fp4_equ((a), SM9_FP4_ZERO) +#define sm9_fp4_is_one(a) sm9_fp4_equ((a), SM9_FP4_ONE) + +void sm9_fp4_set_u(sm9_fp4_t r); +void sm9_fp4_set_v(sm9_fp4_t r); +void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a); +void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a); +void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1); +void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a); +int sm9_fp4_rand(sm9_fp4_t r); +int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b); +void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); +void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); +void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); +void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k); +void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0); +void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b); +void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128]); +int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128]); +void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259]); +int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[259]); + + +typedef sm9_fp4_t sm9_fp12_t[3]; + +#define sm9_fp12_init(r) sm9_fp12_set_zero(a) +#define sm9_fp12_clean(r) sm9_fp12_set_zero(a) + +void sm9_fp12_set_zero(sm9_fp12_t r); +void sm9_fp12_set_one(sm9_fp12_t r); +void sm9_fp12_set_u(sm9_fp12_t r); +void sm9_fp12_set_v(sm9_fp12_t r); +void sm9_fp12_set_w(sm9_fp12_t r); +void sm9_fp12_set_w_sqr(sm9_fp12_t r); +void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a); +void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a); +void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a); +void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2); +void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a); +int sm9_fp12_rand(sm9_fp12_t r); +int sm9_fp12_is_one(const sm9_fp12_t a); +int sm9_fp12_is_zero(const sm9_fp12_t a); +int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b); +void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); +void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a); +void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a); +void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); +void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a); +void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b); +void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a); +void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a); +void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k); +void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12]); +int sm9_fp12_from_bytes(sm9_fp12_t r, const uint8_t in[32 * 12]); +void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12]); +int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12]); // 这个明显是不对的 +void sm9_fp12_print(const char *prefix, const sm9_fp12_t a); + + +void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a); +void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a); +void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x); +void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x); +void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x); +void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x); + + +typedef struct { + sm9_fp_t X; + sm9_fp_t Y; + sm9_fp_t Z; +} SM9_POINT; +extern const SM9_POINT *SM9_P1; + +#define sm9_point_init(R) sm9_point_set_infinity(R) +#define sm9_point_clean(R) sm9_point_set_infinity(R) + +void sm9_point_set_infinity(SM9_POINT *R); +void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P); +void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y); +int sm9_point_is_at_infinity(const SM9_POINT *P); +int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q); +int sm9_point_is_on_curve(const SM9_POINT *P); +void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P); +void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q); +void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P); +void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q); +void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P); +void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k); +void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2]); +int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65]); +int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65]); +int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P); + + +typedef struct { + sm9_fp2_t X; + sm9_fp2_t Y; + sm9_fp2_t Z; +} SM9_TWIST_POINT; + +extern const SM9_TWIST_POINT *SM9_P2; +extern const SM9_TWIST_POINT *SM9_Ppubs; + +#define sm9_twist_point_copy(R, P) memcpy((R), (P), sizeof(SM9_TWIST_POINT)) + +int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129]); +int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129]); + + +void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4]); +int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P); +void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R); +void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y); + +int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); +int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P); +void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); +void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); +void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); +void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); +void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q); +void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P); +void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k); +int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P); + + + +void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q); +void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q); +void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); +void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); +void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P); +void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f); +void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f); +void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P); + + +/* private key extract algorithms */ +#define SM9_HID_SIGN 0x01 +#define SM9_HID_EXCH 0x02 +#define SM9_HID_ENC 0x03 + +#define SM9_HASH1_PREFIX 0x01 +#define SM9_HASH2_PREFIX 0x02 + +int sm9_hash1(sm9_bn_t h1, const char *id, size_t idlen, uint8_t hid); + + +const char *sm9_oid_name(int oid); +int sm9_oid_from_name(const char *name); +int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen); +int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen); +int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen); +int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen); + + +#define PEM_SM9_SIGN_MASTER_KEY "ENCRYPTED SM9 SIGN MASTER KEY" +#define PEM_SM9_SIGN_MASTER_PUBLIC_KEY "SM9 SIGN MASTER PUBLIC KEY" +#define PEM_SM9_SIGN_PRIVATE_KEY "ENCRYPTED SM9 SIGN PRIVATE KEY" +#define PEM_SM9_ENC_MASTER_KEY "ENCRYPTED SM9 ENC MASTER KEY" +#define PEM_SM9_ENC_MASTER_PUBLIC_KEY "SM9 ENC MASTER PUBLIC KEY" +#define PEM_SM9_ENC_PRIVATE_KEY "ENCRYPTED SM9 ENC PRIVATE KEY" + + +#define SM9_MAX_ID_SIZE (SM2_MAX_ID_SIZE) + +/* +SM9SignMasterKey ::= SEQUENCE { + ks INTEGER, + Ppubs BIT STRING -- uncompressed octets of twisted point } + +SM9SignMasterPublicKey ::= SEQUENCE { + Ppubs BIT STRING -- uncompressed octets of twisted point } + +SM9SignPrivateKey ::= SEQUENCE { + ds BIT STRING, -- uncompressed octets of ECPoint + Ppubs BIT STRING -- uncompressed octets of twisted point } +*/ +typedef struct { + SM9_TWIST_POINT Ppubs; // Ppubs = ks * P2 + sm9_fn_t ks; +} SM9_SIGN_MASTER_KEY; + +typedef struct { + SM9_TWIST_POINT Ppubs; + SM9_POINT ds; +} SM9_SIGN_KEY; + +int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master); +int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key); + +// algorthm,parameters = sm9,sm9sign +#define SM9_SIGN_MASTER_KEY_MAX_SIZE 171 +int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen); +int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); +int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); +int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); +int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); +int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); +int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk); + +#define SM9_SIGN_MASTER_PUBLIC_KEY_SIZE 136 +int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); +int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); +int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp); +int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp); +int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk); + +// algorithm,parameters = sm9sign, +#define SM9_SIGN_KEY_SIZE 204 +int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen); +int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen); +int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen); +int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); +int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp); +int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp); +int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key); + +/* +from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification +SM9Signature ::= SEQUENCE { + h OCTET STRING, + S BIT STRING -- uncompressed octets of ECPoint } +*/ +typedef struct { + sm9_fn_t h; + SM9_POINT S; +} SM9_SIGNATURE; + +int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig); +int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, const SM3_CTX *sm3_ctx, const SM9_SIGNATURE *sig); + +#define SM9_SIGNATURE_SIZE 104 +int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen); +int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen); +int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); + +typedef struct { + SM3_CTX sm3_ctx; +} SM9_SIGN_CTX; + +int sm9_sign_init(SM9_SIGN_CTX *ctx); +int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen); +int sm9_verify_init(SM9_SIGN_CTX *ctx); +int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, + const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen); + + +/* +SM9EncMasterKey ::= SEQUENCE { + de INTEGER, + Ppube BIT STRING -- uncompressed octets of ECPoint } + +SM9EncMasterPublicKey ::= SEQUENCE { + Ppube BIT STRING -- uncompressed octets of ECPoint } + +SM9EncPrivateKey ::= SEQUENCE { + de BIT STRING, -- uncompressed octets of twisted point + Ppube BIT STRING -- uncompressed octets of ECPoint } +*/ + +typedef struct { + SM9_POINT Ppube; // Ppube = ke * P1 + sm9_fn_t ke; +} SM9_ENC_MASTER_KEY; + +typedef struct { + SM9_POINT Ppube; + SM9_TWIST_POINT de; +} SM9_ENC_KEY; + +int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master); +int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key); + +// algorithm,parameters = sm9,sm9encrypt +#define SM9_ENC_MASTER_KEY_MAX_SIZE 105 +int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen); +int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); +int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); +int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); +int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); +int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); +int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk); + +#define SM9_ENC_MASTER_PUBLIC_KEY_SIZE 70 +int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); +int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); +int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp); +int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp); +int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk); + +// algorithm,parameters = sm9encrypt, +#define SM9_ENC_KEY_SIZE 204 +int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen); +int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen); +int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen); +int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); +int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp); +int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp); +int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key); + +#define SM9_MAX_PRIVATE_KEY_SIZE (SM9_SIGN_KEY_SIZE) // MAX(SIGN_MASTER_KEY, SIGN_KEY, ENC_MASTER_KEY, ENC_KEY) +#define SM9_MAX_PRIVATE_KEY_INFO_SIZE 512 +#define SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE 1024 + +/* +from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification +SM9Cipher ::= SEQUENCE { + EnType INTEGER, -- 0 for XOR + C1 BIT STRING, -- uncompressed octets of ECPoint + C3 OCTET STRING, -- 32 bytes HMAC-SM3 tag + CipherText OCTET STRING } +*/ + +int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, size_t klen, uint8_t *kbuf, SM9_POINT *C); +int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const SM9_POINT *C, size_t klen, uint8_t *kbuf); +int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, SM9_POINT *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]); +int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, + const SM9_POINT *C1, const uint8_t *c2, size_t c2len, const uint8_t c3[SM3_HMAC_SIZE], uint8_t *out); + +#define SM9_MAX_PLAINTEXT_SIZE 255 +#define SM9_MAX_CIPHERTEXT_SIZE 367 // calculated in test_sm9_ciphertext() +int sm9_ciphertext_to_der(const SM9_POINT *C1, const uint8_t *c2, size_t c2len, + const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen); +int sm9_ciphertext_from_der(SM9_POINT *C1, const uint8_t **c2, size_t *c2len, + const uint8_t *c3[SM3_HMAC_SIZE], const uint8_t **in, size_t *inlen); +int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); +int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index fc74d324..72eee806 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,874 +7,875 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_TLS_H -#define GMSSL_TLS_H - - -#include -#include -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -TLS Public API - - TLS_PROTOCOL - TLS_protocol_tlcp - TLS_protocol_tls12 - TLS_protocol_tls13 - - TLS_CIPHER_SUITE - TLS_cipher_ecc_sm4_cbc_sm3 - TLS_cipher_ecc_sm4_gcm_sm3 - TLS_cipher_ecdhe_sm4_cbc_sm3 - TLS_cipher_ecdhe_sm4_gcm_sm3 - TLS_cipher_sm4_gcm_sm3 - - TLS_CTX - tls_ctx_init - tls_ctx_set_cipher_suites - tls_ctx_set_ca_certificates - tls_ctx_set_certificate_and_key - tls_ctx_set_tlcp_server_certificate_and_keys - tls_ctx_cleanup - - TLS_CONNECT - tls_init - tls_set_socket - tls_do_handshake - tls_send - tls_recv - tls_shutdown - tls_cleanup -*/ - -typedef uint32_t uint24_t; - -#define tls_uint8_size() 1 -#define tls_uint16_size() 2 -#define tls_uint24_size() 3 - -void tls_uint8_to_bytes(uint8_t a, uint8_t **out, size_t *outlen); -void tls_uint16_to_bytes(uint16_t a, uint8_t **out, size_t *outlen); -void tls_uint24_to_bytes(uint24_t a, uint8_t **out, size_t *outlen); -void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen); -void tls_array_to_bytes(const uint8_t *data, size_t len, uint8_t **out, size_t *outlen); -void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); -void tls_uint16array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); -void tls_uint24array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); -int tls_uint8_from_bytes(uint8_t *a, const uint8_t **in, size_t *inlen); -int tls_uint16_from_bytes(uint16_t *a, const uint8_t **in, size_t *inlen); -int tls_uint24_from_bytes(uint24_t *a, const uint8_t **in, size_t *inlen); -int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen); -int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen); -int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); -int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); -int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); -int tls_length_is_zero(size_t len); - - -typedef enum { - TLS_protocol_tlcp = 0x0101, - TLS_protocol_ssl2 = 0x0200, - TLS_protocol_ssl3 = 0x0300, - TLS_protocol_tls1 = 0x0301, - TLS_protocol_tls11 = 0x0302, - TLS_protocol_tls12 = 0x0303, - TLS_protocol_tls13 = 0x0304, - TLS_protocol_dtls1 = 0xfeff, // {254, 255} - TLS_protocol_dtls12 = 0xfefd, // {254, 253} -} TLS_PROTOCOL; - -const char *tls_protocol_name(int proto); - - -typedef enum { - TLS_cipher_null_with_null_null = 0x0000, - - // TLS 1.3, RFC 8998 - TLS_cipher_sm4_gcm_sm3 = 0x00c6, - TLS_cipher_sm4_ccm_sm3 = 0x00c7, - - // TLCP, GB/T 38636-2020, GM/T 0024-2012 - TLS_cipher_ecdhe_sm4_cbc_sm3 = 0xe011, // 可以让TLSv1.2使用这个 - TLS_cipher_ecdhe_sm4_gcm_sm3 = 0xe051, - TLS_cipher_ecc_sm4_cbc_sm3 = 0xe013, - TLS_cipher_ecc_sm4_gcm_sm3 = 0xe053, - TLS_cipher_ibsdh_sm4_cbc_sm3 = 0xe015, - TLS_cipher_ibsdh_sm4_gcm_sm3 = 0xe055, - TLS_cipher_ibc_sm4_cbc_sm3 = 0xe017, - TLS_cipher_ibc_sm4_gcm_sm3 = 0xe057, - TLS_cipher_rsa_sm4_cbc_sm3 = 0xe019, - TLS_cipher_rsa_sm4_gcm_sm3 = 0xe059, - TLS_cipher_rsa_sm4_cbc_sha256 = 0xe01c, - TLS_cipher_rsa_sm4_gcm_sha256 = 0xe05a, - - // TLS 1.3 RFC 8446 - TLS_cipher_aes_128_gcm_sha256 = 0x1301, // Mandatory-to-implement - TLS_cipher_aes_256_gcm_sha384 = 0x1302, // SHOULD implement - TLS_cipher_chacha20_poly1305_sha256 = 0x1303, // SHOULD implement - TLS_cipher_aes_128_ccm_sha256 = 0x1304, - TLS_cipher_aes_128_ccm_8_sha256 = 0x1305, - - TLS_cipher_empty_renegotiation_info_scsv = 0x00ff, -} TLS_CIPHER_SUITE; - -const char *tls_cipher_suite_name(int cipher); -int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len, - const int *server_ciphers, size_t server_ciphers_cnt, int *selected_cipher); -int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count); - - -typedef enum { - TLS_compression_null = 0, - TLS_compression_default = 1, -} TLS_COMPRESSION_METHOD; - -const char *tls_compression_method_name(int meth); - - -typedef enum { - TLS_record_invalid = 0, // TLS 1.3 - TLS_record_change_cipher_spec = 20, // 0x14 - TLS_record_alert = 21, // 0x15 - TLS_record_handshake = 22, // 0x16 - TLS_record_application_data = 23, // 0x17 - TLS_record_heartbeat = 24, // 0x18 - TLS_record_tls12_cid = 25, // 0x19 -} TLS_RECORD_TYPE; - -const char *tls_record_type_name(int type); - - -typedef enum { - TLS_handshake_hello_request = 0, - TLS_handshake_client_hello = 1, - TLS_handshake_server_hello = 2, - TLS_handshake_hello_verify_request = 3, - TLS_handshake_new_session_ticket = 4, - TLS_handshake_end_of_early_data = 5, - TLS_handshake_hello_retry_request = 6, - TLS_handshake_encrypted_extensions = 8, - TLS_handshake_certificate = 11, - TLS_handshake_server_key_exchange = 12, - TLS_handshake_certificate_request = 13, - TLS_handshake_server_hello_done = 14, - TLS_handshake_certificate_verify = 15, - TLS_handshake_client_key_exchange = 16, - TLS_handshake_finished = 20, - TLS_handshake_certificate_url = 21, - TLS_handshake_certificate_status = 22, - TLS_handshake_supplemental_data = 23, - TLS_handshake_key_update = 24, - TLS_handshake_compressed_certificate = 25, - TLS_handshake_ekt_key = 26, - TLS_handshake_message_hash = 254, -} TLS_HANDSHAKE_TYPE; - -const char *tls_handshake_type_name(int type); - - -typedef enum { - TLS_cert_type_rsa_sign = 1, - TLS_cert_type_dss_sign = 2, - TLS_cert_type_rsa_fixed_dh = 3, - TLS_cert_type_dss_fixed_dh = 4, - TLS_cert_type_rsa_ephemeral_dh_RESERVED = 5, - TLS_cert_type_dss_ephemeral_dh_RESERVED = 6, - TLS_cert_type_fortezza_dms_RESERVED = 20, - TLS_cert_type_ecdsa_sign = 64, // also for sm2 - TLS_cert_type_rsa_fixed_ecdh = 65, - TLS_cert_type_ecdsa_fixed_ecdh = 66, - TLS_cert_type_gost_sign256 = 67, - TLS_cert_type_gost_sign512 = 68, - TLS_cert_type_ibc_params = 80, -} TLS_CERTIFICATE_TYPE; - -const char *tls_cert_type_name(int type); -int tls_cert_type_from_oid(int oid); - -typedef enum { - TLS_extension_server_name = 0, - TLS_extension_max_fragment_length = 1, - TLS_extension_client_certificate_url = 2, - TLS_extension_trusted_ca_keys = 3, - TLS_extension_truncated_hmac = 4, - TLS_extension_status_request = 5, - TLS_extension_user_mapping = 6, - TLS_extension_client_authz = 7, - TLS_extension_server_authz = 8, - TLS_extension_cert_type = 9, - TLS_extension_supported_groups = 10, - TLS_extension_ec_point_formats = 11, - TLS_extension_srp = 12, - TLS_extension_signature_algorithms = 13, - TLS_extension_use_srtp = 14, - TLS_extension_heartbeat = 15, - TLS_extension_application_layer_protocol_negotiation= 16, - TLS_extension_status_request_v2 = 17, - TLS_extension_signed_certificate_timestamp = 18, - TLS_extension_client_certificate_type = 19, - TLS_extension_server_certificate_type = 20, - TLS_extension_padding = 21, - TLS_extension_encrypt_then_mac = 22, - TLS_extension_extended_master_secret = 23, - TLS_extension_token_binding = 24, - TLS_extension_cached_info = 25, - TLS_extension_tls_lts = 26, - TLS_extension_compress_certificate = 27, - TLS_extension_record_size_limit = 28, - TLS_extension_pwd_protect = 29, - TLS_extension_pwd_clear = 30, - TLS_extension_password_salt = 31, - TLS_extension_ticket_pinning = 32, - TLS_extension_tls_cert_with_extern_psk = 33, - TLS_extension_delegated_credentials = 34, - TLS_extension_session_ticket = 35, - TLS_extension_TLMSP = 36, - TLS_extension_TLMSP_proxying = 37, - TLS_extension_TLMSP_delegate = 38, - TLS_extension_supported_ekt_ciphers = 39, - TLS_extension_pre_shared_key = 41, - TLS_extension_early_data = 42, - TLS_extension_supported_versions = 43, - TLS_extension_cookie = 44, - TLS_extension_psk_key_exchange_modes = 46, - TLS_extension_certificate_authorities = 47, - TLS_extension_oid_filters = 48, - TLS_extension_post_handshake_auth = 49, - TLS_extension_signature_algorithms_cert = 50, - TLS_extension_key_share = 51, - TLS_extension_transparency_info = 52, - TLS_extension_connection_id = 53, - TLS_extension_external_id_hash = 55, - TLS_extension_external_session_id = 56, - TLS_extension_quic_transport_parameters = 57, - TLS_extension_ticket_request = 58, - TLS_extension_renegotiation_info = 65281, -} TLS_EXTENSION_TYPE; - -const char *tls_extension_name(int ext); - - -typedef enum { - TLS_point_uncompressed = 0, - TLS_point_ansix962_compressed_prime = 1, - TLS_point_ansix962_compressed_char2 = 2, -} TLS_EC_POINT_FORMAT; - -const char *tls_ec_point_format_name(int format); - - -typedef enum { - TLS_curve_type_explicit_prime = 1, - TLS_curve_type_explicit_char2 = 2, - TLS_curve_type_named_curve = 3, -} TLS_CURVE_TYPE; - -const char *tls_curve_type_name(int type); - - -// 与其支持v2,还不如直接修改v2,让v2和v3兼容 - -typedef enum { - TLS_curve_secp256k1 = 22, - TLS_curve_secp256r1 = 23, - TLS_curve_secp384r1 = 24, - TLS_curve_secp521r1 = 25, - TLS_curve_brainpoolp256r1 = 26, - TLS_curve_brainpoolp384r1 = 27, - TLS_curve_brainpoolp512r1 = 28, - TLS_curve_x25519 = 29, - TLS_curve_x448 = 30, - TLS_curve_brainpoolp256r1tls13 = 31, - TLS_curve_brainpoolp384r1tls13 = 32, - TLS_curve_brainpoolp512r1tls13 = 33, - TLS_curve_sm2p256v1 = 41, // GmSSLv2: 30 -} TLS_NAMED_CURVE; - -const char *tls_named_curve_name(int curve); - - -typedef enum { - TLS_sig_rsa_pkcs1_sha1 = 0x0201, - TLS_sig_ecdsa_sha1 = 0x0203, - TLS_sig_rsa_pkcs1_sha256 = 0x0401, - TLS_sig_ecdsa_secp256r1_sha256 = 0x0403, - TLS_sig_rsa_pkcs1_sha256_legacy = 0x0420, - TLS_sig_rsa_pkcs1_sha384 = 0x0501, - TLS_sig_ecdsa_secp384r1_sha384 = 0x0503, - TLS_sig_rsa_pkcs1_sha384_legacy = 0x0520, - TLS_sig_rsa_pkcs1_sha512 = 0x0601, - TLS_sig_ecdsa_secp521r1_sha512 = 0x0603, - TLS_sig_rsa_pkcs1_sha512_legacy = 0x0620, - TLS_sig_sm2sig_sm3 = 0x0708, // GmSSLv2: 0x0707 - TLS_sig_rsa_pss_rsae_sha256 = 0x0804, - TLS_sig_rsa_pss_rsae_sha384 = 0x0805, - TLS_sig_rsa_pss_rsae_sha512 = 0x0806, - TLS_sig_ed25519 = 0x0807, - TLS_sig_ed448 = 0x0808, - TLS_sig_rsa_pss_pss_sha256 = 0x0809, - TLS_sig_rsa_pss_pss_sha384 = 0x080A, - TLS_sig_rsa_pss_pss_sha512 = 0x080B, - TLS_sig_ecdsa_brainpoolP256r1tls13_sha256 = 0x081A, - TLS_sig_ecdsa_brainpoolP384r1tls13_sha384 = 0x081B, - TLS_sig_ecdsa_brainpoolP512r1tls13_sha512 = 0x081C, -} TLS_SIGNATURE_SCHEME; - -const char *tls_signature_scheme_name(int scheme); - - -typedef enum { - TLS_change_cipher_spec = 1, -} TLS_CHANGE_CIPHER_SPEC_TYPE; - - -typedef enum { - TLS_alert_level_warning = 1, - TLS_alert_level_fatal = 2, -} TLS_ALERT_LEVEL; - -const char *tls_alert_level_name(int level); - - -typedef enum { - TLS_alert_close_notify = 0, - TLS_alert_unexpected_message = 10, - TLS_alert_bad_record_mac = 20, - TLS_alert_decryption_failed = 21, - TLS_alert_record_overflow = 22, - TLS_alert_decompression_failure = 30, - TLS_alert_handshake_failure = 40, - TLS_alert_no_certificate = 41, - TLS_alert_bad_certificate = 42, - TLS_alert_unsupported_certificate = 43, - TLS_alert_certificate_revoked = 44, - TLS_alert_certificate_expired = 45, - TLS_alert_certificate_unknown = 46, - TLS_alert_illegal_parameter = 47, - TLS_alert_unknown_ca = 48, - TLS_alert_access_denied = 49, - TLS_alert_decode_error = 50, - TLS_alert_decrypt_error = 51, - TLS_alert_export_restriction = 60, - TLS_alert_protocol_version = 70, - TLS_alert_insufficient_security = 71, - TLS_alert_internal_error = 80, - TLS_alert_user_canceled = 90, - TLS_alert_no_renegotiation = 100, - TLS_alert_unsupported_extension = 110, - TLS_alert_unsupported_site2site = 200, - TLS_alert_no_area = 201, - TLS_alert_unsupported_areatype = 202, - TLS_alert_bad_ibcparam = 203, - TLS_alert_unsupported_ibcparam = 204, - TLS_alert_identity_need = 205, -} TLS_ALERT_DESCRIPTION; - -const char *tls_alert_description_text(int description); - - -int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, - const uint8_t *seed, size_t seedlen, - const uint8_t *more, size_t morelen, - size_t outlen, uint8_t *out); -int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]); -int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], - const char *label, const uint8_t *context, size_t context_len, - size_t outlen, uint8_t *out); -int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]); - -int tls_cbc_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *enc_key, - const uint8_t seq_num[8], const uint8_t header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int tls_cbc_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *dec_key, - const uint8_t seq_num[8], const uint8_t header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); -int tls_record_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen); - -int tls_seq_num_incr(uint8_t seq_num[8]); -int tls_random_generate(uint8_t random[32]); -int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent); -int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol); -int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], int format, int indent); - -int tls_secrets_print(FILE *fp, - const uint8_t *pre_master_secret, size_t pre_master_secret_len, - const uint8_t client_random[32], const uint8_t server_random[32], - const uint8_t master_secret[48], - const uint8_t *key_block, size_t key_block_len, - int format, int indent); - - -typedef struct { - uint8_t type; - uint8_t protocol[2]; - uint8_t data_length[2]; -} TLS_RECORD_HEADER; - -#define TLS_RECORD_HEADER_SIZE (1 + tls_uint16_size() + tls_uint16_size()) // 5 -#define TLS_MAX_PLAINTEXT_SIZE (1 << 14) // 16384 -#define TLS_MAX_COMPRESSED_SIZE ((1 << 14) + 1024) // 17408 -#define TLS_MAX_CIPHERTEXT_SIZE ((1 << 14) + 2048) // 18432 -#define TLS_MAX_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_MAX_CIPHERTEXT_SIZE) // 18437 - -#define tls_record_type(record) ((record)[0]) -#define tls_record_header(record) ((record)+0) -#define tls_record_protocol(record) (((uint16_t)((record)[1]) << 8) | (record)[2]) -#define tls_record_data(record) ((record)+TLS_RECORD_HEADER_SIZE) -#define tls_record_data_length(record) (((uint16_t)((record)[3]) << 8) | (record)[4]) -#define tls_record_length(record) (TLS_RECORD_HEADER_SIZE + tls_record_data_length(record)) - -int tls_record_set_type(uint8_t *record, int type); -int tls_record_set_protocol(uint8_t *record, int protocol); -int tls_record_set_data_length(uint8_t *record, size_t length); -int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen); - -// 握手消息ServerKeyExchange, ClientKeyExchange的解析依赖当前密码套件 -#define tls_format_set_cipher_suite(fmt,cipher) do {(fmt)|=((cipher)<<8);} while (0) -int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); -int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); - - -int tls_record_send(const uint8_t *record, size_t recordlen, int sock); -int tls_record_recv(uint8_t *record, size_t *recordlen, int sock); -int tls12_record_recv(uint8_t *record, size_t *recordlen, int sock); - - - -// Handshake -typedef struct { - uint8_t type; - uint8_t length[3]; -} TLS_HANDSHAKE_HEADER; - -#define TLS_HANDSHAKE_HEADER_SIZE 4 -#define TLS_MAX_HANDSHAKE_DATA_SIZE (TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE) - -#define tls_handshake_data(p) ((p) + TLS_HANDSHAKE_HEADER_SIZE) -//#define tls_handshake_data_length(p) - - -int tls_record_set_handshake(uint8_t *record, size_t *recordlen, - int type, const uint8_t *data, size_t datalen); -int tls_record_get_handshake(const uint8_t *record, - int *type, const uint8_t **data, size_t *datalen); -int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent); - -// HelloRequest -int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - -// ClientHello, ServerHello -#define TLS_MIN_SESSION_ID_SIZE 0 -#define TLS_MAX_SESSION_ID_SIZE 32 - -int tls_record_set_handshake_client_hello(uint8_t *record, size_t *recordlen, - int client_protocol, const uint8_t random[32], - const uint8_t *session_id, size_t session_id_len, - const int *cipher_suites, size_t cipher_suites_count, - const uint8_t *exts, size_t exts_len); -int tls_record_get_handshake_client_hello(const uint8_t *record, - int *client_protocol, const uint8_t **random, - const uint8_t **session_id, size_t *session_id_len, - const uint8_t **cipher_suites, size_t *cipher_suites_len, - const uint8_t **exts, size_t *exts_len); -int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - -int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, - int server_protocol, const uint8_t random[32], - const uint8_t *session_id, size_t session_id_len, - int cipher_suite, const uint8_t *exts, size_t exts_len); -int tls_record_get_handshake_server_hello(const uint8_t *record, - int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len, - int *cipher_suite, const uint8_t **exts, size_t *exts_len); -int tls_server_hello_print(FILE *fp, const uint8_t *server_hello, size_t len, int format, int indent); - -// Extensions -int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, - uint8_t **out, size_t *outlen); -int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen); -int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); - -int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, - uint8_t **out, size_t *outlen); -int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen); -int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen); - -int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen); -int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen); -int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen); -int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen); -int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen); - -int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, - uint8_t **out, size_t *outlen); -int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen); - -int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen); - -int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); -int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); -int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); -int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, - const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, - uint8_t **out, size_t *outlen); -int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point); - - -int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, - uint8_t **out, size_t *outlen); - -int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); -int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); -int tls_process_server_exts(const uint8_t *exts, size_t extslen, - int *ec_point_format, int *supported_group, int *signature_algor); - - -// Certificate -int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, - const uint8_t *certs, size_t certslen); -// 这个函数比较特殊,是直接解析了证书链,而不是返回指针 -// 应该提供一个独立的解析函数来解析TLS的证书链 -int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen); - -// ServerKeyExchange -int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, int format, int indent); - -#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE -int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen); -int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen); -int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, - int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen); -int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record, - int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen); -int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, - int format, int indent); - -int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *recordlen, - const uint8_t *sig, size_t siglen); -int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record, - const uint8_t **sig, size_t *siglen); -int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *sig, size_t siglen, int format, int indent); - - - -// CertificateRequest -#define TLS_MAX_CERTIFICATE_TYPES 256 -#define TLS_MAX_CA_NAMES_SIZE (TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint8_size() - tls_uint16_size()) - -int tls_authorities_from_certs(uint8_t *ca_names, size_t *ca_names_len, size_t maxlen, const uint8_t *certs, size_t certslen); -int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_namelen, const uint8_t *certs, size_t certslen); -int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len); - -int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, - const uint8_t *cert_types, size_t cert_types_len, - const uint8_t *ca_names, size_t ca_names_len); -int tls_record_get_handshake_certificate_request(const uint8_t *record, - const uint8_t **cert_types, size_t *cert_types_len, - const uint8_t **ca_names, size_t *ca_names_len); -int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - - -// ServerHelloDone -int tls_record_set_handshake_server_hello_done(uint8_t *record, size_t *recordlen); -int tls_record_get_handshake_server_hello_done(const uint8_t *record); -int tls_server_hello_done_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - -// ClientKeyExchange -int tls_record_set_handshake_client_key_exchange_pke(uint8_t *record, size_t *recordlen, - const uint8_t *enced_pms, size_t enced_pms_len); -int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record, - const uint8_t **enced_pms, size_t *enced_pms_len); -int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent); -int tls_client_key_exchange_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent); - -int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, - const SM2_POINT *point); // 这里不应该支持SM2_POINT类型 -int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point); -int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, - int format, int indent); - -// CertificateVerify -int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, - const uint8_t *sig, size_t siglen); -int tls_record_get_handshake_certificate_verify(const uint8_t *record, - const uint8_t **sig, size_t *siglen); -int tls_certificate_verify_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent); - -typedef enum { - TLS_client_verify_client_hello = 0, - TLS_client_verify_server_hello = 1, - TLS_client_verify_server_certificate = 2, - TLS_client_verify_server_key_exchange = 3, - TLS_client_verify_cert_request = 4, - TLS_client_verify_server_hello_done = 5, - TLS_client_verify_client_certificate = 6, - TLS_client_verify_client_key_exchange = 7, -} TLS_CLIENT_VERIFY_INDEX; - -typedef struct { - TLS_CLIENT_VERIFY_INDEX index; - uint8_t *handshake[8]; // Record data only, no record header - size_t handshake_len[8]; -} TLS_CLIENT_VERIFY_CTX; - -int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx); -int tls_client_verify_update(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *handshake, size_t handshake_len); -int tls_client_verify_finish(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen, const SM2_KEY *public_key); -void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx); - -// Finished -// FIXME: 支持TLS 1.3 提供MIN, MAX或TLS12, TLS13, TLCP... -#define TLS_VERIFY_DATA_SIZE 12 // TLS 1.3或者其他版本支持更长的verify_data -#define TLS_FINISHED_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_HANDSHAKE_HEADER_SIZE + TLS_VERIFY_DATA_SIZE) // 21 -#define TLS_MAX_PADDING_SIZE (1 + 255) -#define TLS_MAC_SIZE SM3_HMAC_SIZE -#define TLS_FINISHED_RECORD_BUF_SIZE (TLS_FINISHED_RECORD_SIZE + TLS_MAC_SIZE + TLS_MAX_PADDING_SIZE) // 309 - - -int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen, - const uint8_t *verify_data, size_t verify_data_len); -int tls_record_get_handshake_finished(const uint8_t *record, - const uint8_t **verify_data, size_t *verify_data_len); -int tls_finished_print(FILE *fp, const uint8_t *a, size_t len, int format, int indent); - - -// Alert -typedef struct { - uint8_t level; - uint8_t description; -} TLS_ALERT; - -#define TLS_ALERT_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + 2) - -int tls_record_set_alert(uint8_t *record, size_t *recordlen, int alert_level, int alert_description); -int tls_record_get_alert(const uint8_t *record, int *alert_level, int *alert_description); -int tls_alert_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - - -// ChangeCipherSpec -typedef struct { - uint8_t type; -} TLS_CHANGE_CIPHER_SPEC; - -const char *tls_change_cipher_spec_text(int change_cipher_spec); -int tls_change_cipher_spec_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); -int tls_record_set_change_cipher_spec(uint8_t *record, size_t *recordlen); -int tls_record_get_change_cipher_spec(const uint8_t *record); - -// ApplicationData -int tls_record_set_application_data(uint8_t *record, size_t *recordlen, - const uint8_t *data, size_t datalen); -int tls_record_get_application_data(uint8_t *record, - const uint8_t **data, size_t *datalen); -int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); - - - -enum { - TLS_server_mode = 0, - TLS_client_mode = 1, -}; - -#define TLS_MAX_CIPHER_SUITES_COUNT 64 - -typedef struct { - int protocol; - int is_client; - int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; - size_t cipher_suites_cnt; - uint8_t *cacerts; - size_t cacertslen; - uint8_t *certs; - size_t certslen; - SM2_KEY signkey; - SM2_KEY kenckey; - int verify_depth; -} TLS_CTX; - -int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client); -int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt); -int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth); -int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile, - const char *keyfile, const char *keypass); -int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile, - const char *signkeyfile, const char *signkeypass, - const char *kenckeyfile, const char *kenckeypass); -void tls_ctx_cleanup(TLS_CTX *ctx); - - - -#define TLS_MAX_CERTIFICATES_SIZE 2048 -#define TLS_DEFAULT_VERIFY_DEPTH 4 -#define TLS_MAX_VERIFY_DEPTH 5 - - -typedef struct { - int protocol; - int is_client; - int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; - size_t cipher_suites_cnt; - - int sock; - - uint8_t enced_record[TLS_MAX_RECORD_SIZE]; - size_t enced_record_len; - - - uint8_t record[TLS_MAX_RECORD_SIZE]; - - // 其实这个就不太对了,还是应该有一个完整的密文记录 - uint8_t databuf[TLS_MAX_PLAINTEXT_SIZE]; - uint8_t *data; - size_t datalen; - - int cipher_suite; - uint8_t session_id[32]; - size_t session_id_len; - uint8_t server_certs[TLS_MAX_CERTIFICATES_SIZE]; // 动态的可能会好一点 - size_t server_certs_len; - uint8_t client_certs[TLS_MAX_CERTIFICATES_SIZE]; - size_t client_certs_len; - uint8_t ca_certs[2048]; - size_t ca_certs_len; - - SM2_KEY sign_key; - SM2_KEY kenc_key; - - int verify_result; - - uint8_t master_secret[48]; - uint8_t key_block[96]; - - SM3_HMAC_CTX client_write_mac_ctx; - SM3_HMAC_CTX server_write_mac_ctx; - SM4_KEY client_write_enc_key; - SM4_KEY server_write_enc_key; - uint8_t client_seq_num[8]; - uint8_t server_seq_num[8]; - - uint8_t client_write_iv[12]; // tls13 - uint8_t server_write_iv[12]; // tls13 - BLOCK_CIPHER_KEY client_write_key; - BLOCK_CIPHER_KEY server_write_key; - -} TLS_CONNECT; - - -#define TLS_MAX_EXTENSIONS_SIZE 512 // 这个应该再考虑一下数值,是否可以用其他的缓冲区装载? - - -int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx); -int tls_set_socket(TLS_CONNECT *conn, int sock); -int tls_do_handshake(TLS_CONNECT *conn); -int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen); -int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen); -int tls_shutdown(TLS_CONNECT *conn); -void tls_cleanup(TLS_CONNECT *conn); - -int tlcp_do_connect(TLS_CONNECT *conn); -int tlcp_do_accept(TLS_CONNECT *conn); -int tls12_do_connect(TLS_CONNECT *conn); -int tls12_do_accept(TLS_CONNECT *conn); - - -#define TLS13_SM2_ID "TLSv1.3+GM+Cipher+Suite" -#define TLS13_SM2_ID_LENGTH (sizeof(TLS13_SM2_ID)-1) - -int tls13_do_connect(TLS_CONNECT *conn); -int tls13_do_accept(TLS_CONNECT *conn); - -int tls_send_alert(TLS_CONNECT *conn, int alert); -int tls_send_warning(TLS_CONNECT *conn, int alert); - -int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen); -int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen); - - -int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp, - FILE *client_certs_fp, const SM2_KEY *client_sign_key); -int tls13_accept(TLS_CONNECT *conn, int port, - FILE *server_certs_fp, const SM2_KEY *server_sign_key, - FILE *client_cacerts_fp); - - -int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); -int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); - - -int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); -int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, - int *ec_point_format, int *supported_group, int *signature_algor); - - -int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen); - -int tls13_extension_print(FILE *fp, int fmt, int ind, - int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen); -int tls13_extensions_print(FILE *fp, int fmt, int ind, - int handshake_type, const uint8_t *exts, size_t extslen); - -int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen); -int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen); -int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); -int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen); - - -int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], int record_type, - const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content - uint8_t *out, size_t *outlen); // TLSCiphertext.encrypted_record -int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - int *record_type, uint8_t *out, size_t *outlen); - - - -//#define TLS_DEBUG - -#ifdef TLS_DEBUG -# define tls_trace(s) fprintf(stderr,(s)) -# define tls_record_trace(fp,rec,reclen,fmt,ind) tls_record_print(fp,rec,reclen,fmt,ind) -# define tlcp_record_trace(fp,rec,reclen,fmt,ind) tlcp_record_print(fp,rec,reclen,fmt,ind) -# define tls12_record_trace(fp,rec,reclen,fmt,ind) tls12_record_print(fp,rec,reclen,fmt,ind) -# define tls13_record_trace(fp,rec,reclen,fmt,ind) tls13_record_print(fp,fmt,ind,rec,reclen) -#else -# define tls_trace(s) -# define tls_record_trace(fp,rec,reclen,fmt,ind) -# define tlcp_record_trace(fp,rec,reclen,fmt,ind) -# define tls12_record_trace(fp,rec,reclen,fmt,ind) -# define tls13_record_trace(fp,rec,reclen,fmt,ind) -#endif - - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_TLS_H +#define GMSSL_TLS_H + + +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +TLS Public API + + TLS_PROTOCOL + TLS_protocol_tlcp + TLS_protocol_tls12 + TLS_protocol_tls13 + + TLS_CIPHER_SUITE + TLS_cipher_ecc_sm4_cbc_sm3 + TLS_cipher_ecc_sm4_gcm_sm3 + TLS_cipher_ecdhe_sm4_cbc_sm3 + TLS_cipher_ecdhe_sm4_gcm_sm3 + TLS_cipher_sm4_gcm_sm3 + + TLS_CTX + tls_ctx_init + tls_ctx_set_cipher_suites + tls_ctx_set_ca_certificates + tls_ctx_set_certificate_and_key + tls_ctx_set_tlcp_server_certificate_and_keys + tls_ctx_cleanup + + TLS_CONNECT + tls_init + tls_set_socket + tls_do_handshake + tls_send + tls_recv + tls_shutdown + tls_cleanup +*/ + +typedef uint32_t uint24_t; + +#define tls_uint8_size() 1 +#define tls_uint16_size() 2 +#define tls_uint24_size() 3 + +void tls_uint8_to_bytes(uint8_t a, uint8_t **out, size_t *outlen); +void tls_uint16_to_bytes(uint16_t a, uint8_t **out, size_t *outlen); +void tls_uint24_to_bytes(uint24_t a, uint8_t **out, size_t *outlen); +void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen); +void tls_array_to_bytes(const uint8_t *data, size_t len, uint8_t **out, size_t *outlen); +void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); +void tls_uint16array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); +void tls_uint24array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen); +int tls_uint8_from_bytes(uint8_t *a, const uint8_t **in, size_t *inlen); +int tls_uint16_from_bytes(uint16_t *a, const uint8_t **in, size_t *inlen); +int tls_uint24_from_bytes(uint24_t *a, const uint8_t **in, size_t *inlen); +int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen); +int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen); +int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); +int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); +int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); +int tls_length_is_zero(size_t len); + + +typedef enum { + TLS_protocol_tlcp = 0x0101, + TLS_protocol_ssl2 = 0x0200, + TLS_protocol_ssl3 = 0x0300, + TLS_protocol_tls1 = 0x0301, + TLS_protocol_tls11 = 0x0302, + TLS_protocol_tls12 = 0x0303, + TLS_protocol_tls13 = 0x0304, + TLS_protocol_dtls1 = 0xfeff, // {254, 255} + TLS_protocol_dtls12 = 0xfefd, // {254, 253} +} TLS_PROTOCOL; + +const char *tls_protocol_name(int proto); + + +typedef enum { + TLS_cipher_null_with_null_null = 0x0000, + + // TLS 1.3, RFC 8998 + TLS_cipher_sm4_gcm_sm3 = 0x00c6, + TLS_cipher_sm4_ccm_sm3 = 0x00c7, + + // TLCP, GB/T 38636-2020, GM/T 0024-2012 + TLS_cipher_ecdhe_sm4_cbc_sm3 = 0xe011, // 可以让TLSv1.2使用这个 + TLS_cipher_ecdhe_sm4_gcm_sm3 = 0xe051, + TLS_cipher_ecc_sm4_cbc_sm3 = 0xe013, + TLS_cipher_ecc_sm4_gcm_sm3 = 0xe053, + TLS_cipher_ibsdh_sm4_cbc_sm3 = 0xe015, + TLS_cipher_ibsdh_sm4_gcm_sm3 = 0xe055, + TLS_cipher_ibc_sm4_cbc_sm3 = 0xe017, + TLS_cipher_ibc_sm4_gcm_sm3 = 0xe057, + TLS_cipher_rsa_sm4_cbc_sm3 = 0xe019, + TLS_cipher_rsa_sm4_gcm_sm3 = 0xe059, + TLS_cipher_rsa_sm4_cbc_sha256 = 0xe01c, + TLS_cipher_rsa_sm4_gcm_sha256 = 0xe05a, + + // TLS 1.3 RFC 8446 + TLS_cipher_aes_128_gcm_sha256 = 0x1301, // Mandatory-to-implement + TLS_cipher_aes_256_gcm_sha384 = 0x1302, // SHOULD implement + TLS_cipher_chacha20_poly1305_sha256 = 0x1303, // SHOULD implement + TLS_cipher_aes_128_ccm_sha256 = 0x1304, + TLS_cipher_aes_128_ccm_8_sha256 = 0x1305, + + TLS_cipher_empty_renegotiation_info_scsv = 0x00ff, +} TLS_CIPHER_SUITE; + +const char *tls_cipher_suite_name(int cipher); +int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len, + const int *server_ciphers, size_t server_ciphers_cnt, int *selected_cipher); +int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count); + + +typedef enum { + TLS_compression_null = 0, + TLS_compression_default = 1, +} TLS_COMPRESSION_METHOD; + +const char *tls_compression_method_name(int meth); + + +typedef enum { + TLS_record_invalid = 0, // TLS 1.3 + TLS_record_change_cipher_spec = 20, // 0x14 + TLS_record_alert = 21, // 0x15 + TLS_record_handshake = 22, // 0x16 + TLS_record_application_data = 23, // 0x17 + TLS_record_heartbeat = 24, // 0x18 + TLS_record_tls12_cid = 25, // 0x19 +} TLS_RECORD_TYPE; + +const char *tls_record_type_name(int type); + + +typedef enum { + TLS_handshake_hello_request = 0, + TLS_handshake_client_hello = 1, + TLS_handshake_server_hello = 2, + TLS_handshake_hello_verify_request = 3, + TLS_handshake_new_session_ticket = 4, + TLS_handshake_end_of_early_data = 5, + TLS_handshake_hello_retry_request = 6, + TLS_handshake_encrypted_extensions = 8, + TLS_handshake_certificate = 11, + TLS_handshake_server_key_exchange = 12, + TLS_handshake_certificate_request = 13, + TLS_handshake_server_hello_done = 14, + TLS_handshake_certificate_verify = 15, + TLS_handshake_client_key_exchange = 16, + TLS_handshake_finished = 20, + TLS_handshake_certificate_url = 21, + TLS_handshake_certificate_status = 22, + TLS_handshake_supplemental_data = 23, + TLS_handshake_key_update = 24, + TLS_handshake_compressed_certificate = 25, + TLS_handshake_ekt_key = 26, + TLS_handshake_message_hash = 254, +} TLS_HANDSHAKE_TYPE; + +const char *tls_handshake_type_name(int type); + + +typedef enum { + TLS_cert_type_rsa_sign = 1, + TLS_cert_type_dss_sign = 2, + TLS_cert_type_rsa_fixed_dh = 3, + TLS_cert_type_dss_fixed_dh = 4, + TLS_cert_type_rsa_ephemeral_dh_RESERVED = 5, + TLS_cert_type_dss_ephemeral_dh_RESERVED = 6, + TLS_cert_type_fortezza_dms_RESERVED = 20, + TLS_cert_type_ecdsa_sign = 64, // also for sm2 + TLS_cert_type_rsa_fixed_ecdh = 65, + TLS_cert_type_ecdsa_fixed_ecdh = 66, + TLS_cert_type_gost_sign256 = 67, + TLS_cert_type_gost_sign512 = 68, + TLS_cert_type_ibc_params = 80, +} TLS_CERTIFICATE_TYPE; + +const char *tls_cert_type_name(int type); +int tls_cert_type_from_oid(int oid); + +typedef enum { + TLS_extension_server_name = 0, + TLS_extension_max_fragment_length = 1, + TLS_extension_client_certificate_url = 2, + TLS_extension_trusted_ca_keys = 3, + TLS_extension_truncated_hmac = 4, + TLS_extension_status_request = 5, + TLS_extension_user_mapping = 6, + TLS_extension_client_authz = 7, + TLS_extension_server_authz = 8, + TLS_extension_cert_type = 9, + TLS_extension_supported_groups = 10, + TLS_extension_ec_point_formats = 11, + TLS_extension_srp = 12, + TLS_extension_signature_algorithms = 13, + TLS_extension_use_srtp = 14, + TLS_extension_heartbeat = 15, + TLS_extension_application_layer_protocol_negotiation= 16, + TLS_extension_status_request_v2 = 17, + TLS_extension_signed_certificate_timestamp = 18, + TLS_extension_client_certificate_type = 19, + TLS_extension_server_certificate_type = 20, + TLS_extension_padding = 21, + TLS_extension_encrypt_then_mac = 22, + TLS_extension_extended_master_secret = 23, + TLS_extension_token_binding = 24, + TLS_extension_cached_info = 25, + TLS_extension_tls_lts = 26, + TLS_extension_compress_certificate = 27, + TLS_extension_record_size_limit = 28, + TLS_extension_pwd_protect = 29, + TLS_extension_pwd_clear = 30, + TLS_extension_password_salt = 31, + TLS_extension_ticket_pinning = 32, + TLS_extension_tls_cert_with_extern_psk = 33, + TLS_extension_delegated_credentials = 34, + TLS_extension_session_ticket = 35, + TLS_extension_TLMSP = 36, + TLS_extension_TLMSP_proxying = 37, + TLS_extension_TLMSP_delegate = 38, + TLS_extension_supported_ekt_ciphers = 39, + TLS_extension_pre_shared_key = 41, + TLS_extension_early_data = 42, + TLS_extension_supported_versions = 43, + TLS_extension_cookie = 44, + TLS_extension_psk_key_exchange_modes = 46, + TLS_extension_certificate_authorities = 47, + TLS_extension_oid_filters = 48, + TLS_extension_post_handshake_auth = 49, + TLS_extension_signature_algorithms_cert = 50, + TLS_extension_key_share = 51, + TLS_extension_transparency_info = 52, + TLS_extension_connection_id = 53, + TLS_extension_external_id_hash = 55, + TLS_extension_external_session_id = 56, + TLS_extension_quic_transport_parameters = 57, + TLS_extension_ticket_request = 58, + TLS_extension_renegotiation_info = 65281, +} TLS_EXTENSION_TYPE; + +const char *tls_extension_name(int ext); + + +typedef enum { + TLS_point_uncompressed = 0, + TLS_point_ansix962_compressed_prime = 1, + TLS_point_ansix962_compressed_char2 = 2, +} TLS_EC_POINT_FORMAT; + +const char *tls_ec_point_format_name(int format); + + +typedef enum { + TLS_curve_type_explicit_prime = 1, + TLS_curve_type_explicit_char2 = 2, + TLS_curve_type_named_curve = 3, +} TLS_CURVE_TYPE; + +const char *tls_curve_type_name(int type); + + +// 与其支持v2,还不如直接修改v2,让v2和v3兼容 + +typedef enum { + TLS_curve_secp256k1 = 22, + TLS_curve_secp256r1 = 23, + TLS_curve_secp384r1 = 24, + TLS_curve_secp521r1 = 25, + TLS_curve_brainpoolp256r1 = 26, + TLS_curve_brainpoolp384r1 = 27, + TLS_curve_brainpoolp512r1 = 28, + TLS_curve_x25519 = 29, + TLS_curve_x448 = 30, + TLS_curve_brainpoolp256r1tls13 = 31, + TLS_curve_brainpoolp384r1tls13 = 32, + TLS_curve_brainpoolp512r1tls13 = 33, + TLS_curve_sm2p256v1 = 41, // GmSSLv2: 30 +} TLS_NAMED_CURVE; + +const char *tls_named_curve_name(int curve); + + +typedef enum { + TLS_sig_rsa_pkcs1_sha1 = 0x0201, + TLS_sig_ecdsa_sha1 = 0x0203, + TLS_sig_rsa_pkcs1_sha256 = 0x0401, + TLS_sig_ecdsa_secp256r1_sha256 = 0x0403, + TLS_sig_rsa_pkcs1_sha256_legacy = 0x0420, + TLS_sig_rsa_pkcs1_sha384 = 0x0501, + TLS_sig_ecdsa_secp384r1_sha384 = 0x0503, + TLS_sig_rsa_pkcs1_sha384_legacy = 0x0520, + TLS_sig_rsa_pkcs1_sha512 = 0x0601, + TLS_sig_ecdsa_secp521r1_sha512 = 0x0603, + TLS_sig_rsa_pkcs1_sha512_legacy = 0x0620, + TLS_sig_sm2sig_sm3 = 0x0708, // GmSSLv2: 0x0707 + TLS_sig_rsa_pss_rsae_sha256 = 0x0804, + TLS_sig_rsa_pss_rsae_sha384 = 0x0805, + TLS_sig_rsa_pss_rsae_sha512 = 0x0806, + TLS_sig_ed25519 = 0x0807, + TLS_sig_ed448 = 0x0808, + TLS_sig_rsa_pss_pss_sha256 = 0x0809, + TLS_sig_rsa_pss_pss_sha384 = 0x080A, + TLS_sig_rsa_pss_pss_sha512 = 0x080B, + TLS_sig_ecdsa_brainpoolP256r1tls13_sha256 = 0x081A, + TLS_sig_ecdsa_brainpoolP384r1tls13_sha384 = 0x081B, + TLS_sig_ecdsa_brainpoolP512r1tls13_sha512 = 0x081C, +} TLS_SIGNATURE_SCHEME; + +const char *tls_signature_scheme_name(int scheme); + + +typedef enum { + TLS_change_cipher_spec = 1, +} TLS_CHANGE_CIPHER_SPEC_TYPE; + + +typedef enum { + TLS_alert_level_warning = 1, + TLS_alert_level_fatal = 2, +} TLS_ALERT_LEVEL; + +const char *tls_alert_level_name(int level); + + +typedef enum { + TLS_alert_close_notify = 0, + TLS_alert_unexpected_message = 10, + TLS_alert_bad_record_mac = 20, + TLS_alert_decryption_failed = 21, + TLS_alert_record_overflow = 22, + TLS_alert_decompression_failure = 30, + TLS_alert_handshake_failure = 40, + TLS_alert_no_certificate = 41, + TLS_alert_bad_certificate = 42, + TLS_alert_unsupported_certificate = 43, + TLS_alert_certificate_revoked = 44, + TLS_alert_certificate_expired = 45, + TLS_alert_certificate_unknown = 46, + TLS_alert_illegal_parameter = 47, + TLS_alert_unknown_ca = 48, + TLS_alert_access_denied = 49, + TLS_alert_decode_error = 50, + TLS_alert_decrypt_error = 51, + TLS_alert_export_restriction = 60, + TLS_alert_protocol_version = 70, + TLS_alert_insufficient_security = 71, + TLS_alert_internal_error = 80, + TLS_alert_user_canceled = 90, + TLS_alert_no_renegotiation = 100, + TLS_alert_unsupported_extension = 110, + TLS_alert_unsupported_site2site = 200, + TLS_alert_no_area = 201, + TLS_alert_unsupported_areatype = 202, + TLS_alert_bad_ibcparam = 203, + TLS_alert_unsupported_ibcparam = 204, + TLS_alert_identity_need = 205, +} TLS_ALERT_DESCRIPTION; + +const char *tls_alert_description_text(int description); + + +int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, + const uint8_t *seed, size_t seedlen, + const uint8_t *more, size_t morelen, + size_t outlen, uint8_t *out); +int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]); +int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], + const char *label, const uint8_t *context, size_t context_len, + size_t outlen, uint8_t *out); +int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]); + +int tls_cbc_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *enc_key, + const uint8_t seq_num[8], const uint8_t header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int tls_cbc_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *dec_key, + const uint8_t seq_num[8], const uint8_t header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); +int tls_record_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen); + +int tls_seq_num_incr(uint8_t seq_num[8]); +int tls_random_generate(uint8_t random[32]); +int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent); +int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol); +int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], int format, int indent); + +int tls_secrets_print(FILE *fp, + const uint8_t *pre_master_secret, size_t pre_master_secret_len, + const uint8_t client_random[32], const uint8_t server_random[32], + const uint8_t master_secret[48], + const uint8_t *key_block, size_t key_block_len, + int format, int indent); + + +typedef struct { + uint8_t type; + uint8_t protocol[2]; + uint8_t data_length[2]; +} TLS_RECORD_HEADER; + +#define TLS_RECORD_HEADER_SIZE (1 + tls_uint16_size() + tls_uint16_size()) // 5 +#define TLS_MAX_PLAINTEXT_SIZE (1 << 14) // 16384 +#define TLS_MAX_COMPRESSED_SIZE ((1 << 14) + 1024) // 17408 +#define TLS_MAX_CIPHERTEXT_SIZE ((1 << 14) + 2048) // 18432 +#define TLS_MAX_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_MAX_CIPHERTEXT_SIZE) // 18437 + +#define tls_record_type(record) ((record)[0]) +#define tls_record_header(record) ((record)+0) +#define tls_record_protocol(record) (((uint16_t)((record)[1]) << 8) | (record)[2]) +#define tls_record_data(record) ((record)+TLS_RECORD_HEADER_SIZE) +#define tls_record_data_length(record) (((uint16_t)((record)[3]) << 8) | (record)[4]) +#define tls_record_length(record) (TLS_RECORD_HEADER_SIZE + tls_record_data_length(record)) + +int tls_record_set_type(uint8_t *record, int type); +int tls_record_set_protocol(uint8_t *record, int protocol); +int tls_record_set_data_length(uint8_t *record, size_t length); +int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen); + +// 握手消息ServerKeyExchange, ClientKeyExchange的解析依赖当前密码套件 +#define tls_format_set_cipher_suite(fmt,cipher) do {(fmt)|=((cipher)<<8);} while (0) +int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); +int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent); + + +int tls_record_send(const uint8_t *record, size_t recordlen, int sock); +int tls_record_recv(uint8_t *record, size_t *recordlen, int sock); +int tls12_record_recv(uint8_t *record, size_t *recordlen, int sock); + + + +// Handshake +typedef struct { + uint8_t type; + uint8_t length[3]; +} TLS_HANDSHAKE_HEADER; + +#define TLS_HANDSHAKE_HEADER_SIZE 4 +#define TLS_MAX_HANDSHAKE_DATA_SIZE (TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE) + +#define tls_handshake_data(p) ((p) + TLS_HANDSHAKE_HEADER_SIZE) +//#define tls_handshake_data_length(p) + + +int tls_record_set_handshake(uint8_t *record, size_t *recordlen, + int type, const uint8_t *data, size_t datalen); +int tls_record_get_handshake(const uint8_t *record, + int *type, const uint8_t **data, size_t *datalen); +int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent); + +// HelloRequest +int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + +// ClientHello, ServerHello +#define TLS_MIN_SESSION_ID_SIZE 0 +#define TLS_MAX_SESSION_ID_SIZE 32 + +int tls_record_set_handshake_client_hello(uint8_t *record, size_t *recordlen, + int client_protocol, const uint8_t random[32], + const uint8_t *session_id, size_t session_id_len, + const int *cipher_suites, size_t cipher_suites_count, + const uint8_t *exts, size_t exts_len); +int tls_record_get_handshake_client_hello(const uint8_t *record, + int *client_protocol, const uint8_t **random, + const uint8_t **session_id, size_t *session_id_len, + const uint8_t **cipher_suites, size_t *cipher_suites_len, + const uint8_t **exts, size_t *exts_len); +int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + +int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, + int server_protocol, const uint8_t random[32], + const uint8_t *session_id, size_t session_id_len, + int cipher_suite, const uint8_t *exts, size_t exts_len); +int tls_record_get_handshake_server_hello(const uint8_t *record, + int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len, + int *cipher_suite, const uint8_t **exts, size_t *exts_len); +int tls_server_hello_print(FILE *fp, const uint8_t *server_hello, size_t len, int format, int indent); + +// Extensions +int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); + +int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen); + +int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen); + +int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, + uint8_t **out, size_t *outlen); +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); + +int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen); + +int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t **out, size_t *outlen); +int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point); + + +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen); + +int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); +int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); +int tls_process_server_exts(const uint8_t *exts, size_t extslen, + int *ec_point_format, int *supported_group, int *signature_algor); + + +// Certificate +int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, + const uint8_t *certs, size_t certslen); +// 这个函数比较特殊,是直接解析了证书链,而不是返回指针 +// 应该提供一个独立的解析函数来解析TLS的证书链 +int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen); + +// ServerKeyExchange +int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, int format, int indent); + +#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE +int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen); +int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen); +int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, + int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen); +int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record, + int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen); +int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, + int format, int indent); + +int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *recordlen, + const uint8_t *sig, size_t siglen); +int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record, + const uint8_t **sig, size_t *siglen); +int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *sig, size_t siglen, int format, int indent); + + + +// CertificateRequest +#define TLS_MAX_CERTIFICATE_TYPES 256 +#define TLS_MAX_CA_NAMES_SIZE (TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint8_size() - tls_uint16_size()) + +int tls_authorities_from_certs(uint8_t *ca_names, size_t *ca_names_len, size_t maxlen, const uint8_t *certs, size_t certslen); +int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_namelen, const uint8_t *certs, size_t certslen); +int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len); + +int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, + const uint8_t *cert_types, size_t cert_types_len, + const uint8_t *ca_names, size_t ca_names_len); +int tls_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **cert_types, size_t *cert_types_len, + const uint8_t **ca_names, size_t *ca_names_len); +int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + + +// ServerHelloDone +int tls_record_set_handshake_server_hello_done(uint8_t *record, size_t *recordlen); +int tls_record_get_handshake_server_hello_done(const uint8_t *record); +int tls_server_hello_done_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + +// ClientKeyExchange +int tls_record_set_handshake_client_key_exchange_pke(uint8_t *record, size_t *recordlen, + const uint8_t *enced_pms, size_t enced_pms_len); +int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record, + const uint8_t **enced_pms, size_t *enced_pms_len); +int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent); +int tls_client_key_exchange_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent); + +int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, + const SM2_POINT *point); // 这里不应该支持SM2_POINT类型 +int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point); +int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, + int format, int indent); + +// CertificateVerify +int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, + const uint8_t *sig, size_t siglen); +int tls_record_get_handshake_certificate_verify(const uint8_t *record, + const uint8_t **sig, size_t *siglen); +int tls_certificate_verify_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent); + +typedef enum { + TLS_client_verify_client_hello = 0, + TLS_client_verify_server_hello = 1, + TLS_client_verify_server_certificate = 2, + TLS_client_verify_server_key_exchange = 3, + TLS_client_verify_cert_request = 4, + TLS_client_verify_server_hello_done = 5, + TLS_client_verify_client_certificate = 6, + TLS_client_verify_client_key_exchange = 7, +} TLS_CLIENT_VERIFY_INDEX; + +typedef struct { + TLS_CLIENT_VERIFY_INDEX index; + uint8_t *handshake[8]; // Record data only, no record header + size_t handshake_len[8]; +} TLS_CLIENT_VERIFY_CTX; + +int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx); +int tls_client_verify_update(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *handshake, size_t handshake_len); +int tls_client_verify_finish(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen, const SM2_KEY *public_key); +void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx); + +// Finished +// FIXME: 支持TLS 1.3 提供MIN, MAX或TLS12, TLS13, TLCP... +#define TLS_VERIFY_DATA_SIZE 12 // TLS 1.3或者其他版本支持更长的verify_data +#define TLS_FINISHED_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + TLS_HANDSHAKE_HEADER_SIZE + TLS_VERIFY_DATA_SIZE) // 21 +#define TLS_MAX_PADDING_SIZE (1 + 255) +#define TLS_MAC_SIZE SM3_HMAC_SIZE +#define TLS_FINISHED_RECORD_BUF_SIZE (TLS_FINISHED_RECORD_SIZE + TLS_MAC_SIZE + TLS_MAX_PADDING_SIZE) // 309 + + +int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen, + const uint8_t *verify_data, size_t verify_data_len); +int tls_record_get_handshake_finished(const uint8_t *record, + const uint8_t **verify_data, size_t *verify_data_len); +int tls_finished_print(FILE *fp, const uint8_t *a, size_t len, int format, int indent); + + +// Alert +typedef struct { + uint8_t level; + uint8_t description; +} TLS_ALERT; + +#define TLS_ALERT_RECORD_SIZE (TLS_RECORD_HEADER_SIZE + 2) + +int tls_record_set_alert(uint8_t *record, size_t *recordlen, int alert_level, int alert_description); +int tls_record_get_alert(const uint8_t *record, int *alert_level, int *alert_description); +int tls_alert_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + + +// ChangeCipherSpec +typedef struct { + uint8_t type; +} TLS_CHANGE_CIPHER_SPEC; + +const char *tls_change_cipher_spec_text(int change_cipher_spec); +int tls_change_cipher_spec_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); +int tls_record_set_change_cipher_spec(uint8_t *record, size_t *recordlen); +int tls_record_get_change_cipher_spec(const uint8_t *record); + +// ApplicationData +int tls_record_set_application_data(uint8_t *record, size_t *recordlen, + const uint8_t *data, size_t datalen); +int tls_record_get_application_data(uint8_t *record, + const uint8_t **data, size_t *datalen); +int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent); + + + +enum { + TLS_server_mode = 0, + TLS_client_mode = 1, +}; + +#define TLS_MAX_CIPHER_SUITES_COUNT 64 + +typedef struct { + int protocol; + int is_client; + int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; + size_t cipher_suites_cnt; + uint8_t *cacerts; + size_t cacertslen; + uint8_t *certs; + size_t certslen; + SM2_KEY signkey; + SM2_KEY kenckey; + int verify_depth; +} TLS_CTX; + +int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client); +int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt); +int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth); +int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile, + const char *keyfile, const char *keypass); +int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile, + const char *signkeyfile, const char *signkeypass, + const char *kenckeyfile, const char *kenckeypass); +void tls_ctx_cleanup(TLS_CTX *ctx); + + + +#define TLS_MAX_CERTIFICATES_SIZE 2048 +#define TLS_DEFAULT_VERIFY_DEPTH 4 +#define TLS_MAX_VERIFY_DEPTH 5 + + +typedef struct { + int protocol; + int is_client; + int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; + size_t cipher_suites_cnt; + + int sock; + + uint8_t enced_record[TLS_MAX_RECORD_SIZE]; + size_t enced_record_len; + + + uint8_t record[TLS_MAX_RECORD_SIZE]; + + // 其实这个就不太对了,还是应该有一个完整的密文记录 + uint8_t databuf[TLS_MAX_PLAINTEXT_SIZE]; + uint8_t *data; + size_t datalen; + + int cipher_suite; + uint8_t session_id[32]; + size_t session_id_len; + uint8_t server_certs[TLS_MAX_CERTIFICATES_SIZE]; // 动态的可能会好一点 + size_t server_certs_len; + uint8_t client_certs[TLS_MAX_CERTIFICATES_SIZE]; + size_t client_certs_len; + uint8_t ca_certs[2048]; + size_t ca_certs_len; + + SM2_KEY sign_key; + SM2_KEY kenc_key; + + int verify_result; + + uint8_t master_secret[48]; + uint8_t key_block[96]; + + SM3_HMAC_CTX client_write_mac_ctx; + SM3_HMAC_CTX server_write_mac_ctx; + SM4_KEY client_write_enc_key; + SM4_KEY server_write_enc_key; + uint8_t client_seq_num[8]; + uint8_t server_seq_num[8]; + + uint8_t client_write_iv[12]; // tls13 + uint8_t server_write_iv[12]; // tls13 + BLOCK_CIPHER_KEY client_write_key; + BLOCK_CIPHER_KEY server_write_key; + +} TLS_CONNECT; + + +#define TLS_MAX_EXTENSIONS_SIZE 512 // 这个应该再考虑一下数值,是否可以用其他的缓冲区装载? + + +int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx); +int tls_set_socket(TLS_CONNECT *conn, int sock); +int tls_do_handshake(TLS_CONNECT *conn); +int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen); +int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen); +int tls_shutdown(TLS_CONNECT *conn); +void tls_cleanup(TLS_CONNECT *conn); + +int tlcp_do_connect(TLS_CONNECT *conn); +int tlcp_do_accept(TLS_CONNECT *conn); +int tls12_do_connect(TLS_CONNECT *conn); +int tls12_do_accept(TLS_CONNECT *conn); + + +#define TLS13_SM2_ID "TLSv1.3+GM+Cipher+Suite" +#define TLS13_SM2_ID_LENGTH (sizeof(TLS13_SM2_ID)-1) + +int tls13_do_connect(TLS_CONNECT *conn); +int tls13_do_accept(TLS_CONNECT *conn); + +int tls_send_alert(TLS_CONNECT *conn, int alert); +int tls_send_warning(TLS_CONNECT *conn, int alert); + +int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen); +int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen); + + +int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp, + FILE *client_certs_fp, const SM2_KEY *client_sign_key); +int tls13_accept(TLS_CONNECT *conn, int port, + FILE *server_certs_fp, const SM2_KEY *server_sign_key, + FILE *client_cacerts_fp); + + +int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); +int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); + + +int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); +int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, + int *ec_point_format, int *supported_group, int *signature_algor); + + +int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen); + +int tls13_extension_print(FILE *fp, int fmt, int ind, + int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen); +int tls13_extensions_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *exts, size_t extslen); + +int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen); +int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen); +int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); +int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen); + + +int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], int record_type, + const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content + uint8_t *out, size_t *outlen); // TLSCiphertext.encrypted_record +int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + int *record_type, uint8_t *out, size_t *outlen); + + + +//#define TLS_DEBUG + +#ifdef TLS_DEBUG +# define tls_trace(s) fprintf(stderr,(s)) +# define tls_record_trace(fp,rec,reclen,fmt,ind) tls_record_print(fp,rec,reclen,fmt,ind) +# define tlcp_record_trace(fp,rec,reclen,fmt,ind) tlcp_record_print(fp,rec,reclen,fmt,ind) +# define tls12_record_trace(fp,rec,reclen,fmt,ind) tls12_record_print(fp,rec,reclen,fmt,ind) +# define tls13_record_trace(fp,rec,reclen,fmt,ind) tls13_record_print(fp,fmt,ind,rec,reclen) +#else +# define tls_trace(s) +# define tls_record_trace(fp,rec,reclen,fmt,ind) +# define tlcp_record_trace(fp,rec,reclen,fmt,ind) +# define tls12_record_trace(fp,rec,reclen,fmt,ind) +# define tls13_record_trace(fp,rec,reclen,fmt,ind) +#endif + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 2391975f..e1e43919 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,29 +7,30 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_VERSION_H -#define GMSSL_VERSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Version Public API - - gmssl_version_num - gmssl_version_str -*/ - -#define GMSSL_VERSION_NUM 30000 -#define GMSSL_VERSION_STR "GmSSL 3.0.0 Beta" - -int gmssl_version_num(void); -const char *gmssl_version_str(void); - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_VERSION_H +#define GMSSL_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Version Public API + + gmssl_version_num + gmssl_version_str +*/ + +#define GMSSL_VERSION_NUM 30000 +#define GMSSL_VERSION_STR "GmSSL 3.0.0 Beta" + +int gmssl_version_num(void); +const char *gmssl_version_str(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509.h b/include/gmssl/x509.h index 51986d79..f0634e78 100644 --- a/include/gmssl/x509.h +++ b/include/gmssl/x509.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,355 +7,356 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_H -#define GMSSL_X509_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -X509 Public API - - x509_name_add_rdn - x509_name_add_country_name - x509_name_add_state_or_province_name - x509_name_add_locality_name - x509_name_add_organization_name - x509_name_add_organizational_unit_name - x509_name_add_common_name - x509_name_add_domain_component - x509_name_to_der - x509_name_from_der - x509_name_print - x509_name_get_value_by_type - x509_name_get_common_name - - x509_cert_sign - x509_cert_verify - x509_cert_verify_by_ca_cert - x509_cert_get_issuer_and_serial_number - x509_cert_get_issuer - x509_cert_get_subject - x509_cert_get_subject_public_key - x509_cert_to_der - x509_cert_from_der - x509_cert_to_pem - x509_cert_from_pem - x509_cert_print -*/ - -enum X509_Version { - X509_version_v1 = 0, - X509_version_v2 = 1, - X509_version_v3 = 2, -}; - -const char *x509_version_name(int version); -int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen); -int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen); - -/* -Time ::= CHOICE { - utcTime UTCTime, - generalTime GeneralizedTime } -*/ -int x509_time_to_der(time_t a, uint8_t **out, size_t *outlen); -int x509_time_from_der(time_t *a, const uint8_t **in, size_t *inlen); - -/* -Validity ::= SEQUENCE { - notBefore Time, - notAfter Time } -*/ -#define X509_VALIDITY_MIN_DAYS 1 -#define X509_VALIDITY_MAX_DAYS (365 * 10) // ROOTCA, CA需要更长的时间! -int x509_validity_add_days(time_t *not_after, time_t not_before, int days); -int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen); -int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen); -int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -AttributeTypeAndValue ::= SEQUENCE { - type OBJECT IDENTIFIER, - value ANY -- DEFINED BY AttributeType } - -id-at - name DirectoryName 1..ub-name - surname DirectoryName 1..ub-name - givenName DirectoryName 1..ub-name - initials DirectoryName 1..ub-name - generationQualifier DirectoryName 1..ub-name - commonName DirectoryName 1..ub-common-name - localityName DirectoryName 1..ub-locality-name - stateOrProvinceName DirectoryName 1..ub-state-name - organizationName DirectoryName 1..ub-organization-name - organizationalUnitName DirectoryName 1..ub-organizational-unit-name - title DirectoryName 1..ub-title - dnQualifier PrintableString N/A - countryName PrintableString 2..2 - serialNumber PrintableString 1..ub-serial-number - pseudonym DirectoryName 1..ub-pseudonym - domainComponent IA5String N/A -*/ -#define X509_ub_name 32768 -#define X509_ub_common_name 64 -#define X509_ub_locality_name 128 -#define X509_ub_state_name 128 -#define X509_ub_organization_name 64 -#define X509_ub_organizational_unit_name 64 -#define X509_ub_title 64 -#define X509_ub_serial_number 64 -#define X509_ub_pseudonym 128 - -int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen); -int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); -int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); -int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue -*/ -int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen, uint8_t **out, size_t *outlen); -int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **more, size_t *mlen, const uint8_t **in, size_t *inlen); -int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -Name ::= SEQUENCE OF RelativeDistinguishedName - -Example: - SEQUENCE LEN - SET LEN - SEQUENCE LEN OID=countryName, String=CN - SET LEN - SEQUENCE LEN OID=stateName, String=CN - SEQUENCE LEN OID=unknown, String=ABC - SET LEN - SEQUENCE LEN OID=commonNmame, String=ABC -*/ -int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen); -int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2] ); // val: PrintableString SIZE(2) -int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); -int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); -int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); -int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); -int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); -int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, const char *val, size_t vlen); // val: IA5String - -int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, - const char *country, const char *state, const char *locality, - const char *org, const char *org_unit, const char *common_name); - -#define x509_name_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_name_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) -int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen); -int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen); -int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen); - -int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING } - -algorithm.algorithm = OID_ec_public_key; -algorithm.parameters = OID_sm2; -subjectPublicKey = ECPoint -*/ -#define x509_public_key_info_to_der(key,out,outlen) sm2_public_key_info_to_der(key,out,outlen) -#define x509_public_key_info_from_der(key,in,inlen) sm2_public_key_info_from_der(key,in,inlen) -int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -Extension ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value -*/ -int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); -int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); -int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -[3] EXPLICIT SEQUENCE OF Extension - */ -int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -#define x509_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(3,d,dlen,out,outlen) -#define x509_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(3,d,dlen,in,inlen) - -int x509_exts_get_count(const uint8_t *d, size_t dlen, size_t *cnt); -int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index, - int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, - const uint8_t **val, size_t *vlen); -int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid, - int *critical, const uint8_t **val, size_t *vlen); -int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -TBSCertificate ::= SEQUENCE { - version [0] EXPLICIT INTEGER DEFAULT v1, - serialNumber INTEGER, - siganture AlgorithmIdentifier, - issuer Name, - validity Validity, - subject Name, - subjectPulbicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 - subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 - extensions [3] EXPLICIT Extensions OPTIONAL -- If present, must be v3 } -*/ -#define X509_SERIAL_NUMBER_MIN_LEN 1 -#define X509_SERIAL_NUMBER_MAX_LEN 20 -#define X509_UNIQUE_ID_MIN_LEN 32 -#define X509_UNIQUE_ID_MAX_LEN 32 - -int x509_tbs_cert_to_der( - int version, - const uint8_t *serial, size_t serial_len, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t not_before, time_t not_after, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, - const uint8_t *subject_unique_id, size_t subject_unique_id_len, - const uint8_t *exts, size_t exts_len, - uint8_t **out, size_t *outlen); -int x509_tbs_cert_from_der( - int *version, - const uint8_t **serial, size_t *serial_len, - int *signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *not_before, time_t *not_after, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, - const uint8_t **subject_unique_id, size_t *subject_unique_id_len, - const uint8_t **exts, size_t *exts_len, - const uint8_t **in, size_t *inlen); -int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING } -*/ -int x509_certificate_to_der( - const uint8_t *tbs, size_t tbslen, - int signature_algor, - const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen); -int x509_certificate_from_der( - const uint8_t **tbs, size_t *tbslen, - int *signature_algor, - const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen); -int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -// x509_cert functions -int x509_cert_sign( - uint8_t *cert, size_t *certlen, size_t maxlen, - int version, - const uint8_t *serial, size_t serial_len, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t not_before, time_t not_after, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, - const uint8_t *subject_unique_id, size_t subject_unique_id_len, - const uint8_t *exts, size_t exts_len, - const SM2_KEY *sign_key, - const char *signer_id, size_t signer_id_len); -int x509_cert_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, - const char *signer_id, size_t signer_id_len); -int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, - const char *signer_id, size_t signer_id_len); - -int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); -int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); -int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp); -int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); -int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp); -int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp); -int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); - -int x509_cert_get_details(const uint8_t *a, size_t alen, - int *version, - const uint8_t **serial_number, size_t *serial_number_len, - int *inner_signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *not_before, time_t *not_after, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, - const uint8_t **subject_unique_id, size_t *subject_unique_id_len, - const uint8_t **extensions, size_t *extensions_len, - int *signature_algor, - const uint8_t **signature, size_t *signature_len); - -/* -IssuerAndSerialNumber ::= SEQUENCE { - isser Name, - serialNumber INTEGER } -*/ -int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len); -int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **name, size_t *namelen); -int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **subj, size_t *subj_len); -int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key); - -int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp); -int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp); -int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt); -int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen); -int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen); -int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen); - -int x509_certs_get_cert_by_issuer_and_serial_number( - const uint8_t *certs, size_t certs_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - const uint8_t **cert, size_t *cert_len); - - -typedef enum { - X509_verify_err_cert_revoked = -2, - X509_verify_err_cert_not_yet_valid = -3, - X509_verify_err_cert_has_expired = -4, - X509_verify_err_cert_chain_too_long = -5, -} X509_VERIFY_ERR; - -int x509_certs_verify(const uint8_t *certs, size_t certslen, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); -int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); -int x509_certs_get_subjects(const uint8_t *certs, size_t certslen, uint8_t *names, size_t *nameslen); -int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file); -int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file); - - - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_X509_H +#define GMSSL_X509_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +X509 Public API + + x509_name_add_rdn + x509_name_add_country_name + x509_name_add_state_or_province_name + x509_name_add_locality_name + x509_name_add_organization_name + x509_name_add_organizational_unit_name + x509_name_add_common_name + x509_name_add_domain_component + x509_name_to_der + x509_name_from_der + x509_name_print + x509_name_get_value_by_type + x509_name_get_common_name + + x509_cert_sign + x509_cert_verify + x509_cert_verify_by_ca_cert + x509_cert_get_issuer_and_serial_number + x509_cert_get_issuer + x509_cert_get_subject + x509_cert_get_subject_public_key + x509_cert_to_der + x509_cert_from_der + x509_cert_to_pem + x509_cert_from_pem + x509_cert_print +*/ + +enum X509_Version { + X509_version_v1 = 0, + X509_version_v2 = 1, + X509_version_v3 = 2, +}; + +const char *x509_version_name(int version); +int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen); +int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen); + +/* +Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } +*/ +int x509_time_to_der(time_t a, uint8_t **out, size_t *outlen); +int x509_time_from_der(time_t *a, const uint8_t **in, size_t *inlen); + +/* +Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } +*/ +#define X509_VALIDITY_MIN_DAYS 1 +#define X509_VALIDITY_MAX_DAYS (365 * 10) // ROOTCA, CA需要更长的时间! +int x509_validity_add_days(time_t *not_after, time_t not_before, int days); +int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen); +int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen); +int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +AttributeTypeAndValue ::= SEQUENCE { + type OBJECT IDENTIFIER, + value ANY -- DEFINED BY AttributeType } + +id-at + name DirectoryName 1..ub-name + surname DirectoryName 1..ub-name + givenName DirectoryName 1..ub-name + initials DirectoryName 1..ub-name + generationQualifier DirectoryName 1..ub-name + commonName DirectoryName 1..ub-common-name + localityName DirectoryName 1..ub-locality-name + stateOrProvinceName DirectoryName 1..ub-state-name + organizationName DirectoryName 1..ub-organization-name + organizationalUnitName DirectoryName 1..ub-organizational-unit-name + title DirectoryName 1..ub-title + dnQualifier PrintableString N/A + countryName PrintableString 2..2 + serialNumber PrintableString 1..ub-serial-number + pseudonym DirectoryName 1..ub-pseudonym + domainComponent IA5String N/A +*/ +#define X509_ub_name 32768 +#define X509_ub_common_name 64 +#define X509_ub_locality_name 128 +#define X509_ub_state_name 128 +#define X509_ub_organization_name 64 +#define X509_ub_organizational_unit_name 64 +#define X509_ub_title 64 +#define X509_ub_serial_number 64 +#define X509_ub_pseudonym 128 + +int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen); +int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); +int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); +int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue +*/ +int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen, uint8_t **out, size_t *outlen); +int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, const uint8_t **more, size_t *mlen, const uint8_t **in, size_t *inlen); +int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +Name ::= SEQUENCE OF RelativeDistinguishedName + +Example: + SEQUENCE LEN + SET LEN + SEQUENCE LEN OID=countryName, String=CN + SET LEN + SEQUENCE LEN OID=stateName, String=CN + SEQUENCE LEN OID=unknown, String=ABC + SET LEN + SEQUENCE LEN OID=commonNmame, String=ABC +*/ +int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, int oid, int tag, const uint8_t *val, size_t vlen, const uint8_t *more, size_t mlen); +int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2] ); // val: PrintableString SIZE(2) +int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, int tag, const uint8_t *val, size_t vlen); +int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, const char *val, size_t vlen); // val: IA5String + +int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, + const char *country, const char *state, const char *locality, + const char *org, const char *org_unit, const char *common_name); + +#define x509_name_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_name_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen); +int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen); +int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen); + +int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } + +algorithm.algorithm = OID_ec_public_key; +algorithm.parameters = OID_sm2; +subjectPublicKey = ECPoint +*/ +#define x509_public_key_info_to_der(key,out,outlen) sm2_public_key_info_to_der(key,out,outlen) +#define x509_public_key_info_from_der(key,in,inlen) sm2_public_key_info_from_der(key,in,inlen) +int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value +*/ +int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen); +int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, const uint8_t **val, size_t *vlen, const uint8_t **in, size_t *inlen); +int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +[3] EXPLICIT SEQUENCE OF Extension + */ +int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +#define x509_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(3,d,dlen,out,outlen) +#define x509_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(3,d,dlen,in,inlen) + +int x509_exts_get_count(const uint8_t *d, size_t dlen, size_t *cnt); +int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index, + int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, + const uint8_t **val, size_t *vlen); +int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid, + int *critical, const uint8_t **val, size_t *vlen); +int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +TBSCertificate ::= SEQUENCE { + version [0] EXPLICIT INTEGER DEFAULT v1, + serialNumber INTEGER, + siganture AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPulbicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 + subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL, -- If present, must be v2,v3 + extensions [3] EXPLICIT Extensions OPTIONAL -- If present, must be v3 } +*/ +#define X509_SERIAL_NUMBER_MIN_LEN 1 +#define X509_SERIAL_NUMBER_MAX_LEN 20 +#define X509_UNIQUE_ID_MIN_LEN 32 +#define X509_UNIQUE_ID_MAX_LEN 32 + +int x509_tbs_cert_to_der( + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, + const uint8_t *subject_unique_id, size_t subject_unique_id_len, + const uint8_t *exts, size_t exts_len, + uint8_t **out, size_t *outlen); +int x509_tbs_cert_from_der( + int *version, + const uint8_t **serial, size_t *serial_len, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, + const uint8_t **subject_unique_id, size_t *subject_unique_id_len, + const uint8_t **exts, size_t *exts_len, + const uint8_t **in, size_t *inlen); +int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +Certificate ::= SEQUENCE { + tbsCertificate TBSCertificate, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } +*/ +int x509_certificate_to_der( + const uint8_t *tbs, size_t tbslen, + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_certificate_from_der( + const uint8_t **tbs, size_t *tbslen, + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +// x509_cert functions +int x509_cert_sign( + uint8_t *cert, size_t *certlen, size_t maxlen, + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, + const uint8_t *subject_unique_id, size_t subject_unique_id_len, + const uint8_t *exts, size_t exts_len, + const SM2_KEY *sign_key, + const char *signer_id, size_t signer_id_len); +int x509_cert_verify(const uint8_t *a, size_t alen, const SM2_KEY *pub_key, + const char *signer_id, size_t signer_id_len); +int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len); + +int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); +int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); +int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp); +int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); +int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp); +int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp); +int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); + +int x509_cert_get_details(const uint8_t *a, size_t alen, + int *version, + const uint8_t **serial_number, size_t *serial_number_len, + int *inner_signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, + const uint8_t **subject_unique_id, size_t *subject_unique_id_len, + const uint8_t **extensions, size_t *extensions_len, + int *signature_algor, + const uint8_t **signature, size_t *signature_len); + +/* +IssuerAndSerialNumber ::= SEQUENCE { + isser Name, + serialNumber INTEGER } +*/ +int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len); +int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **name, size_t *namelen); +int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **subj, size_t *subj_len); +int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key); + +int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp); +int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp); +int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt); +int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen); +int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen); +int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen); + +int x509_certs_get_cert_by_issuer_and_serial_number( + const uint8_t *certs, size_t certs_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + const uint8_t **cert, size_t *cert_len); + + +typedef enum { + X509_verify_err_cert_revoked = -2, + X509_verify_err_cert_not_yet_valid = -3, + X509_verify_err_cert_has_expired = -4, + X509_verify_err_cert_chain_too_long = -5, +} X509_VERIFY_ERR; + +int x509_certs_verify(const uint8_t *certs, size_t certslen, + const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); +int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, + const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); +int x509_certs_get_subjects(const uint8_t *certs, size_t certslen, uint8_t *names, size_t *nameslen); +int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file); +int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file); + + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_alg.h b/include/gmssl/x509_alg.h index 5b43a663..873ea727 100644 --- a/include/gmssl/x509_alg.h +++ b/include/gmssl/x509_alg.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,63 +7,64 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_ALG_H -#define GMSSL_X509_ALG_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY } -*/ - -const char *x509_digest_algor_name(int oid); -int x509_digest_algor_from_name(const char *name); -int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -const char *x509_encryption_algor_name(int oid); -int x509_encryption_algor_from_name(const char *name); -int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); -int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); -int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -#define X509_ALGOR_ALLOW_EC_NULL_PARAM 1 -const char *x509_signature_algor_name(int oid); -int x509_signature_algor_from_name(const char *name); -int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -const char *x509_public_key_encryption_algor_name(int oid); -int x509_public_key_encryption_algor_from_name(const char *name); -int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, const uint8_t **in, size_t *inlen); -int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -const char *x509_public_key_algor_name(int oid); -int x509_public_key_algor_from_name(const char *name); -int x509_public_key_algor_to_der(int oid, int curve, uint8_t **out, size_t *outlen); -int x509_public_key_algor_from_der(int *oid, int *curve_or_null, const uint8_t **in, size_t *inlen); -int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_X509_ALG_H +#define GMSSL_X509_ALG_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY } +*/ + +const char *x509_digest_algor_name(int oid); +int x509_digest_algor_from_name(const char *name); +int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_encryption_algor_name(int oid); +int x509_encryption_algor_from_name(const char *name); +int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen); +int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen); +int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +#define X509_ALGOR_ALLOW_EC_NULL_PARAM 1 +const char *x509_signature_algor_name(int oid); +int x509_signature_algor_from_name(const char *name); +int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_public_key_encryption_algor_name(int oid); +int x509_public_key_encryption_algor_from_name(const char *name); +int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, const uint8_t **in, size_t *inlen); +int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +const char *x509_public_key_algor_name(int oid); +int x509_public_key_algor_from_name(const char *name); +int x509_public_key_algor_to_der(int oid, int curve, uint8_t **out, size_t *outlen); +int x509_public_key_algor_from_der(int *oid, int *curve_or_null, const uint8_t **in, size_t *inlen); +int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_crl.h b/include/gmssl/x509_crl.h index 811dcff2..9d13b203 100644 --- a/include/gmssl/x509_crl.h +++ b/include/gmssl/x509_crl.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,270 +7,271 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#ifndef GMSSL_X509_CRL_H -#define GMSSL_X509_CRL_H - - -#ifdef __cplusplus -extern "C" { -#endif - -/* -X509 CRL Public API - - -*/ - - - -/* -CRLReason ::= ENUMERATED -*/ -typedef enum { - X509_cr_unspecified = 0, - X509_cr_key_compromise = 1, - X509_cr_ca_compromise = 2 , - X509_cr_affiliation_changed = 3, - X509_cr_superseded = 4, - X509_cr_cessation_of_operation = 5, - X509_cr_certificate_hold = 6, - X509_cr_not_assigned = 7, - X509_cr_remove_from_crl = 8, - X509_cr_privilege_withdrawn = 9, - X509_cr_aa_compromise = 10, -} X509_CRL_REASON; - -const char *x509_crl_reason_name(int reason); -int x509_crl_reason_from_name(int *reason, const char *name); -int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen); -int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen); - -/* -CRL Entry Extensions: - OID_ce_crl_reasons ENUMERATED - OID_ce_invalidity_date GeneralizedTime - OID_ce_certificate_issuer SEQUENCE GeneralNames -*/ -const char *x509_crl_entry_ext_id_name(int oid); -int x509_crl_entry_ext_id_from_name(const char *name); -int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); - -int x509_crl_entry_exts_add_reason( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - int reason); -int x509_crl_entry_exts_add_invalidity_date( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - time_t tv); -int x509_crl_entry_exts_add_certificate_issuer( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *d, size_t dlen); -#define x509_crl_entry_exts_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_crl_entry_exts_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) -int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -RevokedCertificate ::= SEQUENCE { - userCertificate CertificateSerialNumber, - revocationDate Time, - crlEntryExtensions Extensions OPTIONAL } -*/ -int x509_revoked_cert_to_der( - const uint8_t *serial, size_t serial_len, - time_t revoke_date, - const uint8_t *entry_exts, size_t entry_exts_len, - uint8_t **out, size_t *outlen); -int x509_revoked_cert_from_der( - const uint8_t **serial, size_t *serial_len, - time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len, - const uint8_t **in, size_t *inlen); -int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -RevokedCertificates ::= SEQUENCE OF RevokedCertificate -*/ -int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen, - const uint8_t *serial, size_t serial_len, - time_t revoke_date, - const uint8_t *entry_exts, size_t entry_exts_len); -int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen, - const uint8_t *serial, size_t serial_len, - time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len); -#define x509_revoked_certs_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_revoked_certs_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) -int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -CRL Extensions: - OID_ce_authority_key_identifier SEQUENCE AuthorityKeyIdentifier - OID_ce_issuer_alt_name SEQUENCE GeneralNames - OID_ce_crl_number INTEGER - OID_ce_delta_crl_indicator INTEGER - OID_ce_issuing_distribution_point SEQUENCE IssuingDistributionPoint -*/ -const char *x509_crl_ext_id_name(int oid); -int x509_crl_ext_id_from_name(const char *name); -int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); -int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); - - -/* -IssuingDistributionPoint ::= SEQUENCE { - distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, - onlyContainsUserCerts [1] IMPLICIT BOOLEAN DEFAULT FALSE, - onlyContainsCACerts [2] IMPLICIT BOOLEAN DEFAULT FALSE, - onlySomeReasons [3] IMPLICIT ReasonFlags OPTIONAL, - indirectCRL [4] IMPLICIT BOOLEAN DEFAULT FALSE, - onlyContainsAttributeCerts [5] IMPLICIT BOOLEAN DEFAULT FALSE } -*/ - -int x509_issuing_distribution_point_to_der( - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int only_contains_user_certs, - int only_contains_ca_certs, - int only_some_reasons, - int indirect_crl, - int only_contains_attr_certs, - uint8_t **out, size_t *outlen); -int x509_issuing_distribution_point_from_der( - int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, - int *only_contains_user_certs, - int *only_contains_ca_certs, - int *only_some_reasons, - int *indirect_crl, - int *only_contains_attr_certs, - const uint8_t **in, size_t *inlen); - -int x509_crl_exts_add_authority_key_identifier( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len); -int x509_crl_exts_add_issuer_alt_name( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *d, size_t dlen); -int x509_crl_exts_add_crl_number( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - int num); -int x509_crl_exts_add_delta_crl_indicator( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - int num); -int x509_crl_exts_add_issuing_distribution_point( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *dist_point, size_t dist_point_len, - int only_contains_user_certs, - int only_contains_ca_certs, - int only_some_reasons, - int indirect_crl, - int only_contains_attr_certs); - -#define x509_crl_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(0,d,dlen,out,outlen) -#define x509_crl_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(0,d,dlen,in,inlen) -int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - - -/* -TBSCertList ::= SEQUENCE { - version INTEGER OPTIONAL, -- if present, MUST be v2 - signature AlgorithmIdentifier, - issuer Name, - thisUpdate Time, - nextUpdate Time OPTIONAL, - revokedCertificates RevokedCertificates OPTIONAL, - crlExtensions [0] EXPLICIT Extensions OPTIONAL, -- if present, MUST be v2 } -*/ -int x509_tbs_crl_to_der( - int version, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t this_update, - time_t next_update, - const uint8_t *revoked_certs, size_t revoked_certs_len, - const uint8_t *exts, size_t exts_len, - uint8_t **out, size_t *outlen); -int x509_tbs_crl_from_der( - int *version, - int *signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *this_update, - time_t *next_update, - const uint8_t **revoked_certs, size_t *revoked_certs_len, - const uint8_t **exts, size_t *exts_len, - const uint8_t **in, size_t *inlen); -int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -CertificateList ::= SEQUENCE { - tbsCertList TBSCertList, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING } -*/ -int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len, - int signature_algor, const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen); -int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len, - int *signature_algor, const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen); -int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -// x509_crl_ functions -int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); -int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); -int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp); -int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); -int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp); // 去掉这个函数 -int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); // 去掉这个函数 - - -int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); - -int x509_crl_sign(uint8_t *crl, size_t *crl_len, - int version, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t this_update, - time_t next_update, - const uint8_t *revoked_certs, size_t revoked_certs_len, - const uint8_t *exts, size_t exts_len, - const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); -int x509_crl_verify(const uint8_t *a, size_t alen, - const SM2_KEY *sign_pub_key, const char *signer_id, size_t signer_id_len); -int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, - const char *signer_id, size_t signer_id_len); - -int x509_crl_get_details(const uint8_t *crl, size_t crl_len, - int *version, - const uint8_t **issuer, size_t *issuer_len, - time_t *this_update, - time_t *next_update, - const uint8_t **revoked_certs, size_t *revoked_certs_len, - const uint8_t **exts, size_t *exts_len, - int *signature_algor, - const uint8_t **sig, size_t *siglen); -int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, - const uint8_t **issuer, size_t *issuer_len); - -int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, - const uint8_t *serial, size_t serial_len, time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len); - - - -int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -#ifdef __cplusplus -} -#endif -#endif + + + +#ifndef GMSSL_X509_CRL_H +#define GMSSL_X509_CRL_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +X509 CRL Public API + + +*/ + + + +/* +CRLReason ::= ENUMERATED +*/ +typedef enum { + X509_cr_unspecified = 0, + X509_cr_key_compromise = 1, + X509_cr_ca_compromise = 2 , + X509_cr_affiliation_changed = 3, + X509_cr_superseded = 4, + X509_cr_cessation_of_operation = 5, + X509_cr_certificate_hold = 6, + X509_cr_not_assigned = 7, + X509_cr_remove_from_crl = 8, + X509_cr_privilege_withdrawn = 9, + X509_cr_aa_compromise = 10, +} X509_CRL_REASON; + +const char *x509_crl_reason_name(int reason); +int x509_crl_reason_from_name(int *reason, const char *name); +int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen); +int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen); + +/* +CRL Entry Extensions: + OID_ce_crl_reasons ENUMERATED + OID_ce_invalidity_date GeneralizedTime + OID_ce_certificate_issuer SEQUENCE GeneralNames +*/ +const char *x509_crl_entry_ext_id_name(int oid); +int x509_crl_entry_ext_id_from_name(const char *name); +int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); + +int x509_crl_entry_exts_add_reason( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int reason); +int x509_crl_entry_exts_add_invalidity_date( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + time_t tv); +int x509_crl_entry_exts_add_certificate_issuer( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *d, size_t dlen); +#define x509_crl_entry_exts_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_crl_entry_exts_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +RevokedCertificate ::= SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL } +*/ +int x509_revoked_cert_to_der( + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len, + uint8_t **out, size_t *outlen); +int x509_revoked_cert_from_der( + const uint8_t **serial, size_t *serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len, + const uint8_t **in, size_t *inlen); +int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +RevokedCertificates ::= SEQUENCE OF RevokedCertificate +*/ +int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen, + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len); +int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen, + const uint8_t *serial, size_t serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len); +#define x509_revoked_certs_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_revoked_certs_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CRL Extensions: + OID_ce_authority_key_identifier SEQUENCE AuthorityKeyIdentifier + OID_ce_issuer_alt_name SEQUENCE GeneralNames + OID_ce_crl_number INTEGER + OID_ce_delta_crl_indicator INTEGER + OID_ce_issuing_distribution_point SEQUENCE IssuingDistributionPoint +*/ +const char *x509_crl_ext_id_name(int oid); +int x509_crl_ext_id_from_name(const char *name); +int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); +int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen); + + +/* +IssuingDistributionPoint ::= SEQUENCE { + distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, + onlyContainsUserCerts [1] IMPLICIT BOOLEAN DEFAULT FALSE, + onlyContainsCACerts [2] IMPLICIT BOOLEAN DEFAULT FALSE, + onlySomeReasons [3] IMPLICIT ReasonFlags OPTIONAL, + indirectCRL [4] IMPLICIT BOOLEAN DEFAULT FALSE, + onlyContainsAttributeCerts [5] IMPLICIT BOOLEAN DEFAULT FALSE } +*/ + +int x509_issuing_distribution_point_to_der( + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int only_contains_user_certs, + int only_contains_ca_certs, + int only_some_reasons, + int indirect_crl, + int only_contains_attr_certs, + uint8_t **out, size_t *outlen); +int x509_issuing_distribution_point_from_der( + int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, + int *only_contains_user_certs, + int *only_contains_ca_certs, + int *only_some_reasons, + int *indirect_crl, + int *only_contains_attr_certs, + const uint8_t **in, size_t *inlen); + +int x509_crl_exts_add_authority_key_identifier( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len); +int x509_crl_exts_add_issuer_alt_name( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *d, size_t dlen); +int x509_crl_exts_add_crl_number( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num); +int x509_crl_exts_add_delta_crl_indicator( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num); +int x509_crl_exts_add_issuing_distribution_point( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *dist_point, size_t dist_point_len, + int only_contains_user_certs, + int only_contains_ca_certs, + int only_some_reasons, + int indirect_crl, + int only_contains_attr_certs); + +#define x509_crl_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(0,d,dlen,out,outlen) +#define x509_crl_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(0,d,dlen,in,inlen) +int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + + +/* +TBSCertList ::= SEQUENCE { + version INTEGER OPTIONAL, -- if present, MUST be v2 + signature AlgorithmIdentifier, + issuer Name, + thisUpdate Time, + nextUpdate Time OPTIONAL, + revokedCertificates RevokedCertificates OPTIONAL, + crlExtensions [0] EXPLICIT Extensions OPTIONAL, -- if present, MUST be v2 } +*/ +int x509_tbs_crl_to_der( + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, + time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + uint8_t **out, size_t *outlen); +int x509_tbs_crl_from_der( + int *version, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *this_update, + time_t *next_update, + const uint8_t **revoked_certs, size_t *revoked_certs_len, + const uint8_t **exts, size_t *exts_len, + const uint8_t **in, size_t *inlen); +int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificateList ::= SEQUENCE { + tbsCertList TBSCertList, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } +*/ +int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len, + int signature_algor, const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len, + int *signature_algor, const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +// x509_crl_ functions +int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen); +int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen); +int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp); +int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); +int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp); // 去掉这个函数 +int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp); // 去掉这个函数 + + +int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); + +int x509_crl_sign(uint8_t *crl, size_t *crl_len, + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, + time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); +int x509_crl_verify(const uint8_t *a, size_t alen, + const SM2_KEY *sign_pub_key, const char *signer_id, size_t signer_id_len); +int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len); + +int x509_crl_get_details(const uint8_t *crl, size_t crl_len, + int *version, + const uint8_t **issuer, size_t *issuer_len, + time_t *this_update, + time_t *next_update, + const uint8_t **revoked_certs, size_t *revoked_certs_len, + const uint8_t **exts, size_t *exts_len, + int *signature_algor, + const uint8_t **sig, size_t *siglen); +int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, + const uint8_t **issuer, size_t *issuer_len); + +int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, + const uint8_t *serial, size_t serial_len, time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len); + + + +int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_ext.h b/include/gmssl/x509_ext.h index 3595d18d..e2570c54 100644 --- a/include/gmssl/x509_ext.h +++ b/include/gmssl/x509_ext.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,538 +7,539 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_EXT_H -#define GMSSL_X509_EXT_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Extensions: - - 1. AuthorityKeyIdentifier SEQUENCE AuthorityKeyIdentifier - 2. SubjectKeyIdentifier OCTET STRING - 3. KeyUsage BIT STRING - 4. CertificatePolicies SEQUENCE OF SEQUENCE CertificatePolicies - 5. PolicyMappings SEQUENCE OF SEQUENCE PolicyMappings - 6. SubjectAltName SEQUENCE OF SEQUENCE GeneralNames - 7. IssuerAltName SEQUENCE OF SEQUENCE GeneralNames - 8. SubjectDirectoryAttributes SEQUENCE OF SEQUENCE Attributes - 9. BasicConstraints SEQUENCE BasicConstraints - 10. NameConstraints SEQUENCE NameConstraints - 11. PolicyConstraints SEQUENCE PolicyConstraints - 12. ExtKeyUsageSyntax SEQUENCE OF OBJECT IDENTIFIER - 13. CRLDistributionPoints SEQUENCE OF SEQUENCE DistributionPoints - 14. InhibitAnyPolicy INTEGER - 15. FreshestCRL SEQUENCE OF SEQUENCE DistributionPoints -*/ - -int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len); -int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, - const SM2_KEY *public_key); -int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits); -int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, - const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, - const uint8_t *excluded_subtrees, size_t excluded_subtrees_len); -int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, - int require_explicit_policy, int inhibit_policy_mapping); -int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int ca, int path_len_constraint); -int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const int *key_purposes, size_t key_purposes_cnt); -int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); -int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs); -int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); - -int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen, - int oid, int critical, const uint8_t *d, size_t dlen); - -/* -OtherName ::= SEQUENCE { - type-id OBJECT IDENTIFIER, -- known oid from x509_rdn_oid such as OID_at_common_name, or oid nodes - value [0] EXPLICIT ANY DEFINED BY type-id } -*/ -int x509_other_name_to_der( - const uint32_t *nodes, size_t nodes_count, - const uint8_t *value, size_t value_len, - uint8_t **out, size_t *outlen); -int x509_other_name_from_der( - uint32_t *nodes, size_t *nodes_count, - const uint8_t **value, size_t *valuelen, - const uint8_t **in, size_t *inlen); -int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -EDIPartyName ::= SEQUENCE { - nameAssigner [0] EXPLICIT DirectoryString OPTIONAL, - partyName [1] EXPLICIT DirectoryString } -*/ -int x509_edi_party_name_to_der( - int assigner_tag, const uint8_t *assigner, size_t assigner_len, - int party_name_tag, const uint8_t *party_name, size_t party_name_len, - uint8_t **out, size_t *outlen); -int x509_edi_party_name_from_der( - int *assigner_tag, const uint8_t **assigner, size_t *assigner_len, - int *party_name_tag, const uint8_t **party_name, size_t *party_name_len, - const uint8_t **in, size_t *inlen); -int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -GeneralName ::= CHOICE { - otherName [0] IMPLICIT OtherName, -- 只在GeneralName中出现 - rfc822Name [1] IMPLICIT IA5String, - dNSName [2] IMPLICIT IA5String, - x400Address [3] IMPLICIT ORAddress, - directoryName [4] IMPLICIT Name, -- SEQENCE OF,因此是d,dlen - ediPartyName [5] IMPLICIT EDIPartyName, -- 只在GeneralName中出现 - uniformResourceIdentifier [6] IMPLICIT IA5String, - iPAddress [7] IMPLICIT OCTET STRING, -- 4 bytes or string? - registeredID [8] IMPLICIT OBJECT IDENTIFIER } -*/ -typedef enum { - X509_gn_other_name = 0, - X509_gn_rfc822_name = 1, - X509_gn_dns_name = 2, - X509_gn_x400_address = 3, - X509_gn_directory_name = 4, - X509_gn_edi_party_name = 5, - X509_gn_uniform_resource_identifier = 6, - X509_gn_ip_address = 7, - X509_gn_registered_id = 8, -} X509_GENERAL_NAME_CHOICE; - -int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen); - -/* -GeneralNames ::= SEQUENCE OF GeneralName -*/ -#define x509_general_names_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_general_names_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) -int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - int choice, const uint8_t *d, size_t dlen); -int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - const uint32_t *nodes, size_t nodes_count, - const uint8_t *value, size_t value_len); -#define x509_general_names_add_rfc822_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_rfc822_name,(uint8_t*)s,strlen(s)) -#define x509_general_names_add_dns_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_dns_name,(uint8_t*)s,strlen(s)) -#define x509_general_names_add_x400_address(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_x400_address,d,dlen) -#define x509_general_names_add_directory_name(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_directory_name,d,dlen) -int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - int assigner_tag, const uint8_t *assigner, size_t assigner_len, - int party_name_tag, const uint8_t *party_name, size_t party_name_len); -#define x509_general_names_add_uniform_resource_identifier(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_uniform_resource_identifier,(uint8_t*)s,strlen(s)) -#define x509_general_names_add_ip_address(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_ip_address,(uint8_t*)s,strlen(s)) -int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen, - const uint32_t *nodes, size_t nodes_cnt); - -/* -AuthorityKeyIdentifier ::= SEQUENCE { - keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL, - authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, - authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL } -*/ -int x509_authority_key_identifier_to_der( - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - uint8_t **out, size_t *outlen); -int x509_authority_key_identifier_from_der( - const uint8_t **keyid, size_t *keyid_len, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial, size_t *serial_len, - const uint8_t **in, size_t *inlen); -int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -SubjectKeyIdentifier ::= OCTET STRING -*/ -#define X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN 16 -#define X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN 64 - -/* -KeyUsage ::= BIT STRING { - digitalSignature (0), - nonRepudiation (1), -- recent renamed contentCommitment - keyEncipherment (2), - dataEncipherment (3), - keyAgreement (4), - keyCertSign (5), - cRLSign (6), - encipherOnly (7), - decipherOnly (8) } -*/ -#define X509_KU_DIGITAL_SIGNATURE (1 << 0) -#define X509_KU_NON_REPUDIATION (1 << 1) -#define X509_KU_KEY_ENCIPHERMENT (1 << 2) -#define X509_KU_DATA_ENCIPHERMENT (1 << 3) -#define X509_KU_KEY_AGREEMENT (1 << 4) -#define X509_KU_KEY_CERT_SIGN (1 << 5) -#define X509_KU_CRL_SIGN (1 << 6) -#define X509_KU_ENCIPHER_ONLY (1 << 7) -#define X509_KU_DECIPHER_ONLY (1 << 8) - -const char *x509_key_usage_name(int flag); -int x509_key_usage_from_name(int *flag, const char *name); -#define x509_key_usage_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) -#define x509_key_usage_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) -int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits); - -/* -NoticeReference ::= SEQUENCE { - organization DisplayText, - noticeNumbers SEQUENCE OF INTEGER } - -UserNotice ::= SEQUENCE { - noticeRef NoticeReference OPTIONAL, - explicitText DisplayText OPTIONAL } -*/ -#define X509_MAX_NOTICE_NUMBERS 32 - -int x509_notice_reference_to_der( - int org_tag, const uint8_t *org, size_t org_len, - const int *notice_numbers, size_t notice_numbers_cnt, - uint8_t **out, size_t *outlen); -int x509_notice_reference_from_der( - int *org_tag, const uint8_t **org, size_t *org_len, - int *notice_numbers, size_t *notice_numbers_cnt, size_t max_notice_numbers, - const uint8_t **in, size_t *inlen); -int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int x509_user_notice_to_der( - int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len, - const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt, - int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len, - uint8_t **out, size_t *outlen); -int x509_user_notice_from_der( - int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len, - int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, - int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len, - const uint8_t **in, size_t *inlen); -int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -PolicyQualifierInfo ::= SEQUENCE { - policyQualifierId PolicyQualifierId, - qualifier ANY DEFINED BY policyQualifierId } - - switch(policyQualifierId) - case id-qt-cps : qualifier ::= IA5String - case id-qt-unotice : qualifier ::= UserNotice -*/ -int x509_policy_qualifier_info_to_der( - int oid, - const uint8_t *qualifier, size_t qualifier_len, - uint8_t **out, size_t *outlen); -int x509_policy_qualifier_info_from_der( - int *oid, - const uint8_t **qualifier, size_t *qualifier_len, - const uint8_t **in, size_t *inlen); -int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -#define x509_policy_qualifier_infos_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_policy_qualifier_infos_from_der(d,dlen,in,ineln) asn1_sequence_from_der(d,dlen,in,inlen) -int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -PolicyInformation ::= SEQUENCE { - policyIdentifier CertPolicyId, - policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL } - -CertPolicyId ::= OBJECT IDENTIFIER -- undefined -*/ - -int x509_policy_information_to_der( - int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, - const uint8_t *qualifiers, size_t qualifiers_len, - uint8_t **out, size_t *outlen); -int x509_policy_information_from_der( - int *policy_oid, uint32_t *policy_nodes, size_t *policy_nodes_cnt, - const uint8_t **qualifiers, size_t *qualifiers_len, - const uint8_t **in, size_t *inlen); -int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation -*/ -int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen, - int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, - const uint8_t *qualifiers, size_t qualifiers_len); -int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -#define x509_certificate_policies_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_certificate_policies_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) - -/* -PolicyMapping ::= SEQUENCE { - issuerDomainPolicy CertPolicyId, -- id-anyPolicy or other undefined - subjectDomainPolicy CertPolicyId } -*/ -int x509_policy_mapping_to_der( - int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, - int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt, - uint8_t **out, size_t *outlen); -int x509_policy_mapping_from_der( - int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt, - int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt, - const uint8_t **in, size_t *inlen); -int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -PolicyMappings ::= SEQUENCE OF PolicyMapping -*/ -int x509_policy_mappings_add_policy_mapping(uint8_t *d, size_t *dlen, size_t maxlen, - int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, - int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt); -int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -#define x509_policy_mappings_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_policy_mappings_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) - -/* -SubjectAltName ::= GeneralNames -*/ -#define x509_subject_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) - -/* -IssuerAltName ::= GeneralNames -*/ -#define x509_issuer_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) - -/* -SubjectDirectoryAttributes ::= SEQUENCE OF Attribute - -Attribute ::= SEQUENCE { - type OBJECT IDENTIFIER, - values SET OF ANY } -*/ -int x509_attribute_to_der( - const uint32_t *nodes, size_t nodes_cnt, - const uint8_t *values, size_t values_len, - uint8_t **out, size_t *outlen); -int x509_attribute_from_der( - int *oid, uint32_t *nodes, size_t *nodes_cnt, - const uint8_t **values, size_t *values_len, - const uint8_t **in, size_t *inlen); -int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int x509_attributes_add_attribute(uint8_t *d, size_t *dlen, size_t maxlen, - const uint32_t *nodes, size_t nodes_cnt, - const uint8_t *values, size_t values_len); -int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -#define x509_attributes_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_attributes_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) - -/* -BasicConstraints ::= SEQUENCE { - cA BOOLEAN DEFAULT FALSE, - pathLenConstraint INTEGER (0..MAX) OPTIONAL } -*/ -int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen); -int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen); -int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -GeneralSubtree ::= SEQUENCE { - base GeneralName, - minimum [0] IMPLICIT BaseDistance DEFAULT 0, - maximum [1] IMPLICIT BaseDistance OPTIONAL } - -BaseDistance ::= INTEGER (0..MAX) -*/ -int x509_general_subtree_to_der( - int base_choice, const uint8_t *base, size_t base_len, - int minimum, int maximum, - uint8_t **out, size_t *outlen); -int x509_general_subtree_from_der( - int *base_choice, const uint8_t **base, size_t *base_len, - int *minimum, int *maximum, - const uint8_t **in, size_t *inlen); -int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree -*/ -// 应该参考general_names_add_xxx来改写这个函数,只是不知道这个函数用的多不多 -int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen, // 这个功能和general_names很类似,只是多了一点点内容 - int base_choice, const uint8_t *base, size_t base_len, - int minimum, int maximum); -int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -#define x509_general_subtrees_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_general_subtrees_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) - -/* -NameConstraints ::= SEQUENCE { - permittedSubtrees [0] GeneralSubtrees OPTIONAL, - excludedSubtrees [1] GeneralSubtrees OPTIONAL } -*/ -int x509_name_constraints_to_der( - const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, - const uint8_t *excluded_subtrees, size_t excluded_subtrees_len, - uint8_t **out, size_t *outlen); -int x509_name_constraints_from_der( - const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len, - const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len, - const uint8_t **in, size_t *inlen); -int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -PolicyConstraints ::= SEQUENCE { - requireExplicitPolicy [0] IMPLICIT SkipCerts OPTIONAL, - inhibitPolicyMapping [1] IMPLICIT SkipCerts OPTIONAL -} - -SkipCerts ::= INTEGER (0..MAX) -*/ -int x509_policy_constraints_to_der(int require_explicit_policy, int inhibit_policy_mapping, uint8_t **out, size_t *outlen); -int x509_policy_constraints_from_der(int *require_explicit_policy, int *inhibit_policy_mapping, const uint8_t **in, size_t *inlen); -int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - -KeyPurposeId: - OID_kp_server_auth - OID_kp_client_auth - OID_kp_code_signing - OID_kp_email_protection - OID_kp_time_stamping - OID_kp_ocsp_signing -*/ -#define X509_MAX_KEY_PURPOSES 6 -int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen); -int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen); -int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -ReasonFlags ::= BIT STRING { - unused (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - privilegeWithdrawn (7), - aACompromise (8) } -*/ -#define X509_RF_UNUSED (1 << 0) -#define X509_RF_KEY_COMPROMISE (1 << 1) -#define X509_RF_CA_COMPROMISE (1 << 2) -#define X509_RF_AFFILIATION_CHANGED (1 << 3) -#define X509_RF_SUPERSEDED (1 << 4) -#define X509_RF_CESSATION_OF_OPERATION (1 << 5) -#define X509_RF_CERTIFICATE_HOLD (1 << 6) -#define X509_RF_PRIVILEGE_WITHDRAWN (1 << 7) -#define X509_RF_AA_COMPROMISE (1 << 8) - -const char *x509_revoke_reason_name(int flag); -int x509_revoke_reason_from_name(int *flag, const char *name); -#define x509_revoke_reasons_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) -#define x509_revoke_reasons_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) -int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits); - -/* -DistributionPointName ::= CHOICE { - fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF - nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF -*/ -int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen); - -int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_explicit_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -DistributionPoint ::= SEQUENCE { - distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, - reasons [1] IMPLICIT ReasonFlags OPTIONAL, - cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL } -*/ -int x509_distribution_point_to_der( - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len, - uint8_t **out, size_t *outlen); -int x509_distribution_point_from_der( - int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, - int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len, - const uint8_t **in, size_t *inlen); -int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -DistributionPoints ::= SEQUENCE OF DistributionPoint -*/ -int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len); -int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -#define x509_distribution_points_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) -#define x509_distribution_points_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) - -/* -CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint -*/ -#define x509_crl_distribution_points_to_der(d,dlen,out,outlen) x509_distribution_points_to_der(d,dlen,out,outlen) -#define x509_crl_distribution_points_from_der(d,dlen,in,inlen) x509_distribution_points_from_der(d,dlen,in,inlen) -#define x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen) x509_distribution_points_print(fp,fmt,ind,label,d,dlen) - - -/* -InhibitAnyPolicy ::= SkipCerts -SkipCerts ::= INTEGER (0..MAX) -*/ -#define x509_inhibit_any_policy_to_der(val,out,outlen) asn1_int_to_der(val,out,outlen) -#define x509_inhibit_any_policy_from_der(val,in,inlen) asn1_int_from_der(val,in,inlen) - -/* -FreshestCRL ::= CRLDistributionPoints - */ -#define x509_freshest_crl_to_der(d,dlen,out,outlen) x509_crl_distribution_points_to_der(d,dlen,out,outlen) -#define x509_freshest_crl_from_der(d,dlen,in,inlen) x509_crl_distribution_points_from_der(d,dlen,in,inlen) -#define x509_freshest_crl_print(fp,fmt,ind,label,d,dlen) x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen) - -/* -Netscape-Defined Certificate Extensions -https://docs.oracle.com/cd/E19957-01/816-5533-10/ext.htm#1023061 - -NetscapeCertType ::= BIT STRING - - bit 0: SSL Client certificate - bit 1: SSL Server certificate - bit 2: S/MIME certificate - bit 3: Object-signing certificate - bit 4: Reserved for future use - bit 5: SSL CA certificate - bit 6: S/MIME CA certificate - bit 7: Object-signing CA certificate - -NetscapeCertComment ::= IA5String -*/ -int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits); - -#ifdef __cplusplus -} -#endif -#endif - + + +#ifndef GMSSL_X509_EXT_H +#define GMSSL_X509_EXT_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Extensions: + + 1. AuthorityKeyIdentifier SEQUENCE AuthorityKeyIdentifier + 2. SubjectKeyIdentifier OCTET STRING + 3. KeyUsage BIT STRING + 4. CertificatePolicies SEQUENCE OF SEQUENCE CertificatePolicies + 5. PolicyMappings SEQUENCE OF SEQUENCE PolicyMappings + 6. SubjectAltName SEQUENCE OF SEQUENCE GeneralNames + 7. IssuerAltName SEQUENCE OF SEQUENCE GeneralNames + 8. SubjectDirectoryAttributes SEQUENCE OF SEQUENCE Attributes + 9. BasicConstraints SEQUENCE BasicConstraints + 10. NameConstraints SEQUENCE NameConstraints + 11. PolicyConstraints SEQUENCE PolicyConstraints + 12. ExtKeyUsageSyntax SEQUENCE OF OBJECT IDENTIFIER + 13. CRLDistributionPoints SEQUENCE OF SEQUENCE DistributionPoints + 14. InhibitAnyPolicy INTEGER + 15. FreshestCRL SEQUENCE OF SEQUENCE DistributionPoints +*/ + +int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len); +int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_KEY *public_key); +int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits); +int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len); +int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, + int require_explicit_policy, int inhibit_policy_mapping); +int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int ca, int path_len_constraint); +int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const int *key_purposes, size_t key_purposes_cnt); +int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); +int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs); +int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen); + +int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen, + int oid, int critical, const uint8_t *d, size_t dlen); + +/* +OtherName ::= SEQUENCE { + type-id OBJECT IDENTIFIER, -- known oid from x509_rdn_oid such as OID_at_common_name, or oid nodes + value [0] EXPLICIT ANY DEFINED BY type-id } +*/ +int x509_other_name_to_der( + const uint32_t *nodes, size_t nodes_count, + const uint8_t *value, size_t value_len, + uint8_t **out, size_t *outlen); +int x509_other_name_from_der( + uint32_t *nodes, size_t *nodes_count, + const uint8_t **value, size_t *valuelen, + const uint8_t **in, size_t *inlen); +int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +EDIPartyName ::= SEQUENCE { + nameAssigner [0] EXPLICIT DirectoryString OPTIONAL, + partyName [1] EXPLICIT DirectoryString } +*/ +int x509_edi_party_name_to_der( + int assigner_tag, const uint8_t *assigner, size_t assigner_len, + int party_name_tag, const uint8_t *party_name, size_t party_name_len, + uint8_t **out, size_t *outlen); +int x509_edi_party_name_from_der( + int *assigner_tag, const uint8_t **assigner, size_t *assigner_len, + int *party_name_tag, const uint8_t **party_name, size_t *party_name_len, + const uint8_t **in, size_t *inlen); +int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralName ::= CHOICE { + otherName [0] IMPLICIT OtherName, -- 只在GeneralName中出现 + rfc822Name [1] IMPLICIT IA5String, + dNSName [2] IMPLICIT IA5String, + x400Address [3] IMPLICIT ORAddress, + directoryName [4] IMPLICIT Name, -- SEQENCE OF,因此是d,dlen + ediPartyName [5] IMPLICIT EDIPartyName, -- 只在GeneralName中出现 + uniformResourceIdentifier [6] IMPLICIT IA5String, + iPAddress [7] IMPLICIT OCTET STRING, -- 4 bytes or string? + registeredID [8] IMPLICIT OBJECT IDENTIFIER } +*/ +typedef enum { + X509_gn_other_name = 0, + X509_gn_rfc822_name = 1, + X509_gn_dns_name = 2, + X509_gn_x400_address = 3, + X509_gn_directory_name = 4, + X509_gn_edi_party_name = 5, + X509_gn_uniform_resource_identifier = 6, + X509_gn_ip_address = 7, + X509_gn_registered_id = 8, +} X509_GENERAL_NAME_CHOICE; + +int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen); + +/* +GeneralNames ::= SEQUENCE OF GeneralName +*/ +#define x509_general_names_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_general_names_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + int choice, const uint8_t *d, size_t dlen); +int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + const uint32_t *nodes, size_t nodes_count, + const uint8_t *value, size_t value_len); +#define x509_general_names_add_rfc822_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_rfc822_name,(uint8_t*)s,strlen(s)) +#define x509_general_names_add_dns_name(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_dns_name,(uint8_t*)s,strlen(s)) +#define x509_general_names_add_x400_address(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_x400_address,d,dlen) +#define x509_general_names_add_directory_name(a,alen,maxlen,d,dlen) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_directory_name,d,dlen) +int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + int assigner_tag, const uint8_t *assigner, size_t assigner_len, + int party_name_tag, const uint8_t *party_name, size_t party_name_len); +#define x509_general_names_add_uniform_resource_identifier(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_uniform_resource_identifier,(uint8_t*)s,strlen(s)) +#define x509_general_names_add_ip_address(a,alen,maxlen,s) x509_general_names_add_general_name(a,alen,maxlen,X509_gn_ip_address,(uint8_t*)s,strlen(s)) +int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen, + const uint32_t *nodes, size_t nodes_cnt); + +/* +AuthorityKeyIdentifier ::= SEQUENCE { + keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL, + authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL, + authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL } +*/ +int x509_authority_key_identifier_to_der( + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + uint8_t **out, size_t *outlen); +int x509_authority_key_identifier_from_der( + const uint8_t **keyid, size_t *keyid_len, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial, size_t *serial_len, + const uint8_t **in, size_t *inlen); +int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +SubjectKeyIdentifier ::= OCTET STRING +*/ +#define X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN 16 +#define X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN 64 + +/* +KeyUsage ::= BIT STRING { + digitalSignature (0), + nonRepudiation (1), -- recent renamed contentCommitment + keyEncipherment (2), + dataEncipherment (3), + keyAgreement (4), + keyCertSign (5), + cRLSign (6), + encipherOnly (7), + decipherOnly (8) } +*/ +#define X509_KU_DIGITAL_SIGNATURE (1 << 0) +#define X509_KU_NON_REPUDIATION (1 << 1) +#define X509_KU_KEY_ENCIPHERMENT (1 << 2) +#define X509_KU_DATA_ENCIPHERMENT (1 << 3) +#define X509_KU_KEY_AGREEMENT (1 << 4) +#define X509_KU_KEY_CERT_SIGN (1 << 5) +#define X509_KU_CRL_SIGN (1 << 6) +#define X509_KU_ENCIPHER_ONLY (1 << 7) +#define X509_KU_DECIPHER_ONLY (1 << 8) + +const char *x509_key_usage_name(int flag); +int x509_key_usage_from_name(int *flag, const char *name); +#define x509_key_usage_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) +#define x509_key_usage_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) +int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits); + +/* +NoticeReference ::= SEQUENCE { + organization DisplayText, + noticeNumbers SEQUENCE OF INTEGER } + +UserNotice ::= SEQUENCE { + noticeRef NoticeReference OPTIONAL, + explicitText DisplayText OPTIONAL } +*/ +#define X509_MAX_NOTICE_NUMBERS 32 + +int x509_notice_reference_to_der( + int org_tag, const uint8_t *org, size_t org_len, + const int *notice_numbers, size_t notice_numbers_cnt, + uint8_t **out, size_t *outlen); +int x509_notice_reference_from_der( + int *org_tag, const uint8_t **org, size_t *org_len, + int *notice_numbers, size_t *notice_numbers_cnt, size_t max_notice_numbers, + const uint8_t **in, size_t *inlen); +int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_user_notice_to_der( + int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len, + const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt, + int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len, + uint8_t **out, size_t *outlen); +int x509_user_notice_from_der( + int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len, + int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, + int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len, + const uint8_t **in, size_t *inlen); +int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyQualifierInfo ::= SEQUENCE { + policyQualifierId PolicyQualifierId, + qualifier ANY DEFINED BY policyQualifierId } + + switch(policyQualifierId) + case id-qt-cps : qualifier ::= IA5String + case id-qt-unotice : qualifier ::= UserNotice +*/ +int x509_policy_qualifier_info_to_der( + int oid, + const uint8_t *qualifier, size_t qualifier_len, + uint8_t **out, size_t *outlen); +int x509_policy_qualifier_info_from_der( + int *oid, + const uint8_t **qualifier, size_t *qualifier_len, + const uint8_t **in, size_t *inlen); +int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +#define x509_policy_qualifier_infos_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_policy_qualifier_infos_from_der(d,dlen,in,ineln) asn1_sequence_from_der(d,dlen,in,inlen) +int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyInformation ::= SEQUENCE { + policyIdentifier CertPolicyId, + policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL } + +CertPolicyId ::= OBJECT IDENTIFIER -- undefined +*/ + +int x509_policy_information_to_der( + int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len, + uint8_t **out, size_t *outlen); +int x509_policy_information_from_der( + int *policy_oid, uint32_t *policy_nodes, size_t *policy_nodes_cnt, + const uint8_t **qualifiers, size_t *qualifiers_len, + const uint8_t **in, size_t *inlen); +int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation +*/ +int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen, + int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len); +int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_certificate_policies_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_certificate_policies_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +PolicyMapping ::= SEQUENCE { + issuerDomainPolicy CertPolicyId, -- id-anyPolicy or other undefined + subjectDomainPolicy CertPolicyId } +*/ +int x509_policy_mapping_to_der( + int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, + int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt, + uint8_t **out, size_t *outlen); +int x509_policy_mapping_from_der( + int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt, + int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt, + const uint8_t **in, size_t *inlen); +int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyMappings ::= SEQUENCE OF PolicyMapping +*/ +int x509_policy_mappings_add_policy_mapping(uint8_t *d, size_t *dlen, size_t maxlen, + int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, + int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt); +int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_policy_mappings_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_policy_mappings_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +SubjectAltName ::= GeneralNames +*/ +#define x509_subject_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) + +/* +IssuerAltName ::= GeneralNames +*/ +#define x509_issuer_alt_name_print(fp,fmt,ind,label,d,dlen) x509_general_names_print(fp,fmt,ind,label,d,dlen) + +/* +SubjectDirectoryAttributes ::= SEQUENCE OF Attribute + +Attribute ::= SEQUENCE { + type OBJECT IDENTIFIER, + values SET OF ANY } +*/ +int x509_attribute_to_der( + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *values, size_t values_len, + uint8_t **out, size_t *outlen); +int x509_attribute_from_der( + int *oid, uint32_t *nodes, size_t *nodes_cnt, + const uint8_t **values, size_t *values_len, + const uint8_t **in, size_t *inlen); +int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_attributes_add_attribute(uint8_t *d, size_t *dlen, size_t maxlen, + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *values, size_t values_len); +int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_attributes_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_attributes_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +BasicConstraints ::= SEQUENCE { + cA BOOLEAN DEFAULT FALSE, + pathLenConstraint INTEGER (0..MAX) OPTIONAL } +*/ +int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen); +int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen); +int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralSubtree ::= SEQUENCE { + base GeneralName, + minimum [0] IMPLICIT BaseDistance DEFAULT 0, + maximum [1] IMPLICIT BaseDistance OPTIONAL } + +BaseDistance ::= INTEGER (0..MAX) +*/ +int x509_general_subtree_to_der( + int base_choice, const uint8_t *base, size_t base_len, + int minimum, int maximum, + uint8_t **out, size_t *outlen); +int x509_general_subtree_from_der( + int *base_choice, const uint8_t **base, size_t *base_len, + int *minimum, int *maximum, + const uint8_t **in, size_t *inlen); +int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree +*/ +// 应该参考general_names_add_xxx来改写这个函数,只是不知道这个函数用的多不多 +int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen, // 这个功能和general_names很类似,只是多了一点点内容 + int base_choice, const uint8_t *base, size_t base_len, + int minimum, int maximum); +int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_general_subtrees_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_general_subtrees_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +NameConstraints ::= SEQUENCE { + permittedSubtrees [0] GeneralSubtrees OPTIONAL, + excludedSubtrees [1] GeneralSubtrees OPTIONAL } +*/ +int x509_name_constraints_to_der( + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len, + uint8_t **out, size_t *outlen); +int x509_name_constraints_from_der( + const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len, + const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len, + const uint8_t **in, size_t *inlen); +int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +PolicyConstraints ::= SEQUENCE { + requireExplicitPolicy [0] IMPLICIT SkipCerts OPTIONAL, + inhibitPolicyMapping [1] IMPLICIT SkipCerts OPTIONAL +} + +SkipCerts ::= INTEGER (0..MAX) +*/ +int x509_policy_constraints_to_der(int require_explicit_policy, int inhibit_policy_mapping, uint8_t **out, size_t *outlen); +int x509_policy_constraints_from_der(int *require_explicit_policy, int *inhibit_policy_mapping, const uint8_t **in, size_t *inlen); +int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + +KeyPurposeId: + OID_kp_server_auth + OID_kp_client_auth + OID_kp_code_signing + OID_kp_email_protection + OID_kp_time_stamping + OID_kp_ocsp_signing +*/ +#define X509_MAX_KEY_PURPOSES 6 +int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen); +int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen); +int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +ReasonFlags ::= BIT STRING { + unused (0), + keyCompromise (1), + cACompromise (2), + affiliationChanged (3), + superseded (4), + cessationOfOperation (5), + certificateHold (6), + privilegeWithdrawn (7), + aACompromise (8) } +*/ +#define X509_RF_UNUSED (1 << 0) +#define X509_RF_KEY_COMPROMISE (1 << 1) +#define X509_RF_CA_COMPROMISE (1 << 2) +#define X509_RF_AFFILIATION_CHANGED (1 << 3) +#define X509_RF_SUPERSEDED (1 << 4) +#define X509_RF_CESSATION_OF_OPERATION (1 << 5) +#define X509_RF_CERTIFICATE_HOLD (1 << 6) +#define X509_RF_PRIVILEGE_WITHDRAWN (1 << 7) +#define X509_RF_AA_COMPROMISE (1 << 8) + +const char *x509_revoke_reason_name(int flag); +int x509_revoke_reason_from_name(int *flag, const char *name); +#define x509_revoke_reasons_to_der(bits,out,outlen) asn1_bits_to_der(bits,out,outlen) +#define x509_revoke_reasons_from_der(bits,in,inlen) asn1_bits_from_der(bits,in,inlen) +int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits); + +/* +DistributionPointName ::= CHOICE { + fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF + nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF +*/ +int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen); + +int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_explicit_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +DistributionPoint ::= SEQUENCE { + distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, + reasons [1] IMPLICIT ReasonFlags OPTIONAL, + cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL } +*/ +int x509_distribution_point_to_der( + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len, + uint8_t **out, size_t *outlen); +int x509_distribution_point_from_der( + int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, + int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len, + const uint8_t **in, size_t *inlen); +int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +DistributionPoints ::= SEQUENCE OF DistributionPoint +*/ +int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len); +int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +#define x509_distribution_points_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen) +#define x509_distribution_points_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen) + +/* +CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint +*/ +#define x509_crl_distribution_points_to_der(d,dlen,out,outlen) x509_distribution_points_to_der(d,dlen,out,outlen) +#define x509_crl_distribution_points_from_der(d,dlen,in,inlen) x509_distribution_points_from_der(d,dlen,in,inlen) +#define x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen) x509_distribution_points_print(fp,fmt,ind,label,d,dlen) + + +/* +InhibitAnyPolicy ::= SkipCerts +SkipCerts ::= INTEGER (0..MAX) +*/ +#define x509_inhibit_any_policy_to_der(val,out,outlen) asn1_int_to_der(val,out,outlen) +#define x509_inhibit_any_policy_from_der(val,in,inlen) asn1_int_from_der(val,in,inlen) + +/* +FreshestCRL ::= CRLDistributionPoints + */ +#define x509_freshest_crl_to_der(d,dlen,out,outlen) x509_crl_distribution_points_to_der(d,dlen,out,outlen) +#define x509_freshest_crl_from_der(d,dlen,in,inlen) x509_crl_distribution_points_from_der(d,dlen,in,inlen) +#define x509_freshest_crl_print(fp,fmt,ind,label,d,dlen) x509_crl_distribution_points_print(fp,fmt,ind,label,d,dlen) + +/* +Netscape-Defined Certificate Extensions +https://docs.oracle.com/cd/E19957-01/816-5533-10/ext.htm#1023061 + +NetscapeCertType ::= BIT STRING + + bit 0: SSL Client certificate + bit 1: SSL Server certificate + bit 2: S/MIME certificate + bit 3: Object-signing certificate + bit 4: Reserved for future use + bit 5: SSL CA certificate + bit 6: S/MIME CA certificate + bit 7: Object-signing CA certificate + +NetscapeCertComment ::= IA5String +*/ +int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/include/gmssl/x509_oid.h b/include/gmssl/x509_oid.h index 1f1b004a..7b1b8c72 100644 --- a/include/gmssl/x509_oid.h +++ b/include/gmssl/x509_oid.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,105 +7,106 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_OID_H -#define GMSSL_X509_OID_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -id-at: - OID_at_name - OID_at_surname - OID_at_given_name - OID_at_initials - OID_at_generation_qualifier - OID_at_common_name - OID_at_locality_name - OID_at_state_or_province_name - OID_at_organization_name - OID_at_organizational_unit_name - OID_at_title - OID_at_dn_qualifier - OID_at_country_name - OID_at_serial_number - OID_at_pseudonym - OID_domain_component -*/ -const char *x509_name_type_name(int oid); -int x509_name_type_from_name(const char *name); -int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen); - -/* -id-ce: - OID_ce_authority_key_identifier - OID_ce_subject_key_identifier - OID_ce_key_usage - OID_ce_certificate_policies - OID_ce_policy_mappings - OID_ce_subject_alt_name - OID_ce_issuer_alt_name - OID_ce_subject_directory_attributes - OID_ce_basic_constraints - OID_ce_name_constraints - OID_ce_policy_constraints - OID_ce_ext_key_usage - OID_ce_crl_distribution_points - OID_ce_inhibit_any_policy - OID_ce_freshest_crl - OID_netscape_cert_comment -*/ -const char *x509_ext_id_name(int oid); -int x509_ext_id_from_name(const char *name); -int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); -int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); - -/* -id-qt - OID_qt_cps - OID_qt_unotice -*/ -const char *x509_qualifier_id_name(int oid); -int x509_qualifier_id_from_name(const char *name); -int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen); - -/* - OID_any_policy -*/ -char *x509_cert_policy_id_name(int oid); -int x509_cert_policy_id_from_name(const char *name); -int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen); -int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen); - -/* -id-kp - OID_kp_server_auth - OID_kp_client_auth - OID_kp_code_signing - OID_kp_email_protection - OID_kp_time_stamping - OID_kp_ocsp_signing -*/ -const char *x509_key_purpose_name(int oid); -const char *x509_key_purpose_text(int oid); -int x509_key_purpose_from_name(const char *name); -int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen); -int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen); - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_X509_OID_H +#define GMSSL_X509_OID_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +id-at: + OID_at_name + OID_at_surname + OID_at_given_name + OID_at_initials + OID_at_generation_qualifier + OID_at_common_name + OID_at_locality_name + OID_at_state_or_province_name + OID_at_organization_name + OID_at_organizational_unit_name + OID_at_title + OID_at_dn_qualifier + OID_at_country_name + OID_at_serial_number + OID_at_pseudonym + OID_domain_component +*/ +const char *x509_name_type_name(int oid); +int x509_name_type_from_name(const char *name); +int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen); + +/* +id-ce: + OID_ce_authority_key_identifier + OID_ce_subject_key_identifier + OID_ce_key_usage + OID_ce_certificate_policies + OID_ce_policy_mappings + OID_ce_subject_alt_name + OID_ce_issuer_alt_name + OID_ce_subject_directory_attributes + OID_ce_basic_constraints + OID_ce_name_constraints + OID_ce_policy_constraints + OID_ce_ext_key_usage + OID_ce_crl_distribution_points + OID_ce_inhibit_any_policy + OID_ce_freshest_crl + OID_netscape_cert_comment +*/ +const char *x509_ext_id_name(int oid); +int x509_ext_id_from_name(const char *name); +int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen); +int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen); + +/* +id-qt + OID_qt_cps + OID_qt_unotice +*/ +const char *x509_qualifier_id_name(int oid); +int x509_qualifier_id_from_name(const char *name); +int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen); + +/* + OID_any_policy +*/ +char *x509_cert_policy_id_name(int oid); +int x509_cert_policy_id_from_name(const char *name); +int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen); +int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen); + +/* +id-kp + OID_kp_server_auth + OID_kp_client_auth + OID_kp_code_signing + OID_kp_email_protection + OID_kp_time_stamping + OID_kp_ocsp_signing +*/ +const char *x509_key_purpose_name(int oid); +const char *x509_key_purpose_text(int oid); +int x509_key_purpose_from_name(const char *name); +int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen); +int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_req.h b/include/gmssl/x509_req.h index 9e670df2..5ad94e25 100644 --- a/include/gmssl/x509_req.h +++ b/include/gmssl/x509_req.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,99 +7,100 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_REQ_H -#define GMSSL_X509_REQ_H - - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -X509 REQ Public API - - x509_req_sign - x509_req_verify - x509_req_get_details - x509_req_print - x509_req_to_pem - x509_req_from_pem -*/ - - -/* -from RFC 2986 - -CertificationRequestInfo ::= SEQUENCE { - version INTEGER { v1(0) }, - subject Name, - subjectPKInfo SubjectPublicKeyInfo, - attributes [0] IMPLICIT SET OF Attribute } -*/ -int x509_request_info_to_der(int version, const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, const uint8_t *attrs, size_t attrs_len, - uint8_t **out, size_t *outlen); -int x509_request_info_from_der(int *version, const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, const uint8_t **attrs, size_t *attrs_len, - const uint8_t **in, size_t *inlen); -int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -/* -CertificationRequest ::= SEQUENCE { - certificationRequestInfo CertificationRequestInfo, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } -*/ -int x509_request_to_der( - int version, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *attrs, size_t attrs_len, - int signature_algor, - const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen); -int x509_request_from_der( - int *version, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **attrs, size_t *attrs_len, - int *signature_algor, - const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen); -int x509_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); - -int x509_req_sign(uint8_t *req, size_t *reqlen, size_t maxlen, - int version, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *attrs, size_t attrs_len, - int signature_algor, - const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); -int x509_req_verify(const uint8_t *req, size_t reqlen, - const SM2_KEY *sign_pubkey, const char *signer_id, size_t signer_id_len); -int x509_req_get_details(const uint8_t *req, size_t reqlen, - int *verison, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **attributes, size_t *attributes_len, - int *signature_algor, - const uint8_t **signature, size_t *signature_len); -int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen); -int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp); -int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_X509_REQ_H +#define GMSSL_X509_REQ_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +X509 REQ Public API + + x509_req_sign + x509_req_verify + x509_req_get_details + x509_req_print + x509_req_to_pem + x509_req_from_pem +*/ + + +/* +from RFC 2986 + +CertificationRequestInfo ::= SEQUENCE { + version INTEGER { v1(0) }, + subject Name, + subjectPKInfo SubjectPublicKeyInfo, + attributes [0] IMPLICIT SET OF Attribute } +*/ +int x509_request_info_to_der(int version, const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, const uint8_t *attrs, size_t attrs_len, + uint8_t **out, size_t *outlen); +int x509_request_info_from_der(int *version, const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, const uint8_t **attrs, size_t *attrs_len, + const uint8_t **in, size_t *inlen); +int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +/* +CertificationRequest ::= SEQUENCE { + certificationRequestInfo CertificationRequestInfo, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } +*/ +int x509_request_to_der( + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen); +int x509_request_from_der( + int *version, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attrs, size_t *attrs_len, + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen); +int x509_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); + +int x509_req_sign(uint8_t *req, size_t *reqlen, size_t maxlen, + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len); +int x509_req_verify(const uint8_t *req, size_t reqlen, + const SM2_KEY *sign_pubkey, const char *signer_id, size_t signer_id_len); +int x509_req_get_details(const uint8_t *req, size_t reqlen, + int *verison, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attributes, size_t *attributes_len, + int *signature_algor, + const uint8_t **signature, size_t *signature_len); +int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen); +int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp); +int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/x509_str.h b/include/gmssl/x509_str.h index 38256996..aa5e334f 100644 --- a/include/gmssl/x509_str.h +++ b/include/gmssl/x509_str.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,61 +7,62 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_X509_STR_H -#define GMSSL_X509_STR_H - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -DirectoryString or DirectoryName - -DirectoryName ::= CHOICE { - teletexString TeletexString (SIZE (1..MAX)), - printableString PrintableString (SIZE (1..MAX)), - universalString UniversalString (SIZE (1..MAX)), - utf8String UTF8String (SIZE (1..MAX)), - bmpString BMPString (SIZE (1..MAX)), -} -*/ -int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen); -int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen); -int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); - - -/* -DisplayText ::= CHOICE { - ia5String IA5String (SIZE (1..200)), - visibleString VisibleString (SIZE (1..200)), - bmpString BMPString (SIZE (1..200)), - utf8String UTF8String (SIZE (1..200)) -} -*/ -#define X509_DISPLAY_TEXT_MIN_LEN 1 -#define X509_DISPLAY_TEXT_MAX_LEN 200 - -int x509_display_text_check(int tag, const uint8_t *d, size_t dlen); -int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); -int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); -int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_X509_STR_H +#define GMSSL_X509_STR_H + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +DirectoryString or DirectoryName + +DirectoryName ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1..MAX)), + bmpString BMPString (SIZE (1..MAX)), +} +*/ +int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen); +int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen); +int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + + +/* +DisplayText ::= CHOICE { + ia5String IA5String (SIZE (1..200)), + visibleString VisibleString (SIZE (1..200)), + bmpString BMPString (SIZE (1..200)), + utf8String UTF8String (SIZE (1..200)) +} +*/ +#define X509_DISPLAY_TEXT_MIN_LEN 1 +#define X509_DISPLAY_TEXT_MAX_LEN 200 + +int x509_display_text_check(int tag, const uint8_t *d, size_t dlen); +int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen); +int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen); +int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/zuc.h b/include/gmssl/zuc.h index 5daa7e16..8ebfab36 100644 --- a/include/gmssl/zuc.h +++ b/include/gmssl/zuc.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,139 +7,140 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_ZUC_H -#define GMSSL_ZUC_H - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -ZUC Public API - - ZUC_KEY_SIZE - ZUC_IV_SIZE - ZUC_MAC_SIZE - - ZUC_CTX - zuc_encrypt_init - zuc_encrypt_update - zuc_encrypt_finish - zuc_decrypt_init - zuc_decrypt_update - zuc_decrypt_finish - - ZUC_MAC_CTX - zuc_mac_init - zuc_mac_update - zuc_mac_finish - - zuc_eea_encrypt - zuc_eia_generate_mac -*/ - - -# define ZUC_KEY_SIZE 16 -# define ZUC_IV_SIZE 16 -# define ZUC_MAC_SIZE 4 - -typedef uint32_t ZUC_BIT; -typedef uint32_t ZUC_UINT5; -typedef uint8_t ZUC_UINT6; -typedef uint32_t ZUC_UINT15; -typedef uint32_t ZUC_UINT31; -typedef uint32_t ZUC_UINT32; - -typedef struct { - ZUC_UINT31 LFSR[16]; - ZUC_UINT32 R1; - ZUC_UINT32 R2; -} ZUC_STATE; - -void zuc_init(ZUC_STATE *state, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); -void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, ZUC_UINT32 *words); -ZUC_UINT32 zuc_generate_keyword(ZUC_STATE *state); -void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out); - -typedef struct ZUC_MAC_CTX_st { - ZUC_UINT31 LFSR[16]; - ZUC_UINT32 R1; - ZUC_UINT32 R2; - ZUC_UINT32 T; - ZUC_UINT32 K0; - uint8_t buf[4]; - size_t buflen; -} ZUC_MAC_CTX; - -void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); -void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len); -void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]); - -void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits, - const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, - ZUC_BIT direction); -ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits, - const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, - ZUC_BIT direction); - - -# define ZUC256_KEY_SIZE 32 -# define ZUC256_IV_SIZE 23 -# define ZUC256_MAC32_SIZE 4 -# define ZUC256_MAC64_SIZE 8 -# define ZUC256_MAC128_SIZE 16 -# define ZUC256_MIN_MAC_SIZE ZUC256_MAC32_SIZE -# define ZUC256_MAX_MAC_SIZE ZUC256_MAC128_SIZE - -typedef ZUC_STATE ZUC256_STATE; - -void zuc256_init(ZUC256_STATE *state, const uint8_t key[ZUC256_KEY_SIZE], const uint8_t iv[ZUC256_IV_SIZE]); -#define zuc256_generate_keystream(state,nwords,words) zuc_generate_keystream(state,nwords,words) -#define zuc256_generate_keyword(state) zuc_generate_keyword(state) - - -typedef struct ZUC256_MAC_CTX_st { - ZUC_UINT31 LFSR[16]; - ZUC_UINT32 R1; - ZUC_UINT32 R2; - ZUC_UINT32 T[4]; - ZUC_UINT32 K0[4]; - uint8_t buf[4]; - int buflen; - int macbits; -} ZUC256_MAC_CTX; - -void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[ZUC256_KEY_SIZE], - const uint8_t iv[ZUC256_IV_SIZE], int macbits); -void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len); -void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]); - - -// Public API - -typedef struct { - ZUC_STATE zuc_state; - uint8_t block[4]; - size_t block_nbytes; -} ZUC_CTX; - -int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); -int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen); - -#define zuc_decrypt_init(ctx,key,iv) zuc_encrypt_init(ctx,key,iv) -#define zuc_decrypt_update(ctx,in,inlen,out,outlen) zuc_encrypt_update(ctx,in,inlen,out,outlen) -#define zuc_decrypt_finish(ctx,out,outlen) zuc_encrypt_finish(ctx,out,outlen) - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef GMSSL_ZUC_H +#define GMSSL_ZUC_H + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +ZUC Public API + + ZUC_KEY_SIZE + ZUC_IV_SIZE + ZUC_MAC_SIZE + + ZUC_CTX + zuc_encrypt_init + zuc_encrypt_update + zuc_encrypt_finish + zuc_decrypt_init + zuc_decrypt_update + zuc_decrypt_finish + + ZUC_MAC_CTX + zuc_mac_init + zuc_mac_update + zuc_mac_finish + + zuc_eea_encrypt + zuc_eia_generate_mac +*/ + + +# define ZUC_KEY_SIZE 16 +# define ZUC_IV_SIZE 16 +# define ZUC_MAC_SIZE 4 + +typedef uint32_t ZUC_BIT; +typedef uint32_t ZUC_UINT5; +typedef uint8_t ZUC_UINT6; +typedef uint32_t ZUC_UINT15; +typedef uint32_t ZUC_UINT31; +typedef uint32_t ZUC_UINT32; + +typedef struct { + ZUC_UINT31 LFSR[16]; + ZUC_UINT32 R1; + ZUC_UINT32 R2; +} ZUC_STATE; + +void zuc_init(ZUC_STATE *state, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); +void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, ZUC_UINT32 *words); +ZUC_UINT32 zuc_generate_keyword(ZUC_STATE *state); +void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out); + +typedef struct ZUC_MAC_CTX_st { + ZUC_UINT31 LFSR[16]; + ZUC_UINT32 R1; + ZUC_UINT32 R2; + ZUC_UINT32 T; + ZUC_UINT32 K0; + uint8_t buf[4]; + size_t buflen; +} ZUC_MAC_CTX; + +void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); +void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len); +void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]); + +void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits, + const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, + ZUC_BIT direction); +ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits, + const uint8_t key[ZUC_KEY_SIZE], ZUC_UINT32 count, ZUC_UINT5 bearer, + ZUC_BIT direction); + + +# define ZUC256_KEY_SIZE 32 +# define ZUC256_IV_SIZE 23 +# define ZUC256_MAC32_SIZE 4 +# define ZUC256_MAC64_SIZE 8 +# define ZUC256_MAC128_SIZE 16 +# define ZUC256_MIN_MAC_SIZE ZUC256_MAC32_SIZE +# define ZUC256_MAX_MAC_SIZE ZUC256_MAC128_SIZE + +typedef ZUC_STATE ZUC256_STATE; + +void zuc256_init(ZUC256_STATE *state, const uint8_t key[ZUC256_KEY_SIZE], const uint8_t iv[ZUC256_IV_SIZE]); +#define zuc256_generate_keystream(state,nwords,words) zuc_generate_keystream(state,nwords,words) +#define zuc256_generate_keyword(state) zuc_generate_keyword(state) + + +typedef struct ZUC256_MAC_CTX_st { + ZUC_UINT31 LFSR[16]; + ZUC_UINT32 R1; + ZUC_UINT32 R2; + ZUC_UINT32 T[4]; + ZUC_UINT32 K0[4]; + uint8_t buf[4]; + int buflen; + int macbits; +} ZUC256_MAC_CTX; + +void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[ZUC256_KEY_SIZE], + const uint8_t iv[ZUC256_IV_SIZE], int macbits); +void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len); +void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[ZUC_MAC_SIZE]); + + +// Public API + +typedef struct { + ZUC_STATE zuc_state; + uint8_t block[4]; + size_t block_nbytes; +} ZUC_CTX; + +int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]); +int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen); + +#define zuc_decrypt_init(ctx,key,iv) zuc_encrypt_init(ctx,key,iv) +#define zuc_decrypt_update(ctx,in,inlen,out,outlen) zuc_encrypt_update(ctx,in,inlen,out,outlen) +#define zuc_decrypt_finish(ctx,out,outlen) zuc_encrypt_finish(ctx,out,outlen) + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/aes.c b/src/aes.c index 5529c79e..ee8abef0 100644 --- a/src/aes.c +++ b/src/aes.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,437 +7,438 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -static const uint8_t S[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, -}; - -static const uint8_t S_inv[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, -}; - -static const uint8_t Rcon[11] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, -}; - -static uint32_t sub_word(uint32_t A) -{ - return S[(A >> 24) & 0xff] << 24 | - S[(A >> 16) & 0xff] << 16 | - S[(A >> 8) & 0xff] << 8 | - S[A & 0xff]; -} - -/* (a0,a1,a2,a3) => (a1,a2,a3,a0) */ -static uint32_t rot_word(uint32_t A) -{ - return ROL32(A, 8); -} - -#ifdef CRYPTO_INFO -static void print_rk(const AES_KEY *aes_key) -{ - size_t i; - for (i = 0; i <= aes_key->rounds; i++) { - printf("%08x ", aes_key->rk[4 * i]); - printf("%08x ", aes_key->rk[4 * i + 1]); - printf("%08x ", aes_key->rk[4 * i + 2]); - printf("%08x\n", aes_key->rk[4 * i + 3]); - } - printf("\n"); -} -#endif - -int aes_set_encrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen) -{ - /* Nk: num user key words - * AES-128 Nk = 4 W[44] - * AES-192 Nk = 6 W[52] - * AES-256 Nk = 8 W[60] - */ - uint32_t *W = (uint32_t *)aes_key->rk; - size_t Nk = keylen/sizeof(uint32_t); - size_t i; - - switch (keylen) { - case AES128_KEY_SIZE: - aes_key->rounds = 10; - break; - case AES192_KEY_SIZE: - aes_key->rounds = 12; - break; - case AES256_KEY_SIZE: - aes_key->rounds = 14; - break; - default: - return 0; - } - - for (i = 0; i < Nk; i++) { - W[i] = GETU32(key + sizeof(uint32_t) * i); - } - for (; i < 4 * (aes_key->rounds + 1); i++) { - uint32_t T = W[i - 1]; - if (i % Nk == 0) { - T = rot_word(T); - T = sub_word(T); - T ^= ((uint32_t)Rcon[i/Nk] << 24); - - } else if (Nk == 8 && i % 8 == 4) { - T = sub_word(T); - } - W[i] = W[i - Nk] ^ T; - } - -#ifdef CRYPTO_INFO - print_rk(aes_key); -#endif - - return 1; -} - -int aes_set_decrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen) -{ - int ret = 0; - AES_KEY enc_key; - size_t i; - - if (!aes_set_encrypt_key(&enc_key, key, keylen)) { - goto end; - } - - for (i = 0; i <= enc_key.rounds; i++) { - aes_key->rk[4*i ] = enc_key.rk[4*(enc_key.rounds - i)]; - aes_key->rk[4*i + 1] = enc_key.rk[4*(enc_key.rounds - i) + 1]; - aes_key->rk[4*i + 2] = enc_key.rk[4*(enc_key.rounds - i) + 2]; - aes_key->rk[4*i + 3] = enc_key.rk[4*(enc_key.rounds - i) + 3]; - } - aes_key->rounds = enc_key.rounds; - ret = 1; - -#ifdef CRYPTO_INFO - print_rk(aes_key); -#endif - -end: - memset(&enc_key, 0, sizeof(AES_KEY)); - return ret; -} - -/* - * |S00 S01 S02 S03| | | - * |S10 S11 S12 S13| xor |W0 W1 W2 W3| - * |S20 S21 S22 S23| | | - * |S30 S31 S32 S33| | | - */ -static void add_round_key(uint8_t state[4][4], const uint32_t *W) -{ - int i; - for (i = 0; i < 4; i++) { - state[0][i] ^= (W[i] >> 24) & 0xff; - state[1][i] ^= (W[i] >> 16) & 0xff; - state[2][i] ^= (W[i] >> 8) & 0xff; - state[3][i] ^= (W[i] ) & 0xff; - } -} - -static void sub_bytes(uint8_t state[4][4]) -{ - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - state[i][j] = S[state[i][j]]; - } - } -} - -static void inv_sub_bytes(uint8_t state[4][4]) -{ - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - state[i][j] = S_inv[state[i][j]]; - } - } -} - -/* - * |S00 S01 S02 S03| <<<0 |S00 S01 S02 S03| - * |S10 S11 S12 S13| <<<1 => |S11 S12 S13 S10| - * |S20 S21 S22 S23| <<<2 |S22 S23 S20 S21| - * |S30 S31 S32 S33| <<<3 |S33 S30 S31 S32| - */ -static void shift_rows(uint8_t state[4][4]) -{ - uint8_t tmp[4][4]; - - tmp[0][0] = state[0][0]; - tmp[0][1] = state[0][1]; - tmp[0][2] = state[0][2]; - tmp[0][3] = state[0][3]; - - tmp[1][0] = state[1][1]; - tmp[1][1] = state[1][2]; - tmp[1][2] = state[1][3]; - tmp[1][3] = state[1][0]; - - tmp[2][0] = state[2][2]; - tmp[2][1] = state[2][3]; - tmp[2][2] = state[2][0]; - tmp[2][3] = state[2][1]; - - tmp[3][0] = state[3][3]; - tmp[3][1] = state[3][0]; - tmp[3][2] = state[3][1]; - tmp[3][3] = state[3][2]; - - memcpy(state, tmp, sizeof(tmp)); - memset(tmp, 0, sizeof(tmp)); -} - - -/* - * |S00 S01 S02 S03| >>>0 |S00 S01 S02 S03| - * |S10 S11 S12 S13| >>>1 => |S13 S10 S11 S12| - * |S20 S21 S22 S23| >>>2 |S22 S23 S20 S21| - * |S30 S31 S32 S33| >>>3 |S31 S32 S33 S30| - */ -static void inv_shift_rows(uint8_t state[4][4]) -{ - uint8_t tmp[4][4]; - - tmp[0][0] = state[0][0]; - tmp[0][1] = state[0][1]; - tmp[0][2] = state[0][2]; - tmp[0][3] = state[0][3]; - - tmp[1][0] = state[1][3]; - tmp[1][1] = state[1][0]; - tmp[1][2] = state[1][1]; - tmp[1][3] = state[1][2]; - - tmp[2][0] = state[2][2]; - tmp[2][1] = state[2][3]; - tmp[2][2] = state[2][0]; - tmp[2][3] = state[2][1]; - - tmp[3][0] = state[3][1]; - tmp[3][1] = state[3][2]; - tmp[3][2] = state[3][3]; - tmp[3][3] = state[3][0]; - - memcpy(state, tmp, sizeof(tmp)); - memset(tmp, 0, sizeof(tmp)); -} - -/* - * GF(2^8) defSed by f(x) = x^8 + x^4 + x^3 + x + 1 - * x^8 == x^4 + x^3 + x + 1 = 0001,1011 = 0x1b - * if A[7] == 0 then 2 * A = (A << 1) - * else 2 * A = (A << 1) xor A - */ -#define x1(a) (a) - -static uint8_t x2(uint8_t a) { - return (a >> 7) ? ((a << 1) ^ 0x1b) : (a << 1); -} - -static uint8_t x3(uint8_t a) { - return x2(a) ^ x1(a); -} - -static uint8_t x9(uint8_t a) { - return x2(x2(x2(a))) ^ x1(a); -} - -/* 0x0b = 11 = 8 + 2 + 1 */ -static uint8_t xb(uint8_t a) { - return x2(x2(x2(a))) ^ x2(a) ^ x1(a); -} - -/* 0x0d = 13 = 8 + 4 + 1 */ -static uint8_t xd(uint8_t a) { - return x2(x2(x2(a))) ^ x2(x2(a)) ^ x1(a); -} - -/* 0x0e = 14 = 8 + 4 + 2 */ -static uint8_t xe(uint8_t a) { - return x2(x2(x2(a))) ^ x2(x2(a)) ^ x2(a); -} - -/* - * |2 3 1 1| |S00 S01 S02 S03| - * |1 2 3 1| |S10 S11 S12 S13| - * |1 1 2 3|*|S20 S21 S22 S23| - * |3 1 1 2| |S30 S31 S32 S33| - */ -static void mix_columns(uint8_t S[4][4]) -{ - uint8_t tmp[4][4]; - int i; - - /* i-th column */ - for (i = 0; i < 4; i++) { - tmp[0][i] = x2(S[0][i]) ^ x3(S[1][i]) ^ x1(S[2][i]) ^ x1(S[3][i]); - tmp[1][i] = x1(S[0][i]) ^ x2(S[1][i]) ^ x3(S[2][i]) ^ x1(S[3][i]); - tmp[2][i] = x1(S[0][i]) ^ x1(S[1][i]) ^ x2(S[2][i]) ^ x3(S[3][i]); - tmp[3][i] = x3(S[0][i]) ^ x1(S[1][i]) ^ x1(S[2][i]) ^ x2(S[3][i]); - } - - memcpy(S, tmp, sizeof(tmp)); - memset(tmp, 0, sizeof(tmp)); -} - -/* - * |0E 0B 0D 09| |02 03 01 01| |1 0 0 0| - * |09 0E 0B 0D|*|01 02 03 01| = |0 1 0 0| - * |0D 09 0E 0B| |01 01 02 03| |0 0 1 0| - * |0B 0D 09 0E| |03 01 01 02| |0 0 0 1| - * - */ -static void inv_mix_columns(uint8_t S[4][4]) -{ - uint8_t tmp[4][4]; - int i; - - /* i-th column */ - for (i = 0; i < 4; i++) { - tmp[0][i] = xe(S[0][i]) ^ xb(S[1][i]) ^ xd(S[2][i]) ^ x9(S[3][i]); - tmp[1][i] = x9(S[0][i]) ^ xe(S[1][i]) ^ xb(S[2][i]) ^ xd(S[3][i]); - tmp[2][i] = xd(S[0][i]) ^ x9(S[1][i]) ^ xe(S[2][i]) ^ xb(S[3][i]); - tmp[3][i] = xb(S[0][i]) ^ xd(S[1][i]) ^ x9(S[2][i]) ^ xe(S[3][i]); - } - - memcpy(S, tmp, sizeof(tmp)); - memset(tmp, 0, sizeof(tmp)); -} - -#ifdef CRYPTO_INFO -static void print_state(const uint8_t S[4][4]) -{ - int i; - for (i = 0; i < 4; i++) { - printf("%02x %02x %02x %02x\n", S[i][0], S[i][1], S[i][2], S[i][3]); - } - printf("\n"); -} -#endif - -void aes_encrypt(const AES_KEY *key, const uint8_t in[16], uint8_t out[16]) -{ - uint8_t state[4][4]; - size_t i; - - /* fill state columns */ - for (i = 0; i < 4; i++) { - state[0][i] = *in++; - state[1][i] = *in++; - state[2][i] = *in++; - state[3][i] = *in++; - } - - /* Sitial add round key */ - add_round_key(state, key->rk); - - /* first n-1 rounds */ - for (i = 1; i < key->rounds; i++) { - sub_bytes(state); - shift_rows(state); - mix_columns(state); - add_round_key(state, key->rk + 4*i); - } - - /* last round withtmp mix columns */ - sub_bytes(state); - shift_rows(state); - add_round_key(state, key->rk + 4*i); - - /* tmpput state columns */ - for (i = 0; i < 4; i++) { - *out++ = state[0][i]; - *out++ = state[1][i]; - *out++ = state[2][i]; - *out++ = state[3][i]; - } - - memset(state, 0, sizeof(state)); -} - -void aes_decrypt(const AES_KEY *aes_key, const uint8_t in[16], uint8_t out[16]) -{ - uint8_t state[4][4]; - size_t i; - - /* fill state columns */ - for (i = 0; i < 4; i++) { - state[0][i] = *in++; - state[1][i] = *in++; - state[2][i] = *in++; - state[3][i] = *in++; - } - - /* Sitial add round key */ - add_round_key(state, aes_key->rk); - - /* first n-1 rounds */ - for (i = 1; i < aes_key->rounds; i++) { - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, aes_key->rk + 4*i); - inv_mix_columns(state); - } - - /* last round withtmp mix columns */ - inv_shift_rows(state); - inv_sub_bytes(state); - add_round_key(state, aes_key->rk + 4*i); - - /* tmpput state columns */ - for (i = 0; i < 4; i++) { - *out++ = state[0][i]; - *out++ = state[1][i]; - *out++ = state[2][i]; - *out++ = state[3][i]; - } - - memset(state, 0, sizeof(state)); -} + + + +#include +#include +#include +#include +#include +#include + + +static const uint8_t S[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, +}; + +static const uint8_t S_inv[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, +}; + +static const uint8_t Rcon[11] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, +}; + +static uint32_t sub_word(uint32_t A) +{ + return S[(A >> 24) & 0xff] << 24 | + S[(A >> 16) & 0xff] << 16 | + S[(A >> 8) & 0xff] << 8 | + S[A & 0xff]; +} + +/* (a0,a1,a2,a3) => (a1,a2,a3,a0) */ +static uint32_t rot_word(uint32_t A) +{ + return ROL32(A, 8); +} + +#ifdef CRYPTO_INFO +static void print_rk(const AES_KEY *aes_key) +{ + size_t i; + for (i = 0; i <= aes_key->rounds; i++) { + printf("%08x ", aes_key->rk[4 * i]); + printf("%08x ", aes_key->rk[4 * i + 1]); + printf("%08x ", aes_key->rk[4 * i + 2]); + printf("%08x\n", aes_key->rk[4 * i + 3]); + } + printf("\n"); +} +#endif + +int aes_set_encrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen) +{ + /* Nk: num user key words + * AES-128 Nk = 4 W[44] + * AES-192 Nk = 6 W[52] + * AES-256 Nk = 8 W[60] + */ + uint32_t *W = (uint32_t *)aes_key->rk; + size_t Nk = keylen/sizeof(uint32_t); + size_t i; + + switch (keylen) { + case AES128_KEY_SIZE: + aes_key->rounds = 10; + break; + case AES192_KEY_SIZE: + aes_key->rounds = 12; + break; + case AES256_KEY_SIZE: + aes_key->rounds = 14; + break; + default: + return 0; + } + + for (i = 0; i < Nk; i++) { + W[i] = GETU32(key + sizeof(uint32_t) * i); + } + for (; i < 4 * (aes_key->rounds + 1); i++) { + uint32_t T = W[i - 1]; + if (i % Nk == 0) { + T = rot_word(T); + T = sub_word(T); + T ^= ((uint32_t)Rcon[i/Nk] << 24); + + } else if (Nk == 8 && i % 8 == 4) { + T = sub_word(T); + } + W[i] = W[i - Nk] ^ T; + } + +#ifdef CRYPTO_INFO + print_rk(aes_key); +#endif + + return 1; +} + +int aes_set_decrypt_key(AES_KEY *aes_key, const uint8_t *key, size_t keylen) +{ + int ret = 0; + AES_KEY enc_key; + size_t i; + + if (!aes_set_encrypt_key(&enc_key, key, keylen)) { + goto end; + } + + for (i = 0; i <= enc_key.rounds; i++) { + aes_key->rk[4*i ] = enc_key.rk[4*(enc_key.rounds - i)]; + aes_key->rk[4*i + 1] = enc_key.rk[4*(enc_key.rounds - i) + 1]; + aes_key->rk[4*i + 2] = enc_key.rk[4*(enc_key.rounds - i) + 2]; + aes_key->rk[4*i + 3] = enc_key.rk[4*(enc_key.rounds - i) + 3]; + } + aes_key->rounds = enc_key.rounds; + ret = 1; + +#ifdef CRYPTO_INFO + print_rk(aes_key); +#endif + +end: + memset(&enc_key, 0, sizeof(AES_KEY)); + return ret; +} + +/* + * |S00 S01 S02 S03| | | + * |S10 S11 S12 S13| xor |W0 W1 W2 W3| + * |S20 S21 S22 S23| | | + * |S30 S31 S32 S33| | | + */ +static void add_round_key(uint8_t state[4][4], const uint32_t *W) +{ + int i; + for (i = 0; i < 4; i++) { + state[0][i] ^= (W[i] >> 24) & 0xff; + state[1][i] ^= (W[i] >> 16) & 0xff; + state[2][i] ^= (W[i] >> 8) & 0xff; + state[3][i] ^= (W[i] ) & 0xff; + } +} + +static void sub_bytes(uint8_t state[4][4]) +{ + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + state[i][j] = S[state[i][j]]; + } + } +} + +static void inv_sub_bytes(uint8_t state[4][4]) +{ + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + state[i][j] = S_inv[state[i][j]]; + } + } +} + +/* + * |S00 S01 S02 S03| <<<0 |S00 S01 S02 S03| + * |S10 S11 S12 S13| <<<1 => |S11 S12 S13 S10| + * |S20 S21 S22 S23| <<<2 |S22 S23 S20 S21| + * |S30 S31 S32 S33| <<<3 |S33 S30 S31 S32| + */ +static void shift_rows(uint8_t state[4][4]) +{ + uint8_t tmp[4][4]; + + tmp[0][0] = state[0][0]; + tmp[0][1] = state[0][1]; + tmp[0][2] = state[0][2]; + tmp[0][3] = state[0][3]; + + tmp[1][0] = state[1][1]; + tmp[1][1] = state[1][2]; + tmp[1][2] = state[1][3]; + tmp[1][3] = state[1][0]; + + tmp[2][0] = state[2][2]; + tmp[2][1] = state[2][3]; + tmp[2][2] = state[2][0]; + tmp[2][3] = state[2][1]; + + tmp[3][0] = state[3][3]; + tmp[3][1] = state[3][0]; + tmp[3][2] = state[3][1]; + tmp[3][3] = state[3][2]; + + memcpy(state, tmp, sizeof(tmp)); + memset(tmp, 0, sizeof(tmp)); +} + + +/* + * |S00 S01 S02 S03| >>>0 |S00 S01 S02 S03| + * |S10 S11 S12 S13| >>>1 => |S13 S10 S11 S12| + * |S20 S21 S22 S23| >>>2 |S22 S23 S20 S21| + * |S30 S31 S32 S33| >>>3 |S31 S32 S33 S30| + */ +static void inv_shift_rows(uint8_t state[4][4]) +{ + uint8_t tmp[4][4]; + + tmp[0][0] = state[0][0]; + tmp[0][1] = state[0][1]; + tmp[0][2] = state[0][2]; + tmp[0][3] = state[0][3]; + + tmp[1][0] = state[1][3]; + tmp[1][1] = state[1][0]; + tmp[1][2] = state[1][1]; + tmp[1][3] = state[1][2]; + + tmp[2][0] = state[2][2]; + tmp[2][1] = state[2][3]; + tmp[2][2] = state[2][0]; + tmp[2][3] = state[2][1]; + + tmp[3][0] = state[3][1]; + tmp[3][1] = state[3][2]; + tmp[3][2] = state[3][3]; + tmp[3][3] = state[3][0]; + + memcpy(state, tmp, sizeof(tmp)); + memset(tmp, 0, sizeof(tmp)); +} + +/* + * GF(2^8) defSed by f(x) = x^8 + x^4 + x^3 + x + 1 + * x^8 == x^4 + x^3 + x + 1 = 0001,1011 = 0x1b + * if A[7] == 0 then 2 * A = (A << 1) + * else 2 * A = (A << 1) xor A + */ +#define x1(a) (a) + +static uint8_t x2(uint8_t a) { + return (a >> 7) ? ((a << 1) ^ 0x1b) : (a << 1); +} + +static uint8_t x3(uint8_t a) { + return x2(a) ^ x1(a); +} + +static uint8_t x9(uint8_t a) { + return x2(x2(x2(a))) ^ x1(a); +} + +/* 0x0b = 11 = 8 + 2 + 1 */ +static uint8_t xb(uint8_t a) { + return x2(x2(x2(a))) ^ x2(a) ^ x1(a); +} + +/* 0x0d = 13 = 8 + 4 + 1 */ +static uint8_t xd(uint8_t a) { + return x2(x2(x2(a))) ^ x2(x2(a)) ^ x1(a); +} + +/* 0x0e = 14 = 8 + 4 + 2 */ +static uint8_t xe(uint8_t a) { + return x2(x2(x2(a))) ^ x2(x2(a)) ^ x2(a); +} + +/* + * |2 3 1 1| |S00 S01 S02 S03| + * |1 2 3 1| |S10 S11 S12 S13| + * |1 1 2 3|*|S20 S21 S22 S23| + * |3 1 1 2| |S30 S31 S32 S33| + */ +static void mix_columns(uint8_t S[4][4]) +{ + uint8_t tmp[4][4]; + int i; + + /* i-th column */ + for (i = 0; i < 4; i++) { + tmp[0][i] = x2(S[0][i]) ^ x3(S[1][i]) ^ x1(S[2][i]) ^ x1(S[3][i]); + tmp[1][i] = x1(S[0][i]) ^ x2(S[1][i]) ^ x3(S[2][i]) ^ x1(S[3][i]); + tmp[2][i] = x1(S[0][i]) ^ x1(S[1][i]) ^ x2(S[2][i]) ^ x3(S[3][i]); + tmp[3][i] = x3(S[0][i]) ^ x1(S[1][i]) ^ x1(S[2][i]) ^ x2(S[3][i]); + } + + memcpy(S, tmp, sizeof(tmp)); + memset(tmp, 0, sizeof(tmp)); +} + +/* + * |0E 0B 0D 09| |02 03 01 01| |1 0 0 0| + * |09 0E 0B 0D|*|01 02 03 01| = |0 1 0 0| + * |0D 09 0E 0B| |01 01 02 03| |0 0 1 0| + * |0B 0D 09 0E| |03 01 01 02| |0 0 0 1| + * + */ +static void inv_mix_columns(uint8_t S[4][4]) +{ + uint8_t tmp[4][4]; + int i; + + /* i-th column */ + for (i = 0; i < 4; i++) { + tmp[0][i] = xe(S[0][i]) ^ xb(S[1][i]) ^ xd(S[2][i]) ^ x9(S[3][i]); + tmp[1][i] = x9(S[0][i]) ^ xe(S[1][i]) ^ xb(S[2][i]) ^ xd(S[3][i]); + tmp[2][i] = xd(S[0][i]) ^ x9(S[1][i]) ^ xe(S[2][i]) ^ xb(S[3][i]); + tmp[3][i] = xb(S[0][i]) ^ xd(S[1][i]) ^ x9(S[2][i]) ^ xe(S[3][i]); + } + + memcpy(S, tmp, sizeof(tmp)); + memset(tmp, 0, sizeof(tmp)); +} + +#ifdef CRYPTO_INFO +static void print_state(const uint8_t S[4][4]) +{ + int i; + for (i = 0; i < 4; i++) { + printf("%02x %02x %02x %02x\n", S[i][0], S[i][1], S[i][2], S[i][3]); + } + printf("\n"); +} +#endif + +void aes_encrypt(const AES_KEY *key, const uint8_t in[16], uint8_t out[16]) +{ + uint8_t state[4][4]; + size_t i; + + /* fill state columns */ + for (i = 0; i < 4; i++) { + state[0][i] = *in++; + state[1][i] = *in++; + state[2][i] = *in++; + state[3][i] = *in++; + } + + /* Sitial add round key */ + add_round_key(state, key->rk); + + /* first n-1 rounds */ + for (i = 1; i < key->rounds; i++) { + sub_bytes(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, key->rk + 4*i); + } + + /* last round withtmp mix columns */ + sub_bytes(state); + shift_rows(state); + add_round_key(state, key->rk + 4*i); + + /* tmpput state columns */ + for (i = 0; i < 4; i++) { + *out++ = state[0][i]; + *out++ = state[1][i]; + *out++ = state[2][i]; + *out++ = state[3][i]; + } + + memset(state, 0, sizeof(state)); +} + +void aes_decrypt(const AES_KEY *aes_key, const uint8_t in[16], uint8_t out[16]) +{ + uint8_t state[4][4]; + size_t i; + + /* fill state columns */ + for (i = 0; i < 4; i++) { + state[0][i] = *in++; + state[1][i] = *in++; + state[2][i] = *in++; + state[3][i] = *in++; + } + + /* Sitial add round key */ + add_round_key(state, aes_key->rk); + + /* first n-1 rounds */ + for (i = 1; i < aes_key->rounds; i++) { + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, aes_key->rk + 4*i); + inv_mix_columns(state); + } + + /* last round withtmp mix columns */ + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, aes_key->rk + 4*i); + + /* tmpput state columns */ + for (i = 0; i < 4; i++) { + *out++ = state[0][i]; + *out++ = state[1][i]; + *out++ = state[2][i]; + *out++ = state[3][i]; + } + + memset(state, 0, sizeof(state)); +} diff --git a/src/aes_modes.c b/src/aes_modes.c index 57b2b4e3..d54c4e37 100644 --- a/src/aes_modes.c +++ b/src/aes_modes.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,202 +7,203 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include - - -void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t nblocks, uint8_t *out) -{ - while (nblocks--) { - gmssl_memxor(out, in, iv, 16); - aes_encrypt(key, out, out); - iv = out; - in += 16; - out += 16; - } -} - -void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t nblocks, uint8_t *out) -{ - while (nblocks--) { - aes_decrypt(key, in, out); - memxor(out, iv, 16); - iv = in; - in += 16; - out += 16; - } -} - -int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - uint8_t block[16]; - size_t rem = inlen % 16; - int padding = 16 - inlen % 16; - - if (in) { - memcpy(block, in + inlen - rem, rem); - } - memset(block + rem, padding, padding); - if (inlen/16) { - aes_cbc_encrypt(key, iv, in, inlen/16, out); - out += inlen - rem; - iv = out - 16; - } - aes_cbc_encrypt(key, iv, block, 1, out); - *outlen = inlen - rem + 16; - return 1; -} - -int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - uint8_t block[16]; - size_t len = sizeof(block); - int padding; - - if (inlen == 0) { - error_print(); - return 0; - } - if (inlen%16 != 0 || inlen < 16) { - error_print(); - return -1; - } - if (inlen > 16) { - aes_cbc_decrypt(key, iv, in, inlen/16 - 1, out); - iv = in + inlen - 32; - } - aes_cbc_decrypt(key, iv, in + inlen - 16, 1, block); - padding = block[15]; - if (padding < 1 || padding > 16) { - error_print(); - return -1; - } - len -= padding; - memcpy(out + inlen - 16, block, len); - *outlen = inlen - padding; - return 1; -} - -static void ctr_incr(uint8_t a[16]) -{ - int i; - for (i = 15; i > 0; i--) { - a[i]++; - if (a[i]) break; - } -} - -void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out) -{ - uint8_t block[16]; - size_t len; - - while (inlen) { - len = inlen < 16 ? inlen : 16; - aes_encrypt(key, ctr, block); - gmssl_memxor(out, in, block, len); - ctr_incr(ctr); - in += len; - out += len; - inlen -= len; - } -} - -int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag) -{ - const uint8_t *pin = in; - uint8_t *pout = out; - size_t left = inlen; - uint8_t H[16] = {0}; - uint8_t Y[16]; - uint8_t T[16]; - - if (taglen > AES_GCM_MAX_TAG_SIZE) { - error_print(); - return -1; - } - - aes_encrypt(key, H, H); - - if (ivlen == 12) { - memcpy(Y, iv, 12); - Y[12] = Y[13] = Y[14] = 0; - Y[15] = 1; - } else { - ghash(H, NULL, 0, iv, ivlen, Y); - } - - aes_encrypt(key, Y, T); - - while (left) { - uint8_t block[16]; - size_t len = left < 16 ? left : 16; - ctr_incr(Y); - aes_encrypt(key, Y, block); - gmssl_memxor(pout, pin, block, len); - pin += len; - pout += len; - left -= len; - } - - ghash(H, aad, aadlen, out, inlen, H); - gmssl_memxor(tag, T, H, taglen); - return 1; -} - -int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out) -{ - const uint8_t *pin = in; - uint8_t *pout = out; - size_t left = inlen; - uint8_t H[16] = {0}; - uint8_t Y[16]; - uint8_t T[16]; - - aes_encrypt(key, H, H); - - if (ivlen == 12) { - memcpy(Y, iv, 12); - Y[12] = Y[13] = Y[14] = 0; - Y[15] = 1; - } else { - ghash(H, NULL, 0, iv, ivlen, Y); - } - - ghash(H, aad, aadlen, in, inlen, H); - aes_encrypt(key, Y, T); - gmssl_memxor(T, T, H, taglen); - if (memcmp(T, tag, taglen) != 0) { - error_print(); - return -1; - } - - while (left) { - uint8_t block[16]; - size_t len = left < 16 ? left : 16; - ctr_incr(Y); - aes_encrypt(key, Y, block); - gmssl_memxor(pout, pin, block, len); - pin += len; - pout += len; - left -= len; - } - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include + + +void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t nblocks, uint8_t *out) +{ + while (nblocks--) { + gmssl_memxor(out, in, iv, 16); + aes_encrypt(key, out, out); + iv = out; + in += 16; + out += 16; + } +} + +void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t nblocks, uint8_t *out) +{ + while (nblocks--) { + aes_decrypt(key, in, out); + memxor(out, iv, 16); + iv = in; + in += 16; + out += 16; + } +} + +int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + uint8_t block[16]; + size_t rem = inlen % 16; + int padding = 16 - inlen % 16; + + if (in) { + memcpy(block, in + inlen - rem, rem); + } + memset(block + rem, padding, padding); + if (inlen/16) { + aes_cbc_encrypt(key, iv, in, inlen/16, out); + out += inlen - rem; + iv = out - 16; + } + aes_cbc_encrypt(key, iv, block, 1, out); + *outlen = inlen - rem + 16; + return 1; +} + +int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + uint8_t block[16]; + size_t len = sizeof(block); + int padding; + + if (inlen == 0) { + error_print(); + return 0; + } + if (inlen%16 != 0 || inlen < 16) { + error_print(); + return -1; + } + if (inlen > 16) { + aes_cbc_decrypt(key, iv, in, inlen/16 - 1, out); + iv = in + inlen - 32; + } + aes_cbc_decrypt(key, iv, in + inlen - 16, 1, block); + padding = block[15]; + if (padding < 1 || padding > 16) { + error_print(); + return -1; + } + len -= padding; + memcpy(out + inlen - 16, block, len); + *outlen = inlen - padding; + return 1; +} + +static void ctr_incr(uint8_t a[16]) +{ + int i; + for (i = 15; i > 0; i--) { + a[i]++; + if (a[i]) break; + } +} + +void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out) +{ + uint8_t block[16]; + size_t len; + + while (inlen) { + len = inlen < 16 ? inlen : 16; + aes_encrypt(key, ctr, block); + gmssl_memxor(out, in, block, len); + ctr_incr(ctr); + in += len; + out += len; + inlen -= len; + } +} + +int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag) +{ + const uint8_t *pin = in; + uint8_t *pout = out; + size_t left = inlen; + uint8_t H[16] = {0}; + uint8_t Y[16]; + uint8_t T[16]; + + if (taglen > AES_GCM_MAX_TAG_SIZE) { + error_print(); + return -1; + } + + aes_encrypt(key, H, H); + + if (ivlen == 12) { + memcpy(Y, iv, 12); + Y[12] = Y[13] = Y[14] = 0; + Y[15] = 1; + } else { + ghash(H, NULL, 0, iv, ivlen, Y); + } + + aes_encrypt(key, Y, T); + + while (left) { + uint8_t block[16]; + size_t len = left < 16 ? left : 16; + ctr_incr(Y); + aes_encrypt(key, Y, block); + gmssl_memxor(pout, pin, block, len); + pin += len; + pout += len; + left -= len; + } + + ghash(H, aad, aadlen, out, inlen, H); + gmssl_memxor(tag, T, H, taglen); + return 1; +} + +int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out) +{ + const uint8_t *pin = in; + uint8_t *pout = out; + size_t left = inlen; + uint8_t H[16] = {0}; + uint8_t Y[16]; + uint8_t T[16]; + + aes_encrypt(key, H, H); + + if (ivlen == 12) { + memcpy(Y, iv, 12); + Y[12] = Y[13] = Y[14] = 0; + Y[15] = 1; + } else { + ghash(H, NULL, 0, iv, ivlen, Y); + } + + ghash(H, aad, aadlen, in, inlen, H); + aes_encrypt(key, Y, T); + gmssl_memxor(T, T, H, taglen); + if (memcmp(T, tag, taglen) != 0) { + error_print(); + return -1; + } + + while (left) { + uint8_t block[16]; + size_t len = left < 16 ? left : 16; + ctr_incr(Y); + aes_encrypt(key, Y, block); + gmssl_memxor(pout, pin, block, len); + pin += len; + pout += len; + left -= len; + } + return 1; +} diff --git a/src/asn1.c b/src/asn1.c index f23065c4..30513bb8 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1386 +7,1387 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -// https://www.obj-sys.com/asn1tutorial/node128.html - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - -## 返回值 - -解析函数返回错误: - -1. 输入数据长度为0,如待解析的对象具有OPTIONAL属性,那么不意味错误。 - 应显式告知调用方对象编码为空,由调用方判断是否为错误。 -2. 输入数据和目标对象类型不符,如待解析的对象具有OPTIONAL属性,那么意味目标对象为空。 -3. 长度和负载数据解析出错,这意味绝对的错误。 -4. 数据类型具有IMPLICIT属性时,意味着该对象的Tag被修改了,那么解析时调用方必须提供新的Tag。 - -DEFAULT值在接口上不提供这个功能,这个可以在数据的初始化时完成。 - - 内部接口不支持参数默认值或者多态的接口,例如不允许输入参数为空。 - 接口具有单一的逻辑可以通过严格的检查避免隐藏错误,提高健壮性。 - -*/ - - -static char *asn1_tag_index[] = { - "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]", "[8]", "[9]", - "[10]", "[11]", "[12]", "[13]", "[14]", "[15]", "[16]", "[17]", "[18]", "[19]", - "[20]", "[21]", "[22]", "[23]", "[24]", "[25]", "[26]", "[27]", "[28]", "[29]", - "[30]", "[31]", -}; - -const char *asn1_tag_name(int tag) -{ - if (tag < 0 || tag > 0xff) { - error_print(); - return NULL; - } - - switch (tag & 0xc0) { - case ASN1_TAG_CONTENT_SPECIFIC: return asn1_tag_index[tag & 0xe0]; - case ASN1_TAG_APPLICATION: return "Application"; - case ASN1_TAG_PRIVATE: return "Private"; - } - - switch (tag) { - case ASN1_TAG_BOOLEAN: return "BOOLEAN"; - case ASN1_TAG_INTEGER: return "INTEGER"; - case ASN1_TAG_BIT_STRING: return "BIT STRING"; - case ASN1_TAG_OCTET_STRING: return "OCTET STRING"; - case ASN1_TAG_NULL: return "NULL"; - case ASN1_TAG_OBJECT_IDENTIFIER: return "OBJECT IDENTIFIER"; - case ASN1_TAG_ObjectDescriptor: return "ObjectDescriptor"; - case ASN1_TAG_EXTERNAL: return "EXTERNAL"; - case ASN1_TAG_REAL: return "REAL"; - case ASN1_TAG_ENUMERATED: return "ENUMERATED"; - case ASN1_TAG_EMBEDDED: return "EMBEDDED"; - case ASN1_TAG_UTF8String: return "UTF8String"; - case ASN1_TAG_RELATIVE_OID: return "RELATIVE_OID"; - case ASN1_TAG_NumericString: return "NumericString"; - case ASN1_TAG_PrintableString: return "PrintableString"; - case ASN1_TAG_TeletexString: return "TeletexString"; - case ASN1_TAG_VideotexString: return "VideotexString"; - case ASN1_TAG_IA5String: return "IA5String"; - case ASN1_TAG_UTCTime: return "UTCTime"; - case ASN1_TAG_GeneralizedTime: return "GeneralizedTime"; - case ASN1_TAG_GraphicString: return "GraphicString"; - case ASN1_TAG_VisibleString: return "VisibleString"; - case ASN1_TAG_GeneralString: return "GeneralString"; - case ASN1_TAG_UniversalString: return "UniversalString"; - case ASN1_TAG_CHARACTER_STRING: return "CHARACTER STRING"; - case ASN1_TAG_BMPString: return "BMPString"; - case ASN1_TAG_SEQUENCE: return "SEQUENCE"; - case ASN1_TAG_SET: return "SET"; - case ASN1_TAG_EXPLICIT: return "EXPLICIT"; - } - - error_print(); - return NULL; -} - -int asn1_tag_is_cstring(int tag) -{ - switch (tag) { - case ASN1_TAG_UTF8String: - case ASN1_TAG_NumericString: - case ASN1_TAG_PrintableString: - case ASN1_TAG_TeletexString: - case ASN1_TAG_IA5String: - case ASN1_TAG_GeneralString: - return 1; - } - return 0; -} - -int asn1_utf8_string_check(const char *a, size_t alen) -{ - return 1; -} - -int asn1_printable_string_check(const char *a, size_t alen) -{ - return 1; -} - -int asn1_ia5_string_check(const char *a, size_t alen) -{ - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -// DER encoding -///////////////////////////////////////////////////////////////////////////////////////////// -// 这组函数不对输入进行检查 -// 还是检查报错比较方便,这样调用的函数更容易实现 -// asn.1编解码不考虑效率的问题 - -int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - *(*out)++ = (uint8_t)tag; - } - (*outlen)++; - return 1; -} - -int asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen) -{ - if (len < 128) { - if (out && *out) { - *(*out)++ = (uint8_t)len; - } - (*outlen)++; - - } else { - uint8_t buf[4]; - int i; - - PUTU32(buf, (uint32_t)len); - if (len < 256) i = 1; - else if (len < 65536) i = 2; - else if (len < (1 << 24)) i = 3; - else i = 4; - - if (out && *out) { - *(*out)++ = 0x80 + i; - memcpy(*out, buf + 4 - i, i); - (*out) += i; - } - (*outlen) += 1 + i; - } - return 1; -} - -// 提供返回值是为了和其他to_der函数一致 -int asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - memcpy(*out, data, datalen); - *out += datalen; - } - *outlen += datalen; - return 1; -} - -int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen) -{ - if (*inlen == 0) { - return 0; - } - if (**in != tag) { - return 0; - } - (*in)++; - (*inlen)--; - return 1; -} - -int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen) -{ - if (*inlen == 0) { - return 0; - } - *tag = **in; - return 1; -} - -int asn1_length_from_der(size_t *plen, const uint8_t **pin, size_t *pinlen) -{ - const uint8_t *in = *pin; - size_t inlen = *pinlen; - size_t len; - - if (inlen <= 0) { - return -1; - } - - - if (*in < 128) { - len = *in++; - inlen--; - } else { - uint8_t buf[4] = {0}; - int nbytes = *in++ & 0x7f; - //error_print_msg("nbytes = %d\n", nbytes); - - if (nbytes < 1 || nbytes > 4) { - error_print(); - return -1; - } - inlen--; - if (inlen < nbytes) { - error_print(); - return -1; - } - memcpy(buf + sizeof(buf) - nbytes, in, nbytes); - len = (size_t)GETU32(buf); - in += nbytes; - inlen -= nbytes; - } - - *plen = len; - *pin = in; - *pinlen = inlen; - - if (inlen < len) { - error_print_msg("inlen = %zu\n", *pinlen); - error_print_msg("length = %zu, left = %zu\n", len, inlen); - return -2; // 特殊错误值用于 test_asn1_length() 的测试 - } - return 1; -} - -int asn1_data_from_der(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen) -{ - if (*inlen < datalen) { - error_print(); - return -1; - } - *data = *in; - *in += datalen; - *inlen -= datalen; - return 1; -} - -int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen) -{ - if (!outlen) { - error_print(); - return -1; - } - asn1_tag_to_der(tag, out, outlen); - asn1_length_to_der(len, out, outlen); - return 1; -} - - -// If data == NULL, out should not be NULL -// 这个实现是不支持OPTIONAL的 -int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - if (!d) { - if (dlen) { - error_print(); - return -1; - } - return 0; - } - if (asn1_tag_to_der(tag, out, outlen) != 1 - || asn1_length_to_der(dlen, out, outlen) != 1 - || asn1_data_to_der(d, dlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { - if (ret < 0) error_print(); - else { - *d = NULL; - *dlen = 0; - } - return ret; - } - if (asn1_length_from_der(dlen, in, inlen) != 1 - || asn1_data_from_der(d, *dlen, in, inlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen) -{ - if (*inlen == 0) { - return 0; - } - *tag = *(*in)++; - (*inlen)--; - return 1; -} - - - -int asn1_any_type_from_der(int *tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) -{ - int ret; - if ((ret = asn1_any_tag_from_der(tag, in, inlen)) != 1) { - return ret; - } - if (asn1_length_from_der(datalen, in, inlen) != 1) { - error_print(); - return -1; - } - *data = *in; - *in += *datalen; - *inlen -= *datalen; - return 1; -} - -int asn1_any_to_der(const uint8_t *tlv, size_t tlvlen, uint8_t **out, size_t *outlen) -{ - return asn1_data_to_der(tlv, tlvlen, out, outlen); -} - -int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, size_t *inlen) -{ - int ret; - int tag; - const uint8_t *data; - size_t datalen; - - *tlv = *in; - *tlvlen = *inlen; - if ((ret = asn1_any_type_from_der(&tag, &data, &datalen, in, inlen)) != 1) { - error_print(); - return ret; - } - *tlvlen -= *inlen; - return 1; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#define ASN1_TRUE 0xff -#define ASN1_FALSE 0x00 - -const char *asn1_boolean_name(int val) -{ - switch (val) { - case 1: return "true"; - case 0: return "false"; - } - return NULL; -} - -int asn1_boolean_from_name(int *val, const char *name) -{ - if (strcmp(name, "true") == 0) { - *val = 1; - return 1; - } else if (strcmp(name, "false") == 0) { - *val = 0; - return 1; - } - *val = -1; - return -1; -} - -int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen) -{ - if (!outlen) { - error_print(); - return -1; - } - - if (val < 0) { - return 0; - } - - if (out && *out) { - *(*out)++ = tag; - *(*out)++ = 0x01; - *(*out)++ = val ? 0xff : 0x00; - } - (*outlen) += 3; - return 1; -} - -int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) -{ - if (!outlen) { - error_print(); - return -1; - } - - if (!a) { - return 0; - } - if (alen <= 0 || alen > INT_MAX) { - error_print(); - return -1; - } - - if (out && *out) - *(*out)++ = tag; - (*outlen)++; - - while (*a == 0 && alen > 1) { - a++; - alen--; - } - - if (a[0] & 0x80) { - asn1_length_to_der(alen + 1, out, outlen); - if (out && *out) { - *(*out)++ = 0x00; - memcpy(*out, a, alen); - (*out) += alen; - } - (*outlen) += 1 + alen; - } else { - asn1_length_to_der(alen, out ,outlen); - if (out && *out) { - memcpy(*out, a, alen); - (*out) += alen; - } - (*outlen) += alen; - } - - return 1; -} - -int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen) -{ - int i; - uint8_t buf[4] = {0}; - size_t len = 0; - - if (a == -1) { - return 0; - } - - while (a > 0) { - buf[3 - len] = a & 0xff; - a >>= 8; - len++; - } - if (!len) { - len = 1; - } - - return asn1_integer_to_der_ex(tag, buf + 4 - len, len, out, outlen); -} - -int asn1_bit_string_to_der_ex(int tag, const uint8_t *bits, size_t nbits, uint8_t **out, size_t *outlen) -{ - uint8_t unused = (8 - nbits % 8) % 8; - size_t nbytes = (nbits + 7) / 8; - - if (!bits) { - return 0; - } - if (asn1_tag_to_der(tag, out, outlen) != 1 - || asn1_length_to_der(nbytes + 1, out, outlen) != 1 - || asn1_data_to_der(&unused, 1, out, outlen) != 1 - || asn1_data_to_der(bits, nbytes, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int asn1_bit_octets_to_der_ex(int tag, const uint8_t *octs, size_t nocts, uint8_t **out, size_t *outlen) -{ - return asn1_bit_string_to_der_ex(tag, octs, nocts << 3, out, outlen); -} - -int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen) -{ - size_t nbits = 0; - uint8_t buf[4] = {0}; - int i = 0; - uint8_t mask = 0x80; - - if (bits < 0) { - return 0; - } - while (bits > 0) { - if (bits & 1) - buf[i] |= mask; - mask >>= 1; - bits >>= 1; - nbits++; - if (nbits % 8 == 0) { - i++; - mask = 0x80; - } - } - if (!nbits) { - nbits = 1; - } - return asn1_bit_string_to_der_ex(tag, buf, nbits, out, outlen); -} - -const char *asn1_null_name(void) -{ - return "null"; -} - -int asn1_null_to_der(uint8_t **out, size_t *outlen) -{ - if (!outlen) { - error_print(); - return -1; - } - if (out && *out) { - *(*out)++ = ASN1_TAG_NULL; - *(*out)++ = 0x00; - } - *outlen += 2; - return 1; -} - -static void asn1_oid_node_to_base128(uint32_t a, uint8_t **out, size_t *outlen) -{ - uint8_t buf[5]; - int n = 0; - - buf[n++] = a & 0x7f; - a >>= 7; - - while (a) { - buf[n++] = 0x80 | (a & 0x7f); - a >>= 7; - } - - while (n--) { - if (out && *out) - *(*out)++ = buf[n]; - (*outlen)++; - } -} - -// 实际上我们在解析的时候是不知道具体在哪里结束的 -// 解析是有可能出错的,如果没有发现最后一个0开头的字节就出错了 -// 还有值太大也会出错,我们最多读取5个字节 -// { 0x81, 0x82 } -// { 0x81, 0x82, 0x83, 0x84, 0x85, 0x06 } -static int asn1_oid_node_from_base128(uint32_t *a, const uint8_t **in, size_t *inlen) -{ - uint8_t buf[5]; - int n = 0; - int i; - - for (;;) { - if ((*inlen)-- < 1 || n >= 5) { - return -1; - } - buf[n] = *(*in)++; - if ((buf[n++] & 0x80) == 0) { - break; - } - } - - // 32 - 7*4 = 4, so the first byte should be like 1000bbbb - if (n == 5 && (buf[0] & 0x70)) { - return -1; - } - - *a = 0; - for (i = 0; i < n; i++) { - *a = ((*a) << 7) | (buf[i] & 0x7f); - } - - return 1; -} - -int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen) -{ - if (!outlen) { - error_print(); - return -1; - } - if (nodes_cnt < 2 || nodes_cnt > 32) { - return -1; - } - if (out) - *out++ = (uint8_t)(nodes[0] * 40 + nodes[1]); - (*outlen) = 1; - nodes += 2; - nodes_cnt -= 2; - - while (nodes_cnt--) { - asn1_oid_node_to_base128(*nodes++, &out, outlen); - } - return 1; -} - -// 因为这个函数总是被asn1函数调用的,因此给的输入数据长度是已知的 -int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen) -{ - size_t count = 0; - const uint8_t *p = in; - size_t len = inlen; - - if (!nodes || !nodes_cnt || !in || inlen <= 0) { - error_print(); - return -1; - } - - if (inlen < 1) { - error_print(); - return -1; - } - - // FIXME: 需要支持 nodes = NULL 吗? - if (nodes) { - *nodes++ = (*in) / 40; - *nodes++ = (*in) % 40; - } - in++; - inlen--; - count += 2; - - while (inlen) { - uint32_t val; - if (count > 32) { - error_print(); - return -1; - } - if (asn1_oid_node_from_base128(&val, &in, &inlen) < 0) { - error_print(); - return -1; - } - if (nodes) { - *nodes++ = val; - } - count++; - } - - *nodes_cnt = count; - return 1; -} - -int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen) -{ - uint8_t octets[32]; - size_t octetslen = 0; - - if (!outlen) { - error_print(); - return -1; - } - - if (out && *out) - *(*out)++ = tag; - (*outlen)++; - - asn1_object_identifier_to_octets(nodes, nodes_cnt, octets, &octetslen); - - asn1_length_to_der(octetslen, out, outlen); - - if (out && *out) { - // 注意:If out == NULL, *out ==> Segment Fault - memcpy(*out, octets, octetslen); - *out += octetslen; - } - *outlen += octetslen; - return 1; -} - -const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name) -{ - size_t i; - for (i = 0; i < count; i++) { - if (strcmp(infos[i].name, name) == 0) { - return &infos[i]; - } - } - return NULL; -} - -const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid) -{ - size_t i; - for (i = 0; i < count; i++) { - if (infos[i].oid == oid) { - return &infos[i]; - } - } - return NULL; -} - -// 如果一个正确解析的OID并不在infos列表中,那么仍然返回1,但是调用方必须检查返回的info是否为空 -int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt, - const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) -{ - int ret; - size_t i; - - if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - *info = NULL; - for (i = 0; i < count; i++) { - if (*nodes_cnt == infos[i].nodes_cnt - && memcmp(nodes, infos[i].nodes, (*nodes_cnt) * sizeof(int)) == 0) { - *info = &infos[i]; - goto end; - } - } -end: - return 1; -} - -// 和ex版本不同的是,如果在infos列表中未找到OID,返回错误 -int asn1_oid_info_from_der(const ASN1_OID_INFO **info, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) -{ - int ret; - uint32_t nodes[32]; - size_t nodes_cnt; - - if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (*info == NULL) { - asn1_object_identifier_print(stderr, 0, 0, "Unknown OID", NULL, nodes, nodes_cnt); - error_print(); - return -1; - } - return 1; -} - - -// asn1_oid_from_octets 不返回错误值,只返回 OID_undef -// 但是数据编码仍可能是非法的 -// 如果返回 OID_undef,需要通过 asn1_object_identifier_from_octets 判断格式是否正确 - -// 显然这个函数并不合适,因为在整个gmssl中,我们不提供完整的ASN.1数据库,无法从一个OID中给出解析 - - - - - - - - -int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); -} - -int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); -} - -int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); -} - -int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) -{ - struct tm tm_val; - char buf[ASN1_UTC_TIME_LEN + 1]; - - if (!outlen) { - error_print(); - return -1; - } - - gmtime_r(&a, &tm_val); - strftime(buf, sizeof(buf), "%y%m%d%H%M%SZ", &tm_val); - - if (out && *out) - *(*out)++ = tag; - (*outlen)++; - asn1_length_to_der(sizeof(buf)-1, out, outlen); - if (out && *out) { - memcpy(*out, buf, sizeof(buf)-1); - (*out) += sizeof(buf)-1; - } - *outlen += sizeof(buf)-1; - - return 1; -} - - -int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) -{ - struct tm tm_val; - char buf[ASN1_GENERALIZED_TIME_LEN + 1]; - - if (!outlen) { - error_print(); - return -1; - } - - gmtime_r(&a, &tm_val); - strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &tm_val); - //printf("%s %d: generalized time : %s\n", __FILE__, __LINE__, buf); - - if (out && *out) - *(*out)++ = tag; - (*outlen)++; - asn1_length_to_der(ASN1_GENERALIZED_TIME_LEN, out, outlen); - if (out && *out) { - memcpy(*out, buf, ASN1_GENERALIZED_TIME_LEN); - (*out) += ASN1_GENERALIZED_TIME_LEN; - } - *outlen += ASN1_GENERALIZED_TIME_LEN; - - return 1; -} - - -///////////////////////////////////////////////////////////////////////////////////////////// -// DER decoding -///////////////////////////////////////////////////////////////////////////////////////////// - - -/* -解码函数的返回值: - - ret == 0 - 当前剩余的数据数据长度为0 - 或者下一个对象与期待不符,即输入对象的标签不等于输入的tag - 当对象为OPTIONAL时,调用方可以通过判断返回值是否为0进行处理 - ret < 0 - 标签正确但是长度或数据解析出错 - ret == 1 - 解析正确 - - -解码函数的输入: - - *in != NULL - 例如一个SEQUENCE中的属性均为OPTIONAL,解析后指针仍不为空 - 因此不允许输入空的输入数据指针 - - -处理规则 - - 当返回值 ret <= 0 时,*tag, *in, *inlen 的值保持不变 - - 如果一个类型有 DEFAULT 属性,调用方可以将返回数据预先设置为默认值, - 如果该对象未被编码,即返回值为0,那么解码函数不会修改已经设置的默认值 - -*/ - -int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen) -{ - if (!val || !in || !(*in) || !inlen) { - return -1; - } - - if (*inlen <= 0 || **in != tag) { - *val = -1; - return 0; - } - if (*inlen < 3 - || *(*in + 1) != 0x01 - || (*(*in + 2) != 0 && *(*in + 2) != 0xff)) { - return -1; - } - *val = *(*in + 2) ? 1 : 0; - *in += 3; - *inlen -= 3; - return 1; -} - -int asn1_integer_from_der_ex(int tag, const uint8_t **a, size_t *alen, const uint8_t **pin, size_t *pinlen) -{ - const uint8_t *in = *pin; - size_t inlen = *pinlen; - size_t len; - - if (!a || !alen || !pin || !(*pin) || !pinlen) { - error_print(); - return -1; - } - - if (inlen-- <= 0 || *in++ != tag) { - return 0; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1 - || len <= 0) { - error_print(); - return -1; - } - - // 判断 ASN1_INTEGER 是否为负数,我们不支持负整数,返回特性不支持错误 - if (*in & 0x80) { - error_print(); - return -255; - } - - if (*in == 0 && len > 1) { - inlen--; - in++; - len--; - } - if (*in == 0 && len > 1) { - error_print(); - return -1; - } - *a = in; - *alen = len; - *pin = in + len; - *pinlen = inlen - len; - return 1; -} - -int asn1_int_from_der_ex(int tag, int *a, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len, i; - unsigned int val = 0; - - if (!a || !in || !(*in) || !inlen) { - error_print(); - return -1; - } - if ((ret = asn1_integer_from_der_ex(tag, &p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *a = -1; - return ret; - } - if (len > 8) { - error_print(); - return -1; - } - - for (i = 0; i < len; i++) { - val = (val << 8) | p[i]; - } - *a = val; - return 1; -} - -int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **in, size_t *inlen) -{ - int ret; - size_t len; - int unused_bits; - - if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { - if (ret < 0) error_print(); - else { - *bits = NULL; - *nbits = 0; - } - return ret; - } - if (asn1_length_from_der(&len, in, inlen) != 1 - || asn1_data_from_der(bits, len, in, inlen) != 1) { - error_print(); - return -1; - } - if (len < 2) { - error_print(); - return -1; - } - - - unused_bits = **bits; - - if (len < 1) { - error_print(); - return -1; - } - if (unused_bits > 8 || (len == 1 && unused_bits > 0)) { - error_print(); - return -1; - } - - (*bits)++; - *nbits = (len - 1) << 3; - - return 1; -} - -int asn1_bit_octets_from_der_ex(int tag, const uint8_t **octs, size_t *nocts, const uint8_t **in, size_t *inlen) -{ - int ret; - size_t nbits; - - if ((ret = asn1_bit_string_from_der_ex(tag, octs, &nbits, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (nbits % 8) { - error_print(); - return -1; - } - *nocts = nbits >> 3; - return 1; -} - -int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t nbits, i; - uint8_t c; - - if ((ret = asn1_bit_string_from_der_ex(tag, &p, &nbits, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (nbits > 31) { - error_print(); - return -1; - } - - *bits = 0; - for (i = 0; i < nbits; i++) { - if (i % 8 == 0) { - c = *p++; - } - *bits |= ((c & 0x80) >> 7) << i; - c <<= 1; - } - return 1; -} - -int asn1_null_from_der(const uint8_t **in, size_t *inlen) -{ - if (!in || !(*in) || !inlen) { - return -1; - } - if (*inlen <= 0 || **in != ASN1_TAG_NULL) { - return 0; - } - if (*inlen < 2 - || (*in)[1] != 0x00) { - return -1; - } - *in += 2; - *inlen -= 2; - return 1; -} - -int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, - const uint8_t **in, size_t *inlen) -{ - int ret; - size_t len; - const uint8_t *p; - - if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_length_from_der(&len, in, inlen) != 1 - || asn1_data_from_der(&p, len, in, inlen) != 1 - || asn1_object_identifier_from_octets(nodes, nodes_cnt, p, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int asn1_string_from_der(int tag, const char **a, size_t *alen, const uint8_t **pin, size_t *pinlen) -{ - const uint8_t *in = *pin; - size_t inlen = *pinlen; - size_t len; - - if (!a || !alen || !pin || !(*pin) || !pinlen) { - return -1; - } - - if (inlen-- <= 0 || *in++ != tag) { - return 0; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1 - || len <= 0) { - return -1; - } - *a = (char *)in; - *alen = len; - - *pin = in + len; - *pinlen = inlen - len; - return 1; -} - -int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) -{ - return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); -} - -int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) -{ - return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); -} - -int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) -{ - return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); -} - -/* -int hh, mm, ss; -struct tm when = {0}; - -sscanf_s(date, "%d:%d:%d", &hh, &mm, &ss); - - -when.tm_hour = hh; -when.tm_min = mm; -when.tm_sec = ss; - -time_t converted; -converted = mktime(&when); -*/ - -int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen) -{ - const uint8_t *in = *pin; - size_t inlen = *pinlen; - struct tm tm_val; - char buf[sizeof("YYYYMMDDHHMMSSZ")] = {0}; - size_t len; - int year; - - - if (!t || !pin || !(*pin) || !pinlen) { - return -1; - } - if (inlen-- <= 0 || *in++ != tag) { - return 0; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1 - || (len != sizeof("YYMMDDHHMMSSZ")-1 && len != sizeof("YYMMDDHHMMSS+HHMM")-1)) { - return -1; - } - memcpy(buf + 2, in, len); - - if (!isdigit(buf[2]) && !isdigit(buf[3])) { - return -1; - } - year = (buf[2] - '0') * 10 + (buf[3] - '0'); - if (year >= 50) { - buf[0] = '1'; - buf[1] = '9'; - } else { - buf[0] = '2'; - buf[1] = '0'; - } - if (len == sizeof("YYMMDDHHMMSSZ")-1) { - // 这里应该自己写一个函数来解析 - if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { // 注意:这个函数在Windows上没有!! - return -1; - } - } else { - return -1; - } - *t = timegm(&tm_val); // FIXME: Windows ! - - *pin = in + len; - *pinlen = inlen - len; - return 1; -} - -int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen) -{ - int ret; - const uint8_t *in = *pin; - size_t inlen = *pinlen; - struct tm tm_val; - char buf[sizeof("YYYYMMDDHHMMSS+HHMM")] = {0}; - size_t len; - - if ((ret = asn1_tag_from_der(tag, &in, &inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_length_from_der(&len, &in, &inlen) != 1) { - error_print(); - return -1; - } - if (len != sizeof("YYYYMMDDHHMMSSZ")-1 && len != sizeof("YYYYMMDDHHMMSS+HHMM")-1) { - error_print(); - return -1; - } - memcpy(buf, in, len); - - if (len == sizeof("YYYYMMDDHHMMSSZ")-1) { - if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { - error_print(); - return -1; - } - } else { - // TODO: 处理这种情况 - error_print(); - return -2; - } - *t = timegm(&tm_val); - *pin = in + len; - *pinlen = inlen - len; - return 1; -} - - -int asn1_check(int expr) -{ - if (expr) - return 1; - error_print(); - return -1; -} - -int asn1_length_is_zero(size_t len) -{ - if (len) { - error_print(); - return -1; - } - return 1; -} - -int asn1_length_le(size_t len1, size_t len2) -{ - if (len1 > len2) { - error_print(); - format_print(stderr, 0, 0, "%s: %zu <= %zu failed\n", __FUNCTION__, len1, len2); - return -1; - } - return 1; -} - -int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt) -{ - if (a_cnt == b_cnt - && memcmp(a, b, b_cnt * sizeof(uint32_t)) == 0) { - return 1; - } - return 0; -} - - -int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - size_t i; - for (i = 0; i < nums_cnt; i++) { - if (asn1_int_to_der(nums[i], NULL, &len) != 1) { - error_print(); - return -1; - } - } - if (asn1_sequence_header_to_der(len, out, outlen) != 1) { - error_print(); - return -1; - } - for (i = 0; i < nums_cnt; i++) { - if (asn1_int_to_der(nums[i], out, outlen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - *nums_cnt = 0; - while (dlen) { - int num; - if (asn1_int_from_der(&num, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (nums) { - *nums++ = num; - } - (*nums_cnt)++; - } - return 1; -} - -int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int val; - format_print(fp, fmt, ind, "%s: ", label); - while (dlen) { - if (asn1_int_from_der(&val, &d, &dlen) != 1) { - error_print(); - return -1; - } - fprintf(fp, "%d%s", val, dlen ? "," : ""); - } - fprintf(fp, "\n"); - return 1; -} - - -int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *label, const char *name, - const uint32_t *nodes, size_t nodes_cnt) -{ - size_t i; - format_print(fp, format, indent, "%s: %s", label, name ? name : "(unknown)"); - if (nodes) { - fprintf(fp, " ("); - for (i = 0; i < nodes_cnt - 1; i++) { - fprintf(fp, "%d.", (int)nodes[i]); - } - fprintf(fp, "%d)", nodes[i]); - } - fprintf(fp, "\n"); - return 1; -} - -int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) -{ - format_print(fp, fmt, ind, "%s: ", label); - while (dlen--) { - fprintf(fp, "%c", *d++); - } - fprintf(fp, "\n"); - return 1; -} - -int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits) -{ - size_t i; - format_print(fp, fmt, ind, "%s: ", label); - - for (i = 0; i < names_cnt; i++) { - if (bits & 0x01) - fprintf(fp, "%s%s", names[i], bits >> 1 ? "," : ""); - bits >>= 1; - } - fprintf(fp, "\n"); - if (bits) { - error_print(); - return -1; - } - return 1; -} - -int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt) -{ - error_print(); - return -1; -} - -int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag, - int index, const uint8_t **item_d, size_t *item_dlen) -{ - error_print(); - return -1; -} + + +// https://www.obj-sys.com/asn1tutorial/node128.html + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + +## 返回值 + +解析函数返回错误: + +1. 输入数据长度为0,如待解析的对象具有OPTIONAL属性,那么不意味错误。 + 应显式告知调用方对象编码为空,由调用方判断是否为错误。 +2. 输入数据和目标对象类型不符,如待解析的对象具有OPTIONAL属性,那么意味目标对象为空。 +3. 长度和负载数据解析出错,这意味绝对的错误。 +4. 数据类型具有IMPLICIT属性时,意味着该对象的Tag被修改了,那么解析时调用方必须提供新的Tag。 + +DEFAULT值在接口上不提供这个功能,这个可以在数据的初始化时完成。 + + 内部接口不支持参数默认值或者多态的接口,例如不允许输入参数为空。 + 接口具有单一的逻辑可以通过严格的检查避免隐藏错误,提高健壮性。 + +*/ + + +static char *asn1_tag_index[] = { + "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]", "[8]", "[9]", + "[10]", "[11]", "[12]", "[13]", "[14]", "[15]", "[16]", "[17]", "[18]", "[19]", + "[20]", "[21]", "[22]", "[23]", "[24]", "[25]", "[26]", "[27]", "[28]", "[29]", + "[30]", "[31]", +}; + +const char *asn1_tag_name(int tag) +{ + if (tag < 0 || tag > 0xff) { + error_print(); + return NULL; + } + + switch (tag & 0xc0) { + case ASN1_TAG_CONTENT_SPECIFIC: return asn1_tag_index[tag & 0xe0]; + case ASN1_TAG_APPLICATION: return "Application"; + case ASN1_TAG_PRIVATE: return "Private"; + } + + switch (tag) { + case ASN1_TAG_BOOLEAN: return "BOOLEAN"; + case ASN1_TAG_INTEGER: return "INTEGER"; + case ASN1_TAG_BIT_STRING: return "BIT STRING"; + case ASN1_TAG_OCTET_STRING: return "OCTET STRING"; + case ASN1_TAG_NULL: return "NULL"; + case ASN1_TAG_OBJECT_IDENTIFIER: return "OBJECT IDENTIFIER"; + case ASN1_TAG_ObjectDescriptor: return "ObjectDescriptor"; + case ASN1_TAG_EXTERNAL: return "EXTERNAL"; + case ASN1_TAG_REAL: return "REAL"; + case ASN1_TAG_ENUMERATED: return "ENUMERATED"; + case ASN1_TAG_EMBEDDED: return "EMBEDDED"; + case ASN1_TAG_UTF8String: return "UTF8String"; + case ASN1_TAG_RELATIVE_OID: return "RELATIVE_OID"; + case ASN1_TAG_NumericString: return "NumericString"; + case ASN1_TAG_PrintableString: return "PrintableString"; + case ASN1_TAG_TeletexString: return "TeletexString"; + case ASN1_TAG_VideotexString: return "VideotexString"; + case ASN1_TAG_IA5String: return "IA5String"; + case ASN1_TAG_UTCTime: return "UTCTime"; + case ASN1_TAG_GeneralizedTime: return "GeneralizedTime"; + case ASN1_TAG_GraphicString: return "GraphicString"; + case ASN1_TAG_VisibleString: return "VisibleString"; + case ASN1_TAG_GeneralString: return "GeneralString"; + case ASN1_TAG_UniversalString: return "UniversalString"; + case ASN1_TAG_CHARACTER_STRING: return "CHARACTER STRING"; + case ASN1_TAG_BMPString: return "BMPString"; + case ASN1_TAG_SEQUENCE: return "SEQUENCE"; + case ASN1_TAG_SET: return "SET"; + case ASN1_TAG_EXPLICIT: return "EXPLICIT"; + } + + error_print(); + return NULL; +} + +int asn1_tag_is_cstring(int tag) +{ + switch (tag) { + case ASN1_TAG_UTF8String: + case ASN1_TAG_NumericString: + case ASN1_TAG_PrintableString: + case ASN1_TAG_TeletexString: + case ASN1_TAG_IA5String: + case ASN1_TAG_GeneralString: + return 1; + } + return 0; +} + +int asn1_utf8_string_check(const char *a, size_t alen) +{ + return 1; +} + +int asn1_printable_string_check(const char *a, size_t alen) +{ + return 1; +} + +int asn1_ia5_string_check(const char *a, size_t alen) +{ + return 1; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +// DER encoding +///////////////////////////////////////////////////////////////////////////////////////////// +// 这组函数不对输入进行检查 +// 还是检查报错比较方便,这样调用的函数更容易实现 +// asn.1编解码不考虑效率的问题 + +int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + *(*out)++ = (uint8_t)tag; + } + (*outlen)++; + return 1; +} + +int asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen) +{ + if (len < 128) { + if (out && *out) { + *(*out)++ = (uint8_t)len; + } + (*outlen)++; + + } else { + uint8_t buf[4]; + int i; + + PUTU32(buf, (uint32_t)len); + if (len < 256) i = 1; + else if (len < 65536) i = 2; + else if (len < (1 << 24)) i = 3; + else i = 4; + + if (out && *out) { + *(*out)++ = 0x80 + i; + memcpy(*out, buf + 4 - i, i); + (*out) += i; + } + (*outlen) += 1 + i; + } + return 1; +} + +// 提供返回值是为了和其他to_der函数一致 +int asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + memcpy(*out, data, datalen); + *out += datalen; + } + *outlen += datalen; + return 1; +} + +int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen) +{ + if (*inlen == 0) { + return 0; + } + if (**in != tag) { + return 0; + } + (*in)++; + (*inlen)--; + return 1; +} + +int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen) +{ + if (*inlen == 0) { + return 0; + } + *tag = **in; + return 1; +} + +int asn1_length_from_der(size_t *plen, const uint8_t **pin, size_t *pinlen) +{ + const uint8_t *in = *pin; + size_t inlen = *pinlen; + size_t len; + + if (inlen <= 0) { + return -1; + } + + + if (*in < 128) { + len = *in++; + inlen--; + } else { + uint8_t buf[4] = {0}; + int nbytes = *in++ & 0x7f; + //error_print_msg("nbytes = %d\n", nbytes); + + if (nbytes < 1 || nbytes > 4) { + error_print(); + return -1; + } + inlen--; + if (inlen < nbytes) { + error_print(); + return -1; + } + memcpy(buf + sizeof(buf) - nbytes, in, nbytes); + len = (size_t)GETU32(buf); + in += nbytes; + inlen -= nbytes; + } + + *plen = len; + *pin = in; + *pinlen = inlen; + + if (inlen < len) { + error_print_msg("inlen = %zu\n", *pinlen); + error_print_msg("length = %zu, left = %zu\n", len, inlen); + return -2; // 特殊错误值用于 test_asn1_length() 的测试 + } + return 1; +} + +int asn1_data_from_der(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen) +{ + if (*inlen < datalen) { + error_print(); + return -1; + } + *data = *in; + *in += datalen; + *inlen -= datalen; + return 1; +} + +int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen) +{ + if (!outlen) { + error_print(); + return -1; + } + asn1_tag_to_der(tag, out, outlen); + asn1_length_to_der(len, out, outlen); + return 1; +} + + +// If data == NULL, out should not be NULL +// 这个实现是不支持OPTIONAL的 +int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + if (!d) { + if (dlen) { + error_print(); + return -1; + } + return 0; + } + if (asn1_tag_to_der(tag, out, outlen) != 1 + || asn1_length_to_der(dlen, out, outlen) != 1 + || asn1_data_to_der(d, dlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + else { + *d = NULL; + *dlen = 0; + } + return ret; + } + if (asn1_length_from_der(dlen, in, inlen) != 1 + || asn1_data_from_der(d, *dlen, in, inlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen) +{ + if (*inlen == 0) { + return 0; + } + *tag = *(*in)++; + (*inlen)--; + return 1; +} + + + +int asn1_any_type_from_der(int *tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) +{ + int ret; + if ((ret = asn1_any_tag_from_der(tag, in, inlen)) != 1) { + return ret; + } + if (asn1_length_from_der(datalen, in, inlen) != 1) { + error_print(); + return -1; + } + *data = *in; + *in += *datalen; + *inlen -= *datalen; + return 1; +} + +int asn1_any_to_der(const uint8_t *tlv, size_t tlvlen, uint8_t **out, size_t *outlen) +{ + return asn1_data_to_der(tlv, tlvlen, out, outlen); +} + +int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, size_t *inlen) +{ + int ret; + int tag; + const uint8_t *data; + size_t datalen; + + *tlv = *in; + *tlvlen = *inlen; + if ((ret = asn1_any_type_from_der(&tag, &data, &datalen, in, inlen)) != 1) { + error_print(); + return ret; + } + *tlvlen -= *inlen; + return 1; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define ASN1_TRUE 0xff +#define ASN1_FALSE 0x00 + +const char *asn1_boolean_name(int val) +{ + switch (val) { + case 1: return "true"; + case 0: return "false"; + } + return NULL; +} + +int asn1_boolean_from_name(int *val, const char *name) +{ + if (strcmp(name, "true") == 0) { + *val = 1; + return 1; + } else if (strcmp(name, "false") == 0) { + *val = 0; + return 1; + } + *val = -1; + return -1; +} + +int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen) +{ + if (!outlen) { + error_print(); + return -1; + } + + if (val < 0) { + return 0; + } + + if (out && *out) { + *(*out)++ = tag; + *(*out)++ = 0x01; + *(*out)++ = val ? 0xff : 0x00; + } + (*outlen) += 3; + return 1; +} + +int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) +{ + if (!outlen) { + error_print(); + return -1; + } + + if (!a) { + return 0; + } + if (alen <= 0 || alen > INT_MAX) { + error_print(); + return -1; + } + + if (out && *out) + *(*out)++ = tag; + (*outlen)++; + + while (*a == 0 && alen > 1) { + a++; + alen--; + } + + if (a[0] & 0x80) { + asn1_length_to_der(alen + 1, out, outlen); + if (out && *out) { + *(*out)++ = 0x00; + memcpy(*out, a, alen); + (*out) += alen; + } + (*outlen) += 1 + alen; + } else { + asn1_length_to_der(alen, out ,outlen); + if (out && *out) { + memcpy(*out, a, alen); + (*out) += alen; + } + (*outlen) += alen; + } + + return 1; +} + +int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen) +{ + int i; + uint8_t buf[4] = {0}; + size_t len = 0; + + if (a == -1) { + return 0; + } + + while (a > 0) { + buf[3 - len] = a & 0xff; + a >>= 8; + len++; + } + if (!len) { + len = 1; + } + + return asn1_integer_to_der_ex(tag, buf + 4 - len, len, out, outlen); +} + +int asn1_bit_string_to_der_ex(int tag, const uint8_t *bits, size_t nbits, uint8_t **out, size_t *outlen) +{ + uint8_t unused = (8 - nbits % 8) % 8; + size_t nbytes = (nbits + 7) / 8; + + if (!bits) { + return 0; + } + if (asn1_tag_to_der(tag, out, outlen) != 1 + || asn1_length_to_der(nbytes + 1, out, outlen) != 1 + || asn1_data_to_der(&unused, 1, out, outlen) != 1 + || asn1_data_to_der(bits, nbytes, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int asn1_bit_octets_to_der_ex(int tag, const uint8_t *octs, size_t nocts, uint8_t **out, size_t *outlen) +{ + return asn1_bit_string_to_der_ex(tag, octs, nocts << 3, out, outlen); +} + +int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen) +{ + size_t nbits = 0; + uint8_t buf[4] = {0}; + int i = 0; + uint8_t mask = 0x80; + + if (bits < 0) { + return 0; + } + while (bits > 0) { + if (bits & 1) + buf[i] |= mask; + mask >>= 1; + bits >>= 1; + nbits++; + if (nbits % 8 == 0) { + i++; + mask = 0x80; + } + } + if (!nbits) { + nbits = 1; + } + return asn1_bit_string_to_der_ex(tag, buf, nbits, out, outlen); +} + +const char *asn1_null_name(void) +{ + return "null"; +} + +int asn1_null_to_der(uint8_t **out, size_t *outlen) +{ + if (!outlen) { + error_print(); + return -1; + } + if (out && *out) { + *(*out)++ = ASN1_TAG_NULL; + *(*out)++ = 0x00; + } + *outlen += 2; + return 1; +} + +static void asn1_oid_node_to_base128(uint32_t a, uint8_t **out, size_t *outlen) +{ + uint8_t buf[5]; + int n = 0; + + buf[n++] = a & 0x7f; + a >>= 7; + + while (a) { + buf[n++] = 0x80 | (a & 0x7f); + a >>= 7; + } + + while (n--) { + if (out && *out) + *(*out)++ = buf[n]; + (*outlen)++; + } +} + +// 实际上我们在解析的时候是不知道具体在哪里结束的 +// 解析是有可能出错的,如果没有发现最后一个0开头的字节就出错了 +// 还有值太大也会出错,我们最多读取5个字节 +// { 0x81, 0x82 } +// { 0x81, 0x82, 0x83, 0x84, 0x85, 0x06 } +static int asn1_oid_node_from_base128(uint32_t *a, const uint8_t **in, size_t *inlen) +{ + uint8_t buf[5]; + int n = 0; + int i; + + for (;;) { + if ((*inlen)-- < 1 || n >= 5) { + return -1; + } + buf[n] = *(*in)++; + if ((buf[n++] & 0x80) == 0) { + break; + } + } + + // 32 - 7*4 = 4, so the first byte should be like 1000bbbb + if (n == 5 && (buf[0] & 0x70)) { + return -1; + } + + *a = 0; + for (i = 0; i < n; i++) { + *a = ((*a) << 7) | (buf[i] & 0x7f); + } + + return 1; +} + +int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen) +{ + if (!outlen) { + error_print(); + return -1; + } + if (nodes_cnt < 2 || nodes_cnt > 32) { + return -1; + } + if (out) + *out++ = (uint8_t)(nodes[0] * 40 + nodes[1]); + (*outlen) = 1; + nodes += 2; + nodes_cnt -= 2; + + while (nodes_cnt--) { + asn1_oid_node_to_base128(*nodes++, &out, outlen); + } + return 1; +} + +// 因为这个函数总是被asn1函数调用的,因此给的输入数据长度是已知的 +int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen) +{ + size_t count = 0; + const uint8_t *p = in; + size_t len = inlen; + + if (!nodes || !nodes_cnt || !in || inlen <= 0) { + error_print(); + return -1; + } + + if (inlen < 1) { + error_print(); + return -1; + } + + // FIXME: 需要支持 nodes = NULL 吗? + if (nodes) { + *nodes++ = (*in) / 40; + *nodes++ = (*in) % 40; + } + in++; + inlen--; + count += 2; + + while (inlen) { + uint32_t val; + if (count > 32) { + error_print(); + return -1; + } + if (asn1_oid_node_from_base128(&val, &in, &inlen) < 0) { + error_print(); + return -1; + } + if (nodes) { + *nodes++ = val; + } + count++; + } + + *nodes_cnt = count; + return 1; +} + +int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen) +{ + uint8_t octets[32]; + size_t octetslen = 0; + + if (!outlen) { + error_print(); + return -1; + } + + if (out && *out) + *(*out)++ = tag; + (*outlen)++; + + asn1_object_identifier_to_octets(nodes, nodes_cnt, octets, &octetslen); + + asn1_length_to_der(octetslen, out, outlen); + + if (out && *out) { + // 注意:If out == NULL, *out ==> Segment Fault + memcpy(*out, octets, octetslen); + *out += octetslen; + } + *outlen += octetslen; + return 1; +} + +const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name) +{ + size_t i; + for (i = 0; i < count; i++) { + if (strcmp(infos[i].name, name) == 0) { + return &infos[i]; + } + } + return NULL; +} + +const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid) +{ + size_t i; + for (i = 0; i < count; i++) { + if (infos[i].oid == oid) { + return &infos[i]; + } + } + return NULL; +} + +// 如果一个正确解析的OID并不在infos列表中,那么仍然返回1,但是调用方必须检查返回的info是否为空 +int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt, + const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) +{ + int ret; + size_t i; + + if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + *info = NULL; + for (i = 0; i < count; i++) { + if (*nodes_cnt == infos[i].nodes_cnt + && memcmp(nodes, infos[i].nodes, (*nodes_cnt) * sizeof(int)) == 0) { + *info = &infos[i]; + goto end; + } + } +end: + return 1; +} + +// 和ex版本不同的是,如果在infos列表中未找到OID,返回错误 +int asn1_oid_info_from_der(const ASN1_OID_INFO **info, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen) +{ + int ret; + uint32_t nodes[32]; + size_t nodes_cnt; + + if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (*info == NULL) { + asn1_object_identifier_print(stderr, 0, 0, "Unknown OID", NULL, nodes, nodes_cnt); + error_print(); + return -1; + } + return 1; +} + + +// asn1_oid_from_octets 不返回错误值,只返回 OID_undef +// 但是数据编码仍可能是非法的 +// 如果返回 OID_undef,需要通过 asn1_object_identifier_from_octets 判断格式是否正确 + +// 显然这个函数并不合适,因为在整个gmssl中,我们不提供完整的ASN.1数据库,无法从一个OID中给出解析 + + + + + + + + +int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); +} + +int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); +} + +int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); +} + +int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) +{ + struct tm tm_val; + char buf[ASN1_UTC_TIME_LEN + 1]; + + if (!outlen) { + error_print(); + return -1; + } + + gmtime_r(&a, &tm_val); + strftime(buf, sizeof(buf), "%y%m%d%H%M%SZ", &tm_val); + + if (out && *out) + *(*out)++ = tag; + (*outlen)++; + asn1_length_to_der(sizeof(buf)-1, out, outlen); + if (out && *out) { + memcpy(*out, buf, sizeof(buf)-1); + (*out) += sizeof(buf)-1; + } + *outlen += sizeof(buf)-1; + + return 1; +} + + +int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) +{ + struct tm tm_val; + char buf[ASN1_GENERALIZED_TIME_LEN + 1]; + + if (!outlen) { + error_print(); + return -1; + } + + gmtime_r(&a, &tm_val); + strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &tm_val); + //printf("%s %d: generalized time : %s\n", __FILE__, __LINE__, buf); + + if (out && *out) + *(*out)++ = tag; + (*outlen)++; + asn1_length_to_der(ASN1_GENERALIZED_TIME_LEN, out, outlen); + if (out && *out) { + memcpy(*out, buf, ASN1_GENERALIZED_TIME_LEN); + (*out) += ASN1_GENERALIZED_TIME_LEN; + } + *outlen += ASN1_GENERALIZED_TIME_LEN; + + return 1; +} + + +///////////////////////////////////////////////////////////////////////////////////////////// +// DER decoding +///////////////////////////////////////////////////////////////////////////////////////////// + + +/* +解码函数的返回值: + + ret == 0 + 当前剩余的数据数据长度为0 + 或者下一个对象与期待不符,即输入对象的标签不等于输入的tag + 当对象为OPTIONAL时,调用方可以通过判断返回值是否为0进行处理 + ret < 0 + 标签正确但是长度或数据解析出错 + ret == 1 + 解析正确 + + +解码函数的输入: + + *in != NULL + 例如一个SEQUENCE中的属性均为OPTIONAL,解析后指针仍不为空 + 因此不允许输入空的输入数据指针 + + +处理规则 + + 当返回值 ret <= 0 时,*tag, *in, *inlen 的值保持不变 + + 如果一个类型有 DEFAULT 属性,调用方可以将返回数据预先设置为默认值, + 如果该对象未被编码,即返回值为0,那么解码函数不会修改已经设置的默认值 + +*/ + +int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen) +{ + if (!val || !in || !(*in) || !inlen) { + return -1; + } + + if (*inlen <= 0 || **in != tag) { + *val = -1; + return 0; + } + if (*inlen < 3 + || *(*in + 1) != 0x01 + || (*(*in + 2) != 0 && *(*in + 2) != 0xff)) { + return -1; + } + *val = *(*in + 2) ? 1 : 0; + *in += 3; + *inlen -= 3; + return 1; +} + +int asn1_integer_from_der_ex(int tag, const uint8_t **a, size_t *alen, const uint8_t **pin, size_t *pinlen) +{ + const uint8_t *in = *pin; + size_t inlen = *pinlen; + size_t len; + + if (!a || !alen || !pin || !(*pin) || !pinlen) { + error_print(); + return -1; + } + + if (inlen-- <= 0 || *in++ != tag) { + return 0; + } + if (asn1_length_from_der(&len, &in, &inlen) != 1 + || len <= 0) { + error_print(); + return -1; + } + + // 判断 ASN1_INTEGER 是否为负数,我们不支持负整数,返回特性不支持错误 + if (*in & 0x80) { + error_print(); + return -255; + } + + if (*in == 0 && len > 1) { + inlen--; + in++; + len--; + } + if (*in == 0 && len > 1) { + error_print(); + return -1; + } + *a = in; + *alen = len; + *pin = in + len; + *pinlen = inlen - len; + return 1; +} + +int asn1_int_from_der_ex(int tag, int *a, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len, i; + unsigned int val = 0; + + if (!a || !in || !(*in) || !inlen) { + error_print(); + return -1; + } + if ((ret = asn1_integer_from_der_ex(tag, &p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *a = -1; + return ret; + } + if (len > 8) { + error_print(); + return -1; + } + + for (i = 0; i < len; i++) { + val = (val << 8) | p[i]; + } + *a = val; + return 1; +} + +int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **in, size_t *inlen) +{ + int ret; + size_t len; + int unused_bits; + + if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + else { + *bits = NULL; + *nbits = 0; + } + return ret; + } + if (asn1_length_from_der(&len, in, inlen) != 1 + || asn1_data_from_der(bits, len, in, inlen) != 1) { + error_print(); + return -1; + } + if (len < 2) { + error_print(); + return -1; + } + + + unused_bits = **bits; + + if (len < 1) { + error_print(); + return -1; + } + if (unused_bits > 8 || (len == 1 && unused_bits > 0)) { + error_print(); + return -1; + } + + (*bits)++; + *nbits = (len - 1) << 3; + + return 1; +} + +int asn1_bit_octets_from_der_ex(int tag, const uint8_t **octs, size_t *nocts, const uint8_t **in, size_t *inlen) +{ + int ret; + size_t nbits; + + if ((ret = asn1_bit_string_from_der_ex(tag, octs, &nbits, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (nbits % 8) { + error_print(); + return -1; + } + *nocts = nbits >> 3; + return 1; +} + +int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t nbits, i; + uint8_t c; + + if ((ret = asn1_bit_string_from_der_ex(tag, &p, &nbits, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (nbits > 31) { + error_print(); + return -1; + } + + *bits = 0; + for (i = 0; i < nbits; i++) { + if (i % 8 == 0) { + c = *p++; + } + *bits |= ((c & 0x80) >> 7) << i; + c <<= 1; + } + return 1; +} + +int asn1_null_from_der(const uint8_t **in, size_t *inlen) +{ + if (!in || !(*in) || !inlen) { + return -1; + } + if (*inlen <= 0 || **in != ASN1_TAG_NULL) { + return 0; + } + if (*inlen < 2 + || (*in)[1] != 0x00) { + return -1; + } + *in += 2; + *inlen -= 2; + return 1; +} + +int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt, + const uint8_t **in, size_t *inlen) +{ + int ret; + size_t len; + const uint8_t *p; + + if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_length_from_der(&len, in, inlen) != 1 + || asn1_data_from_der(&p, len, in, inlen) != 1 + || asn1_object_identifier_from_octets(nodes, nodes_cnt, p, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int asn1_string_from_der(int tag, const char **a, size_t *alen, const uint8_t **pin, size_t *pinlen) +{ + const uint8_t *in = *pin; + size_t inlen = *pinlen; + size_t len; + + if (!a || !alen || !pin || !(*pin) || !pinlen) { + return -1; + } + + if (inlen-- <= 0 || *in++ != tag) { + return 0; + } + if (asn1_length_from_der(&len, &in, &inlen) != 1 + || len <= 0) { + return -1; + } + *a = (char *)in; + *alen = len; + + *pin = in + len; + *pinlen = inlen - len; + return 1; +} + +int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) +{ + return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); +} + +int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) +{ + return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); +} + +int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen) +{ + return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); +} + +/* +int hh, mm, ss; +struct tm when = {0}; + +sscanf_s(date, "%d:%d:%d", &hh, &mm, &ss); + + +when.tm_hour = hh; +when.tm_min = mm; +when.tm_sec = ss; + +time_t converted; +converted = mktime(&when); +*/ + +int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen) +{ + const uint8_t *in = *pin; + size_t inlen = *pinlen; + struct tm tm_val; + char buf[sizeof("YYYYMMDDHHMMSSZ")] = {0}; + size_t len; + int year; + + + if (!t || !pin || !(*pin) || !pinlen) { + return -1; + } + if (inlen-- <= 0 || *in++ != tag) { + return 0; + } + if (asn1_length_from_der(&len, &in, &inlen) != 1 + || (len != sizeof("YYMMDDHHMMSSZ")-1 && len != sizeof("YYMMDDHHMMSS+HHMM")-1)) { + return -1; + } + memcpy(buf + 2, in, len); + + if (!isdigit(buf[2]) && !isdigit(buf[3])) { + return -1; + } + year = (buf[2] - '0') * 10 + (buf[3] - '0'); + if (year >= 50) { + buf[0] = '1'; + buf[1] = '9'; + } else { + buf[0] = '2'; + buf[1] = '0'; + } + if (len == sizeof("YYMMDDHHMMSSZ")-1) { + // 这里应该自己写一个函数来解析 + if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { // 注意:这个函数在Windows上没有!! + return -1; + } + } else { + return -1; + } + *t = timegm(&tm_val); // FIXME: Windows ! + + *pin = in + len; + *pinlen = inlen - len; + return 1; +} + +int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen) +{ + int ret; + const uint8_t *in = *pin; + size_t inlen = *pinlen; + struct tm tm_val; + char buf[sizeof("YYYYMMDDHHMMSS+HHMM")] = {0}; + size_t len; + + if ((ret = asn1_tag_from_der(tag, &in, &inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_length_from_der(&len, &in, &inlen) != 1) { + error_print(); + return -1; + } + if (len != sizeof("YYYYMMDDHHMMSSZ")-1 && len != sizeof("YYYYMMDDHHMMSS+HHMM")-1) { + error_print(); + return -1; + } + memcpy(buf, in, len); + + if (len == sizeof("YYYYMMDDHHMMSSZ")-1) { + if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { + error_print(); + return -1; + } + } else { + // TODO: 处理这种情况 + error_print(); + return -2; + } + *t = timegm(&tm_val); + *pin = in + len; + *pinlen = inlen - len; + return 1; +} + + +int asn1_check(int expr) +{ + if (expr) + return 1; + error_print(); + return -1; +} + +int asn1_length_is_zero(size_t len) +{ + if (len) { + error_print(); + return -1; + } + return 1; +} + +int asn1_length_le(size_t len1, size_t len2) +{ + if (len1 > len2) { + error_print(); + format_print(stderr, 0, 0, "%s: %zu <= %zu failed\n", __FUNCTION__, len1, len2); + return -1; + } + return 1; +} + +int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt) +{ + if (a_cnt == b_cnt + && memcmp(a, b, b_cnt * sizeof(uint32_t)) == 0) { + return 1; + } + return 0; +} + + +int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + size_t i; + for (i = 0; i < nums_cnt; i++) { + if (asn1_int_to_der(nums[i], NULL, &len) != 1) { + error_print(); + return -1; + } + } + if (asn1_sequence_header_to_der(len, out, outlen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < nums_cnt; i++) { + if (asn1_int_to_der(nums[i], out, outlen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + *nums_cnt = 0; + while (dlen) { + int num; + if (asn1_int_from_der(&num, &d, &dlen) != 1) { + error_print(); + return -1; + } + if (nums) { + *nums++ = num; + } + (*nums_cnt)++; + } + return 1; +} + +int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int val; + format_print(fp, fmt, ind, "%s: ", label); + while (dlen) { + if (asn1_int_from_der(&val, &d, &dlen) != 1) { + error_print(); + return -1; + } + fprintf(fp, "%d%s", val, dlen ? "," : ""); + } + fprintf(fp, "\n"); + return 1; +} + + +int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *label, const char *name, + const uint32_t *nodes, size_t nodes_cnt) +{ + size_t i; + format_print(fp, format, indent, "%s: %s", label, name ? name : "(unknown)"); + if (nodes) { + fprintf(fp, " ("); + for (i = 0; i < nodes_cnt - 1; i++) { + fprintf(fp, "%d.", (int)nodes[i]); + } + fprintf(fp, "%d)", nodes[i]); + } + fprintf(fp, "\n"); + return 1; +} + +int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) +{ + format_print(fp, fmt, ind, "%s: ", label); + while (dlen--) { + fprintf(fp, "%c", *d++); + } + fprintf(fp, "\n"); + return 1; +} + +int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits) +{ + size_t i; + format_print(fp, fmt, ind, "%s: ", label); + + for (i = 0; i < names_cnt; i++) { + if (bits & 0x01) + fprintf(fp, "%s%s", names[i], bits >> 1 ? "," : ""); + bits >>= 1; + } + fprintf(fp, "\n"); + if (bits) { + error_print(); + return -1; + } + return 1; +} + +int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt) +{ + error_print(); + return -1; +} + +int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag, + int index, const uint8_t **item_d, size_t *item_dlen) +{ + error_print(); + return -1; +} diff --git a/src/base64.c b/src/base64.c index 0aa992a3..dd95e19c 100644 --- a/src/base64.c +++ b/src/base64.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,372 +7,373 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - -static unsigned char conv_ascii2bin(unsigned char a); -#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) - - -/*- - * 64 char lines - * pad input with 0 - * left over chars are set to = - * 1 byte => xx== - * 2 bytes => xxx= - * 3 bytes => xxxx - */ -#define BIN_PER_LINE (64/4*3) -#define CHUNKS_PER_LINE (64/4) -#define CHAR_PER_LINE (64+1) - -static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ -abcdefghijklmnopqrstuvwxyz0123456789+/"; - -/*- - * 0xF0 is a EOLN - * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). - * 0xF2 is EOF - * 0xE0 is ignore at start of line. - * 0xFF is error - */ - -#define B64_EOLN 0xF0 -#define B64_CR 0xF1 -#define B64_EOF 0xF2 -#define B64_WS 0xE0 -#define B64_ERROR 0xFF -#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) -#define B64_BASE64(a) (!B64_NOT_BASE64(a)) - -static const unsigned char data_ascii2bin[128] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -static unsigned char conv_ascii2bin(unsigned char a) -{ - if (a & 0x80) - return B64_ERROR; - return data_ascii2bin[a]; -} - - -int base64_ctx_num(BASE64_CTX *ctx) -{ - return ctx->num; -} - -void base64_encode_init(BASE64_CTX *ctx) -{ - ctx->length = 48; - ctx->num = 0; - ctx->line_num = 0; -} - -int base64_encode_update(BASE64_CTX *ctx, const uint8_t *in, int inl, uint8_t *out, int *outl) -{ - int i, j; - size_t total = 0; - - *outl = 0; - if (inl <= 0) - return 0; - assert(ctx->length <= (int)sizeof(ctx->enc_data)); - if (ctx->length - ctx->num > inl) { - memcpy(&(ctx->enc_data[ctx->num]), in, inl); - ctx->num += inl; - return 1; - } - if (ctx->num != 0) { - i = ctx->length - ctx->num; - memcpy(&(ctx->enc_data[ctx->num]), in, i); - in += i; - inl -= i; - j = base64_encode_block(out, ctx->enc_data, ctx->length); - ctx->num = 0; - out += j; - *(out++) = '\n'; - *out = '\0'; - total = j + 1; - } - while (inl >= ctx->length && total <= INT_MAX) { - j = base64_encode_block(out, in, ctx->length); - in += ctx->length; - inl -= ctx->length; - out += j; - *(out++) = '\n'; - *out = '\0'; - total += j + 1; - } - if (total > INT_MAX) { - /* Too much output data! */ - *outl = 0; - return 0; - } - if (inl != 0) - memcpy(&(ctx->enc_data[0]), in, inl); - ctx->num = inl; - *outl = total; - - return 1; -} - -void base64_encode_finish(BASE64_CTX *ctx, uint8_t *out, int *outl) -{ - unsigned int ret = 0; - - if (ctx->num != 0) { - ret = base64_encode_block(out, ctx->enc_data, ctx->num); - out[ret++] = '\n'; - out[ret] = '\0'; - ctx->num = 0; - } - *outl = ret; -} - -int base64_encode_block(unsigned char *t, const unsigned char *f, int dlen) -{ - int i, ret = 0; - unsigned long l; - - for (i = dlen; i > 0; i -= 3) { - if (i >= 3) { - l = (((unsigned long)f[0]) << 16L) | - (((unsigned long)f[1]) << 8L) | f[2]; - *(t++) = conv_bin2ascii(l >> 18L); - *(t++) = conv_bin2ascii(l >> 12L); - *(t++) = conv_bin2ascii(l >> 6L); - *(t++) = conv_bin2ascii(l); - } else { - l = ((unsigned long)f[0]) << 16L; - if (i == 2) - l |= ((unsigned long)f[1] << 8L); - - *(t++) = conv_bin2ascii(l >> 18L); - *(t++) = conv_bin2ascii(l >> 12L); - *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); - *(t++) = '='; - } - ret += 4; - f += 3; - } - - *t = '\0'; - return (ret); -} - -void base64_decode_init(BASE64_CTX *ctx) -{ - /* Only ctx->num is used during decoding. */ - ctx->num = 0; - ctx->length = 0; - ctx->line_num = 0; - ctx->expect_nl = 0; -} - -/*- - * -1 for error - * 0 for last line - * 1 for full line - * - * Note: even though base64_decode_update attempts to detect and report end of - * content, the context doesn't currently remember it and will accept more data - * in the next call. Therefore, the caller is responsible for checking and - * rejecting a 0 return value in the middle of content. - * - * Note: even though base64_decode_update has historically tried to detect end of - * content based on line length, this has never worked properly. Therefore, - * we now return 0 when one of the following is true: - * - Padding or B64_EOF was detected and the last block is complete. - * - Input has zero-length. - * -1 is returned if: - * - Invalid characters are detected. - * - There is extra trailing padding, or data after padding. - * - B64_EOF is detected after an incomplete base64 block. - */ -int base64_decode_update(BASE64_CTX *ctx, const uint8_t *in, int inl, uint8_t *out, int *outl) -{ - int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; - unsigned char *d; - - n = ctx->num; - d = ctx->enc_data; - - if (n > 0 && d[n - 1] == '=') { - eof++; - if (n > 1 && d[n - 2] == '=') - eof++; - } - - /* Legacy behaviour: an empty input chunk signals end of input. */ - if (inl == 0) { - rv = 0; - goto end; - } - - for (i = 0; i < inl; i++) { - tmp = *(in++); - v = conv_ascii2bin(tmp); - if (v == B64_ERROR) { - rv = -1; - error_print(); - goto end; - } - - if (tmp == '=') { - eof++; - } else if (eof > 0 && B64_BASE64(v)) { - /* More data after padding. */ - rv = -1; - error_print(); - goto end; - } - - if (eof > 2) { - rv = -1; - error_print(); - goto end; - } - - if (v == B64_EOF) { - seof = 1; - goto tail; - } - - /* Only save valid base64 characters. */ - if (B64_BASE64(v)) { - if (n >= 64) { - /* - * We increment n once per loop, and empty the buffer as soon as - * we reach 64 characters, so this can only happen if someone's - * manually messed with the ctx. Refuse to write any more data. - */ - rv = -1; - error_print(); - goto end; - } - assert(n < (int)sizeof(ctx->enc_data)); - d[n++] = tmp; - } - - if (n == 64) { - decoded_len = base64_decode_block(out, d, n); - n = 0; - if (decoded_len < 0 || eof > decoded_len) { - rv = -1; - goto end; - } - ret += decoded_len - eof; - out += decoded_len - eof; - } - } - - /* - * Legacy behaviour: if the current line is a full base64-block (i.e., has - * 0 mod 4 base64 characters), it is processed immediately. We keep this - * behaviour as applications may not be calling base64_decode_final properly. - */ -tail: - if (n > 0) { - if ((n & 3) == 0) { - decoded_len = base64_decode_block(out, d, n); - n = 0; - if (decoded_len < 0 || eof > decoded_len) { - error_print(); - rv = -1; - goto end; - } - ret += (decoded_len - eof); - } else if (seof) { - /* EOF in the middle of a base64 block. */ - error_print(); - rv = -1; - goto end; - } - } - - rv = seof || (n == 0 && eof) ? 0 : 1; -end: - /* Legacy behaviour. This should probably rather be zeroed on error. */ - *outl = ret; - ctx->num = n; - return (rv); -} - -int base64_decode_block(unsigned char *t, const unsigned char *f, int n) -{ - int i, ret = 0, a, b, c, d; - unsigned long l; - - /* trim white space from the start of the line. */ - while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { - f++; - n--; - } - - /* - * strip off stuff at the end of the line ascii2bin values B64_WS, - * B64_EOLN, B64_EOLN and B64_EOF - */ - while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) - n--; - - if (n % 4 != 0) - return (-1); - - for (i = 0; i < n; i += 4) { - a = conv_ascii2bin(*(f++)); - b = conv_ascii2bin(*(f++)); - c = conv_ascii2bin(*(f++)); - d = conv_ascii2bin(*(f++)); - if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) - return (-1); - l = ((((unsigned long)a) << 18L) | - (((unsigned long)b) << 12L) | - (((unsigned long)c) << 6L) | (((unsigned long)d))); - *(t++) = (unsigned char)(l >> 16L) & 0xff; - *(t++) = (unsigned char)(l >> 8L) & 0xff; - *(t++) = (unsigned char)(l) & 0xff; - ret += 3; - } - return (ret); -} - -int base64_decode_finish(BASE64_CTX *ctx, uint8_t *out, int *outl) -{ - int i; - - *outl = 0; - if (ctx->num != 0) { - i = base64_decode_block(out, ctx->enc_data, ctx->num); - if (i < 0) { - error_print(); - return (-1); - } - ctx->num = 0; - *outl = i; - return (1); - } else - return (1); -} + + +#include +#include +#include +#include +#include +#include +#include + +static unsigned char conv_ascii2bin(unsigned char a); +#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) + + +/*- + * 64 char lines + * pad input with 0 + * left over chars are set to = + * 1 byte => xx== + * 2 bytes => xxx= + * 3 bytes => xxxx + */ +#define BIN_PER_LINE (64/4*3) +#define CHUNKS_PER_LINE (64/4) +#define CHAR_PER_LINE (64+1) + +static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +abcdefghijklmnopqrstuvwxyz0123456789+/"; + +/*- + * 0xF0 is a EOLN + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). + * 0xF2 is EOF + * 0xE0 is ignore at start of line. + * 0xFF is error + */ + +#define B64_EOLN 0xF0 +#define B64_CR 0xF1 +#define B64_EOF 0xF2 +#define B64_WS 0xE0 +#define B64_ERROR 0xFF +#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) +#define B64_BASE64(a) (!B64_NOT_BASE64(a)) + +static const unsigned char data_ascii2bin[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +static unsigned char conv_ascii2bin(unsigned char a) +{ + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} + + +int base64_ctx_num(BASE64_CTX *ctx) +{ + return ctx->num; +} + +void base64_encode_init(BASE64_CTX *ctx) +{ + ctx->length = 48; + ctx->num = 0; + ctx->line_num = 0; +} + +int base64_encode_update(BASE64_CTX *ctx, const uint8_t *in, int inl, uint8_t *out, int *outl) +{ + int i, j; + size_t total = 0; + + *outl = 0; + if (inl <= 0) + return 0; + assert(ctx->length <= (int)sizeof(ctx->enc_data)); + if (ctx->length - ctx->num > inl) { + memcpy(&(ctx->enc_data[ctx->num]), in, inl); + ctx->num += inl; + return 1; + } + if (ctx->num != 0) { + i = ctx->length - ctx->num; + memcpy(&(ctx->enc_data[ctx->num]), in, i); + in += i; + inl -= i; + j = base64_encode_block(out, ctx->enc_data, ctx->length); + ctx->num = 0; + out += j; + *(out++) = '\n'; + *out = '\0'; + total = j + 1; + } + while (inl >= ctx->length && total <= INT_MAX) { + j = base64_encode_block(out, in, ctx->length); + in += ctx->length; + inl -= ctx->length; + out += j; + *(out++) = '\n'; + *out = '\0'; + total += j + 1; + } + if (total > INT_MAX) { + /* Too much output data! */ + *outl = 0; + return 0; + } + if (inl != 0) + memcpy(&(ctx->enc_data[0]), in, inl); + ctx->num = inl; + *outl = total; + + return 1; +} + +void base64_encode_finish(BASE64_CTX *ctx, uint8_t *out, int *outl) +{ + unsigned int ret = 0; + + if (ctx->num != 0) { + ret = base64_encode_block(out, ctx->enc_data, ctx->num); + out[ret++] = '\n'; + out[ret] = '\0'; + ctx->num = 0; + } + *outl = ret; +} + +int base64_encode_block(unsigned char *t, const unsigned char *f, int dlen) +{ + int i, ret = 0; + unsigned long l; + + for (i = dlen; i > 0; i -= 3) { + if (i >= 3) { + l = (((unsigned long)f[0]) << 16L) | + (((unsigned long)f[1]) << 8L) | f[2]; + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = conv_bin2ascii(l >> 6L); + *(t++) = conv_bin2ascii(l); + } else { + l = ((unsigned long)f[0]) << 16L; + if (i == 2) + l |= ((unsigned long)f[1] << 8L); + + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(t++) = '='; + } + ret += 4; + f += 3; + } + + *t = '\0'; + return (ret); +} + +void base64_decode_init(BASE64_CTX *ctx) +{ + /* Only ctx->num is used during decoding. */ + ctx->num = 0; + ctx->length = 0; + ctx->line_num = 0; + ctx->expect_nl = 0; +} + +/*- + * -1 for error + * 0 for last line + * 1 for full line + * + * Note: even though base64_decode_update attempts to detect and report end of + * content, the context doesn't currently remember it and will accept more data + * in the next call. Therefore, the caller is responsible for checking and + * rejecting a 0 return value in the middle of content. + * + * Note: even though base64_decode_update has historically tried to detect end of + * content based on line length, this has never worked properly. Therefore, + * we now return 0 when one of the following is true: + * - Padding or B64_EOF was detected and the last block is complete. + * - Input has zero-length. + * -1 is returned if: + * - Invalid characters are detected. + * - There is extra trailing padding, or data after padding. + * - B64_EOF is detected after an incomplete base64 block. + */ +int base64_decode_update(BASE64_CTX *ctx, const uint8_t *in, int inl, uint8_t *out, int *outl) +{ + int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; + unsigned char *d; + + n = ctx->num; + d = ctx->enc_data; + + if (n > 0 && d[n - 1] == '=') { + eof++; + if (n > 1 && d[n - 2] == '=') + eof++; + } + + /* Legacy behaviour: an empty input chunk signals end of input. */ + if (inl == 0) { + rv = 0; + goto end; + } + + for (i = 0; i < inl; i++) { + tmp = *(in++); + v = conv_ascii2bin(tmp); + if (v == B64_ERROR) { + rv = -1; + error_print(); + goto end; + } + + if (tmp == '=') { + eof++; + } else if (eof > 0 && B64_BASE64(v)) { + /* More data after padding. */ + rv = -1; + error_print(); + goto end; + } + + if (eof > 2) { + rv = -1; + error_print(); + goto end; + } + + if (v == B64_EOF) { + seof = 1; + goto tail; + } + + /* Only save valid base64 characters. */ + if (B64_BASE64(v)) { + if (n >= 64) { + /* + * We increment n once per loop, and empty the buffer as soon as + * we reach 64 characters, so this can only happen if someone's + * manually messed with the ctx. Refuse to write any more data. + */ + rv = -1; + error_print(); + goto end; + } + assert(n < (int)sizeof(ctx->enc_data)); + d[n++] = tmp; + } + + if (n == 64) { + decoded_len = base64_decode_block(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += decoded_len - eof; + out += decoded_len - eof; + } + } + + /* + * Legacy behaviour: if the current line is a full base64-block (i.e., has + * 0 mod 4 base64 characters), it is processed immediately. We keep this + * behaviour as applications may not be calling base64_decode_final properly. + */ +tail: + if (n > 0) { + if ((n & 3) == 0) { + decoded_len = base64_decode_block(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + error_print(); + rv = -1; + goto end; + } + ret += (decoded_len - eof); + } else if (seof) { + /* EOF in the middle of a base64 block. */ + error_print(); + rv = -1; + goto end; + } + } + + rv = seof || (n == 0 && eof) ? 0 : 1; +end: + /* Legacy behaviour. This should probably rather be zeroed on error. */ + *outl = ret; + ctx->num = n; + return (rv); +} + +int base64_decode_block(unsigned char *t, const unsigned char *f, int n) +{ + int i, ret = 0, a, b, c, d; + unsigned long l; + + /* trim white space from the start of the line. */ + while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { + f++; + n--; + } + + /* + * strip off stuff at the end of the line ascii2bin values B64_WS, + * B64_EOLN, B64_EOLN and B64_EOF + */ + while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) + n--; + + if (n % 4 != 0) + return (-1); + + for (i = 0; i < n; i += 4) { + a = conv_ascii2bin(*(f++)); + b = conv_ascii2bin(*(f++)); + c = conv_ascii2bin(*(f++)); + d = conv_ascii2bin(*(f++)); + if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) + return (-1); + l = ((((unsigned long)a) << 18L) | + (((unsigned long)b) << 12L) | + (((unsigned long)c) << 6L) | (((unsigned long)d))); + *(t++) = (unsigned char)(l >> 16L) & 0xff; + *(t++) = (unsigned char)(l >> 8L) & 0xff; + *(t++) = (unsigned char)(l) & 0xff; + ret += 3; + } + return (ret); +} + +int base64_decode_finish(BASE64_CTX *ctx, uint8_t *out, int *outl) +{ + int i; + + *outl = 0; + if (ctx->num != 0) { + i = base64_decode_block(out, ctx->enc_data, ctx->num); + if (i < 0) { + error_print(); + return (-1); + } + ctx->num = 0; + *outl = i; + return (1); + } else + return (1); +} diff --git a/src/block_cipher.c b/src/block_cipher.c index dc8d5381..c4f22029 100644 --- a/src/block_cipher.c +++ b/src/block_cipher.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,76 +7,77 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) -{ - memset(key, 0, sizeof(BLOCK_CIPHER_KEY)); - cipher->set_encrypt_key(key, raw_key); - key->cipher = cipher; - return 1; -} - -int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) -{ - memset(key, 0, sizeof(BLOCK_CIPHER_KEY)); - cipher->set_decrypt_key(key, raw_key); - key->cipher = cipher; - return 1; -} - -int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out) -{ - key->cipher->encrypt(key, in, out); - return 1; -} - -int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out) -{ - key->cipher->decrypt(key, in, out); - return 1; -} - -static const BLOCK_CIPHER sm4_block_cipher_object = { - OID_sm4, - SM4_KEY_SIZE, - SM4_BLOCK_SIZE, - (block_cipher_set_encrypt_key_func)sm4_set_encrypt_key, - (block_cipher_set_decrypt_key_func)sm4_set_decrypt_key, - (block_cipher_encrypt_func)sm4_encrypt, - (block_cipher_decrypt_func)sm4_encrypt, -}; - -const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void) { - return &sm4_block_cipher_object; -} - -static int aes128_set_encrypt_key(AES_KEY *aes_key, const uint8_t key[16]) { - return aes_set_encrypt_key(aes_key, key, 16); -} - -static int aes128_set_decrypt_key(AES_KEY *aes_key, const uint8_t key[16]) { - return aes_set_decrypt_key(aes_key, key, 16); -} - -static const BLOCK_CIPHER aes128_block_cipher_object = { - OID_aes128, - AES128_KEY_SIZE, - AES_BLOCK_SIZE, - (block_cipher_set_encrypt_key_func)aes128_set_encrypt_key, - (block_cipher_set_decrypt_key_func)aes128_set_decrypt_key, - (block_cipher_encrypt_func)aes_encrypt, - (block_cipher_decrypt_func)aes_encrypt, -}; - -const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void) { - return &aes128_block_cipher_object; -} + + + +#include +#include +#include +#include +#include +#include + + +int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) +{ + memset(key, 0, sizeof(BLOCK_CIPHER_KEY)); + cipher->set_encrypt_key(key, raw_key); + key->cipher = cipher; + return 1; +} + +int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) +{ + memset(key, 0, sizeof(BLOCK_CIPHER_KEY)); + cipher->set_decrypt_key(key, raw_key); + key->cipher = cipher; + return 1; +} + +int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out) +{ + key->cipher->encrypt(key, in, out); + return 1; +} + +int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out) +{ + key->cipher->decrypt(key, in, out); + return 1; +} + +static const BLOCK_CIPHER sm4_block_cipher_object = { + OID_sm4, + SM4_KEY_SIZE, + SM4_BLOCK_SIZE, + (block_cipher_set_encrypt_key_func)sm4_set_encrypt_key, + (block_cipher_set_decrypt_key_func)sm4_set_decrypt_key, + (block_cipher_encrypt_func)sm4_encrypt, + (block_cipher_decrypt_func)sm4_encrypt, +}; + +const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void) { + return &sm4_block_cipher_object; +} + +static int aes128_set_encrypt_key(AES_KEY *aes_key, const uint8_t key[16]) { + return aes_set_encrypt_key(aes_key, key, 16); +} + +static int aes128_set_decrypt_key(AES_KEY *aes_key, const uint8_t key[16]) { + return aes_set_decrypt_key(aes_key, key, 16); +} + +static const BLOCK_CIPHER aes128_block_cipher_object = { + OID_aes128, + AES128_KEY_SIZE, + AES_BLOCK_SIZE, + (block_cipher_set_encrypt_key_func)aes128_set_encrypt_key, + (block_cipher_set_decrypt_key_func)aes128_set_decrypt_key, + (block_cipher_encrypt_func)aes_encrypt, + (block_cipher_decrypt_func)aes_encrypt, +}; + +const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void) { + return &aes128_block_cipher_object; +} diff --git a/src/chacha20.c b/src/chacha20.c index 96b01b62..59f40c89 100644 --- a/src/chacha20.c +++ b/src/chacha20.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,79 +7,80 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include - - -void chacha20_init(CHACHA20_STATE *state, - const uint8_t key[CHACHA20_KEY_SIZE], - const uint8_t nonce[CHACHA20_NONCE_SIZE], - uint32_t counter) -{ - state->d[ 0] = 0x61707865; - state->d[ 1] = 0x3320646e; - state->d[ 2] = 0x79622d32; - state->d[ 3] = 0x6b206574; - state->d[ 4] = GETU32_LE(key ); - state->d[ 5] = GETU32_LE(key + 4); - state->d[ 6] = GETU32_LE(key + 8); - state->d[ 7] = GETU32_LE(key + 12); - state->d[ 8] = GETU32_LE(key + 16); - state->d[ 9] = GETU32_LE(key + 20); - state->d[10] = GETU32_LE(key + 24); - state->d[11] = GETU32_LE(key + 28); - state->d[12] = counter; - state->d[13] = GETU32_LE(nonce); - state->d[14] = GETU32_LE(nonce + 4); - state->d[15] = GETU32_LE(nonce + 8); -} - -/* quarter round */ -#define QR(A, B, C, D) \ - A += B; D ^= A; D = ROL32(D, 16); \ - C += D; B ^= C; B = ROL32(B, 12); \ - A += B; D ^= A; D = ROL32(D, 8); \ - C += D; B ^= C; B = ROL32(B, 7) - -/* double round on state 4x4 matrix: - * four column rounds and and four diagonal rounds - * - * 0 1 2 3 - * 4 5 6 7 - * 8 9 10 11 - * 12 13 14 15 - * - */ -#define DR(S) \ - QR(S[0], S[4], S[ 8], S[12]); \ - QR(S[1], S[5], S[ 9], S[13]); \ - QR(S[2], S[6], S[10], S[14]); \ - QR(S[3], S[7], S[11], S[15]); \ - QR(S[0], S[5], S[10], S[15]); \ - QR(S[1], S[6], S[11], S[12]); \ - QR(S[2], S[7], S[ 8], S[13]); \ - QR(S[3], S[4], S[ 9], S[14]) - -void chacha20_generate_keystream(CHACHA20_STATE *state, size_t counts, uint8_t *out) -{ - uint32_t working_state[16]; - int i; - - while (counts-- > 0) { - memcpy(working_state, state->d, sizeof(working_state)); - for (i = 0; i < 10; i++) { - DR(working_state); - } - for (i = 0; i < 16; i++) { - working_state[i] += state->d[i]; - PUTU32_LE(out, working_state[i]); - out += sizeof(uint32_t); - } - state->d[12]++; - } -} + + + +#include +#include +#include +#include +#include + + +void chacha20_init(CHACHA20_STATE *state, + const uint8_t key[CHACHA20_KEY_SIZE], + const uint8_t nonce[CHACHA20_NONCE_SIZE], + uint32_t counter) +{ + state->d[ 0] = 0x61707865; + state->d[ 1] = 0x3320646e; + state->d[ 2] = 0x79622d32; + state->d[ 3] = 0x6b206574; + state->d[ 4] = GETU32_LE(key ); + state->d[ 5] = GETU32_LE(key + 4); + state->d[ 6] = GETU32_LE(key + 8); + state->d[ 7] = GETU32_LE(key + 12); + state->d[ 8] = GETU32_LE(key + 16); + state->d[ 9] = GETU32_LE(key + 20); + state->d[10] = GETU32_LE(key + 24); + state->d[11] = GETU32_LE(key + 28); + state->d[12] = counter; + state->d[13] = GETU32_LE(nonce); + state->d[14] = GETU32_LE(nonce + 4); + state->d[15] = GETU32_LE(nonce + 8); +} + +/* quarter round */ +#define QR(A, B, C, D) \ + A += B; D ^= A; D = ROL32(D, 16); \ + C += D; B ^= C; B = ROL32(B, 12); \ + A += B; D ^= A; D = ROL32(D, 8); \ + C += D; B ^= C; B = ROL32(B, 7) + +/* double round on state 4x4 matrix: + * four column rounds and and four diagonal rounds + * + * 0 1 2 3 + * 4 5 6 7 + * 8 9 10 11 + * 12 13 14 15 + * + */ +#define DR(S) \ + QR(S[0], S[4], S[ 8], S[12]); \ + QR(S[1], S[5], S[ 9], S[13]); \ + QR(S[2], S[6], S[10], S[14]); \ + QR(S[3], S[7], S[11], S[15]); \ + QR(S[0], S[5], S[10], S[15]); \ + QR(S[1], S[6], S[11], S[12]); \ + QR(S[2], S[7], S[ 8], S[13]); \ + QR(S[3], S[4], S[ 9], S[14]) + +void chacha20_generate_keystream(CHACHA20_STATE *state, size_t counts, uint8_t *out) +{ + uint32_t working_state[16]; + int i; + + while (counts-- > 0) { + memcpy(working_state, state->d, sizeof(working_state)); + for (i = 0; i < 10; i++) { + DR(working_state); + } + for (i = 0; i < 16; i++) { + working_state[i] += state->d[i]; + PUTU32_LE(out, working_state[i]); + out += sizeof(uint32_t); + } + state->d[12]++; + } +} diff --git a/src/cms.c b/src/cms.c index a7dbac23..91e5cc8e 100644 --- a/src/cms.c +++ b/src/cms.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,2474 +7,2475 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -static uint32_t oid_cms_data[] = { oid_sm2_cms,1 }; -static uint32_t oid_cms_signed_data[] = { oid_sm2_cms,2 }; -static uint32_t oid_cms_enveloped_data[] = { oid_sm2_cms,3 }; -static uint32_t oid_cms_signed_and_enveloped_data[] = { oid_sm2_cms,4 }; -static uint32_t oid_cms_encrypted_data[] = { oid_sm2_cms,5 }; -static uint32_t oid_cms_key_agreement_info[] = { oid_sm2_cms,6 }; -#define OID_CMS_CONUNT (sizeof(oid_cms_data)/sizeof(int)) - -static const ASN1_OID_INFO cms_content_types[] = { - { OID_cms_data, "data", oid_cms_data, OID_CMS_CONUNT }, - { OID_cms_signed_data, "signedData", oid_cms_signed_data, OID_CMS_CONUNT }, - { OID_cms_enveloped_data, "envelopedData", oid_cms_enveloped_data, OID_CMS_CONUNT }, - { OID_cms_signed_and_enveloped_data, "signedAndEnvelopedData", oid_cms_signed_and_enveloped_data, OID_CMS_CONUNT }, - { OID_cms_encrypted_data, "encryptedData", oid_cms_encrypted_data, OID_CMS_CONUNT }, - { OID_cms_key_agreement_info, "keyAgreementInfo", oid_cms_key_agreement_info, OID_CMS_CONUNT } -}; - -static const size_t cms_content_types_count = - sizeof(cms_content_types)/sizeof(cms_content_types[0]); - -const char *cms_content_type_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(cms_content_types, cms_content_types_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int cms_content_type_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(cms_content_types, cms_content_types_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - - if (oid == -1) { - return 0; - } - if (!(info = asn1_oid_info_from_oid(cms_content_types, cms_content_types_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - - if ((ret = asn1_oid_info_from_der(&info, cms_content_types, cms_content_types_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - -/* -static int cms_content_info_data_header_to_der(size_t dlen, uint8_t **out, size_t *outlen) -{ - uint8_t d[1]; - size_t len = 0; - size_t content_len = 0; - if (asn1_octet_string_to_der(p, dlen, NULL, &content_len) != 1 - || cms_content_type_to_der(OID_cms_data, out, outlen) != 1 - || asn1_explicit_header_to_der(0, content_len, out, outlen) < 0 - || asn1_octet_string_to_der(dlen, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} -*/ - -int cms_content_info_header_to_der(int content_type, size_t content_len, uint8_t **out, size_t *outlen) -{ - size_t len = content_len; // 注意:由于header_to_der没有输出数据,因此需要加上数据的长度,header length 才是正确的值 - /* - if (content_type == OID_cms_data) { - return cms_content_info_data_header_to_der(content_len, out, outlen); - } - */ - - if (cms_content_type_to_der(content_type, NULL, &len) != 1 - || asn1_explicit_header_to_der(0, content_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || cms_content_type_to_der(content_type, out, outlen) != 1 - || asn1_explicit_header_to_der(0, content_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -static int cms_content_info_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - size_t content_len = 0; - if (asn1_octet_string_to_der(d, dlen, NULL, &content_len) != 1 - || cms_content_type_to_der(OID_cms_data, NULL, &len) != 1 - || asn1_explicit_to_der(0, d, content_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || cms_content_type_to_der(OID_cms_data, out, outlen) != 1 - || asn1_explicit_header_to_der(0, content_len, out, outlen) != 1 - || asn1_octet_string_to_der(d, dlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_content_info_to_der( - int content_type, const uint8_t *content, size_t content_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (content_type == OID_cms_data) { - return cms_content_info_data_to_der(content, content_len, out, outlen); - } - if (cms_content_type_to_der(content_type, NULL, &len) != 1 - || asn1_explicit_to_der(0, content, content_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || cms_content_type_to_der(content_type, out, outlen) != 1 - || asn1_explicit_to_der(0, content, content_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int cms_content_info_from_der( - int *content_type, - const uint8_t **content, size_t *content_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (cms_content_type_from_der(content_type, &d, &dlen) != 1 - || asn1_explicit_from_der(0, content, content_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - int content_type; - const uint8_t *content; - size_t content_len; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (cms_content_type_from_der(&content_type, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "contentType: %s\n", cms_content_type_name(content_type)); - - /* - if (content_type == OID_cms_data) { - if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1) goto err; - } else { - if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) goto err; - } - */ - - //format_bytes(stderr, 0, 0, "content", d, dlen); - - if ((ret = asn1_explicit_from_der(0, &content, &content_len, &d, &dlen)) < 0) { error_print(); goto err; } - if (ret == 0) { error_print(); goto err; } - - if (content_type == OID_cms_data) { - if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1 - || asn1_length_is_zero(content_len) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "content", p, len); - return 1; - } - - - if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) { error_print(); goto err; } - - switch (content_type) { - //case OID_cms_data: format_bytes(fp, fmt, ind, "content", p, len); break; - case OID_cms_signed_data: cms_signed_data_print(fp, fmt, ind, "content", p, len); break; - case OID_cms_enveloped_data: cms_enveloped_data_print(fp, fmt, ind, "content", p, len); break; - case OID_cms_signed_and_enveloped_data: cms_signed_and_enveloped_data_print(fp, fmt, ind, "content", p, len); break; - case OID_cms_encrypted_data: cms_encrypted_data_print(fp, fmt, ind, "content", p, len); break; - case OID_cms_key_agreement_info: cms_key_agreement_info_print(fp, fmt, ind, "content", p, len); break; - } - if (asn1_length_is_zero(content_len) != 1) goto err; - - - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_enced_content_info_to_der( - int content_type, - int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (cms_content_type_to_der(content_type, NULL, &len) != 1 - || x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, NULL, &len) != 1 - || asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, NULL, &len) < 0 - || asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, NULL, &len) < 0 - || asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || cms_content_type_to_der(content_type, out, outlen) != 1 - || x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, out, outlen) != 1 - || asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, out, outlen) < 0 - || asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, out, outlen) < 0 - || asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int cms_enced_content_info_from_der( - int *content_type, - int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (cms_content_type_from_der(content_type, &d, &dlen) != 1 - || x509_encryption_algor_from_der(enc_algor, enc_iv, enc_iv_len, &d, &dlen) != 1 - || asn1_implicit_octet_string_from_der(0, enced_content, enced_content_len, &d, &dlen) < 0 - || asn1_implicit_octet_string_from_der(1, shared_info1, shared_info1_len, &d, &dlen) < 0 - || asn1_implicit_octet_string_from_der(2, shared_info2, shared_info2_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (cms_content_type_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "contentType: %s\n", cms_content_type_name(val)); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_encryption_algor_print(fp, fmt, ind, "contentEncryptionAlgorithm", p, len); - if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "encryptedContent", p, len); - if ((ret = asn1_implicit_octet_string_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "sharedInfo1", p, len); - if ((ret = asn1_implicit_octet_string_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "sharedInfo2", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_enced_content_info_encrypt_to_der( - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - int ret; - SM4_KEY sm4_key; - uint8_t enced_content[32 + content_len]; // FIXME: 如果content_len 过长,会直接导致segment fault - size_t enced_content_len = 100; - - if (enc_algor != OID_sm4_cbc || keylen != 16 || ivlen != 16) { - error_print(); - return -1; - } - - sm4_set_encrypt_key(&sm4_key, key); - if (sm4_cbc_padding_encrypt(&sm4_key, iv, content, content_len, - enced_content, &enced_content_len) != 1) { - memset(&sm4_key, 0, sizeof(SM4_KEY)); - error_print(); - return -1; - } - memset(&sm4_key, 0, sizeof(SM4_KEY)); - - if ((ret = cms_enced_content_info_to_der(content_type, - enc_algor, iv, ivlen, enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -// 这个函数显然是有问题的,调用方根本不知道应该准备多大的buffer -// 应该为content_len 输出给一个maxlen 的最大buffer值 -int cms_enced_content_info_decrypt_from_der( - int *enc_algor, const uint8_t *key, size_t keylen, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len,// 支持可选null输出 - const uint8_t **shared_info2, size_t *shared_info2_len,// 支持可选null输出 - const uint8_t **in, size_t *inlen) -{ - int ret; - SM4_KEY sm4_key; - const uint8_t *iv; - size_t ivlen; - const uint8_t *enced_content; - size_t enced_content_len; - - if (cms_enced_content_info_from_der(content_type, - enc_algor, &iv, &ivlen, &enced_content, &enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - in, inlen) != 1 - || asn1_check(*enc_algor == OID_sm4_cbc) != 1 - || asn1_check(ivlen == SM4_BLOCK_SIZE) != 1 - || asn1_check(keylen == SM4_KEY_SIZE) != 1) { - error_print(); - return -1; - } - - sm4_set_decrypt_key(&sm4_key, key); - if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_content, enced_content_len, - content, content_len) != 1) { - memset(&sm4_key, 0, sizeof(SM4_KEY)); - return -1; - } - memset(&sm4_key, 0, sizeof(SM4_KEY)); - - return 1; -} - -int cms_encrypted_data_to_der( - int version, - int content_type, - int enc_algor, const uint8_t *iv, size_t ivlen, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (version != 1) { - error_print(); - return -1; - } - if (asn1_int_to_der(version, NULL, &len) != 1 - || cms_enced_content_info_to_der( - content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || cms_enced_content_info_to_der( - content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_encrypted_data_from_der( - int *version, - int *content_type, - int *enc_algor, const uint8_t **iv, size_t *ivlen, - const uint8_t **enced_content, size_t *enced_content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || cms_enced_content_info_from_der( - content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*version != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_encrypted_data_encrypt_to_der( - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_encrypted_data_decrypt_from_der( - int *enc_algor, const uint8_t *key, size_t keylen, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen) -{ - int ret, version; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(&version, &d, &dlen) != 1 - || asn1_check(version == CMS_version_v1) != 1 - || cms_enced_content_info_decrypt_from_der( - enc_algor, key, keylen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_issuer_and_serial_number_to_der( - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1 - || asn1_integer_to_der(serial_number, serial_number_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1 - || asn1_integer_to_der(serial_number, serial_number_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_issuer_and_serial_number_from_der( - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_sequence_from_der(issuer, issuer_len, &d, &dlen) != 1 - || asn1_integer_from_der(serial_number, serial_number_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "issuer", p, len); - if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "serialNumber", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_signer_info_to_der( - int version, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - int digest_algor, - const uint8_t *authed_attrs, size_t authed_attrs_len, - int signature_algor, - const uint8_t *enced_digest, size_t enced_digest_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (version != 1) { - error_print(); - return -1; - } - - if (asn1_int_to_der(version, NULL, &len) != 1 - || cms_issuer_and_serial_number_to_der( - issuer, issuer_len, - serial_number, serial_number_len, NULL, &len) != 1 - || x509_digest_algor_to_der(digest_algor, NULL, &len) != 1 - || asn1_implicit_set_to_der(0, authed_attrs, authed_attrs_len, NULL, &len) < 0 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_octet_string_to_der(enced_digest, enced_digest_len, NULL, &len) != 1 - || asn1_implicit_set_to_der(1, unauthed_attrs, unauthed_attrs_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || cms_issuer_and_serial_number_to_der( - issuer, issuer_len, - serial_number, serial_number_len, out, outlen) != 1 - || x509_digest_algor_to_der(digest_algor, out, outlen) != 1 - || asn1_implicit_set_to_der(0, authed_attrs, authed_attrs_len, out, outlen) < 0 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || asn1_octet_string_to_der(enced_digest, enced_digest_len, out, outlen) != 1 - || asn1_implicit_set_to_der(1, unauthed_attrs, unauthed_attrs_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int cms_signer_info_from_der( - int *version, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - int *digest_algor, - const uint8_t **authed_attrs, size_t *authed_attrs_len, - int *signature_algor, - const uint8_t **enced_digest, size_t *enced_digest_len, - const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || cms_issuer_and_serial_number_from_der(issuer, issuer_len, - serial_number, serial_number_len, &d, &dlen) != 1 - || x509_digest_algor_from_der(digest_algor, &d, &dlen) != 1 - || asn1_implicit_set_from_der(0, authed_attrs, authed_attrs_len, &d, &dlen) < 0 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || asn1_octet_string_from_der(enced_digest, enced_digest_len, &d, &dlen) != 1 - || asn1_implicit_set_from_der(1, unauthed_attrs, unauthed_attrs_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_issuer_and_serial_number_print(fp, fmt, ind, "issuerAndSerialNumber", p, len); - if (x509_digest_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "digestAlgorithm: %s\n", x509_digest_algor_name(val)); - if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_attributes_print(fp, fmt, ind, "authenticatedAttributes", p, len); - if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "digestEncryptionAlgorithm: %s\n", x509_signature_algor_name(val)); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "encryptedDigest", p, len); - if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_attributes_print(fp, fmt, ind, "unauthenticatedAttributes", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_signer_info_sign_to_der( - const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, - uint8_t **out, size_t *outlen) -{ - SM3_CTX ctx = *sm3_ctx; - int fixed_outlen = 1; - uint8_t dgst[SM3_DIGEST_SIZE]; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - sm3_update(&ctx, authed_attrs, authed_attrs_len); - sm3_finish(&ctx, dgst); - - - - if (sm2_sign_ex(sign_key, fixed_outlen, dgst, sig, &siglen) != 1) { - error_print(); - return -1; - } - if (cms_signer_info_to_der(CMS_version_v1, - issuer, issuer_len, serial_number, serial_number_len, - OID_sm3, authed_attrs, authed_attrs_len, - OID_sm2sign_with_sm3, sig, siglen, - unauthed_attrs, unauthed_attrs_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signer_info_verify_from_der( - const SM3_CTX *ctx, const uint8_t *certs, size_t certslen, - const uint8_t **cert, size_t *certlen, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial, size_t *serial_len, - const uint8_t **authed_attrs, size_t *authed_attrs_len, - const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, - const uint8_t **in, size_t *inlen) -{ - int version; - int digest_algor; - int signature_algor; - const uint8_t *sig; - size_t siglen; - SM2_KEY public_key; - SM3_CTX sm3_ctx = *ctx; - uint8_t dgst[32]; - - if (cms_signer_info_from_der(&version, - issuer, issuer_len, - serial, serial_len, - &digest_algor, authed_attrs, authed_attrs_len, - &signature_algor, &sig, &siglen, - unauthed_attrs, unauthed_attrs_len, - in, inlen) != 1 - || asn1_check(version == CMS_version_v1) != 1 - || asn1_check(digest_algor == OID_sm3) != 1 - || asn1_check(signature_algor == OID_sm2sign_with_sm3) != 1) { - error_print(); - return -1; - } - if (x509_certs_get_cert_by_issuer_and_serial_number(certs, certslen, - *issuer, *issuer_len, *serial, *serial_len, cert, certlen) != 1 - || x509_cert_get_subject_public_key(*cert, *certlen, &public_key) != 1) { - error_print(); - return -1; - } - - sm3_update(&sm3_ctx, *authed_attrs, *authed_attrs_len); - sm3_finish(&sm3_ctx, dgst); - - if (sm2_verify(&public_key, dgst, sig, siglen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signer_infos_add_signer_info( - uint8_t *d, size_t *dlen, size_t maxlen, - const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *authed_attrs, size_t authed_attrs_len, - const uint8_t *unauthed_attrs, size_t unauthed_attrs_len) -{ - size_t len = *dlen; - d += *dlen; - if (cms_signer_info_sign_to_der(sm3_ctx, sign_key, - issuer, issuer_len, serial_number, serial_number_len, - authed_attrs, authed_attrs_len, - unauthed_attrs, unauthed_attrs_len, - NULL, &len) != 1 - || asn1_length_le(len, maxlen) != 1 - || cms_signer_info_sign_to_der(sm3_ctx, sign_key, - issuer, issuer_len, serial_number, serial_number_len, - authed_attrs, authed_attrs_len, - unauthed_attrs, unauthed_attrs_len, - &d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - cms_signer_info_print(fp, fmt, ind, "SignerInfo", p, len); - } - return 1; -} - -int cms_digest_algors_to_der(const int *digest_algors, size_t digest_algors_cnt, - uint8_t **out, size_t *outlen) -{ - size_t len = 0, i; - for (i = 0; i < digest_algors_cnt; i++) { - if (x509_digest_algor_to_der(digest_algors[i], NULL, &len) != 1) { - error_print(); - return -1; - } - } - if (asn1_set_header_to_der(len, out, outlen) != 1) { - error_print(); - return -1; - } - for (i = 0; i < digest_algors_cnt; i++) { - if (x509_digest_algor_to_der(digest_algors[i], out, outlen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int cms_digest_algors_from_der(int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_set_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - - *digest_algors_cnt = 0; - while (dlen) { - if (*digest_algors_cnt > max_digest_algors) { - error_print(); - return -1; - } - if (x509_digest_algor_from_der(digest_algors, &d, &dlen) != 1) { - error_print(); - return -1; - } - digest_algors++; - (*digest_algors_cnt)++; - } - return 1; -} - -int cms_digest_algors_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int oid; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (x509_digest_algor_from_der(&oid, &d, &dlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s\n", x509_digest_algor_name(oid)); - } - return 1; -} - -int cms_signed_data_to_der( - int version, - const int *digest_algors, size_t digest_algors_cnt, - const int content_type, const uint8_t *content, const size_t content_len, - const uint8_t *certs, size_t certs_len, - const uint8_t *crls, const size_t crls_len, - const uint8_t *signer_infos, size_t signer_infos_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(version, NULL, &len) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 - || cms_content_info_to_der(content_type, content, content_len, NULL, &len) != 1 - || asn1_implicit_set_to_der(0, certs, certs_len, NULL, &len) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 - || cms_signer_infos_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 - || cms_content_info_to_der(content_type, content, content_len, out, outlen) != 1 - || asn1_implicit_set_to_der(0, certs, certs_len, out, outlen) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 - || cms_signer_infos_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_data_from_der( - int *version, - int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || cms_digest_algors_from_der(digest_algors, digest_algors_cnt, max_digest_algors, &d, &dlen) != 1 - || cms_content_info_from_der(content_type, content, content_len, &d, &dlen) != 1 - || asn1_implicit_set_from_der(0, certs, certs_len, &d, &dlen) < 0 - || asn1_implicit_set_from_der(1, crls, crls_len, &d, &dlen) < 0 - || asn1_set_from_der(signer_infos, signer_infos_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*version != CMS_version_v1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_digest_algors_print(fp, fmt, ind, "digestAlgorithms", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_content_info_print(fp, fmt, ind, "contentInfo", p, len); - if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_certs_print(fp, fmt, ind, "certificates", p, len); - if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_signer_infos_print(fp, fmt, ind, "signerInfos", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -static int cms_implicit_signers_certs_to_der(int index, - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - uint8_t **out, size_t *outlen) -{ - size_t i; - size_t len = 0; - for (i = 0; i < signers_cnt; i++) { - if (asn1_data_to_der(signers[i].certs, signers[i].certs_len, NULL, &len) != 1) { - error_print(); - return -1; - } - } - if (asn1_implicit_header_to_der(index, len, out, outlen) != 1) { - error_print(); - return -1; - } - for (i = 0; i < signers_cnt; i++) { - if (asn1_data_to_der(signers[i].certs, signers[i].certs_len, out, outlen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int cms_signed_data_sign_to_der( - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - int content_type, const uint8_t *data, size_t datalen, - const uint8_t *crls, size_t crls_len, - uint8_t **out, size_t *outlen) -{ - int digest_algors[] = { OID_sm3 }; - size_t digest_algors_cnt = sizeof(digest_algors)/sizeof(int); - uint8_t content_header[256]; - size_t content_header_len; - const uint8_t *certs; - size_t certs_len = 0; - uint8_t signer_infos[512]; - size_t signer_infos_len = 0; - SM3_CTX sm3_ctx; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - uint8_t *p; - size_t len = 0; - size_t i; - - - // 当content_type == OID_cms_data 时,data是raw data,被封装为OCTET STRING编码输出 - // 而content_type为其他类型时,data均为TLV的DER数据 - // 在to_der/from_der 中已经处理,但是计算哈希值时也需要做处理 - p = content_header; - content_header_len = 0; - if (content_type == OID_cms_data) { - size_t content_len = 0; - if (asn1_octet_string_to_der(data, datalen, NULL, &content_len) != 1 - || cms_content_info_header_to_der(content_type, content_len, &p, &content_header_len) != 1 - || asn1_octet_string_header_to_der(datalen, &p, &content_header_len) != 1) { - error_print(); - return -1; - } - } else { - if (cms_content_info_header_to_der(content_type, datalen, &p, &content_header_len) != 1) { - error_print(); - return -1; - } - } - - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, content_header, content_header_len); - sm3_update(&sm3_ctx, data, datalen); - - for (i = 0; i < signers_cnt; i++) { - if (x509_cert_get_issuer_and_serial_number( - signers[i].certs, signers[i].certs_len, - &issuer, &issuer_len, &serial, &serial_len) != 1 - || cms_signer_infos_add_signer_info( - signer_infos, &signer_infos_len, sizeof(signer_infos), - &sm3_ctx, signers->sign_key, - issuer, issuer_len, serial, serial_len, - NULL, 0, NULL, 0) != 1) { - error_print(); - return -1; - } - } - - if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 - || cms_content_info_to_der(content_type, data, datalen, NULL, &len) != 1 - || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 - || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 - || cms_content_info_to_der(content_type, data, datalen, out, outlen) != 1 - || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 - || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_data_verify_from_der( - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **psigner_infos, size_t *psigner_infos_len, - const uint8_t **in, size_t *inlen) -{ - int version; - int digest_algors[4]; - size_t digest_algors_cnt; - SM3_CTX sm3_ctx; - uint8_t content_info_header[128]; - size_t content_info_header_len; - uint8_t *p = content_info_header; - const uint8_t *signer_infos; - size_t signer_infos_len; - - if (cms_signed_data_from_der( - &version, - digest_algors, &digest_algors_cnt, sizeof(digest_algors)/sizeof(int), - content_type, content, content_len, - certs, certs_len, - crls, crls_len, - &signer_infos, &signer_infos_len, - in, inlen) != 1 - || asn1_check(version == CMS_version_v1) != 1 - || asn1_check(digest_algors[0] == OID_sm3) != 1 - || asn1_check(digest_algors_cnt == 1) != 1) { - error_print(); - return -1; - } - *psigner_infos = signer_infos; - *psigner_infos_len = signer_infos_len; - - content_info_header_len = 0; - if (cms_content_info_header_to_der(*content_type, *content_len, - &p, &content_info_header_len) != 1) { - error_print(); - return -1; - } - sm3_init(&sm3_ctx); - - sm3_update(&sm3_ctx, content_info_header, content_info_header_len); - sm3_update(&sm3_ctx, *content, *content_len); - - while (signer_infos_len) { - const uint8_t *cert; - size_t certlen; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - const uint8_t *authed_attrs; - size_t authed_attrs_len; - const uint8_t *unauthed_attrs; - size_t unauthed_attrs_len; - - if (cms_signer_info_verify_from_der( - &sm3_ctx, *certs, *certs_len, - &cert, &certlen, - &issuer, &issuer_len, - &serial, &serial_len, - &authed_attrs, &authed_attrs_len, - &unauthed_attrs, &unauthed_attrs_len, - &signer_infos, &signer_infos_len) != 1) { - - error_print(); - return -1; - } - } - return 1; -} - -int cms_recipient_info_to_der( - int version, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - int public_key_enc_algor, - const uint8_t *enced_key, size_t enced_key_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (version != 1) { - error_print(); - return -1; - } - if (asn1_int_to_der(version, NULL, &len) != 1 - || cms_issuer_and_serial_number_to_der(issuer, issuer_len, - serial_number, serial_number_len, NULL, &len) != 1 - || x509_public_key_encryption_algor_to_der(public_key_enc_algor, NULL, &len) != 1 - || asn1_octet_string_to_der(enced_key, enced_key_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || cms_issuer_and_serial_number_to_der(issuer, issuer_len, - serial_number, serial_number_len, out, outlen) != 1 - || x509_public_key_encryption_algor_to_der(public_key_enc_algor, out, outlen) != 1 - || asn1_octet_string_to_der(enced_key, enced_key_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_recipient_info_from_der( - int *version, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len, - int *pke_algor, const uint8_t **params, size_t *params_len,// SM2加密只使用SM3,没有默认参数,但是ECIES可能有 - const uint8_t **enced_key, size_t *enced_key_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || cms_issuer_and_serial_number_from_der(issuer, issuer_len, - serial_number, serial_number_len, &d, &dlen) != 1 - || x509_public_key_encryption_algor_from_der(pke_algor, params, params_len, &d, &dlen) != 1 - || asn1_octet_string_from_der(enced_key, enced_key_len, &d, &dlen) != 1 - // || asn1_length_is_zero(dlen) != 1 - ) { - error_print(); - return -1; - } - if (*version != 1) { - error_print(); - return -1; - } - if (*pke_algor != OID_sm2encrypt) { - error_print(); - return -1; - } - if (*params || *params_len) { - error_print(); - return -1; - } - return 1; -} - -int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_issuer_and_serial_number_print(fp, fmt, ind, "issuerAndSerialNumber", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_public_key_encryption_algor_print(fp, fmt, ind, "keyEncryptionAlgorithm", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "encryptedKey", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_recipient_info_encrypt_to_der( - const SM2_KEY *public_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial_number, size_t serial_number_len, - const uint8_t *in, size_t inlen, - uint8_t **out, size_t *outlen) -{ - int pke_algor = OID_sm2encrypt; - uint8_t enced_key[SM2_MAX_CIPHERTEXT_SIZE]; - size_t enced_key_len; - int fixed_outlen = 1; - - if (pke_algor != OID_sm2encrypt) { - error_print(); - return -1; - } - - if (sm2_encrypt_ex(public_key, fixed_outlen, in, inlen, enced_key, &enced_key_len) != 1) { - error_print(); - return -1; - } - if (cms_recipient_info_to_der(CMS_version_v1, - issuer, issuer_len, serial_number, serial_number_len, - pke_algor, enced_key, enced_key_len, - out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_recipient_info_decrypt_from_der( - const SM2_KEY *sm2_key, - const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, - const uint8_t *rcpt_serial, size_t rcpt_serial_len, - uint8_t *out, size_t *outlen, size_t maxlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - int version; - int pke_algor; - const uint8_t *params; - size_t params_len; - const uint8_t *enced_key; - size_t enced_key_len; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - uint8_t outbuf[SM2_MAX_PLAINTEXT_SIZE]; - - if (cms_recipient_info_from_der(&version, - &issuer, &issuer_len, &serial, &serial_len, - &pke_algor, ¶ms, ¶ms_len, - &enced_key, &enced_key_len, - in, inlen) != 1) { - error_print(); - return -1; - } - if (issuer_len != rcpt_issuer_len - || memcmp(issuer, rcpt_issuer, rcpt_issuer_len) != 0 - || serial_len != rcpt_serial_len - || memcmp(serial, rcpt_serial, serial_len) != 0) { - error_print(); - return 0; - } - if (pke_algor != OID_sm2encrypt || params || params_len) { - error_print(); - return -1; - } - if (sm2_decrypt(sm2_key, enced_key, enced_key_len, outbuf, outlen) != 1) { - error_print(); - return -1; - } - if (maxlen < *outlen) { - error_print(); - return -1; - } - memcpy(out, outbuf, *outlen); - return 1; -} - -int cms_recipient_infos_add_recipient_info( - uint8_t *d, size_t *dlen, size_t maxlen, - const SM2_KEY *public_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - const uint8_t *in, size_t inlen) -{ - size_t len = *dlen; - d += *dlen; - - if (cms_recipient_info_encrypt_to_der( - public_key, - issuer, issuer_len, - serial, serial_len, - in, inlen, - NULL, &len) != 1 - || asn1_length_le(len, maxlen) != 1 - || cms_recipient_info_encrypt_to_der( - public_key, - issuer, issuer_len, - serial, serial_len, - in, inlen, - &d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - cms_recipient_info_print(fp, fmt, ind, "RecipientInfo", p, len); - } - return 1; -} - -int cms_enveloped_data_to_der( - int version, - const uint8_t *rcpt_infos, size_t rcpt_infos_len, - int content_type, - int enc_algor, const uint8_t *iv, size_t ivlen, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(version, NULL, &len) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 - || cms_enced_content_info_to_der(content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 - || cms_enced_content_info_to_der(content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_enveloped_data_from_der( - int *version, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **enced_content_info, size_t *enced_content_info_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || asn1_set_from_der(rcpt_infos, rcpt_infos_len, &d, &dlen) != 1 - || asn1_any_from_der(enced_content_info, enced_content_info_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_recipient_infos_print(fp, fmt, ind, "recipientInfos", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_enveloped_data_encrypt_to_der( - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - uint8_t rcpt_infos[1024]; // 到底需要多大? - size_t rcpt_infos_len = 0; - uint8_t *p = rcpt_infos; - size_t len = 0; - - while (rcpt_certs_len) { - const uint8_t *cert; - size_t certlen; - SM2_KEY public_key; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - - if (asn1_any_from_der(&cert, &certlen, &rcpt_certs, &rcpt_certs_len) != 1 - || x509_cert_get_issuer_and_serial_number(cert, certlen, - &issuer, &issuer_len, &serial, &serial_len) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { - error_print(); - return -1; - } - if (cms_recipient_info_encrypt_to_der(&public_key, - issuer, issuer_len, serial, serial_len, - key, keylen, NULL, &len) != 1 - || asn1_length_le(len, sizeof(rcpt_infos)) != 1 - || cms_recipient_info_encrypt_to_der(&public_key, - issuer, issuer_len, serial, serial_len, - key, keylen, &p, &rcpt_infos_len) != 1) { - error_print(); - return -1; - } - } - len = 0; - if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_enveloped_data_decrypt_from_der( - const SM2_KEY *sm2_key, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **recipient_infos, size_t *recipient_infos_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - int version; - const uint8_t *rcpt_infos; - size_t rcpt_infos_len; - const uint8_t *enced_content_info; - size_t enced_content_info_len; - int enc_algor; - uint8_t key[32]; - size_t keylen; - - if (cms_enveloped_data_from_der( - &version, &rcpt_infos, &rcpt_infos_len, - &enced_content_info, &enced_content_info_len, - in, inlen) != 1 - || asn1_check(version == CMS_version_v1) != 1) { - return ret; - } - *recipient_infos = rcpt_infos; - *recipient_infos_len = rcpt_infos_len; - - while (rcpt_infos_len) { - if ((ret = cms_recipient_info_decrypt_from_der( - sm2_key, - issuer, issuer_len, - serial, serial_len, - key, &keylen, sizeof(key), - &rcpt_infos, &rcpt_infos_len)) < 0) { - error_print(); - return -1; - } else if (ret) { - break; - } - } - if (!ret) { - error_print(); - return -1; - } - - if (cms_enced_content_info_decrypt_from_der( - &enc_algor, key, keylen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &enced_content_info, &enced_content_info_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_and_enveloped_data_to_der( - int version, - const uint8_t *rcpt_infos, size_t rcpt_infos_len, - const int *digest_algors, size_t digest_algors_cnt, - int content_type, - int enc_algor, const uint8_t *iv, size_t ivlen, - const uint8_t *enced_content, size_t enced_content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - const uint8_t *certs, size_t certs_len, - const uint8_t *crls, size_t crls_len, - const uint8_t *signer_infos, size_t signer_infos_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(version, NULL, &len) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 - || cms_enced_content_info_to_der(content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || asn1_implicit_set_to_der(0, certs, certs_len, NULL, &len) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 - || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 - || cms_enced_content_info_to_der(content_type, - enc_algor, iv, ivlen, - enced_content, enced_content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen) != 1 - || asn1_implicit_set_to_der(0, certs, certs_len, out, outlen) < 0 - || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 - || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_and_enveloped_data_from_der( - int *version, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, - const uint8_t **enced_content_info, size_t *enced_content_info_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || asn1_set_from_der(rcpt_infos, rcpt_infos_len, &d, &dlen) != 1 - || cms_digest_algors_from_der(digest_algors, digest_algors_cnt, max_digest_algors, &d, &dlen) != 1 - || asn1_any_from_der(enced_content_info, enced_content_info_len, &d, &dlen) != 1 - || asn1_implicit_set_from_der(0, certs, certs_len, &d, &dlen) < 0 - || asn1_implicit_set_from_der(1, crls, crls_len, &d, &dlen) < 0 - || asn1_set_from_der(signer_infos, signer_infos_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_recipient_infos_print(fp, fmt, ind, "recipientInfos", p, len); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_digest_algors_print(fp, fmt, ind, "digestAlgorithms", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); - if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_certs_print(fp, fmt, ind, "certificates", p, len); - if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_crls_print(fp, fmt, ind, "crls", p, len); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - cms_signer_infos_print(fp, fmt, ind, "signerInfos", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_signed_and_enveloped_data_encipher_to_der( - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *signers_crls, size_t signers_crls_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len, - uint8_t **out, size_t *outlen) -{ - uint8_t rcpt_infos[512]; - size_t rcpt_infos_len = 0; - int digest_algors[] = { OID_sm3 }; - size_t digest_algors_cnt = sizeof(digest_algors)/sizeof(int); - uint8_t content_info_header[256]; - size_t content_info_header_len = 0; - uint8_t signer_infos[512]; - size_t signer_infos_len = 0; - SM3_CTX sm3_ctx; - const uint8_t *issuer; - const uint8_t *serial; - size_t issuer_len; - size_t serial_len; - uint8_t *p; - size_t len = 0; - size_t i; - - p = rcpt_infos; - while (rcpt_certs_len) { - const uint8_t *cert; - size_t certlen; - SM2_KEY public_key; - - if (asn1_any_from_der(&cert, &certlen, &rcpt_certs, &rcpt_certs_len) != 1 - || x509_cert_get_issuer_and_serial_number(cert, certlen, - &issuer, &issuer_len, &serial, &serial_len) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 - || cms_recipient_info_encrypt_to_der(&public_key, - issuer, issuer_len, serial, serial_len, - key, keylen, NULL, &len) != 1 - || asn1_length_le(len, sizeof(rcpt_infos)) != 1 - || cms_recipient_info_encrypt_to_der(&public_key, - issuer, issuer_len, serial, serial_len, - key, keylen, &p, &rcpt_infos_len) != 1) { - error_print(); - return -1; - } - } - - p = content_info_header; - if (cms_content_info_header_to_der(content_type, content_len, - &p, &content_info_header_len) != 1) { - error_print(); - return -1; - } - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, content_info_header, content_info_header_len); - sm3_update(&sm3_ctx, content, content_len); - - for (i = 0; i < signers_cnt; i++) { - if (x509_cert_get_issuer_and_serial_number( - signers[i].certs, signers[i].certs_len, - &issuer, &issuer_len, &serial, &serial_len) != 1 - || cms_signer_infos_add_signer_info( - signer_infos, &signer_infos_len, sizeof(signer_infos), - &sm3_ctx, signers->sign_key, - issuer, issuer_len, serial, serial_len, - NULL, 0, NULL, 0) != 1) { - error_print(); - return -1; - } - } - - len = 0; - if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1 - || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) != 1 - || asn1_implicit_set_to_der(1, signers_crls, signers_crls_len, NULL, &len) < 0 - || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 - || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 - || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 - || cms_enced_content_info_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - out, outlen) != 1 - || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) != 1 - || asn1_implicit_set_to_der(1, signers_crls, signers_crls_len, out, outlen) != 1 - || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_signed_and_enveloped_data_decipher_from_der( - const SM2_KEY *rcpt_key, - const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, - const uint8_t *rcpt_serial, size_t rcpt_serial_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **prcpt_infos, size_t *prcpt_infos_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **psigner_infos, size_t *psigner_infos_len, - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - int version; - const uint8_t *rcpt_infos; - size_t rcpt_infos_len; - int digest_algors[4]; - size_t digest_algors_cnt; - const uint8_t *enced_content_info; - size_t enced_content_info_len; - const uint8_t *signer_infos; - size_t signer_infos_len; - int enc_algor; - uint8_t key[32]; - size_t keylen; - SM3_CTX sm3_ctx; - uint8_t content_info_header[128]; - size_t content_info_header_len = 0; - uint8_t *p = content_info_header; - - if (cms_signed_and_enveloped_data_from_der( - &version, - &rcpt_infos, &rcpt_infos_len, - digest_algors, &digest_algors_cnt, sizeof(digest_algors)/sizeof(int), - &enced_content_info, &enced_content_info_len, - certs, certs_len, - crls, crls_len, - &signer_infos, &signer_infos_len, - in, inlen) != 1 - || asn1_check(version == CMS_version_v1) != 1 - || asn1_check(digest_algors[0] == OID_sm3) != 1) { - error_print(); - return -1; - } - *prcpt_infos = rcpt_infos; - *prcpt_infos_len = rcpt_infos_len; - *psigner_infos = signer_infos; - *psigner_infos_len = signer_infos_len; - - while (rcpt_infos_len) { - if ((ret = cms_recipient_info_decrypt_from_der( - rcpt_key, - rcpt_issuer, rcpt_issuer_len, - rcpt_serial, rcpt_serial_len, - key, &keylen, sizeof(key), - &rcpt_infos, &rcpt_infos_len)) < 0) { - error_print(); - return -1; - } else if (ret) { - break; - } - } - if (!ret) { - error_print(); - return -1; - } - - if (cms_enced_content_info_decrypt_from_der( - &enc_algor, key, keylen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &enced_content_info, &enced_content_info_len) != 1) { - error_print(); - return -1; - } - - if (cms_content_info_header_to_der(*content_type, *content_len, - &p, &content_info_header_len) != 1) { - error_print(); - return -1; - } - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, content_info_header, content_info_header_len); - sm3_update(&sm3_ctx, content, *content_len); - - while (signer_infos_len) { - const uint8_t *cert; - size_t certlen; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - const uint8_t *authed_attrs; - size_t authed_attrs_len; - const uint8_t *unauthed_attrs; - size_t unauthed_attrs_len; - - if (cms_signer_info_verify_from_der( - &sm3_ctx, *certs, *certs_len, - &cert, &certlen, - &issuer, &issuer_len, - &serial, &serial_len, - &authed_attrs, &authed_attrs_len, - &unauthed_attrs, &unauthed_attrs_len, - &signer_infos, &signer_infos_len) != 1) { - error_print(); - return -1; - } - } - - return 1; -} - -int cms_key_agreement_info_to_der( - int version, - const SM2_KEY *temp_public_key_r, - const uint8_t *user_cert, size_t user_cert_len, - const uint8_t *user_id, size_t user_id_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(version, NULL, &len) != 1 - || sm2_public_key_info_to_der(temp_public_key_r, NULL, &len) != 1 - || x509_cert_to_der(user_cert, user_cert_len, NULL, &len) != 1 - || asn1_octet_string_to_der(user_id, user_id_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || sm2_public_key_info_to_der(temp_public_key_r, out, outlen) != 1 - || x509_cert_to_der(user_cert, user_cert_len, out, outlen) != 1 - || asn1_octet_string_to_der(user_id, user_id_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_key_agreement_info_from_der( - int *version, - SM2_KEY *temp_public_key_r, - const uint8_t **user_cert, size_t *user_cert_len, - const uint8_t **user_id, size_t *user_id_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || sm2_public_key_info_from_der(temp_public_key_r, &d, &dlen) != 1 - || x509_cert_from_der(user_cert, user_cert_len, &d, &dlen) != 1 - || asn1_octet_string_from_der(user_id, user_id_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int val; - SM2_KEY pub_key; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (sm2_public_key_info_from_der(&pub_key, &d, &dlen) != 1) goto err; - sm2_public_key_print(fp, fmt, ind, "tempPublicKeyR", &pub_key); - if (x509_cert_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_cert_print(fp, fmt, ind, "certificate", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_string(fp, fmt, ind, "userID", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int cms_set_data(uint8_t *cms, size_t *cmslen, const uint8_t *d, size_t dlen) -{ - int oid = OID_cms_data; - size_t len = 0; - - if (asn1_octet_string_to_der(d, dlen, NULL, &len) < 0) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || asn1_octet_string_to_der(d, dlen, &cms, cmslen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int cms_encrypt(uint8_t *cms, size_t *cmslen, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len) -{ - int oid = OID_cms_encrypted_data; - size_t len = 0; - - if (cms_encrypted_data_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || cms_encrypted_data_encrypt_to_der( - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &cms, cmslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_decrypt(const uint8_t *cms, size_t cmslen, - int *enc_algor, const uint8_t *key, size_t keylen, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len) -{ - int cms_type; - const uint8_t *cms_content; - size_t cms_content_len; - - if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 - || asn1_check(cms_type == OID_cms_encrypted_data) != 1 - || asn1_check(cms_content && cms_content_len) != 1 - || asn1_length_is_zero(cmslen) != 1) { - error_print(); - return -1; - } - if (cms_encrypted_data_decrypt_from_der( - enc_algor, key, keylen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &cms_content, &cms_content_len) != 1 - || asn1_length_is_zero(cms_content_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_sign(uint8_t *cms, size_t *cmslen, - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *crls, size_t crls_len) -{ - int oid = OID_cms_signed_data; - size_t len = 0; - - if (cms_signed_data_sign_to_der( - signers, signers_cnt, - content_type, content, content_len, - crls, crls_len, - NULL, &len) != 1) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || cms_signed_data_sign_to_der( - signers, signers_cnt, - content_type, content, content_len, - crls, crls_len, - &cms, cmslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_verify(const uint8_t *cms, size_t cmslen, - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - int *content_type, const uint8_t **content, size_t *content_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **signer_infos, size_t *signer_infos_len) -{ - int cms_type; - const uint8_t *cms_content; - size_t cms_content_len; - - if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 - || asn1_length_is_zero(cmslen) != 1) { - error_print(); - return -1; - } - if (cms_type != OID_cms_signed_data) { - error_print(); - return -1; - } - if (cms_content_len <= 0) { - error_print(); - return -1; - } - - if (cms_signed_data_verify_from_der( - extra_certs, extra_certs_len, - extra_crls, extra_crls_len, - content_type, content, content_len, - certs, certs_len, - crls, crls_len, - signer_infos, signer_infos_len, - &cms_content, &cms_content_len) != 1 - || asn1_length_is_zero(cms_content_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_envelop( - uint8_t *cms, size_t *cmslen, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len) -{ - int oid = OID_cms_enveloped_data; - size_t len = 0; - - if (cms_enveloped_data_encrypt_to_der( - rcpt_certs, rcpt_certs_len, - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || cms_enveloped_data_encrypt_to_der( - rcpt_certs, rcpt_certs_len, - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &cms, cmslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_deenvelop(const uint8_t *cms, size_t cmslen, - const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len) -{ - int cms_type; - const uint8_t *cms_content; - size_t cms_content_len; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - SM2_KEY public_key; - - if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 - || asn1_check(cms_type == OID_cms_enveloped_data) != 1 - || asn1_check(cms_content && cms_content_len) != 1 - || asn1_length_is_zero(cmslen) != 1) { - error_print(); - return -1; - } - - if (x509_cert_get_issuer_and_serial_number(rcpt_cert, rcpt_cert_len, - &issuer, &issuer_len, &serial, &serial_len) != 1 - || x509_cert_get_subject_public_key(rcpt_cert, rcpt_cert_len, - &public_key) != 1) { - error_print(); - return -1; - } - if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) { - error_print(); - return -1; - } - - if (cms_enveloped_data_decrypt_from_der( - rcpt_key, issuer, issuer_len, serial, serial_len, - content_type, content, content_len, - rcpt_infos, rcpt_infos_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &cms_content, &cms_content_len) != 1 - || asn1_length_is_zero(cms_content_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_sign_and_envelop(uint8_t *cms, size_t *cmslen, - const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, - const uint8_t *rcpt_certs, size_t rcpt_certs_len, - int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - int content_type, const uint8_t *content, size_t content_len, - const uint8_t *crls, size_t crls_len, - const uint8_t *shared_info1, size_t shared_info1_len, - const uint8_t *shared_info2, size_t shared_info2_len) -{ - int oid = OID_cms_signed_and_enveloped_data; - size_t len = 0; - - if (cms_signed_and_enveloped_data_encipher_to_der( - signers, signers_cnt, - rcpt_certs, rcpt_certs_len, - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - crls, crls_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - NULL, &len) != 1) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || cms_signed_and_enveloped_data_encipher_to_der( - signers, signers_cnt, - rcpt_certs, rcpt_certs_len, - enc_algor, key, keylen, iv, ivlen, - content_type, content, content_len, - crls, crls_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - &cms, cmslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen, - const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, - const uint8_t *extra_certs, size_t extra_certs_len, - const uint8_t *extra_crls, size_t extra_crls_len, - int *content_type, uint8_t *content, size_t *content_len, - const uint8_t **rcpt_infos, size_t *rcpt_infos_len, - const uint8_t **signer_infos, size_t *signer_infos_len, - const uint8_t **certs, size_t *certs_len, - const uint8_t **crls, size_t *crls_len, - const uint8_t **shared_info1, size_t *shared_info1_len, - const uint8_t **shared_info2, size_t *shared_info2_len) -{ - const uint8_t *rcpt_issuer; - size_t rcpt_issuer_len; - const uint8_t *rcpt_serial; - size_t rcpt_serial_len; - SM2_KEY public_key; - int cms_type; - const uint8_t *cms_content; - size_t cms_content_len; - int digest_algors[4]; - size_t digest_algors_cnt; - - if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 - || asn1_check(cms_type == OID_cms_signed_and_enveloped_data) != 1 - || asn1_check(cms_content && cms_content_len) != 1 - || asn1_length_is_zero(cmslen) != 1) { - error_print(); - return -1; - } - - if (x509_cert_get_issuer_and_serial_number(rcpt_cert, rcpt_cert_len, - &rcpt_issuer, &rcpt_issuer_len, - &rcpt_serial, &rcpt_serial_len) != 1 - || x509_cert_get_subject_public_key(rcpt_cert, rcpt_cert_len, - &public_key) != 1) { - error_print(); - return -1; - } - if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) { - error_print(); - return -1; - } - - if (cms_signed_and_enveloped_data_decipher_from_der( - rcpt_key, - rcpt_issuer, rcpt_issuer_len, - rcpt_serial, rcpt_serial_len, - content_type, content, content_len, - rcpt_infos, rcpt_infos_len, - shared_info1, shared_info1_len, - shared_info2, shared_info2_len, - certs, certs_len, - crls, crls_len, - signer_infos, signer_infos_len, - extra_certs, extra_certs_len, - extra_crls, extra_crls_len, - &cms_content, &cms_content_len) != 1 - || asn1_length_is_zero(cms_content_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_set_key_agreement_info( - uint8_t *cms, size_t *cmslen, - const SM2_KEY *temp_public_key_r, - const uint8_t *user_cert, size_t user_cert_len, - const uint8_t *user_id, size_t user_id_len) -{ - int oid = OID_cms_key_agreement_info; - size_t len = 0; - - if (cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r, - user_cert, user_cert_len, user_id, user_id_len, NULL, &len) != 1) { - error_print(); - return -1; - } - *cmslen = 0; - if (!cms) { - uint8_t data[1]; - if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { - error_print(); - return -1; - } - return 1; - } - if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 - || cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r, - user_cert, user_cert_len, user_id, user_id_len, &cms, cmslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp) -{ - if (pem_write(fp, PEM_CMS, cms, cms_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp) -{ - int ret; - if ((ret = pem_read(fp, PEM_CMS, cms, cms_len, maxlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - - return 1; -} - -int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - const uint8_t *d; - size_t dlen; - - - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err; - - - cms_content_info_print(fp, fmt, ind, label, d, dlen); - //if (asn1_length_is_zero(alen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - - + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static uint32_t oid_cms_data[] = { oid_sm2_cms,1 }; +static uint32_t oid_cms_signed_data[] = { oid_sm2_cms,2 }; +static uint32_t oid_cms_enveloped_data[] = { oid_sm2_cms,3 }; +static uint32_t oid_cms_signed_and_enveloped_data[] = { oid_sm2_cms,4 }; +static uint32_t oid_cms_encrypted_data[] = { oid_sm2_cms,5 }; +static uint32_t oid_cms_key_agreement_info[] = { oid_sm2_cms,6 }; +#define OID_CMS_CONUNT (sizeof(oid_cms_data)/sizeof(int)) + +static const ASN1_OID_INFO cms_content_types[] = { + { OID_cms_data, "data", oid_cms_data, OID_CMS_CONUNT }, + { OID_cms_signed_data, "signedData", oid_cms_signed_data, OID_CMS_CONUNT }, + { OID_cms_enveloped_data, "envelopedData", oid_cms_enveloped_data, OID_CMS_CONUNT }, + { OID_cms_signed_and_enveloped_data, "signedAndEnvelopedData", oid_cms_signed_and_enveloped_data, OID_CMS_CONUNT }, + { OID_cms_encrypted_data, "encryptedData", oid_cms_encrypted_data, OID_CMS_CONUNT }, + { OID_cms_key_agreement_info, "keyAgreementInfo", oid_cms_key_agreement_info, OID_CMS_CONUNT } +}; + +static const size_t cms_content_types_count = + sizeof(cms_content_types)/sizeof(cms_content_types[0]); + +const char *cms_content_type_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(cms_content_types, cms_content_types_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int cms_content_type_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(cms_content_types, cms_content_types_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + + if (oid == -1) { + return 0; + } + if (!(info = asn1_oid_info_from_oid(cms_content_types, cms_content_types_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + + if ((ret = asn1_oid_info_from_der(&info, cms_content_types, cms_content_types_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + +/* +static int cms_content_info_data_header_to_der(size_t dlen, uint8_t **out, size_t *outlen) +{ + uint8_t d[1]; + size_t len = 0; + size_t content_len = 0; + if (asn1_octet_string_to_der(p, dlen, NULL, &content_len) != 1 + || cms_content_type_to_der(OID_cms_data, out, outlen) != 1 + || asn1_explicit_header_to_der(0, content_len, out, outlen) < 0 + || asn1_octet_string_to_der(dlen, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} +*/ + +int cms_content_info_header_to_der(int content_type, size_t content_len, uint8_t **out, size_t *outlen) +{ + size_t len = content_len; // 注意:由于header_to_der没有输出数据,因此需要加上数据的长度,header length 才是正确的值 + /* + if (content_type == OID_cms_data) { + return cms_content_info_data_header_to_der(content_len, out, outlen); + } + */ + + if (cms_content_type_to_der(content_type, NULL, &len) != 1 + || asn1_explicit_header_to_der(0, content_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || cms_content_type_to_der(content_type, out, outlen) != 1 + || asn1_explicit_header_to_der(0, content_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +static int cms_content_info_data_to_der(const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + size_t content_len = 0; + if (asn1_octet_string_to_der(d, dlen, NULL, &content_len) != 1 + || cms_content_type_to_der(OID_cms_data, NULL, &len) != 1 + || asn1_explicit_to_der(0, d, content_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || cms_content_type_to_der(OID_cms_data, out, outlen) != 1 + || asn1_explicit_header_to_der(0, content_len, out, outlen) != 1 + || asn1_octet_string_to_der(d, dlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_content_info_to_der( + int content_type, const uint8_t *content, size_t content_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (content_type == OID_cms_data) { + return cms_content_info_data_to_der(content, content_len, out, outlen); + } + if (cms_content_type_to_der(content_type, NULL, &len) != 1 + || asn1_explicit_to_der(0, content, content_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || cms_content_type_to_der(content_type, out, outlen) != 1 + || asn1_explicit_to_der(0, content, content_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int cms_content_info_from_der( + int *content_type, + const uint8_t **content, size_t *content_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (cms_content_type_from_der(content_type, &d, &dlen) != 1 + || asn1_explicit_from_der(0, content, content_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + int content_type; + const uint8_t *content; + size_t content_len; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (cms_content_type_from_der(&content_type, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "contentType: %s\n", cms_content_type_name(content_type)); + + /* + if (content_type == OID_cms_data) { + if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1) goto err; + } else { + if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) goto err; + } + */ + + //format_bytes(stderr, 0, 0, "content", d, dlen); + + if ((ret = asn1_explicit_from_der(0, &content, &content_len, &d, &dlen)) < 0) { error_print(); goto err; } + if (ret == 0) { error_print(); goto err; } + + if (content_type == OID_cms_data) { + if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1 + || asn1_length_is_zero(content_len) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "content", p, len); + return 1; + } + + + if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) { error_print(); goto err; } + + switch (content_type) { + //case OID_cms_data: format_bytes(fp, fmt, ind, "content", p, len); break; + case OID_cms_signed_data: cms_signed_data_print(fp, fmt, ind, "content", p, len); break; + case OID_cms_enveloped_data: cms_enveloped_data_print(fp, fmt, ind, "content", p, len); break; + case OID_cms_signed_and_enveloped_data: cms_signed_and_enveloped_data_print(fp, fmt, ind, "content", p, len); break; + case OID_cms_encrypted_data: cms_encrypted_data_print(fp, fmt, ind, "content", p, len); break; + case OID_cms_key_agreement_info: cms_key_agreement_info_print(fp, fmt, ind, "content", p, len); break; + } + if (asn1_length_is_zero(content_len) != 1) goto err; + + + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_enced_content_info_to_der( + int content_type, + int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (cms_content_type_to_der(content_type, NULL, &len) != 1 + || x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, NULL, &len) != 1 + || asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, NULL, &len) < 0 + || asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, NULL, &len) < 0 + || asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || cms_content_type_to_der(content_type, out, outlen) != 1 + || x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, out, outlen) != 1 + || asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, out, outlen) < 0 + || asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, out, outlen) < 0 + || asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int cms_enced_content_info_from_der( + int *content_type, + int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (cms_content_type_from_der(content_type, &d, &dlen) != 1 + || x509_encryption_algor_from_der(enc_algor, enc_iv, enc_iv_len, &d, &dlen) != 1 + || asn1_implicit_octet_string_from_der(0, enced_content, enced_content_len, &d, &dlen) < 0 + || asn1_implicit_octet_string_from_der(1, shared_info1, shared_info1_len, &d, &dlen) < 0 + || asn1_implicit_octet_string_from_der(2, shared_info2, shared_info2_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_enced_content_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (cms_content_type_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "contentType: %s\n", cms_content_type_name(val)); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_encryption_algor_print(fp, fmt, ind, "contentEncryptionAlgorithm", p, len); + if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "encryptedContent", p, len); + if ((ret = asn1_implicit_octet_string_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "sharedInfo1", p, len); + if ((ret = asn1_implicit_octet_string_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "sharedInfo2", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_enced_content_info_encrypt_to_der( + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + int ret; + SM4_KEY sm4_key; + uint8_t enced_content[32 + content_len]; // FIXME: 如果content_len 过长,会直接导致segment fault + size_t enced_content_len = 100; + + if (enc_algor != OID_sm4_cbc || keylen != 16 || ivlen != 16) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + if (sm4_cbc_padding_encrypt(&sm4_key, iv, content, content_len, + enced_content, &enced_content_len) != 1) { + memset(&sm4_key, 0, sizeof(SM4_KEY)); + error_print(); + return -1; + } + memset(&sm4_key, 0, sizeof(SM4_KEY)); + + if ((ret = cms_enced_content_info_to_der(content_type, + enc_algor, iv, ivlen, enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +// 这个函数显然是有问题的,调用方根本不知道应该准备多大的buffer +// 应该为content_len 输出给一个maxlen 的最大buffer值 +int cms_enced_content_info_decrypt_from_der( + int *enc_algor, const uint8_t *key, size_t keylen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len,// 支持可选null输出 + const uint8_t **shared_info2, size_t *shared_info2_len,// 支持可选null输出 + const uint8_t **in, size_t *inlen) +{ + int ret; + SM4_KEY sm4_key; + const uint8_t *iv; + size_t ivlen; + const uint8_t *enced_content; + size_t enced_content_len; + + if (cms_enced_content_info_from_der(content_type, + enc_algor, &iv, &ivlen, &enced_content, &enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + in, inlen) != 1 + || asn1_check(*enc_algor == OID_sm4_cbc) != 1 + || asn1_check(ivlen == SM4_BLOCK_SIZE) != 1 + || asn1_check(keylen == SM4_KEY_SIZE) != 1) { + error_print(); + return -1; + } + + sm4_set_decrypt_key(&sm4_key, key); + if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_content, enced_content_len, + content, content_len) != 1) { + memset(&sm4_key, 0, sizeof(SM4_KEY)); + return -1; + } + memset(&sm4_key, 0, sizeof(SM4_KEY)); + + return 1; +} + +int cms_encrypted_data_to_der( + int version, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (version != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(version, NULL, &len) != 1 + || cms_enced_content_info_to_der( + content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || cms_enced_content_info_to_der( + content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_encrypted_data_from_der( + int *version, + int *content_type, + int *enc_algor, const uint8_t **iv, size_t *ivlen, + const uint8_t **enced_content, size_t *enced_content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || cms_enced_content_info_from_der( + content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*version != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_encrypted_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_encrypted_data_encrypt_to_der( + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_encrypted_data_decrypt_from_der( + int *enc_algor, const uint8_t *key, size_t keylen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen) +{ + int ret, version; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(&version, &d, &dlen) != 1 + || asn1_check(version == CMS_version_v1) != 1 + || cms_enced_content_info_decrypt_from_der( + enc_algor, key, keylen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_issuer_and_serial_number_to_der( + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1 + || asn1_integer_to_der(serial_number, serial_number_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1 + || asn1_integer_to_der(serial_number, serial_number_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_issuer_and_serial_number_from_der( + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_sequence_from_der(issuer, issuer_len, &d, &dlen) != 1 + || asn1_integer_from_der(serial_number, serial_number_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_issuer_and_serial_number_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_name_print(fp, fmt, ind, "issuer", p, len); + if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "serialNumber", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_signer_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int digest_algor, + const uint8_t *authed_attrs, size_t authed_attrs_len, + int signature_algor, + const uint8_t *enced_digest, size_t enced_digest_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (version != 1) { + error_print(); + return -1; + } + + if (asn1_int_to_der(version, NULL, &len) != 1 + || cms_issuer_and_serial_number_to_der( + issuer, issuer_len, + serial_number, serial_number_len, NULL, &len) != 1 + || x509_digest_algor_to_der(digest_algor, NULL, &len) != 1 + || asn1_implicit_set_to_der(0, authed_attrs, authed_attrs_len, NULL, &len) < 0 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_octet_string_to_der(enced_digest, enced_digest_len, NULL, &len) != 1 + || asn1_implicit_set_to_der(1, unauthed_attrs, unauthed_attrs_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || cms_issuer_and_serial_number_to_der( + issuer, issuer_len, + serial_number, serial_number_len, out, outlen) != 1 + || x509_digest_algor_to_der(digest_algor, out, outlen) != 1 + || asn1_implicit_set_to_der(0, authed_attrs, authed_attrs_len, out, outlen) < 0 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || asn1_octet_string_to_der(enced_digest, enced_digest_len, out, outlen) != 1 + || asn1_implicit_set_to_der(1, unauthed_attrs, unauthed_attrs_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int cms_signer_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *digest_algor, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + int *signature_algor, + const uint8_t **enced_digest, size_t *enced_digest_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || cms_issuer_and_serial_number_from_der(issuer, issuer_len, + serial_number, serial_number_len, &d, &dlen) != 1 + || x509_digest_algor_from_der(digest_algor, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, authed_attrs, authed_attrs_len, &d, &dlen) < 0 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || asn1_octet_string_from_der(enced_digest, enced_digest_len, &d, &dlen) != 1 + || asn1_implicit_set_from_der(1, unauthed_attrs, unauthed_attrs_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_issuer_and_serial_number_print(fp, fmt, ind, "issuerAndSerialNumber", p, len); + if (x509_digest_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "digestAlgorithm: %s\n", x509_digest_algor_name(val)); + if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_attributes_print(fp, fmt, ind, "authenticatedAttributes", p, len); + if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "digestEncryptionAlgorithm: %s\n", x509_signature_algor_name(val)); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "encryptedDigest", p, len); + if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_attributes_print(fp, fmt, ind, "unauthenticatedAttributes", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_signer_info_sign_to_der( + const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len, + uint8_t **out, size_t *outlen) +{ + SM3_CTX ctx = *sm3_ctx; + int fixed_outlen = 1; + uint8_t dgst[SM3_DIGEST_SIZE]; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + sm3_update(&ctx, authed_attrs, authed_attrs_len); + sm3_finish(&ctx, dgst); + + + + if (sm2_sign_ex(sign_key, fixed_outlen, dgst, sig, &siglen) != 1) { + error_print(); + return -1; + } + if (cms_signer_info_to_der(CMS_version_v1, + issuer, issuer_len, serial_number, serial_number_len, + OID_sm3, authed_attrs, authed_attrs_len, + OID_sm2sign_with_sm3, sig, siglen, + unauthed_attrs, unauthed_attrs_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signer_info_verify_from_der( + const SM3_CTX *ctx, const uint8_t *certs, size_t certslen, + const uint8_t **cert, size_t *certlen, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial, size_t *serial_len, + const uint8_t **authed_attrs, size_t *authed_attrs_len, + const uint8_t **unauthed_attrs, size_t *unauthed_attrs_len, + const uint8_t **in, size_t *inlen) +{ + int version; + int digest_algor; + int signature_algor; + const uint8_t *sig; + size_t siglen; + SM2_KEY public_key; + SM3_CTX sm3_ctx = *ctx; + uint8_t dgst[32]; + + if (cms_signer_info_from_der(&version, + issuer, issuer_len, + serial, serial_len, + &digest_algor, authed_attrs, authed_attrs_len, + &signature_algor, &sig, &siglen, + unauthed_attrs, unauthed_attrs_len, + in, inlen) != 1 + || asn1_check(version == CMS_version_v1) != 1 + || asn1_check(digest_algor == OID_sm3) != 1 + || asn1_check(signature_algor == OID_sm2sign_with_sm3) != 1) { + error_print(); + return -1; + } + if (x509_certs_get_cert_by_issuer_and_serial_number(certs, certslen, + *issuer, *issuer_len, *serial, *serial_len, cert, certlen) != 1 + || x509_cert_get_subject_public_key(*cert, *certlen, &public_key) != 1) { + error_print(); + return -1; + } + + sm3_update(&sm3_ctx, *authed_attrs, *authed_attrs_len); + sm3_finish(&sm3_ctx, dgst); + + if (sm2_verify(&public_key, dgst, sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signer_infos_add_signer_info( + uint8_t *d, size_t *dlen, size_t maxlen, + const SM3_CTX *sm3_ctx, const SM2_KEY *sign_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *authed_attrs, size_t authed_attrs_len, + const uint8_t *unauthed_attrs, size_t unauthed_attrs_len) +{ + size_t len = *dlen; + d += *dlen; + if (cms_signer_info_sign_to_der(sm3_ctx, sign_key, + issuer, issuer_len, serial_number, serial_number_len, + authed_attrs, authed_attrs_len, + unauthed_attrs, unauthed_attrs_len, + NULL, &len) != 1 + || asn1_length_le(len, maxlen) != 1 + || cms_signer_info_sign_to_der(sm3_ctx, sign_key, + issuer, issuer_len, serial_number, serial_number_len, + authed_attrs, authed_attrs_len, + unauthed_attrs, unauthed_attrs_len, + &d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + cms_signer_info_print(fp, fmt, ind, "SignerInfo", p, len); + } + return 1; +} + +int cms_digest_algors_to_der(const int *digest_algors, size_t digest_algors_cnt, + uint8_t **out, size_t *outlen) +{ + size_t len = 0, i; + for (i = 0; i < digest_algors_cnt; i++) { + if (x509_digest_algor_to_der(digest_algors[i], NULL, &len) != 1) { + error_print(); + return -1; + } + } + if (asn1_set_header_to_der(len, out, outlen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < digest_algors_cnt; i++) { + if (x509_digest_algor_to_der(digest_algors[i], out, outlen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int cms_digest_algors_from_der(int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_set_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + + *digest_algors_cnt = 0; + while (dlen) { + if (*digest_algors_cnt > max_digest_algors) { + error_print(); + return -1; + } + if (x509_digest_algor_from_der(digest_algors, &d, &dlen) != 1) { + error_print(); + return -1; + } + digest_algors++; + (*digest_algors_cnt)++; + } + return 1; +} + +int cms_digest_algors_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int oid; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (x509_digest_algor_from_der(&oid, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s\n", x509_digest_algor_name(oid)); + } + return 1; +} + +int cms_signed_data_to_der( + int version, + const int *digest_algors, size_t digest_algors_cnt, + const int content_type, const uint8_t *content, const size_t content_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, const size_t crls_len, + const uint8_t *signer_infos, size_t signer_infos_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(version, NULL, &len) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 + || cms_content_info_to_der(content_type, content, content_len, NULL, &len) != 1 + || asn1_implicit_set_to_der(0, certs, certs_len, NULL, &len) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 + || cms_signer_infos_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 + || cms_content_info_to_der(content_type, content, content_len, out, outlen) != 1 + || asn1_implicit_set_to_der(0, certs, certs_len, out, outlen) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 + || cms_signer_infos_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_data_from_der( + int *version, + int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || cms_digest_algors_from_der(digest_algors, digest_algors_cnt, max_digest_algors, &d, &dlen) != 1 + || cms_content_info_from_der(content_type, content, content_len, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, certs, certs_len, &d, &dlen) < 0 + || asn1_implicit_set_from_der(1, crls, crls_len, &d, &dlen) < 0 + || asn1_set_from_der(signer_infos, signer_infos_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*version != CMS_version_v1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_digest_algors_print(fp, fmt, ind, "digestAlgorithms", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_content_info_print(fp, fmt, ind, "contentInfo", p, len); + if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_certs_print(fp, fmt, ind, "certificates", p, len); + if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_signer_infos_print(fp, fmt, ind, "signerInfos", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +static int cms_implicit_signers_certs_to_der(int index, + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + uint8_t **out, size_t *outlen) +{ + size_t i; + size_t len = 0; + for (i = 0; i < signers_cnt; i++) { + if (asn1_data_to_der(signers[i].certs, signers[i].certs_len, NULL, &len) != 1) { + error_print(); + return -1; + } + } + if (asn1_implicit_header_to_der(index, len, out, outlen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < signers_cnt; i++) { + if (asn1_data_to_der(signers[i].certs, signers[i].certs_len, out, outlen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int cms_signed_data_sign_to_der( + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + int content_type, const uint8_t *data, size_t datalen, + const uint8_t *crls, size_t crls_len, + uint8_t **out, size_t *outlen) +{ + int digest_algors[] = { OID_sm3 }; + size_t digest_algors_cnt = sizeof(digest_algors)/sizeof(int); + uint8_t content_header[256]; + size_t content_header_len; + const uint8_t *certs; + size_t certs_len = 0; + uint8_t signer_infos[512]; + size_t signer_infos_len = 0; + SM3_CTX sm3_ctx; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + uint8_t *p; + size_t len = 0; + size_t i; + + + // 当content_type == OID_cms_data 时,data是raw data,被封装为OCTET STRING编码输出 + // 而content_type为其他类型时,data均为TLV的DER数据 + // 在to_der/from_der 中已经处理,但是计算哈希值时也需要做处理 + p = content_header; + content_header_len = 0; + if (content_type == OID_cms_data) { + size_t content_len = 0; + if (asn1_octet_string_to_der(data, datalen, NULL, &content_len) != 1 + || cms_content_info_header_to_der(content_type, content_len, &p, &content_header_len) != 1 + || asn1_octet_string_header_to_der(datalen, &p, &content_header_len) != 1) { + error_print(); + return -1; + } + } else { + if (cms_content_info_header_to_der(content_type, datalen, &p, &content_header_len) != 1) { + error_print(); + return -1; + } + } + + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, content_header, content_header_len); + sm3_update(&sm3_ctx, data, datalen); + + for (i = 0; i < signers_cnt; i++) { + if (x509_cert_get_issuer_and_serial_number( + signers[i].certs, signers[i].certs_len, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || cms_signer_infos_add_signer_info( + signer_infos, &signer_infos_len, sizeof(signer_infos), + &sm3_ctx, signers->sign_key, + issuer, issuer_len, serial, serial_len, + NULL, 0, NULL, 0) != 1) { + error_print(); + return -1; + } + } + + if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 + || cms_content_info_to_der(content_type, data, datalen, NULL, &len) != 1 + || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 + || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 + || cms_content_info_to_der(content_type, data, datalen, out, outlen) != 1 + || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 + || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_data_verify_from_der( + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **psigner_infos, size_t *psigner_infos_len, + const uint8_t **in, size_t *inlen) +{ + int version; + int digest_algors[4]; + size_t digest_algors_cnt; + SM3_CTX sm3_ctx; + uint8_t content_info_header[128]; + size_t content_info_header_len; + uint8_t *p = content_info_header; + const uint8_t *signer_infos; + size_t signer_infos_len; + + if (cms_signed_data_from_der( + &version, + digest_algors, &digest_algors_cnt, sizeof(digest_algors)/sizeof(int), + content_type, content, content_len, + certs, certs_len, + crls, crls_len, + &signer_infos, &signer_infos_len, + in, inlen) != 1 + || asn1_check(version == CMS_version_v1) != 1 + || asn1_check(digest_algors[0] == OID_sm3) != 1 + || asn1_check(digest_algors_cnt == 1) != 1) { + error_print(); + return -1; + } + *psigner_infos = signer_infos; + *psigner_infos_len = signer_infos_len; + + content_info_header_len = 0; + if (cms_content_info_header_to_der(*content_type, *content_len, + &p, &content_info_header_len) != 1) { + error_print(); + return -1; + } + sm3_init(&sm3_ctx); + + sm3_update(&sm3_ctx, content_info_header, content_info_header_len); + sm3_update(&sm3_ctx, *content, *content_len); + + while (signer_infos_len) { + const uint8_t *cert; + size_t certlen; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + const uint8_t *authed_attrs; + size_t authed_attrs_len; + const uint8_t *unauthed_attrs; + size_t unauthed_attrs_len; + + if (cms_signer_info_verify_from_der( + &sm3_ctx, *certs, *certs_len, + &cert, &certlen, + &issuer, &issuer_len, + &serial, &serial_len, + &authed_attrs, &authed_attrs_len, + &unauthed_attrs, &unauthed_attrs_len, + &signer_infos, &signer_infos_len) != 1) { + + error_print(); + return -1; + } + } + return 1; +} + +int cms_recipient_info_to_der( + int version, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + int public_key_enc_algor, + const uint8_t *enced_key, size_t enced_key_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (version != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(version, NULL, &len) != 1 + || cms_issuer_and_serial_number_to_der(issuer, issuer_len, + serial_number, serial_number_len, NULL, &len) != 1 + || x509_public_key_encryption_algor_to_der(public_key_enc_algor, NULL, &len) != 1 + || asn1_octet_string_to_der(enced_key, enced_key_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || cms_issuer_and_serial_number_to_der(issuer, issuer_len, + serial_number, serial_number_len, out, outlen) != 1 + || x509_public_key_encryption_algor_to_der(public_key_enc_algor, out, outlen) != 1 + || asn1_octet_string_to_der(enced_key, enced_key_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_recipient_info_from_der( + int *version, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len, + int *pke_algor, const uint8_t **params, size_t *params_len,// SM2加密只使用SM3,没有默认参数,但是ECIES可能有 + const uint8_t **enced_key, size_t *enced_key_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || cms_issuer_and_serial_number_from_der(issuer, issuer_len, + serial_number, serial_number_len, &d, &dlen) != 1 + || x509_public_key_encryption_algor_from_der(pke_algor, params, params_len, &d, &dlen) != 1 + || asn1_octet_string_from_der(enced_key, enced_key_len, &d, &dlen) != 1 + // || asn1_length_is_zero(dlen) != 1 + ) { + error_print(); + return -1; + } + if (*version != 1) { + error_print(); + return -1; + } + if (*pke_algor != OID_sm2encrypt) { + error_print(); + return -1; + } + if (*params || *params_len) { + error_print(); + return -1; + } + return 1; +} + +int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_issuer_and_serial_number_print(fp, fmt, ind, "issuerAndSerialNumber", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_public_key_encryption_algor_print(fp, fmt, ind, "keyEncryptionAlgorithm", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "encryptedKey", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_recipient_info_encrypt_to_der( + const SM2_KEY *public_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial_number, size_t serial_number_len, + const uint8_t *in, size_t inlen, + uint8_t **out, size_t *outlen) +{ + int pke_algor = OID_sm2encrypt; + uint8_t enced_key[SM2_MAX_CIPHERTEXT_SIZE]; + size_t enced_key_len; + int fixed_outlen = 1; + + if (pke_algor != OID_sm2encrypt) { + error_print(); + return -1; + } + + if (sm2_encrypt_ex(public_key, fixed_outlen, in, inlen, enced_key, &enced_key_len) != 1) { + error_print(); + return -1; + } + if (cms_recipient_info_to_der(CMS_version_v1, + issuer, issuer_len, serial_number, serial_number_len, + pke_algor, enced_key, enced_key_len, + out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_recipient_info_decrypt_from_der( + const SM2_KEY *sm2_key, + const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, + const uint8_t *rcpt_serial, size_t rcpt_serial_len, + uint8_t *out, size_t *outlen, size_t maxlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + int version; + int pke_algor; + const uint8_t *params; + size_t params_len; + const uint8_t *enced_key; + size_t enced_key_len; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + uint8_t outbuf[SM2_MAX_PLAINTEXT_SIZE]; + + if (cms_recipient_info_from_der(&version, + &issuer, &issuer_len, &serial, &serial_len, + &pke_algor, ¶ms, ¶ms_len, + &enced_key, &enced_key_len, + in, inlen) != 1) { + error_print(); + return -1; + } + if (issuer_len != rcpt_issuer_len + || memcmp(issuer, rcpt_issuer, rcpt_issuer_len) != 0 + || serial_len != rcpt_serial_len + || memcmp(serial, rcpt_serial, serial_len) != 0) { + error_print(); + return 0; + } + if (pke_algor != OID_sm2encrypt || params || params_len) { + error_print(); + return -1; + } + if (sm2_decrypt(sm2_key, enced_key, enced_key_len, outbuf, outlen) != 1) { + error_print(); + return -1; + } + if (maxlen < *outlen) { + error_print(); + return -1; + } + memcpy(out, outbuf, *outlen); + return 1; +} + +int cms_recipient_infos_add_recipient_info( + uint8_t *d, size_t *dlen, size_t maxlen, + const SM2_KEY *public_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + const uint8_t *in, size_t inlen) +{ + size_t len = *dlen; + d += *dlen; + + if (cms_recipient_info_encrypt_to_der( + public_key, + issuer, issuer_len, + serial, serial_len, + in, inlen, + NULL, &len) != 1 + || asn1_length_le(len, maxlen) != 1 + || cms_recipient_info_encrypt_to_der( + public_key, + issuer, issuer_len, + serial, serial_len, + in, inlen, + &d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + cms_recipient_info_print(fp, fmt, ind, "RecipientInfo", p, len); + } + return 1; +} + +int cms_enveloped_data_to_der( + int version, + const uint8_t *rcpt_infos, size_t rcpt_infos_len, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(version, NULL, &len) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 + || cms_enced_content_info_to_der(content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 + || cms_enced_content_info_to_der(content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_enveloped_data_from_der( + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **enced_content_info, size_t *enced_content_info_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || asn1_set_from_der(rcpt_infos, rcpt_infos_len, &d, &dlen) != 1 + || asn1_any_from_der(enced_content_info, enced_content_info_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_recipient_infos_print(fp, fmt, ind, "recipientInfos", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_enveloped_data_encrypt_to_der( + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + uint8_t rcpt_infos[1024]; // 到底需要多大? + size_t rcpt_infos_len = 0; + uint8_t *p = rcpt_infos; + size_t len = 0; + + while (rcpt_certs_len) { + const uint8_t *cert; + size_t certlen; + SM2_KEY public_key; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + + if (asn1_any_from_der(&cert, &certlen, &rcpt_certs, &rcpt_certs_len) != 1 + || x509_cert_get_issuer_and_serial_number(cert, certlen, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + return -1; + } + if (cms_recipient_info_encrypt_to_der(&public_key, + issuer, issuer_len, serial, serial_len, + key, keylen, NULL, &len) != 1 + || asn1_length_le(len, sizeof(rcpt_infos)) != 1 + || cms_recipient_info_encrypt_to_der(&public_key, + issuer, issuer_len, serial, serial_len, + key, keylen, &p, &rcpt_infos_len) != 1) { + error_print(); + return -1; + } + } + len = 0; + if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_enveloped_data_decrypt_from_der( + const SM2_KEY *sm2_key, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **recipient_infos, size_t *recipient_infos_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + int version; + const uint8_t *rcpt_infos; + size_t rcpt_infos_len; + const uint8_t *enced_content_info; + size_t enced_content_info_len; + int enc_algor; + uint8_t key[32]; + size_t keylen; + + if (cms_enveloped_data_from_der( + &version, &rcpt_infos, &rcpt_infos_len, + &enced_content_info, &enced_content_info_len, + in, inlen) != 1 + || asn1_check(version == CMS_version_v1) != 1) { + return ret; + } + *recipient_infos = rcpt_infos; + *recipient_infos_len = rcpt_infos_len; + + while (rcpt_infos_len) { + if ((ret = cms_recipient_info_decrypt_from_der( + sm2_key, + issuer, issuer_len, + serial, serial_len, + key, &keylen, sizeof(key), + &rcpt_infos, &rcpt_infos_len)) < 0) { + error_print(); + return -1; + } else if (ret) { + break; + } + } + if (!ret) { + error_print(); + return -1; + } + + if (cms_enced_content_info_decrypt_from_der( + &enc_algor, key, keylen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &enced_content_info, &enced_content_info_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_and_enveloped_data_to_der( + int version, + const uint8_t *rcpt_infos, size_t rcpt_infos_len, + const int *digest_algors, size_t digest_algors_cnt, + int content_type, + int enc_algor, const uint8_t *iv, size_t ivlen, + const uint8_t *enced_content, size_t enced_content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + const uint8_t *certs, size_t certs_len, + const uint8_t *crls, size_t crls_len, + const uint8_t *signer_infos, size_t signer_infos_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(version, NULL, &len) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 + || cms_enced_content_info_to_der(content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || asn1_implicit_set_to_der(0, certs, certs_len, NULL, &len) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0 + || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 + || cms_enced_content_info_to_der(content_type, + enc_algor, iv, ivlen, + enced_content, enced_content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen) != 1 + || asn1_implicit_set_to_der(0, certs, certs_len, out, outlen) < 0 + || asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0 + || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_and_enveloped_data_from_der( + int *version, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + int *digest_algors, size_t *digest_algors_cnt, size_t max_digest_algors, + const uint8_t **enced_content_info, size_t *enced_content_info_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || asn1_set_from_der(rcpt_infos, rcpt_infos_len, &d, &dlen) != 1 + || cms_digest_algors_from_der(digest_algors, digest_algors_cnt, max_digest_algors, &d, &dlen) != 1 + || asn1_any_from_der(enced_content_info, enced_content_info_len, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, certs, certs_len, &d, &dlen) < 0 + || asn1_implicit_set_from_der(1, crls, crls_len, &d, &dlen) < 0 + || asn1_set_from_der(signer_infos, signer_infos_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_and_enveloped_data_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_recipient_infos_print(fp, fmt, ind, "recipientInfos", p, len); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_digest_algors_print(fp, fmt, ind, "digestAlgorithms", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_enced_content_info_print(fp, fmt, ind, "encryptedContentInfo", p, len); + if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_certs_print(fp, fmt, ind, "certificates", p, len); + if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_crls_print(fp, fmt, ind, "crls", p, len); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + cms_signer_infos_print(fp, fmt, ind, "signerInfos", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_signed_and_enveloped_data_encipher_to_der( + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *signers_crls, size_t signers_crls_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len, + uint8_t **out, size_t *outlen) +{ + uint8_t rcpt_infos[512]; + size_t rcpt_infos_len = 0; + int digest_algors[] = { OID_sm3 }; + size_t digest_algors_cnt = sizeof(digest_algors)/sizeof(int); + uint8_t content_info_header[256]; + size_t content_info_header_len = 0; + uint8_t signer_infos[512]; + size_t signer_infos_len = 0; + SM3_CTX sm3_ctx; + const uint8_t *issuer; + const uint8_t *serial; + size_t issuer_len; + size_t serial_len; + uint8_t *p; + size_t len = 0; + size_t i; + + p = rcpt_infos; + while (rcpt_certs_len) { + const uint8_t *cert; + size_t certlen; + SM2_KEY public_key; + + if (asn1_any_from_der(&cert, &certlen, &rcpt_certs, &rcpt_certs_len) != 1 + || x509_cert_get_issuer_and_serial_number(cert, certlen, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 + || cms_recipient_info_encrypt_to_der(&public_key, + issuer, issuer_len, serial, serial_len, + key, keylen, NULL, &len) != 1 + || asn1_length_le(len, sizeof(rcpt_infos)) != 1 + || cms_recipient_info_encrypt_to_der(&public_key, + issuer, issuer_len, serial, serial_len, + key, keylen, &p, &rcpt_infos_len) != 1) { + error_print(); + return -1; + } + } + + p = content_info_header; + if (cms_content_info_header_to_der(content_type, content_len, + &p, &content_info_header_len) != 1) { + error_print(); + return -1; + } + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, content_info_header, content_info_header_len); + sm3_update(&sm3_ctx, content, content_len); + + for (i = 0; i < signers_cnt; i++) { + if (x509_cert_get_issuer_and_serial_number( + signers[i].certs, signers[i].certs_len, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || cms_signer_infos_add_signer_info( + signer_infos, &signer_infos_len, sizeof(signer_infos), + &sm3_ctx, signers->sign_key, + issuer, issuer_len, serial, serial_len, + NULL, 0, NULL, 0) != 1) { + error_print(); + return -1; + } + } + + len = 0; + if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1 + || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) != 1 + || asn1_implicit_set_to_der(1, signers_crls, signers_crls_len, NULL, &len) < 0 + || asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(CMS_version_v1, out, outlen) != 1 + || asn1_set_to_der(rcpt_infos, rcpt_infos_len, out, outlen) != 1 + || cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1 + || cms_enced_content_info_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + out, outlen) != 1 + || cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) != 1 + || asn1_implicit_set_to_der(1, signers_crls, signers_crls_len, out, outlen) != 1 + || asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_signed_and_enveloped_data_decipher_from_der( + const SM2_KEY *rcpt_key, + const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, + const uint8_t *rcpt_serial, size_t rcpt_serial_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **prcpt_infos, size_t *prcpt_infos_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **psigner_infos, size_t *psigner_infos_len, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + int version; + const uint8_t *rcpt_infos; + size_t rcpt_infos_len; + int digest_algors[4]; + size_t digest_algors_cnt; + const uint8_t *enced_content_info; + size_t enced_content_info_len; + const uint8_t *signer_infos; + size_t signer_infos_len; + int enc_algor; + uint8_t key[32]; + size_t keylen; + SM3_CTX sm3_ctx; + uint8_t content_info_header[128]; + size_t content_info_header_len = 0; + uint8_t *p = content_info_header; + + if (cms_signed_and_enveloped_data_from_der( + &version, + &rcpt_infos, &rcpt_infos_len, + digest_algors, &digest_algors_cnt, sizeof(digest_algors)/sizeof(int), + &enced_content_info, &enced_content_info_len, + certs, certs_len, + crls, crls_len, + &signer_infos, &signer_infos_len, + in, inlen) != 1 + || asn1_check(version == CMS_version_v1) != 1 + || asn1_check(digest_algors[0] == OID_sm3) != 1) { + error_print(); + return -1; + } + *prcpt_infos = rcpt_infos; + *prcpt_infos_len = rcpt_infos_len; + *psigner_infos = signer_infos; + *psigner_infos_len = signer_infos_len; + + while (rcpt_infos_len) { + if ((ret = cms_recipient_info_decrypt_from_der( + rcpt_key, + rcpt_issuer, rcpt_issuer_len, + rcpt_serial, rcpt_serial_len, + key, &keylen, sizeof(key), + &rcpt_infos, &rcpt_infos_len)) < 0) { + error_print(); + return -1; + } else if (ret) { + break; + } + } + if (!ret) { + error_print(); + return -1; + } + + if (cms_enced_content_info_decrypt_from_der( + &enc_algor, key, keylen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &enced_content_info, &enced_content_info_len) != 1) { + error_print(); + return -1; + } + + if (cms_content_info_header_to_der(*content_type, *content_len, + &p, &content_info_header_len) != 1) { + error_print(); + return -1; + } + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, content_info_header, content_info_header_len); + sm3_update(&sm3_ctx, content, *content_len); + + while (signer_infos_len) { + const uint8_t *cert; + size_t certlen; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + const uint8_t *authed_attrs; + size_t authed_attrs_len; + const uint8_t *unauthed_attrs; + size_t unauthed_attrs_len; + + if (cms_signer_info_verify_from_der( + &sm3_ctx, *certs, *certs_len, + &cert, &certlen, + &issuer, &issuer_len, + &serial, &serial_len, + &authed_attrs, &authed_attrs_len, + &unauthed_attrs, &unauthed_attrs_len, + &signer_infos, &signer_infos_len) != 1) { + error_print(); + return -1; + } + } + + return 1; +} + +int cms_key_agreement_info_to_der( + int version, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(version, NULL, &len) != 1 + || sm2_public_key_info_to_der(temp_public_key_r, NULL, &len) != 1 + || x509_cert_to_der(user_cert, user_cert_len, NULL, &len) != 1 + || asn1_octet_string_to_der(user_id, user_id_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || sm2_public_key_info_to_der(temp_public_key_r, out, outlen) != 1 + || x509_cert_to_der(user_cert, user_cert_len, out, outlen) != 1 + || asn1_octet_string_to_der(user_id, user_id_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_key_agreement_info_from_der( + int *version, + SM2_KEY *temp_public_key_r, + const uint8_t **user_cert, size_t *user_cert_len, + const uint8_t **user_id, size_t *user_id_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || sm2_public_key_info_from_der(temp_public_key_r, &d, &dlen) != 1 + || x509_cert_from_der(user_cert, user_cert_len, &d, &dlen) != 1 + || asn1_octet_string_from_der(user_id, user_id_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int val; + SM2_KEY pub_key; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (sm2_public_key_info_from_der(&pub_key, &d, &dlen) != 1) goto err; + sm2_public_key_print(fp, fmt, ind, "tempPublicKeyR", &pub_key); + if (x509_cert_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_cert_print(fp, fmt, ind, "certificate", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_string(fp, fmt, ind, "userID", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int cms_set_data(uint8_t *cms, size_t *cmslen, const uint8_t *d, size_t dlen) +{ + int oid = OID_cms_data; + size_t len = 0; + + if (asn1_octet_string_to_der(d, dlen, NULL, &len) < 0) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || asn1_octet_string_to_der(d, dlen, &cms, cmslen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int cms_encrypt(uint8_t *cms, size_t *cmslen, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len) +{ + int oid = OID_cms_encrypted_data; + size_t len = 0; + + if (cms_encrypted_data_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || cms_encrypted_data_encrypt_to_der( + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &cms, cmslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_decrypt(const uint8_t *cms, size_t cmslen, + int *enc_algor, const uint8_t *key, size_t keylen, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len) +{ + int cms_type; + const uint8_t *cms_content; + size_t cms_content_len; + + if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 + || asn1_check(cms_type == OID_cms_encrypted_data) != 1 + || asn1_check(cms_content && cms_content_len) != 1 + || asn1_length_is_zero(cmslen) != 1) { + error_print(); + return -1; + } + if (cms_encrypted_data_decrypt_from_der( + enc_algor, key, keylen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &cms_content, &cms_content_len) != 1 + || asn1_length_is_zero(cms_content_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_sign(uint8_t *cms, size_t *cmslen, + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *crls, size_t crls_len) +{ + int oid = OID_cms_signed_data; + size_t len = 0; + + if (cms_signed_data_sign_to_der( + signers, signers_cnt, + content_type, content, content_len, + crls, crls_len, + NULL, &len) != 1) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || cms_signed_data_sign_to_der( + signers, signers_cnt, + content_type, content, content_len, + crls, crls_len, + &cms, cmslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_verify(const uint8_t *cms, size_t cmslen, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + int *content_type, const uint8_t **content, size_t *content_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **signer_infos, size_t *signer_infos_len) +{ + int cms_type; + const uint8_t *cms_content; + size_t cms_content_len; + + if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 + || asn1_length_is_zero(cmslen) != 1) { + error_print(); + return -1; + } + if (cms_type != OID_cms_signed_data) { + error_print(); + return -1; + } + if (cms_content_len <= 0) { + error_print(); + return -1; + } + + if (cms_signed_data_verify_from_der( + extra_certs, extra_certs_len, + extra_crls, extra_crls_len, + content_type, content, content_len, + certs, certs_len, + crls, crls_len, + signer_infos, signer_infos_len, + &cms_content, &cms_content_len) != 1 + || asn1_length_is_zero(cms_content_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_envelop( + uint8_t *cms, size_t *cmslen, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len) +{ + int oid = OID_cms_enveloped_data; + size_t len = 0; + + if (cms_enveloped_data_encrypt_to_der( + rcpt_certs, rcpt_certs_len, + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || cms_enveloped_data_encrypt_to_der( + rcpt_certs, rcpt_certs_len, + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &cms, cmslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_deenvelop(const uint8_t *cms, size_t cmslen, + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len) +{ + int cms_type; + const uint8_t *cms_content; + size_t cms_content_len; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + SM2_KEY public_key; + + if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 + || asn1_check(cms_type == OID_cms_enveloped_data) != 1 + || asn1_check(cms_content && cms_content_len) != 1 + || asn1_length_is_zero(cmslen) != 1) { + error_print(); + return -1; + } + + if (x509_cert_get_issuer_and_serial_number(rcpt_cert, rcpt_cert_len, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_cert_get_subject_public_key(rcpt_cert, rcpt_cert_len, + &public_key) != 1) { + error_print(); + return -1; + } + if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) { + error_print(); + return -1; + } + + if (cms_enveloped_data_decrypt_from_der( + rcpt_key, issuer, issuer_len, serial, serial_len, + content_type, content, content_len, + rcpt_infos, rcpt_infos_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &cms_content, &cms_content_len) != 1 + || asn1_length_is_zero(cms_content_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_sign_and_envelop(uint8_t *cms, size_t *cmslen, + const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, + const uint8_t *rcpt_certs, size_t rcpt_certs_len, + int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + int content_type, const uint8_t *content, size_t content_len, + const uint8_t *crls, size_t crls_len, + const uint8_t *shared_info1, size_t shared_info1_len, + const uint8_t *shared_info2, size_t shared_info2_len) +{ + int oid = OID_cms_signed_and_enveloped_data; + size_t len = 0; + + if (cms_signed_and_enveloped_data_encipher_to_der( + signers, signers_cnt, + rcpt_certs, rcpt_certs_len, + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + crls, crls_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + NULL, &len) != 1) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || cms_signed_and_enveloped_data_encipher_to_der( + signers, signers_cnt, + rcpt_certs, rcpt_certs_len, + enc_algor, key, keylen, iv, ivlen, + content_type, content, content_len, + crls, crls_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + &cms, cmslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_deenvelop_and_verify(const uint8_t *cms, size_t cmslen, + const SM2_KEY *rcpt_key, const uint8_t *rcpt_cert, size_t rcpt_cert_len, + const uint8_t *extra_certs, size_t extra_certs_len, + const uint8_t *extra_crls, size_t extra_crls_len, + int *content_type, uint8_t *content, size_t *content_len, + const uint8_t **rcpt_infos, size_t *rcpt_infos_len, + const uint8_t **signer_infos, size_t *signer_infos_len, + const uint8_t **certs, size_t *certs_len, + const uint8_t **crls, size_t *crls_len, + const uint8_t **shared_info1, size_t *shared_info1_len, + const uint8_t **shared_info2, size_t *shared_info2_len) +{ + const uint8_t *rcpt_issuer; + size_t rcpt_issuer_len; + const uint8_t *rcpt_serial; + size_t rcpt_serial_len; + SM2_KEY public_key; + int cms_type; + const uint8_t *cms_content; + size_t cms_content_len; + int digest_algors[4]; + size_t digest_algors_cnt; + + if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1 + || asn1_check(cms_type == OID_cms_signed_and_enveloped_data) != 1 + || asn1_check(cms_content && cms_content_len) != 1 + || asn1_length_is_zero(cmslen) != 1) { + error_print(); + return -1; + } + + if (x509_cert_get_issuer_and_serial_number(rcpt_cert, rcpt_cert_len, + &rcpt_issuer, &rcpt_issuer_len, + &rcpt_serial, &rcpt_serial_len) != 1 + || x509_cert_get_subject_public_key(rcpt_cert, rcpt_cert_len, + &public_key) != 1) { + error_print(); + return -1; + } + if (memcmp(&public_key, rcpt_key, sizeof(SM2_POINT)) != 0) { + error_print(); + return -1; + } + + if (cms_signed_and_enveloped_data_decipher_from_der( + rcpt_key, + rcpt_issuer, rcpt_issuer_len, + rcpt_serial, rcpt_serial_len, + content_type, content, content_len, + rcpt_infos, rcpt_infos_len, + shared_info1, shared_info1_len, + shared_info2, shared_info2_len, + certs, certs_len, + crls, crls_len, + signer_infos, signer_infos_len, + extra_certs, extra_certs_len, + extra_crls, extra_crls_len, + &cms_content, &cms_content_len) != 1 + || asn1_length_is_zero(cms_content_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_set_key_agreement_info( + uint8_t *cms, size_t *cmslen, + const SM2_KEY *temp_public_key_r, + const uint8_t *user_cert, size_t user_cert_len, + const uint8_t *user_id, size_t user_id_len) +{ + int oid = OID_cms_key_agreement_info; + size_t len = 0; + + if (cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r, + user_cert, user_cert_len, user_id, user_id_len, NULL, &len) != 1) { + error_print(); + return -1; + } + *cmslen = 0; + if (!cms) { + uint8_t data[1]; + if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) { + error_print(); + return -1; + } + return 1; + } + if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1 + || cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r, + user_cert, user_cert_len, user_id, user_id_len, &cms, cmslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp) +{ + if (pem_write(fp, PEM_CMS, cms, cms_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp) +{ + int ret; + if ((ret = pem_read(fp, PEM_CMS, cms, cms_len, maxlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + + return 1; +} + +int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + const uint8_t *d; + size_t dlen; + + + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err; + + + cms_content_info_print(fp, fmt, ind, label, d, dlen); + //if (asn1_length_is_zero(alen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + diff --git a/src/debug.c b/src/debug.c index 07a2589c..be642739 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,106 +7,107 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - -void print_der(const uint8_t *in, size_t inlen) -{ - size_t i; - for (i = 0; i < inlen; i++) { - printf("%02x ", in[i]); - } -} - -void print_bytes(const uint8_t *data, size_t datalen) -{ - size_t i; - for (i = 0; i < datalen; i++) { - printf("%02X ", data[i]); - if ((i + 1) % 32 == 0) - printf("\n"); - } - printf("\n"); -} - -void print_nodes(const uint32_t *in, size_t inlen) -{ - size_t i; - printf("%u", in[0]); - for (i = 1; i < inlen; i++) { - printf(".%u", in[i]); - } -} - - - -int format_print(FILE *fp, int format, int indent, const char *str, ...) -{ - va_list args; - int i; - for (i = 0; i < indent; i++) { - fprintf(fp, " "); - } - va_start(args, str); - vfprintf(fp, str, args); - va_end(args); - return 1; -} - -int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen) -{ - int i; - - if (datalen > 4096) { - error_print(); - return -1; - } - - for (i = 0; i < indent; i++) { - fprintf(fp, " "); - } - fprintf(fp, "%s: ", str); - if (!datalen) { - fprintf(fp, "(null)\n"); - return 1; - } - for (i = 0; i < datalen; i++) { - fprintf(fp, "%02X", data[i]); - } - fprintf(fp, "\n"); - return 1; -} - - -int format_string(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - while (ind--) { - fprintf(fp, " "); - } - fprintf(fp, "%s: ", label); - while (dlen--) { - fprintf(fp, "%c", *d++); - } - fprintf(fp, "\n"); - return 1; -} - -int tls_trace(int format, int indent, const char *str, ...) -{ - FILE *fp = stderr; - va_list args; - int i; - for (i = 0; i < indent; i++) { - fprintf(fp, " "); - } - va_start(args, str); - vfprintf(fp, str, args); - va_end(args); - fprintf(fp, "\n"); - return 1; -} - + + +#include +#include +#include +#include +#include + +void print_der(const uint8_t *in, size_t inlen) +{ + size_t i; + for (i = 0; i < inlen; i++) { + printf("%02x ", in[i]); + } +} + +void print_bytes(const uint8_t *data, size_t datalen) +{ + size_t i; + for (i = 0; i < datalen; i++) { + printf("%02X ", data[i]); + if ((i + 1) % 32 == 0) + printf("\n"); + } + printf("\n"); +} + +void print_nodes(const uint32_t *in, size_t inlen) +{ + size_t i; + printf("%u", in[0]); + for (i = 1; i < inlen; i++) { + printf(".%u", in[i]); + } +} + + + +int format_print(FILE *fp, int format, int indent, const char *str, ...) +{ + va_list args; + int i; + for (i = 0; i < indent; i++) { + fprintf(fp, " "); + } + va_start(args, str); + vfprintf(fp, str, args); + va_end(args); + return 1; +} + +int format_bytes(FILE *fp, int format, int indent, const char *str, const uint8_t *data, size_t datalen) +{ + int i; + + if (datalen > 4096) { + error_print(); + return -1; + } + + for (i = 0; i < indent; i++) { + fprintf(fp, " "); + } + fprintf(fp, "%s: ", str); + if (!datalen) { + fprintf(fp, "(null)\n"); + return 1; + } + for (i = 0; i < datalen; i++) { + fprintf(fp, "%02X", data[i]); + } + fprintf(fp, "\n"); + return 1; +} + + +int format_string(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + while (ind--) { + fprintf(fp, " "); + } + fprintf(fp, "%s: ", label); + while (dlen--) { + fprintf(fp, "%c", *d++); + } + fprintf(fp, "\n"); + return 1; +} + +int tls_trace(int format, int indent, const char *str, ...) +{ + FILE *fp = stderr; + va_list args; + int i; + for (i = 0; i < indent; i++) { + fprintf(fp, " "); + } + va_start(args, str); + vfprintf(fp, str, args); + va_end(args); + fprintf(fp, "\n"); + return 1; +} + diff --git a/src/des.c b/src/des.c index 283df428..61268175 100644 --- a/src/des.c +++ b/src/des.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,223 +7,224 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -/* permuted choice 1 for key schedule, 64 bits to 56 bits */ -static unsigned char PC1[56] = { - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4, -}; - -/* permuted choice 2 for key schedule, 48 bits to 48 bits */ -static unsigned char PC2[48] = { - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32, -}; - -/* rotations for every round of key schedule */ -static unsigned char S[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, -}; - -/* initial permutation, 64 bits to 64 bits */ -static unsigned char IP[64] = { - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, -}; - -/* inverse initial permutation, 64 bits to 64 bits */ -static unsigned char IP_inv[64] = { - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25, -}; - -/* expansion permutation, 32 bits to 48 bits */ -static unsigned char E[48] = { - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1, -}; - -/* eight s-box, 6 bits to 4 bits */ -static unsigned char S1[64] = { - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, -}; - -static unsigned char S2[64] = { - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, -}; - -static unsigned char S3[64] = { - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, -}; - -static unsigned char S4[64] = { - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, -}; - -static unsigned char S5[64] = { - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, -}; - -static unsigned char S6[64] = { - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, -}; - -static unsigned char S7[64] = { - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, -}; - -static unsigned char S8[64] = { - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, -}; - -/* permutation, 32 bits to 32 bits */ -static unsigned char P[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25, -}; - - -static uint64_t permute(const unsigned char *table, size_t n, uint64_t A) -{ - uint64_t R = 0; - for (size_t i = 0; i < n; i++) { - R |= (A >> (n - table[i])) & 0x01; - } - return R; -} - -static uint32_t substitution(const uint64_t A) -{ - return (((uint32_t)S1[(A >> 42) & 0x3f]) << 28) | - (((uint32_t)S2[(A >> 36) & 0x3f]) << 24) | - (((uint32_t)S3[(A >> 30) & 0x3f]) << 20) | - (((uint32_t)S4[(A >> 24) & 0x3f]) << 16) | - (((uint32_t)S5[(A >> 18) & 0x3f]) << 12) | - (((uint32_t)S6[(A >> 12) & 0x3f]) << 8) | - (((uint32_t)S7[(A >> 6) & 0x3f]) << 4) | - (((uint32_t)S8[(A ) & 0x3f]) ); -} - -//#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si)))) - -void des_set_encrypt_key(DES_KEY *key, const unsigned char user_key[8]) -{ - uint64_t K; - uint32_t L, R; - int i; - - K = GETU64(user_key); - K = permute(PC1, sizeof(PC1), K); - L = K >> 28; - R = K & 0x0fffffff; - - for (i = 0; i < 16; i++) { - L = ROL32(L, S[i]); - R = ROL32(R, S[i]); - K = ((uint64_t)L << 28) | R; - key->rk[i] = permute(PC2, sizeof(PC2), K); - } -} - -void des_set_decrypt_key(DES_KEY *key, const unsigned char user_key[8]) -{ - // TODO -} - -void des_encrypt(DES_KEY *key, const unsigned char in[DES_BLOCK_SIZE], - unsigned char out[DES_BLOCK_SIZE]) -{ - uint64_t T; - uint32_t L, R; - int i; - - T = GETU64(in); - - /* initial permutation */ - T = permute(IP, sizeof(IP), T); - - L = T >> 32; - R = T & 0xffffffff; - - for (i = 0; i < 16; i++) { - - /* compute F_{Ki}(R) */ - T = permute(E, sizeof(E), R); - T ^= key->rk[i]; - T = substitution(T); - T = permute(P, sizeof(P), T); - - T ^= L; - - L = R; - R = T; - } - - T = ((uint64_t)L << 32) | R; - - /* inverse initial permutation */ - T = permute(IP_inv, sizeof(IP_inv), T); - - PUTU64(out, T); -} + + +#include +#include +#include +#include +#include + + +/* permuted choice 1 for key schedule, 64 bits to 56 bits */ +static unsigned char PC1[56] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +/* permuted choice 2 for key schedule, 48 bits to 48 bits */ +static unsigned char PC2[48] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32, +}; + +/* rotations for every round of key schedule */ +static unsigned char S[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* initial permutation, 64 bits to 64 bits */ +static unsigned char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* inverse initial permutation, 64 bits to 64 bits */ +static unsigned char IP_inv[64] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25, +}; + +/* expansion permutation, 32 bits to 48 bits */ +static unsigned char E[48] = { + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +/* eight s-box, 6 bits to 4 bits */ +static unsigned char S1[64] = { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, +}; + +static unsigned char S2[64] = { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, +}; + +static unsigned char S3[64] = { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, +}; + +static unsigned char S4[64] = { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, +}; + +static unsigned char S5[64] = { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, +}; + +static unsigned char S6[64] = { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, +}; + +static unsigned char S7[64] = { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, +}; + +static unsigned char S8[64] = { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, +}; + +/* permutation, 32 bits to 32 bits */ +static unsigned char P[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25, +}; + + +static uint64_t permute(const unsigned char *table, size_t n, uint64_t A) +{ + uint64_t R = 0; + for (size_t i = 0; i < n; i++) { + R |= (A >> (n - table[i])) & 0x01; + } + return R; +} + +static uint32_t substitution(const uint64_t A) +{ + return (((uint32_t)S1[(A >> 42) & 0x3f]) << 28) | + (((uint32_t)S2[(A >> 36) & 0x3f]) << 24) | + (((uint32_t)S3[(A >> 30) & 0x3f]) << 20) | + (((uint32_t)S4[(A >> 24) & 0x3f]) << 16) | + (((uint32_t)S5[(A >> 18) & 0x3f]) << 12) | + (((uint32_t)S6[(A >> 12) & 0x3f]) << 8) | + (((uint32_t)S7[(A >> 6) & 0x3f]) << 4) | + (((uint32_t)S8[(A ) & 0x3f]) ); +} + +//#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si)))) + +void des_set_encrypt_key(DES_KEY *key, const unsigned char user_key[8]) +{ + uint64_t K; + uint32_t L, R; + int i; + + K = GETU64(user_key); + K = permute(PC1, sizeof(PC1), K); + L = K >> 28; + R = K & 0x0fffffff; + + for (i = 0; i < 16; i++) { + L = ROL32(L, S[i]); + R = ROL32(R, S[i]); + K = ((uint64_t)L << 28) | R; + key->rk[i] = permute(PC2, sizeof(PC2), K); + } +} + +void des_set_decrypt_key(DES_KEY *key, const unsigned char user_key[8]) +{ + // TODO +} + +void des_encrypt(DES_KEY *key, const unsigned char in[DES_BLOCK_SIZE], + unsigned char out[DES_BLOCK_SIZE]) +{ + uint64_t T; + uint32_t L, R; + int i; + + T = GETU64(in); + + /* initial permutation */ + T = permute(IP, sizeof(IP), T); + + L = T >> 32; + R = T & 0xffffffff; + + for (i = 0; i < 16; i++) { + + /* compute F_{Ki}(R) */ + T = permute(E, sizeof(E), R); + T ^= key->rk[i]; + T = substitution(T); + T = permute(P, sizeof(P), T); + + T ^= L; + + L = R; + R = T; + } + + T = ((uint64_t)L << 32) | R; + + /* inverse initial permutation */ + T = permute(IP_inv, sizeof(IP_inv), T); + + PUTU64(out, T); +} diff --git a/src/digest.c b/src/digest.c index bbb48cf3..06c0a671 100644 --- a/src/digest.c +++ b/src/digest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,495 +7,496 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include - - -typedef struct { - int oid; - char *short_name; - char *display_name; -} DIGEST_TABLE; - -DIGEST_TABLE digest_table[] = { - { OID_sm3, "sm3", "SM3" }, -// { OID_md5, "md5", "MD5" }, - { OID_sha1, "sha1", "SHA-1" }, - { OID_sha224, "sha224", "SHA-224" }, - { OID_sha256, "sha256", "SHA-256" }, - { OID_sha384, "sha384", "SHA-384" }, - { OID_sha512, "sha512", "SHA-512" }, -}; - -const char *digest_name(const DIGEST *digest) -{ - int i; - for (i = 0; i < sizeof(digest_table)/sizeof(digest_table[0]); i++) { - if (digest->oid == digest_table[i].oid) { - return digest_table[i].short_name; - } - } - return NULL; -} - -int digest_init(DIGEST_CTX *ctx, const DIGEST *algor) -{ - memset(ctx, 0, sizeof(DIGEST_CTX)); - if (algor == NULL) { - error_print(); - return -1; - } - ctx->digest = algor; - ctx->digest->init(ctx); - return 1; -} - -int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen) -{ - if (data == NULL || datalen == 0) { - return 0; - } - ctx->digest->update(ctx, data, datalen); - return 1; -} - -int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen) -{ - if (dgst == NULL || dgstlen == NULL) { - error_print(); - return -1; - } - ctx->digest->finish(ctx, dgst); - *dgstlen = ctx->digest->digest_size; - return 1; -} - -int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, - uint8_t *dgst, size_t *dgstlen) -{ - DIGEST_CTX ctx; - if (digest_init(&ctx, digest) != 1 - || digest_update(&ctx, data, datalen) < 0 - || digest_finish(&ctx, dgst, dgstlen) != 1) { - error_print(); - return -1; - } - memset(&ctx, 0, sizeof(DIGEST_CTX)); - return 1; -} - -const DIGEST *digest_from_name(const char *name) -{ - if (!strcmp(name, "sm3") || !strcmp(name, "SM3")) { - return DIGEST_sm3(); - /* - } else if (!strcmp(name, "md5") || !strcmp(name, "MD5")) { - return DIGEST_md5(); - */ - } else if (!strcmp(name, "sha1") || !strcmp(name, "SHA1")) { - return DIGEST_sha1(); - } else if (!strcmp(name, "sha224") || !strcmp(name, "SHA224")) { - return DIGEST_sha224(); - } else if (!strcmp(name, "sha256") || !strcmp(name, "SHA256")) { - return DIGEST_sha256(); - } else if (!strcmp(name, "sha384") || !strcmp(name, "SHA384")) { - return DIGEST_sha384(); - } else if (!strcmp(name, "sha512") || !strcmp(name, "SHA512")) { - return DIGEST_sha512(); - } else if (!strcmp(name, "sha512-224") || !strcmp(name, "SHA512-224")) { - return DIGEST_sha512_224(); - } else if (!strcmp(name, "sha512-256") || !strcmp(name, "SHA512-256")) { - return DIGEST_sha512_256(); - } - return NULL; -} - -static int sm3_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sm3_init(&ctx->u.sm3_ctx); - return 1; -} - -static int sm3_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sm3_update(&ctx->u.sm3_ctx, in, inlen); - return 1; -} - -static int sm3_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sm3_finish(&ctx->u.sm3_ctx, dgst); - return 1; -} - -static const DIGEST sm3_digest_object = { - OID_sm3, - SM3_DIGEST_SIZE, - SM3_BLOCK_SIZE, - sizeof(SM3_CTX), - sm3_digest_init, - sm3_digest_update, - sm3_digest_finish, -}; - -const DIGEST *DIGEST_sm3(void) -{ - return &sm3_digest_object; -} - -/* -#include - -static int md5_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - md5_init(&ctx->u.md5_ctx); - return 1; -} - -static int md5_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - md5_update(&ctx->u.md5_ctx, in, inlen); - return 1; -} - -static int md5_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - md5_finish(&ctx->u.md5_ctx, dgst); - return 1; -} - -static const DIGEST md5_digest_object = { - OID_md5, - MD5_DIGEST_SIZE, - MD5_BLOCK_SIZE, - sizeof(MD5_CTX), - md5_digest_init, - md5_digest_update, - md5_digest_finish, -}; - -const DIGEST *DIGEST_md5(void) -{ - return &md5_digest_object; -} -*/ - - -#include - -static int sha1_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sha1_init(&ctx->u.sha1_ctx); - return 1; -} - -static int sha1_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sha1_update(&ctx->u.sha1_ctx, in, inlen); - return 1; -} - -static int sha1_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha1_finish(&ctx->u.sha1_ctx, dgst); - return 1; -} - -static const DIGEST sha1_digest_object = { - OID_sha1, - SHA1_DIGEST_SIZE, - SHA1_BLOCK_SIZE, - sizeof(SHA1_CTX), - sha1_digest_init, - sha1_digest_update, - sha1_digest_finish, -}; - -const DIGEST *DIGEST_sha1(void) -{ - return &sha1_digest_object; -} - -#include - -static int sha224_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sha224_init(&ctx->u.sha224_ctx); - return 1; -} - -static int sha224_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sha224_update(&ctx->u.sha224_ctx, in, inlen); - return 1; -} - -static int sha224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha224_finish(&ctx->u.sha224_ctx, dgst); - return 1; -} - -static const DIGEST sha224_digest_object = { - OID_sha224, - SHA224_DIGEST_SIZE, - SHA224_BLOCK_SIZE, - sizeof(SHA224_CTX), - sha224_digest_init, - sha224_digest_update, - sha224_digest_finish, -}; - -const DIGEST *DIGEST_sha224(void) -{ - return &sha224_digest_object; -} - -static int sha256_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sha256_init(&ctx->u.sha256_ctx); - return 1; -} - -static int sha256_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sha256_update(&ctx->u.sha256_ctx, in, inlen); - return 1; -} - -static int sha256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha256_finish(&ctx->u.sha256_ctx, dgst); - return 1; -} - -static const DIGEST sha256_digest_object = { - OID_sha256, - SHA256_DIGEST_SIZE, - SHA256_BLOCK_SIZE, - sizeof(SHA256_CTX), - sha256_digest_init, - sha256_digest_update, - sha256_digest_finish, -}; - -const DIGEST *DIGEST_sha256(void) -{ - return &sha256_digest_object; -} - - -static int sha384_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sha384_init(&ctx->u.sha384_ctx); - return 1; -} - -static int sha384_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sha384_update(&ctx->u.sha384_ctx, in, inlen); - return 1; -} - -static int sha384_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha384_finish(&ctx->u.sha384_ctx, dgst); - return 1; -} - -static const DIGEST sha384_digest_object = { - OID_sha384, - SHA384_DIGEST_SIZE, - SHA384_BLOCK_SIZE, - sizeof(SHA384_CTX), - sha384_digest_init, - sha384_digest_update, - sha384_digest_finish, -}; - -const DIGEST *DIGEST_sha384(void) -{ - return &sha384_digest_object; -} - - -static int sha512_digest_init(DIGEST_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - sha512_init(&ctx->u.sha512_ctx); - return 1; -} - -static int sha512_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) -{ - if (!ctx || (!in && inlen != 0)) { - error_print(); - return -1; - } - sha512_update(&ctx->u.sha512_ctx, in, inlen); - return 1; -} - -static int sha512_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha512_finish(&ctx->u.sha512_ctx, dgst); - return 1; -} - -static const DIGEST sha512_digest_object = { - OID_sha512, - SHA512_DIGEST_SIZE, - SHA512_BLOCK_SIZE, - sizeof(SHA512_CTX), - sha512_digest_init, - sha512_digest_update, - sha512_digest_finish, -}; - -const DIGEST *DIGEST_sha512(void) -{ - return &sha512_digest_object; -} - - -static int sha512_224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - uint8_t buf[SHA512_DIGEST_SIZE]; - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha512_finish(&ctx->u.sha512_ctx, buf); - memcpy(dgst, buf, SHA224_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); - return 1; -} - -static const DIGEST sha512_224_digest_object = { - OID_sha512_224, - SHA224_DIGEST_SIZE, - SHA512_BLOCK_SIZE, - sizeof(SHA512_CTX), - sha512_digest_init, - sha512_digest_update, - sha512_224_digest_finish, -}; - -const DIGEST *DIGEST_sha512_224(void) -{ - return &sha512_224_digest_object; -} - - -static int sha512_256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - uint8_t buf[SHA512_DIGEST_SIZE]; - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha512_finish(&ctx->u.sha512_ctx, buf); - memcpy(dgst, buf, SHA256_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); - return 1; -} - - -static const DIGEST sha512_256_digest_object = { - OID_sha512_256, - SHA256_DIGEST_SIZE, - SHA512_BLOCK_SIZE, - sizeof(SHA512_CTX), - sha512_digest_init, - sha512_digest_update, - sha512_256_digest_finish, -}; - -const DIGEST *DIGEST_sha512_256(void) -{ - return &sha512_256_digest_object; -} + + + +#include +#include +#include +#include +#include + + +typedef struct { + int oid; + char *short_name; + char *display_name; +} DIGEST_TABLE; + +DIGEST_TABLE digest_table[] = { + { OID_sm3, "sm3", "SM3" }, +// { OID_md5, "md5", "MD5" }, + { OID_sha1, "sha1", "SHA-1" }, + { OID_sha224, "sha224", "SHA-224" }, + { OID_sha256, "sha256", "SHA-256" }, + { OID_sha384, "sha384", "SHA-384" }, + { OID_sha512, "sha512", "SHA-512" }, +}; + +const char *digest_name(const DIGEST *digest) +{ + int i; + for (i = 0; i < sizeof(digest_table)/sizeof(digest_table[0]); i++) { + if (digest->oid == digest_table[i].oid) { + return digest_table[i].short_name; + } + } + return NULL; +} + +int digest_init(DIGEST_CTX *ctx, const DIGEST *algor) +{ + memset(ctx, 0, sizeof(DIGEST_CTX)); + if (algor == NULL) { + error_print(); + return -1; + } + ctx->digest = algor; + ctx->digest->init(ctx); + return 1; +} + +int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (data == NULL || datalen == 0) { + return 0; + } + ctx->digest->update(ctx, data, datalen); + return 1; +} + +int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen) +{ + if (dgst == NULL || dgstlen == NULL) { + error_print(); + return -1; + } + ctx->digest->finish(ctx, dgst); + *dgstlen = ctx->digest->digest_size; + return 1; +} + +int digest(const DIGEST *digest, const uint8_t *data, size_t datalen, + uint8_t *dgst, size_t *dgstlen) +{ + DIGEST_CTX ctx; + if (digest_init(&ctx, digest) != 1 + || digest_update(&ctx, data, datalen) < 0 + || digest_finish(&ctx, dgst, dgstlen) != 1) { + error_print(); + return -1; + } + memset(&ctx, 0, sizeof(DIGEST_CTX)); + return 1; +} + +const DIGEST *digest_from_name(const char *name) +{ + if (!strcmp(name, "sm3") || !strcmp(name, "SM3")) { + return DIGEST_sm3(); + /* + } else if (!strcmp(name, "md5") || !strcmp(name, "MD5")) { + return DIGEST_md5(); + */ + } else if (!strcmp(name, "sha1") || !strcmp(name, "SHA1")) { + return DIGEST_sha1(); + } else if (!strcmp(name, "sha224") || !strcmp(name, "SHA224")) { + return DIGEST_sha224(); + } else if (!strcmp(name, "sha256") || !strcmp(name, "SHA256")) { + return DIGEST_sha256(); + } else if (!strcmp(name, "sha384") || !strcmp(name, "SHA384")) { + return DIGEST_sha384(); + } else if (!strcmp(name, "sha512") || !strcmp(name, "SHA512")) { + return DIGEST_sha512(); + } else if (!strcmp(name, "sha512-224") || !strcmp(name, "SHA512-224")) { + return DIGEST_sha512_224(); + } else if (!strcmp(name, "sha512-256") || !strcmp(name, "SHA512-256")) { + return DIGEST_sha512_256(); + } + return NULL; +} + +static int sm3_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sm3_init(&ctx->u.sm3_ctx); + return 1; +} + +static int sm3_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sm3_update(&ctx->u.sm3_ctx, in, inlen); + return 1; +} + +static int sm3_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sm3_finish(&ctx->u.sm3_ctx, dgst); + return 1; +} + +static const DIGEST sm3_digest_object = { + OID_sm3, + SM3_DIGEST_SIZE, + SM3_BLOCK_SIZE, + sizeof(SM3_CTX), + sm3_digest_init, + sm3_digest_update, + sm3_digest_finish, +}; + +const DIGEST *DIGEST_sm3(void) +{ + return &sm3_digest_object; +} + +/* +#include + +static int md5_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + md5_init(&ctx->u.md5_ctx); + return 1; +} + +static int md5_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + md5_update(&ctx->u.md5_ctx, in, inlen); + return 1; +} + +static int md5_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + md5_finish(&ctx->u.md5_ctx, dgst); + return 1; +} + +static const DIGEST md5_digest_object = { + OID_md5, + MD5_DIGEST_SIZE, + MD5_BLOCK_SIZE, + sizeof(MD5_CTX), + md5_digest_init, + md5_digest_update, + md5_digest_finish, +}; + +const DIGEST *DIGEST_md5(void) +{ + return &md5_digest_object; +} +*/ + + +#include + +static int sha1_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha1_init(&ctx->u.sha1_ctx); + return 1; +} + +static int sha1_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sha1_update(&ctx->u.sha1_ctx, in, inlen); + return 1; +} + +static int sha1_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha1_finish(&ctx->u.sha1_ctx, dgst); + return 1; +} + +static const DIGEST sha1_digest_object = { + OID_sha1, + SHA1_DIGEST_SIZE, + SHA1_BLOCK_SIZE, + sizeof(SHA1_CTX), + sha1_digest_init, + sha1_digest_update, + sha1_digest_finish, +}; + +const DIGEST *DIGEST_sha1(void) +{ + return &sha1_digest_object; +} + +#include + +static int sha224_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha224_init(&ctx->u.sha224_ctx); + return 1; +} + +static int sha224_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sha224_update(&ctx->u.sha224_ctx, in, inlen); + return 1; +} + +static int sha224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha224_finish(&ctx->u.sha224_ctx, dgst); + return 1; +} + +static const DIGEST sha224_digest_object = { + OID_sha224, + SHA224_DIGEST_SIZE, + SHA224_BLOCK_SIZE, + sizeof(SHA224_CTX), + sha224_digest_init, + sha224_digest_update, + sha224_digest_finish, +}; + +const DIGEST *DIGEST_sha224(void) +{ + return &sha224_digest_object; +} + +static int sha256_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha256_init(&ctx->u.sha256_ctx); + return 1; +} + +static int sha256_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sha256_update(&ctx->u.sha256_ctx, in, inlen); + return 1; +} + +static int sha256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha256_finish(&ctx->u.sha256_ctx, dgst); + return 1; +} + +static const DIGEST sha256_digest_object = { + OID_sha256, + SHA256_DIGEST_SIZE, + SHA256_BLOCK_SIZE, + sizeof(SHA256_CTX), + sha256_digest_init, + sha256_digest_update, + sha256_digest_finish, +}; + +const DIGEST *DIGEST_sha256(void) +{ + return &sha256_digest_object; +} + + +static int sha384_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha384_init(&ctx->u.sha384_ctx); + return 1; +} + +static int sha384_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sha384_update(&ctx->u.sha384_ctx, in, inlen); + return 1; +} + +static int sha384_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha384_finish(&ctx->u.sha384_ctx, dgst); + return 1; +} + +static const DIGEST sha384_digest_object = { + OID_sha384, + SHA384_DIGEST_SIZE, + SHA384_BLOCK_SIZE, + sizeof(SHA384_CTX), + sha384_digest_init, + sha384_digest_update, + sha384_digest_finish, +}; + +const DIGEST *DIGEST_sha384(void) +{ + return &sha384_digest_object; +} + + +static int sha512_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha512_init(&ctx->u.sha512_ctx); + return 1; +} + +static int sha512_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) +{ + if (!ctx || (!in && inlen != 0)) { + error_print(); + return -1; + } + sha512_update(&ctx->u.sha512_ctx, in, inlen); + return 1; +} + +static int sha512_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha512_finish(&ctx->u.sha512_ctx, dgst); + return 1; +} + +static const DIGEST sha512_digest_object = { + OID_sha512, + SHA512_DIGEST_SIZE, + SHA512_BLOCK_SIZE, + sizeof(SHA512_CTX), + sha512_digest_init, + sha512_digest_update, + sha512_digest_finish, +}; + +const DIGEST *DIGEST_sha512(void) +{ + return &sha512_digest_object; +} + + +static int sha512_224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + uint8_t buf[SHA512_DIGEST_SIZE]; + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha512_finish(&ctx->u.sha512_ctx, buf); + memcpy(dgst, buf, SHA224_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); + return 1; +} + +static const DIGEST sha512_224_digest_object = { + OID_sha512_224, + SHA224_DIGEST_SIZE, + SHA512_BLOCK_SIZE, + sizeof(SHA512_CTX), + sha512_digest_init, + sha512_digest_update, + sha512_224_digest_finish, +}; + +const DIGEST *DIGEST_sha512_224(void) +{ + return &sha512_224_digest_object; +} + + +static int sha512_256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + uint8_t buf[SHA512_DIGEST_SIZE]; + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha512_finish(&ctx->u.sha512_ctx, buf); + memcpy(dgst, buf, SHA256_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); + return 1; +} + + +static const DIGEST sha512_256_digest_object = { + OID_sha512_256, + SHA256_DIGEST_SIZE, + SHA512_BLOCK_SIZE, + sizeof(SHA512_CTX), + sha512_digest_init, + sha512_digest_update, + sha512_256_digest_finish, +}; + +const DIGEST *DIGEST_sha512_256(void) +{ + return &sha512_256_digest_object; +} diff --git a/src/ec.c b/src/ec.c index ede26b6b..379ccf2f 100644 --- a/src/ec.c +++ b/src/ec.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,134 +7,135 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -#define oid_sm_scheme 1,2,156,10197,1 -static uint32_t oid_sm2[] = { oid_sm_scheme,301 }; - -#define oid_x9_62_curves oid_x9_62,3 -#define oid_x9_62_prime_curves oid_x9_62_curves,1 -static uint32_t oid_prime192v1[] = { oid_x9_62_prime_curves,1 }; -static uint32_t oid_prime256v1[] = { oid_x9_62_prime_curves,7 }; // NIST P-256 - -#define oid_secg_curve 1,3,132,0 -static uint32_t oid_secp256k1[] = { oid_secg_curve,10 }; -static uint32_t oid_secp384r1[] = { oid_secg_curve,34 }; // NIST P-384 -static uint32_t oid_secp521r1[] = { oid_secg_curve,35 }; // NIST P-521 - - -static const ASN1_OID_INFO ec_named_curves[] = { - { OID_sm2, "sm2p256v1", oid_sm2, sizeof(oid_sm2)/sizeof(int), 0, "SM2" }, - { OID_prime192v1, "prime192v1", oid_prime192v1, sizeof(oid_prime192v1)/sizeof(int), 0, }, - { OID_prime256v1, "prime256v1", oid_prime256v1, sizeof(oid_prime256v1)/sizeof(int), 0, "NIST P-256" }, - { OID_secp256k1, "secp256k1", oid_secp256k1, sizeof(oid_secp256k1)/sizeof(int) }, - { OID_secp384r1, "secp384r1", oid_secp384r1, sizeof(oid_secp384r1)/sizeof(int), 0, "NIST P-384" }, - { OID_secp521r1, "secp521r1", oid_secp521r1, sizeof(oid_secp521r1)/sizeof(int), 0, "NIST P-521" } -}; - -static const int ec_named_curves_count = - sizeof(ec_named_curves)/sizeof(ec_named_curves[0]); - -const char *ec_named_curve_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int ec_named_curve_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(ec_named_curves, ec_named_curves_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int ec_named_curve_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int ec_named_curve_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - if ((ret = asn1_oid_info_from_der(&info, ec_named_curves, ec_named_curves_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - -int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, label, p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *a; - size_t alen; - const uint8_t *p; - size_t len; - int val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "privateKey", p, len); - if ((ret = asn1_explicit_from_der(0, &a, &alen, &d, &dlen)) < 0) goto err; - else if (ret) { - if (ec_named_curve_from_der(&val, &a, &alen) != 1) goto err; - format_print(fp, fmt, ind, "parameters: %s\n", ec_named_curve_name(val)); - if (asn1_length_is_zero(alen) != 1) goto err; - } - format_print(fp, fmt, ind, "publicKey\n"); - ind += 4; - if ((ret = asn1_explicit_from_der(1, &a, &alen, &d, &dlen)) < 0) goto err; - else if (ret) { - if (asn1_bit_octets_from_der(&p, &len, &a, &alen) != 1) goto err; - format_bytes(fp, fmt, ind, "ECPoint", p, len); - if (asn1_length_is_zero(alen) != 1) goto err; - } - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include + + +#define oid_sm_scheme 1,2,156,10197,1 +static uint32_t oid_sm2[] = { oid_sm_scheme,301 }; + +#define oid_x9_62_curves oid_x9_62,3 +#define oid_x9_62_prime_curves oid_x9_62_curves,1 +static uint32_t oid_prime192v1[] = { oid_x9_62_prime_curves,1 }; +static uint32_t oid_prime256v1[] = { oid_x9_62_prime_curves,7 }; // NIST P-256 + +#define oid_secg_curve 1,3,132,0 +static uint32_t oid_secp256k1[] = { oid_secg_curve,10 }; +static uint32_t oid_secp384r1[] = { oid_secg_curve,34 }; // NIST P-384 +static uint32_t oid_secp521r1[] = { oid_secg_curve,35 }; // NIST P-521 + + +static const ASN1_OID_INFO ec_named_curves[] = { + { OID_sm2, "sm2p256v1", oid_sm2, sizeof(oid_sm2)/sizeof(int), 0, "SM2" }, + { OID_prime192v1, "prime192v1", oid_prime192v1, sizeof(oid_prime192v1)/sizeof(int), 0, }, + { OID_prime256v1, "prime256v1", oid_prime256v1, sizeof(oid_prime256v1)/sizeof(int), 0, "NIST P-256" }, + { OID_secp256k1, "secp256k1", oid_secp256k1, sizeof(oid_secp256k1)/sizeof(int) }, + { OID_secp384r1, "secp384r1", oid_secp384r1, sizeof(oid_secp384r1)/sizeof(int), 0, "NIST P-384" }, + { OID_secp521r1, "secp521r1", oid_secp521r1, sizeof(oid_secp521r1)/sizeof(int), 0, "NIST P-521" } +}; + +static const int ec_named_curves_count = + sizeof(ec_named_curves)/sizeof(ec_named_curves[0]); + +const char *ec_named_curve_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int ec_named_curve_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(ec_named_curves, ec_named_curves_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int ec_named_curve_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(ec_named_curves, ec_named_curves_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int ec_named_curve_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + if ((ret = asn1_oid_info_from_der(&info, ec_named_curves, ec_named_curves_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + +int ec_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, label, p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *a; + size_t alen; + const uint8_t *p; + size_t len; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "privateKey", p, len); + if ((ret = asn1_explicit_from_der(0, &a, &alen, &d, &dlen)) < 0) goto err; + else if (ret) { + if (ec_named_curve_from_der(&val, &a, &alen) != 1) goto err; + format_print(fp, fmt, ind, "parameters: %s\n", ec_named_curve_name(val)); + if (asn1_length_is_zero(alen) != 1) goto err; + } + format_print(fp, fmt, ind, "publicKey\n"); + ind += 4; + if ((ret = asn1_explicit_from_der(1, &a, &alen, &d, &dlen)) < 0) goto err; + else if (ret) { + if (asn1_bit_octets_from_der(&p, &len, &a, &alen) != 1) goto err; + format_bytes(fp, fmt, ind, "ECPoint", p, len); + if (asn1_length_is_zero(alen) != 1) goto err; + } + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} diff --git a/src/gcm.c b/src/gcm.c index 36121dfd..49adcf77 100644 --- a/src/gcm.c +++ b/src/gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,110 +7,111 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * GHASH(H, A, C) = X_{m + n + 1} - * A additional authenticated data, A = A_1, ..., A_{m-1}, A_{m^*}, nbits(A_{m^*}) = v - * C ciphertext, C = C_1, ..., C_{n-1}, C_{n^*}, nbits(C_{n^*}) = u - * H = E_K(0^128) - * - * X_i = 0 for i = 0 - * = (X_{i-1} xor A_i ) * H for i = 1, ..., m-1 - * = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m - * = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n − 1 - * = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n - * = (X_{m+n} xor (nbits(A)||nbits(C))) * H for i = m + n + 1 - */ -void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16]) -{ - gf128_t H = gf128_from_bytes(h); - gf128_t X = gf128_zero(); - gf128_t L; - - PUTU64(out, (uint64_t)aadlen << 3); - PUTU64(out + 8, (uint64_t)clen << 3); - L = gf128_from_bytes(out); - - while (aadlen) { - gf128_t A; - if (aadlen >= 16) { - A = gf128_from_bytes(aad); - aad += 16; - aadlen -= 16; - } else { - memset(out, 0, 16); - memcpy(out, aad, aadlen); - A = gf128_from_bytes(out); - aadlen = 0; - } - X = gf128_add(X, A); - X = gf128_mul(X, H); - } - - while (clen) { - gf128_t C; - if (clen >= 16) { - C = gf128_from_bytes(c); - c += 16; - clen -= 16; - } else { - memset(out, 0, 16); - memcpy(out, c, clen); - C = gf128_from_bytes(out); - clen = 0; - } - X = gf128_add(X, C); - X = gf128_mul(X, H); - } - - X = gf128_add(X, L); - H = gf128_mul(X, H); - gf128_to_bytes(H, out); -} - -int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag) -{ - if (key->cipher == BLOCK_CIPHER_sm4()) { - if (sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { - error_print(); - return -1; - } - } else if (key->cipher == BLOCK_CIPHER_aes128()) { - if (aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out) -{ - if (key->cipher == BLOCK_CIPHER_sm4()) { - if (sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { - error_print(); - return -1; - } - } else if (key->cipher == BLOCK_CIPHER_aes128()) { - if (aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { - error_print(); - return -1; - } - } - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * GHASH(H, A, C) = X_{m + n + 1} + * A additional authenticated data, A = A_1, ..., A_{m-1}, A_{m^*}, nbits(A_{m^*}) = v + * C ciphertext, C = C_1, ..., C_{n-1}, C_{n^*}, nbits(C_{n^*}) = u + * H = E_K(0^128) + * + * X_i = 0 for i = 0 + * = (X_{i-1} xor A_i ) * H for i = 1, ..., m-1 + * = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m + * = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n − 1 + * = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n + * = (X_{m+n} xor (nbits(A)||nbits(C))) * H for i = m + n + 1 + */ +void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16]) +{ + gf128_t H = gf128_from_bytes(h); + gf128_t X = gf128_zero(); + gf128_t L; + + PUTU64(out, (uint64_t)aadlen << 3); + PUTU64(out + 8, (uint64_t)clen << 3); + L = gf128_from_bytes(out); + + while (aadlen) { + gf128_t A; + if (aadlen >= 16) { + A = gf128_from_bytes(aad); + aad += 16; + aadlen -= 16; + } else { + memset(out, 0, 16); + memcpy(out, aad, aadlen); + A = gf128_from_bytes(out); + aadlen = 0; + } + X = gf128_add(X, A); + X = gf128_mul(X, H); + } + + while (clen) { + gf128_t C; + if (clen >= 16) { + C = gf128_from_bytes(c); + c += 16; + clen -= 16; + } else { + memset(out, 0, 16); + memcpy(out, c, clen); + C = gf128_from_bytes(out); + clen = 0; + } + X = gf128_add(X, C); + X = gf128_mul(X, H); + } + + X = gf128_add(X, L); + H = gf128_mul(X, H); + gf128_to_bytes(H, out); +} + +int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag) +{ + if (key->cipher == BLOCK_CIPHER_sm4()) { + if (sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } + } else if (key->cipher == BLOCK_CIPHER_aes128()) { + if (aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out) +{ + if (key->cipher == BLOCK_CIPHER_sm4()) { + if (sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } + } else if (key->cipher == BLOCK_CIPHER_aes128()) { + if (aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } + } + return 1; +} diff --git a/src/gf128.c b/src/gf128.c index 0056b8f3..6704b370 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,171 +7,172 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1 - * A + B mod f(x) = a xor b - * A * 2 mod f(x) - */ - - -#include -#include -#include -#include -#include -#include -#include - - -gf128_t gf128_zero(void) -{ - uint8_t zero[16] = {0}; - return gf128_from_bytes(zero); -} - -gf128_t gf128_from_hex(const char *s) -{ - uint8_t bin[16]; - size_t len; - hex_to_bytes(s, strlen(s), bin, &len); - return gf128_from_bytes(bin); -} - -int gf128_equ_hex(gf128_t a, const char *s) -{ - uint8_t bin1[16]; - uint8_t bin2[16]; - size_t len; - hex_to_bytes(s, strlen(s), bin1, &len); - gf128_to_bytes(a, bin2); - return memcmp(bin1, bin2, sizeof(bin1)) == 0; -} - -void gf128_print_bits(gf128_t a) -{ - int i; - for (i = 0; i < 64; i++) { - printf("%d", (int)(a.hi % 2)); - a.hi >>= 1; - } - for (i = 0; i < 64; i++) { - printf("%d", (int)(a.lo % 2)); - a.lo >>= 1; - } - printf("\n"); -} - -int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a) -{ - uint8_t be[16]; - int i; - - printf("%s: ", label); - gf128_to_bytes(a, be); - for (i = 0; i < 16; i++) { - printf("%02x", be[i]); - } - printf("\n"); - return 1; -} - -static uint64_t reverse_bits(uint64_t a) -{ - uint64_t r = 0; - int i; - - for (i = 0; i < 63; i++) { - r |= a & 1; - r <<= 1; - a >>= 1; - } - r |= a & 1; - return r; -} - -gf128_t gf128_from_bytes(const uint8_t p[16]) -{ - gf128_t r; - - r.lo = GETU64(p); - r.hi = GETU64(p + 8); - - r.lo = reverse_bits(r.lo); - r.hi = reverse_bits(r.hi); - return r; -} - -void gf128_to_bytes(gf128_t a, uint8_t p[16]) -{ - a.lo = reverse_bits(a.lo); - a.hi = reverse_bits(a.hi); - PUTU64(p, a.lo); - PUTU64(p + 8, a.hi); -} - -gf128_t gf128_add(gf128_t a, gf128_t b) -{ - gf128_t r; - r.hi = a.hi ^ b.hi; - r.lo = a.lo ^ b.lo; - return r; -} - -gf128_t gf128_mul(gf128_t a, gf128_t b) -{ - gf128_t r = {0, 0}; - uint64_t mask = (uint64_t)1 << 63; - int i; - - for (i = 0; i < 64; i++) { - if (r.hi & mask) { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = (r.lo << 1); - r.lo ^= 0x87; - } else { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = r.lo << 1; - } - - if (b.hi & mask) { - r.hi ^= a.hi; - r.lo ^= a.lo; - } - - b.hi <<= 1; - } - for (i = 0; i < 64; i++) { - if (r.hi & mask) { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = (r.lo << 1) ^ 0x87; - } else { - r.hi = r.hi << 1 | r.lo >> 63; - r.lo = r.lo << 1; - } - - if (b.lo & mask) { - r.hi ^= a.hi; - r.lo ^= a.lo; - } - - b.lo <<= 1; - } - - return r; -} - -gf128_t gf128_mul2(gf128_t a) -{ - gf128_t r; - - if (a.hi & ((uint64_t)1 << 63)) { - r.hi = a.hi << 1 | a.lo >> 63; - r.lo = a.lo << 1; - r.lo ^= 0x87; - } else { - r.hi = a.hi << 1 | a.lo >> 63; - r.lo = a.lo << 1; - } - - return r; -} + + +/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1 + * A + B mod f(x) = a xor b + * A * 2 mod f(x) + */ + + +#include +#include +#include +#include +#include +#include +#include + + +gf128_t gf128_zero(void) +{ + uint8_t zero[16] = {0}; + return gf128_from_bytes(zero); +} + +gf128_t gf128_from_hex(const char *s) +{ + uint8_t bin[16]; + size_t len; + hex_to_bytes(s, strlen(s), bin, &len); + return gf128_from_bytes(bin); +} + +int gf128_equ_hex(gf128_t a, const char *s) +{ + uint8_t bin1[16]; + uint8_t bin2[16]; + size_t len; + hex_to_bytes(s, strlen(s), bin1, &len); + gf128_to_bytes(a, bin2); + return memcmp(bin1, bin2, sizeof(bin1)) == 0; +} + +void gf128_print_bits(gf128_t a) +{ + int i; + for (i = 0; i < 64; i++) { + printf("%d", (int)(a.hi % 2)); + a.hi >>= 1; + } + for (i = 0; i < 64; i++) { + printf("%d", (int)(a.lo % 2)); + a.lo >>= 1; + } + printf("\n"); +} + +int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a) +{ + uint8_t be[16]; + int i; + + printf("%s: ", label); + gf128_to_bytes(a, be); + for (i = 0; i < 16; i++) { + printf("%02x", be[i]); + } + printf("\n"); + return 1; +} + +static uint64_t reverse_bits(uint64_t a) +{ + uint64_t r = 0; + int i; + + for (i = 0; i < 63; i++) { + r |= a & 1; + r <<= 1; + a >>= 1; + } + r |= a & 1; + return r; +} + +gf128_t gf128_from_bytes(const uint8_t p[16]) +{ + gf128_t r; + + r.lo = GETU64(p); + r.hi = GETU64(p + 8); + + r.lo = reverse_bits(r.lo); + r.hi = reverse_bits(r.hi); + return r; +} + +void gf128_to_bytes(gf128_t a, uint8_t p[16]) +{ + a.lo = reverse_bits(a.lo); + a.hi = reverse_bits(a.hi); + PUTU64(p, a.lo); + PUTU64(p + 8, a.hi); +} + +gf128_t gf128_add(gf128_t a, gf128_t b) +{ + gf128_t r; + r.hi = a.hi ^ b.hi; + r.lo = a.lo ^ b.lo; + return r; +} + +gf128_t gf128_mul(gf128_t a, gf128_t b) +{ + gf128_t r = {0, 0}; + uint64_t mask = (uint64_t)1 << 63; + int i; + + for (i = 0; i < 64; i++) { + if (r.hi & mask) { + r.hi = r.hi << 1 | r.lo >> 63; + r.lo = (r.lo << 1); + r.lo ^= 0x87; + } else { + r.hi = r.hi << 1 | r.lo >> 63; + r.lo = r.lo << 1; + } + + if (b.hi & mask) { + r.hi ^= a.hi; + r.lo ^= a.lo; + } + + b.hi <<= 1; + } + for (i = 0; i < 64; i++) { + if (r.hi & mask) { + r.hi = r.hi << 1 | r.lo >> 63; + r.lo = (r.lo << 1) ^ 0x87; + } else { + r.hi = r.hi << 1 | r.lo >> 63; + r.lo = r.lo << 1; + } + + if (b.lo & mask) { + r.hi ^= a.hi; + r.lo ^= a.lo; + } + + b.lo <<= 1; + } + + return r; +} + +gf128_t gf128_mul2(gf128_t a) +{ + gf128_t r; + + if (a.hi & ((uint64_t)1 << 63)) { + r.hi = a.hi << 1 | a.lo >> 63; + r.lo = a.lo << 1; + r.lo ^= 0x87; + } else { + r.hi = a.hi << 1 | a.lo >> 63; + r.lo = a.lo << 1; + } + + return r; +} diff --git a/src/hash_drbg.c b/src/hash_drbg.c index d7ea70ad..35e2517d 100644 --- a/src/hash_drbg.c +++ b/src/hash_drbg.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,295 +7,296 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -static int hash_df(const DIGEST *digest, const uint8_t *in, size_t inlen, - size_t outlen, uint8_t *out) -{ - int ret = 0; - DIGEST_CTX ctx; - uint8_t counter; - uint8_t outbits[4]; - unsigned char dgst[64]; - size_t len; - - counter = 0x01; - PUTU32(outbits, (uint32_t)outlen << 3); - - while (outlen > 0) { - if (digest_init(&ctx, digest) != 1 - || digest_update(&ctx, &counter, sizeof(counter)) != 1 - || digest_update(&ctx, outbits, sizeof(outbits)) != 1 - || digest_update(&ctx, in, inlen) != 1 - || digest_finish(&ctx, dgst, &len) != 1) { - goto end; - } - - if (outlen < len) { - len = outlen; - } - memcpy(out, dgst, len); - out += len; - outlen -= len; - - counter++; - } - - ret = 1; -end: - memset(&ctx, 0, sizeof(ctx)); - memset(dgst, 0, sizeof(dgst)); - return ret; -} - -int hash_drbg_init(HASH_DRBG *drbg, const DIGEST *digest, - const uint8_t *entropy, size_t entropy_len, - const uint8_t *nonce, size_t nonce_len, - const uint8_t *personalstr, size_t personalstr_len) -{ - int ret = 0; - unsigned char *seed_material = NULL; - size_t seed_material_len; - uint8_t buf[1 + HASH_DRBG_MAX_SEED_SIZE]; - uint8_t *p; - - memset(drbg, 0, sizeof(HASH_DRBG)); - - /* set digest */ - drbg->digest = digest; - - /* set seedlen */ - if (digest->digest_size <= 32) { - drbg->seedlen = HASH_DRBG_SM3_SEED_SIZE; - } else { - drbg->seedlen = HASH_DRBG_SHA512_SEED_SIZE; - } - - /* seed_material = entropy_input || nonce || personalization_string */ - seed_material_len = entropy_len + nonce_len + personalstr_len; - if (!(seed_material = malloc(seed_material_len))) { - return 0; - } - p = seed_material; - memcpy(p, entropy, entropy_len); - p += entropy_len; - memcpy(p, nonce, nonce_len); - p += nonce_len; - memcpy(p, personalstr, personalstr_len); - - /* V = Hash_df (seed_material, seedlen) */ - if (!hash_df(drbg->digest, seed_material, seed_material_len, drbg->seedlen, - drbg->V)) { - goto end; - } - - /* C = Hash_df ((0x00 || V), seedlen) */ - buf[0] = 0x00; - memcpy(buf + 1, drbg->V, drbg->seedlen); - if (!hash_df(drbg->digest, buf, 1 + drbg->seedlen, drbg->seedlen, - drbg->C)) { - goto end; - } - - /* reseed_counter = 1 */ - drbg->reseed_counter = 1; - - ret = 1; -end: - if (seed_material) { - memset(seed_material, 0, seed_material_len); - free(seed_material); - } - memset(buf, 0, sizeof(buf)); - return ret; -} - -int hash_drbg_reseed(HASH_DRBG *drbg, - const uint8_t *entropy, size_t entropy_len, - const uint8_t *additional, size_t additional_len) -{ - int ret = 0; - uint8_t *seed_material = NULL; - size_t seed_material_len; - uint8_t *p; - uint8_t buf[1 + HASH_DRBG_MAX_SEED_SIZE]; - - /* seed_material = 0x01 || V || entropy_input || additional_input */ - seed_material_len = 1 + drbg->seedlen + entropy_len + additional_len; - if (!(seed_material = malloc(seed_material_len))) { - return 0; - } - seed_material[0] = 0x01; - p = seed_material + 1; - memcpy(p, drbg->V, drbg->seedlen); - p += drbg->seedlen; - memcpy(p, entropy, entropy_len); - p += entropy_len; - memcpy(p, additional, additional_len); - - /* V = Hash_df(seed_material, seedlen) */ - if (!hash_df(drbg->digest, seed_material, seed_material_len, drbg->seedlen, - drbg->V)) { - goto end; - } - - /* C = Hash_df((0x00 || V), seedlen) */ - buf[0] = 0x00; - memcpy(buf + 1, drbg->V, drbg->seedlen); - if (!hash_df(drbg->digest, buf, 1 + drbg->seedlen, drbg->seedlen, - drbg->C)) { - goto end; - } - - /* reseed_counter = 1 */ - drbg->reseed_counter = 1; - - ret = 1; -end: - if (seed_material) { - memset(seed_material, 0, seed_material_len); - free(seed_material); - } - memset(buf, 0, sizeof(buf)); - return ret; -} - -/* seedlen is always >= dgstlen - * R0 ... Ru-v .. .. .. Ru-1 - * + A0 A1 A2 .. Av-1 - */ -static void drbg_add(uint8_t *R, const uint8_t *A, size_t seedlen) -{ - int temp = 0; - int i; - for (i = seedlen - 1; i >= 0; i--) { - temp += R[i] + A[i]; - R[i] = temp & 0xff; - temp >>= 8; - } -} - -static void drbg_add1(uint8_t *R, size_t seedlen) -{ - int temp = 1; - int i; - for (i = seedlen - 1; i >= 0; i--) { - temp += R[i]; - R[i] = temp & 0xff; - temp >>= 8; - } -} - -static int drbg_hashgen(HASH_DRBG *drbg, size_t outlen, uint8_t *out) -{ - int ret = 0; - DIGEST_CTX ctx; - uint8_t data[HASH_DRBG_MAX_SEED_SIZE]; - uint8_t dgst[DIGEST_MAX_SIZE]; - size_t len; - - /* data = V */ - memcpy(data, drbg->V, drbg->seedlen); - - while (outlen > 0) { - - /* output Hash(data) */ - if (digest_init(&ctx, drbg->digest) != 1 - || digest_update(&ctx, data, drbg->seedlen) != 1 - || digest_finish(&ctx, dgst, &len) != 1) { - goto end; - } - - if (outlen < len) { - len = outlen; - } - memcpy(out, dgst, len); - out += len; - outlen -= len; - - /* data = (data + 1) mod 2^seedlen */ - drbg_add1(data, drbg->seedlen); - } - - ret = 1; -end: - memset(&ctx, 0, sizeof(ctx)); - memset(data, 0, sizeof(data)); - return ret; -} - -int hash_drbg_generate(HASH_DRBG *drbg, - const uint8_t *additional, size_t additional_len, - size_t outlen, uint8_t *out) -{ - int ret = 0; - DIGEST_CTX ctx; - uint8_t prefix; - uint8_t T[HASH_DRBG_MAX_SEED_SIZE]; - uint8_t dgst[DIGEST_MAX_SIZE]; - size_t dgstlen; - - // FIXME: check outlen max value - - if (drbg->reseed_counter > HASH_DRBG_RESEED_INTERVAL) { - return 0; - } - - if (additional) { - /* w = Hash (0x02 || V || additional_input) */ - prefix = 0x02; - if (digest_init(&ctx, drbg->digest) != 1 - || digest_update(&ctx, &prefix, 1) != 1 - || digest_update(&ctx, drbg->V, drbg->seedlen) != 1 - || digest_update(&ctx, additional, additional_len) != 1 - || digest_finish(&ctx, dgst, &dgstlen) != 1) { - goto end; - } - - /* V = (V + w) mod 2^seedlen */ - memset(T, 0, drbg->seedlen - dgstlen); - memcpy(T + drbg->seedlen - dgstlen, dgst, dgstlen); - drbg_add(drbg->V, T, drbg->seedlen); - } - - /* (returned_bits) = Hashgen (requested_number_of_bits, V). */ - drbg_hashgen(drbg, outlen, out); - - /* H = Hash (0x03 || V). */ - prefix = 0x03; - if (digest_init(&ctx, drbg->digest) != 1 - || digest_update(&ctx, &prefix, 1) != 1 - || digest_update(&ctx, drbg->V, drbg->seedlen) != 1 - || digest_finish(&ctx, dgst, &dgstlen) != 1) { - goto end; - } - - /* V = (V + H + C + reseed_counter) mod 2^seedlen */ - memset(T, 0, drbg->seedlen - dgstlen); - memcpy(T + drbg->seedlen - dgstlen, dgst, dgstlen); - drbg_add(drbg->V, T, drbg->seedlen); - - drbg_add(drbg->V, drbg->C, drbg->seedlen); - - memset(T, 0, drbg->seedlen - sizeof(uint64_t)); - PUTU64(T + drbg->seedlen - sizeof(uint64_t), drbg->reseed_counter); - drbg_add(drbg->V, T, drbg->seedlen); - - /* reseed_counter = reseed_counter + 1 */ - drbg->reseed_counter++; - - ret = 1; -end: - memset(&ctx, 0, sizeof(ctx)); - memset(T, 0, sizeof(T)); - memset(dgst, 0, sizeof(dgst)); - return ret; -} + + + +#include +#include +#include +#include +#include +#include + + +static int hash_df(const DIGEST *digest, const uint8_t *in, size_t inlen, + size_t outlen, uint8_t *out) +{ + int ret = 0; + DIGEST_CTX ctx; + uint8_t counter; + uint8_t outbits[4]; + unsigned char dgst[64]; + size_t len; + + counter = 0x01; + PUTU32(outbits, (uint32_t)outlen << 3); + + while (outlen > 0) { + if (digest_init(&ctx, digest) != 1 + || digest_update(&ctx, &counter, sizeof(counter)) != 1 + || digest_update(&ctx, outbits, sizeof(outbits)) != 1 + || digest_update(&ctx, in, inlen) != 1 + || digest_finish(&ctx, dgst, &len) != 1) { + goto end; + } + + if (outlen < len) { + len = outlen; + } + memcpy(out, dgst, len); + out += len; + outlen -= len; + + counter++; + } + + ret = 1; +end: + memset(&ctx, 0, sizeof(ctx)); + memset(dgst, 0, sizeof(dgst)); + return ret; +} + +int hash_drbg_init(HASH_DRBG *drbg, const DIGEST *digest, + const uint8_t *entropy, size_t entropy_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *personalstr, size_t personalstr_len) +{ + int ret = 0; + unsigned char *seed_material = NULL; + size_t seed_material_len; + uint8_t buf[1 + HASH_DRBG_MAX_SEED_SIZE]; + uint8_t *p; + + memset(drbg, 0, sizeof(HASH_DRBG)); + + /* set digest */ + drbg->digest = digest; + + /* set seedlen */ + if (digest->digest_size <= 32) { + drbg->seedlen = HASH_DRBG_SM3_SEED_SIZE; + } else { + drbg->seedlen = HASH_DRBG_SHA512_SEED_SIZE; + } + + /* seed_material = entropy_input || nonce || personalization_string */ + seed_material_len = entropy_len + nonce_len + personalstr_len; + if (!(seed_material = malloc(seed_material_len))) { + return 0; + } + p = seed_material; + memcpy(p, entropy, entropy_len); + p += entropy_len; + memcpy(p, nonce, nonce_len); + p += nonce_len; + memcpy(p, personalstr, personalstr_len); + + /* V = Hash_df (seed_material, seedlen) */ + if (!hash_df(drbg->digest, seed_material, seed_material_len, drbg->seedlen, + drbg->V)) { + goto end; + } + + /* C = Hash_df ((0x00 || V), seedlen) */ + buf[0] = 0x00; + memcpy(buf + 1, drbg->V, drbg->seedlen); + if (!hash_df(drbg->digest, buf, 1 + drbg->seedlen, drbg->seedlen, + drbg->C)) { + goto end; + } + + /* reseed_counter = 1 */ + drbg->reseed_counter = 1; + + ret = 1; +end: + if (seed_material) { + memset(seed_material, 0, seed_material_len); + free(seed_material); + } + memset(buf, 0, sizeof(buf)); + return ret; +} + +int hash_drbg_reseed(HASH_DRBG *drbg, + const uint8_t *entropy, size_t entropy_len, + const uint8_t *additional, size_t additional_len) +{ + int ret = 0; + uint8_t *seed_material = NULL; + size_t seed_material_len; + uint8_t *p; + uint8_t buf[1 + HASH_DRBG_MAX_SEED_SIZE]; + + /* seed_material = 0x01 || V || entropy_input || additional_input */ + seed_material_len = 1 + drbg->seedlen + entropy_len + additional_len; + if (!(seed_material = malloc(seed_material_len))) { + return 0; + } + seed_material[0] = 0x01; + p = seed_material + 1; + memcpy(p, drbg->V, drbg->seedlen); + p += drbg->seedlen; + memcpy(p, entropy, entropy_len); + p += entropy_len; + memcpy(p, additional, additional_len); + + /* V = Hash_df(seed_material, seedlen) */ + if (!hash_df(drbg->digest, seed_material, seed_material_len, drbg->seedlen, + drbg->V)) { + goto end; + } + + /* C = Hash_df((0x00 || V), seedlen) */ + buf[0] = 0x00; + memcpy(buf + 1, drbg->V, drbg->seedlen); + if (!hash_df(drbg->digest, buf, 1 + drbg->seedlen, drbg->seedlen, + drbg->C)) { + goto end; + } + + /* reseed_counter = 1 */ + drbg->reseed_counter = 1; + + ret = 1; +end: + if (seed_material) { + memset(seed_material, 0, seed_material_len); + free(seed_material); + } + memset(buf, 0, sizeof(buf)); + return ret; +} + +/* seedlen is always >= dgstlen + * R0 ... Ru-v .. .. .. Ru-1 + * + A0 A1 A2 .. Av-1 + */ +static void drbg_add(uint8_t *R, const uint8_t *A, size_t seedlen) +{ + int temp = 0; + int i; + for (i = seedlen - 1; i >= 0; i--) { + temp += R[i] + A[i]; + R[i] = temp & 0xff; + temp >>= 8; + } +} + +static void drbg_add1(uint8_t *R, size_t seedlen) +{ + int temp = 1; + int i; + for (i = seedlen - 1; i >= 0; i--) { + temp += R[i]; + R[i] = temp & 0xff; + temp >>= 8; + } +} + +static int drbg_hashgen(HASH_DRBG *drbg, size_t outlen, uint8_t *out) +{ + int ret = 0; + DIGEST_CTX ctx; + uint8_t data[HASH_DRBG_MAX_SEED_SIZE]; + uint8_t dgst[DIGEST_MAX_SIZE]; + size_t len; + + /* data = V */ + memcpy(data, drbg->V, drbg->seedlen); + + while (outlen > 0) { + + /* output Hash(data) */ + if (digest_init(&ctx, drbg->digest) != 1 + || digest_update(&ctx, data, drbg->seedlen) != 1 + || digest_finish(&ctx, dgst, &len) != 1) { + goto end; + } + + if (outlen < len) { + len = outlen; + } + memcpy(out, dgst, len); + out += len; + outlen -= len; + + /* data = (data + 1) mod 2^seedlen */ + drbg_add1(data, drbg->seedlen); + } + + ret = 1; +end: + memset(&ctx, 0, sizeof(ctx)); + memset(data, 0, sizeof(data)); + return ret; +} + +int hash_drbg_generate(HASH_DRBG *drbg, + const uint8_t *additional, size_t additional_len, + size_t outlen, uint8_t *out) +{ + int ret = 0; + DIGEST_CTX ctx; + uint8_t prefix; + uint8_t T[HASH_DRBG_MAX_SEED_SIZE]; + uint8_t dgst[DIGEST_MAX_SIZE]; + size_t dgstlen; + + // FIXME: check outlen max value + + if (drbg->reseed_counter > HASH_DRBG_RESEED_INTERVAL) { + return 0; + } + + if (additional) { + /* w = Hash (0x02 || V || additional_input) */ + prefix = 0x02; + if (digest_init(&ctx, drbg->digest) != 1 + || digest_update(&ctx, &prefix, 1) != 1 + || digest_update(&ctx, drbg->V, drbg->seedlen) != 1 + || digest_update(&ctx, additional, additional_len) != 1 + || digest_finish(&ctx, dgst, &dgstlen) != 1) { + goto end; + } + + /* V = (V + w) mod 2^seedlen */ + memset(T, 0, drbg->seedlen - dgstlen); + memcpy(T + drbg->seedlen - dgstlen, dgst, dgstlen); + drbg_add(drbg->V, T, drbg->seedlen); + } + + /* (returned_bits) = Hashgen (requested_number_of_bits, V). */ + drbg_hashgen(drbg, outlen, out); + + /* H = Hash (0x03 || V). */ + prefix = 0x03; + if (digest_init(&ctx, drbg->digest) != 1 + || digest_update(&ctx, &prefix, 1) != 1 + || digest_update(&ctx, drbg->V, drbg->seedlen) != 1 + || digest_finish(&ctx, dgst, &dgstlen) != 1) { + goto end; + } + + /* V = (V + H + C + reseed_counter) mod 2^seedlen */ + memset(T, 0, drbg->seedlen - dgstlen); + memcpy(T + drbg->seedlen - dgstlen, dgst, dgstlen); + drbg_add(drbg->V, T, drbg->seedlen); + + drbg_add(drbg->V, drbg->C, drbg->seedlen); + + memset(T, 0, drbg->seedlen - sizeof(uint64_t)); + PUTU64(T + drbg->seedlen - sizeof(uint64_t), drbg->reseed_counter); + drbg_add(drbg->V, T, drbg->seedlen); + + /* reseed_counter = reseed_counter + 1 */ + drbg->reseed_counter++; + + ret = 1; +end: + memset(&ctx, 0, sizeof(ctx)); + memset(T, 0, sizeof(T)); + memset(dgst, 0, sizeof(dgst)); + return ret; +} diff --git a/src/hex.c b/src/hex.c index bcdc4bb9..35cc7358 100644 --- a/src/hex.c +++ b/src/hex.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,213 +7,214 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include - -int OPENSSL_hexchar2int(unsigned char c) -{ - switch (c) { - case '0': - return 0; - case '1': - return 1; - case '2': - return 2; - case '3': - return 3; - case '4': - return 4; - case '5': - return 5; - case '6': - return 6; - case '7': - return 7; - case '8': - return 8; - case '9': - return 9; - case 'a': - case 'A': - return 0x0A; - case 'b': case 'B': - return 0x0B; - case 'c': case 'C': - return 0x0C; - case 'd': case 'D': - return 0x0D; - case 'e': case 'E': - return 0x0E; - case 'f': case 'F': - return 0x0F; - } - return -1; -} - -unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len) -{ - unsigned char *hexbuf, *q; - unsigned char ch, cl; - int chi, cli; - const unsigned char *p; - size_t s; - - s = strlen(str); - if ((hexbuf = malloc(s >> 1)) == NULL) { - return NULL; - } - for (p = (const unsigned char *)str, q = hexbuf; *p; ) { - ch = *p++; - if (ch == ':') - continue; - cl = *p++; - if (!cl) { - //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ODD_NUMBER_OF_DIGITS); - free(hexbuf); - return NULL; - } - cli = OPENSSL_hexchar2int(cl); - chi = OPENSSL_hexchar2int(ch); - if (cli < 0 || chi < 0) { - free(hexbuf); - //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); - return NULL; - } - *q++ = (unsigned char)((chi << 4) | cli); - } - - if (len) - *len = q - hexbuf; - return hexbuf; -} - - -static int hexchar2int(char c) -{ - if ('0' <= c && c <= '9') return c - '0'; - else if ('a' <= c && c <= 'f') return c - 'a' + 10; - else if ('A' <= c && c <= 'F') return c - 'A' + 10; - else return -1; -} - -int hex2bin(const char *in, size_t inlen, uint8_t *out) -{ - int c; - if (inlen % 2) { - error_print_msg("hex %s len = %zu\n", in, inlen); - return -1; - } - - while (inlen) { - if ((c = hexchar2int(*in++)) < 0) { - error_print_msg("%d", 5); - return -1; - } - *out = (uint8_t)c << 4; - if ((c = hexchar2int(*in++)) < 0) { - error_print(); - return -1; - } - *out |= (uint8_t)c; - inlen -= 2; - out++; - } - return 1; -} - -int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - *outlen = inlen/2; - return hex2bin(in, inlen, out); -} - - -void memxor(void *r, const void *a, size_t len) -{ - uint8_t *pr = r; - const uint8_t *pa = a; - size_t i; - for (i = 0; i < len; i++) { - pr[i] ^= pa[i]; - } - -} - - -void gmssl_memxor(void *r, const void *a, const void *b, size_t len) -{ - uint8_t *pr = r; - const uint8_t *pa = a; - const uint8_t *pb = b; - size_t i; - for (i = 0; i < len; i++) { - pr[i] = pa[i] ^ pb[i]; - } -} - - -// Note: comments and code from OpenSSL crypto/cryptlib.c:CRYPTO_memcmp() -/* volatile unsigned char* pointers are there because - * 1. Accessing a variable declared volatile via a pointer - * that lacks a volatile qualifier causes undefined behavior. - * 2. When the variable itself is not volatile the compiler is - * not required to keep all those reads and can convert - * this into canonical memcmp() which doesn't read the whole block. - * Pointers to volatile resolve the first problem fully. The second - * problem cannot be resolved in any Standard-compliant way but this - * works the problem around. Compilers typically react to - * pointers to volatile by preserving the reads and writes through them. - * The latter is not required by the Standard if the memory pointed to - * is not volatile. - * Pointers themselves are volatile in the function signature to work - * around a subtle bug in gcc 4.6+ which causes writes through - * pointers to volatile to not be emitted in some rare, - * never needed in real life, pieces of code. - */ -int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len) -{ - size_t i; - const volatile unsigned char *a = in_a; - const volatile unsigned char *b = in_b; - unsigned char x = 0; - - for (i = 0; i < len; i++) { - x |= a[i] ^ b[i]; - } - - return x; -} - -/* - * Pointer to memset is volatile so that compiler must de-reference - * the pointer and can't assume that it points to any function in - * particular (such as memset, which it then might further "optimize") - */ -typedef void *(*memset_t)(void *, int, size_t); - -static volatile memset_t memset_func = memset; - -void gmssl_secure_clear(void *ptr, size_t len) -{ - memset_func(ptr, 0, len); -} - -int mem_is_zero(const uint8_t *buf, size_t len) -{ - int ret = 1; - size_t i; - for (i = 0; i < len; i++) { - if (buf[i]) ret = 0; - } - return ret; -} - - - - - + + + +#include +#include +#include +#include +#include + +int OPENSSL_hexchar2int(unsigned char c) +{ + switch (c) { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + case 'a': + case 'A': + return 0x0A; + case 'b': case 'B': + return 0x0B; + case 'c': case 'C': + return 0x0C; + case 'd': case 'D': + return 0x0D; + case 'e': case 'E': + return 0x0E; + case 'f': case 'F': + return 0x0F; + } + return -1; +} + +unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl; + int chi, cli; + const unsigned char *p; + size_t s; + + s = strlen(str); + if ((hexbuf = malloc(s >> 1)) == NULL) { + return NULL; + } + for (p = (const unsigned char *)str, q = hexbuf; *p; ) { + ch = *p++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ODD_NUMBER_OF_DIGITS); + free(hexbuf); + return NULL; + } + cli = OPENSSL_hexchar2int(cl); + chi = OPENSSL_hexchar2int(ch); + if (cli < 0 || chi < 0) { + free(hexbuf); + //CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); + return NULL; + } + *q++ = (unsigned char)((chi << 4) | cli); + } + + if (len) + *len = q - hexbuf; + return hexbuf; +} + + +static int hexchar2int(char c) +{ + if ('0' <= c && c <= '9') return c - '0'; + else if ('a' <= c && c <= 'f') return c - 'a' + 10; + else if ('A' <= c && c <= 'F') return c - 'A' + 10; + else return -1; +} + +int hex2bin(const char *in, size_t inlen, uint8_t *out) +{ + int c; + if (inlen % 2) { + error_print_msg("hex %s len = %zu\n", in, inlen); + return -1; + } + + while (inlen) { + if ((c = hexchar2int(*in++)) < 0) { + error_print_msg("%d", 5); + return -1; + } + *out = (uint8_t)c << 4; + if ((c = hexchar2int(*in++)) < 0) { + error_print(); + return -1; + } + *out |= (uint8_t)c; + inlen -= 2; + out++; + } + return 1; +} + +int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + *outlen = inlen/2; + return hex2bin(in, inlen, out); +} + + +void memxor(void *r, const void *a, size_t len) +{ + uint8_t *pr = r; + const uint8_t *pa = a; + size_t i; + for (i = 0; i < len; i++) { + pr[i] ^= pa[i]; + } + +} + + +void gmssl_memxor(void *r, const void *a, const void *b, size_t len) +{ + uint8_t *pr = r; + const uint8_t *pa = a; + const uint8_t *pb = b; + size_t i; + for (i = 0; i < len; i++) { + pr[i] = pa[i] ^ pb[i]; + } +} + + +// Note: comments and code from OpenSSL crypto/cryptlib.c:CRYPTO_memcmp() +/* volatile unsigned char* pointers are there because + * 1. Accessing a variable declared volatile via a pointer + * that lacks a volatile qualifier causes undefined behavior. + * 2. When the variable itself is not volatile the compiler is + * not required to keep all those reads and can convert + * this into canonical memcmp() which doesn't read the whole block. + * Pointers to volatile resolve the first problem fully. The second + * problem cannot be resolved in any Standard-compliant way but this + * works the problem around. Compilers typically react to + * pointers to volatile by preserving the reads and writes through them. + * The latter is not required by the Standard if the memory pointed to + * is not volatile. + * Pointers themselves are volatile in the function signature to work + * around a subtle bug in gcc 4.6+ which causes writes through + * pointers to volatile to not be emitted in some rare, + * never needed in real life, pieces of code. + */ +int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len) +{ + size_t i; + const volatile unsigned char *a = in_a; + const volatile unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + + return x; +} + +/* + * Pointer to memset is volatile so that compiler must de-reference + * the pointer and can't assume that it points to any function in + * particular (such as memset, which it then might further "optimize") + */ +typedef void *(*memset_t)(void *, int, size_t); + +static volatile memset_t memset_func = memset; + +void gmssl_secure_clear(void *ptr, size_t len) +{ + memset_func(ptr, 0, len); +} + +int mem_is_zero(const uint8_t *buf, size_t len) +{ + int ret = 1; + size_t i; + for (i = 0; i < len; i++) { + if (buf[i]) ret = 0; + } + return ret; +} + + + + + diff --git a/src/hkdf.c b/src/hkdf.c index ac8a2aa4..895b5ef2 100644 --- a/src/hkdf.c +++ b/src/hkdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,199 +7,200 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - -/* - -HKDF-Extract(salt, IKM) -> PRK - - salt optional, len(salt) == hash_len is recommended - IKM input key material - PRK output pseudorandom key, len(PRK) = hashLen - - PRK = HMAC_hash(salt, IKM) - salt as key? - - -HKDF-Expand(PRK, info, L) -> OKM - info optional - L output length, L <= 255 * hashLen - OKM output key - - - N = (L + hashLen - 1)//hashLen - T = T(1) || T(2) || ... | T(N) - OKM = T[0..L-1] - - T(0) = empty string (len = 0) - T(1) = HMAC_hash(PRK, T(0) | info | 0x01) - T(2) = HMAC_hash(PRK, T(1) | info | 0x02) - T(3) = HMAC_hash(PRK, T(2) | info | 0x03) - ... - - -*/ - -int hkdf_extract(const DIGEST *digest, const uint8_t *salt, size_t saltlen, - const uint8_t *ikm, size_t ikmlen, - uint8_t *prk, size_t *prklen) -{ - HMAC_CTX hmac_ctx; - - if (!salt || saltlen == 0) { - uint8_t zeros[DIGEST_MAX_SIZE] = {0}; - if (hmac_init(&hmac_ctx, digest, zeros, digest->digest_size) != 1) { - error_print(); - return -1; - } - } else { - if (hmac_init(&hmac_ctx, digest, salt, saltlen) != 1) { - error_print(); - return -1; - } - } - - if (hmac_update(&hmac_ctx, ikm, ikmlen) != 1 - || hmac_finish(&hmac_ctx, prk, prklen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen, - const uint8_t *opt_info, size_t opt_infolen, - size_t L, uint8_t *okm) -{ - HMAC_CTX hmac_ctx; - uint8_t T[HMAC_MAX_SIZE]; - uint8_t counter = 0x01; - size_t len; - - if (L > 0) { - if (hmac_init(&hmac_ctx, digest, prk, prklen) != 1 - || hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 - || hmac_update(&hmac_ctx, &counter, 1) != 1 - || hmac_finish(&hmac_ctx, T, &len) != 1) { - error_print(); - return -1; - } - counter++; - if (len > L) { - len = L; - } - memcpy(okm, T, len); - okm += len; - L -= len; - } - while (L > 0) { - if (counter == 0) { - error_print(); - return -1; - } - if (hmac_init(&hmac_ctx, digest, prk, prklen) != 1 - || hmac_update(&hmac_ctx, T, len) != 1 - || hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 - || hmac_update(&hmac_ctx, &counter, 1) != 1 - || hmac_finish(&hmac_ctx, T, &len) != 1) { - error_print(); - return -1; - } - counter++; - if (len > L) { - len = L; - } - memcpy(okm, T, len); - okm += len; - L -= len; - } - return 1; -} - -/* -int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen, - const uint8_t *ikm, size_t ikmlen, - uint8_t *prk, size_t *prklen) -{ - SM3_HMAC_CTX hmac_ctx; - - if (!salt || saltlen == 0) { - uint8_t zeros[SM3_HMAC_SIZE] = {0}; - if (sm3_hmac_init(&hmac_ctx, zeros, SM3_HMAC_SIZE) != 1) { - error_print(); - return -1; - } - } else { - if (sm3_hmac_init(&hmac_ctx, salt, saltlen) != 1) { - error_print(); - return -1; - } - } - - if (sm3_hmac_update(&hmac_ctx, ikm, ikmlen) != 1 - || sm3_hmac_finish(&hmac_ctx, prk) != 1) { - error_print(); - return -1; - } - *prklen = SM3_HMAC_SIZE; - return 1; -} - -int sm3_hkdf_expand(const uint8_t *prk, size_t prklen, - const uint8_t *opt_info, size_t opt_infolen, - size_t L, uint8_t *okm) -{ - SM3_HMAC_CTX hmac_ctx; - uint8_t T[SM3_HMAC_SIZE]; - uint8_t counter = 0x01; - size_t len; - - if (L > 0) { - if (sm3_hmac_init(&hmac_ctx, prk, prklen) != 1 - || sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 - || sm3_hmac_update(&hmac_ctx, &counter, 1) != 1 - || sm3_hmac_finish(&hmac_ctx, T) != 1) { - error_print(); - return -1; - } - counter++; - len = SM3_HMAC_SIZE; - if (len > L) { - len = L; - } - memcpy(okm, T, len); - okm += len; - L -= len; - } - while (L > 0) { - if (counter == 0) { - error_print(); - return -1; - } - if (sm3_hmac_init(&hmac_ctx, digest, prk, prklen) != 1 - || sm3_hmac_update(&hmac_ctx, T, len) != 1 - || sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 - || sm3_hmac_update(&hmac_ctx, &counter, 1) != 1 - || sm3_hmac_finish(&hmac_ctx, T) != 1) { - error_print(); - return -1; - } - counter++; - len = SM3_HMAC_SIZE; - if (len > L) { - len = L; - } - memcpy(okm, T, len); - okm += len; - L -= len; - } - return 1; -} -*/ + + + +#include +#include +#include +#include +#include +#include + +/* + +HKDF-Extract(salt, IKM) -> PRK + + salt optional, len(salt) == hash_len is recommended + IKM input key material + PRK output pseudorandom key, len(PRK) = hashLen + + PRK = HMAC_hash(salt, IKM) + salt as key? + + +HKDF-Expand(PRK, info, L) -> OKM + info optional + L output length, L <= 255 * hashLen + OKM output key + + + N = (L + hashLen - 1)//hashLen + T = T(1) || T(2) || ... | T(N) + OKM = T[0..L-1] + + T(0) = empty string (len = 0) + T(1) = HMAC_hash(PRK, T(0) | info | 0x01) + T(2) = HMAC_hash(PRK, T(1) | info | 0x02) + T(3) = HMAC_hash(PRK, T(2) | info | 0x03) + ... + + +*/ + +int hkdf_extract(const DIGEST *digest, const uint8_t *salt, size_t saltlen, + const uint8_t *ikm, size_t ikmlen, + uint8_t *prk, size_t *prklen) +{ + HMAC_CTX hmac_ctx; + + if (!salt || saltlen == 0) { + uint8_t zeros[DIGEST_MAX_SIZE] = {0}; + if (hmac_init(&hmac_ctx, digest, zeros, digest->digest_size) != 1) { + error_print(); + return -1; + } + } else { + if (hmac_init(&hmac_ctx, digest, salt, saltlen) != 1) { + error_print(); + return -1; + } + } + + if (hmac_update(&hmac_ctx, ikm, ikmlen) != 1 + || hmac_finish(&hmac_ctx, prk, prklen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen, + const uint8_t *opt_info, size_t opt_infolen, + size_t L, uint8_t *okm) +{ + HMAC_CTX hmac_ctx; + uint8_t T[HMAC_MAX_SIZE]; + uint8_t counter = 0x01; + size_t len; + + if (L > 0) { + if (hmac_init(&hmac_ctx, digest, prk, prklen) != 1 + || hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 + || hmac_update(&hmac_ctx, &counter, 1) != 1 + || hmac_finish(&hmac_ctx, T, &len) != 1) { + error_print(); + return -1; + } + counter++; + if (len > L) { + len = L; + } + memcpy(okm, T, len); + okm += len; + L -= len; + } + while (L > 0) { + if (counter == 0) { + error_print(); + return -1; + } + if (hmac_init(&hmac_ctx, digest, prk, prklen) != 1 + || hmac_update(&hmac_ctx, T, len) != 1 + || hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 + || hmac_update(&hmac_ctx, &counter, 1) != 1 + || hmac_finish(&hmac_ctx, T, &len) != 1) { + error_print(); + return -1; + } + counter++; + if (len > L) { + len = L; + } + memcpy(okm, T, len); + okm += len; + L -= len; + } + return 1; +} + +/* +int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen, + const uint8_t *ikm, size_t ikmlen, + uint8_t *prk, size_t *prklen) +{ + SM3_HMAC_CTX hmac_ctx; + + if (!salt || saltlen == 0) { + uint8_t zeros[SM3_HMAC_SIZE] = {0}; + if (sm3_hmac_init(&hmac_ctx, zeros, SM3_HMAC_SIZE) != 1) { + error_print(); + return -1; + } + } else { + if (sm3_hmac_init(&hmac_ctx, salt, saltlen) != 1) { + error_print(); + return -1; + } + } + + if (sm3_hmac_update(&hmac_ctx, ikm, ikmlen) != 1 + || sm3_hmac_finish(&hmac_ctx, prk) != 1) { + error_print(); + return -1; + } + *prklen = SM3_HMAC_SIZE; + return 1; +} + +int sm3_hkdf_expand(const uint8_t *prk, size_t prklen, + const uint8_t *opt_info, size_t opt_infolen, + size_t L, uint8_t *okm) +{ + SM3_HMAC_CTX hmac_ctx; + uint8_t T[SM3_HMAC_SIZE]; + uint8_t counter = 0x01; + size_t len; + + if (L > 0) { + if (sm3_hmac_init(&hmac_ctx, prk, prklen) != 1 + || sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 + || sm3_hmac_update(&hmac_ctx, &counter, 1) != 1 + || sm3_hmac_finish(&hmac_ctx, T) != 1) { + error_print(); + return -1; + } + counter++; + len = SM3_HMAC_SIZE; + if (len > L) { + len = L; + } + memcpy(okm, T, len); + okm += len; + L -= len; + } + while (L > 0) { + if (counter == 0) { + error_print(); + return -1; + } + if (sm3_hmac_init(&hmac_ctx, digest, prk, prklen) != 1 + || sm3_hmac_update(&hmac_ctx, T, len) != 1 + || sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0 + || sm3_hmac_update(&hmac_ctx, &counter, 1) != 1 + || sm3_hmac_finish(&hmac_ctx, T) != 1) { + error_print(); + return -1; + } + counter++; + len = SM3_HMAC_SIZE; + if (len > L) { + len = L; + } + memcpy(okm, T, len); + okm += len; + L -= len; + } + return 1; +} +*/ diff --git a/src/hmac.c b/src/hmac.c index 798461e1..c595688c 100644 --- a/src/hmac.c +++ b/src/hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,123 +7,124 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include - - -#define IPAD 0x36 -#define OPAD 0x5C - - -int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen) -{ - uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0}; - uint8_t o_key[DIGEST_MAX_BLOCK_SIZE] = {0}; - size_t blocksize; - int i; - - if (!ctx || !digest || !key || !keylen) { - error_print(); - return -1; - } - - ctx->digest = digest; - - blocksize = digest->block_size; - if (keylen <= blocksize) { - memcpy(i_key, key, keylen); - memcpy(o_key, key, keylen); - } else { - digest_init(&ctx->digest_ctx, digest); - digest_update(&ctx->digest_ctx, key, keylen); - digest_finish(&ctx->digest_ctx, i_key, &keylen); - memcpy(o_key, i_key, keylen); - } - for (i = 0; i < blocksize; i++) { - i_key[i] ^= IPAD; - o_key[i] ^= OPAD; - } - - digest_init(&ctx->i_ctx, digest); - digest_update(&ctx->i_ctx, i_key, blocksize); - digest_init(&ctx->o_ctx, digest); - digest_update(&ctx->o_ctx, o_key, blocksize); - memcpy(&ctx->digest_ctx, &ctx->i_ctx, sizeof(DIGEST_CTX)); - - memset(i_key, 0, sizeof(i_key)); - memset(o_key, 0, sizeof(o_key)); - return 1; -} - -int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen) -{ - if (ctx == NULL) { - error_print(); - return -1; - } - if (data == NULL || datalen == 0) { - return 0; - } - if (digest_update(&ctx->digest_ctx, data, datalen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen) -{ - if (ctx == NULL || maclen == NULL) { - error_print(); - return -1; - } - if (digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { - error_print(); - return -1; - } - memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX)); - if (digest_update(&ctx->digest_ctx, mac, *maclen) != 1 - || digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int hmac_finish_and_verify(HMAC_CTX *ctx, const uint8_t *mac, size_t maclen) -{ - uint8_t hmac[64]; - size_t hmaclen; - - if (hmac_finish(ctx, hmac, &hmaclen) != 1) { - error_print(); - return -1; - } - if (maclen != hmaclen - || memcmp(hmac, mac, maclen) != 0) { - error_print(); - return -1; - } - return 1; -} - -int hmac(const DIGEST *digest, const uint8_t *key, size_t keylen, - const uint8_t *data, size_t datalen, - uint8_t *mac, size_t *maclen) -{ - int ret = 0; - HMAC_CTX ctx; - - if (hmac_init(&ctx, digest, key, keylen) != 1 - || hmac_update(&ctx, data, datalen) != 1 - || hmac_finish(&ctx, mac, maclen) != 1) { - goto end; - } - ret = 1; - -end: - memset(&ctx, 0, sizeof(ctx)); - return ret; -} + + +#include +#include +#include + + +#define IPAD 0x36 +#define OPAD 0x5C + + +int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const uint8_t *key, size_t keylen) +{ + uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0}; + uint8_t o_key[DIGEST_MAX_BLOCK_SIZE] = {0}; + size_t blocksize; + int i; + + if (!ctx || !digest || !key || !keylen) { + error_print(); + return -1; + } + + ctx->digest = digest; + + blocksize = digest->block_size; + if (keylen <= blocksize) { + memcpy(i_key, key, keylen); + memcpy(o_key, key, keylen); + } else { + digest_init(&ctx->digest_ctx, digest); + digest_update(&ctx->digest_ctx, key, keylen); + digest_finish(&ctx->digest_ctx, i_key, &keylen); + memcpy(o_key, i_key, keylen); + } + for (i = 0; i < blocksize; i++) { + i_key[i] ^= IPAD; + o_key[i] ^= OPAD; + } + + digest_init(&ctx->i_ctx, digest); + digest_update(&ctx->i_ctx, i_key, blocksize); + digest_init(&ctx->o_ctx, digest); + digest_update(&ctx->o_ctx, o_key, blocksize); + memcpy(&ctx->digest_ctx, &ctx->i_ctx, sizeof(DIGEST_CTX)); + + memset(i_key, 0, sizeof(i_key)); + memset(o_key, 0, sizeof(o_key)); + return 1; +} + +int hmac_update(HMAC_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (ctx == NULL) { + error_print(); + return -1; + } + if (data == NULL || datalen == 0) { + return 0; + } + if (digest_update(&ctx->digest_ctx, data, datalen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int hmac_finish(HMAC_CTX *ctx, uint8_t *mac, size_t *maclen) +{ + if (ctx == NULL || maclen == NULL) { + error_print(); + return -1; + } + if (digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { + error_print(); + return -1; + } + memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX)); + if (digest_update(&ctx->digest_ctx, mac, *maclen) != 1 + || digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int hmac_finish_and_verify(HMAC_CTX *ctx, const uint8_t *mac, size_t maclen) +{ + uint8_t hmac[64]; + size_t hmaclen; + + if (hmac_finish(ctx, hmac, &hmaclen) != 1) { + error_print(); + return -1; + } + if (maclen != hmaclen + || memcmp(hmac, mac, maclen) != 0) { + error_print(); + return -1; + } + return 1; +} + +int hmac(const DIGEST *digest, const uint8_t *key, size_t keylen, + const uint8_t *data, size_t datalen, + uint8_t *mac, size_t *maclen) +{ + int ret = 0; + HMAC_CTX ctx; + + if (hmac_init(&ctx, digest, key, keylen) != 1 + || hmac_update(&ctx, data, datalen) != 1 + || hmac_finish(&ctx, mac, maclen) != 1) { + goto end; + } + ret = 1; + +end: + memset(&ctx, 0, sizeof(ctx)); + return ret; +} diff --git a/src/md5.c b/src/md5.c index a833588e..544fad2f 100644 --- a/src/md5.c +++ b/src/md5.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,175 +7,176 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include - - -#define F(B, C, D) (((B) & (C)) | ((~(B)) & (D))) -#define G(B, C, D) (((B) & (D)) | ((C) & (~(D)))) -#define H(B, C, D) ((B) ^ (C) ^ (D)) -#define I(B, C, D) ((C) ^ ((B) | (~(D)))) - -static const uint32_t K[] = { - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, -}; - -static const int S[] = { - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, -}; - -static void md5_compress_blocks(uint32_t state[4], - const unsigned char *data, size_t blocks) -{ - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - uint32_t T; - uint32_t W[16]; - int g, i; - - while (blocks--) { - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - - for (i = 0; i < 16; i++) { - W[i] = GETU32_LE(data); - data += sizeof(uint32_t); - } - - for (i = 0; i < 16; i++) { - T = ROL32(A + F(B, C, D) + W[i] + K[i], S[i]) + B; - A = D; - D = C; - C = B; - B = T; - } - for (; i < 32; i++) { - g = (5 * i + 1) % 16; - T = ROL32(A + G(B, C, D) + W[g] + K[i], S[i]) + B; - A = D; - D = C; - C = B; - B = T; - } - for (; i < 48; i++) { - g = (3 * i + 5) % 16; - T = ROL32(A + H(B, C, D) + W[g] + K[i], S[i]) + B; - A = D; - D = C; - C = B; - B = T; - } - for (; i < 64; i++) { - g = (7 * i) % 16; - T = ROL32(A + I(B, C, D) + W[g] + K[i], S[i]) + B; - A = D; - D = C; - C = B; - B = T; - } - - state[0] += A; - state[1] += B; - state[2] += C; - state[3] += D; - } -} - -void md5_init(MD5_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xefcdab89; - ctx->state[2] = 0x98badcfe; - ctx->state[3] = 0x10325476; -} - -void md5_update(MD5_CTX *ctx, const unsigned char *data, size_t datalen) -{ - size_t blocks; - - ctx->num &= 0x3f; - if (ctx->num) { - size_t left = MD5_BLOCK_SIZE - ctx->num; - if (datalen < left) { - memcpy(ctx->block + ctx->num, data, datalen); - ctx->num += datalen; - return; - } else { - memcpy(ctx->block + ctx->num, data, left); - md5_compress_blocks(ctx->state, ctx->block, 1); - ctx->nblocks++; - data += left; - datalen -= left; - } - } - - blocks = datalen / MD5_BLOCK_SIZE; - md5_compress_blocks(ctx->state, data, blocks); - ctx->nblocks += blocks; - data += MD5_BLOCK_SIZE * blocks; - datalen -= MD5_BLOCK_SIZE * blocks; - - ctx->num = datalen; - if (datalen) { - memcpy(ctx->block, data, datalen); - } -} - -void md5_finish(MD5_CTX *ctx, unsigned char *dgst) -{ - int i; - - ctx->num &= 0x3f; - ctx->block[ctx->num] = 0x80; - - if (ctx->num <= MD5_BLOCK_SIZE - 9) { - memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 9); - } else { - memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 1); - md5_compress_blocks(ctx->state, ctx->block, 1); - memset(ctx->block, 0, MD5_BLOCK_SIZE - 8); - } - PUTU64_LE(ctx->block + 56, (ctx->nblocks << 9) + (ctx->num << 3)); - md5_compress_blocks(ctx->state, ctx->block, 1); - for (i = 0; i < 4; i++) { - PUTU32_LE(dgst, ctx->state[i]); - dgst += sizeof(uint32_t); - } - memset(ctx, 0, sizeof(*ctx)); -} - -void md5_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[MD5_DIGEST_SIZE]) -{ - MD5_CTX ctx; - md5_init(&ctx); - md5_update(&ctx, data, datalen); - md5_finish(&ctx, dgst); -} + + + +#include +#include +#include + + +#define F(B, C, D) (((B) & (C)) | ((~(B)) & (D))) +#define G(B, C, D) (((B) & (D)) | ((C) & (~(D)))) +#define H(B, C, D) ((B) ^ (C) ^ (D)) +#define I(B, C, D) ((C) ^ ((B) | (~(D)))) + +static const uint32_t K[] = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +static const int S[] = { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, +}; + +static void md5_compress_blocks(uint32_t state[4], + const unsigned char *data, size_t blocks) +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t T; + uint32_t W[16]; + int g, i; + + while (blocks--) { + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + for (i = 0; i < 16; i++) { + W[i] = GETU32_LE(data); + data += sizeof(uint32_t); + } + + for (i = 0; i < 16; i++) { + T = ROL32(A + F(B, C, D) + W[i] + K[i], S[i]) + B; + A = D; + D = C; + C = B; + B = T; + } + for (; i < 32; i++) { + g = (5 * i + 1) % 16; + T = ROL32(A + G(B, C, D) + W[g] + K[i], S[i]) + B; + A = D; + D = C; + C = B; + B = T; + } + for (; i < 48; i++) { + g = (3 * i + 5) % 16; + T = ROL32(A + H(B, C, D) + W[g] + K[i], S[i]) + B; + A = D; + D = C; + C = B; + B = T; + } + for (; i < 64; i++) { + g = (7 * i) % 16; + T = ROL32(A + I(B, C, D) + W[g] + K[i], S[i]) + B; + A = D; + D = C; + C = B; + B = T; + } + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + } +} + +void md5_init(MD5_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; +} + +void md5_update(MD5_CTX *ctx, const unsigned char *data, size_t datalen) +{ + size_t blocks; + + ctx->num &= 0x3f; + if (ctx->num) { + size_t left = MD5_BLOCK_SIZE - ctx->num; + if (datalen < left) { + memcpy(ctx->block + ctx->num, data, datalen); + ctx->num += datalen; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + md5_compress_blocks(ctx->state, ctx->block, 1); + ctx->nblocks++; + data += left; + datalen -= left; + } + } + + blocks = datalen / MD5_BLOCK_SIZE; + md5_compress_blocks(ctx->state, data, blocks); + ctx->nblocks += blocks; + data += MD5_BLOCK_SIZE * blocks; + datalen -= MD5_BLOCK_SIZE * blocks; + + ctx->num = datalen; + if (datalen) { + memcpy(ctx->block, data, datalen); + } +} + +void md5_finish(MD5_CTX *ctx, unsigned char *dgst) +{ + int i; + + ctx->num &= 0x3f; + ctx->block[ctx->num] = 0x80; + + if (ctx->num <= MD5_BLOCK_SIZE - 9) { + memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 9); + } else { + memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 1); + md5_compress_blocks(ctx->state, ctx->block, 1); + memset(ctx->block, 0, MD5_BLOCK_SIZE - 8); + } + PUTU64_LE(ctx->block + 56, (ctx->nblocks << 9) + (ctx->num << 3)); + md5_compress_blocks(ctx->state, ctx->block, 1); + for (i = 0; i < 4; i++) { + PUTU32_LE(dgst, ctx->state[i]); + dgst += sizeof(uint32_t); + } + memset(ctx, 0, sizeof(*ctx)); +} + +void md5_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[MD5_DIGEST_SIZE]) +{ + MD5_CTX ctx; + md5_init(&ctx); + md5_update(&ctx, data, datalen); + md5_finish(&ctx, dgst); +} diff --git a/src/pbkdf2.c b/src/pbkdf2.c index b8093b8b..bc59ece9 100644 --- a/src/pbkdf2.c +++ b/src/pbkdf2.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,182 +7,183 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -/* - PBKDF2 (P, S, c, dkLen) - - Options: PRF underlying pseudorandom function (hLen - denotes the length in octets of the - pseudorandom function output) - - Input: P password, an octet string - S salt, an octet string - c iteration count, a positive integer - dkLen intended length in octets of the derived - key, a positive integer, at most - (2^32 - 1) * hLen - - Output: DK derived key, a dkLen-octet string - - Steps: - - 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and - stop. - - 2. Let l be the number of hLen-octet blocks in the derived key, - rounding up, and let r be the number of octets in the last - block: - - l = CEIL (dkLen / hLen) , - r = dkLen - (l - 1) * hLen . - - Here, CEIL (x) is the "ceiling" function, i.e. the smallest - integer greater than, or equal to, x. - - 3. For each block of the derived key apply the function F defined - below to the password P, the salt S, the iteration count c, and - the block index to compute the block: - - T_1 = F (P, S, c, 1) , - T_2 = F (P, S, c, 2) , - ... - T_l = F (P, S, c, l) , - - where the function F is defined as the exclusive-or sum of the - first c iterates of the underlying pseudorandom function PRF - applied to the password P and the concatenation of the salt S - and the block index i: - - F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c - - where - - U_1 = PRF (P, S || INT (i)) , - U_2 = PRF (P, U_1) , - ... - U_c = PRF (P, U_{c-1}) . - - Here, INT (i) is a four-octet encoding of the integer i, most - significant octet first. - - 4. Concatenate the blocks and extract the first dkLen octets to - produce a derived key DK: - - DK = T_1 || T_2 || ... || T_l<0..r-1> - - 5. Output the derived key DK. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int pbkdf2_genkey(const DIGEST *digest, - const char *pass, size_t passlen, - const uint8_t *salt, size_t saltlen, size_t count, - size_t outlen, uint8_t *out) -{ - HMAC_CTX ctx; - HMAC_CTX ctx_tmpl; - uint32_t iter = 1; - uint8_t iter_be[4]; - uint8_t tmp_block[64]; - uint8_t key_block[64]; - size_t len; - - hmac_init(&ctx_tmpl, digest, (uint8_t *)pass, passlen); - - while (outlen > 0) { - size_t i; - - PUTU32(iter_be, iter); - iter++; - - ctx = ctx_tmpl; - hmac_update(&ctx, salt, saltlen); - hmac_update(&ctx, iter_be, sizeof(iter_be)); - hmac_finish(&ctx, tmp_block, &len); - memcpy(key_block, tmp_block, len); - - for (i = 1; i < count; i++) { - ctx = ctx_tmpl; - hmac_update(&ctx, tmp_block, len); - hmac_finish(&ctx, tmp_block, &len); - memxor(key_block, tmp_block, len); - } - - if (outlen < len) { - memcpy(out, key_block, outlen); - out += outlen; - outlen = 0; - } else { - memcpy(out, key_block, len); - out += len; - outlen -= len; - } - } - - memset(&ctx, 0, sizeof(ctx)); - memset(key_block, 0, sizeof(key_block)); - memset(tmp_block, 0, sizeof(key_block)); - return 1; -} - -int pbkdf2_hmac_sm3_genkey( - const char *pass, size_t passlen, - const uint8_t *salt, size_t saltlen, size_t count, - size_t outlen, uint8_t *out) -{ - SM3_HMAC_CTX ctx; - SM3_HMAC_CTX ctx_tmpl; - uint32_t iter = 1; - uint8_t iter_be[4]; - uint8_t tmp_block[SM3_DIGEST_SIZE]; - uint8_t key_block[SM3_DIGEST_SIZE]; - size_t len; - - sm3_hmac_init(&ctx_tmpl, (uint8_t *)pass, passlen); - - while (outlen > 0) { - size_t i; - - PUTU32(iter_be, iter); - iter++; - - ctx = ctx_tmpl; - sm3_hmac_update(&ctx, salt, saltlen); - sm3_hmac_update(&ctx, iter_be, sizeof(iter_be)); - sm3_hmac_finish(&ctx, tmp_block); - memcpy(key_block, tmp_block, SM3_DIGEST_SIZE); - - for (i = 1; i < count; i++) { - ctx = ctx_tmpl; - sm3_hmac_update(&ctx, tmp_block, SM3_DIGEST_SIZE); - sm3_hmac_finish(&ctx, tmp_block); - memxor(key_block, tmp_block, SM3_DIGEST_SIZE); - } - - if (outlen < SM3_DIGEST_SIZE) { - memcpy(out, key_block, outlen); - out += outlen; - outlen = 0; - } else { - memcpy(out, key_block, SM3_DIGEST_SIZE); - out += len; - outlen -= len; - } - } - - memset(&ctx, 0, sizeof(ctx)); - memset(key_block, 0, sizeof(key_block)); - memset(tmp_block, 0, sizeof(key_block)); - return 1; -} + + + +/* + PBKDF2 (P, S, c, dkLen) + + Options: PRF underlying pseudorandom function (hLen + denotes the length in octets of the + pseudorandom function output) + + Input: P password, an octet string + S salt, an octet string + c iteration count, a positive integer + dkLen intended length in octets of the derived + key, a positive integer, at most + (2^32 - 1) * hLen + + Output: DK derived key, a dkLen-octet string + + Steps: + + 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and + stop. + + 2. Let l be the number of hLen-octet blocks in the derived key, + rounding up, and let r be the number of octets in the last + block: + + l = CEIL (dkLen / hLen) , + r = dkLen - (l - 1) * hLen . + + Here, CEIL (x) is the "ceiling" function, i.e. the smallest + integer greater than, or equal to, x. + + 3. For each block of the derived key apply the function F defined + below to the password P, the salt S, the iteration count c, and + the block index to compute the block: + + T_1 = F (P, S, c, 1) , + T_2 = F (P, S, c, 2) , + ... + T_l = F (P, S, c, l) , + + where the function F is defined as the exclusive-or sum of the + first c iterates of the underlying pseudorandom function PRF + applied to the password P and the concatenation of the salt S + and the block index i: + + F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c + + where + + U_1 = PRF (P, S || INT (i)) , + U_2 = PRF (P, U_1) , + ... + U_c = PRF (P, U_{c-1}) . + + Here, INT (i) is a four-octet encoding of the integer i, most + significant octet first. + + 4. Concatenate the blocks and extract the first dkLen octets to + produce a derived key DK: + + DK = T_1 || T_2 || ... || T_l<0..r-1> + + 5. Output the derived key DK. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int pbkdf2_genkey(const DIGEST *digest, + const char *pass, size_t passlen, + const uint8_t *salt, size_t saltlen, size_t count, + size_t outlen, uint8_t *out) +{ + HMAC_CTX ctx; + HMAC_CTX ctx_tmpl; + uint32_t iter = 1; + uint8_t iter_be[4]; + uint8_t tmp_block[64]; + uint8_t key_block[64]; + size_t len; + + hmac_init(&ctx_tmpl, digest, (uint8_t *)pass, passlen); + + while (outlen > 0) { + size_t i; + + PUTU32(iter_be, iter); + iter++; + + ctx = ctx_tmpl; + hmac_update(&ctx, salt, saltlen); + hmac_update(&ctx, iter_be, sizeof(iter_be)); + hmac_finish(&ctx, tmp_block, &len); + memcpy(key_block, tmp_block, len); + + for (i = 1; i < count; i++) { + ctx = ctx_tmpl; + hmac_update(&ctx, tmp_block, len); + hmac_finish(&ctx, tmp_block, &len); + memxor(key_block, tmp_block, len); + } + + if (outlen < len) { + memcpy(out, key_block, outlen); + out += outlen; + outlen = 0; + } else { + memcpy(out, key_block, len); + out += len; + outlen -= len; + } + } + + memset(&ctx, 0, sizeof(ctx)); + memset(key_block, 0, sizeof(key_block)); + memset(tmp_block, 0, sizeof(key_block)); + return 1; +} + +int pbkdf2_hmac_sm3_genkey( + const char *pass, size_t passlen, + const uint8_t *salt, size_t saltlen, size_t count, + size_t outlen, uint8_t *out) +{ + SM3_HMAC_CTX ctx; + SM3_HMAC_CTX ctx_tmpl; + uint32_t iter = 1; + uint8_t iter_be[4]; + uint8_t tmp_block[SM3_DIGEST_SIZE]; + uint8_t key_block[SM3_DIGEST_SIZE]; + size_t len; + + sm3_hmac_init(&ctx_tmpl, (uint8_t *)pass, passlen); + + while (outlen > 0) { + size_t i; + + PUTU32(iter_be, iter); + iter++; + + ctx = ctx_tmpl; + sm3_hmac_update(&ctx, salt, saltlen); + sm3_hmac_update(&ctx, iter_be, sizeof(iter_be)); + sm3_hmac_finish(&ctx, tmp_block); + memcpy(key_block, tmp_block, SM3_DIGEST_SIZE); + + for (i = 1; i < count; i++) { + ctx = ctx_tmpl; + sm3_hmac_update(&ctx, tmp_block, SM3_DIGEST_SIZE); + sm3_hmac_finish(&ctx, tmp_block); + memxor(key_block, tmp_block, SM3_DIGEST_SIZE); + } + + if (outlen < SM3_DIGEST_SIZE) { + memcpy(out, key_block, outlen); + out += outlen; + outlen = 0; + } else { + memcpy(out, key_block, SM3_DIGEST_SIZE); + out += len; + outlen -= len; + } + } + + memset(&ctx, 0, sizeof(ctx)); + memset(key_block, 0, sizeof(key_block)); + memset(tmp_block, 0, sizeof(key_block)); + return 1; +} diff --git a/src/pem.c b/src/pem.c index aaefa393..98989459 100644 --- a/src/pem.c +++ b/src/pem.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,85 +7,86 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -int pem_write(FILE *fp, const char *name, const uint8_t *data, size_t datalen) -{ - int ret = 0; - BASE64_CTX ctx; - uint8_t b64[datalen * 2]; - int len; - - base64_encode_init(&ctx); - base64_encode_update(&ctx, data, (int)datalen, b64, &len); - base64_encode_finish(&ctx, b64 + len, &len); - - ret += fprintf(fp, "-----BEGIN %s-----\n", name); - ret += fprintf(fp, "%s", (char *)b64); - ret += fprintf(fp, "-----END %s-----\n", name); - //return ret; - return 1; -} - -int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen, size_t maxlen) -{ - char line[80]; - char begin_line[80]; - char end_line[80]; - int len; - BASE64_CTX ctx; - - snprintf(begin_line, sizeof(begin_line), "-----BEGIN %s-----\n", name); - snprintf(end_line, sizeof(end_line), "-----END %s-----\n", name); - - if (feof(fp)) { - return 0; - } - - if (!fgets(line, sizeof(line), fp)) { - if (feof(fp)) - return 0; - else { - error_print(); - return -1; - } - } - - if (strcmp(line, begin_line) != 0) { - // FIXME: 这里是不是应该容忍一些错误呢? - - fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, line); - fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, begin_line); - - error_print(); - return -1; - } - - *datalen = 0; - - base64_decode_init(&ctx); - - for (;;) { - if (!fgets(line, sizeof(line), fp)) { - error_print(); - return -1; - } - if (strcmp(line, end_line) == 0) { - break; - } - - base64_decode_update(&ctx, (uint8_t *)line, strlen(line), data, &len); - data += len; - *datalen += len; - } - - base64_decode_finish(&ctx, data, &len); - *datalen += len; - return 1; -} + + +#include +#include +#include +#include +#include + + +int pem_write(FILE *fp, const char *name, const uint8_t *data, size_t datalen) +{ + int ret = 0; + BASE64_CTX ctx; + uint8_t b64[datalen * 2]; + int len; + + base64_encode_init(&ctx); + base64_encode_update(&ctx, data, (int)datalen, b64, &len); + base64_encode_finish(&ctx, b64 + len, &len); + + ret += fprintf(fp, "-----BEGIN %s-----\n", name); + ret += fprintf(fp, "%s", (char *)b64); + ret += fprintf(fp, "-----END %s-----\n", name); + //return ret; + return 1; +} + +int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen, size_t maxlen) +{ + char line[80]; + char begin_line[80]; + char end_line[80]; + int len; + BASE64_CTX ctx; + + snprintf(begin_line, sizeof(begin_line), "-----BEGIN %s-----\n", name); + snprintf(end_line, sizeof(end_line), "-----END %s-----\n", name); + + if (feof(fp)) { + return 0; + } + + if (!fgets(line, sizeof(line), fp)) { + if (feof(fp)) + return 0; + else { + error_print(); + return -1; + } + } + + if (strcmp(line, begin_line) != 0) { + // FIXME: 这里是不是应该容忍一些错误呢? + + fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, line); + fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, begin_line); + + error_print(); + return -1; + } + + *datalen = 0; + + base64_decode_init(&ctx); + + for (;;) { + if (!fgets(line, sizeof(line), fp)) { + error_print(); + return -1; + } + if (strcmp(line, end_line) == 0) { + break; + } + + base64_decode_update(&ctx, (uint8_t *)line, strlen(line), data, &len); + data += len; + *datalen += len; + } + + base64_decode_finish(&ctx, data, &len); + *datalen += len; + return 1; +} diff --git a/src/pkcs8.c b/src/pkcs8.c index 6296f378..3769a5f9 100644 --- a/src/pkcs8.c +++ b/src/pkcs8.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,449 +7,450 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const uint32_t oid_hmac_sm3[] = { oid_sm_algors,401,2 }; -static const size_t oid_hmac_sm3_cnt = sizeof(oid_hmac_sm3)/sizeof(oid_hmac_sm3[0]); - -char *pbkdf2_prf_name(int oid) -{ - switch (oid) { - case OID_hmac_sm3: return "hmac-sm3"; - } - return NULL; -} - -int pbkdf2_prf_from_name(const char *name) -{ - if (strcmp(name, "hmac-sm3") == 0) { - return OID_hmac_sm3; - } - return 0; -} - -int pbkdf2_prf_to_der(int oid, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (oid == -1) - return 0; - - if (oid != OID_hmac_sm3) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbkdf2_prf_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - uint32_t nodes[32]; - size_t nodes_cnt; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid_hmac_sm3, oid_hmac_sm3_cnt) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - *oid = OID_hmac_sm3; - return 1; -} - -int pbkdf2_params_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_octet_string_to_der(salt, saltlen, NULL, &len) != 1 - || asn1_int_to_der(iter, NULL, &len) != 1 - || asn1_int_to_der(keylen, NULL, &len) < 0 - || pbkdf2_prf_to_der(prf, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_octet_string_to_der(salt, saltlen, out, outlen) != 1 - || asn1_int_to_der(iter, out, outlen) != 1 - || asn1_int_to_der(keylen, out, outlen) < 0 - || pbkdf2_prf_to_der(prf, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int pbkdf2_params_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_octet_string_from_der(salt, saltlen, &d, &dlen) != 1 - || asn1_int_from_der(iter, &d, &dlen) != 1 - || asn1_int_from_der(keylen, &d, &dlen) < 0 - || pbkdf2_prf_from_der(prf, &d, &dlen) < 0 - || asn1_check(*saltlen > 0) != 1 - || asn1_check(*iter > 0) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - int val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "salt", p, len); - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "iterationCount: %d\n", val); - if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "keyLength: %d\n", val); - if ((ret = pbkdf2_prf_from_der(&val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "prf: %s\n", pbkdf2_prf_name(val)); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -static const uint32_t oid_pbkdf2[] = { oid_pkcs5,12 }; -static const size_t oid_pbkdf2_cnt = sizeof(oid_pbkdf2)/sizeof(oid_pbkdf2[0]); - -int pbkdf2_algor_to_der( - const uint8_t *salt, size_t saltlen, - int iter, - int keylen, - int prf, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, NULL, &len) != 1 - || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, out, outlen) != 1 - || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbkdf2_algor_from_der( - const uint8_t **salt, size_t *saltlen, - int *iter, - int *keylen, - int *prf, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - uint32_t nodes[32]; - size_t nodes_cnt; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1 - || pbkdf2_params_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "algorithm: %s\n", "pbkdf2"); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - pbkdf2_params_print(fp, fmt, ind, "parameters", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int pbes2_enc_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) -{ - if (oid != OID_sm4_cbc) { - error_print(); - return -1; - } - if (x509_encryption_algor_to_der(oid, iv, ivlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_enc_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) -{ - int ret; - if ((ret = x509_encryption_algor_from_der(oid, iv, ivlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (*oid != OID_sm4_cbc) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return x509_encryption_algor_print(fp, fmt, ind, label, d, dlen); -} - -int pbes2_params_to_der( - const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, - int cipher, const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 - || pbes2_enc_algor_to_der(cipher, iv, ivlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1 - || pbes2_enc_algor_to_der(cipher, iv, ivlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_params_from_der( - const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, - int *cipher, const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (pbkdf2_algor_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 - || pbes2_enc_algor_from_der(cipher, iv, ivlen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - pbkdf2_algor_print(fp, fmt, ind, "keyDerivationFunc", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - pbes2_enc_algor_print(fp, fmt, ind, "encryptionScheme", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - - -static const uint32_t oid_pbes2[] = { oid_pkcs5,13 }; -static const size_t oid_pbes2_cnt = sizeof(oid_pbes2)/sizeof(oid_pbes2[0]); - -int pbes2_algor_to_der( - const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, - int cipher, const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, NULL, &len) != 1 - || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, out, outlen) != 1 - || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_algor_from_der( - const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, - int *cipher, const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - int oid; - uint32_t nodes[32]; - size_t nodes_cnt; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1 - || pbes2_params_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1) - goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", "pbes2"); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - pbes2_params_print(fp, fmt, ind, "parameters", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int pkcs8_enced_private_key_info_to_der( - const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, - int cipher, const uint8_t *iv, size_t ivlen, - const uint8_t *enced, size_t encedlen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 - || asn1_octet_string_to_der(enced, encedlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1 - || asn1_octet_string_to_der(enced, encedlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pkcs8_enced_private_key_info_from_der( - const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, - int *cipher, const uint8_t **iv, size_t *ivlen, - const uint8_t **enced, size_t *encedlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (pbes2_algor_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 - || asn1_octet_string_from_der(enced, encedlen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - pbes2_algor_print(fp, fmt, ind, "encryptionAlgorithm", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "encryptedData", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const uint32_t oid_hmac_sm3[] = { oid_sm_algors,401,2 }; +static const size_t oid_hmac_sm3_cnt = sizeof(oid_hmac_sm3)/sizeof(oid_hmac_sm3[0]); + +char *pbkdf2_prf_name(int oid) +{ + switch (oid) { + case OID_hmac_sm3: return "hmac-sm3"; + } + return NULL; +} + +int pbkdf2_prf_from_name(const char *name) +{ + if (strcmp(name, "hmac-sm3") == 0) { + return OID_hmac_sm3; + } + return 0; +} + +int pbkdf2_prf_to_der(int oid, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (oid == -1) + return 0; + + if (oid != OID_hmac_sm3) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbkdf2_prf_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + uint32_t nodes[32]; + size_t nodes_cnt; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_hmac_sm3, oid_hmac_sm3_cnt) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + *oid = OID_hmac_sm3; + return 1; +} + +int pbkdf2_params_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_octet_string_to_der(salt, saltlen, NULL, &len) != 1 + || asn1_int_to_der(iter, NULL, &len) != 1 + || asn1_int_to_der(keylen, NULL, &len) < 0 + || pbkdf2_prf_to_der(prf, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_octet_string_to_der(salt, saltlen, out, outlen) != 1 + || asn1_int_to_der(iter, out, outlen) != 1 + || asn1_int_to_der(keylen, out, outlen) < 0 + || pbkdf2_prf_to_der(prf, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int pbkdf2_params_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_octet_string_from_der(salt, saltlen, &d, &dlen) != 1 + || asn1_int_from_der(iter, &d, &dlen) != 1 + || asn1_int_from_der(keylen, &d, &dlen) < 0 + || pbkdf2_prf_from_der(prf, &d, &dlen) < 0 + || asn1_check(*saltlen > 0) != 1 + || asn1_check(*iter > 0) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "salt", p, len); + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "iterationCount: %d\n", val); + if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "keyLength: %d\n", val); + if ((ret = pbkdf2_prf_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "prf: %s\n", pbkdf2_prf_name(val)); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +static const uint32_t oid_pbkdf2[] = { oid_pkcs5,12 }; +static const size_t oid_pbkdf2_cnt = sizeof(oid_pbkdf2)/sizeof(oid_pbkdf2[0]); + +int pbkdf2_algor_to_der( + const uint8_t *salt, size_t saltlen, + int iter, + int keylen, + int prf, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, NULL, &len) != 1 + || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, out, outlen) != 1 + || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbkdf2_algor_from_der( + const uint8_t **salt, size_t *saltlen, + int *iter, + int *keylen, + int *prf, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + uint32_t nodes[32]; + size_t nodes_cnt; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1 + || pbkdf2_params_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "algorithm: %s\n", "pbkdf2"); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbkdf2_params_print(fp, fmt, ind, "parameters", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int pbes2_enc_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen) +{ + if (oid != OID_sm4_cbc) { + error_print(); + return -1; + } + if (x509_encryption_algor_to_der(oid, iv, ivlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_enc_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen) +{ + int ret; + if ((ret = x509_encryption_algor_from_der(oid, iv, ivlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (*oid != OID_sm4_cbc) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + return x509_encryption_algor_print(fp, fmt, ind, label, d, dlen); +} + +int pbes2_params_to_der( + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1 + || pbes2_enc_algor_to_der(cipher, iv, ivlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1 + || pbes2_enc_algor_to_der(cipher, iv, ivlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_params_from_der( + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (pbkdf2_algor_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1 + || pbes2_enc_algor_from_der(cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbkdf2_algor_print(fp, fmt, ind, "keyDerivationFunc", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_enc_algor_print(fp, fmt, ind, "encryptionScheme", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + +static const uint32_t oid_pbes2[] = { oid_pkcs5,13 }; +static const size_t oid_pbes2_cnt = sizeof(oid_pbes2)/sizeof(oid_pbes2[0]); + +int pbes2_algor_to_der( + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, NULL, &len) != 1 + || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, out, outlen) != 1 + || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_algor_from_der( + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1 + || pbes2_params_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1) + goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", "pbes2"); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_params_print(fp, fmt, ind, "parameters", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int pkcs8_enced_private_key_info_to_der( + const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf, + int cipher, const uint8_t *iv, size_t ivlen, + const uint8_t *enced, size_t encedlen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1 + || asn1_octet_string_to_der(enced, encedlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1 + || asn1_octet_string_to_der(enced, encedlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pkcs8_enced_private_key_info_from_der( + const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf, + int *cipher, const uint8_t **iv, size_t *ivlen, + const uint8_t **enced, size_t *encedlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (pbes2_algor_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1 + || asn1_octet_string_from_der(enced, encedlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + pbes2_algor_print(fp, fmt, ind, "encryptionAlgorithm", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "encryptedData", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} diff --git a/src/rand.c b/src/rand.c index 3ef082de..56261678 100644 --- a/src/rand.c +++ b/src/rand.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,40 +7,41 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include - -#define RAND_MAX_BUF_SIZE 4096 - -int rand_bytes(uint8_t *buf, size_t len) -{ - FILE *fp; - if (!buf) { - error_print(); - return -1; - } - if (len > RAND_MAX_BUF_SIZE) { - error_print(); - return -1; - } - if (!len) { - return 0; - } - - if (!(fp = fopen("/dev/urandom", "rb"))) { - error_print(); - return -1; - } - if (fread(buf, 1, len, fp) != len) { - error_print(); - fclose(fp); - return -1; - } - fclose(fp); - return 1; -} + + + +#include +#include +#include +#include +#include + +#define RAND_MAX_BUF_SIZE 4096 + +int rand_bytes(uint8_t *buf, size_t len) +{ + FILE *fp; + if (!buf) { + error_print(); + return -1; + } + if (len > RAND_MAX_BUF_SIZE) { + error_print(); + return -1; + } + if (!len) { + return 0; + } + + if (!(fp = fopen("/dev/urandom", "rb"))) { + error_print(); + return -1; + } + if (fread(buf, 1, len, fp) != len) { + error_print(); + fclose(fp); + return -1; + } + fclose(fp); + return 1; +} diff --git a/src/rc4.c b/src/rc4.c index 89fbf547..0c7e55fc 100644 --- a/src/rc4.c +++ b/src/rc4.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,73 +7,74 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen) -{ - int i, j; - uint8_t *s = state->d; - uint8_t k[256]; - uint8_t temp; - - /* expand key */ - for (i = 0; i < keylen; i++) { - k[i] = key[i]; - } - for (i = keylen; i < 256; i++) { - k[i] = key[i % keylen]; - } - - /* init state */ - for (i = 0; i < 256; i++) { - s[i] = i; - } - - /* shuffle state with key */ - j = 0; - for (i = 0; i < 256; i++) { - j = (j + s[i] + k[i]) % 256; - - /* swap(s[i], s[j]) */ - temp = s[j]; - s[j] = s[i]; - s[i] = temp; - } - - /* clean expanded temp key */ - memset(k, 0, sizeof(k)); -} - -void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out) -{ - int i = 0, j = 0; - uint8_t *s = state->d; - int oi; - int temp; - - while (outlen > 0) { - i = (i + 1) % 256; - j = (j + s[i]) % 256; - - /* swap(s[i], s[j]) */ - temp = s[j]; - s[j] = s[i]; - s[i] = temp; - - oi = (s[i] + s[j]) % 256; - *out++ = s[oi]; - - outlen--; - } -} - -uint8_t rc4_generate_keybyte(RC4_STATE *state) -{ - uint8_t out[1]; - rc4_generate_keystream(state, 1, out); - return out[0]; -} + + +#include +#include +#include +#include + +void rc4_init(RC4_STATE *state, const uint8_t *key, size_t keylen) +{ + int i, j; + uint8_t *s = state->d; + uint8_t k[256]; + uint8_t temp; + + /* expand key */ + for (i = 0; i < keylen; i++) { + k[i] = key[i]; + } + for (i = keylen; i < 256; i++) { + k[i] = key[i % keylen]; + } + + /* init state */ + for (i = 0; i < 256; i++) { + s[i] = i; + } + + /* shuffle state with key */ + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + k[i]) % 256; + + /* swap(s[i], s[j]) */ + temp = s[j]; + s[j] = s[i]; + s[i] = temp; + } + + /* clean expanded temp key */ + memset(k, 0, sizeof(k)); +} + +void rc4_generate_keystream(RC4_STATE *state, size_t outlen, uint8_t *out) +{ + int i = 0, j = 0; + uint8_t *s = state->d; + int oi; + int temp; + + while (outlen > 0) { + i = (i + 1) % 256; + j = (j + s[i]) % 256; + + /* swap(s[i], s[j]) */ + temp = s[j]; + s[j] = s[i]; + s[i] = temp; + + oi = (s[i] + s[j]) % 256; + *out++ = s[oi]; + + outlen--; + } +} + +uint8_t rc4_generate_keybyte(RC4_STATE *state) +{ + uint8_t out[1]; + rc4_generate_keystream(state, 1, out); + return out[0]; +} diff --git a/src/rdrand.c b/src/rdrand.c index 5a1ad280..dbaa34d2 100644 --- a/src/rdrand.c +++ b/src/rdrand.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,45 +7,46 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - -int rdrand_bytes(uint8_t *buf, size_t buflen) -{ - uint64_t val; - uint8_t *p = (uint8_t *)&val; - - while (buflen) { - size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen; - if (_rdrand64_step(&val) != 1) { - error_print(); - return -1; - } - memcpy(buf, p, len); - buf += len; - buflen -= len; - } - return 1; -} - -int rdseed_bytes(uint8_t *buf, size_t buflen) -{ - uint64_t val; - uint8_t *p = (uint8_t *)&val; - - while (buflen) { - size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen; - if (_rdseed64_step(&val) != 1) { - error_print(); - return -1; - } - memcpy(buf, p, len); - buf += len; - buflen -= len; - } - return 1; -} + + +#include +#include +#include +#include +#include + +int rdrand_bytes(uint8_t *buf, size_t buflen) +{ + uint64_t val; + uint8_t *p = (uint8_t *)&val; + + while (buflen) { + size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen; + if (_rdrand64_step(&val) != 1) { + error_print(); + return -1; + } + memcpy(buf, p, len); + buf += len; + buflen -= len; + } + return 1; +} + +int rdseed_bytes(uint8_t *buf, size_t buflen) +{ + uint64_t val; + uint8_t *p = (uint8_t *)&val; + + while (buflen) { + size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen; + if (_rdseed64_step(&val) != 1) { + error_print(); + return -1; + } + memcpy(buf, p, len); + buf += len; + buflen -= len; + } + return 1; +} diff --git a/src/rsa.c b/src/rsa.c index c8284c1e..d6181654 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,36 +7,37 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include - - -int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - const uint8_t *d; - size_t dlen; - const uint8_t *p; - size_t len; - int val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err; - if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "modulus", p, len); - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "publicExponent: %d\n",val); - if (asn1_length_is_zero(dlen) != 1) goto err; - if (asn1_length_is_zero(alen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} + + + +#include +#include +#include +#include +#include +#include +#include + + +int rsa_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + const uint8_t *d; + size_t dlen; + const uint8_t *p; + size_t len; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err; + if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "modulus", p, len); + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "publicExponent: %d\n",val); + if (asn1_length_is_zero(dlen) != 1) goto err; + if (asn1_length_is_zero(alen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} diff --git a/src/sdf/sdf.c b/src/sdf/sdf.c index 950d240f..d7af1f1a 100644 --- a/src/sdf/sdf.c +++ b/src/sdf/sdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,207 +7,208 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include "sdf.h" -#include "sdf_ext.h" - - - -static const uint8_t zeros[ECCref_MAX_LEN - 32] = {0}; - -static int SDF_ECCrefPublicKey_to_SM2_KEY(const ECCrefPublicKey *ref, SM2_KEY *sm2_key) -{ - SM2_POINT point; - - if (ref->bits != 256) { - error_print(); - return -1; - } - if (memcmp(ref->x, zeros, sizeof(zeros)) != 0 - || memcmp(ref->y, zeros, sizeof(zeros)) != 0) { - error_print(); - return -1; - } - - if (sm2_point_from_xy(&point, ref->x + ECCref_MAX_LEN - 32, ref->y + ECCref_MAX_LEN - 32) != 1 - || sm2_key_set_public_key(sm2_key, &point) != 1) { - error_print(); - return -1; - } - return SDR_OK; -} - -static int SDF_ECCSignature_to_SM2_SIGNATURE(const ECCSignature *ref, SM2_SIGNATURE *sig) -{ - if (memcmp(ref->r, zeros, sizeof(zeros)) != 0 - || memcmp(ref->s, zeros, sizeof(zeros)) != 0) { - error_print(); - return -1; - } - memset(sig, 0, sizeof(SM2_SIGNATURE)); - memcpy(sig->r, ref->r + ECCref_MAX_LEN - 32, 32); - memcpy(sig->s, ref->s + ECCref_MAX_LEN - 32, 32); - return SDR_OK; -} - -int sdf_load_library(const char *so_path, const char *vendor) -{ - if (SDF_LoadLibrary((char *)so_path, (char *)vendor) != SDR_OK) { - error_print(); - return -1; - } - return 1; -} - -void sdf_unload_library(void) -{ - SDF_UnloadLibrary(); -} - -int sdf_open_device(SDF_DEVICE *dev) -{ - int ret = -1; - void *hDevice = NULL; - void *hSession = NULL; - DEVICEINFO devInfo; - - if (SDF_OpenDevice(&hDevice) != SDR_OK - || SDF_OpenSession(hDevice, &hSession) != SDR_OK - || SDF_GetDeviceInfo(hSession, &devInfo) != SDR_OK) { - error_print(); - goto end; - } - - memset(dev, 0, sizeof(SDF_DEVICE)); - dev->handle = hDevice; - hDevice = NULL; - memcpy(dev->issuer, devInfo.IssuerName, 40); - memcpy(dev->name, devInfo.DeviceName, 16); - memcpy(dev->serial, devInfo.DeviceSerial, 16); - ret = 1; -end: - if (hSession) SDF_CloseSession(hSession); - if (hDevice) SDF_CloseDevice(hDevice); - return ret; -} - -int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev) -{ - int ret = -1; - void *hSession = NULL; - DEVICEINFO devInfo; - - if (SDF_OpenSession(dev->handle, hSession) != SDR_OK - || SDF_GetDeviceInfo(hSession, &devInfo) != SDR_OK) { - error_print(); - goto end; - } - SDF_PrintDeviceInfo(fp, &devInfo); - ret = 1; -end: - if (hSession) SDF_CloseSession(hSession); - return ret; -} - -int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len) -{ - int ret = -1; - void *hSession = NULL; - - if (!dev || !buf || !len) { - error_print(); - return -1; - } - if (SDF_OpenSession(dev->handle, &hSession) != SDR_OK - || SDF_GenerateRandom(hSession, len, buf) != SDR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hSession) SDF_CloseSession(hSession); - return ret; -} - -int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass) -{ - int ret = -1; - void *hSession = NULL; - ECCrefPublicKey eccPublicKey; - SM2_KEY public_key; - - if (!dev || !key || !pass) { - error_print(); - return -1; - } - if (SDF_OpenSession(dev->handle, &hSession) != SDR_OK - || SDF_ExportSignPublicKey_ECC(hSession, index, &eccPublicKey) != SDR_OK - || SDF_ECCrefPublicKey_to_SM2_KEY(&eccPublicKey, &public_key) != SDR_OK - || SDF_GetPrivateKeyAccessRight(hSession, index, (unsigned char *)pass, strlen(pass)) != SDR_OK) { - error_print(); - goto end; - } - - memset(key, 0, sizeof(SDF_KEY)); - key->public_key = public_key; - key->session = hSession; - key->index = index; - hSession = NULL; - ret = 1; -end: - if (hSession) SDF_CloseSession(hSession); - return ret; -} - -int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) -{ - ECCSignature ecc_sig; - SM2_SIGNATURE sm2_sig; - - if (!key || !dgst || !sig || !siglen) { - error_print(); - return -1; - } - if (SDF_InternalSign_ECC(key->session, key->index, (unsigned char *)dgst, 32, &ecc_sig) != SDR_OK - || SDF_ECCSignature_to_SM2_SIGNATURE(&ecc_sig, &sm2_sig) != SDR_OK) { - error_print(); - return -1; - } - - - - - *siglen = 0; - if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sdf_release_key(SDF_KEY *key) -{ - if (SDF_ReleasePrivateKeyAccessRight(key->session, key->index) != SDR_OK - || SDF_CloseSession(key->session) != SDR_OK) { - error_print(); - return -1; - } - memset(key, 0, sizeof(SDF_KEY)); - return 1; -} - -int sdf_close_device(SDF_DEVICE *dev) -{ - if (SDF_CloseDevice(dev->handle) != SDR_OK) { - error_print(); - return -1; - } - memset(dev, 0, sizeof(SDF_DEVICE)); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include "sdf.h" +#include "sdf_ext.h" + + + +static const uint8_t zeros[ECCref_MAX_LEN - 32] = {0}; + +static int SDF_ECCrefPublicKey_to_SM2_KEY(const ECCrefPublicKey *ref, SM2_KEY *sm2_key) +{ + SM2_POINT point; + + if (ref->bits != 256) { + error_print(); + return -1; + } + if (memcmp(ref->x, zeros, sizeof(zeros)) != 0 + || memcmp(ref->y, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + + if (sm2_point_from_xy(&point, ref->x + ECCref_MAX_LEN - 32, ref->y + ECCref_MAX_LEN - 32) != 1 + || sm2_key_set_public_key(sm2_key, &point) != 1) { + error_print(); + return -1; + } + return SDR_OK; +} + +static int SDF_ECCSignature_to_SM2_SIGNATURE(const ECCSignature *ref, SM2_SIGNATURE *sig) +{ + if (memcmp(ref->r, zeros, sizeof(zeros)) != 0 + || memcmp(ref->s, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + memset(sig, 0, sizeof(SM2_SIGNATURE)); + memcpy(sig->r, ref->r + ECCref_MAX_LEN - 32, 32); + memcpy(sig->s, ref->s + ECCref_MAX_LEN - 32, 32); + return SDR_OK; +} + +int sdf_load_library(const char *so_path, const char *vendor) +{ + if (SDF_LoadLibrary((char *)so_path, (char *)vendor) != SDR_OK) { + error_print(); + return -1; + } + return 1; +} + +void sdf_unload_library(void) +{ + SDF_UnloadLibrary(); +} + +int sdf_open_device(SDF_DEVICE *dev) +{ + int ret = -1; + void *hDevice = NULL; + void *hSession = NULL; + DEVICEINFO devInfo; + + if (SDF_OpenDevice(&hDevice) != SDR_OK + || SDF_OpenSession(hDevice, &hSession) != SDR_OK + || SDF_GetDeviceInfo(hSession, &devInfo) != SDR_OK) { + error_print(); + goto end; + } + + memset(dev, 0, sizeof(SDF_DEVICE)); + dev->handle = hDevice; + hDevice = NULL; + memcpy(dev->issuer, devInfo.IssuerName, 40); + memcpy(dev->name, devInfo.DeviceName, 16); + memcpy(dev->serial, devInfo.DeviceSerial, 16); + ret = 1; +end: + if (hSession) SDF_CloseSession(hSession); + if (hDevice) SDF_CloseDevice(hDevice); + return ret; +} + +int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev) +{ + int ret = -1; + void *hSession = NULL; + DEVICEINFO devInfo; + + if (SDF_OpenSession(dev->handle, hSession) != SDR_OK + || SDF_GetDeviceInfo(hSession, &devInfo) != SDR_OK) { + error_print(); + goto end; + } + SDF_PrintDeviceInfo(fp, &devInfo); + ret = 1; +end: + if (hSession) SDF_CloseSession(hSession); + return ret; +} + +int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len) +{ + int ret = -1; + void *hSession = NULL; + + if (!dev || !buf || !len) { + error_print(); + return -1; + } + if (SDF_OpenSession(dev->handle, &hSession) != SDR_OK + || SDF_GenerateRandom(hSession, len, buf) != SDR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hSession) SDF_CloseSession(hSession); + return ret; +} + +int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass) +{ + int ret = -1; + void *hSession = NULL; + ECCrefPublicKey eccPublicKey; + SM2_KEY public_key; + + if (!dev || !key || !pass) { + error_print(); + return -1; + } + if (SDF_OpenSession(dev->handle, &hSession) != SDR_OK + || SDF_ExportSignPublicKey_ECC(hSession, index, &eccPublicKey) != SDR_OK + || SDF_ECCrefPublicKey_to_SM2_KEY(&eccPublicKey, &public_key) != SDR_OK + || SDF_GetPrivateKeyAccessRight(hSession, index, (unsigned char *)pass, strlen(pass)) != SDR_OK) { + error_print(); + goto end; + } + + memset(key, 0, sizeof(SDF_KEY)); + key->public_key = public_key; + key->session = hSession; + key->index = index; + hSession = NULL; + ret = 1; +end: + if (hSession) SDF_CloseSession(hSession); + return ret; +} + +int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) +{ + ECCSignature ecc_sig; + SM2_SIGNATURE sm2_sig; + + if (!key || !dgst || !sig || !siglen) { + error_print(); + return -1; + } + if (SDF_InternalSign_ECC(key->session, key->index, (unsigned char *)dgst, 32, &ecc_sig) != SDR_OK + || SDF_ECCSignature_to_SM2_SIGNATURE(&ecc_sig, &sm2_sig) != SDR_OK) { + error_print(); + return -1; + } + + + + + *siglen = 0; + if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sdf_release_key(SDF_KEY *key) +{ + if (SDF_ReleasePrivateKeyAccessRight(key->session, key->index) != SDR_OK + || SDF_CloseSession(key->session) != SDR_OK) { + error_print(); + return -1; + } + memset(key, 0, sizeof(SDF_KEY)); + return 1; +} + +int sdf_close_device(SDF_DEVICE *dev) +{ + if (SDF_CloseDevice(dev->handle) != SDR_OK) { + error_print(); + return -1; + } + memset(dev, 0, sizeof(SDF_DEVICE)); + return 1; +} diff --git a/src/sdf/sdf.h b/src/sdf/sdf.h index 70e2be0d..5335ebe8 100644 --- a/src/sdf/sdf.h +++ b/src/sdf/sdf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,6 +7,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ + /* * SDF API is a cryptographic API for PCI-E cards defined in standard * GM/T 0018-2012: Interface Specifications of Cryptography Device Application diff --git a/src/sdf/sdf_dummy.c b/src/sdf/sdf_dummy.c index eb369d89..43372716 100644 --- a/src/sdf/sdf_dummy.c +++ b/src/sdf/sdf_dummy.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,723 +7,724 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include "../sgd.h" -#include "sdf.h" - -static char *deviceHandle = "SDF Device Handle"; -static char *sessionHandle = "SDF Session Handle"; -static char *keyHandle = "SDF Key Handle"; -static char *agreementHandle = "SDF Agreement Handle"; - -unsigned char rsaPublicKeyBuf[516] = { - 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xd5,0x43,0xbf,0x24,0xd2,0x69,0x56,0x21,0x20,0x57,0x8a,0xd8, - 0x67,0x4f,0xbd,0xd5,0xf5,0x3a,0xf5,0x9e,0xa5,0x87,0x52,0x39,0x47,0xc3,0xce,0x32, - 0x56,0xb6,0x06,0x2d,0xdc,0x8d,0xc2,0x18,0x53,0x5c,0xb0,0xcb,0xb6,0xe8,0x7c,0x82, - 0x97,0x38,0xbb,0x85,0x45,0x2e,0xc8,0x24,0x08,0x96,0x9e,0xb0,0x00,0xaf,0xd9,0xa7, - 0x1f,0x50,0x7f,0xc4,0x93,0x14,0x74,0x9a,0x43,0x8e,0x04,0x95,0xa0,0xd6,0xd9,0xdd, - 0xb4,0x97,0xb3,0x52,0x93,0xe4,0xbe,0xd1,0x1f,0x8c,0xf9,0xcd,0xe1,0xae,0x54,0xae, - 0x72,0xdf,0x94,0xe3,0x15,0x6a,0x5c,0x99,0xd6,0x80,0x46,0x94,0xad,0xb3,0x76,0x95, - 0x4e,0x14,0x8f,0x8f,0xe5,0x55,0xf1,0x3f,0xd0,0xd3,0x96,0x01,0xf6,0x94,0x3e,0x61, - 0xc1,0x8e,0xb3,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01,0x00,0x01,}; -unsigned char rsaPrivateKeyBuf[1412] = { - 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xd5,0x43,0xbf,0x24,0xd2,0x69,0x56,0x21,0x20,0x57,0x8a,0xd8, - 0x67,0x4f,0xbd,0xd5,0xf5,0x3a,0xf5,0x9e,0xa5,0x87,0x52,0x39,0x47,0xc3,0xce,0x32, - 0x56,0xb6,0x06,0x2d,0xdc,0x8d,0xc2,0x18,0x53,0x5c,0xb0,0xcb,0xb6,0xe8,0x7c,0x82, - 0x97,0x38,0xbb,0x85,0x45,0x2e,0xc8,0x24,0x08,0x96,0x9e,0xb0,0x00,0xaf,0xd9,0xa7, - 0x1f,0x50,0x7f,0xc4,0x93,0x14,0x74,0x9a,0x43,0x8e,0x04,0x95,0xa0,0xd6,0xd9,0xdd, - 0xb4,0x97,0xb3,0x52,0x93,0xe4,0xbe,0xd1,0x1f,0x8c,0xf9,0xcd,0xe1,0xae,0x54,0xae, - 0x72,0xdf,0x94,0xe3,0x15,0x6a,0x5c,0x99,0xd6,0x80,0x46,0x94,0xad,0xb3,0x76,0x95, - 0x4e,0x14,0x8f,0x8f,0xe5,0x55,0xf1,0x3f,0xd0,0xd3,0x96,0x01,0xf6,0x94,0x3e,0x61, - 0xc1,0x8e,0xb3,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x1e,0xd9,0x55,0xe4,0xf5,0xaa,0xd7,0x12,0xa3,0xa3,0x06,0x2a, - 0x97,0x87,0x29,0x66,0xb1,0xba,0x7d,0x9d,0x1d,0x44,0x9d,0xd8,0x3b,0x51,0x4f,0x9a, - 0x68,0x80,0x9c,0x14,0x36,0x3b,0x2b,0x40,0x69,0x8e,0x96,0xe4,0x60,0xe8,0xf0,0x59, - 0xd3,0x96,0x19,0x4a,0x05,0xdf,0xe6,0x83,0x8f,0xda,0x79,0xc9,0xeb,0xcf,0x84,0x24, - 0x70,0x9b,0x2c,0x5f,0xf7,0x56,0xe2,0xe0,0xc7,0xfb,0x67,0x92,0xd2,0xf6,0x59,0x19, - 0xe9,0xdd,0xb4,0x54,0x52,0x0d,0xf8,0xda,0x64,0x67,0xe0,0xb9,0xe6,0x52,0x08,0xff, - 0x28,0x06,0x89,0x5c,0x2b,0xd5,0x6e,0x21,0xe1,0x6d,0x1d,0xe3,0xf8,0x1e,0x0f,0x20, - 0x9f,0x0a,0x60,0xd1,0xff,0x4e,0xa2,0x45,0xa1,0xee,0x96,0x90,0xc0,0xc4,0xa8,0x25, - 0x5a,0xe8,0xe8,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0xde,0x0d,0x0c,0xc5,0x03,0x53,0x44,0xfa,0x70,0xc7,0x44, - 0x63,0xf8,0x57,0x7e,0x49,0x76,0xe4,0x7a,0x76,0x01,0x7d,0xda,0x65,0xaa,0x9d,0xbe, - 0xfe,0x24,0x9b,0x48,0xf9,0xa8,0x18,0x42,0x47,0xf3,0x1a,0x1e,0x61,0xe9,0xb8,0xb3, - 0x07,0xee,0xfd,0x83,0x2e,0xf2,0xf8,0xb9,0x1f,0x9a,0xee,0xeb,0x21,0xd0,0xc0,0x13, - 0xa2,0x31,0x33,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xde,0x0d,0xba,0xf3,0x62,0x8f,0x75,0x16,0xe6,0x87,0x72,0xba, - 0x12,0x6a,0x43,0x5c,0xde,0x22,0x60,0xea,0xef,0x7a,0x7e,0xb6,0x28,0x16,0x4f,0xda, - 0xe7,0xb8,0xfe,0x48,0x17,0x65,0x1a,0x73,0x38,0x98,0xdb,0xa2,0xda,0x50,0xc8,0x81, - 0x53,0x07,0x1d,0x0e,0xa7,0x3f,0x48,0x57,0xea,0x5b,0x34,0x64,0x9f,0x0a,0x8b,0x36, - 0x7e,0x08,0xef,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xa8,0xd9,0xe6,0x7c,0x6e,0x90,0xea,0x0e,0xe5,0x2f,0xae,0xa9, - 0xf9,0x3e,0x04,0x58,0x66,0x7b,0x90,0x4d,0xc9,0xdd,0x1c,0x61,0x70,0x90,0xcb,0xe4, - 0xef,0x04,0x94,0xe0,0x79,0x14,0x48,0x14,0xbc,0xf4,0xe7,0x6b,0x16,0x33,0x3c,0xf5, - 0x36,0xed,0x9a,0x8d,0x0d,0x21,0x30,0x4f,0x72,0xb5,0x24,0x7f,0xb6,0xa9,0x76,0x40, - 0x05,0x93,0x64,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x85,0x35,0x31,0x68,0x9e,0x40,0xb7,0x1a,0x34,0xd3,0x1e,0x84, - 0xf7,0x55,0x1d,0xf2,0x11,0x24,0x08,0x86,0x07,0x81,0xb1,0x8f,0xee,0xfe,0x6b,0x8b, - 0x43,0xa5,0x5b,0x8d,0xbd,0xd3,0x1e,0x09,0xee,0xf2,0xec,0x17,0x86,0xe6,0x1d,0x52, - 0x4f,0x8f,0x9d,0xe3,0xd3,0x7b,0x08,0x18,0x0d,0x74,0x07,0x3b,0x31,0x99,0x6e,0xa8, - 0x12,0xf5,0xa3,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x23,0x60,0x23,0xc4,0x44,0x67,0x91,0xb7,0xde,0x06,0x9a,0x17, - 0x49,0x3a,0x8e,0x66,0xb4,0x54,0x61,0x4b,0xc4,0x9e,0xf8,0xe6,0xbc,0xf8,0x87,0xef, - 0x06,0xb5,0x40,0x4b,0xab,0xaf,0xf0,0xa0,0x46,0x43,0xc5,0xbd,0xec,0xff,0x57,0xfd, - 0x51,0x8a,0x6b,0x7b,0x32,0xee,0xeb,0x2f,0x81,0xd0,0xa0,0xa2,0x09,0x18,0xab,0x5c, - 0x85,0x1b,0x0f,0x57,}; -unsigned char eccPublicKeyBuf[132] = { - 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x0e,0x42,0x92,0x4a,0x1b,0x01,0xb6,0x64,0x89,0x97,0xfb,0x67, - 0x3f,0xa5,0xa6,0xc4,0xc4,0x82,0xa2,0xfa,0xe6,0x96,0xc9,0x0a,0x37,0xf2,0x44,0x6c, - 0xac,0x37,0x85,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf8,0xbb,0x32,0x55,0xe2,0x47,0x34,0x9a,0xc9,0xb5,0xdb,0xc7, - 0x17,0x4a,0xd9,0x84,0xbf,0xc5,0x3e,0x99,0x92,0xc6,0xd8,0x2d,0x6f,0xea,0xff,0x79, - 0x6b,0xde,0x3d,0x37,}; -unsigned char eccPrivateKeyBuf[68] = { - 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe6,0x51,0x2e,0xf8,0xca,0x14,0x84,0xa2,0xd9,0x76,0xc9,0x0d, - 0x37,0x1d,0xf1,0x95,0x49,0xbe,0x83,0x8e,0x70,0x09,0x1d,0x81,0xbd,0x6e,0xd9,0x5c, - 0xad,0x02,0x19,0x44,}; - - -#define SDF_TRACE() fprintf(stderr, "SDF_Dummy->%s\n", __FUNCTION__) - -int SDF_OpenDevice( - void **phDeviceHandle) -{ - if (!phDeviceHandle /* || !(*phDeviceHandle) */) - return SDR_INARGERR; - - *phDeviceHandle = deviceHandle; - return SDR_OK; -} - -int SDF_CloseDevice( - void *hDeviceHandle) -{ - return SDR_OK; -} - -int SDF_OpenSession( - void *hDeviceHandle, - void **phSessionHandle) -{ - if (!phSessionHandle /* || !(*phSessionHandle) */) - return SDR_INARGERR; - *phSessionHandle = sessionHandle; - return SDR_OK; -} - -int SDF_CloseSession( - void *hSessionHandle) -{ - return SDR_OK; -} - -#define SDF_DEV_DATE "20140101" -#define SDF_DEV_BATCH_NUM "001" -#define SDF_DEV_SERIAL_NUM "00123" -#define SDF_DEV_SERIAL SDF_DEV_DATE \ - SDF_DEV_BATCH_NUM \ - SDF_DEV_SERIAL_NUM - -int SDF_GetDeviceInfo( - void *hSessionHandle, - DEVICEINFO *pstDeviceInfo) -{ - if (!pstDeviceInfo) - return SDR_INARGERR; - memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo)); - strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)", - sizeof(pstDeviceInfo->IssuerName)); - strncpy((char *)pstDeviceInfo->DeviceName, "Dummy SDF", - sizeof(pstDeviceInfo->DeviceName)); - strncpy((char *)pstDeviceInfo->DeviceSerial, SDF_DEV_SERIAL, - sizeof(pstDeviceInfo->DeviceSerial)); - pstDeviceInfo->DeviceVersion = 1; - pstDeviceInfo->StandardVersion = 1; - pstDeviceInfo->AsymAlgAbility[0] = SGD_RSA_SIGN|SGD_RSA_ENC| - SGD_SM2_1|SGD_SM2_2|SGD_SM2_3; - pstDeviceInfo->AsymAlgAbility[1] = 256|512|1024|2048|4096; - pstDeviceInfo->SymAlgAbility = SGD_SM1|SGD_SSF33|SGD_SM4|SGD_ZUC| - SGD_ECB|SGD_CBC|SGD_CFB|SGD_OFB|SGD_MAC; - pstDeviceInfo->HashAlgAbility = SGD_SM3|SGD_SHA1|SGD_SHA256; - pstDeviceInfo->BufferSize = 256*1024; - return SDR_OK; -} - -int SDF_GenerateRandom( - void *hSessionHandle, - unsigned int uiLength, - unsigned char *pucRandom) -{ - return SDR_OK; -} - -int SDF_GetPrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucPassword, - unsigned int uiPwdLength) -{ - return SDR_OK; -} - -int SDF_ReleasePrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex) -{ - return SDR_OK; -} - -int SDF_ExportSignPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey) -{ - if (!pucPublicKey) - return SDR_INARGERR; - memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); - return SDR_OK; -} - -int SDF_ExportEncPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey) -{ - if (!pucPublicKey) - return SDR_INARGERR; - memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); - return SDR_OK; -} - -int SDF_GenerateKeyPair_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - RSArefPrivateKey *pucPrivateKey) -{ - if (!pucPublicKey || !pucPrivateKey) - return SDR_INARGERR; - memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); - memcpy(pucPrivateKey, rsaPrivateKeyBuf, sizeof(*pucPrivateKey)); - return SDR_OK; -} - -int SDF_GenerateKeyWithIPK_RSA( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - if (!puiKeyLength) - return SDR_INARGERR; - *puiKeyLength = 2048/8; - if (phKeyHandle && *phKeyHandle) - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_GenerateKeyWithEPK_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - if (!puiKeyLength) - return SDR_INARGERR; - *puiKeyLength = 2048/8; - if (phKeyHandle && *phKeyHandle) - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_ImportKeyWithISK_RSA( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_ExchangeDigitEnvelopeBaseOnRSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDEInput, - unsigned int uiDELength, - unsigned char *pucDEOutput, - unsigned int *puiDELength) -{ - if (!puiDELength) - return SDR_INARGERR; - *puiDELength = 2048/8; - return SDR_OK; -} - -int SDF_ExportSignPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey) -{ - if (!pucPublicKey) - return SDR_INARGERR; - memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); - return SDR_OK; -} - -int SDF_ExportEncPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey) -{ - if (!pucPublicKey) - return SDR_INARGERR; - memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); - return SDR_OK; -} - -int SDF_GenerateKeyPair_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKeyBits, - ECCrefPublicKey *pucPublicKey, - ECCrefPrivateKey *pucPrivateKey) -{ - if (!pucPublicKey || !pucPublicKey) - return SDR_INARGERR; - memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); - memcpy(pucPrivateKey, eccPrivateKeyBuf, sizeof(*pucPrivateKey)); - return SDR_OK; -} - -int SDF_GenerateKeyWithIPK_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - ECCCipher *pucKey, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_GenerateKeyWithEPK_ECC( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucKey, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_ImportKeyWithISK_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - ECCCipher *pucKey, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -/* 6.3.14 */ -int SDF_GenerateAgreementDataWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - void **phAgreementHandle) -{ - // any output public key ? - if (!phAgreementHandle || !(*phAgreementHandle)) - return SDR_INARGERR; - *phAgreementHandle = agreementHandle; - return SDR_OK; -} - -/* 6.3.15 */ -int SDF_GenerateKeyWithECC( - void *hSessionHandle, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void *hAgreementHandle, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -/* 6.3.16 */ -int SDF_GenerateAgreementDataAndKeyWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void **phKeyHandle) -{ - // any output - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_ExchangeDigitEnvelopeBaseOnECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucEncDataIn, - ECCCipher *pucEncDataOut) -{ - return SDR_OK; -} - -int SDF_GenerateKeyWithKEK( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_ImportKeyWithKEK( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle) -{ - if (!phKeyHandle || !(*phKeyHandle)) - return SDR_INARGERR; - *phKeyHandle = keyHandle; - return SDR_OK; -} - -int SDF_DestroyKey( - void *hSessionHandle, - void *hKeyHandle) -{ - return SDR_OK; -} - -int SDF_ExternalPublicKeyOperation_RSA( - void *hSessionHandle, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - if (!puiOutputLength) - return SDR_INARGERR; - *puiOutputLength = 2048/8; - return SDR_OK; -} - -int SDF_ExternalPrivateKeyOperation_RSA( - void *hSessionHandle, - RSArefPrivateKey *pucPrivateKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - if (!puiOutputLength) - return SDR_INARGERR; - *puiOutputLength = 2048/8; - return SDR_OK; -} - -int SDF_InternalPrivateKeyOperation_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - if (!puiOutputLength) - return SDR_INARGERR; - *puiOutputLength = 2048/8; - return SDR_OK; -} - -int SDF_ExternalVerify_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - ECCSignature *pucSignature) -{ - return SDR_OK; -} - -int SDF_InternalSign_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature) -{ - return SDR_OK; -} - -int SDF_InternalVerify_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature) -{ - return SDR_OK; -} - -int SDF_ExternalEncrypt_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData) -{ - if (!pucEncData) - return SDR_INARGERR; - pucEncData->L = uiDataLength; - return SDR_OK; -} - -int SDF_Encrypt( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucEncData, - unsigned int *puiEncDataLength) -{ - if (!puiEncDataLength) - return SDR_INARGERR; - *puiEncDataLength = uiDataLength; - return SDR_OK; -} - -int SDF_Decrypt( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucEncData, - unsigned int uiEncDataLength, - unsigned char *pucData, - unsigned int *puiDataLength) -{ - if (!puiDataLength) - return SDR_INARGERR; - *puiDataLength = uiEncDataLength; - return SDR_OK; -} - -int SDF_CalculateMAC( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucMAC, - unsigned int *puiMACLength) -{ - if (!puiMACLength) - return SDR_INARGERR; - *puiMACLength = 16; /* CBC-MAC length */ - return SDR_OK; -} - -int SDF_HashInit( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucID, - unsigned int uiIDLength) -{ - return SDR_OK; -} - -int SDF_HashUpdate( - void *hSessionHandle, - unsigned char *pucData, - unsigned int uiDataLength) -{ - return SDR_OK; -} - -int SDF_HashFinal(void *hSessionHandle, - unsigned char *pucHash, - unsigned int *puiHashLength) -{ - if (!puiHashLength) - return SDR_INARGERR; - *puiHashLength = 32; - return SDR_OK; -} - -int SDF_CreateFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiFileSize) -{ - return SDR_OK; -} - -int SDF_ReadFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int *puiReadLength, - unsigned char *pucBuffer) -{ - if (!puiReadLength) - return SDR_INARGERR; - return SDR_OK; -} - -int SDF_WriteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int uiWriteLength, - unsigned char *pucBuffer) -{ - return SDR_OK; -} - -int SDF_DeleteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen) -{ - return SDR_OK; -} + + +#include +#include +#include +#include "../sgd.h" +#include "sdf.h" + +static char *deviceHandle = "SDF Device Handle"; +static char *sessionHandle = "SDF Session Handle"; +static char *keyHandle = "SDF Key Handle"; +static char *agreementHandle = "SDF Agreement Handle"; + +unsigned char rsaPublicKeyBuf[516] = { + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xd5,0x43,0xbf,0x24,0xd2,0x69,0x56,0x21,0x20,0x57,0x8a,0xd8, + 0x67,0x4f,0xbd,0xd5,0xf5,0x3a,0xf5,0x9e,0xa5,0x87,0x52,0x39,0x47,0xc3,0xce,0x32, + 0x56,0xb6,0x06,0x2d,0xdc,0x8d,0xc2,0x18,0x53,0x5c,0xb0,0xcb,0xb6,0xe8,0x7c,0x82, + 0x97,0x38,0xbb,0x85,0x45,0x2e,0xc8,0x24,0x08,0x96,0x9e,0xb0,0x00,0xaf,0xd9,0xa7, + 0x1f,0x50,0x7f,0xc4,0x93,0x14,0x74,0x9a,0x43,0x8e,0x04,0x95,0xa0,0xd6,0xd9,0xdd, + 0xb4,0x97,0xb3,0x52,0x93,0xe4,0xbe,0xd1,0x1f,0x8c,0xf9,0xcd,0xe1,0xae,0x54,0xae, + 0x72,0xdf,0x94,0xe3,0x15,0x6a,0x5c,0x99,0xd6,0x80,0x46,0x94,0xad,0xb3,0x76,0x95, + 0x4e,0x14,0x8f,0x8f,0xe5,0x55,0xf1,0x3f,0xd0,0xd3,0x96,0x01,0xf6,0x94,0x3e,0x61, + 0xc1,0x8e,0xb3,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x00,0x01,}; +unsigned char rsaPrivateKeyBuf[1412] = { + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xd5,0x43,0xbf,0x24,0xd2,0x69,0x56,0x21,0x20,0x57,0x8a,0xd8, + 0x67,0x4f,0xbd,0xd5,0xf5,0x3a,0xf5,0x9e,0xa5,0x87,0x52,0x39,0x47,0xc3,0xce,0x32, + 0x56,0xb6,0x06,0x2d,0xdc,0x8d,0xc2,0x18,0x53,0x5c,0xb0,0xcb,0xb6,0xe8,0x7c,0x82, + 0x97,0x38,0xbb,0x85,0x45,0x2e,0xc8,0x24,0x08,0x96,0x9e,0xb0,0x00,0xaf,0xd9,0xa7, + 0x1f,0x50,0x7f,0xc4,0x93,0x14,0x74,0x9a,0x43,0x8e,0x04,0x95,0xa0,0xd6,0xd9,0xdd, + 0xb4,0x97,0xb3,0x52,0x93,0xe4,0xbe,0xd1,0x1f,0x8c,0xf9,0xcd,0xe1,0xae,0x54,0xae, + 0x72,0xdf,0x94,0xe3,0x15,0x6a,0x5c,0x99,0xd6,0x80,0x46,0x94,0xad,0xb3,0x76,0x95, + 0x4e,0x14,0x8f,0x8f,0xe5,0x55,0xf1,0x3f,0xd0,0xd3,0x96,0x01,0xf6,0x94,0x3e,0x61, + 0xc1,0x8e,0xb3,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1e,0xd9,0x55,0xe4,0xf5,0xaa,0xd7,0x12,0xa3,0xa3,0x06,0x2a, + 0x97,0x87,0x29,0x66,0xb1,0xba,0x7d,0x9d,0x1d,0x44,0x9d,0xd8,0x3b,0x51,0x4f,0x9a, + 0x68,0x80,0x9c,0x14,0x36,0x3b,0x2b,0x40,0x69,0x8e,0x96,0xe4,0x60,0xe8,0xf0,0x59, + 0xd3,0x96,0x19,0x4a,0x05,0xdf,0xe6,0x83,0x8f,0xda,0x79,0xc9,0xeb,0xcf,0x84,0x24, + 0x70,0x9b,0x2c,0x5f,0xf7,0x56,0xe2,0xe0,0xc7,0xfb,0x67,0x92,0xd2,0xf6,0x59,0x19, + 0xe9,0xdd,0xb4,0x54,0x52,0x0d,0xf8,0xda,0x64,0x67,0xe0,0xb9,0xe6,0x52,0x08,0xff, + 0x28,0x06,0x89,0x5c,0x2b,0xd5,0x6e,0x21,0xe1,0x6d,0x1d,0xe3,0xf8,0x1e,0x0f,0x20, + 0x9f,0x0a,0x60,0xd1,0xff,0x4e,0xa2,0x45,0xa1,0xee,0x96,0x90,0xc0,0xc4,0xa8,0x25, + 0x5a,0xe8,0xe8,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0xde,0x0d,0x0c,0xc5,0x03,0x53,0x44,0xfa,0x70,0xc7,0x44, + 0x63,0xf8,0x57,0x7e,0x49,0x76,0xe4,0x7a,0x76,0x01,0x7d,0xda,0x65,0xaa,0x9d,0xbe, + 0xfe,0x24,0x9b,0x48,0xf9,0xa8,0x18,0x42,0x47,0xf3,0x1a,0x1e,0x61,0xe9,0xb8,0xb3, + 0x07,0xee,0xfd,0x83,0x2e,0xf2,0xf8,0xb9,0x1f,0x9a,0xee,0xeb,0x21,0xd0,0xc0,0x13, + 0xa2,0x31,0x33,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xde,0x0d,0xba,0xf3,0x62,0x8f,0x75,0x16,0xe6,0x87,0x72,0xba, + 0x12,0x6a,0x43,0x5c,0xde,0x22,0x60,0xea,0xef,0x7a,0x7e,0xb6,0x28,0x16,0x4f,0xda, + 0xe7,0xb8,0xfe,0x48,0x17,0x65,0x1a,0x73,0x38,0x98,0xdb,0xa2,0xda,0x50,0xc8,0x81, + 0x53,0x07,0x1d,0x0e,0xa7,0x3f,0x48,0x57,0xea,0x5b,0x34,0x64,0x9f,0x0a,0x8b,0x36, + 0x7e,0x08,0xef,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xa8,0xd9,0xe6,0x7c,0x6e,0x90,0xea,0x0e,0xe5,0x2f,0xae,0xa9, + 0xf9,0x3e,0x04,0x58,0x66,0x7b,0x90,0x4d,0xc9,0xdd,0x1c,0x61,0x70,0x90,0xcb,0xe4, + 0xef,0x04,0x94,0xe0,0x79,0x14,0x48,0x14,0xbc,0xf4,0xe7,0x6b,0x16,0x33,0x3c,0xf5, + 0x36,0xed,0x9a,0x8d,0x0d,0x21,0x30,0x4f,0x72,0xb5,0x24,0x7f,0xb6,0xa9,0x76,0x40, + 0x05,0x93,0x64,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x85,0x35,0x31,0x68,0x9e,0x40,0xb7,0x1a,0x34,0xd3,0x1e,0x84, + 0xf7,0x55,0x1d,0xf2,0x11,0x24,0x08,0x86,0x07,0x81,0xb1,0x8f,0xee,0xfe,0x6b,0x8b, + 0x43,0xa5,0x5b,0x8d,0xbd,0xd3,0x1e,0x09,0xee,0xf2,0xec,0x17,0x86,0xe6,0x1d,0x52, + 0x4f,0x8f,0x9d,0xe3,0xd3,0x7b,0x08,0x18,0x0d,0x74,0x07,0x3b,0x31,0x99,0x6e,0xa8, + 0x12,0xf5,0xa3,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x23,0x60,0x23,0xc4,0x44,0x67,0x91,0xb7,0xde,0x06,0x9a,0x17, + 0x49,0x3a,0x8e,0x66,0xb4,0x54,0x61,0x4b,0xc4,0x9e,0xf8,0xe6,0xbc,0xf8,0x87,0xef, + 0x06,0xb5,0x40,0x4b,0xab,0xaf,0xf0,0xa0,0x46,0x43,0xc5,0xbd,0xec,0xff,0x57,0xfd, + 0x51,0x8a,0x6b,0x7b,0x32,0xee,0xeb,0x2f,0x81,0xd0,0xa0,0xa2,0x09,0x18,0xab,0x5c, + 0x85,0x1b,0x0f,0x57,}; +unsigned char eccPublicKeyBuf[132] = { + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x0e,0x42,0x92,0x4a,0x1b,0x01,0xb6,0x64,0x89,0x97,0xfb,0x67, + 0x3f,0xa5,0xa6,0xc4,0xc4,0x82,0xa2,0xfa,0xe6,0x96,0xc9,0x0a,0x37,0xf2,0x44,0x6c, + 0xac,0x37,0x85,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf8,0xbb,0x32,0x55,0xe2,0x47,0x34,0x9a,0xc9,0xb5,0xdb,0xc7, + 0x17,0x4a,0xd9,0x84,0xbf,0xc5,0x3e,0x99,0x92,0xc6,0xd8,0x2d,0x6f,0xea,0xff,0x79, + 0x6b,0xde,0x3d,0x37,}; +unsigned char eccPrivateKeyBuf[68] = { + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe6,0x51,0x2e,0xf8,0xca,0x14,0x84,0xa2,0xd9,0x76,0xc9,0x0d, + 0x37,0x1d,0xf1,0x95,0x49,0xbe,0x83,0x8e,0x70,0x09,0x1d,0x81,0xbd,0x6e,0xd9,0x5c, + 0xad,0x02,0x19,0x44,}; + + +#define SDF_TRACE() fprintf(stderr, "SDF_Dummy->%s\n", __FUNCTION__) + +int SDF_OpenDevice( + void **phDeviceHandle) +{ + if (!phDeviceHandle /* || !(*phDeviceHandle) */) + return SDR_INARGERR; + + *phDeviceHandle = deviceHandle; + return SDR_OK; +} + +int SDF_CloseDevice( + void *hDeviceHandle) +{ + return SDR_OK; +} + +int SDF_OpenSession( + void *hDeviceHandle, + void **phSessionHandle) +{ + if (!phSessionHandle /* || !(*phSessionHandle) */) + return SDR_INARGERR; + *phSessionHandle = sessionHandle; + return SDR_OK; +} + +int SDF_CloseSession( + void *hSessionHandle) +{ + return SDR_OK; +} + +#define SDF_DEV_DATE "20140101" +#define SDF_DEV_BATCH_NUM "001" +#define SDF_DEV_SERIAL_NUM "00123" +#define SDF_DEV_SERIAL SDF_DEV_DATE \ + SDF_DEV_BATCH_NUM \ + SDF_DEV_SERIAL_NUM + +int SDF_GetDeviceInfo( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo) +{ + if (!pstDeviceInfo) + return SDR_INARGERR; + memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo)); + strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)", + sizeof(pstDeviceInfo->IssuerName)); + strncpy((char *)pstDeviceInfo->DeviceName, "Dummy SDF", + sizeof(pstDeviceInfo->DeviceName)); + strncpy((char *)pstDeviceInfo->DeviceSerial, SDF_DEV_SERIAL, + sizeof(pstDeviceInfo->DeviceSerial)); + pstDeviceInfo->DeviceVersion = 1; + pstDeviceInfo->StandardVersion = 1; + pstDeviceInfo->AsymAlgAbility[0] = SGD_RSA_SIGN|SGD_RSA_ENC| + SGD_SM2_1|SGD_SM2_2|SGD_SM2_3; + pstDeviceInfo->AsymAlgAbility[1] = 256|512|1024|2048|4096; + pstDeviceInfo->SymAlgAbility = SGD_SM1|SGD_SSF33|SGD_SM4|SGD_ZUC| + SGD_ECB|SGD_CBC|SGD_CFB|SGD_OFB|SGD_MAC; + pstDeviceInfo->HashAlgAbility = SGD_SM3|SGD_SHA1|SGD_SHA256; + pstDeviceInfo->BufferSize = 256*1024; + return SDR_OK; +} + +int SDF_GenerateRandom( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom) +{ + return SDR_OK; +} + +int SDF_GetPrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + return SDR_OK; +} + +int SDF_ReleasePrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex) +{ + return SDR_OK; +} + +int SDF_ExportSignPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + if (!pucPublicKey) + return SDR_INARGERR; + memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); + return SDR_OK; +} + +int SDF_ExportEncPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + if (!pucPublicKey) + return SDR_INARGERR; + memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); + return SDR_OK; +} + +int SDF_GenerateKeyPair_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey) +{ + if (!pucPublicKey || !pucPrivateKey) + return SDR_INARGERR; + memcpy(pucPublicKey, rsaPublicKeyBuf, sizeof(*pucPublicKey)); + memcpy(pucPrivateKey, rsaPrivateKeyBuf, sizeof(*pucPrivateKey)); + return SDR_OK; +} + +int SDF_GenerateKeyWithIPK_RSA( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + if (!puiKeyLength) + return SDR_INARGERR; + *puiKeyLength = 2048/8; + if (phKeyHandle && *phKeyHandle) + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_GenerateKeyWithEPK_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + if (!puiKeyLength) + return SDR_INARGERR; + *puiKeyLength = 2048/8; + if (phKeyHandle && *phKeyHandle) + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_ImportKeyWithISK_RSA( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_ExchangeDigitEnvelopeBaseOnRSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength) +{ + if (!puiDELength) + return SDR_INARGERR; + *puiDELength = 2048/8; + return SDR_OK; +} + +int SDF_ExportSignPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + if (!pucPublicKey) + return SDR_INARGERR; + memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); + return SDR_OK; +} + +int SDF_ExportEncPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + if (!pucPublicKey) + return SDR_INARGERR; + memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); + return SDR_OK; +} + +int SDF_GenerateKeyPair_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + if (!pucPublicKey || !pucPublicKey) + return SDR_INARGERR; + memcpy(pucPublicKey, eccPublicKeyBuf, sizeof(*pucPublicKey)); + memcpy(pucPrivateKey, eccPrivateKeyBuf, sizeof(*pucPrivateKey)); + return SDR_OK; +} + +int SDF_GenerateKeyWithIPK_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + ECCCipher *pucKey, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_GenerateKeyWithEPK_ECC( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_ImportKeyWithISK_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +/* 6.3.14 */ +int SDF_GenerateAgreementDataWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle) +{ + // any output public key ? + if (!phAgreementHandle || !(*phAgreementHandle)) + return SDR_INARGERR; + *phAgreementHandle = agreementHandle; + return SDR_OK; +} + +/* 6.3.15 */ +int SDF_GenerateKeyWithECC( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +/* 6.3.16 */ +int SDF_GenerateAgreementDataAndKeyWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle) +{ + // any output + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_ExchangeDigitEnvelopeBaseOnECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut) +{ + return SDR_OK; +} + +int SDF_GenerateKeyWithKEK( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_ImportKeyWithKEK( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + if (!phKeyHandle || !(*phKeyHandle)) + return SDR_INARGERR; + *phKeyHandle = keyHandle; + return SDR_OK; +} + +int SDF_DestroyKey( + void *hSessionHandle, + void *hKeyHandle) +{ + return SDR_OK; +} + +int SDF_ExternalPublicKeyOperation_RSA( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + if (!puiOutputLength) + return SDR_INARGERR; + *puiOutputLength = 2048/8; + return SDR_OK; +} + +int SDF_ExternalPrivateKeyOperation_RSA( + void *hSessionHandle, + RSArefPrivateKey *pucPrivateKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + if (!puiOutputLength) + return SDR_INARGERR; + *puiOutputLength = 2048/8; + return SDR_OK; +} + +int SDF_InternalPrivateKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + if (!puiOutputLength) + return SDR_INARGERR; + *puiOutputLength = 2048/8; + return SDR_OK; +} + +int SDF_ExternalVerify_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature) +{ + return SDR_OK; +} + +int SDF_InternalSign_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + return SDR_OK; +} + +int SDF_InternalVerify_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + return SDR_OK; +} + +int SDF_ExternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + if (!pucEncData) + return SDR_INARGERR; + pucEncData->L = uiDataLength; + return SDR_OK; +} + +int SDF_Encrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength) +{ + if (!puiEncDataLength) + return SDR_INARGERR; + *puiEncDataLength = uiDataLength; + return SDR_OK; +} + +int SDF_Decrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucEncData, + unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + if (!puiDataLength) + return SDR_INARGERR; + *puiDataLength = uiEncDataLength; + return SDR_OK; +} + +int SDF_CalculateMAC( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucMAC, + unsigned int *puiMACLength) +{ + if (!puiMACLength) + return SDR_INARGERR; + *puiMACLength = 16; /* CBC-MAC length */ + return SDR_OK; +} + +int SDF_HashInit( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength) +{ + return SDR_OK; +} + +int SDF_HashUpdate( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength) +{ + return SDR_OK; +} + +int SDF_HashFinal(void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength) +{ + if (!puiHashLength) + return SDR_INARGERR; + *puiHashLength = 32; + return SDR_OK; +} + +int SDF_CreateFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiFileSize) +{ + return SDR_OK; +} + +int SDF_ReadFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer) +{ + if (!puiReadLength) + return SDR_INARGERR; + return SDR_OK; +} + +int SDF_WriteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer) +{ + return SDR_OK; +} + +int SDF_DeleteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen) +{ + return SDR_OK; +} diff --git a/src/sdf/sdf_ext.c b/src/sdf/sdf_ext.c index ac66e676..f3d6a49f 100644 --- a/src/sdf/sdf_ext.c +++ b/src/sdf/sdf_ext.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,256 +7,257 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include "sdf_int.h" -#include "sdf_sansec.h" - - -#define SDFerr(a,b) - - -typedef struct { - ULONG id; - char *name; -} table_item_t; - -static table_item_t sdf_cipher_caps[] = { - { SGD_SM1_ECB, "sm1-ecb" }, - { SGD_SM1_CBC, "sm1-cbc" }, - { SGD_SM1_CFB, "sm1-cfb" }, - { SGD_SM1_OFB, "sm1-ofb128" }, - { SGD_SM1_MAC, "cbcmac-sm1" }, - { SGD_SSF33_ECB, "ssf33-ecb" }, - { SGD_SSF33_CBC, "ssf33-cbc" }, - { SGD_SSF33_CFB, "ssf33-cfb" }, - { SGD_SSF33_OFB, "ssf33-ofb128" }, - { SGD_SSF33_MAC, "cbcmac-ssf33" }, - { SGD_SM4_ECB, "sms4-ecb" }, - { SGD_SM4_CBC, "sms4-cbc" }, - { SGD_SM4_CFB, "sms4-cfb" }, - { SGD_SM4_OFB, "sms4-ofb128" }, - { SGD_SM4_MAC, "cbcmac-sms4" }, - { SGD_ZUC_EEA3, "zuc_128eea3" }, - { SGD_ZUC_EIA3, "zuc_128eia3" } -}; - -static table_item_t sdf_digest_caps[] = { - { SGD_SM3, "sm3" }, - { SGD_SHA1, "sha1" }, - { SGD_SHA256, "sha256" }, -}; - -static table_item_t sdf_pkey_caps[] = { - { SGD_RSA_SIGN, "rsa" }, - { SGD_RSA_ENC, "rsaEncryption" }, - { SGD_SM2_1, "sm2sign" }, - { SGD_SM2_2, "sm2exchange" }, - { SGD_SM2_3, "sm2encrypt" } -}; - -int SDF_PrintDeviceInfo(FILE *fp, const DEVICEINFO *pstDeviceInfo) -{ - size_t i, n; - DEVICEINFO buf; - DEVICEINFO *devInfo = &buf; - int fmt = 0, ind = 4; - - memcpy(devInfo, pstDeviceInfo, sizeof(DEVICEINFO)); - devInfo->IssuerName[39] = 0; - devInfo->DeviceName[15] = 0; - devInfo->DeviceSerial[15] = 0; - - format_print(fp, fmt, ind, "%-18s: %s\n", "Device Name", devInfo->DeviceName); - format_print(fp, fmt, ind, "%-18s: %s\n", "Serial Number", devInfo->DeviceSerial); - format_print(fp, fmt, ind, "%-18s: %s\n", "Issuer", devInfo->IssuerName); - format_print(fp, fmt, ind, "%-18s: %u\n", "Hardware Version", devInfo->DeviceVersion); - format_print(fp, fmt, ind, "%-18s: %u\n", "Standard Version", devInfo->StandardVersion); - format_print(fp, fmt, ind, "%-18s: ", "Public Key Algors"); - for (i = n = 0; i < sizeof(sdf_pkey_caps)/sizeof(sdf_pkey_caps[0]); i++) { - if ((devInfo->AsymAlgAbility[0] & sdf_pkey_caps[i].id) == - sdf_pkey_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_pkey_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - - format_print(fp, fmt, ind, "%-18s: ", "Ciphers"); - for (i = n = 0; i < sizeof(sdf_cipher_caps)/sizeof(sdf_cipher_caps[0]); i++) { - if ((devInfo->SymAlgAbility & sdf_cipher_caps[i].id) == - sdf_cipher_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_cipher_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - - format_print(fp, fmt, ind, "%-18s: ", "Digests"); - for (i = n = 0; i < sizeof(sdf_digest_caps)/sizeof(sdf_digest_caps[0]); i++) { - if ((devInfo->HashAlgAbility & sdf_digest_caps[i].id) == - sdf_digest_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_digest_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - return SDR_OK; -} - -int SDF_PrintRSAPublicKey(FILE *fp, const RSArefPublicKey *blob) -{ - int fmt = 0, ind = 4; - (void)format_print(fp, fmt, ind, "bits: %d\n", blob->bits); - (void)format_bytes(fp, fmt, ind, "m", blob->m, sizeof(blob->m)); - (void)format_bytes(fp, fmt, ind, "e", blob->e, sizeof(blob->e)); - return SDR_OK; -} - -int SDF_PrintRSAPrivateKey(FILE *fp, const RSArefPrivateKey *blob) -{ - int fmt = 0, ind = 4; - (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); - (void)format_bytes(fp, fmt, ind, "m", blob->m, sizeof(blob->m)); - (void)format_bytes(fp, fmt, ind, "e", blob->e, sizeof(blob->e)); - (void)format_bytes(fp, fmt, ind, "d", blob->d, sizeof(blob->d)); - (void)format_bytes(fp, fmt, ind, "prime[0]", blob->prime[0], sizeof(blob->prime[0])); - (void)format_bytes(fp, fmt, ind, "prime[1]", blob->prime[1], sizeof(blob->prime[1])); - (void)format_bytes(fp, fmt, ind, "pexp[0]", blob->pexp[0], sizeof(blob->pexp[0])); - (void)format_bytes(fp, fmt, ind, "pexp[1]", blob->pexp[1], sizeof(blob->pexp[1])); - (void)format_bytes(fp, fmt, ind, "coef", blob->coef, sizeof(blob->coef)); - return SDR_OK; -} - -int SDF_PrintECCPublicKey(FILE *fp, const ECCrefPublicKey *blob) -{ - int fmt = 0, ind = 4; - (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); - (void)format_bytes(fp, fmt, ind, "x", blob->x, sizeof(blob->x)); - (void)format_bytes(fp, fmt, ind, "y", blob->y, sizeof(blob->y)); - return SDR_OK; -} - -int SDF_PrintECCPrivateKey(FILE *fp, const ECCrefPrivateKey *blob) -{ - int fmt = 0, ind = 4; - (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); - (void)format_bytes(fp, fmt, ind, "K", blob->K, sizeof(blob->K)); - return SDR_OK; -} - -int SDF_PrintECCCipher(FILE *fp, const ECCCipher *blob) -{ - int fmt = 0, ind = 4; - (void)format_bytes(fp, fmt, ind, "x", blob->x, sizeof(blob->x)); - (void)format_bytes(fp, fmt, ind, "y", blob->y, sizeof(blob->y)); - (void)format_bytes(fp, fmt, ind, "M", blob->M, sizeof(blob->M)); - (void)format_print(fp, fmt, ind, "L: %d", blob->L); - (void)format_bytes(fp, fmt, ind, "C", blob->C, sizeof(blob->C)); - return SDR_OK; -} - -int SDF_PrintECCSignature(FILE *fp, const ECCSignature *blob) -{ - int fmt = 0, ind = 4; - (void)format_bytes(fp, fmt, ind, "r", blob->r, sizeof(blob->r)); - (void)format_bytes(fp, fmt, ind, "s", blob->s, sizeof(blob->s)); - return SDR_OK; -} - -int SDF_ImportKey( - void *hSessionHandle, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle) -{ - (void)hSessionHandle; - (void)pucKey; - (void)uiKeyLength; - (void)phKeyHandle; - SDFerr(SDF_F_SDF_IMPORTKEY, SDF_R_NOT_IMPLEMENTED); - return SDR_NOTSUPPORT; -} - -int SDF_NewECCCipher(ECCCipher **cipher, size_t ulDataLen) -{ - ECCCipher *ecc_cipher = NULL; - size_t len; - - if (!cipher) { - SDFerr(SDF_F_SDF_NEWECCCIPHER, ERR_R_PASSED_NULL_PARAMETER); - return SDR_INARGERR; - } - - if (!ulDataLen || ulDataLen > INT_MAX) { - SDFerr(SDF_F_SDF_NEWECCCIPHER, - SDF_R_INVALID_SM2_CIPHERTEXT_LENGTH); - return SDR_INARGERR; - } - - len = sizeof(ECCCipher) - 1 + ulDataLen; - if (len < sizeof(SANSEC_ECCCipher)) { - len = sizeof(SANSEC_ECCCipher); - } - - if (!(ecc_cipher = malloc(len))) { - SDFerr(SDF_F_SDF_NEWECCCIPHER, ERR_R_MALLOC_FAILURE); - return SDR_NOBUFFER; - } - memset(ecc_cipher, 0, sizeof(*ecc_cipher)); - - ecc_cipher->L = (unsigned int)ulDataLen; - - *cipher = ecc_cipher; - return SDR_OK; -} - -int SDF_FreeECCCipher(ECCCipher *cipher) -{ - free(cipher); - return SDR_OK; -} - -const char *SDF_GetErrorReason(int err) -{ - switch (err) { - case SDR_OK: return "SDR_OK"; - case SDR_BASE: return "SDR_BASE"; - case SDR_UNKNOWERR: return "SDR_UNKNOWERR"; - case SDR_NOTSUPPORT: return "SDR_NOTSUPPORT"; - case SDR_COMMFAIL: return "SDR_COMMFAIL"; - case SDR_HARDFAIL: return "SDR_HARDFAIL"; - case SDR_OPENDEVICE: return "SDR_OPENDEVICE"; - case SDR_OPENSESSION: return "SDR_OPENSESSION"; - case SDR_PARDENY: return "SDR_PARDENY"; - case SDR_KEYNOTEXIST: return "SDR_KEYNOTEXIST"; - case SDR_ALGNOTSUPPORT: return "SDR_ALGNOTSUPPORT"; - case SDR_ALGMODNOTSUPPORT: return "SDR_ALGMODNOTSUPPORT"; - case SDR_PKOPERR: return "SDR_PKOPERR"; - case SDR_SKOPERR: return "SDR_SKOPERR"; - case SDR_SIGNERR: return "SDR_SIGNERR"; - case SDR_VERIFYERR: return "SDR_VERIFYERR"; - case SDR_SYMOPERR: return "SDR_SYMOPERR"; - case SDR_STEPERR: return "SDR_STEPERR"; - case SDR_FILESIZEERR: return "SDR_FILESIZEERR"; - case SDR_FILENOEXIST: return "SDR_FILENOEXIST"; - case SDR_FILEOFSERR: return "SDR_FILEOFSERR"; - case SDR_KEYTYPEERR: return "SDR_KEYTYPEERR"; - case SDR_KEYERR: return "SDR_KEYERR"; - case SDR_ENCDATAERR: return "SDR_ENCDATAERR"; - case SDR_RANDERR: return "SDR_RANDERR"; - case SDR_PRKRERR: return "SDR_PRKRERR"; - case SDR_MACERR: return "SDR_MACERR"; - case SDR_FILEEXSITS: return "SDR_FILEEXSITS"; - case SDR_FILEWERR: return "SDR_FILEWERR"; - case SDR_NOBUFFER: return "SDR_NOBUFFER"; - case SDR_INARGERR: return "SDR_INARGERR"; - case SDR_OUTARGERR: return "SDR_OUTARGERR"; - } - return "(unknown)"; -} + + +#include +#include +#include +#include +#include +#include +#include "sdf_int.h" +#include "sdf_sansec.h" + + +#define SDFerr(a,b) + + +typedef struct { + ULONG id; + char *name; +} table_item_t; + +static table_item_t sdf_cipher_caps[] = { + { SGD_SM1_ECB, "sm1-ecb" }, + { SGD_SM1_CBC, "sm1-cbc" }, + { SGD_SM1_CFB, "sm1-cfb" }, + { SGD_SM1_OFB, "sm1-ofb128" }, + { SGD_SM1_MAC, "cbcmac-sm1" }, + { SGD_SSF33_ECB, "ssf33-ecb" }, + { SGD_SSF33_CBC, "ssf33-cbc" }, + { SGD_SSF33_CFB, "ssf33-cfb" }, + { SGD_SSF33_OFB, "ssf33-ofb128" }, + { SGD_SSF33_MAC, "cbcmac-ssf33" }, + { SGD_SM4_ECB, "sms4-ecb" }, + { SGD_SM4_CBC, "sms4-cbc" }, + { SGD_SM4_CFB, "sms4-cfb" }, + { SGD_SM4_OFB, "sms4-ofb128" }, + { SGD_SM4_MAC, "cbcmac-sms4" }, + { SGD_ZUC_EEA3, "zuc_128eea3" }, + { SGD_ZUC_EIA3, "zuc_128eia3" } +}; + +static table_item_t sdf_digest_caps[] = { + { SGD_SM3, "sm3" }, + { SGD_SHA1, "sha1" }, + { SGD_SHA256, "sha256" }, +}; + +static table_item_t sdf_pkey_caps[] = { + { SGD_RSA_SIGN, "rsa" }, + { SGD_RSA_ENC, "rsaEncryption" }, + { SGD_SM2_1, "sm2sign" }, + { SGD_SM2_2, "sm2exchange" }, + { SGD_SM2_3, "sm2encrypt" } +}; + +int SDF_PrintDeviceInfo(FILE *fp, const DEVICEINFO *pstDeviceInfo) +{ + size_t i, n; + DEVICEINFO buf; + DEVICEINFO *devInfo = &buf; + int fmt = 0, ind = 4; + + memcpy(devInfo, pstDeviceInfo, sizeof(DEVICEINFO)); + devInfo->IssuerName[39] = 0; + devInfo->DeviceName[15] = 0; + devInfo->DeviceSerial[15] = 0; + + format_print(fp, fmt, ind, "%-18s: %s\n", "Device Name", devInfo->DeviceName); + format_print(fp, fmt, ind, "%-18s: %s\n", "Serial Number", devInfo->DeviceSerial); + format_print(fp, fmt, ind, "%-18s: %s\n", "Issuer", devInfo->IssuerName); + format_print(fp, fmt, ind, "%-18s: %u\n", "Hardware Version", devInfo->DeviceVersion); + format_print(fp, fmt, ind, "%-18s: %u\n", "Standard Version", devInfo->StandardVersion); + format_print(fp, fmt, ind, "%-18s: ", "Public Key Algors"); + for (i = n = 0; i < sizeof(sdf_pkey_caps)/sizeof(sdf_pkey_caps[0]); i++) { + if ((devInfo->AsymAlgAbility[0] & sdf_pkey_caps[i].id) == + sdf_pkey_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_pkey_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "%-18s: ", "Ciphers"); + for (i = n = 0; i < sizeof(sdf_cipher_caps)/sizeof(sdf_cipher_caps[0]); i++) { + if ((devInfo->SymAlgAbility & sdf_cipher_caps[i].id) == + sdf_cipher_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_cipher_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "%-18s: ", "Digests"); + for (i = n = 0; i < sizeof(sdf_digest_caps)/sizeof(sdf_digest_caps[0]); i++) { + if ((devInfo->HashAlgAbility & sdf_digest_caps[i].id) == + sdf_digest_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", sdf_digest_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + return SDR_OK; +} + +int SDF_PrintRSAPublicKey(FILE *fp, const RSArefPublicKey *blob) +{ + int fmt = 0, ind = 4; + (void)format_print(fp, fmt, ind, "bits: %d\n", blob->bits); + (void)format_bytes(fp, fmt, ind, "m", blob->m, sizeof(blob->m)); + (void)format_bytes(fp, fmt, ind, "e", blob->e, sizeof(blob->e)); + return SDR_OK; +} + +int SDF_PrintRSAPrivateKey(FILE *fp, const RSArefPrivateKey *blob) +{ + int fmt = 0, ind = 4; + (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); + (void)format_bytes(fp, fmt, ind, "m", blob->m, sizeof(blob->m)); + (void)format_bytes(fp, fmt, ind, "e", blob->e, sizeof(blob->e)); + (void)format_bytes(fp, fmt, ind, "d", blob->d, sizeof(blob->d)); + (void)format_bytes(fp, fmt, ind, "prime[0]", blob->prime[0], sizeof(blob->prime[0])); + (void)format_bytes(fp, fmt, ind, "prime[1]", blob->prime[1], sizeof(blob->prime[1])); + (void)format_bytes(fp, fmt, ind, "pexp[0]", blob->pexp[0], sizeof(blob->pexp[0])); + (void)format_bytes(fp, fmt, ind, "pexp[1]", blob->pexp[1], sizeof(blob->pexp[1])); + (void)format_bytes(fp, fmt, ind, "coef", blob->coef, sizeof(blob->coef)); + return SDR_OK; +} + +int SDF_PrintECCPublicKey(FILE *fp, const ECCrefPublicKey *blob) +{ + int fmt = 0, ind = 4; + (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); + (void)format_bytes(fp, fmt, ind, "x", blob->x, sizeof(blob->x)); + (void)format_bytes(fp, fmt, ind, "y", blob->y, sizeof(blob->y)); + return SDR_OK; +} + +int SDF_PrintECCPrivateKey(FILE *fp, const ECCrefPrivateKey *blob) +{ + int fmt = 0, ind = 4; + (void)format_print(fp, fmt, ind, "bits: %d", blob->bits); + (void)format_bytes(fp, fmt, ind, "K", blob->K, sizeof(blob->K)); + return SDR_OK; +} + +int SDF_PrintECCCipher(FILE *fp, const ECCCipher *blob) +{ + int fmt = 0, ind = 4; + (void)format_bytes(fp, fmt, ind, "x", blob->x, sizeof(blob->x)); + (void)format_bytes(fp, fmt, ind, "y", blob->y, sizeof(blob->y)); + (void)format_bytes(fp, fmt, ind, "M", blob->M, sizeof(blob->M)); + (void)format_print(fp, fmt, ind, "L: %d", blob->L); + (void)format_bytes(fp, fmt, ind, "C", blob->C, sizeof(blob->C)); + return SDR_OK; +} + +int SDF_PrintECCSignature(FILE *fp, const ECCSignature *blob) +{ + int fmt = 0, ind = 4; + (void)format_bytes(fp, fmt, ind, "r", blob->r, sizeof(blob->r)); + (void)format_bytes(fp, fmt, ind, "s", blob->s, sizeof(blob->s)); + return SDR_OK; +} + +int SDF_ImportKey( + void *hSessionHandle, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + (void)hSessionHandle; + (void)pucKey; + (void)uiKeyLength; + (void)phKeyHandle; + SDFerr(SDF_F_SDF_IMPORTKEY, SDF_R_NOT_IMPLEMENTED); + return SDR_NOTSUPPORT; +} + +int SDF_NewECCCipher(ECCCipher **cipher, size_t ulDataLen) +{ + ECCCipher *ecc_cipher = NULL; + size_t len; + + if (!cipher) { + SDFerr(SDF_F_SDF_NEWECCCIPHER, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + + if (!ulDataLen || ulDataLen > INT_MAX) { + SDFerr(SDF_F_SDF_NEWECCCIPHER, + SDF_R_INVALID_SM2_CIPHERTEXT_LENGTH); + return SDR_INARGERR; + } + + len = sizeof(ECCCipher) - 1 + ulDataLen; + if (len < sizeof(SANSEC_ECCCipher)) { + len = sizeof(SANSEC_ECCCipher); + } + + if (!(ecc_cipher = malloc(len))) { + SDFerr(SDF_F_SDF_NEWECCCIPHER, ERR_R_MALLOC_FAILURE); + return SDR_NOBUFFER; + } + memset(ecc_cipher, 0, sizeof(*ecc_cipher)); + + ecc_cipher->L = (unsigned int)ulDataLen; + + *cipher = ecc_cipher; + return SDR_OK; +} + +int SDF_FreeECCCipher(ECCCipher *cipher) +{ + free(cipher); + return SDR_OK; +} + +const char *SDF_GetErrorReason(int err) +{ + switch (err) { + case SDR_OK: return "SDR_OK"; + case SDR_BASE: return "SDR_BASE"; + case SDR_UNKNOWERR: return "SDR_UNKNOWERR"; + case SDR_NOTSUPPORT: return "SDR_NOTSUPPORT"; + case SDR_COMMFAIL: return "SDR_COMMFAIL"; + case SDR_HARDFAIL: return "SDR_HARDFAIL"; + case SDR_OPENDEVICE: return "SDR_OPENDEVICE"; + case SDR_OPENSESSION: return "SDR_OPENSESSION"; + case SDR_PARDENY: return "SDR_PARDENY"; + case SDR_KEYNOTEXIST: return "SDR_KEYNOTEXIST"; + case SDR_ALGNOTSUPPORT: return "SDR_ALGNOTSUPPORT"; + case SDR_ALGMODNOTSUPPORT: return "SDR_ALGMODNOTSUPPORT"; + case SDR_PKOPERR: return "SDR_PKOPERR"; + case SDR_SKOPERR: return "SDR_SKOPERR"; + case SDR_SIGNERR: return "SDR_SIGNERR"; + case SDR_VERIFYERR: return "SDR_VERIFYERR"; + case SDR_SYMOPERR: return "SDR_SYMOPERR"; + case SDR_STEPERR: return "SDR_STEPERR"; + case SDR_FILESIZEERR: return "SDR_FILESIZEERR"; + case SDR_FILENOEXIST: return "SDR_FILENOEXIST"; + case SDR_FILEOFSERR: return "SDR_FILEOFSERR"; + case SDR_KEYTYPEERR: return "SDR_KEYTYPEERR"; + case SDR_KEYERR: return "SDR_KEYERR"; + case SDR_ENCDATAERR: return "SDR_ENCDATAERR"; + case SDR_RANDERR: return "SDR_RANDERR"; + case SDR_PRKRERR: return "SDR_PRKRERR"; + case SDR_MACERR: return "SDR_MACERR"; + case SDR_FILEEXSITS: return "SDR_FILEEXSITS"; + case SDR_FILEWERR: return "SDR_FILEWERR"; + case SDR_NOBUFFER: return "SDR_NOBUFFER"; + case SDR_INARGERR: return "SDR_INARGERR"; + case SDR_OUTARGERR: return "SDR_OUTARGERR"; + } + return "(unknown)"; +} diff --git a/src/sdf/sdf_ext.h b/src/sdf/sdf_ext.h index 4bfdb314..c2fe7ac9 100644 --- a/src/sdf/sdf_ext.h +++ b/src/sdf/sdf_ext.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,48 +7,49 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef SDFUTIL_SDF_EXT_H -#define SDFUTIL_SDF_EXT_H - - -#include -#include -#include "../sgd.h" -#include "sdf.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SDF_MIN_KEY_INDEX 1 /* defined by GM/T 0018 */ -#define SDF_MAX_KEY_INDEX 32 /* defined by GmSSL */ -#define SDF_MIN_PASSWORD_LENGTH 8 /* defined by GM/T 0018 */ -#define SDF_MAX_PASSWORD_LENGTH 255 /* defined by GmSSL */ -#define SDF_MAX_FILE_SIZE (256 * 1024) - - - -int SDF_LoadLibrary(char *so_path, char *vendor); -int SDF_UnloadLibrary(void); -int SDF_ImportKey(void *hSessionHandle, unsigned char *pucKey, - unsigned int uiKeyLength, void **phKeyHandle); - -int SDF_PrintDeviceInfo(FILE *fp, const DEVICEINFO *devInfo); -int SDF_PrintRSAPublicKey(FILE *fp, const RSArefPublicKey *ref); -int SDF_PrintRSAPrivateKey(FILE *fp, const RSArefPrivateKey *ref); -int SDF_PrintECCPublicKey(FILE *fp, const ECCrefPublicKey *ref); -int SDF_PrintECCPrivateKey(FILE *fp, const ECCrefPrivateKey *ref); -int SDF_NewECCCipher(ECCCipher **cipher, size_t ulDataLen); // FIMXE: 和GmSSL的内存使用方式不同 -int SDF_FreeECCCipher(ECCCipher *cipher); -int SDF_PrintECCCipher(FILE *out, ECCCipher *cipher); -int SDF_PrintECCSignature(FILE *out, ECCSignature *sig); -const char *SDF_GetErrorReason(int err); - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef SDFUTIL_SDF_EXT_H +#define SDFUTIL_SDF_EXT_H + + +#include +#include +#include "../sgd.h" +#include "sdf.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SDF_MIN_KEY_INDEX 1 /* defined by GM/T 0018 */ +#define SDF_MAX_KEY_INDEX 32 /* defined by GmSSL */ +#define SDF_MIN_PASSWORD_LENGTH 8 /* defined by GM/T 0018 */ +#define SDF_MAX_PASSWORD_LENGTH 255 /* defined by GmSSL */ +#define SDF_MAX_FILE_SIZE (256 * 1024) + + + +int SDF_LoadLibrary(char *so_path, char *vendor); +int SDF_UnloadLibrary(void); +int SDF_ImportKey(void *hSessionHandle, unsigned char *pucKey, + unsigned int uiKeyLength, void **phKeyHandle); + +int SDF_PrintDeviceInfo(FILE *fp, const DEVICEINFO *devInfo); +int SDF_PrintRSAPublicKey(FILE *fp, const RSArefPublicKey *ref); +int SDF_PrintRSAPrivateKey(FILE *fp, const RSArefPrivateKey *ref); +int SDF_PrintECCPublicKey(FILE *fp, const ECCrefPublicKey *ref); +int SDF_PrintECCPrivateKey(FILE *fp, const ECCrefPrivateKey *ref); +int SDF_NewECCCipher(ECCCipher **cipher, size_t ulDataLen); // FIMXE: 和GmSSL的内存使用方式不同 +int SDF_FreeECCCipher(ECCCipher *cipher); +int SDF_PrintECCCipher(FILE *out, ECCCipher *cipher); +int SDF_PrintECCSignature(FILE *out, ECCSignature *sig); +const char *SDF_GetErrorReason(int err); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/sdf/sdf_int.h b/src/sdf/sdf_int.h index 4e3027d1..f328ffd7 100644 --- a/src/sdf/sdf_int.h +++ b/src/sdf/sdf_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,415 +7,416 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef SDFUTIL_SDF_METH_H -#define SDFUTIL_SDF_METH_H - -#include "sdf.h" - -typedef int (*SDF_OpenDevice_FuncPtr)( - void **phDeviceHandle); - -typedef int (*SDF_CloseDevice_FuncPtr)( - void *hDeviceHandle); - -typedef int (*SDF_OpenSession_FuncPtr)( - void *hDeviceHandle, - void **phSessionHandle); - -typedef int (*SDF_CloseSession_FuncPtr)( - void *hSessionHandle); - -typedef int (*SDF_GetDeviceInfo_FuncPtr)( - void *hSessionHandle, - DEVICEINFO *pstDeviceInfo); - -typedef int (*SDF_GenerateRandom_FuncPtr)( - void *hSessionHandle, - unsigned int uiLength, - unsigned char *pucRandom); - -typedef int (*SDF_GetPrivateKeyAccessRight_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucPassword, - unsigned int uiPwdLength); - -typedef int (*SDF_ReleasePrivateKeyAccessRight_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex); - -typedef int (*SDF_ExportSignPublicKey_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey); - -typedef int (*SDF_ExportEncPublicKey_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey); - -typedef int (*SDF_GenerateKeyPair_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - RSArefPrivateKey *pucPrivateKey); - -typedef int (*SDF_GenerateKeyWithIPK_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -typedef int (*SDF_GenerateKeyWithEPK_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -typedef int (*SDF_ImportKeyWithISK_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle); - -typedef int (*SDF_ExchangeDigitEnvelopeBaseOnRSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDEInput, - unsigned int uiDELength, - unsigned char *pucDEOutput, - unsigned int *puiDELength); - -typedef int (*SDF_ExportSignPublicKey_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey); - -typedef int (*SDF_ExportEncPublicKey_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey); - -typedef int (*SDF_GenerateKeyPair_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKeyBits, - ECCrefPublicKey *pucPublicKey, - ECCrefPrivateKey *pucPrivateKey); - -typedef int (*SDF_GenerateKeyWithIPK_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - ECCCipher *pucKey, - void **phKeyHandle); - -typedef int (*SDF_GenerateKeyWithEPK_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucKey, - void **phKeyHandle); - -typedef int (*SDF_ImportKeyWithISK_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - ECCCipher *pucKey, - void **phKeyHandle); - -typedef int (*SDF_GenerateAgreementDataWithECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - void **phAgreementHandle); - -typedef int (*SDF_GenerateKeyWithECC_FuncPtr)( - void *hSessionHandle, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void *hAgreementHandle, - void **phKeyHandle); - -typedef int (*SDF_GenerateAgreementDataAndKeyWithECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void **phKeyHandle); - -typedef int (*SDF_ExchangeDigitEnvelopeBaseOnECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucEncDataIn, - ECCCipher *pucEncDataOut); - -typedef int (*SDF_GenerateKeyWithKEK_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -typedef int (*SDF_ImportKeyWithKEK_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle); - -typedef int (*SDF_DestroyKey_FuncPtr)( - void *hSessionHandle, - void *hKeyHandle); - -typedef int (*SDF_ExternalPublicKeyOperation_RSA_FuncPtr)( - void *hSessionHandle, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -typedef int (*SDF_InternalPublicKeyOperation_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -typedef int (*SDF_InternalPrivateKeyOperation_RSA_FuncPtr)( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -typedef int (*SDF_ExternalVerify_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - ECCSignature *pucSignature); - -typedef int (*SDF_InternalSign_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature); - -typedef int (*SDF_InternalVerify_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature); - -typedef int (*SDF_ExternalEncrypt_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData); - -typedef int (*SDF_ExternalDecrypt_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPrivateKey *pucPrivateKey, - ECCCipher *pucEncData, - unsigned char *pucData, - unsigned int *puiDataLength); - -typedef int (*SDF_InternalEncrypt_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiAlgID, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData); - -typedef int (*SDF_InternalDecrypt_ECC_FuncPtr)( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiAlgID, - ECCCipher *pucEncData, - unsigned char *pucData, - unsigned int *puiDataLength); - -typedef int (*SDF_Encrypt_FuncPtr)( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucEncData, - unsigned int *puiEncDataLength); - -typedef int (*SDF_Decrypt_FuncPtr)( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucEncData, - unsigned int uiEncDataLength, - unsigned char *pucData, - unsigned int *puiDataLength); - -typedef int (*SDF_CalculateMAC_FuncPtr)( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucMAC, - unsigned int *puiMACLength); - -typedef int (*SDF_HashInit_FuncPtr)( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucID, - unsigned int uiIDLength); - -typedef int (*SDF_HashUpdate_FuncPtr)( - void *hSessionHandle, - unsigned char *pucData, - unsigned int uiDataLength); - -typedef int (*SDF_HashFinal_FuncPtr)(void *hSessionHandle, - unsigned char *pucHash, - unsigned int *puiHashLength); - -typedef int (*SDF_CreateObject_FuncPtr)( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiFileSize); - -typedef int (*SDF_ReadObject_FuncPtr)( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int *puiReadLength, - unsigned char *pucBuffer); - -typedef int (*SDF_WriteObject_FuncPtr)( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int uiWriteLength, - unsigned char *pucBuffer); - -typedef int (*SDF_DeleteObject_FuncPtr)( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen); - -typedef struct sdf_method_st { - char *name; - void *dso; - SDF_OpenDevice_FuncPtr OpenDevice; - SDF_CloseDevice_FuncPtr CloseDevice; - SDF_OpenSession_FuncPtr OpenSession; - SDF_CloseSession_FuncPtr CloseSession; - SDF_GetDeviceInfo_FuncPtr GetDeviceInfo; - SDF_GenerateRandom_FuncPtr GenerateRandom; - SDF_GetPrivateKeyAccessRight_FuncPtr GetPrivateKeyAccessRight; - SDF_ReleasePrivateKeyAccessRight_FuncPtr ReleasePrivateKeyAccessRight; - SDF_ExportSignPublicKey_RSA_FuncPtr ExportSignPublicKey_RSA; - SDF_ExportEncPublicKey_RSA_FuncPtr ExportEncPublicKey_RSA; - SDF_GenerateKeyPair_RSA_FuncPtr GenerateKeyPair_RSA; - SDF_GenerateKeyWithIPK_RSA_FuncPtr GenerateKeyWithIPK_RSA; - SDF_GenerateKeyWithEPK_RSA_FuncPtr GenerateKeyWithEPK_RSA; - SDF_ImportKeyWithISK_RSA_FuncPtr ImportKeyWithISK_RSA; - SDF_ExchangeDigitEnvelopeBaseOnRSA_FuncPtr ExchangeDigitEnvelopeBaseOnRSA; - SDF_ExportSignPublicKey_ECC_FuncPtr ExportSignPublicKey_ECC; - SDF_ExportEncPublicKey_ECC_FuncPtr ExportEncPublicKey_ECC; - SDF_GenerateKeyPair_ECC_FuncPtr GenerateKeyPair_ECC; - SDF_GenerateKeyWithIPK_ECC_FuncPtr GenerateKeyWithIPK_ECC; - SDF_GenerateKeyWithEPK_ECC_FuncPtr GenerateKeyWithEPK_ECC; - SDF_ImportKeyWithISK_ECC_FuncPtr ImportKeyWithISK_ECC; - SDF_GenerateAgreementDataWithECC_FuncPtr GenerateAgreementDataWithECC; - SDF_GenerateKeyWithECC_FuncPtr GenerateKeyWithECC; - SDF_GenerateAgreementDataAndKeyWithECC_FuncPtr GenerateAgreementDataAndKeyWithECC; - SDF_ExchangeDigitEnvelopeBaseOnECC_FuncPtr ExchangeDigitEnvelopeBaseOnECC; - SDF_GenerateKeyWithKEK_FuncPtr GenerateKeyWithKEK; - SDF_ImportKeyWithKEK_FuncPtr ImportKeyWithKEK; - SDF_DestroyKey_FuncPtr DestroyKey; - SDF_ExternalPublicKeyOperation_RSA_FuncPtr ExternalPublicKeyOperation_RSA; - SDF_InternalPublicKeyOperation_RSA_FuncPtr InternalPublicKeyOperation_RSA; - SDF_InternalPrivateKeyOperation_RSA_FuncPtr InternalPrivateKeyOperation_RSA; - SDF_ExternalVerify_ECC_FuncPtr ExternalVerify_ECC; - SDF_InternalSign_ECC_FuncPtr InternalSign_ECC; - SDF_InternalVerify_ECC_FuncPtr InternalVerify_ECC; - SDF_ExternalEncrypt_ECC_FuncPtr ExternalEncrypt_ECC; - SDF_ExternalDecrypt_ECC_FuncPtr ExternalDecrypt_ECC; - SDF_InternalEncrypt_ECC_FuncPtr InternalEncrypt_ECC; - SDF_InternalDecrypt_ECC_FuncPtr InternalDecrypt_ECC; - SDF_Encrypt_FuncPtr Encrypt; - SDF_Decrypt_FuncPtr Decrypt; - SDF_CalculateMAC_FuncPtr CalculateMAC; - SDF_HashInit_FuncPtr HashInit; - SDF_HashUpdate_FuncPtr HashUpdate; - SDF_HashFinal_FuncPtr HashFinal; - SDF_CreateObject_FuncPtr CreateObject; - SDF_ReadObject_FuncPtr ReadObject; - SDF_WriteObject_FuncPtr WriteObject; - SDF_DeleteObject_FuncPtr DeleteObject; -} SDF_METHOD; - -SDF_METHOD *SDF_METHOD_load_library(const char *so_path); -void SDF_METHOD_free(SDF_METHOD *meth); - - -typedef struct sdf_vendor_st { - char *name; - unsigned int (*cipher_vendor2std)(unsigned int vendor_id); - unsigned int (*cipher_std2vendor)(unsigned int std_id); - unsigned int (*cipher_cap)(unsigned int vendor_cap); - unsigned int (*digest_vendor2std)(unsigned int vendor_id); - unsigned int (*digest_std2vendor)(unsigned int std_id); - unsigned int (*digest_cap)(unsigned int vendor_cap); - unsigned int (*pkey_vendor2std)(unsigned int vendor_id); - unsigned int (*pkey_std2vendor)(unsigned int std_id); - unsigned int (*pkey_cap)(unsigned int vendor_cap); - int (*encode_ecccipher)(const ECCCipher *a, void *buf); - int (*decode_ecccipher)(ECCCipher *a, const void *buf); - unsigned long (*get_error_reason)(int err); -} SDF_VENDOR; - - -#endif + + +#ifndef SDFUTIL_SDF_METH_H +#define SDFUTIL_SDF_METH_H + +#include "sdf.h" + +typedef int (*SDF_OpenDevice_FuncPtr)( + void **phDeviceHandle); + +typedef int (*SDF_CloseDevice_FuncPtr)( + void *hDeviceHandle); + +typedef int (*SDF_OpenSession_FuncPtr)( + void *hDeviceHandle, + void **phSessionHandle); + +typedef int (*SDF_CloseSession_FuncPtr)( + void *hSessionHandle); + +typedef int (*SDF_GetDeviceInfo_FuncPtr)( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo); + +typedef int (*SDF_GenerateRandom_FuncPtr)( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom); + +typedef int (*SDF_GetPrivateKeyAccessRight_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength); + +typedef int (*SDF_ReleasePrivateKeyAccessRight_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex); + +typedef int (*SDF_ExportSignPublicKey_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey); + +typedef int (*SDF_ExportEncPublicKey_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey); + +typedef int (*SDF_GenerateKeyPair_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey); + +typedef int (*SDF_GenerateKeyWithIPK_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +typedef int (*SDF_GenerateKeyWithEPK_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +typedef int (*SDF_ImportKeyWithISK_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle); + +typedef int (*SDF_ExchangeDigitEnvelopeBaseOnRSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength); + +typedef int (*SDF_ExportSignPublicKey_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey); + +typedef int (*SDF_ExportEncPublicKey_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey); + +typedef int (*SDF_GenerateKeyPair_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey); + +typedef int (*SDF_GenerateKeyWithIPK_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + ECCCipher *pucKey, + void **phKeyHandle); + +typedef int (*SDF_GenerateKeyWithEPK_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle); + +typedef int (*SDF_ImportKeyWithISK_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle); + +typedef int (*SDF_GenerateAgreementDataWithECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle); + +typedef int (*SDF_GenerateKeyWithECC_FuncPtr)( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle); + +typedef int (*SDF_GenerateAgreementDataAndKeyWithECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle); + +typedef int (*SDF_ExchangeDigitEnvelopeBaseOnECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut); + +typedef int (*SDF_GenerateKeyWithKEK_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +typedef int (*SDF_ImportKeyWithKEK_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle); + +typedef int (*SDF_DestroyKey_FuncPtr)( + void *hSessionHandle, + void *hKeyHandle); + +typedef int (*SDF_ExternalPublicKeyOperation_RSA_FuncPtr)( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +typedef int (*SDF_InternalPublicKeyOperation_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +typedef int (*SDF_InternalPrivateKeyOperation_RSA_FuncPtr)( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +typedef int (*SDF_ExternalVerify_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature); + +typedef int (*SDF_InternalSign_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature); + +typedef int (*SDF_InternalVerify_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature); + +typedef int (*SDF_ExternalEncrypt_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData); + +typedef int (*SDF_ExternalDecrypt_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPrivateKey *pucPrivateKey, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength); + +typedef int (*SDF_InternalEncrypt_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiAlgID, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData); + +typedef int (*SDF_InternalDecrypt_ECC_FuncPtr)( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiAlgID, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength); + +typedef int (*SDF_Encrypt_FuncPtr)( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength); + +typedef int (*SDF_Decrypt_FuncPtr)( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucEncData, + unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength); + +typedef int (*SDF_CalculateMAC_FuncPtr)( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucMAC, + unsigned int *puiMACLength); + +typedef int (*SDF_HashInit_FuncPtr)( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength); + +typedef int (*SDF_HashUpdate_FuncPtr)( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength); + +typedef int (*SDF_HashFinal_FuncPtr)(void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength); + +typedef int (*SDF_CreateObject_FuncPtr)( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiFileSize); + +typedef int (*SDF_ReadObject_FuncPtr)( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer); + +typedef int (*SDF_WriteObject_FuncPtr)( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer); + +typedef int (*SDF_DeleteObject_FuncPtr)( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen); + +typedef struct sdf_method_st { + char *name; + void *dso; + SDF_OpenDevice_FuncPtr OpenDevice; + SDF_CloseDevice_FuncPtr CloseDevice; + SDF_OpenSession_FuncPtr OpenSession; + SDF_CloseSession_FuncPtr CloseSession; + SDF_GetDeviceInfo_FuncPtr GetDeviceInfo; + SDF_GenerateRandom_FuncPtr GenerateRandom; + SDF_GetPrivateKeyAccessRight_FuncPtr GetPrivateKeyAccessRight; + SDF_ReleasePrivateKeyAccessRight_FuncPtr ReleasePrivateKeyAccessRight; + SDF_ExportSignPublicKey_RSA_FuncPtr ExportSignPublicKey_RSA; + SDF_ExportEncPublicKey_RSA_FuncPtr ExportEncPublicKey_RSA; + SDF_GenerateKeyPair_RSA_FuncPtr GenerateKeyPair_RSA; + SDF_GenerateKeyWithIPK_RSA_FuncPtr GenerateKeyWithIPK_RSA; + SDF_GenerateKeyWithEPK_RSA_FuncPtr GenerateKeyWithEPK_RSA; + SDF_ImportKeyWithISK_RSA_FuncPtr ImportKeyWithISK_RSA; + SDF_ExchangeDigitEnvelopeBaseOnRSA_FuncPtr ExchangeDigitEnvelopeBaseOnRSA; + SDF_ExportSignPublicKey_ECC_FuncPtr ExportSignPublicKey_ECC; + SDF_ExportEncPublicKey_ECC_FuncPtr ExportEncPublicKey_ECC; + SDF_GenerateKeyPair_ECC_FuncPtr GenerateKeyPair_ECC; + SDF_GenerateKeyWithIPK_ECC_FuncPtr GenerateKeyWithIPK_ECC; + SDF_GenerateKeyWithEPK_ECC_FuncPtr GenerateKeyWithEPK_ECC; + SDF_ImportKeyWithISK_ECC_FuncPtr ImportKeyWithISK_ECC; + SDF_GenerateAgreementDataWithECC_FuncPtr GenerateAgreementDataWithECC; + SDF_GenerateKeyWithECC_FuncPtr GenerateKeyWithECC; + SDF_GenerateAgreementDataAndKeyWithECC_FuncPtr GenerateAgreementDataAndKeyWithECC; + SDF_ExchangeDigitEnvelopeBaseOnECC_FuncPtr ExchangeDigitEnvelopeBaseOnECC; + SDF_GenerateKeyWithKEK_FuncPtr GenerateKeyWithKEK; + SDF_ImportKeyWithKEK_FuncPtr ImportKeyWithKEK; + SDF_DestroyKey_FuncPtr DestroyKey; + SDF_ExternalPublicKeyOperation_RSA_FuncPtr ExternalPublicKeyOperation_RSA; + SDF_InternalPublicKeyOperation_RSA_FuncPtr InternalPublicKeyOperation_RSA; + SDF_InternalPrivateKeyOperation_RSA_FuncPtr InternalPrivateKeyOperation_RSA; + SDF_ExternalVerify_ECC_FuncPtr ExternalVerify_ECC; + SDF_InternalSign_ECC_FuncPtr InternalSign_ECC; + SDF_InternalVerify_ECC_FuncPtr InternalVerify_ECC; + SDF_ExternalEncrypt_ECC_FuncPtr ExternalEncrypt_ECC; + SDF_ExternalDecrypt_ECC_FuncPtr ExternalDecrypt_ECC; + SDF_InternalEncrypt_ECC_FuncPtr InternalEncrypt_ECC; + SDF_InternalDecrypt_ECC_FuncPtr InternalDecrypt_ECC; + SDF_Encrypt_FuncPtr Encrypt; + SDF_Decrypt_FuncPtr Decrypt; + SDF_CalculateMAC_FuncPtr CalculateMAC; + SDF_HashInit_FuncPtr HashInit; + SDF_HashUpdate_FuncPtr HashUpdate; + SDF_HashFinal_FuncPtr HashFinal; + SDF_CreateObject_FuncPtr CreateObject; + SDF_ReadObject_FuncPtr ReadObject; + SDF_WriteObject_FuncPtr WriteObject; + SDF_DeleteObject_FuncPtr DeleteObject; +} SDF_METHOD; + +SDF_METHOD *SDF_METHOD_load_library(const char *so_path); +void SDF_METHOD_free(SDF_METHOD *meth); + + +typedef struct sdf_vendor_st { + char *name; + unsigned int (*cipher_vendor2std)(unsigned int vendor_id); + unsigned int (*cipher_std2vendor)(unsigned int std_id); + unsigned int (*cipher_cap)(unsigned int vendor_cap); + unsigned int (*digest_vendor2std)(unsigned int vendor_id); + unsigned int (*digest_std2vendor)(unsigned int std_id); + unsigned int (*digest_cap)(unsigned int vendor_cap); + unsigned int (*pkey_vendor2std)(unsigned int vendor_id); + unsigned int (*pkey_std2vendor)(unsigned int std_id); + unsigned int (*pkey_cap)(unsigned int vendor_cap); + int (*encode_ecccipher)(const ECCCipher *a, void *buf); + int (*decode_ecccipher)(ECCCipher *a, const void *buf); + unsigned long (*get_error_reason)(int err); +} SDF_VENDOR; + + +#endif diff --git a/src/sdf/sdf_lib.c b/src/sdf/sdf_lib.c index 4d4e97ab..0a579007 100644 --- a/src/sdf/sdf_lib.c +++ b/src/sdf/sdf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1462 +7,1463 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include "sdf_ext.h" -#include "sdf_int.h" - -SDF_METHOD *sdf_method = NULL; -SDF_VENDOR *sdf_vendor = NULL; -extern SDF_VENDOR sdf_sansec; - - -#define SDFerr(reason) fprintf(stderr,"sdfutil: %s %d: %s %s\n", __FILE__, __LINE__, __FUNCTION__, reason) - - -#define SDF_R_LOAD_LIBRARY_FAILURE "SDF_R_LOAD_LIBRARY_FAILURE" -#define SDF_R_NOT_INITIALIZED "SDF_R_NOT_INITIALIZED" -#define SDF_R_NOT_SUPPORTED_ECC_ALGOR "SDF_R_NOT_SUPPORTED_ECC_ALGOR" -#define SDF_R_NOT_SUPPORTED_CIPHER_ALGOR "SDF_R_NOT_SUPPORTED_CIPHER_ALGOR" -#define SDF_R_BUFFER_TOO_SMALL "SDF_R_BUFFER_TOO_SMALL" -#define SDF_R_NOT_SUPPORTED_PKEY_ALGOR "SDF_R_NOT_SUPPORTED_PKEY_ALGOR" -#define SDF_R_NOT_SUPPORTED_DIGEST_ALGOR "SDF_R_NOT_SUPPORTED_DIGEST_ALGOR" -#define ERR_R_SDF_LIB "ERR_R_SDF_LIB" - - - -int SDF_LoadLibrary(char *so_path, char *vendor) -{ - if (sdf_method) { - SDF_METHOD_free(sdf_method); - sdf_method = NULL; - } - - if (!(sdf_method = SDF_METHOD_load_library(so_path))) { - SDFerr(SDF_R_LOAD_LIBRARY_FAILURE); - return SDR_BASE; - } - - if (vendor) { - if (strcmp(vendor, sdf_sansec.name) == 0) { - sdf_vendor = &sdf_sansec; - } - } - - return SDR_OK; -} - -int SDF_UnloadLibrary(void) -{ - SDF_METHOD_free(sdf_method); - sdf_method = NULL; - sdf_vendor = NULL; - return SDR_OK; -} - -int SDF_OpenDevice( - void **phDeviceHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->OpenDevice) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->OpenDevice( - phDeviceHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_CloseDevice( - void *hDeviceHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->CloseDevice) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->CloseDevice( - hDeviceHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_OpenSession( - void *hDeviceHandle, - void **phSessionHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->OpenSession) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->OpenSession( - hDeviceHandle, - phSessionHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_CloseSession( - void *hSessionHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->CloseSession) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->CloseSession( - hSessionHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GetDeviceInfo( - void *hSessionHandle, - DEVICEINFO *pstDeviceInfo) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GetDeviceInfo) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GetDeviceInfo( - hSessionHandle, - pstDeviceInfo)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateRandom( - void *hSessionHandle, - unsigned int uiLength, - unsigned char *pucRandom) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateRandom) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateRandom( - hSessionHandle, - uiLength, - pucRandom)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GetPrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucPassword, - unsigned int uiPwdLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GetPrivateKeyAccessRight) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GetPrivateKeyAccessRight( - hSessionHandle, - uiKeyIndex, - pucPassword, - uiPwdLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ReleasePrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ReleasePrivateKeyAccessRight) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ReleasePrivateKeyAccessRight( - hSessionHandle, - uiKeyIndex)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExportSignPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExportSignPublicKey_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExportSignPublicKey_RSA( - hSessionHandle, - uiKeyIndex, - pucPublicKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExportEncPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExportEncPublicKey_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExportEncPublicKey_RSA( - hSessionHandle, - uiKeyIndex, - pucPublicKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyPair_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - RSArefPrivateKey *pucPrivateKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyPair_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateKeyPair_RSA( - hSessionHandle, - uiKeyBits, - pucPublicKey, - pucPrivateKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithIPK_RSA( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithIPK_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateKeyWithIPK_RSA( - hSessionHandle, - uiIPKIndex, - uiKeyBits, - pucKey, - puiKeyLength, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithEPK_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithEPK_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateKeyWithEPK_RSA( - hSessionHandle, - uiKeyBits, - pucPublicKey, - pucKey, - puiKeyLength, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ImportKeyWithISK_RSA( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ImportKeyWithISK_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ImportKeyWithISK_RSA( - hSessionHandle, - uiISKIndex, - pucKey, - uiKeyLength, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExchangeDigitEnvelopeBaseOnRSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDEInput, - unsigned int uiDELength, - unsigned char *pucDEOutput, - unsigned int *puiDELength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExchangeDigitEnvelopeBaseOnRSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExchangeDigitEnvelopeBaseOnRSA( - hSessionHandle, - uiKeyIndex, - pucPublicKey, - pucDEInput, - uiDELength, - pucDEOutput, - puiDELength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExportSignPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExportSignPublicKey_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExportSignPublicKey_ECC( - hSessionHandle, - uiKeyIndex, - pucPublicKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExportEncPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExportEncPublicKey_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExportEncPublicKey_ECC( - hSessionHandle, - uiKeyIndex, - pucPublicKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyPair_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKeyBits, - ECCrefPublicKey *pucPublicKey, - ECCrefPrivateKey *pucPrivateKey) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyPair_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_ECC_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->GenerateKeyPair_ECC( - hSessionHandle, - uiAlgID, - uiKeyBits, - pucPublicKey, - pucPrivateKey)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithIPK_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - ECCCipher *pucKey, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithIPK_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateKeyWithIPK_ECC( - hSessionHandle, - uiIPKIndex, - uiKeyBits, - pucKey, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithEPK_ECC( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucKey, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithEPK_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->GenerateKeyWithEPK_ECC( - hSessionHandle, - uiKeyBits, - uiAlgID, - pucPublicKey, - pucKey, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ImportKeyWithISK_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - ECCCipher *pucKey, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ImportKeyWithISK_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ImportKeyWithISK_ECC( - hSessionHandle, - uiISKIndex, - pucKey, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateAgreementDataWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - void **phAgreementHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateAgreementDataWithECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateAgreementDataWithECC( - hSessionHandle, - uiISKIndex, - uiKeyBits, - pucSponsorID, - uiSponsorIDLength, - pucSponsorPublicKey, - pucSponsorTmpPublicKey, - phAgreementHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithECC( - void *hSessionHandle, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void *hAgreementHandle, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateKeyWithECC( - hSessionHandle, - pucResponseID, - uiResponseIDLength, - pucResponsePublicKey, - pucResponseTmpPublicKey, - hAgreementHandle, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateAgreementDataAndKeyWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateAgreementDataAndKeyWithECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->GenerateAgreementDataAndKeyWithECC( - hSessionHandle, - uiISKIndex, - uiKeyBits, - pucResponseID, - uiResponseIDLength, - pucSponsorID, - uiSponsorIDLength, - pucSponsorPublicKey, - pucSponsorTmpPublicKey, - pucResponsePublicKey, - pucResponseTmpPublicKey, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExchangeDigitEnvelopeBaseOnECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucEncDataIn, - ECCCipher *pucEncDataOut) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExchangeDigitEnvelopeBaseOnECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->ExchangeDigitEnvelopeBaseOnECC( - hSessionHandle, - uiKeyIndex, - uiAlgID, - pucPublicKey, - pucEncDataIn, - pucEncDataOut)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_GenerateKeyWithKEK( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->GenerateKeyWithKEK) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->GenerateKeyWithKEK( - hSessionHandle, - uiKeyBits, - uiAlgID, - uiKEKIndex, - pucKey, - puiKeyLength, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ImportKeyWithKEK( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ImportKeyWithKEK) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->ImportKeyWithKEK( - hSessionHandle, - uiAlgID, - uiKEKIndex, - pucKey, - uiKeyLength, - phKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_DestroyKey( - void *hSessionHandle, - void *hKeyHandle) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->DestroyKey) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->DestroyKey( - hSessionHandle, - hKeyHandle)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExternalPublicKeyOperation_RSA( - void *hSessionHandle, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExternalPublicKeyOperation_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ExternalPublicKeyOperation_RSA( - hSessionHandle, - pucPublicKey, - pucDataInput, - uiInputLength, - pucDataOutput, - puiOutputLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_InternalPublicKeyOperation_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->InternalPublicKeyOperation_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->InternalPublicKeyOperation_RSA( - hSessionHandle, - uiKeyIndex, - pucDataInput, - uiInputLength, - pucDataOutput, - puiOutputLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_InternalPrivateKeyOperation_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->InternalPrivateKeyOperation_RSA) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->InternalPrivateKeyOperation_RSA( - hSessionHandle, - uiKeyIndex, - pucDataInput, - uiInputLength, - pucDataOutput, - puiOutputLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExternalVerify_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - ECCSignature *pucSignature) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExternalVerify_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->ExternalVerify_ECC( - hSessionHandle, - uiAlgID, - pucPublicKey, - pucDataInput, - uiInputLength, - pucSignature)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_InternalSign_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->InternalSign_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->InternalSign_ECC( - hSessionHandle, - uiISKIndex, - pucData, - uiDataLength, - pucSignature)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_InternalVerify_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->InternalVerify_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->InternalVerify_ECC( - hSessionHandle, - uiIPKIndex, - pucData, - uiDataLength, - pucSignature)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ExternalEncrypt_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ExternalEncrypt_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->ExternalEncrypt_ECC( - hSessionHandle, - uiAlgID, - pucPublicKey, - pucData, - uiDataLength, - pucEncData)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_InternalEncrypt_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiAlgID, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData) -{ - int ret = SDR_UNKNOWERR; - ECCCipher *buf = pucEncData; - - if (!sdf_method || !sdf_method->InternalEncrypt_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (pucEncData->L < uiDataLength) { - SDFerr(SDF_R_BUFFER_TOO_SMALL); - return SDR_NOBUFFER; - } - - if (sdf_vendor && sdf_vendor->decode_ecccipher) { - if (SDF_NewECCCipher(&buf, uiDataLength) != SDR_OK) { - SDFerr(ERR_R_SDF_LIB); - return SDR_UNKNOWERR; - } - } - - if (sdf_vendor && sdf_vendor->pkey_std2vendor) { - if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); - ret = SDR_ALGNOTSUPPORT; - goto end; - } - } - - if ((ret = sdf_method->InternalEncrypt_ECC( - hSessionHandle, - uiIPKIndex, - uiAlgID, - pucData, - uiDataLength, - buf)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - goto end; - } - - if (sdf_vendor && sdf_vendor->decode_ecccipher) { - if (!sdf_vendor->decode_ecccipher(pucEncData, buf)) { - SDFerr(ERR_R_SDF_LIB); - ret = SDR_UNKNOWERR; - goto end; - } - } - - /* - { - int i; - unsigned char *p = (unsigned char *)pucEncData; - for (i = 0; i < sizeof(ECCCipher) -1 + uiDataLength; i++) { - printf("%02x", p[i]); - } - printf("\n"); - } - */ - - ret = SDR_OK; - -end: - if (sdf_vendor && sdf_vendor->decode_ecccipher && buf) { - SDF_FreeECCCipher(buf); - } - return ret; -} - -int SDF_InternalDecrypt_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiAlgID, - ECCCipher *pucEncData, - unsigned char *pucData, - unsigned int *uiDataLength) -{ - int ret = SDR_UNKNOWERR; - ECCCipher *buf = pucEncData; - - if (!sdf_method || !sdf_method->InternalDecrypt_ECC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor && sdf_vendor->pkey_std2vendor) { - if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if (sdf_vendor && sdf_vendor->encode_ecccipher) { - if (SDF_NewECCCipher(&buf, pucEncData->L) != SDR_OK) { - SDFerr(ERR_R_SDF_LIB); - return SDR_UNKNOWERR; - } - - if (!sdf_vendor->encode_ecccipher(pucEncData, buf)) { - SDFerr(ERR_R_SDF_LIB); - ret = SDR_UNKNOWERR; - goto end; - } - } - - if ((ret = sdf_method->InternalDecrypt_ECC( - hSessionHandle, - uiISKIndex, - uiAlgID, - buf, - pucData, - uiDataLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - goto end; - } - -end: - if (sdf_vendor && sdf_vendor->encode_ecccipher && buf) { - SDF_FreeECCCipher(buf); - } - return ret; -} - -int SDF_Encrypt( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucEncData, - unsigned int *puiEncDataLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->Encrypt) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->Encrypt( - hSessionHandle, - hKeyHandle, - uiAlgID, - pucIV, - pucData, - uiDataLength, - pucEncData, - puiEncDataLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_Decrypt( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucEncData, - unsigned int uiEncDataLength, - unsigned char *pucData, - unsigned int *puiDataLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->Decrypt) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->Decrypt( - hSessionHandle, - hKeyHandle, - uiAlgID, - pucIV, - pucEncData, - uiEncDataLength, - pucData, - puiDataLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_CalculateMAC( - void *hSessionHandle, - void *hKeyHandle, - unsigned int uiAlgID, - unsigned char *pucIV, - unsigned char *pucData, - unsigned int uiDataLength, - unsigned char *pucMAC, - unsigned int *puiMACLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->CalculateMAC) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->CalculateMAC( - hSessionHandle, - hKeyHandle, - uiAlgID, - pucIV, - pucData, - uiDataLength, - pucMAC, - puiMACLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_HashInit( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucID, - unsigned int uiIDLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->HashInit) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if (sdf_vendor) { - if (!(uiAlgID = sdf_vendor->digest_std2vendor(uiAlgID))) { - SDFerr(SDF_R_NOT_SUPPORTED_DIGEST_ALGOR); - return SDR_ALGNOTSUPPORT; - } - } - - if ((ret = sdf_method->HashInit( - hSessionHandle, - uiAlgID, - pucPublicKey, - pucID, - uiIDLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_HashUpdate( - void *hSessionHandle, - unsigned char *pucData, - unsigned int uiDataLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->HashUpdate) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->HashUpdate( - hSessionHandle, - pucData, - uiDataLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_HashFinal( - void *hSessionHandle, - unsigned char *pucHash, - unsigned int *puiHashLength) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->HashFinal) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->HashFinal( - hSessionHandle, - pucHash, - puiHashLength)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_CreateFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiFileSize) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->CreateObject) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->CreateObject( - hSessionHandle, - pucFileName, - uiNameLen, - uiFileSize)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_ReadFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int *puiReadLength, - unsigned char *pucBuffer) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->ReadObject) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->ReadObject( - hSessionHandle, - pucFileName, - uiNameLen, - uiOffset, - puiReadLength, - pucBuffer)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_WriteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int uiWriteLength, - unsigned char *pucBuffer) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->WriteObject) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->WriteObject( - hSessionHandle, - pucFileName, - uiNameLen, - uiOffset, - uiWriteLength, - pucBuffer)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} - -int SDF_DeleteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen) -{ - int ret = SDR_UNKNOWERR; - - if (!sdf_method || !sdf_method->DeleteObject) { - SDFerr(SDF_R_NOT_INITIALIZED); - return SDR_NOTSUPPORT; - } - - if ((ret = sdf_method->DeleteObject( - hSessionHandle, - pucFileName, - uiNameLen)) != SDR_OK) { - SDFerr(SDF_GetErrorReason(ret)); - return ret; - } - - return SDR_OK; -} + + +#include +#include "sdf_ext.h" +#include "sdf_int.h" + +SDF_METHOD *sdf_method = NULL; +SDF_VENDOR *sdf_vendor = NULL; +extern SDF_VENDOR sdf_sansec; + + +#define SDFerr(reason) fprintf(stderr,"sdfutil: %s %d: %s %s\n", __FILE__, __LINE__, __FUNCTION__, reason) + + +#define SDF_R_LOAD_LIBRARY_FAILURE "SDF_R_LOAD_LIBRARY_FAILURE" +#define SDF_R_NOT_INITIALIZED "SDF_R_NOT_INITIALIZED" +#define SDF_R_NOT_SUPPORTED_ECC_ALGOR "SDF_R_NOT_SUPPORTED_ECC_ALGOR" +#define SDF_R_NOT_SUPPORTED_CIPHER_ALGOR "SDF_R_NOT_SUPPORTED_CIPHER_ALGOR" +#define SDF_R_BUFFER_TOO_SMALL "SDF_R_BUFFER_TOO_SMALL" +#define SDF_R_NOT_SUPPORTED_PKEY_ALGOR "SDF_R_NOT_SUPPORTED_PKEY_ALGOR" +#define SDF_R_NOT_SUPPORTED_DIGEST_ALGOR "SDF_R_NOT_SUPPORTED_DIGEST_ALGOR" +#define ERR_R_SDF_LIB "ERR_R_SDF_LIB" + + + +int SDF_LoadLibrary(char *so_path, char *vendor) +{ + if (sdf_method) { + SDF_METHOD_free(sdf_method); + sdf_method = NULL; + } + + if (!(sdf_method = SDF_METHOD_load_library(so_path))) { + SDFerr(SDF_R_LOAD_LIBRARY_FAILURE); + return SDR_BASE; + } + + if (vendor) { + if (strcmp(vendor, sdf_sansec.name) == 0) { + sdf_vendor = &sdf_sansec; + } + } + + return SDR_OK; +} + +int SDF_UnloadLibrary(void) +{ + SDF_METHOD_free(sdf_method); + sdf_method = NULL; + sdf_vendor = NULL; + return SDR_OK; +} + +int SDF_OpenDevice( + void **phDeviceHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->OpenDevice) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->OpenDevice( + phDeviceHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_CloseDevice( + void *hDeviceHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->CloseDevice) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->CloseDevice( + hDeviceHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_OpenSession( + void *hDeviceHandle, + void **phSessionHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->OpenSession) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->OpenSession( + hDeviceHandle, + phSessionHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_CloseSession( + void *hSessionHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->CloseSession) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->CloseSession( + hSessionHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GetDeviceInfo( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GetDeviceInfo) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GetDeviceInfo( + hSessionHandle, + pstDeviceInfo)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateRandom( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateRandom) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateRandom( + hSessionHandle, + uiLength, + pucRandom)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GetPrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GetPrivateKeyAccessRight) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GetPrivateKeyAccessRight( + hSessionHandle, + uiKeyIndex, + pucPassword, + uiPwdLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ReleasePrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ReleasePrivateKeyAccessRight) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ReleasePrivateKeyAccessRight( + hSessionHandle, + uiKeyIndex)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExportSignPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExportSignPublicKey_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExportSignPublicKey_RSA( + hSessionHandle, + uiKeyIndex, + pucPublicKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExportEncPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExportEncPublicKey_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExportEncPublicKey_RSA( + hSessionHandle, + uiKeyIndex, + pucPublicKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyPair_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyPair_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateKeyPair_RSA( + hSessionHandle, + uiKeyBits, + pucPublicKey, + pucPrivateKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithIPK_RSA( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithIPK_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateKeyWithIPK_RSA( + hSessionHandle, + uiIPKIndex, + uiKeyBits, + pucKey, + puiKeyLength, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithEPK_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithEPK_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateKeyWithEPK_RSA( + hSessionHandle, + uiKeyBits, + pucPublicKey, + pucKey, + puiKeyLength, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ImportKeyWithISK_RSA( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ImportKeyWithISK_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ImportKeyWithISK_RSA( + hSessionHandle, + uiISKIndex, + pucKey, + uiKeyLength, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExchangeDigitEnvelopeBaseOnRSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExchangeDigitEnvelopeBaseOnRSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExchangeDigitEnvelopeBaseOnRSA( + hSessionHandle, + uiKeyIndex, + pucPublicKey, + pucDEInput, + uiDELength, + pucDEOutput, + puiDELength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExportSignPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExportSignPublicKey_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExportSignPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + pucPublicKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExportEncPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExportEncPublicKey_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExportEncPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + pucPublicKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyPair_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyPair_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_ECC_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->GenerateKeyPair_ECC( + hSessionHandle, + uiAlgID, + uiKeyBits, + pucPublicKey, + pucPrivateKey)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithIPK_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithIPK_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateKeyWithIPK_ECC( + hSessionHandle, + uiIPKIndex, + uiKeyBits, + pucKey, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithEPK_ECC( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithEPK_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->GenerateKeyWithEPK_ECC( + hSessionHandle, + uiKeyBits, + uiAlgID, + pucPublicKey, + pucKey, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ImportKeyWithISK_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ImportKeyWithISK_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ImportKeyWithISK_ECC( + hSessionHandle, + uiISKIndex, + pucKey, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateAgreementDataWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateAgreementDataWithECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateAgreementDataWithECC( + hSessionHandle, + uiISKIndex, + uiKeyBits, + pucSponsorID, + uiSponsorIDLength, + pucSponsorPublicKey, + pucSponsorTmpPublicKey, + phAgreementHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithECC( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateKeyWithECC( + hSessionHandle, + pucResponseID, + uiResponseIDLength, + pucResponsePublicKey, + pucResponseTmpPublicKey, + hAgreementHandle, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateAgreementDataAndKeyWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateAgreementDataAndKeyWithECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->GenerateAgreementDataAndKeyWithECC( + hSessionHandle, + uiISKIndex, + uiKeyBits, + pucResponseID, + uiResponseIDLength, + pucSponsorID, + uiSponsorIDLength, + pucSponsorPublicKey, + pucSponsorTmpPublicKey, + pucResponsePublicKey, + pucResponseTmpPublicKey, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExchangeDigitEnvelopeBaseOnECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExchangeDigitEnvelopeBaseOnECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->ExchangeDigitEnvelopeBaseOnECC( + hSessionHandle, + uiKeyIndex, + uiAlgID, + pucPublicKey, + pucEncDataIn, + pucEncDataOut)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_GenerateKeyWithKEK( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->GenerateKeyWithKEK) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->GenerateKeyWithKEK( + hSessionHandle, + uiKeyBits, + uiAlgID, + uiKEKIndex, + pucKey, + puiKeyLength, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ImportKeyWithKEK( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ImportKeyWithKEK) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->ImportKeyWithKEK( + hSessionHandle, + uiAlgID, + uiKEKIndex, + pucKey, + uiKeyLength, + phKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_DestroyKey( + void *hSessionHandle, + void *hKeyHandle) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->DestroyKey) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->DestroyKey( + hSessionHandle, + hKeyHandle)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExternalPublicKeyOperation_RSA( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExternalPublicKeyOperation_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ExternalPublicKeyOperation_RSA( + hSessionHandle, + pucPublicKey, + pucDataInput, + uiInputLength, + pucDataOutput, + puiOutputLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_InternalPublicKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->InternalPublicKeyOperation_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->InternalPublicKeyOperation_RSA( + hSessionHandle, + uiKeyIndex, + pucDataInput, + uiInputLength, + pucDataOutput, + puiOutputLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_InternalPrivateKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->InternalPrivateKeyOperation_RSA) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->InternalPrivateKeyOperation_RSA( + hSessionHandle, + uiKeyIndex, + pucDataInput, + uiInputLength, + pucDataOutput, + puiOutputLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExternalVerify_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExternalVerify_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->ExternalVerify_ECC( + hSessionHandle, + uiAlgID, + pucPublicKey, + pucDataInput, + uiInputLength, + pucSignature)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_InternalSign_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->InternalSign_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->InternalSign_ECC( + hSessionHandle, + uiISKIndex, + pucData, + uiDataLength, + pucSignature)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_InternalVerify_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->InternalVerify_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->InternalVerify_ECC( + hSessionHandle, + uiIPKIndex, + pucData, + uiDataLength, + pucSignature)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ExternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ExternalEncrypt_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->ExternalEncrypt_ECC( + hSessionHandle, + uiAlgID, + pucPublicKey, + pucData, + uiDataLength, + pucEncData)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_InternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiAlgID, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + int ret = SDR_UNKNOWERR; + ECCCipher *buf = pucEncData; + + if (!sdf_method || !sdf_method->InternalEncrypt_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (pucEncData->L < uiDataLength) { + SDFerr(SDF_R_BUFFER_TOO_SMALL); + return SDR_NOBUFFER; + } + + if (sdf_vendor && sdf_vendor->decode_ecccipher) { + if (SDF_NewECCCipher(&buf, uiDataLength) != SDR_OK) { + SDFerr(ERR_R_SDF_LIB); + return SDR_UNKNOWERR; + } + } + + if (sdf_vendor && sdf_vendor->pkey_std2vendor) { + if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); + ret = SDR_ALGNOTSUPPORT; + goto end; + } + } + + if ((ret = sdf_method->InternalEncrypt_ECC( + hSessionHandle, + uiIPKIndex, + uiAlgID, + pucData, + uiDataLength, + buf)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + goto end; + } + + if (sdf_vendor && sdf_vendor->decode_ecccipher) { + if (!sdf_vendor->decode_ecccipher(pucEncData, buf)) { + SDFerr(ERR_R_SDF_LIB); + ret = SDR_UNKNOWERR; + goto end; + } + } + + /* + { + int i; + unsigned char *p = (unsigned char *)pucEncData; + for (i = 0; i < sizeof(ECCCipher) -1 + uiDataLength; i++) { + printf("%02x", p[i]); + } + printf("\n"); + } + */ + + ret = SDR_OK; + +end: + if (sdf_vendor && sdf_vendor->decode_ecccipher && buf) { + SDF_FreeECCCipher(buf); + } + return ret; +} + +int SDF_InternalDecrypt_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiAlgID, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *uiDataLength) +{ + int ret = SDR_UNKNOWERR; + ECCCipher *buf = pucEncData; + + if (!sdf_method || !sdf_method->InternalDecrypt_ECC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor && sdf_vendor->pkey_std2vendor) { + if (!(uiAlgID = sdf_vendor->pkey_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_PKEY_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if (sdf_vendor && sdf_vendor->encode_ecccipher) { + if (SDF_NewECCCipher(&buf, pucEncData->L) != SDR_OK) { + SDFerr(ERR_R_SDF_LIB); + return SDR_UNKNOWERR; + } + + if (!sdf_vendor->encode_ecccipher(pucEncData, buf)) { + SDFerr(ERR_R_SDF_LIB); + ret = SDR_UNKNOWERR; + goto end; + } + } + + if ((ret = sdf_method->InternalDecrypt_ECC( + hSessionHandle, + uiISKIndex, + uiAlgID, + buf, + pucData, + uiDataLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + goto end; + } + +end: + if (sdf_vendor && sdf_vendor->encode_ecccipher && buf) { + SDF_FreeECCCipher(buf); + } + return ret; +} + +int SDF_Encrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->Encrypt) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->Encrypt( + hSessionHandle, + hKeyHandle, + uiAlgID, + pucIV, + pucData, + uiDataLength, + pucEncData, + puiEncDataLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_Decrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucEncData, + unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->Decrypt) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->Decrypt( + hSessionHandle, + hKeyHandle, + uiAlgID, + pucIV, + pucEncData, + uiEncDataLength, + pucData, + puiDataLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_CalculateMAC( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucMAC, + unsigned int *puiMACLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->CalculateMAC) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->cipher_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->CalculateMAC( + hSessionHandle, + hKeyHandle, + uiAlgID, + pucIV, + pucData, + uiDataLength, + pucMAC, + puiMACLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_HashInit( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->HashInit) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if (sdf_vendor) { + if (!(uiAlgID = sdf_vendor->digest_std2vendor(uiAlgID))) { + SDFerr(SDF_R_NOT_SUPPORTED_DIGEST_ALGOR); + return SDR_ALGNOTSUPPORT; + } + } + + if ((ret = sdf_method->HashInit( + hSessionHandle, + uiAlgID, + pucPublicKey, + pucID, + uiIDLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_HashUpdate( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->HashUpdate) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->HashUpdate( + hSessionHandle, + pucData, + uiDataLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_HashFinal( + void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->HashFinal) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->HashFinal( + hSessionHandle, + pucHash, + puiHashLength)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_CreateFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiFileSize) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->CreateObject) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->CreateObject( + hSessionHandle, + pucFileName, + uiNameLen, + uiFileSize)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_ReadFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->ReadObject) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->ReadObject( + hSessionHandle, + pucFileName, + uiNameLen, + uiOffset, + puiReadLength, + pucBuffer)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_WriteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->WriteObject) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->WriteObject( + hSessionHandle, + pucFileName, + uiNameLen, + uiOffset, + uiWriteLength, + pucBuffer)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} + +int SDF_DeleteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen) +{ + int ret = SDR_UNKNOWERR; + + if (!sdf_method || !sdf_method->DeleteObject) { + SDFerr(SDF_R_NOT_INITIALIZED); + return SDR_NOTSUPPORT; + } + + if ((ret = sdf_method->DeleteObject( + hSessionHandle, + pucFileName, + uiNameLen)) != SDR_OK) { + SDFerr(SDF_GetErrorReason(ret)); + return ret; + } + + return SDR_OK; +} diff --git a/src/sdf/sdf_meth.c b/src/sdf/sdf_meth.c index 180635f5..f95dfe3f 100644 --- a/src/sdf/sdf_meth.c +++ b/src/sdf/sdf_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,99 +7,100 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include "sdf_int.h" - -#define SDFerr(a,b) - -#define SDF_METHOD_BIND_FUNCTION_EX(func,name) \ - sdf->func = (SDF_##func##_FuncPtr)dlsym(sdf->dso, "SDF_"#name) - -#define SDF_METHOD_BIND_FUNCTION(func) \ - SDF_METHOD_BIND_FUNCTION_EX(func,func) - -SDF_METHOD *SDF_METHOD_load_library(const char *so_path) -{ - SDF_METHOD *ret = NULL; - SDF_METHOD *sdf = NULL; - - if (!(sdf = malloc(sizeof(*sdf)))) { - SDFerr(SDF_F_SDF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); - goto end; - } - memset(sdf, 0, sizeof(*sdf)); - - if (!(sdf->dso = dlopen(so_path, RTLD_LAZY))) { - fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, dlerror()); - SDFerr(SDF_F_SDF_METHOD_LOAD_LIBRARY, SDF_R_DSO_LOAD_FAILURE); - goto end; - } - - SDF_METHOD_BIND_FUNCTION(OpenDevice); - SDF_METHOD_BIND_FUNCTION(CloseDevice); - SDF_METHOD_BIND_FUNCTION(OpenSession); - SDF_METHOD_BIND_FUNCTION(CloseSession); - SDF_METHOD_BIND_FUNCTION(GetDeviceInfo); - SDF_METHOD_BIND_FUNCTION(GenerateRandom); - SDF_METHOD_BIND_FUNCTION(GetPrivateKeyAccessRight); - SDF_METHOD_BIND_FUNCTION(ReleasePrivateKeyAccessRight); - SDF_METHOD_BIND_FUNCTION(ExportSignPublicKey_RSA); - SDF_METHOD_BIND_FUNCTION(ExportEncPublicKey_RSA); - SDF_METHOD_BIND_FUNCTION(GenerateKeyPair_RSA); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithIPK_RSA); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithEPK_RSA); - SDF_METHOD_BIND_FUNCTION(ImportKeyWithISK_RSA); - SDF_METHOD_BIND_FUNCTION(ExchangeDigitEnvelopeBaseOnRSA); - SDF_METHOD_BIND_FUNCTION(ExportSignPublicKey_ECC); - SDF_METHOD_BIND_FUNCTION(ExportEncPublicKey_ECC); - SDF_METHOD_BIND_FUNCTION(GenerateKeyPair_ECC); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithIPK_ECC); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithEPK_ECC); - SDF_METHOD_BIND_FUNCTION(ImportKeyWithISK_ECC); - SDF_METHOD_BIND_FUNCTION(GenerateAgreementDataWithECC); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithECC); - SDF_METHOD_BIND_FUNCTION(GenerateAgreementDataAndKeyWithECC); - SDF_METHOD_BIND_FUNCTION(ExchangeDigitEnvelopeBaseOnECC); - SDF_METHOD_BIND_FUNCTION(GenerateKeyWithKEK); - SDF_METHOD_BIND_FUNCTION(ImportKeyWithKEK); - SDF_METHOD_BIND_FUNCTION(DestroyKey); - SDF_METHOD_BIND_FUNCTION(ExternalPublicKeyOperation_RSA); - //SDF_METHOD_BIND_FUNCTION(InternalPublicKeyOperation_RSA); - SDF_METHOD_BIND_FUNCTION(InternalPrivateKeyOperation_RSA); - SDF_METHOD_BIND_FUNCTION(ExternalVerify_ECC); - SDF_METHOD_BIND_FUNCTION(InternalSign_ECC); - SDF_METHOD_BIND_FUNCTION(InternalVerify_ECC); - SDF_METHOD_BIND_FUNCTION(ExternalEncrypt_ECC); - //SDF_METHOD_BIND_FUNCTION(ExternalDecrypt_ECC); - SDF_METHOD_BIND_FUNCTION(InternalEncrypt_ECC); - SDF_METHOD_BIND_FUNCTION(InternalDecrypt_ECC); - SDF_METHOD_BIND_FUNCTION(Encrypt); - SDF_METHOD_BIND_FUNCTION(Decrypt); - SDF_METHOD_BIND_FUNCTION(CalculateMAC); - SDF_METHOD_BIND_FUNCTION(HashInit); - SDF_METHOD_BIND_FUNCTION(HashUpdate); - SDF_METHOD_BIND_FUNCTION(HashFinal); - SDF_METHOD_BIND_FUNCTION_EX(CreateObject,CreateFile); - SDF_METHOD_BIND_FUNCTION_EX(ReadObject,ReadFile); - SDF_METHOD_BIND_FUNCTION_EX(WriteObject,WriteFile); - SDF_METHOD_BIND_FUNCTION_EX(DeleteObject,DeleteFile); - - ret = sdf; - sdf = NULL; - -end: - SDF_METHOD_free(sdf); - return ret; -} - -void SDF_METHOD_free(SDF_METHOD *meth) -{ - if (meth) free(meth->dso); - free(meth); -} - - + + +#include +#include +#include +#include +#include "sdf_int.h" + +#define SDFerr(a,b) + +#define SDF_METHOD_BIND_FUNCTION_EX(func,name) \ + sdf->func = (SDF_##func##_FuncPtr)dlsym(sdf->dso, "SDF_"#name) + +#define SDF_METHOD_BIND_FUNCTION(func) \ + SDF_METHOD_BIND_FUNCTION_EX(func,func) + +SDF_METHOD *SDF_METHOD_load_library(const char *so_path) +{ + SDF_METHOD *ret = NULL; + SDF_METHOD *sdf = NULL; + + if (!(sdf = malloc(sizeof(*sdf)))) { + SDFerr(SDF_F_SDF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); + goto end; + } + memset(sdf, 0, sizeof(*sdf)); + + if (!(sdf->dso = dlopen(so_path, RTLD_LAZY))) { + fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, dlerror()); + SDFerr(SDF_F_SDF_METHOD_LOAD_LIBRARY, SDF_R_DSO_LOAD_FAILURE); + goto end; + } + + SDF_METHOD_BIND_FUNCTION(OpenDevice); + SDF_METHOD_BIND_FUNCTION(CloseDevice); + SDF_METHOD_BIND_FUNCTION(OpenSession); + SDF_METHOD_BIND_FUNCTION(CloseSession); + SDF_METHOD_BIND_FUNCTION(GetDeviceInfo); + SDF_METHOD_BIND_FUNCTION(GenerateRandom); + SDF_METHOD_BIND_FUNCTION(GetPrivateKeyAccessRight); + SDF_METHOD_BIND_FUNCTION(ReleasePrivateKeyAccessRight); + SDF_METHOD_BIND_FUNCTION(ExportSignPublicKey_RSA); + SDF_METHOD_BIND_FUNCTION(ExportEncPublicKey_RSA); + SDF_METHOD_BIND_FUNCTION(GenerateKeyPair_RSA); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithIPK_RSA); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithEPK_RSA); + SDF_METHOD_BIND_FUNCTION(ImportKeyWithISK_RSA); + SDF_METHOD_BIND_FUNCTION(ExchangeDigitEnvelopeBaseOnRSA); + SDF_METHOD_BIND_FUNCTION(ExportSignPublicKey_ECC); + SDF_METHOD_BIND_FUNCTION(ExportEncPublicKey_ECC); + SDF_METHOD_BIND_FUNCTION(GenerateKeyPair_ECC); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithIPK_ECC); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithEPK_ECC); + SDF_METHOD_BIND_FUNCTION(ImportKeyWithISK_ECC); + SDF_METHOD_BIND_FUNCTION(GenerateAgreementDataWithECC); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithECC); + SDF_METHOD_BIND_FUNCTION(GenerateAgreementDataAndKeyWithECC); + SDF_METHOD_BIND_FUNCTION(ExchangeDigitEnvelopeBaseOnECC); + SDF_METHOD_BIND_FUNCTION(GenerateKeyWithKEK); + SDF_METHOD_BIND_FUNCTION(ImportKeyWithKEK); + SDF_METHOD_BIND_FUNCTION(DestroyKey); + SDF_METHOD_BIND_FUNCTION(ExternalPublicKeyOperation_RSA); + //SDF_METHOD_BIND_FUNCTION(InternalPublicKeyOperation_RSA); + SDF_METHOD_BIND_FUNCTION(InternalPrivateKeyOperation_RSA); + SDF_METHOD_BIND_FUNCTION(ExternalVerify_ECC); + SDF_METHOD_BIND_FUNCTION(InternalSign_ECC); + SDF_METHOD_BIND_FUNCTION(InternalVerify_ECC); + SDF_METHOD_BIND_FUNCTION(ExternalEncrypt_ECC); + //SDF_METHOD_BIND_FUNCTION(ExternalDecrypt_ECC); + SDF_METHOD_BIND_FUNCTION(InternalEncrypt_ECC); + SDF_METHOD_BIND_FUNCTION(InternalDecrypt_ECC); + SDF_METHOD_BIND_FUNCTION(Encrypt); + SDF_METHOD_BIND_FUNCTION(Decrypt); + SDF_METHOD_BIND_FUNCTION(CalculateMAC); + SDF_METHOD_BIND_FUNCTION(HashInit); + SDF_METHOD_BIND_FUNCTION(HashUpdate); + SDF_METHOD_BIND_FUNCTION(HashFinal); + SDF_METHOD_BIND_FUNCTION_EX(CreateObject,CreateFile); + SDF_METHOD_BIND_FUNCTION_EX(ReadObject,ReadFile); + SDF_METHOD_BIND_FUNCTION_EX(WriteObject,WriteFile); + SDF_METHOD_BIND_FUNCTION_EX(DeleteObject,DeleteFile); + + ret = sdf; + sdf = NULL; + +end: + SDF_METHOD_free(sdf); + return ret; +} + +void SDF_METHOD_free(SDF_METHOD *meth) +{ + if (meth) free(meth->dso); + free(meth); +} + + diff --git a/src/sdf/sdf_sansec.c b/src/sdf/sdf_sansec.c index b04a3ffc..5f3b6a12 100644 --- a/src/sdf/sdf_sansec.c +++ b/src/sdf/sdf_sansec.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,260 +7,261 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include "sdf.h" -#include "sdf_int.h" -#include "sdf_sansec.h" - - -#define SDFerr(a,b) - -typedef struct { - unsigned int std_id; - unsigned int vendor_id; -} SDF_ALGOR_PAIR; - -static SDF_ALGOR_PAIR sansec_ciphers[] = { - { SGD_SM1, SANSEC_SM1 }, - { SGD_SM1_ECB, SANSEC_SM1_ECB }, - { SGD_SM1_CBC, SANSEC_SM1_CBC }, - { SGD_SM1_CFB, SANSEC_SM1_CFB }, - { SGD_SM1_OFB, SANSEC_SM1_OFB }, - { SGD_SM1_MAC, SANSEC_SM1_MAC }, - { SGD_SM4, SANSEC_SM4 }, - { SGD_SM4_ECB, SANSEC_SM4_ECB }, - { SGD_SM4_CBC, SANSEC_SM4_CBC }, - { SGD_SM4_CFB, SANSEC_SM4_CFB }, - { SGD_SM4_OFB, SANSEC_SM4_OFB }, - { SGD_SM4_MAC, SANSEC_SM4_MAC }, - { SGD_SSF33, SANSEC_SSF33 }, - { SGD_SSF33_ECB, SANSEC_SSF33_ECB }, - { SGD_SSF33_CBC, SANSEC_SSF33_CBC }, - { SGD_SSF33_CFB, SANSEC_SSF33_CFB }, - { SGD_SSF33_OFB, SANSEC_SSF33_OFB }, - { SGD_SSF33_MAC, SANSEC_SSF33_MAC }, - { 0, SANSEC_AES }, - { 0, SANSEC_AES_ECB }, - { 0, SANSEC_AES_CBC }, - { 0, SANSEC_AES_CFB }, - { 0, SANSEC_AES_OFB }, - { 0, SANSEC_AES_MAC }, - { 0, SANSEC_DES }, - { 0, SANSEC_DES_ECB }, - { 0, SANSEC_DES_CBC }, - { 0, SANSEC_DES_CFB }, - { 0, SANSEC_DES_OFB }, - { 0, SANSEC_DES_MAC }, - { 0, SANSEC_3DES }, - { 0, SANSEC_3DES_ECB }, - { 0, SANSEC_3DES_CBC }, - { 0, SANSEC_3DES_CFB }, - { 0, SANSEC_3DES_OFB }, - { 0, SANSEC_3DES_MAC }, -}; - -static unsigned int sansec_cipher_vendor2std(unsigned int vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { - if (vendor_id == sansec_ciphers[i].vendor_id) { - return sansec_ciphers[i].std_id; - } - } - return 0; -} - -static unsigned int sansec_cipher_std2vendor(unsigned int std_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { - if (std_id == sansec_ciphers[i].std_id) { - return sansec_ciphers[i].vendor_id; - } - } - return 0; -} - -static unsigned int sansec_cipher_cap(unsigned int vendor_cap) -{ - unsigned int std_cap = 0; - size_t i; - - for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { - if (vendor_cap & sansec_ciphers[i].vendor_id) { - std_cap |= sansec_ciphers[i].std_id; - } - } - - return std_cap; -} - -static SDF_ALGOR_PAIR sansec_digests[] = { - { SGD_SM3, SANSEC_SM3 }, - { SGD_SHA1, SANSEC_SHA1 }, - { SGD_SHA256, SANSEC_SHA256 }, - { 0, SANSEC_SHA512 }, - { 0, SANSEC_SHA384 }, - { 0, SANSEC_SHA224 }, - { 0, SANSEC_MD5 }, -}; - -static unsigned int sansec_digest_vendor2std(unsigned int vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { - if (vendor_id == sansec_digests[i].vendor_id) { - return sansec_digests[i].std_id; - } - } - return 0; -} - -static unsigned int sansec_digest_std2vendor(unsigned int std_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { - if (std_id == sansec_digests[i].std_id) { - return sansec_digests[i].vendor_id; - } - } - return 0; -} - -static unsigned int sansec_digest_cap(unsigned int vendor_cap) -{ - unsigned int std_cap = 0; - size_t i; - - for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { - if (vendor_cap & sansec_digests[i].vendor_id) { - std_cap |= sansec_digests[i].std_id; - } - } - - return std_cap; -} - -static SDF_ALGOR_PAIR sansec_pkeys[] = { - { SGD_RSA,SANSEC_RSA }, - { SGD_RSA_SIGN,SANSEC_RSA_SIGN }, - { SGD_RSA_ENC,SANSEC_RSA_ENC }, - { SGD_SM2,SANSEC_SM2 }, - { SGD_SM2_1,SANSEC_SM2_1 }, - { SGD_SM2_2,SANSEC_SM2_2 }, - { SGD_SM2_3,SANSEC_SM2_3 }, -}; - -static unsigned int sansec_pkey_vendor2std(unsigned int vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { - if (vendor_id == sansec_pkeys[i].vendor_id) { - return sansec_pkeys[i].std_id; - } - } - return 0; -} - -static unsigned int sansec_pkey_std2vendor(unsigned int std_id) -{ - size_t i; - for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { - if (std_id == sansec_pkeys[i].std_id) { - return sansec_pkeys[i].vendor_id; - } - } - return 0; -} - -static unsigned int sansec_pkey_cap(unsigned int vendor_cap) -{ - unsigned int std_cap = 0; - size_t i; - - for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { - if (vendor_cap & sansec_pkeys[i].vendor_id) { - std_cap |= sansec_pkeys[i].std_id; - } - } - - return std_cap; -} - -static int sansec_encode_ecccipher(const ECCCipher *ec, void *vendor) -{ - int ret; - SANSEC_ECCCipher *sansec = vendor; - ret = sizeof(SANSEC_ECCCipher); - - if (ec->L > sizeof(sansec->C)) { - SDFerr(SDF_F_SANSEC_ENCODE_ECCCIPHER, - SDF_R_INVALID_SANSEC_ECCCIPHER_LENGTH); - return 0; - } - - if (vendor) { - sansec->clength = ec->L; - memcpy(sansec->x, ec->x, sizeof(ec->x)); - memcpy(sansec->y, ec->y, sizeof(ec->y)); - memcpy(sansec->M, ec->M, sizeof(ec->M)); - memset(sansec->M + sizeof(ec->M), 0, sizeof(sansec->M) - sizeof(ec->M)); - memcpy(sansec->C, ec->C, ec->L); - memset(sansec->C + ec->L, 0, sizeof(sansec->C) - ec->L); - } - - return ret; -} - -static int sansec_decode_ecccipher(ECCCipher *ec, const void *vendor) -{ - int ret; - const SANSEC_ECCCipher *sansec = vendor; - ret = sizeof(ECCCipher) -1 + sansec->clength; - - if (sansec->clength > sizeof(sansec->C)) { - SDFerr(SDF_F_SANSEC_DECODE_ECCCIPHER, - SDF_R_INVALID_SANSEC_ECCCIPHER_LENGTH); - return 0; - } - - if (ec) { - memcpy(ec->x, sansec->x, sizeof(ec->x)); - memcpy(ec->y, sansec->y, sizeof(ec->y)); - memcpy(ec->M, sansec->M, sizeof(ec->M)); - ec->L = sansec->clength; - memcpy(ec->C, sansec->C, sansec->clength); - } - - return ret; -} - -static unsigned long sansec_get_error_reason(int err) -{ -/* - size_t i = 0; - for (i = 0; i < OSSL_NELEM(sansec_errors); i++) { - if (err == sansec_errors[i].err) { - return sansec_errors[i].reason; - } - } -*/ - return 0; -} - -SDF_VENDOR sdf_sansec = { - "sansec", - sansec_cipher_vendor2std, - sansec_cipher_std2vendor, - sansec_cipher_cap, - sansec_digest_vendor2std, - sansec_digest_std2vendor, - sansec_digest_cap, - sansec_pkey_vendor2std, - sansec_pkey_std2vendor, - sansec_pkey_cap, - sansec_encode_ecccipher, - sansec_decode_ecccipher, - sansec_get_error_reason, -}; + + +#include +#include "sdf.h" +#include "sdf_int.h" +#include "sdf_sansec.h" + + +#define SDFerr(a,b) + +typedef struct { + unsigned int std_id; + unsigned int vendor_id; +} SDF_ALGOR_PAIR; + +static SDF_ALGOR_PAIR sansec_ciphers[] = { + { SGD_SM1, SANSEC_SM1 }, + { SGD_SM1_ECB, SANSEC_SM1_ECB }, + { SGD_SM1_CBC, SANSEC_SM1_CBC }, + { SGD_SM1_CFB, SANSEC_SM1_CFB }, + { SGD_SM1_OFB, SANSEC_SM1_OFB }, + { SGD_SM1_MAC, SANSEC_SM1_MAC }, + { SGD_SM4, SANSEC_SM4 }, + { SGD_SM4_ECB, SANSEC_SM4_ECB }, + { SGD_SM4_CBC, SANSEC_SM4_CBC }, + { SGD_SM4_CFB, SANSEC_SM4_CFB }, + { SGD_SM4_OFB, SANSEC_SM4_OFB }, + { SGD_SM4_MAC, SANSEC_SM4_MAC }, + { SGD_SSF33, SANSEC_SSF33 }, + { SGD_SSF33_ECB, SANSEC_SSF33_ECB }, + { SGD_SSF33_CBC, SANSEC_SSF33_CBC }, + { SGD_SSF33_CFB, SANSEC_SSF33_CFB }, + { SGD_SSF33_OFB, SANSEC_SSF33_OFB }, + { SGD_SSF33_MAC, SANSEC_SSF33_MAC }, + { 0, SANSEC_AES }, + { 0, SANSEC_AES_ECB }, + { 0, SANSEC_AES_CBC }, + { 0, SANSEC_AES_CFB }, + { 0, SANSEC_AES_OFB }, + { 0, SANSEC_AES_MAC }, + { 0, SANSEC_DES }, + { 0, SANSEC_DES_ECB }, + { 0, SANSEC_DES_CBC }, + { 0, SANSEC_DES_CFB }, + { 0, SANSEC_DES_OFB }, + { 0, SANSEC_DES_MAC }, + { 0, SANSEC_3DES }, + { 0, SANSEC_3DES_ECB }, + { 0, SANSEC_3DES_CBC }, + { 0, SANSEC_3DES_CFB }, + { 0, SANSEC_3DES_OFB }, + { 0, SANSEC_3DES_MAC }, +}; + +static unsigned int sansec_cipher_vendor2std(unsigned int vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { + if (vendor_id == sansec_ciphers[i].vendor_id) { + return sansec_ciphers[i].std_id; + } + } + return 0; +} + +static unsigned int sansec_cipher_std2vendor(unsigned int std_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { + if (std_id == sansec_ciphers[i].std_id) { + return sansec_ciphers[i].vendor_id; + } + } + return 0; +} + +static unsigned int sansec_cipher_cap(unsigned int vendor_cap) +{ + unsigned int std_cap = 0; + size_t i; + + for (i = 0; i < sizeof(sansec_ciphers)/sizeof(sansec_ciphers[0]); i++) { + if (vendor_cap & sansec_ciphers[i].vendor_id) { + std_cap |= sansec_ciphers[i].std_id; + } + } + + return std_cap; +} + +static SDF_ALGOR_PAIR sansec_digests[] = { + { SGD_SM3, SANSEC_SM3 }, + { SGD_SHA1, SANSEC_SHA1 }, + { SGD_SHA256, SANSEC_SHA256 }, + { 0, SANSEC_SHA512 }, + { 0, SANSEC_SHA384 }, + { 0, SANSEC_SHA224 }, + { 0, SANSEC_MD5 }, +}; + +static unsigned int sansec_digest_vendor2std(unsigned int vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { + if (vendor_id == sansec_digests[i].vendor_id) { + return sansec_digests[i].std_id; + } + } + return 0; +} + +static unsigned int sansec_digest_std2vendor(unsigned int std_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { + if (std_id == sansec_digests[i].std_id) { + return sansec_digests[i].vendor_id; + } + } + return 0; +} + +static unsigned int sansec_digest_cap(unsigned int vendor_cap) +{ + unsigned int std_cap = 0; + size_t i; + + for (i = 0; i < sizeof(sansec_digests)/sizeof(sansec_digests[0]); i++) { + if (vendor_cap & sansec_digests[i].vendor_id) { + std_cap |= sansec_digests[i].std_id; + } + } + + return std_cap; +} + +static SDF_ALGOR_PAIR sansec_pkeys[] = { + { SGD_RSA,SANSEC_RSA }, + { SGD_RSA_SIGN,SANSEC_RSA_SIGN }, + { SGD_RSA_ENC,SANSEC_RSA_ENC }, + { SGD_SM2,SANSEC_SM2 }, + { SGD_SM2_1,SANSEC_SM2_1 }, + { SGD_SM2_2,SANSEC_SM2_2 }, + { SGD_SM2_3,SANSEC_SM2_3 }, +}; + +static unsigned int sansec_pkey_vendor2std(unsigned int vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { + if (vendor_id == sansec_pkeys[i].vendor_id) { + return sansec_pkeys[i].std_id; + } + } + return 0; +} + +static unsigned int sansec_pkey_std2vendor(unsigned int std_id) +{ + size_t i; + for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { + if (std_id == sansec_pkeys[i].std_id) { + return sansec_pkeys[i].vendor_id; + } + } + return 0; +} + +static unsigned int sansec_pkey_cap(unsigned int vendor_cap) +{ + unsigned int std_cap = 0; + size_t i; + + for (i = 0; i < sizeof(sansec_pkeys)/sizeof(sansec_pkeys[0]); i++) { + if (vendor_cap & sansec_pkeys[i].vendor_id) { + std_cap |= sansec_pkeys[i].std_id; + } + } + + return std_cap; +} + +static int sansec_encode_ecccipher(const ECCCipher *ec, void *vendor) +{ + int ret; + SANSEC_ECCCipher *sansec = vendor; + ret = sizeof(SANSEC_ECCCipher); + + if (ec->L > sizeof(sansec->C)) { + SDFerr(SDF_F_SANSEC_ENCODE_ECCCIPHER, + SDF_R_INVALID_SANSEC_ECCCIPHER_LENGTH); + return 0; + } + + if (vendor) { + sansec->clength = ec->L; + memcpy(sansec->x, ec->x, sizeof(ec->x)); + memcpy(sansec->y, ec->y, sizeof(ec->y)); + memcpy(sansec->M, ec->M, sizeof(ec->M)); + memset(sansec->M + sizeof(ec->M), 0, sizeof(sansec->M) - sizeof(ec->M)); + memcpy(sansec->C, ec->C, ec->L); + memset(sansec->C + ec->L, 0, sizeof(sansec->C) - ec->L); + } + + return ret; +} + +static int sansec_decode_ecccipher(ECCCipher *ec, const void *vendor) +{ + int ret; + const SANSEC_ECCCipher *sansec = vendor; + ret = sizeof(ECCCipher) -1 + sansec->clength; + + if (sansec->clength > sizeof(sansec->C)) { + SDFerr(SDF_F_SANSEC_DECODE_ECCCIPHER, + SDF_R_INVALID_SANSEC_ECCCIPHER_LENGTH); + return 0; + } + + if (ec) { + memcpy(ec->x, sansec->x, sizeof(ec->x)); + memcpy(ec->y, sansec->y, sizeof(ec->y)); + memcpy(ec->M, sansec->M, sizeof(ec->M)); + ec->L = sansec->clength; + memcpy(ec->C, sansec->C, sansec->clength); + } + + return ret; +} + +static unsigned long sansec_get_error_reason(int err) +{ +/* + size_t i = 0; + for (i = 0; i < OSSL_NELEM(sansec_errors); i++) { + if (err == sansec_errors[i].err) { + return sansec_errors[i].reason; + } + } +*/ + return 0; +} + +SDF_VENDOR sdf_sansec = { + "sansec", + sansec_cipher_vendor2std, + sansec_cipher_std2vendor, + sansec_cipher_cap, + sansec_digest_vendor2std, + sansec_digest_std2vendor, + sansec_digest_cap, + sansec_pkey_vendor2std, + sansec_pkey_std2vendor, + sansec_pkey_cap, + sansec_encode_ecccipher, + sansec_decode_ecccipher, + sansec_get_error_reason, +}; diff --git a/src/sdf/sdf_sansec.h b/src/sdf/sdf_sansec.h index 694e750d..43833ab3 100644 --- a/src/sdf/sdf_sansec.h +++ b/src/sdf/sdf_sansec.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,147 +7,148 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#ifndef SDFUTIL_SDF_SANSEC_H -#define SDFUTIL_SDF_SANSEC_H - -#include "../sgd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SANSEC_SM1 (SGD_SM1) -#define SANSEC_SM1_ECB (SANSEC_SM1|SGD_ECB) -#define SANSEC_SM1_CBC (SANSEC_SM1|SGD_CBC) -#define SANSEC_SM1_CFB (SANSEC_SM1|SGD_CFB) -#define SANSEC_SM1_OFB (SANSEC_SM1|SGD_OFB) -#define SANSEC_SM1_MAC (SANSEC_SM1|SGD_MAC) - -#define SANSEC_SM4 0x00002000 -#define SANSEC_SM4_ECB (SANSEC_SM4|SGD_ECB) -#define SANSEC_SM4_CBC (SANSEC_SM4|SGD_CBC) -#define SANSEC_SM4_CFB (SANSEC_SM4|SGD_CFB) -#define SANSEC_SM4_OFB (SANSEC_SM4|SGD_OFB) -#define SANSEC_SM4_MAC (SANSEC_SM4|SGD_MAC) - -#define SANSEC_SSF33 (SGD_SSF33) -#define SANSEC_SSF33_ECB (SANSEC_SSF33|SGD_ECB) -#define SANSEC_SSF33_CBC (SANSEC_SSF33|SGD_CBC) -#define SANSEC_SSF33_CFB (SANSEC_SSF33|SGD_CFB) -#define SANSEC_SSF33_OFB (SANSEC_SSF33|SGD_OFB) -#define SANSEC_SSF33_MAC (SANSEC_SSF33|SGD_MAC) - -#define SANSEC_AES 0x00000400 -#define SANSEC_AES_ECB (SANSEC_AES|SGD_ECB) -#define SANSEC_AES_CBC (SANSEC_AES|SGD_CBC) -#define SANSEC_AES_CFB (SANSEC_AES|SGD_CFB) -#define SANSEC_AES_OFB (SANSEC_AES|SGD_OFB) -#define SANSEC_AES_MAC (SANSEC_AES|SGD_MAC) - -#define SANSEC_DES 0x00004000 -#define SANSEC_DES_ECB (SANSEC_DES|SGD_ECB) -#define SANSEC_DES_CBC (SANSEC_DES|SGD_CBC) -#define SANSEC_DES_CFB (SANSEC_DES|SGD_CFB) -#define SANSEC_DES_OFB (SANSEC_DES|SGD_OFB) -#define SANSEC_DES_MAC (SANSEC_DES|SGD_MAC) - -#define SANSEC_3DES 0x00000800 -#define SANSEC_3DES_ECB (SANSEC_3DES|SGD_ECB) -#define SANSEC_3DES_CBC (SANSEC_3DES|SGD_CBC) -#define SANSEC_3DES_CFB (SANSEC_3DES|SGD_CFB) -#define SANSEC_3DES_OFB (SANSEC_3DES|SGD_OFB) -#define SANSEC_3DES_MAC (SANSEC_3DES|SGD_MAC) - -#define SANSEC_SM3 (SGD_SM3) -#define SANSEC_SHA1 (SGD_SHA1) -#define SANSEC_SHA256 (SGD_SHA256) -#define SANSEC_SHA512 0x00000008 -#define SANSEC_SHA384 0x00000010 -#define SANSEC_SHA224 0x00000020 -#define SANSEC_MD5 0x00000080 - -#define SANSEC_RSA (SGD_RSA) -#define SANSEC_RSA_SIGN (SGD_RSA_SIGN) -#define SANSEC_RSA_ENC 0x00010200 -#define SANSEC_SM2 (SGD_SM2) -#define SANSEC_SM2_1 (SGD_SM2_1) -#define SANSEC_SM2_2 (SGD_SM2_2) -#define SANSEC_SM2_3 (SGD_SM2_3) - -#define SANSEC_BASE (SDR_BASE + 0x00010000) -#define SANSEC_INVALID_USER (SANSEC_BASE + 0x00000001) -#define SANSEC_INVALID_AUTHENCODE (SANSEC_BASE + 0x00000002) -#define SANSEC_PROTOCOL_VERSION_ERROR (SANSEC_BASE + 0x00000003) -#define SANSEC_INVALID_COMMAND (SANSEC_BASE + 0x00000004) -#define SANSEC_INVALID_PARAMETERS (SANSEC_BASE + 0x00000005) -#define SANSEC_FILE_ALREADY_EXIST (SANSEC_BASE + 0x00000006) -#define SANSEC_SYNC_ERROR (SANSEC_BASE + 0x00000007) -#define SANSEC_SYNC_LOGIN_ERROR (SANSEC_BASE + 0x00000008) -#define SANSEC_SOCKET_TIMEOUT (SANSEC_BASE + 0x00000100) -#define SANSEC_CONNECT_ERROR (SANSEC_BASE + 0x00000101) -#define SANSEC_SET_SOCKET_OPTION_ERROR (SANSEC_BASE + 0x00000102) -#define SANSEC_SOCKET_SEND_ERROR (SANSEC_BASE + 0x00000104) -#define SANSEC_SOCKET_RECV_ERROR (SANSEC_BASE + 0x00000105) -#define SANSEC_SOCKET_RECV_0 (SANSEC_BASE + 0x00000106) -#define SANSEC_SEM_TIMEOUT (SANSEC_BASE + 0x00000200) -#define SANSEC_NO_AVAILABLE_HSM (SANSEC_BASE + 0x00000201) -#define SANSEC_NO_AVAILABLE_CSM (SANSEC_BASE + 0x00000202) -#define SANSEC_CONFIG_ERROR (SANSEC_BASE + 0x00000301) -#define SANSEC_CARD_BASE (SDR_BASE + 0x00020000) -#define SANSEC_CARD_UNKNOW_ERROR (SANSEC_CARD_BASE + 0x00000001) -#define SANSEC_CARD_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000002) -#define SANSEC_CARD_COMMMUCATION_FAILED (SANSEC_CARD_BASE + 0x00000003) -#define SANSEC_CARD_HARDWARE_FAILURE (SANSEC_CARD_BASE + 0x00000004) -#define SANSEC_CARD_OPEN_DEVICE_FAILED (SANSEC_CARD_BASE + 0x00000005) -#define SANSEC_CARD_OPEN_SESSION_FAILED (SANSEC_CARD_BASE + 0x00000006) -#define SANSEC_CARD_PRIVATE_KEY_ACCESS_DENYED (SANSEC_CARD_BASE + 0x00000007) -#define SANSEC_CARD_KEY_NOT_EXIST (SANSEC_CARD_BASE + 0x00000008) -#define SANSEC_CARD_ALGOR_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000009) -#define SANSEC_CARD_ALG_MODE_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000010) -#define SANSEC_CARD_PUBLIC_KEY_OPERATION_ERROR (SANSEC_CARD_BASE + 0x00000011) -#define SANSEC_CARD_PRIVATE_KEY_OPERATION_ERROR (SANSEC_CARD_BASE + 0x00000012) -#define SANSEC_CARD_SIGN_ERROR (SANSEC_CARD_BASE + 0x00000013) -#define SANSEC_CARD_VERIFY_ERROR (SANSEC_CARD_BASE + 0x00000014) -#define SANSEC_CARD_SYMMETRIC_ALGOR_ERROR (SANSEC_CARD_BASE + 0x00000015) -#define SANSEC_CARD_STEP_ERROR (SANSEC_CARD_BASE + 0x00000016) -#define SANSEC_CARD_FILE_SIZE_ERROR (SANSEC_CARD_BASE + 0x00000017) -#define SANSEC_CARD_FILE_NOT_EXIST (SANSEC_CARD_BASE + 0x00000018) -#define SANSEC_CARD_FILE_OFFSET_ERROR (SANSEC_CARD_BASE + 0x00000019) -#define SANSEC_CARD_KEY_TYPE_ERROR (SANSEC_CARD_BASE + 0x00000020) -#define SANSEC_CARD_KEY_ERROR (SANSEC_CARD_BASE + 0x00000021) -#define SANSEC_CARD_BUFFER_TOO_SMALL (SANSEC_CARD_BASE + 0x00000101) -#define SANSEC_CARD_DATA_PADDING_ERROR (SANSEC_CARD_BASE + 0x00000102) -#define SANSEC_CARD_DATA_SIZE (SANSEC_CARD_BASE + 0x00000103) -#define SANSEC_CARD_CRYPTO_NOT_INITED (SANSEC_CARD_BASE + 0x00000104) -#define SANSEC_CARD_MANAGEMENT_DENYED (SANSEC_CARD_BASE + 0x00001001) -#define SANSEC_CARD_OPERATION_DENYED (SANSEC_CARD_BASE + 0x00001002) -#define SANSEC_CARD_DEVICE_STATUS_ERROR (SANSEC_CARD_BASE + 0x00001003) -#define SANSEC_CARD_LOGIN_ERROR (SANSEC_CARD_BASE + 0x00001011) -#define SANSEC_CARD_USERID_ERROR (SANSEC_CARD_BASE + 0x00001012) -#define SANSEC_CARD_PARAMENT_ERROR (SANSEC_CARD_BASE + 0x00001013) -#define SANSEC_CARD_MANAGEMENT_DENYED_05 (SANSEC_CARD_BASE + 0x00000801) -#define SANSEC_CARD_OPERATION_DENYED_05 (SANSEC_CARD_BASE + 0x00000802) -#define SANSEC_CARD_DEVICE_STATUS_ERROR_05 (SANSEC_CARD_BASE + 0x00000803) -#define SANSEC_CARD_LOGIN_ERROR_05 (SANSEC_CARD_BASE + 0x00000811) -#define SANSEC_CARD_USERID_ERROR_05 (SANSEC_CARD_BASE + 0x00000812) -#define SANSEC_CARD_PARAMENT_ERROR_05 (SANSEC_CARD_BASE + 0x00000813) -#define SANSEC_CARD_READER_BASE (SDR_BASE + 0x00030000) -#define SANSEC_CARD_READER_PIN_ERROR (SANSEC_CARD_READER_BASE + 0x000063CE) -#define SANSEC_CARD_READER_NO_CARD (SANSEC_CARD_READER_BASE + 0x0000FF01) -#define SANSEC_CARD_READER_CARD_INSERT (SANSEC_CARD_READER_BASE + 0x0000FF02) -#define SANSEC_CARD_READER_CARD_INSERT_TYPE (SANSEC_CARD_READER_BASE + 0x0000FF03) - -#pragma pack(1) -typedef struct { - unsigned int clength; - unsigned char x[ECCref_MAX_LEN]; - unsigned char y[ECCref_MAX_LEN]; - unsigned char C[136]; - unsigned char M[ECCref_MAX_LEN]; -} SANSEC_ECCCipher; -#pragma pack() - -#ifdef __cplusplus -} -#endif -#endif + +#ifndef SDFUTIL_SDF_SANSEC_H +#define SDFUTIL_SDF_SANSEC_H + +#include "../sgd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SANSEC_SM1 (SGD_SM1) +#define SANSEC_SM1_ECB (SANSEC_SM1|SGD_ECB) +#define SANSEC_SM1_CBC (SANSEC_SM1|SGD_CBC) +#define SANSEC_SM1_CFB (SANSEC_SM1|SGD_CFB) +#define SANSEC_SM1_OFB (SANSEC_SM1|SGD_OFB) +#define SANSEC_SM1_MAC (SANSEC_SM1|SGD_MAC) + +#define SANSEC_SM4 0x00002000 +#define SANSEC_SM4_ECB (SANSEC_SM4|SGD_ECB) +#define SANSEC_SM4_CBC (SANSEC_SM4|SGD_CBC) +#define SANSEC_SM4_CFB (SANSEC_SM4|SGD_CFB) +#define SANSEC_SM4_OFB (SANSEC_SM4|SGD_OFB) +#define SANSEC_SM4_MAC (SANSEC_SM4|SGD_MAC) + +#define SANSEC_SSF33 (SGD_SSF33) +#define SANSEC_SSF33_ECB (SANSEC_SSF33|SGD_ECB) +#define SANSEC_SSF33_CBC (SANSEC_SSF33|SGD_CBC) +#define SANSEC_SSF33_CFB (SANSEC_SSF33|SGD_CFB) +#define SANSEC_SSF33_OFB (SANSEC_SSF33|SGD_OFB) +#define SANSEC_SSF33_MAC (SANSEC_SSF33|SGD_MAC) + +#define SANSEC_AES 0x00000400 +#define SANSEC_AES_ECB (SANSEC_AES|SGD_ECB) +#define SANSEC_AES_CBC (SANSEC_AES|SGD_CBC) +#define SANSEC_AES_CFB (SANSEC_AES|SGD_CFB) +#define SANSEC_AES_OFB (SANSEC_AES|SGD_OFB) +#define SANSEC_AES_MAC (SANSEC_AES|SGD_MAC) + +#define SANSEC_DES 0x00004000 +#define SANSEC_DES_ECB (SANSEC_DES|SGD_ECB) +#define SANSEC_DES_CBC (SANSEC_DES|SGD_CBC) +#define SANSEC_DES_CFB (SANSEC_DES|SGD_CFB) +#define SANSEC_DES_OFB (SANSEC_DES|SGD_OFB) +#define SANSEC_DES_MAC (SANSEC_DES|SGD_MAC) + +#define SANSEC_3DES 0x00000800 +#define SANSEC_3DES_ECB (SANSEC_3DES|SGD_ECB) +#define SANSEC_3DES_CBC (SANSEC_3DES|SGD_CBC) +#define SANSEC_3DES_CFB (SANSEC_3DES|SGD_CFB) +#define SANSEC_3DES_OFB (SANSEC_3DES|SGD_OFB) +#define SANSEC_3DES_MAC (SANSEC_3DES|SGD_MAC) + +#define SANSEC_SM3 (SGD_SM3) +#define SANSEC_SHA1 (SGD_SHA1) +#define SANSEC_SHA256 (SGD_SHA256) +#define SANSEC_SHA512 0x00000008 +#define SANSEC_SHA384 0x00000010 +#define SANSEC_SHA224 0x00000020 +#define SANSEC_MD5 0x00000080 + +#define SANSEC_RSA (SGD_RSA) +#define SANSEC_RSA_SIGN (SGD_RSA_SIGN) +#define SANSEC_RSA_ENC 0x00010200 +#define SANSEC_SM2 (SGD_SM2) +#define SANSEC_SM2_1 (SGD_SM2_1) +#define SANSEC_SM2_2 (SGD_SM2_2) +#define SANSEC_SM2_3 (SGD_SM2_3) + +#define SANSEC_BASE (SDR_BASE + 0x00010000) +#define SANSEC_INVALID_USER (SANSEC_BASE + 0x00000001) +#define SANSEC_INVALID_AUTHENCODE (SANSEC_BASE + 0x00000002) +#define SANSEC_PROTOCOL_VERSION_ERROR (SANSEC_BASE + 0x00000003) +#define SANSEC_INVALID_COMMAND (SANSEC_BASE + 0x00000004) +#define SANSEC_INVALID_PARAMETERS (SANSEC_BASE + 0x00000005) +#define SANSEC_FILE_ALREADY_EXIST (SANSEC_BASE + 0x00000006) +#define SANSEC_SYNC_ERROR (SANSEC_BASE + 0x00000007) +#define SANSEC_SYNC_LOGIN_ERROR (SANSEC_BASE + 0x00000008) +#define SANSEC_SOCKET_TIMEOUT (SANSEC_BASE + 0x00000100) +#define SANSEC_CONNECT_ERROR (SANSEC_BASE + 0x00000101) +#define SANSEC_SET_SOCKET_OPTION_ERROR (SANSEC_BASE + 0x00000102) +#define SANSEC_SOCKET_SEND_ERROR (SANSEC_BASE + 0x00000104) +#define SANSEC_SOCKET_RECV_ERROR (SANSEC_BASE + 0x00000105) +#define SANSEC_SOCKET_RECV_0 (SANSEC_BASE + 0x00000106) +#define SANSEC_SEM_TIMEOUT (SANSEC_BASE + 0x00000200) +#define SANSEC_NO_AVAILABLE_HSM (SANSEC_BASE + 0x00000201) +#define SANSEC_NO_AVAILABLE_CSM (SANSEC_BASE + 0x00000202) +#define SANSEC_CONFIG_ERROR (SANSEC_BASE + 0x00000301) +#define SANSEC_CARD_BASE (SDR_BASE + 0x00020000) +#define SANSEC_CARD_UNKNOW_ERROR (SANSEC_CARD_BASE + 0x00000001) +#define SANSEC_CARD_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000002) +#define SANSEC_CARD_COMMMUCATION_FAILED (SANSEC_CARD_BASE + 0x00000003) +#define SANSEC_CARD_HARDWARE_FAILURE (SANSEC_CARD_BASE + 0x00000004) +#define SANSEC_CARD_OPEN_DEVICE_FAILED (SANSEC_CARD_BASE + 0x00000005) +#define SANSEC_CARD_OPEN_SESSION_FAILED (SANSEC_CARD_BASE + 0x00000006) +#define SANSEC_CARD_PRIVATE_KEY_ACCESS_DENYED (SANSEC_CARD_BASE + 0x00000007) +#define SANSEC_CARD_KEY_NOT_EXIST (SANSEC_CARD_BASE + 0x00000008) +#define SANSEC_CARD_ALGOR_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000009) +#define SANSEC_CARD_ALG_MODE_NOT_SUPPORTED (SANSEC_CARD_BASE + 0x00000010) +#define SANSEC_CARD_PUBLIC_KEY_OPERATION_ERROR (SANSEC_CARD_BASE + 0x00000011) +#define SANSEC_CARD_PRIVATE_KEY_OPERATION_ERROR (SANSEC_CARD_BASE + 0x00000012) +#define SANSEC_CARD_SIGN_ERROR (SANSEC_CARD_BASE + 0x00000013) +#define SANSEC_CARD_VERIFY_ERROR (SANSEC_CARD_BASE + 0x00000014) +#define SANSEC_CARD_SYMMETRIC_ALGOR_ERROR (SANSEC_CARD_BASE + 0x00000015) +#define SANSEC_CARD_STEP_ERROR (SANSEC_CARD_BASE + 0x00000016) +#define SANSEC_CARD_FILE_SIZE_ERROR (SANSEC_CARD_BASE + 0x00000017) +#define SANSEC_CARD_FILE_NOT_EXIST (SANSEC_CARD_BASE + 0x00000018) +#define SANSEC_CARD_FILE_OFFSET_ERROR (SANSEC_CARD_BASE + 0x00000019) +#define SANSEC_CARD_KEY_TYPE_ERROR (SANSEC_CARD_BASE + 0x00000020) +#define SANSEC_CARD_KEY_ERROR (SANSEC_CARD_BASE + 0x00000021) +#define SANSEC_CARD_BUFFER_TOO_SMALL (SANSEC_CARD_BASE + 0x00000101) +#define SANSEC_CARD_DATA_PADDING_ERROR (SANSEC_CARD_BASE + 0x00000102) +#define SANSEC_CARD_DATA_SIZE (SANSEC_CARD_BASE + 0x00000103) +#define SANSEC_CARD_CRYPTO_NOT_INITED (SANSEC_CARD_BASE + 0x00000104) +#define SANSEC_CARD_MANAGEMENT_DENYED (SANSEC_CARD_BASE + 0x00001001) +#define SANSEC_CARD_OPERATION_DENYED (SANSEC_CARD_BASE + 0x00001002) +#define SANSEC_CARD_DEVICE_STATUS_ERROR (SANSEC_CARD_BASE + 0x00001003) +#define SANSEC_CARD_LOGIN_ERROR (SANSEC_CARD_BASE + 0x00001011) +#define SANSEC_CARD_USERID_ERROR (SANSEC_CARD_BASE + 0x00001012) +#define SANSEC_CARD_PARAMENT_ERROR (SANSEC_CARD_BASE + 0x00001013) +#define SANSEC_CARD_MANAGEMENT_DENYED_05 (SANSEC_CARD_BASE + 0x00000801) +#define SANSEC_CARD_OPERATION_DENYED_05 (SANSEC_CARD_BASE + 0x00000802) +#define SANSEC_CARD_DEVICE_STATUS_ERROR_05 (SANSEC_CARD_BASE + 0x00000803) +#define SANSEC_CARD_LOGIN_ERROR_05 (SANSEC_CARD_BASE + 0x00000811) +#define SANSEC_CARD_USERID_ERROR_05 (SANSEC_CARD_BASE + 0x00000812) +#define SANSEC_CARD_PARAMENT_ERROR_05 (SANSEC_CARD_BASE + 0x00000813) +#define SANSEC_CARD_READER_BASE (SDR_BASE + 0x00030000) +#define SANSEC_CARD_READER_PIN_ERROR (SANSEC_CARD_READER_BASE + 0x000063CE) +#define SANSEC_CARD_READER_NO_CARD (SANSEC_CARD_READER_BASE + 0x0000FF01) +#define SANSEC_CARD_READER_CARD_INSERT (SANSEC_CARD_READER_BASE + 0x0000FF02) +#define SANSEC_CARD_READER_CARD_INSERT_TYPE (SANSEC_CARD_READER_BASE + 0x0000FF03) + +#pragma pack(1) +typedef struct { + unsigned int clength; + unsigned char x[ECCref_MAX_LEN]; + unsigned char y[ECCref_MAX_LEN]; + unsigned char C[136]; + unsigned char M[ECCref_MAX_LEN]; +} SANSEC_ECCCipher; +#pragma pack() + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/sgd.h b/src/sgd.h index 95dd5125..93ad96a3 100644 --- a/src/sgd.h +++ b/src/sgd.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,391 +7,392 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -/* - * this header file is based on the standard GM/T 0006-2012 - * Cryptographic Application Identifier Criterion Specification - */ - -#ifndef SDFUTIL_SGD_H -#define SDFUTIL_SGD_H - - -#include - - -/* block cipher modes */ -#define SGD_ECB 0x01 -#define SGD_CBC 0x02 -#define SGD_CFB 0x04 -#define SGD_OFB 0x08 -#define SGD_MAC 0x10 - -/* stream cipher modes */ -#define SGD_EEA3 0x01 -#define SGD_EIA3 0x02 - -/* ciphers */ -#define SGD_SM1 0x00000100 -#define SGD_SSF33 0x00000200 -#define SGD_SM4 0x00000400 -#define SGD_ZUC 0x00000800 - -/* ciphers with modes */ -#define SGD_SM1_ECB (SGD_SM1|SGD_ECB) -#define SGD_SM1_CBC (SGD_SM1|SGD_CBC) -#define SGD_SM1_CFB (SGD_SM1|SGD_CFB) -#define SGD_SM1_OFB (SGD_SM1|SGD_OFB) -#define SGD_SM1_MAC (SGD_SM1|SGD_MAC) -#define SGD_SSF33_ECB (SGD_SSF33|SGD_ECB) -#define SGD_SSF33_CBC (SGD_SSF33|SGD_CBC) -#define SGD_SSF33_CFB (SGD_SSF33|SGD_CFB) -#define SGD_SSF33_OFB (SGD_SSF33|SGD_OFB) -#define SGD_SSF33_MAC (SGD_SSF33|SGD_MAC) -#define SGD_SM4_ECB (SGD_SM4|SGD_ECB) -#define SGD_SM4_CBC (SGD_SM4|SGD_CBC) -#define SGD_SM4_CFB (SGD_SM4|SGD_CFB) -#define SGD_SM4_OFB (SGD_SM4|SGD_OFB) -#define SGD_SM4_MAC (SGD_SM4|SGD_MAC) -#define SGD_ZUC_EEA3 (SGD_ZUC|SGD_EEA3) -#define SGD_ZUC_EIA3 (SGD_ZUC|SGD_EIA3) - -/* public key usage */ -#define SGD_PK_SIGN 0x0100 // FIXME: correct? -#define SGD_PK_DH 0x0200 // FIXME: correct? -#define SGD_PK_ENC 0x0400 // FIXME: correct? - -/* public key types */ -#define SGD_RSA 0x00010000 -#define SGD_RSA_SIGN (SGD_RSA|SGD_PK_SIGN) // FIXME: correct? -#define SGD_RSA_ENC (SGD_RSA|SGD_PK_ENC) // FIXME: correct? -#define SGD_SM2 0x00020100 -#define SGD_SM2_1 0x00020200 -#define SGD_SM2_2 0x00020400 -#define SGD_SM2_3 0x00020800 - -/* hash */ -#define SGD_SM3 0x00000001 -#define SGD_SHA1 0x00000002 -#define SGD_SHA256 0x00000004 -#define SGD_HASH_FROM 0x00000008 -#define SGD_HASH_TO 0x000000FF - -/* signatue schemes */ -#define SGD_SM3_RSA (SGD_SM3|SGD_RSA) -#define SGD_SHA1_RSA (SGD_SHA1|SGD_RSA) -#define SGD_SHA256_RSA (SGD_SHA256|SGD_RSA) -#define SGD_SM3_SM2 (SGD_SM3|SGD_SM2) -#define SGD_SIG_FROM 0x00040000 -#define SGD_SIG_TO 0x800000FF - -/* data types */ -typedef char SGD_CHAR; -typedef char SGD_INT8; -typedef int16_t SGD_INT16; -typedef int32_t SGD_INT32; -typedef int64_t SGD_INT64; -typedef unsigned char SGD_UCHAR; -typedef uint8_t SGD_UINT8; -typedef uint16_t SGD_UINT16; -typedef uint32_t SGD_UINT32; -typedef uint64_t SGD_UINT64; -typedef uint32_t SGD_RV; -typedef void * SGD_OBJ; -typedef int32_t SGD_BOOL; - -#define SGD_TRUE 0x00000001 -#define SGD_FALSE 0x00000000 - -#define SGD_KEY_INDEX 0x00000101 -#define SGD_SECRET_KEY 0x00000102 -#define SGD_PUBLIC_KEY_SIGN 0x00000103 -#define SGD_PUBLIC_KEY_ENCRYPT 0x00000104 -#define SGD_PRIVATE_KEY_SIGN 0x00000105 -#define SGD_PRIVATE_KEY_ENCRYPT 0x00000106 -#define SGD_KEY_COMPONENT 0x00000107 -#define SGD_PASSWORD 0x00000108 -#define SGD_PUBLIC_KEY_CERT 0x00000109 -#define SGD_ATTRIBUTE_CERT 0x1000010A -#define SGD_SIGNATURE_DATA 0x10000111 -#define SGD_ENVELOPE_DATA 0x10000112 -#define SGD_RANDOM_DATA 0x10000113 -#define SGD_PLAIN_DATA 0x10000114 -#define SGD_CIPHER_DATA 0x10000115 -#define SGD_DIGEST_DATA 0x10000116 -#define SGD_USER_DATA 0x10000117 - -/* certificate */ -#define SGD_CERT_VERSION 0x00000001 -#define SGD_CERT_SERIAL 0x00000002 -#define SGD_CERT_ISSUER 0x00000005 -#define SGD_CERT_VALID_TIME 0x00000006 -#define SGD_CERT_SUBJECT 0x00000007 -#define SGD_CERT_DER_PUBLIC_KEY 0x00000008 -#define SGD_CERT_DER_EXTENSIONS 0x00000009 -#define SGD_EXT_AUTHORITYKEYIDENTIFIER_INFO 0x00000011 -#define SGD_EXT_SUBJECTKEYIDENTIFIER_INFO 0x00000012 -#define SGD_EXT_KEYUSAGE_INFO 0x00000013 -#define SGD_EXT_PRIVATEKEYUSAGEPERIOD_INFO 0x00000014 -#define SGD_EXT_CERTIFICATEPOLICIES_INFO 0x00000015 -#define SGD_EXT_POLICYMAPPINGS_INFO 0x00000016 -#define SGD_EXT_BASICCONSTRAINTS_INFO 0x00000017 -#define SGD_EXT_POLICYCONSTRAINTS_INFO 0x00000018 -#define SGD_EXT_EXTKEYUSAGE_INFO 0x00000019 -#define SGD_EXT_CRLDISTRIBUTIONPOINTS_INFO 0x0000001A -#define SGD_EXT_NETSCAPE_CERT_TYPE_INFO 0x0000001B -#define SGD_EXT_SELFDEFINED_EXTENSION_INFO 0x0000001C -#define SGD_CERT_ISSUER_CN 0x00000021 -#define SGD_CERT_ISSUER_O 0x00000022 -#define SGD_CERT_ISSUER_OU 0x00000023 -#define SGD_CERT_SUBJECT_CN 0x00000031 -#define SGD_CERT_SUBJECT_O 0x00000032 -#define SGD_CERT_SUBJECT_OU 0x00000033 -#define SGD_CERT_SUBJECT_EMAIL 0x00000034 -#define SGD_CERT_NOTBEFORE_TIME 0x00000035 -#define SGD_CERT_NOTAFTER_TIME 0x00000036 - -/* timestamp info */ -#define SGD_TIME_OF_STAMP 0x00000201 -#define SGD_CN_OF_TSSIGNER 0x00000202 /* Common Name of TS Signer */ -#define SGD_ORININAL_DATA 0x00000203 -#define SGD_CERT_OF_TSSSERVER 0x00000204 -#define SGD_GERTCHAIN_OF_TSSERVER 0x00000205 -#define SGD_SOURCE_OF_TIME 0x00000206 -#define SGD_TIME_PRECISION 0x00000207 -#define SGD_RESPONSE_TYPE 0x00000208 -#define SGD_SUBJECT_COUNTRY_OF_TSSIGNER 0x00000209 -#define SGD_SUBJECT_ORGNIZATION_OF_TSSIGNER 0x0000020A -#define SGD_SUJECT_CITY_OF_TSSIGNER 0x0000020B -#define SGD_SUBJECT_EMAIL_OF_TSSIGNER 0x0000020C - -/* single sign-on */ -#define SGD_SP_ID 0x00000001 -#define SGD_SP_USER_ID 0x00000002 -#define SGD_IDP_ID 0x00000003 -#define SGD_IDP_USER_ID 0x00000004 - -/* data encoding */ -#define SGD_ENCODING_RAW 0x00000000 -#define SGD_ENCODING_DER 0x01000000 -#define SGD_ENCODING_BASE64 0x02000000 -#define SGD_ENCODING_PEM 0x03000000 -#define SGD_ENCODING_TXT 0x04000000 - -/* APIs */ -#define SGD_PROTOCOL_CSP 1 /* Microsoft CryptoAPI */ -#define SGD_PROTOCOL_PKCS11 2 /* PKCS#11 */ -#define SGD_PROTOCOL_SDS 3 /* SDF API */ -#define SGD_PROTOCOL_UKEY 4 /* SKF API */ -#define SGD_PROTOCOL_CNG 5 /* Microsoft CryptoAPI Next Gen */ -#define SGD_PROTOCOL_GCS 6 /* */ - -/* certificate validation */ -#define SGD_CRL_VERIFY 1 -#define SGD_OCSP_VEIFY 2 - -/* role */ -#define SGD_ROLE_SUPER_MANAGER 0x00000001 -#define SGD_ROLE_MANAGER 0x00000002 -#define SGD_ROLE_AUDIT_MANAGER 0x00000003 -#define SGD_ROLE_AUDITOR 0x00000004 -#define SGD_ROLE_OPERATOR 0x00000005 -#define SGD_ROLE_USER 0x00000006 - -/* user operations */ -#define SGD_OPERATION_SIGNIN 0x00000001 -#define SGD_OPERATION_SIGNOUT 0x00000002 -#define SGD_OPERATION_CREATE 0x00000003 -#define SGD_OPERATION_DELETE 0x00000004 -#define SGD_OPERATION_MODIFY 0x00000005 -#define SGD_OPERATION_CHG_PWD 0x00000006 -#define SGD_OPERATION_AUTHORIZATION 0x00000007 - -/* user operation results */ -#define SGD_OPERATION_SUCCESS 0x00000000 - -/* key types */ -#define SGD_MAIN_KEY 0x00000101 -#define SGD_DEVICE_KEYS 0x00000102 -#define SGD_USER_KEYS 0x00000103 -#define SGD_KEY 0x00000104 -#define SGD_SESSION_KEY 0x00000105 -#define SGD_PRIKEY_PASSWD 0x00000106 -#define SGD_COMPARTITION_KEY 0x00000107 - -/* key operations */ -#define SGD_KEY_GENERATION 0x00000101 -#define SGD_KEY_DISPENSE 0x00000102 -#define SGD_KEY_IMPORT 0x00000103 -#define SGD_KEY_EXPORT 0x00000104 -#define SGD_KEY_DIVISION 0x00000105 -#define SGD_KEY_COMPOSE 0x00000106 -#define SGD_KEY_RENEWAL 0x00000107 -#define SGD_KEY_BACKUP 0x00000108 -#define SGD_KEY_RESTORE 0x00000109 -#define SGD_KEY_DESTORY 0x0000010A - -/* system operations */ -#define SGD_SYSTEM_INIT 0x00000201 -#define SGD_SYSTEM_START 0x00000202 -#define SGD_SYSTEM_SHUT 0x00000203 -#define SGD_SYSTEM_RESTART 0x00000204 -#define SGD_SYSTEM_QUERY 0x00000205 -#define SGD_SYSTEM_BACKUP 0x00000206 -#define SGD_SYSTEM_RESTORE 0x00000207 - -/* device info */ -#define SGD_DEVICE_SORT 0x00000201 -#define SGD_DEVICE_TYPE 0x00000202 -#define SGD_DEVICE_NAME 0x00000203 -#define SGD_DEVICE_MANUFACTURER 0x00000204 -#define SGD_DEVICE_HARDWARE_VERSION 0x00000205 -#define SGD_DEVICE_SOFTWARE_VERSION 0x00000206 -#define SGD_DEVICE_STANDARD_VERSION 0x00000207 -#define SGD_DEVICE_SERIAL_NUMBER 0x00000208 -#define SGD_DEVICE_SUPPORT_SYMM_ALG 0x00000209 -#define SGD_DEVICE_SUPPORT_PKEY_ALG 0x0000020A -#define SGD_DEVICE_SUPPORT_HASH_ALG 0x0000020B -#define SGD_DEVICE_SUPPORT_STORAGE_SPACE 0x0000020C -#define SGD_DEVICE_SUPPORT_FREE_SPACE 0x0000020D -#define SGD_DEVICE_RUNTIME 0x0000020E -#define SGD_DEVICE_USED_TIMES 0x0000020F -#define SGD_DEVICE_LOCATION 0x00000210 -#define SGD_DEVICE_DESCRIPTION 0x00000211 -#define SGD_DEVICE_MANAGER_INFO 0x00000212 -#define SGD_DEVICE_MAX_DATA_SIZE 0x00000213 - -/* device types */ -#define SGD_DEVICE_SORT_SJ 0x02000000 /* Server */ -#define SGD_DEVICE_SORT_SK 0x03000000 /* PCI-E Card */ -#define SGD_DEVICE_SORT_SM 0x04000000 /* USB-Key and SmartCard */ - -/* device functionality */ -#define SGD_DEVICE_SORT_FE 0x00000100 /* encryption */ -#define SGD_DEVICE_SORT_FA 0x00000200 /* authentication */ -#define SGD_DEVICE_SORT_FM 0x00000300 /* key management */ - -/* device status */ -#define SGD_STATUS_INIT 0x00000201 -#define SGD_STATUS_READY 0x00000202 -#define SGD_STATUS_EXCEPTION 0x00000203 - -/* SKF */ -#ifndef WIN32 -typedef signed char INT8; -typedef signed short INT16; -typedef signed int INT32; -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -typedef long BOOL; -typedef UINT8 BYTE; -typedef UINT8 CHAR; -typedef INT16 SHORT; -typedef UINT16 USHORT; -# ifndef SGD_NATIVE_LONG -typedef INT32 LONG; -typedef UINT32 ULONG; -# else -typedef long LONG; -typedef unsigned long ULONG; -# endif -typedef UINT32 UINT; -typedef UINT16 WORD; -typedef UINT32 DWORD; -typedef UINT32 FLAGS; -typedef CHAR * LPSTR; -typedef void * HANDLE; -#else -#ifndef _WINDEF_H -typedef signed char INT8; -typedef signed short INT16; -typedef signed int INT32; -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -typedef long BOOL; -typedef UINT8 BYTE; -typedef UINT8 CHAR; -typedef INT16 SHORT; -typedef UINT16 USHORT; -# ifndef SGD_NATIVE_LONG -typedef INT32 LONG; -typedef UINT32 ULONG; -# else -typedef long LONG; -typedef unsigned long ULONG; -# endif -typedef UINT32 UINT; -typedef UINT16 WORD; -typedef UINT32 DWORD; -typedef UINT32 FLAGS; -typedef CHAR * LPSTR; -typedef void * HANDLE; -#endif -#endif - -typedef HANDLE DEVHANDLE; -typedef HANDLE HAPPLICATION; -typedef HANDLE HSESSION; -typedef HANDLE HCONTAINER; - -#ifndef FALSE -#define FALSE 0x00000000 -#endif - -#ifndef TRUE -#define TRUE 0x00000001 -#endif - -#ifdef WIN32 -#define DEVAPI __stdcall -#else -#define DEVAPI -#endif - -#ifndef ADMIN_TYPE -#define ADMIN_TYPE 0 -#endif - -#ifndef USER_TYPE -#define USER_TYPE 1 -#endif - -#define MAX_RSA_MODULUS_LEN 256 -#define MAX_RSA_EXPONENT_LEN 4 -#define ECC_MAX_XCOORDINATE_BITS_LEN 512 -#define ECC_MAX_YCOORDINATE_BITS_LEN 512 -#define ECC_MAX_MODULUS_BITS_LEN 512 - -#define MAX_IV_LEN 32 - -#define MAX_FILE_NAME_SIZE 32 -#define MAX_FILE_CONTAINER_NAME_SIZE 64 - -#define SECURE_NEVER_ACCOUNT 0x00000000 -#define SECURE_ADM_ACCOUNT 0x00000001 -#define SECURE_USER_ACCOUNT 0x00000010 -#define SECURE_ANYONE_ACCOUNT 0x000000FF - - -/* SDF */ - -#define RSAref_MAX_BITS 2048 -#define RSAref_MAX_LEN ((RSAref_MAX_BITS + 7) / 8) -#define RSAref_MAX_PBITS ((RSAref_MAX_BITS + 1) / 2) -#define RSAref_MAX_PLEN ((RSAref_MAX_PBITS + 7)/ 8) - -#ifdef SGD_MAX_ECC_BITS_256 -#define ECCref_MAX_BITS 256 -#else -#define ECCref_MAX_BITS 512 -#endif -#define ECCref_MAX_LEN ((ECCref_MAX_BITS+7) / 8) - - -/* SAF */ -#define SGD_MAX_COUNT 64 -#define SGD_MAX_NAME_SIZE 256 - - -#endif + +/* + * this header file is based on the standard GM/T 0006-2012 + * Cryptographic Application Identifier Criterion Specification + */ + +#ifndef SDFUTIL_SGD_H +#define SDFUTIL_SGD_H + + +#include + + +/* block cipher modes */ +#define SGD_ECB 0x01 +#define SGD_CBC 0x02 +#define SGD_CFB 0x04 +#define SGD_OFB 0x08 +#define SGD_MAC 0x10 + +/* stream cipher modes */ +#define SGD_EEA3 0x01 +#define SGD_EIA3 0x02 + +/* ciphers */ +#define SGD_SM1 0x00000100 +#define SGD_SSF33 0x00000200 +#define SGD_SM4 0x00000400 +#define SGD_ZUC 0x00000800 + +/* ciphers with modes */ +#define SGD_SM1_ECB (SGD_SM1|SGD_ECB) +#define SGD_SM1_CBC (SGD_SM1|SGD_CBC) +#define SGD_SM1_CFB (SGD_SM1|SGD_CFB) +#define SGD_SM1_OFB (SGD_SM1|SGD_OFB) +#define SGD_SM1_MAC (SGD_SM1|SGD_MAC) +#define SGD_SSF33_ECB (SGD_SSF33|SGD_ECB) +#define SGD_SSF33_CBC (SGD_SSF33|SGD_CBC) +#define SGD_SSF33_CFB (SGD_SSF33|SGD_CFB) +#define SGD_SSF33_OFB (SGD_SSF33|SGD_OFB) +#define SGD_SSF33_MAC (SGD_SSF33|SGD_MAC) +#define SGD_SM4_ECB (SGD_SM4|SGD_ECB) +#define SGD_SM4_CBC (SGD_SM4|SGD_CBC) +#define SGD_SM4_CFB (SGD_SM4|SGD_CFB) +#define SGD_SM4_OFB (SGD_SM4|SGD_OFB) +#define SGD_SM4_MAC (SGD_SM4|SGD_MAC) +#define SGD_ZUC_EEA3 (SGD_ZUC|SGD_EEA3) +#define SGD_ZUC_EIA3 (SGD_ZUC|SGD_EIA3) + +/* public key usage */ +#define SGD_PK_SIGN 0x0100 // FIXME: correct? +#define SGD_PK_DH 0x0200 // FIXME: correct? +#define SGD_PK_ENC 0x0400 // FIXME: correct? + +/* public key types */ +#define SGD_RSA 0x00010000 +#define SGD_RSA_SIGN (SGD_RSA|SGD_PK_SIGN) // FIXME: correct? +#define SGD_RSA_ENC (SGD_RSA|SGD_PK_ENC) // FIXME: correct? +#define SGD_SM2 0x00020100 +#define SGD_SM2_1 0x00020200 +#define SGD_SM2_2 0x00020400 +#define SGD_SM2_3 0x00020800 + +/* hash */ +#define SGD_SM3 0x00000001 +#define SGD_SHA1 0x00000002 +#define SGD_SHA256 0x00000004 +#define SGD_HASH_FROM 0x00000008 +#define SGD_HASH_TO 0x000000FF + +/* signatue schemes */ +#define SGD_SM3_RSA (SGD_SM3|SGD_RSA) +#define SGD_SHA1_RSA (SGD_SHA1|SGD_RSA) +#define SGD_SHA256_RSA (SGD_SHA256|SGD_RSA) +#define SGD_SM3_SM2 (SGD_SM3|SGD_SM2) +#define SGD_SIG_FROM 0x00040000 +#define SGD_SIG_TO 0x800000FF + +/* data types */ +typedef char SGD_CHAR; +typedef char SGD_INT8; +typedef int16_t SGD_INT16; +typedef int32_t SGD_INT32; +typedef int64_t SGD_INT64; +typedef unsigned char SGD_UCHAR; +typedef uint8_t SGD_UINT8; +typedef uint16_t SGD_UINT16; +typedef uint32_t SGD_UINT32; +typedef uint64_t SGD_UINT64; +typedef uint32_t SGD_RV; +typedef void * SGD_OBJ; +typedef int32_t SGD_BOOL; + +#define SGD_TRUE 0x00000001 +#define SGD_FALSE 0x00000000 + +#define SGD_KEY_INDEX 0x00000101 +#define SGD_SECRET_KEY 0x00000102 +#define SGD_PUBLIC_KEY_SIGN 0x00000103 +#define SGD_PUBLIC_KEY_ENCRYPT 0x00000104 +#define SGD_PRIVATE_KEY_SIGN 0x00000105 +#define SGD_PRIVATE_KEY_ENCRYPT 0x00000106 +#define SGD_KEY_COMPONENT 0x00000107 +#define SGD_PASSWORD 0x00000108 +#define SGD_PUBLIC_KEY_CERT 0x00000109 +#define SGD_ATTRIBUTE_CERT 0x1000010A +#define SGD_SIGNATURE_DATA 0x10000111 +#define SGD_ENVELOPE_DATA 0x10000112 +#define SGD_RANDOM_DATA 0x10000113 +#define SGD_PLAIN_DATA 0x10000114 +#define SGD_CIPHER_DATA 0x10000115 +#define SGD_DIGEST_DATA 0x10000116 +#define SGD_USER_DATA 0x10000117 + +/* certificate */ +#define SGD_CERT_VERSION 0x00000001 +#define SGD_CERT_SERIAL 0x00000002 +#define SGD_CERT_ISSUER 0x00000005 +#define SGD_CERT_VALID_TIME 0x00000006 +#define SGD_CERT_SUBJECT 0x00000007 +#define SGD_CERT_DER_PUBLIC_KEY 0x00000008 +#define SGD_CERT_DER_EXTENSIONS 0x00000009 +#define SGD_EXT_AUTHORITYKEYIDENTIFIER_INFO 0x00000011 +#define SGD_EXT_SUBJECTKEYIDENTIFIER_INFO 0x00000012 +#define SGD_EXT_KEYUSAGE_INFO 0x00000013 +#define SGD_EXT_PRIVATEKEYUSAGEPERIOD_INFO 0x00000014 +#define SGD_EXT_CERTIFICATEPOLICIES_INFO 0x00000015 +#define SGD_EXT_POLICYMAPPINGS_INFO 0x00000016 +#define SGD_EXT_BASICCONSTRAINTS_INFO 0x00000017 +#define SGD_EXT_POLICYCONSTRAINTS_INFO 0x00000018 +#define SGD_EXT_EXTKEYUSAGE_INFO 0x00000019 +#define SGD_EXT_CRLDISTRIBUTIONPOINTS_INFO 0x0000001A +#define SGD_EXT_NETSCAPE_CERT_TYPE_INFO 0x0000001B +#define SGD_EXT_SELFDEFINED_EXTENSION_INFO 0x0000001C +#define SGD_CERT_ISSUER_CN 0x00000021 +#define SGD_CERT_ISSUER_O 0x00000022 +#define SGD_CERT_ISSUER_OU 0x00000023 +#define SGD_CERT_SUBJECT_CN 0x00000031 +#define SGD_CERT_SUBJECT_O 0x00000032 +#define SGD_CERT_SUBJECT_OU 0x00000033 +#define SGD_CERT_SUBJECT_EMAIL 0x00000034 +#define SGD_CERT_NOTBEFORE_TIME 0x00000035 +#define SGD_CERT_NOTAFTER_TIME 0x00000036 + +/* timestamp info */ +#define SGD_TIME_OF_STAMP 0x00000201 +#define SGD_CN_OF_TSSIGNER 0x00000202 /* Common Name of TS Signer */ +#define SGD_ORININAL_DATA 0x00000203 +#define SGD_CERT_OF_TSSSERVER 0x00000204 +#define SGD_GERTCHAIN_OF_TSSERVER 0x00000205 +#define SGD_SOURCE_OF_TIME 0x00000206 +#define SGD_TIME_PRECISION 0x00000207 +#define SGD_RESPONSE_TYPE 0x00000208 +#define SGD_SUBJECT_COUNTRY_OF_TSSIGNER 0x00000209 +#define SGD_SUBJECT_ORGNIZATION_OF_TSSIGNER 0x0000020A +#define SGD_SUJECT_CITY_OF_TSSIGNER 0x0000020B +#define SGD_SUBJECT_EMAIL_OF_TSSIGNER 0x0000020C + +/* single sign-on */ +#define SGD_SP_ID 0x00000001 +#define SGD_SP_USER_ID 0x00000002 +#define SGD_IDP_ID 0x00000003 +#define SGD_IDP_USER_ID 0x00000004 + +/* data encoding */ +#define SGD_ENCODING_RAW 0x00000000 +#define SGD_ENCODING_DER 0x01000000 +#define SGD_ENCODING_BASE64 0x02000000 +#define SGD_ENCODING_PEM 0x03000000 +#define SGD_ENCODING_TXT 0x04000000 + +/* APIs */ +#define SGD_PROTOCOL_CSP 1 /* Microsoft CryptoAPI */ +#define SGD_PROTOCOL_PKCS11 2 /* PKCS#11 */ +#define SGD_PROTOCOL_SDS 3 /* SDF API */ +#define SGD_PROTOCOL_UKEY 4 /* SKF API */ +#define SGD_PROTOCOL_CNG 5 /* Microsoft CryptoAPI Next Gen */ +#define SGD_PROTOCOL_GCS 6 /* */ + +/* certificate validation */ +#define SGD_CRL_VERIFY 1 +#define SGD_OCSP_VEIFY 2 + +/* role */ +#define SGD_ROLE_SUPER_MANAGER 0x00000001 +#define SGD_ROLE_MANAGER 0x00000002 +#define SGD_ROLE_AUDIT_MANAGER 0x00000003 +#define SGD_ROLE_AUDITOR 0x00000004 +#define SGD_ROLE_OPERATOR 0x00000005 +#define SGD_ROLE_USER 0x00000006 + +/* user operations */ +#define SGD_OPERATION_SIGNIN 0x00000001 +#define SGD_OPERATION_SIGNOUT 0x00000002 +#define SGD_OPERATION_CREATE 0x00000003 +#define SGD_OPERATION_DELETE 0x00000004 +#define SGD_OPERATION_MODIFY 0x00000005 +#define SGD_OPERATION_CHG_PWD 0x00000006 +#define SGD_OPERATION_AUTHORIZATION 0x00000007 + +/* user operation results */ +#define SGD_OPERATION_SUCCESS 0x00000000 + +/* key types */ +#define SGD_MAIN_KEY 0x00000101 +#define SGD_DEVICE_KEYS 0x00000102 +#define SGD_USER_KEYS 0x00000103 +#define SGD_KEY 0x00000104 +#define SGD_SESSION_KEY 0x00000105 +#define SGD_PRIKEY_PASSWD 0x00000106 +#define SGD_COMPARTITION_KEY 0x00000107 + +/* key operations */ +#define SGD_KEY_GENERATION 0x00000101 +#define SGD_KEY_DISPENSE 0x00000102 +#define SGD_KEY_IMPORT 0x00000103 +#define SGD_KEY_EXPORT 0x00000104 +#define SGD_KEY_DIVISION 0x00000105 +#define SGD_KEY_COMPOSE 0x00000106 +#define SGD_KEY_RENEWAL 0x00000107 +#define SGD_KEY_BACKUP 0x00000108 +#define SGD_KEY_RESTORE 0x00000109 +#define SGD_KEY_DESTORY 0x0000010A + +/* system operations */ +#define SGD_SYSTEM_INIT 0x00000201 +#define SGD_SYSTEM_START 0x00000202 +#define SGD_SYSTEM_SHUT 0x00000203 +#define SGD_SYSTEM_RESTART 0x00000204 +#define SGD_SYSTEM_QUERY 0x00000205 +#define SGD_SYSTEM_BACKUP 0x00000206 +#define SGD_SYSTEM_RESTORE 0x00000207 + +/* device info */ +#define SGD_DEVICE_SORT 0x00000201 +#define SGD_DEVICE_TYPE 0x00000202 +#define SGD_DEVICE_NAME 0x00000203 +#define SGD_DEVICE_MANUFACTURER 0x00000204 +#define SGD_DEVICE_HARDWARE_VERSION 0x00000205 +#define SGD_DEVICE_SOFTWARE_VERSION 0x00000206 +#define SGD_DEVICE_STANDARD_VERSION 0x00000207 +#define SGD_DEVICE_SERIAL_NUMBER 0x00000208 +#define SGD_DEVICE_SUPPORT_SYMM_ALG 0x00000209 +#define SGD_DEVICE_SUPPORT_PKEY_ALG 0x0000020A +#define SGD_DEVICE_SUPPORT_HASH_ALG 0x0000020B +#define SGD_DEVICE_SUPPORT_STORAGE_SPACE 0x0000020C +#define SGD_DEVICE_SUPPORT_FREE_SPACE 0x0000020D +#define SGD_DEVICE_RUNTIME 0x0000020E +#define SGD_DEVICE_USED_TIMES 0x0000020F +#define SGD_DEVICE_LOCATION 0x00000210 +#define SGD_DEVICE_DESCRIPTION 0x00000211 +#define SGD_DEVICE_MANAGER_INFO 0x00000212 +#define SGD_DEVICE_MAX_DATA_SIZE 0x00000213 + +/* device types */ +#define SGD_DEVICE_SORT_SJ 0x02000000 /* Server */ +#define SGD_DEVICE_SORT_SK 0x03000000 /* PCI-E Card */ +#define SGD_DEVICE_SORT_SM 0x04000000 /* USB-Key and SmartCard */ + +/* device functionality */ +#define SGD_DEVICE_SORT_FE 0x00000100 /* encryption */ +#define SGD_DEVICE_SORT_FA 0x00000200 /* authentication */ +#define SGD_DEVICE_SORT_FM 0x00000300 /* key management */ + +/* device status */ +#define SGD_STATUS_INIT 0x00000201 +#define SGD_STATUS_READY 0x00000202 +#define SGD_STATUS_EXCEPTION 0x00000203 + +/* SKF */ +#ifndef WIN32 +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef long BOOL; +typedef UINT8 BYTE; +typedef UINT8 CHAR; +typedef INT16 SHORT; +typedef UINT16 USHORT; +# ifndef SGD_NATIVE_LONG +typedef INT32 LONG; +typedef UINT32 ULONG; +# else +typedef long LONG; +typedef unsigned long ULONG; +# endif +typedef UINT32 UINT; +typedef UINT16 WORD; +typedef UINT32 DWORD; +typedef UINT32 FLAGS; +typedef CHAR * LPSTR; +typedef void * HANDLE; +#else +#ifndef _WINDEF_H +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef long BOOL; +typedef UINT8 BYTE; +typedef UINT8 CHAR; +typedef INT16 SHORT; +typedef UINT16 USHORT; +# ifndef SGD_NATIVE_LONG +typedef INT32 LONG; +typedef UINT32 ULONG; +# else +typedef long LONG; +typedef unsigned long ULONG; +# endif +typedef UINT32 UINT; +typedef UINT16 WORD; +typedef UINT32 DWORD; +typedef UINT32 FLAGS; +typedef CHAR * LPSTR; +typedef void * HANDLE; +#endif +#endif + +typedef HANDLE DEVHANDLE; +typedef HANDLE HAPPLICATION; +typedef HANDLE HSESSION; +typedef HANDLE HCONTAINER; + +#ifndef FALSE +#define FALSE 0x00000000 +#endif + +#ifndef TRUE +#define TRUE 0x00000001 +#endif + +#ifdef WIN32 +#define DEVAPI __stdcall +#else +#define DEVAPI +#endif + +#ifndef ADMIN_TYPE +#define ADMIN_TYPE 0 +#endif + +#ifndef USER_TYPE +#define USER_TYPE 1 +#endif + +#define MAX_RSA_MODULUS_LEN 256 +#define MAX_RSA_EXPONENT_LEN 4 +#define ECC_MAX_XCOORDINATE_BITS_LEN 512 +#define ECC_MAX_YCOORDINATE_BITS_LEN 512 +#define ECC_MAX_MODULUS_BITS_LEN 512 + +#define MAX_IV_LEN 32 + +#define MAX_FILE_NAME_SIZE 32 +#define MAX_FILE_CONTAINER_NAME_SIZE 64 + +#define SECURE_NEVER_ACCOUNT 0x00000000 +#define SECURE_ADM_ACCOUNT 0x00000001 +#define SECURE_USER_ACCOUNT 0x00000010 +#define SECURE_ANYONE_ACCOUNT 0x000000FF + + +/* SDF */ + +#define RSAref_MAX_BITS 2048 +#define RSAref_MAX_LEN ((RSAref_MAX_BITS + 7) / 8) +#define RSAref_MAX_PBITS ((RSAref_MAX_BITS + 1) / 2) +#define RSAref_MAX_PLEN ((RSAref_MAX_PBITS + 7)/ 8) + +#ifdef SGD_MAX_ECC_BITS_256 +#define ECCref_MAX_BITS 256 +#else +#define ECCref_MAX_BITS 512 +#endif +#define ECCref_MAX_LEN ((ECCref_MAX_BITS+7) / 8) + + +/* SAF */ +#define SGD_MAX_COUNT 64 +#define SGD_MAX_NAME_SIZE 256 + + +#endif diff --git a/src/sha1.c b/src/sha1.c index 22fc4cc4..c64faad2 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,163 +7,164 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include - - -#define F0(B, C, D) (((B) & (C)) | ((~(B)) & (D))) -#define F1(B, C, D) ((B) ^ (C) ^ (D)) -#define F2(B, C, D) (((B) & (C)) | ((B) & (D)) | ((C) & (D))) -#define F3(B, C, D) ((B) ^ (C) ^ (D)) - -#define K0 0x5A827999 -#define K1 0x6ED9EBA1 -#define K2 0x8F1BBCDC -#define K3 0xCA62C1D6 - -static void sha1_compress_blocks(uint32_t state[5], - const unsigned char *data, size_t blocks) -{ - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - uint32_t E; - uint32_t T; - uint32_t W[80]; - int i; - - while (blocks--) { - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - - for (i = 0; i < 16; i++) { - W[i] = GETU32(data); - data += 4; - } - for (; i < 80; i++) { - W[i] = ROL32(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - } - - /* see https://en.wikipedia.org/wiki/SHA-1#/media/File:SHA-1.svg */ - for (i = 0; i < 20; i++) { - T = E + F0(B, C, D) + ROL32(A, 5) + W[i] + K0; - E = D; - D = C; - C = ROL32(B, 30); - B = A; - A = T; - } - for (; i < 40; i++) { - T = E + F1(B, C, D) + ROL32(A, 5) + W[i] + K1; - E = D; - D = C; - C = ROL32(B, 30); - B = A; - A = T; - } - for (; i < 60; i++) { - T = E + F2(B, C, D) + ROL32(A, 5) + W[i] + K2; - E = D; - D = C; - C = ROL32(B, 30); - B = A; - A = T; - } - for (; i < 80; i++) { - T = E + F3(B, C, D) + ROL32(A, 5) + W[i] + K3; - E = D; - D = C; - C = ROL32(B, 30); - B = A; - A = T; - } - - state[0] += A; - state[1] += B; - state[2] += C; - state[3] += D; - state[4] += E; - } -} - -void sha1_init(SHA1_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -void sha1_update(SHA1_CTX *ctx, const unsigned char *data, size_t datalen) -{ - size_t blocks; - - ctx->num &= 0x3f; - if (ctx->num) { - unsigned int left = SHA1_BLOCK_SIZE - ctx->num; - if (datalen < left) { - memcpy(ctx->block + ctx->num, data, datalen); - ctx->num += datalen; - return; - } else { - memcpy(ctx->block + ctx->num, data, left); - sha1_compress_blocks(ctx->state, ctx->block, 1); - ctx->nblocks++; - data += left; - datalen -= left; - } - } - - blocks = datalen / SHA1_BLOCK_SIZE; - sha1_compress_blocks(ctx->state, data, blocks); - ctx->nblocks += blocks; - data += SHA1_BLOCK_SIZE * blocks; - datalen -= SHA1_BLOCK_SIZE * blocks; - - ctx->num = datalen; - if (datalen) { - memcpy(ctx->block, data, datalen); - } -} - -void sha1_finish(SHA1_CTX *ctx, unsigned char *dgst) -{ - int i; - - ctx->num &= 0x3f; - ctx->block[ctx->num] = 0x80; - - if (ctx->num <= SHA1_BLOCK_SIZE - 9) { - memset(ctx->block + ctx->num + 1, 0, SHA1_BLOCK_SIZE - ctx->num - 9); - } else { - memset(ctx->block + ctx->num + 1, 0, SHA1_BLOCK_SIZE - ctx->num - 1); - sha1_compress_blocks(ctx->state, ctx->block, 1); - memset(ctx->block, 0, SHA1_BLOCK_SIZE - 8); - } - PUTU32(ctx->block + 56, ctx->nblocks >> 23); - PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); - - sha1_compress_blocks(ctx->state, ctx->block, 1); - for (i = 0; i < 5; i++) { - PUTU32(dgst + i*4, ctx->state[i]); - } - memset(ctx, 0, sizeof(*ctx)); -} - -void sha1_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA1_DIGEST_SIZE]) -{ - SHA1_CTX ctx; - sha1_init(&ctx); - sha1_update(&ctx, data, datalen); - memset(&ctx, 0, sizeof(ctx)); -} + + +#include +#include +#include + + +#define F0(B, C, D) (((B) & (C)) | ((~(B)) & (D))) +#define F1(B, C, D) ((B) ^ (C) ^ (D)) +#define F2(B, C, D) (((B) & (C)) | ((B) & (D)) | ((C) & (D))) +#define F3(B, C, D) ((B) ^ (C) ^ (D)) + +#define K0 0x5A827999 +#define K1 0x6ED9EBA1 +#define K2 0x8F1BBCDC +#define K3 0xCA62C1D6 + +static void sha1_compress_blocks(uint32_t state[5], + const unsigned char *data, size_t blocks) +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; + uint32_t T; + uint32_t W[80]; + int i; + + while (blocks--) { + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (i = 0; i < 16; i++) { + W[i] = GETU32(data); + data += 4; + } + for (; i < 80; i++) { + W[i] = ROL32(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* see https://en.wikipedia.org/wiki/SHA-1#/media/File:SHA-1.svg */ + for (i = 0; i < 20; i++) { + T = E + F0(B, C, D) + ROL32(A, 5) + W[i] + K0; + E = D; + D = C; + C = ROL32(B, 30); + B = A; + A = T; + } + for (; i < 40; i++) { + T = E + F1(B, C, D) + ROL32(A, 5) + W[i] + K1; + E = D; + D = C; + C = ROL32(B, 30); + B = A; + A = T; + } + for (; i < 60; i++) { + T = E + F2(B, C, D) + ROL32(A, 5) + W[i] + K2; + E = D; + D = C; + C = ROL32(B, 30); + B = A; + A = T; + } + for (; i < 80; i++) { + T = E + F3(B, C, D) + ROL32(A, 5) + W[i] + K3; + E = D; + D = C; + C = ROL32(B, 30); + B = A; + A = T; + } + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + } +} + +void sha1_init(SHA1_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void sha1_update(SHA1_CTX *ctx, const unsigned char *data, size_t datalen) +{ + size_t blocks; + + ctx->num &= 0x3f; + if (ctx->num) { + unsigned int left = SHA1_BLOCK_SIZE - ctx->num; + if (datalen < left) { + memcpy(ctx->block + ctx->num, data, datalen); + ctx->num += datalen; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + sha1_compress_blocks(ctx->state, ctx->block, 1); + ctx->nblocks++; + data += left; + datalen -= left; + } + } + + blocks = datalen / SHA1_BLOCK_SIZE; + sha1_compress_blocks(ctx->state, data, blocks); + ctx->nblocks += blocks; + data += SHA1_BLOCK_SIZE * blocks; + datalen -= SHA1_BLOCK_SIZE * blocks; + + ctx->num = datalen; + if (datalen) { + memcpy(ctx->block, data, datalen); + } +} + +void sha1_finish(SHA1_CTX *ctx, unsigned char *dgst) +{ + int i; + + ctx->num &= 0x3f; + ctx->block[ctx->num] = 0x80; + + if (ctx->num <= SHA1_BLOCK_SIZE - 9) { + memset(ctx->block + ctx->num + 1, 0, SHA1_BLOCK_SIZE - ctx->num - 9); + } else { + memset(ctx->block + ctx->num + 1, 0, SHA1_BLOCK_SIZE - ctx->num - 1); + sha1_compress_blocks(ctx->state, ctx->block, 1); + memset(ctx->block, 0, SHA1_BLOCK_SIZE - 8); + } + PUTU32(ctx->block + 56, ctx->nblocks >> 23); + PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); + + sha1_compress_blocks(ctx->state, ctx->block, 1); + for (i = 0; i < 5; i++) { + PUTU32(dgst + i*4, ctx->state[i]); + } + memset(ctx, 0, sizeof(*ctx)); +} + +void sha1_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[SHA1_DIGEST_SIZE]) +{ + SHA1_CTX ctx; + sha1_init(&ctx); + sha1_update(&ctx, data, datalen); + memset(&ctx, 0, sizeof(ctx)); +} diff --git a/src/sha256.c b/src/sha256.c index e7db8d2a..6d14b29c 100644 --- a/src/sha256.c +++ b/src/sha256.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,208 +7,209 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include - - -#define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z))) -#define Maj(X, Y, Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z))) -#define Sigma0(X) (ROR32((X), 2) ^ ROR32((X), 13) ^ ROR32((X), 22)) -#define Sigma1(X) (ROR32((X), 6) ^ ROR32((X), 11) ^ ROR32((X), 25)) -#define sigma0(X) (ROR32((X), 7) ^ ROR32((X), 18) ^ ((X) >> 3)) -#define sigma1(X) (ROR32((X), 17) ^ ROR32((X), 19) ^ ((X) >> 10)) - -static const uint32_t K[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, -}; - -static void sha256_compress_blocks(uint32_t state[8], - const unsigned char *data, size_t blocks) -{ - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - uint32_t E; - uint32_t F; - uint32_t G; - uint32_t H; - uint32_t W[64]; - uint32_t T1, T2; - int i; - - while (blocks--) { - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - F = state[5]; - G = state[6]; - H = state[7]; - - for (i = 0; i < 16; i++) { - W[i] = GETU32(data); - data += 4; - } - for (; i < 64; i++) { - W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16]; - } - - for (i = 0; i < 64; i++) { - T1 = H + Sigma1(E) + Ch(E, F, G) + K[i] + W[i]; - T2 = Sigma0(A) + Maj(A, B, C); - H = G; - G = F; - F = E; - E = D + T1; - D = C; - C = B; - B = A; - A = T1 + T2; - } - - state[0] += A; - state[1] += B; - state[2] += C; - state[3] += D; - state[4] += E; - state[5] += F; - state[6] += G; - state[7] += H; - } -} - - -void sha256_init(SHA256_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0x6a09e667; - ctx->state[1] = 0xbb67ae85; - ctx->state[2] = 0x3c6ef372; - ctx->state[3] = 0xa54ff53a; - ctx->state[4] = 0x510e527f; - ctx->state[5] = 0x9b05688c; - ctx->state[6] = 0x1f83d9ab; - ctx->state[7] = 0x5be0cd19; -} - -void sha256_update(SHA256_CTX *ctx, const unsigned char *data, size_t datalen) -{ - size_t blocks; - - ctx->num &= 0x3f; - if (ctx->num) { - unsigned int left = SHA256_BLOCK_SIZE - ctx->num; - if (datalen < left) { - memcpy(ctx->block + ctx->num, data, datalen); - ctx->num += datalen; - return; - } else { - memcpy(ctx->block + ctx->num, data, left); - sha256_compress_blocks(ctx->state, ctx->block, 1); - ctx->nblocks++; - data += left; - datalen -= left; - } - } - - blocks = datalen / SHA256_BLOCK_SIZE; - sha256_compress_blocks(ctx->state, data, blocks); - ctx->nblocks += blocks; - data += SHA256_BLOCK_SIZE * blocks; - datalen -= SHA256_BLOCK_SIZE * blocks; - - ctx->num = datalen; - if (datalen) { - memcpy(ctx->block, data, datalen); - } -} - -void sha256_finish(SHA256_CTX *ctx, unsigned char dgst[SHA256_DIGEST_SIZE]) -{ - int i; - - ctx->num &= 0x3f; - ctx->block[ctx->num] = 0x80; - - if (ctx->num <= SHA256_BLOCK_SIZE - 9) { - memset(ctx->block + ctx->num + 1, 0, SHA256_BLOCK_SIZE - ctx->num - 9); - } else { - memset(ctx->block + ctx->num + 1, 0, SHA256_BLOCK_SIZE - ctx->num - 1); - sha256_compress_blocks(ctx->state, ctx->block, 1); - memset(ctx->block, 0, SHA256_BLOCK_SIZE - 8); - } - PUTU32(ctx->block + 56, ctx->nblocks >> 23); - PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); - - sha256_compress_blocks(ctx->state, ctx->block, 1); - for (i = 0; i < 8; i++) { - PUTU32(dgst, ctx->state[i]); - dgst += sizeof(uint32_t); - } - memset(ctx, 0, sizeof(*ctx)); -} - -void sha256_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA256_DIGEST_SIZE]) -{ - SHA256_CTX ctx; - sha256_init(&ctx); - sha256_update(&ctx, data, datalen); - sha256_finish(&ctx, dgst); -} - - -void sha224_init(SHA224_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0xc1059ed8; - ctx->state[1] = 0x367cd507; - ctx->state[2] = 0x3070dd17; - ctx->state[3] = 0xf70e5939; - ctx->state[4] = 0xffc00b31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64f98fa7; - ctx->state[7] = 0xbefa4fa4; -} - -void sha224_update(SHA224_CTX *ctx, const unsigned char *data, size_t datalen) -{ - sha256_update((SHA256_CTX *)ctx, data, datalen); -} - -void sha224_finish(SHA224_CTX *ctx, unsigned char dgst[SHA224_DIGEST_SIZE]) -{ - uint8_t buf[SHA256_DIGEST_SIZE]; - sha256_finish((SHA256_CTX *)ctx, buf); - memcpy(dgst, buf, SHA224_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); -} - -void sha224_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA224_DIGEST_SIZE]) -{ - SHA224_CTX ctx; - sha224_init(&ctx); - sha224_update(&ctx, data, datalen); - sha224_finish(&ctx, dgst); -} + + +#include +#include +#include + + +#define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z))) +#define Maj(X, Y, Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z))) +#define Sigma0(X) (ROR32((X), 2) ^ ROR32((X), 13) ^ ROR32((X), 22)) +#define Sigma1(X) (ROR32((X), 6) ^ ROR32((X), 11) ^ ROR32((X), 25)) +#define sigma0(X) (ROR32((X), 7) ^ ROR32((X), 18) ^ ((X) >> 3)) +#define sigma1(X) (ROR32((X), 17) ^ ROR32((X), 19) ^ ((X) >> 10)) + +static const uint32_t K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; + +static void sha256_compress_blocks(uint32_t state[8], + const unsigned char *data, size_t blocks) +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; + uint32_t F; + uint32_t G; + uint32_t H; + uint32_t W[64]; + uint32_t T1, T2; + int i; + + while (blocks--) { + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + F = state[5]; + G = state[6]; + H = state[7]; + + for (i = 0; i < 16; i++) { + W[i] = GETU32(data); + data += 4; + } + for (; i < 64; i++) { + W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16]; + } + + for (i = 0; i < 64; i++) { + T1 = H + Sigma1(E) + Ch(E, F, G) + K[i] + W[i]; + T2 = Sigma0(A) + Maj(A, B, C); + H = G; + G = F; + F = E; + E = D + T1; + D = C; + C = B; + B = A; + A = T1 + T2; + } + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + state[5] += F; + state[6] += G; + state[7] += H; + } +} + + +void sha256_init(SHA256_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; +} + +void sha256_update(SHA256_CTX *ctx, const unsigned char *data, size_t datalen) +{ + size_t blocks; + + ctx->num &= 0x3f; + if (ctx->num) { + unsigned int left = SHA256_BLOCK_SIZE - ctx->num; + if (datalen < left) { + memcpy(ctx->block + ctx->num, data, datalen); + ctx->num += datalen; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + sha256_compress_blocks(ctx->state, ctx->block, 1); + ctx->nblocks++; + data += left; + datalen -= left; + } + } + + blocks = datalen / SHA256_BLOCK_SIZE; + sha256_compress_blocks(ctx->state, data, blocks); + ctx->nblocks += blocks; + data += SHA256_BLOCK_SIZE * blocks; + datalen -= SHA256_BLOCK_SIZE * blocks; + + ctx->num = datalen; + if (datalen) { + memcpy(ctx->block, data, datalen); + } +} + +void sha256_finish(SHA256_CTX *ctx, unsigned char dgst[SHA256_DIGEST_SIZE]) +{ + int i; + + ctx->num &= 0x3f; + ctx->block[ctx->num] = 0x80; + + if (ctx->num <= SHA256_BLOCK_SIZE - 9) { + memset(ctx->block + ctx->num + 1, 0, SHA256_BLOCK_SIZE - ctx->num - 9); + } else { + memset(ctx->block + ctx->num + 1, 0, SHA256_BLOCK_SIZE - ctx->num - 1); + sha256_compress_blocks(ctx->state, ctx->block, 1); + memset(ctx->block, 0, SHA256_BLOCK_SIZE - 8); + } + PUTU32(ctx->block + 56, ctx->nblocks >> 23); + PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); + + sha256_compress_blocks(ctx->state, ctx->block, 1); + for (i = 0; i < 8; i++) { + PUTU32(dgst, ctx->state[i]); + dgst += sizeof(uint32_t); + } + memset(ctx, 0, sizeof(*ctx)); +} + +void sha256_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[SHA256_DIGEST_SIZE]) +{ + SHA256_CTX ctx; + sha256_init(&ctx); + sha256_update(&ctx, data, datalen); + sha256_finish(&ctx, dgst); +} + + +void sha224_init(SHA224_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0xc1059ed8; + ctx->state[1] = 0x367cd507; + ctx->state[2] = 0x3070dd17; + ctx->state[3] = 0xf70e5939; + ctx->state[4] = 0xffc00b31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64f98fa7; + ctx->state[7] = 0xbefa4fa4; +} + +void sha224_update(SHA224_CTX *ctx, const unsigned char *data, size_t datalen) +{ + sha256_update((SHA256_CTX *)ctx, data, datalen); +} + +void sha224_finish(SHA224_CTX *ctx, unsigned char dgst[SHA224_DIGEST_SIZE]) +{ + uint8_t buf[SHA256_DIGEST_SIZE]; + sha256_finish((SHA256_CTX *)ctx, buf); + memcpy(dgst, buf, SHA224_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); +} + +void sha224_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[SHA224_DIGEST_SIZE]) +{ + SHA224_CTX ctx; + sha224_init(&ctx); + sha224_update(&ctx, data, datalen); + sha224_finish(&ctx, dgst); +} diff --git a/src/sha512.c b/src/sha512.c index 26e08151..385d836f 100644 --- a/src/sha512.c +++ b/src/sha512.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,225 +7,226 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -static void sha512_compress_blocks(uint64_t state[8], - const unsigned char *data, size_t blocks); - -void sha512_init(SHA512_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0x6a09e667f3bcc908; - ctx->state[1] = 0xbb67ae8584caa73b; - ctx->state[2] = 0x3c6ef372fe94f82b; - ctx->state[3] = 0xa54ff53a5f1d36f1; - ctx->state[4] = 0x510e527fade682d1; - ctx->state[5] = 0x9b05688c2b3e6c1f; - ctx->state[6] = 0x1f83d9abfb41bd6b; - ctx->state[7] = 0x5be0cd19137e2179; -} - -void sha512_update(SHA512_CTX *ctx, const unsigned char *data, size_t datalen) -{ - size_t blocks; - - if (ctx->num) { - unsigned int left = SHA512_BLOCK_SIZE - ctx->num; - if (datalen < left) { - memcpy(ctx->block + ctx->num, data, datalen); - ctx->num += datalen; - return; - } else { - memcpy(ctx->block + ctx->num, data, left); - sha512_compress_blocks(ctx->state, ctx->block, 1); - ctx->nblocks++; - data += left; - datalen -= left; - } - } - - blocks = datalen / SHA512_BLOCK_SIZE; - sha512_compress_blocks(ctx->state, data, blocks); - ctx->nblocks += blocks; - data += SHA512_BLOCK_SIZE * blocks; - datalen -= SHA512_BLOCK_SIZE * blocks; - - ctx->num = datalen; - if (datalen) { - memcpy(ctx->block, data, datalen); - } -} - -void sha512_finish(SHA512_CTX *ctx, unsigned char dgst[SHA512_DIGEST_SIZE]) -{ - int i; - - ctx->block[ctx->num] = 0x80; - - if (ctx->num + 17 <= SHA512_BLOCK_SIZE) { - memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 17); - } else { - memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 1); - sha512_compress_blocks(ctx->state, ctx->block, 1); - memset(ctx->block, 0, SHA512_BLOCK_SIZE - 16); - } - PUTU64(ctx->block + 112, ctx->nblocks >> 54); - PUTU64(ctx->block + 120, (ctx->nblocks << 10) + (ctx->num << 3)); - - sha512_compress_blocks(ctx->state, ctx->block, 1); - for (i = 0; i < 8; i++) { - PUTU64(dgst, ctx->state[i]); - dgst += sizeof(uint64_t); - } - memset(ctx, 0, sizeof(SHA512_CTX)); -} - -#define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z))) -#define Maj(X, Y, Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z))) -#define Sigma0(X) (ROR64((X), 28) ^ ROR64((X), 34) ^ ROR64((X), 39)) -#define Sigma1(X) (ROR64((X), 14) ^ ROR64((X), 18) ^ ROR64((X), 41)) -#define sigma0(X) (ROR64((X), 1) ^ ROR64((X), 8) ^ ((X) >> 7)) -#define sigma1(X) (ROR64((X), 19) ^ ROR64((X), 61) ^ ((X) >> 6)) - -static const uint64_t K[80] = { - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, - 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, - 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, - 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, - 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, - 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, - 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, - 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, - 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, - 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, - 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, - 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, - 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, - 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, - 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, - 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, - 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, -}; - -static void sha512_compress_blocks(uint64_t state[8], - const unsigned char *data, size_t blocks) -{ - uint64_t A; - uint64_t B; - uint64_t C; - uint64_t D; - uint64_t E; - uint64_t F; - uint64_t G; - uint64_t H; - uint64_t W[80]; - uint64_t T1, T2; - int i; - - while (blocks--) { - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - F = state[5]; - G = state[6]; - H = state[7]; - - for (i = 0; i < 16; i++) { - W[i] = GETU64(data); - data += sizeof(uint64_t); - } - for (; i < 80; i++) { - W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16]; - } - - for (i = 0; i < 80; i++) { - T1 = H + Sigma1(E) + Ch(E, F, G) + K[i] + W[i]; - T2 = Sigma0(A) + Maj(A, B, C); - H = G; - G = F; - F = E; - E = D + T1; - D = C; - C = B; - B = A; - A = T1 + T2; - } - - state[0] += A; - state[1] += B; - state[2] += C; - state[3] += D; - state[4] += E; - state[5] += F; - state[6] += G; - state[7] += H; - } -} - -void sha512_compress(uint64_t state[8], const unsigned char block[64]) -{ - sha512_compress_blocks(state, block, 1); -} - -void sha512_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA512_DIGEST_SIZE]) -{ - SHA512_CTX ctx; - sha512_init(&ctx); - sha512_update(&ctx, data, datalen); - sha512_finish(&ctx, dgst); -} - - -void sha384_init(SHA384_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->state[0] = 0xcbbb9d5dc1059ed8; - ctx->state[1] = 0x629a292a367cd507; - ctx->state[2] = 0x9159015a3070dd17; - ctx->state[3] = 0x152fecd8f70e5939; - ctx->state[4] = 0x67332667ffc00b31; - ctx->state[5] = 0x8eb44a8768581511; - ctx->state[6] = 0xdb0c2e0d64f98fa7; - ctx->state[7] = 0x47b5481dbefa4fa4; -} - -void sha384_update(SHA384_CTX *ctx, const unsigned char *data, size_t datalen) -{ - sha512_update((SHA512_CTX *)ctx, data, datalen); -} - -void sha384_finish(SHA384_CTX *ctx, unsigned char dgst[SHA384_DIGEST_SIZE]) -{ - unsigned char buf[SHA512_DIGEST_SIZE]; - sha512_finish((SHA512_CTX *)ctx, buf); - memcpy(dgst, buf, SHA384_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); -} - -void sha384_compress(uint64_t state[8], const unsigned char block[64]) -{ - sha512_compress_blocks(state, block, 1); -} - -void sha384_digest(const unsigned char *data, size_t datalen, - unsigned char dgst[SHA384_DIGEST_SIZE]) -{ - SHA384_CTX ctx; - sha384_init(&ctx); - sha384_update(&ctx, data, datalen); - sha384_finish(&ctx, dgst); -} - + + +#include +#include +#include +#include +#include + + +static void sha512_compress_blocks(uint64_t state[8], + const unsigned char *data, size_t blocks); + +void sha512_init(SHA512_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x6a09e667f3bcc908; + ctx->state[1] = 0xbb67ae8584caa73b; + ctx->state[2] = 0x3c6ef372fe94f82b; + ctx->state[3] = 0xa54ff53a5f1d36f1; + ctx->state[4] = 0x510e527fade682d1; + ctx->state[5] = 0x9b05688c2b3e6c1f; + ctx->state[6] = 0x1f83d9abfb41bd6b; + ctx->state[7] = 0x5be0cd19137e2179; +} + +void sha512_update(SHA512_CTX *ctx, const unsigned char *data, size_t datalen) +{ + size_t blocks; + + if (ctx->num) { + unsigned int left = SHA512_BLOCK_SIZE - ctx->num; + if (datalen < left) { + memcpy(ctx->block + ctx->num, data, datalen); + ctx->num += datalen; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + sha512_compress_blocks(ctx->state, ctx->block, 1); + ctx->nblocks++; + data += left; + datalen -= left; + } + } + + blocks = datalen / SHA512_BLOCK_SIZE; + sha512_compress_blocks(ctx->state, data, blocks); + ctx->nblocks += blocks; + data += SHA512_BLOCK_SIZE * blocks; + datalen -= SHA512_BLOCK_SIZE * blocks; + + ctx->num = datalen; + if (datalen) { + memcpy(ctx->block, data, datalen); + } +} + +void sha512_finish(SHA512_CTX *ctx, unsigned char dgst[SHA512_DIGEST_SIZE]) +{ + int i; + + ctx->block[ctx->num] = 0x80; + + if (ctx->num + 17 <= SHA512_BLOCK_SIZE) { + memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 17); + } else { + memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 1); + sha512_compress_blocks(ctx->state, ctx->block, 1); + memset(ctx->block, 0, SHA512_BLOCK_SIZE - 16); + } + PUTU64(ctx->block + 112, ctx->nblocks >> 54); + PUTU64(ctx->block + 120, (ctx->nblocks << 10) + (ctx->num << 3)); + + sha512_compress_blocks(ctx->state, ctx->block, 1); + for (i = 0; i < 8; i++) { + PUTU64(dgst, ctx->state[i]); + dgst += sizeof(uint64_t); + } + memset(ctx, 0, sizeof(SHA512_CTX)); +} + +#define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z))) +#define Maj(X, Y, Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z))) +#define Sigma0(X) (ROR64((X), 28) ^ ROR64((X), 34) ^ ROR64((X), 39)) +#define Sigma1(X) (ROR64((X), 14) ^ ROR64((X), 18) ^ ROR64((X), 41)) +#define sigma0(X) (ROR64((X), 1) ^ ROR64((X), 8) ^ ((X) >> 7)) +#define sigma1(X) (ROR64((X), 19) ^ ROR64((X), 61) ^ ((X) >> 6)) + +static const uint64_t K[80] = { + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, + 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, + 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, + 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, +}; + +static void sha512_compress_blocks(uint64_t state[8], + const unsigned char *data, size_t blocks) +{ + uint64_t A; + uint64_t B; + uint64_t C; + uint64_t D; + uint64_t E; + uint64_t F; + uint64_t G; + uint64_t H; + uint64_t W[80]; + uint64_t T1, T2; + int i; + + while (blocks--) { + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + F = state[5]; + G = state[6]; + H = state[7]; + + for (i = 0; i < 16; i++) { + W[i] = GETU64(data); + data += sizeof(uint64_t); + } + for (; i < 80; i++) { + W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16]; + } + + for (i = 0; i < 80; i++) { + T1 = H + Sigma1(E) + Ch(E, F, G) + K[i] + W[i]; + T2 = Sigma0(A) + Maj(A, B, C); + H = G; + G = F; + F = E; + E = D + T1; + D = C; + C = B; + B = A; + A = T1 + T2; + } + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + state[5] += F; + state[6] += G; + state[7] += H; + } +} + +void sha512_compress(uint64_t state[8], const unsigned char block[64]) +{ + sha512_compress_blocks(state, block, 1); +} + +void sha512_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[SHA512_DIGEST_SIZE]) +{ + SHA512_CTX ctx; + sha512_init(&ctx); + sha512_update(&ctx, data, datalen); + sha512_finish(&ctx, dgst); +} + + +void sha384_init(SHA384_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0xcbbb9d5dc1059ed8; + ctx->state[1] = 0x629a292a367cd507; + ctx->state[2] = 0x9159015a3070dd17; + ctx->state[3] = 0x152fecd8f70e5939; + ctx->state[4] = 0x67332667ffc00b31; + ctx->state[5] = 0x8eb44a8768581511; + ctx->state[6] = 0xdb0c2e0d64f98fa7; + ctx->state[7] = 0x47b5481dbefa4fa4; +} + +void sha384_update(SHA384_CTX *ctx, const unsigned char *data, size_t datalen) +{ + sha512_update((SHA512_CTX *)ctx, data, datalen); +} + +void sha384_finish(SHA384_CTX *ctx, unsigned char dgst[SHA384_DIGEST_SIZE]) +{ + unsigned char buf[SHA512_DIGEST_SIZE]; + sha512_finish((SHA512_CTX *)ctx, buf); + memcpy(dgst, buf, SHA384_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); +} + +void sha384_compress(uint64_t state[8], const unsigned char block[64]) +{ + sha512_compress_blocks(state, block, 1); +} + +void sha384_digest(const unsigned char *data, size_t datalen, + unsigned char dgst[SHA384_DIGEST_SIZE]) +{ + SHA384_CTX ctx; + sha384_init(&ctx); + sha384_update(&ctx, data, datalen); + sha384_finish(&ctx, dgst); +} + diff --git a/src/skf/skf.c b/src/skf/skf.c index dd6bee30..8a76e75f 100644 --- a/src/skf/skf.c +++ b/src/skf/skf.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,776 +7,777 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include "../sgd.h" -#include "skf.h" -#include "skf_ext.h" -#include "skf_int.h" - - -int skf_load_library(const char *so_path, const char *vendor) -{ - if (SKF_LoadLibrary((LPSTR)so_path, (LPSTR)vendor) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -void skf_unload_library(void) -{ - SKF_UnloadLibrary(); -} - - -static int skf_open_app(SKF_DEVICE *dev, const char *appname, const char *pin, HAPPLICATION *phApp) -{ - int ret = 0; - HAPPLICATION hApp = NULL; - ULONG ulPINType = USER_TYPE; - ULONG numRetry; - - if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK) { - error_print(); - return -1; - } - if (SKF_VerifyPIN(hApp, ulPINType, (CHAR *)pin, &numRetry) != SAR_OK) { - fprintf(stderr, "Invalid user PIN, retry count = %u\n", numRetry); - error_print(); - goto end; - } - *phApp = hApp; - hApp = NULL; - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -static const uint8_t zeros[ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32] = {0}; - -static int SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB *blob, SM2_KEY *sm2_key) -{ - SM2_POINT point; - - if (blob->BitLen != 256) { - error_print(); - return -1; - } - if (memcmp(blob->XCoordinate, zeros, sizeof(zeros)) != 0 - || memcmp(blob->YCoordinate, zeros, sizeof(zeros)) != 0) { - error_print(); - return -1; - } - if (sm2_point_from_xy(&point, - blob->XCoordinate + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, - blob->YCoordinate + ECC_MAX_YCOORDINATE_BITS_LEN/8 - 32) != 1 - || sm2_key_set_public_key(sm2_key, &point) != 1) { - error_print(); - return -1; - } - return SAR_OK; -} - -static int SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB *blob, SM2_SIGNATURE *sig) -{ - if (memcmp(blob->r, zeros, sizeof(zeros)) != 0 - || memcmp(blob->s, zeros, sizeof(zeros)) != 0) { - error_print(); - return -1; - } - memset(sig, 0, sizeof(SM2_SIGNATURE)); - memcpy(sig->r, blob->r + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); - memcpy(sig->s, blob->s + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); - return SAR_OK; -} - -int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len) -{ - if (SKF_GenRandom(dev->handle, buf, (ULONG)len) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - HCONTAINER hContainer = NULL; - ULONG containerType = 0; - BOOL bSign = SGD_TRUE; - ECCPUBLICKEYBLOB publicKeyBlob; - ULONG ulBlobLen = sizeof(ECCPUBLICKEYBLOB); - SM2_KEY public_key; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_OpenContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK - || SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { - error_print(); - goto end; - } - if (containerType != SKF_CONTAINER_TYPE_ECC) { - error_print(); - goto end; - } - if (SKF_ExportPublicKey(hContainer, bSign, (BYTE *)&publicKeyBlob, &ulBlobLen) != SAR_OK) { - error_print(); - goto end; - } - if (ulBlobLen != sizeof(ECCPUBLICKEYBLOB)) { - error_print(); - goto end; - } - if (SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(&publicKeyBlob, &public_key) != SAR_OK) { - error_print(); - goto end; - } - memset(key, 0, sizeof(SKF_KEY)); - key->public_key = public_key; - key->app_handle = hApp; - hApp = NULL; - strncpy(key->app_name, appname, 64); - key->container_handle = hContainer; - hContainer = NULL; - strncpy(key->container_name, container_name, 64); - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - if (hContainer) SKF_CloseContainer(hContainer); - return ret; -} - -int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) -{ - ECCSIGNATUREBLOB sigBlob; - SM2_SIGNATURE sm2_sig; - - if (SKF_ECCSignData(key->container_handle, (BYTE *)dgst, 32, &sigBlob) != SAR_OK) { - error_print(); - return -1; - } - if (SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(&sigBlob, &sm2_sig) != SAR_OK) { - error_print(); - return -1; - } - *siglen = 0; - if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int skf_release_key(SKF_KEY *key) -{ - if (key->app_handle) { - if (SKF_ClearSecureState(key->app_handle) != SAR_OK - || SKF_CloseApplication(key->app_handle) != SAR_OK) { - error_print(); - return -1; - } - key->app_handle = NULL; - } - if (key->container_handle) { - if (SKF_CloseContainer(key->container_handle) != SAR_OK) { - error_print(); - return -1; - } - } - memset(key, 0, sizeof(SKF_KEY)); - return 1; -} - -int skf_close_device(SKF_DEVICE *dev) -{ - if (SKF_UnlockDev(dev->handle) != SAR_OK - || SKF_DisConnectDev(dev->handle) != SAR_OK) { - error_print(); - return -1; - } - memset(dev, 0, sizeof(SKF_DEVICE)); - return 1; -} - - - - - - - -int skf_list_devices(FILE *fp, int fmt, int ind, const char *label) -{ - int ret = -1; - BOOL bPresent = TRUE; - char *nameList = NULL; - ULONG nameListLen = 0; - const char *name; - int i; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (SKF_EnumDev(bPresent, NULL, &nameListLen) != SAR_OK) { - error_print(); - return -1; - } - if (nameListLen == 0) { - return 0; - } - if (!(nameList = malloc(nameListLen))) { - error_print(); - return -1; - } - if (SKF_EnumDev(bPresent, (LPSTR)nameList, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { - (void)format_print(fp, fmt, ind, "%s\n", name); - } - ret = 1; -end: - free(nameList); - return ret; -} - -int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname) -{ - int ret = 0; - DEVHANDLE hDev = NULL; - ULONG devState = 0; - LPSTR devStateName = NULL; - DEVINFO devInfo = {{0,0}}; - - format_print(fp, fmt, ind, "%s\n", devname); - ind += 4; - - if (SKF_GetDevState((LPSTR)devname, &devState) != SAR_OK - || SKF_GetDevStateName(devState, &devStateName) != SAR_OK - || SKF_ConnectDev((LPSTR)devname, &hDev) != SAR_OK - || SKF_GetDevInfo(hDev, &devInfo) != SAR_OK) { - error_print(); - goto end; - } - - (void)format_print(fp, fmt, ind, "DeviceState: %s\n", (char *)devStateName); - //(void)SKF_PrintDevInfo(fp, fmt, ind, "DeviceInfo", &devInfo); - ret = 1; -end: - if (hDev) SKF_DisConnectDev(hDev); - return ret; -} - -int skf_set_label(SKF_DEVICE *dev, const char *label) -{ - if (SKF_SetLabel(dev->handle, (LPSTR)label) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]) -{ - DEVHANDLE hDev = NULL; - DEVINFO devInfo = {{0,0}}; - ULONG ulTimeOut = 0xffffffff; - BYTE authRand[16] = {0}; - BYTE authData[16] = {0}; - ULONG authRandLen = SKF_AUTHRAND_LENGTH; - ULONG authDataLen = sizeof(authData); - BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; - - if (SKF_OpenDevice((LPSTR)devname, (BYTE *)authkey, &devInfo, &hDev) != SAR_OK - || SKF_LockDev(hDev, ulTimeOut) != SAR_OK) { - error_print(); - return -1; - } - memset(dev, 0, sizeof(SKF_DEVICE)); - dev->handle = hDev; - hDev = NULL; - - return 1; -} - -int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]) -{ - if (SKF_ChangeDevAuthKey(dev->handle, (BYTE *)authkey, 16) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp) -{ - int ret = 0; - HAPPLICATION hApp = NULL; - char *nameList = NULL; - ULONG nameListLen = 0; - const char *name; - int i; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (SKF_EnumApplication(dev->handle, NULL, &nameListLen) != SAR_OK) { - error_print(); - return -1; - } - if (nameListLen <= 1) { - return 0; - } - if (!(nameList = malloc(nameListLen))) { - error_print(); - return -1; - } - if (SKF_EnumApplication(dev->handle, (LPSTR)nameList, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { - ULONG adminMaxRetry; - ULONG adminMinRetry; - ULONG userMaxRetry; - ULONG userMinRetry; - BOOL adminDefaultPin; - BOOL userDefaultPin; - - if (SKF_OpenApplication(dev->handle, (LPSTR)name, &hApp) != SAR_OK - || SKF_GetPINInfo(hApp, ADMIN_TYPE, &adminMaxRetry, &adminMinRetry, &adminDefaultPin) != SAR_OK - || SKF_GetPINInfo(hApp, USER_TYPE, &userMaxRetry, &userMinRetry, &userDefaultPin) != SAR_OK - || SKF_CloseApplication(hApp) != SAR_OK) { - error_print(); - goto end; - } - hApp = NULL; - - (void)format_print(fp, fmt, ind, "Application %d:\n", i); - (void)format_print(fp, fmt, ind + 4, "ApplicationName", name); - (void)format_print(fp, fmt, ind + 4, "AdminPinMaxRetry: %s\n", adminMaxRetry); - (void)format_print(fp, fmt, ind + 4, "AdminPinMinRetry: %u\n", adminMinRetry); - (void)format_print(fp, fmt, ind + 4, "AdminDefaultPin: %s\n", adminDefaultPin ? "True" : "False"); - (void)format_print(fp, fmt, ind + 4, "UserPinMaxRetry: %u\n", userMaxRetry); - (void)format_print(fp, fmt, ind + 4, "UserPinMinRetry: %u\n", userMinRetry); - (void)format_print(fp, fmt, ind + 4, "UserDefaultPin: %s\n", userDefaultPin ? "True" : "False"); - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin) -{ - int ret = 0; - HAPPLICATION hApp = NULL; - ULONG appRights = SECURE_ANYONE_ACCOUNT; - - if (SKF_CreateApplication(dev->handle, (LPSTR)appname, - (CHAR *)admin_pin, SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT, - (CHAR *)user_pin, SKF_DEFAULT_USER_PIN_RETRY_COUNT, - appRights, &hApp) != SAR_OK) { - error_print(); - return -1; - } - if (SKF_CloseApplication(hApp) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -int skf_delete_app(SKF_DEVICE *dev, const char *appname) -{ - if (SKF_DeleteApplication(dev->handle, (LPSTR)appname) != SAR_OK) { - error_print(); - return -1; - } - return 1; -} - -int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - ULONG ulPINType = ADMIN_TYPE; - ULONG ulRetryCount = 0; - - if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK - || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { - fprintf(stderr, "Retry Count = %u\n", ulRetryCount); - error_print(); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - ULONG ulPINType = USER_TYPE; - ULONG ulRetryCount = 0; - - if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK - || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { - fprintf(stderr, "Retry Count = %u\n", ulRetryCount); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - ULONG ulRetryCount = 0; - - if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK - || SKF_UnblockPIN(hApp, (CHAR *)admin_pin, (CHAR *)new_user_pin, &ulRetryCount) != SAR_OK) { - fprintf(stderr, "Invalid admin PIN, retry count = %u\n", ulRetryCount); - error_print(); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, - SKF_DEVICE *dev, const char *appname, const char *pin) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - char *nameList = NULL; - ULONG nameListLen = 0; - const char *name; - int i; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_EnumFiles(hApp, NULL, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - if (nameListLen <= 1) { - ret = 0; - goto end; - } - if (!(nameList = malloc(nameListLen))) { - error_print(); - goto end; - } - if (SKF_EnumFiles(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { - FILEATTRIBUTE fileInfo; - - if (SKF_GetFileInfo(hApp, (LPSTR)name, &fileInfo) != SAR_OK) { - error_print(); - goto end; - } - format_print(fp, fmt, ind, "Object:\n"); - format_print(fp, fmt, ind + 4, "Name: %s\n", (char *)&(fileInfo.FileName)); - format_print(fp, fmt, ind + 4, "Size: %u\n", fileInfo.FileSize); - format_print(fp, fmt, ind + 4, "ReadRights: %08X\n", fileInfo.ReadRights); - format_print(fp, fmt, ind + 4, "WriteRights: %08X\n", fileInfo.WriteRights); - } - - ret = 1; - -end: - if (hApp) SKF_CloseApplication(hApp); - if (nameList) free(nameList); - return ret; -} - -int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, - const char *objname, const uint8_t *data, size_t datalen) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - ULONG ulReadRights = SECURE_ANYONE_ACCOUNT; - ULONG ulWriteRights = SECURE_USER_ACCOUNT; - - if (!dev || !appname || !pin || !objname || !data || !datalen) { - error_print(); - return -1; - } - if (datalen > SKF_MAX_FILE_SIZE) { - error_print(); - return -1; - } - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_CreateFile(hApp, (LPSTR)objname, datalen, ulReadRights, ulWriteRights) != SAR_OK - || SKF_WriteFile(hApp, (LPSTR)objname, 0, (BYTE *)data, datalen) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, - const char *objname, uint8_t *out, size_t *outlen) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - FILEATTRIBUTE fileInfo; - ULONG ulen; - int len; - - if (!dev || !appname || !pin || !objname || !outlen) { - error_print(); - return -1; - } - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_GetFileInfo(hApp, (LPSTR)objname, &fileInfo) != SAR_OK) { - error_print(); - goto end; - } - if (fileInfo.FileSize > SKF_MAX_FILE_SIZE) { - error_print(); - goto end; - } - if (!out) { - *outlen = (size_t)fileInfo.FileSize; - ret = 1; - goto end; - } - ulen = fileInfo.FileSize; - if (SKF_ReadFile(hApp, (LPSTR)objname, 0, fileInfo.FileSize, out, &ulen) != SAR_OK) { - goto end; - } - if (ulen != fileInfo.FileSize) { - error_print(); - goto end; - } - *outlen = ulen; - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_DeleteFile(hApp, (LPSTR)objname) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, - SKF_DEVICE *dev, const char *appname, const char *pin) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - HCONTAINER hContainer = NULL; - char *nameList = NULL; - ULONG nameListLen = 0; - const char *name; - int i; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_EnumContainer(hApp, NULL, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - if (nameListLen <= 1) { - ret = 0; - goto end; - } - if (!(nameList = malloc(nameListLen))) { - error_print(); - goto end; - } - if (SKF_EnumContainer(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { - error_print(); - goto end; - } - for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { - ULONG containerType; - LPSTR containerTypeName; - - if (SKF_OpenContainer(hApp, (LPSTR)name, &hContainer) != SAR_OK - || SKF_GetContainerType(hContainer, &containerType) != SAR_OK - || SKF_GetContainerTypeName(containerType, &containerTypeName) != SAR_OK - || SKF_CloseContainer(hContainer) != SAR_OK) { - error_print(); - goto end; - } - hContainer = NULL; - (void)format_print(fp, fmt, ind, "Container:\n"); - (void)format_print(fp, fmt, ind + 4, "Name: %s\n", name); - (void)format_print(fp, fmt, ind + 4, "Type: %s\n", (char *)containerTypeName); - } - ret = 1; - -end: - if (hContainer) SKF_CloseContainer(hContainer); - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - HCONTAINER hContainer = NULL; - ECCPUBLICKEYBLOB publicKey = {0, {0}, {0}}; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_CreateContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK - || SKF_GenECCKeyPair(hContainer, SGD_SM2_1, &publicKey) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hContainer) SKF_CloseContainer(hContainer); - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_DeleteContainer(hApp, (LPSTR)container_name) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hApp) SKF_CloseApplication(hApp); - return 1; -} - -int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, - const char *container_name, const uint8_t *cert, size_t certlen) -{ - int ret = 0; - HAPPLICATION hApp = NULL; - HCONTAINER hContainer = NULL; - ULONG containerType; - BOOL bSign = SGD_TRUE; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { - error_print(); - goto end; - } - if (containerType == SKF_CONTAINER_TYPE_UNDEF) { - error_print(); - goto end; - } - if (containerType != SKF_CONTAINER_TYPE_ECC) { - error_print(); - goto end; - } - // FIXME: 判断导入证书的类型是否为签名证书 - if (SKF_ImportCertificate(hContainer, bSign, (BYTE *)cert, (ULONG)certlen) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hContainer) SKF_CloseContainer(hContainer); - if (hApp) SKF_CloseApplication(hApp); - return ret; -} - -int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, - const char *container_name, uint8_t *cert, size_t *certlen) -{ - int ret = -1; - HAPPLICATION hApp = NULL; - HCONTAINER hContainer = NULL; - ULONG containerType; - BOOL bSign = SGD_TRUE; - ULONG ulCertLen = 0; - - if (skf_open_app(dev, appname, pin, &hApp) != 1) { - error_print(); - return -1; - } - if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { - error_print(); - goto end; - } - if (containerType != SKF_CONTAINER_TYPE_ECC) { - error_print(); - goto end; - } - if (SKF_ExportCertificate(hContainer, bSign, (BYTE *)cert, &ulCertLen) != SAR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hContainer) SKF_CloseContainer(hContainer); - if (hApp) SKF_CloseApplication(hApp); - return ret; -} + + +#include +#include +#include +#include +#include +#include "../sgd.h" +#include "skf.h" +#include "skf_ext.h" +#include "skf_int.h" + + +int skf_load_library(const char *so_path, const char *vendor) +{ + if (SKF_LoadLibrary((LPSTR)so_path, (LPSTR)vendor) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +void skf_unload_library(void) +{ + SKF_UnloadLibrary(); +} + + +static int skf_open_app(SKF_DEVICE *dev, const char *appname, const char *pin, HAPPLICATION *phApp) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + ULONG ulPINType = USER_TYPE; + ULONG numRetry; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_VerifyPIN(hApp, ulPINType, (CHAR *)pin, &numRetry) != SAR_OK) { + fprintf(stderr, "Invalid user PIN, retry count = %u\n", numRetry); + error_print(); + goto end; + } + *phApp = hApp; + hApp = NULL; + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +static const uint8_t zeros[ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32] = {0}; + +static int SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB *blob, SM2_KEY *sm2_key) +{ + SM2_POINT point; + + if (blob->BitLen != 256) { + error_print(); + return -1; + } + if (memcmp(blob->XCoordinate, zeros, sizeof(zeros)) != 0 + || memcmp(blob->YCoordinate, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + if (sm2_point_from_xy(&point, + blob->XCoordinate + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, + blob->YCoordinate + ECC_MAX_YCOORDINATE_BITS_LEN/8 - 32) != 1 + || sm2_key_set_public_key(sm2_key, &point) != 1) { + error_print(); + return -1; + } + return SAR_OK; +} + +static int SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB *blob, SM2_SIGNATURE *sig) +{ + if (memcmp(blob->r, zeros, sizeof(zeros)) != 0 + || memcmp(blob->s, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + memset(sig, 0, sizeof(SM2_SIGNATURE)); + memcpy(sig->r, blob->r + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); + memcpy(sig->s, blob->s + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); + return SAR_OK; +} + +int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len) +{ + if (SKF_GenRandom(dev->handle, buf, (ULONG)len) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType = 0; + BOOL bSign = SGD_TRUE; + ECCPUBLICKEYBLOB publicKeyBlob; + ULONG ulBlobLen = sizeof(ECCPUBLICKEYBLOB); + SM2_KEY public_key; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_OpenContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK + || SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + if (SKF_ExportPublicKey(hContainer, bSign, (BYTE *)&publicKeyBlob, &ulBlobLen) != SAR_OK) { + error_print(); + goto end; + } + if (ulBlobLen != sizeof(ECCPUBLICKEYBLOB)) { + error_print(); + goto end; + } + if (SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(&publicKeyBlob, &public_key) != SAR_OK) { + error_print(); + goto end; + } + memset(key, 0, sizeof(SKF_KEY)); + key->public_key = public_key; + key->app_handle = hApp; + hApp = NULL; + strncpy(key->app_name, appname, 64); + key->container_handle = hContainer; + hContainer = NULL; + strncpy(key->container_name, container_name, 64); + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + if (hContainer) SKF_CloseContainer(hContainer); + return ret; +} + +int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) +{ + ECCSIGNATUREBLOB sigBlob; + SM2_SIGNATURE sm2_sig; + + if (SKF_ECCSignData(key->container_handle, (BYTE *)dgst, 32, &sigBlob) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(&sigBlob, &sm2_sig) != SAR_OK) { + error_print(); + return -1; + } + *siglen = 0; + if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int skf_release_key(SKF_KEY *key) +{ + if (key->app_handle) { + if (SKF_ClearSecureState(key->app_handle) != SAR_OK + || SKF_CloseApplication(key->app_handle) != SAR_OK) { + error_print(); + return -1; + } + key->app_handle = NULL; + } + if (key->container_handle) { + if (SKF_CloseContainer(key->container_handle) != SAR_OK) { + error_print(); + return -1; + } + } + memset(key, 0, sizeof(SKF_KEY)); + return 1; +} + +int skf_close_device(SKF_DEVICE *dev) +{ + if (SKF_UnlockDev(dev->handle) != SAR_OK + || SKF_DisConnectDev(dev->handle) != SAR_OK) { + error_print(); + return -1; + } + memset(dev, 0, sizeof(SKF_DEVICE)); + return 1; +} + + + + + + + +int skf_list_devices(FILE *fp, int fmt, int ind, const char *label) +{ + int ret = -1; + BOOL bPresent = TRUE; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (SKF_EnumDev(bPresent, NULL, &nameListLen) != SAR_OK) { + error_print(); + return -1; + } + if (nameListLen == 0) { + return 0; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + return -1; + } + if (SKF_EnumDev(bPresent, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + (void)format_print(fp, fmt, ind, "%s\n", name); + } + ret = 1; +end: + free(nameList); + return ret; +} + +int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname) +{ + int ret = 0; + DEVHANDLE hDev = NULL; + ULONG devState = 0; + LPSTR devStateName = NULL; + DEVINFO devInfo = {{0,0}}; + + format_print(fp, fmt, ind, "%s\n", devname); + ind += 4; + + if (SKF_GetDevState((LPSTR)devname, &devState) != SAR_OK + || SKF_GetDevStateName(devState, &devStateName) != SAR_OK + || SKF_ConnectDev((LPSTR)devname, &hDev) != SAR_OK + || SKF_GetDevInfo(hDev, &devInfo) != SAR_OK) { + error_print(); + goto end; + } + + (void)format_print(fp, fmt, ind, "DeviceState: %s\n", (char *)devStateName); + //(void)SKF_PrintDevInfo(fp, fmt, ind, "DeviceInfo", &devInfo); + ret = 1; +end: + if (hDev) SKF_DisConnectDev(hDev); + return ret; +} + +int skf_set_label(SKF_DEVICE *dev, const char *label) +{ + if (SKF_SetLabel(dev->handle, (LPSTR)label) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]) +{ + DEVHANDLE hDev = NULL; + DEVINFO devInfo = {{0,0}}; + ULONG ulTimeOut = 0xffffffff; + BYTE authRand[16] = {0}; + BYTE authData[16] = {0}; + ULONG authRandLen = SKF_AUTHRAND_LENGTH; + ULONG authDataLen = sizeof(authData); + BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; + + if (SKF_OpenDevice((LPSTR)devname, (BYTE *)authkey, &devInfo, &hDev) != SAR_OK + || SKF_LockDev(hDev, ulTimeOut) != SAR_OK) { + error_print(); + return -1; + } + memset(dev, 0, sizeof(SKF_DEVICE)); + dev->handle = hDev; + hDev = NULL; + + return 1; +} + +int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]) +{ + if (SKF_ChangeDevAuthKey(dev->handle, (BYTE *)authkey, 16) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (SKF_EnumApplication(dev->handle, NULL, &nameListLen) != SAR_OK) { + error_print(); + return -1; + } + if (nameListLen <= 1) { + return 0; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + return -1; + } + if (SKF_EnumApplication(dev->handle, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + ULONG adminMaxRetry; + ULONG adminMinRetry; + ULONG userMaxRetry; + ULONG userMinRetry; + BOOL adminDefaultPin; + BOOL userDefaultPin; + + if (SKF_OpenApplication(dev->handle, (LPSTR)name, &hApp) != SAR_OK + || SKF_GetPINInfo(hApp, ADMIN_TYPE, &adminMaxRetry, &adminMinRetry, &adminDefaultPin) != SAR_OK + || SKF_GetPINInfo(hApp, USER_TYPE, &userMaxRetry, &userMinRetry, &userDefaultPin) != SAR_OK + || SKF_CloseApplication(hApp) != SAR_OK) { + error_print(); + goto end; + } + hApp = NULL; + + (void)format_print(fp, fmt, ind, "Application %d:\n", i); + (void)format_print(fp, fmt, ind + 4, "ApplicationName", name); + (void)format_print(fp, fmt, ind + 4, "AdminPinMaxRetry: %s\n", adminMaxRetry); + (void)format_print(fp, fmt, ind + 4, "AdminPinMinRetry: %u\n", adminMinRetry); + (void)format_print(fp, fmt, ind + 4, "AdminDefaultPin: %s\n", adminDefaultPin ? "True" : "False"); + (void)format_print(fp, fmt, ind + 4, "UserPinMaxRetry: %u\n", userMaxRetry); + (void)format_print(fp, fmt, ind + 4, "UserPinMinRetry: %u\n", userMinRetry); + (void)format_print(fp, fmt, ind + 4, "UserDefaultPin: %s\n", userDefaultPin ? "True" : "False"); + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + ULONG appRights = SECURE_ANYONE_ACCOUNT; + + if (SKF_CreateApplication(dev->handle, (LPSTR)appname, + (CHAR *)admin_pin, SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT, + (CHAR *)user_pin, SKF_DEFAULT_USER_PIN_RETRY_COUNT, + appRights, &hApp) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_CloseApplication(hApp) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_delete_app(SKF_DEVICE *dev, const char *appname) +{ + if (SKF_DeleteApplication(dev->handle, (LPSTR)appname) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulPINType = ADMIN_TYPE; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Retry Count = %u\n", ulRetryCount); + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulPINType = USER_TYPE; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Retry Count = %u\n", ulRetryCount); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_UnblockPIN(hApp, (CHAR *)admin_pin, (CHAR *)new_user_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Invalid admin PIN, retry count = %u\n", ulRetryCount); + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, + SKF_DEVICE *dev, const char *appname, const char *pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_EnumFiles(hApp, NULL, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + if (nameListLen <= 1) { + ret = 0; + goto end; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + goto end; + } + if (SKF_EnumFiles(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + FILEATTRIBUTE fileInfo; + + if (SKF_GetFileInfo(hApp, (LPSTR)name, &fileInfo) != SAR_OK) { + error_print(); + goto end; + } + format_print(fp, fmt, ind, "Object:\n"); + format_print(fp, fmt, ind + 4, "Name: %s\n", (char *)&(fileInfo.FileName)); + format_print(fp, fmt, ind + 4, "Size: %u\n", fileInfo.FileSize); + format_print(fp, fmt, ind + 4, "ReadRights: %08X\n", fileInfo.ReadRights); + format_print(fp, fmt, ind + 4, "WriteRights: %08X\n", fileInfo.WriteRights); + } + + ret = 1; + +end: + if (hApp) SKF_CloseApplication(hApp); + if (nameList) free(nameList); + return ret; +} + +int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *objname, const uint8_t *data, size_t datalen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulReadRights = SECURE_ANYONE_ACCOUNT; + ULONG ulWriteRights = SECURE_USER_ACCOUNT; + + if (!dev || !appname || !pin || !objname || !data || !datalen) { + error_print(); + return -1; + } + if (datalen > SKF_MAX_FILE_SIZE) { + error_print(); + return -1; + } + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_CreateFile(hApp, (LPSTR)objname, datalen, ulReadRights, ulWriteRights) != SAR_OK + || SKF_WriteFile(hApp, (LPSTR)objname, 0, (BYTE *)data, datalen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *objname, uint8_t *out, size_t *outlen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + FILEATTRIBUTE fileInfo; + ULONG ulen; + int len; + + if (!dev || !appname || !pin || !objname || !outlen) { + error_print(); + return -1; + } + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetFileInfo(hApp, (LPSTR)objname, &fileInfo) != SAR_OK) { + error_print(); + goto end; + } + if (fileInfo.FileSize > SKF_MAX_FILE_SIZE) { + error_print(); + goto end; + } + if (!out) { + *outlen = (size_t)fileInfo.FileSize; + ret = 1; + goto end; + } + ulen = fileInfo.FileSize; + if (SKF_ReadFile(hApp, (LPSTR)objname, 0, fileInfo.FileSize, out, &ulen) != SAR_OK) { + goto end; + } + if (ulen != fileInfo.FileSize) { + error_print(); + goto end; + } + *outlen = ulen; + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_DeleteFile(hApp, (LPSTR)objname) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, + SKF_DEVICE *dev, const char *appname, const char *pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_EnumContainer(hApp, NULL, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + if (nameListLen <= 1) { + ret = 0; + goto end; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + goto end; + } + if (SKF_EnumContainer(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + ULONG containerType; + LPSTR containerTypeName; + + if (SKF_OpenContainer(hApp, (LPSTR)name, &hContainer) != SAR_OK + || SKF_GetContainerType(hContainer, &containerType) != SAR_OK + || SKF_GetContainerTypeName(containerType, &containerTypeName) != SAR_OK + || SKF_CloseContainer(hContainer) != SAR_OK) { + error_print(); + goto end; + } + hContainer = NULL; + (void)format_print(fp, fmt, ind, "Container:\n"); + (void)format_print(fp, fmt, ind + 4, "Name: %s\n", name); + (void)format_print(fp, fmt, ind + 4, "Type: %s\n", (char *)containerTypeName); + } + ret = 1; + +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ECCPUBLICKEYBLOB publicKey = {0, {0}, {0}}; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_CreateContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK + || SKF_GenECCKeyPair(hContainer, SGD_SM2_1, &publicKey) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_DeleteContainer(hApp, (LPSTR)container_name) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return 1; +} + +int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *container_name, const uint8_t *cert, size_t certlen) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType; + BOOL bSign = SGD_TRUE; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType == SKF_CONTAINER_TYPE_UNDEF) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + // FIXME: 判断导入证书的类型是否为签名证书 + if (SKF_ImportCertificate(hContainer, bSign, (BYTE *)cert, (ULONG)certlen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *container_name, uint8_t *cert, size_t *certlen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType; + BOOL bSign = SGD_TRUE; + ULONG ulCertLen = 0; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + if (SKF_ExportCertificate(hContainer, bSign, (BYTE *)cert, &ulCertLen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} diff --git a/src/skf/skf.h b/src/skf/skf.h index 7780be87..664735c2 100644 --- a/src/skf/skf.h +++ b/src/skf/skf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,703 +7,704 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -/* This header file is from the official specification with minor - * modification. - */ - -#ifndef SKFUTIL_SKF_H -#define SKFUTIL_SKF_H - - -#include "../sgd.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(1) -typedef struct Struct_Version{ - BYTE major; - BYTE minor; -} VERSION; - -typedef struct Struct_DEVINFO { - VERSION Version; - CHAR Manufacturer[64]; - CHAR Issuer[64]; - CHAR Label[32]; - CHAR SerialNumber[32]; - VERSION HWVersion; - VERSION FirmwareVersion; - ULONG AlgSymCap; - ULONG AlgAsymCap; - ULONG AlgHashCap; - ULONG DevAuthAlgId; - ULONG TotalSpace; - ULONG FreeSpace; - ULONG MaxECCBufferSize; - ULONG MaxBufferSize; - BYTE Reserved[64]; -} DEVINFO, *PDEVINFO; - -typedef struct Struct_RSAPUBLICKEYBLOB { - ULONG AlgID; - ULONG BitLen; - BYTE Modulus[MAX_RSA_MODULUS_LEN]; - BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; -} RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB; - -typedef struct Struct_RSAPRIVATEKEYBLOB { - ULONG AlgID; - ULONG BitLen; - BYTE Modulus[MAX_RSA_MODULUS_LEN]; - BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; - BYTE PrivateExponent[MAX_RSA_MODULUS_LEN]; - BYTE Prime1[MAX_RSA_MODULUS_LEN/2]; - BYTE Prime2[MAX_RSA_MODULUS_LEN/2]; - BYTE Prime1Exponent[MAX_RSA_MODULUS_LEN/2]; - BYTE Prime2Exponent[MAX_RSA_MODULUS_LEN/2]; - BYTE Coefficient[MAX_RSA_MODULUS_LEN/2]; -} RSAPRIVATEKEYBLOB, *PRSAPRIVATEKEYBLOB; - -typedef struct Struct_ECCPUBLICKEYBLOB { - ULONG BitLen; - BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; - BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8]; -} ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB; - -typedef struct Struct_ECCPRIVATEKEYBLOB { - ULONG BitLen; - BYTE PrivateKey[ECC_MAX_MODULUS_BITS_LEN/8]; -} ECCPRIVATEKEYBLOB, *PECCPRIVATEKEYBLOB; - -typedef struct Struct_ECCCIPHERBLOB { - BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; - BYTE YCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; - BYTE HASH[32]; - ULONG CipherLen; - BYTE Cipher[1]; -} ECCCIPHERBLOB, *PECCCIPHERBLOB; - -typedef struct Struct_ECCSIGNATUREBLOB { - BYTE r[ECC_MAX_XCOORDINATE_BITS_LEN/8]; - BYTE s[ECC_MAX_XCOORDINATE_BITS_LEN/8]; -} ECCSIGNATUREBLOB, *PECCSIGNATUREBLOB; - -typedef struct Struct_BLOCKCIPHERPARAM { - BYTE IV[MAX_IV_LEN]; - ULONG IVLen; - ULONG PaddingType; - ULONG FeedBitLen; -} BLOCKCIPHERPARAM, *PBLOCKCIPHERPARAM; - -typedef struct SKF_ENVELOPEDKEYBLOB { - ULONG Version; - ULONG ulSymmAlgID; - ULONG ulBits; - BYTE cbEncryptedPriKey[64]; - ECCPUBLICKEYBLOB PubKey; - ECCCIPHERBLOB ECCCipherBlob; -} ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB; - -typedef struct Struct_FILEATTRIBUTE { - CHAR FileName[MAX_FILE_NAME_SIZE]; - ULONG FileSize; - ULONG ReadRights; - ULONG WriteRights; -} FILEATTRIBUTE, *PFILEATTRIBUTE; -#pragma pack() - -/* 7.1.2 */ -ULONG DEVAPI SKF_WaitForDevEvent( - LPSTR szDevName, - ULONG *pulDevNameLen, - ULONG *pulEvent); - -/* 7.1.3 */ -ULONG DEVAPI SKF_CancelWaitForDevEvent( - void); - -/* 7.1.4 */ -ULONG DEVAPI SKF_EnumDev( - BOOL bPresent, - LPSTR szNameList, - ULONG *pulSize); - -/* 7.1.5 */ -ULONG DEVAPI SKF_ConnectDev( - LPSTR szName, - DEVHANDLE *phDev); - -/* 7.1.6 */ -ULONG DEVAPI SKF_DisConnectDev( - DEVHANDLE hDev); - -/* 7.1.7 */ -ULONG DEVAPI SKF_GetDevState( - LPSTR szDevName, - ULONG *pulDevState); - -/* 7.1.8 */ -ULONG DEVAPI SKF_SetLabel( - DEVHANDLE hDev, - LPSTR szLabel); - -/* 7.1.9 */ -ULONG DEVAPI SKF_GetDevInfo( - DEVHANDLE hDev, - DEVINFO *pDevInfo); - -/* 7.1.10 */ -ULONG DEVAPI SKF_LockDev( - DEVHANDLE hDev, - ULONG ulTimeOut); - -/* 7.1.11 */ -ULONG DEVAPI SKF_UnlockDev( - DEVHANDLE hDev); - -/* 7.1.12 */ -ULONG DEVAPI SKF_Transmit( - DEVHANDLE hDev, - BYTE *pbCommand, - ULONG ulCommandLen, - BYTE *pbData, - ULONG *pulDataLen); - -/* 7.2.2 */ -ULONG DEVAPI SKF_ChangeDevAuthKey( - DEVHANDLE hDev, - BYTE *pbKeyValue, - ULONG ulKeyLen); - -/* 7.2.3 */ -ULONG DEVAPI SKF_DevAuth( - DEVHANDLE hDev, - BYTE *pbAuthData, - ULONG ulLen); - -/* 7.2.4 */ -ULONG DEVAPI SKF_ChangePIN( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szOldPin, - LPSTR szNewPin, - ULONG *pulRetryCount); - -/* 7.2.5 */ -LONG DEVAPI SKF_GetPINInfo( - HAPPLICATION hApplication, - ULONG ulPINType, - ULONG *pulMaxRetryCount, - ULONG *pulRemainRetryCount, - BOOL *pbDefaultPin); - -/* 7.2.6 */ -ULONG DEVAPI SKF_VerifyPIN( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szPIN, - ULONG *pulRetryCount); - -/* 7.2.7 */ -ULONG DEVAPI SKF_UnblockPIN( - HAPPLICATION hApplication, - LPSTR szAdminPIN, - LPSTR szNewUserPIN, - ULONG *pulRetryCount); - -/* 7.2.8 */ -ULONG DEVAPI SKF_ClearSecureState( - HAPPLICATION hApplication); - -/* 7.3.2 */ -ULONG DEVAPI SKF_CreateApplication( - DEVHANDLE hDev, - LPSTR szAppName, - LPSTR szAdminPin, - DWORD dwAdminPinRetryCount, - LPSTR szUserPin, - DWORD dwUserPinRetryCount, - DWORD dwCreateFileRights, - HAPPLICATION *phApplication); - -/* 7.3.3 */ -ULONG DEVAPI SKF_EnumApplication( - DEVHANDLE hDev, - LPSTR szAppName, - ULONG *pulSize); - -/* 7.3.4 */ -ULONG DEVAPI SKF_DeleteApplication( - DEVHANDLE hDev, - LPSTR szAppName); - -/* 7.3.5 */ -ULONG DEVAPI SKF_OpenApplication( - DEVHANDLE hDev, - LPSTR szAppName, - HAPPLICATION *phApplication); - -/* 7.3.6 */ -ULONG DEVAPI SKF_CloseApplication( - HAPPLICATION hApplication); - -/* 7.4.2 */ -ULONG DEVAPI SKF_CreateFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulFileSize, - ULONG ulReadRights, - ULONG ulWriteRights); - -/* 7.4.3 */ -ULONG DEVAPI SKF_DeleteFile( - HAPPLICATION hApplication, - LPSTR szFileName); - -/* 7.4.4 */ -ULONG DEVAPI SKF_EnumFiles( - HAPPLICATION hApplication, - LPSTR szFileList, - ULONG *pulSize); - -/* 7.4.5 */ -ULONG DEVAPI SKF_GetFileInfo( - HAPPLICATION hApplication, - LPSTR szFileName, - FILEATTRIBUTE *pFileInfo); - -/* 7.4.6 */ -ULONG DEVAPI SKF_ReadFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - ULONG ulSize, - BYTE *pbOutData, - ULONG *pulOutLen); - -/* 7.4.7 */ -ULONG DEVAPI SKF_WriteFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - BYTE *pbData, - ULONG ulSize); - -/* 7.5.2 */ -ULONG DEVAPI SKF_CreateContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer); - -/* 7.5.3 */ -ULONG DEVAPI SKF_DeleteContainer( - HAPPLICATION hApplication, - LPSTR szContainerName); - -/* 7.5.4 */ -ULONG DEVAPI SKF_OpenContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer); - -/* 7.5.5 */ -ULONG DEVAPI SKF_CloseContainer( - HCONTAINER hContainer); - -/* 7.5.6 */ -ULONG DEVAPI SKF_EnumContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - ULONG *pulSize); - -/* 7.5.7 */ -ULONG DEVAPI SKF_GetContainerType( - HCONTAINER hContainer, - ULONG *pulContainerType); - -/* 7.5.8 */ -ULONG DEVAPI SKF_ImportCertificate( - HCONTAINER hContainer, - BOOL bExportSignKey, - BYTE *pbCert, - ULONG ulCertLen); - -/* 7.5.9 */ -ULONG DEVAPI SKF_ExportCertificate( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbCert, - ULONG *pulCertLen); - -/* 7.6.2 */ -ULONG DEVAPI SKF_GenRandom( - DEVHANDLE hDev, - BYTE *pbRandom, - ULONG ulRandomLen); - -/* 7.6.3 */ -ULONG DEVAPI SKF_GenExtRSAKey( - DEVHANDLE hDev, - ULONG ulBitsLen, - RSAPRIVATEKEYBLOB *pBlob); - -/* 7.6.4 */ -ULONG DEVAPI SKF_GenRSAKeyPair( - HCONTAINER hContainer, - ULONG ulBitsLen, - RSAPUBLICKEYBLOB *pBlob); - -/* 7.6.5 */ -ULONG DEVAPI SKF_ImportRSAKeyPair( - HCONTAINER hContainer, - ULONG ulSymAlgId, - BYTE *pbWrappedKey, - ULONG ulWrappedKeyLen, - BYTE *pbEncryptedData, - ULONG ulEncryptedDataLen); - -/* 7.6.6 */ -ULONG DEVAPI SKF_RSASignData( - HCONTAINER hContainer, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG *pulSignLen); - -/* 7.6.7 */ -ULONG DEVAPI SKF_RSAVerify( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG ulSignLen); - -/* 7.6.8 */ -ULONG DEVAPI SKF_RSAExportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - RSAPUBLICKEYBLOB *pPubKey, - BYTE *pbData, - ULONG *pulDataLen, - HANDLE *phSessionKey); - -/* 7.6.9 */ -ULONG DEVAPI SKF_ExtRSAPubKeyOperation( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen); - -/* 7.6.10 */ -ULONG DEVAPI SKF_ExtRSAPriKeyOperation( - DEVHANDLE hDev, - RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen); - -/* 7.6.11 */ -ULONG DEVAPI SKF_GenECCKeyPair( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pBlob); - -/* 7.6.12 */ -ULONG DEVAPI SKF_ImportECCKeyPair( - HCONTAINER hContainer, - ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); - -/* 7.6.13 */ -ULONG DEVAPI SKF_ECCSignData( - HCONTAINER hContainer, - BYTE *pbDigest, - ULONG ulDigestLen, - ECCSIGNATUREBLOB *pSignature); - -#ifdef SKF_HAS_ECCDECRYPT -ULONG DEVAPI SKF_ECCDecrypt( - HCONTAINER hContainer, - ECCCIPHERBLOB *pCipherBlob, - BYTE *pbPlainText, - ULONG *pulPlainTextLen); -#endif - -/* 7.6.14 */ -ULONG DEVAPI SKF_ECCVerify( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -/* 7.6.15 */ -ULONG DEVAPI SKF_ECCExportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pPubKey, - ECCCIPHERBLOB *pData, - HANDLE *phSessionKey); - -/* 7.6.16 */ -ULONG DEVAPI SKF_ExtECCEncrypt( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbPlainText, - ULONG ulPlainTextLen, - ECCCIPHERBLOB *pCipherText); - -/* 7.6.17 */ -ULONG DEVAPI SKF_ExtECCDecrypt( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - ECCCIPHERBLOB *pCipherText, - BYTE *pbPlainText, - ULONG *pulPlainTextLen); - -/* 7.6.18 */ -ULONG DEVAPI SKF_ExtECCSign( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -/* 7.6.19 */ -ULONG DEVAPI SKF_ExtECCVerify( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -/* 7.6.20 */ -ULONG DEVAPI SKF_GenerateAgreementDataWithECC( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phAgreementHandle); - -/* 7.6.21 */ -ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( - HANDLE hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, - ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - BYTE *pbSponsorID, - ULONG ulSponsorIDLen, - HANDLE *phKeyHandle); - -/* 7.6.22 */ -ULONG DEVAPI SKF_GenerateKeyWithECC( - HANDLE hAgreementHandle, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phKeyHandle); - -/* 7.6.23 */ -ULONG DEVAPI SKF_ExportPublicKey( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbBlob, - ULONG *pulBlobLen); - -/* 7.6.24 */ -ULONG DEVAPI SKF_ImportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - BYTE *pbWrapedData, - ULONG ulWrapedLen, - HANDLE *phKey); - -/* 7.6.25 */ -ULONG DEVAPI SKF_SetSymmKey( - DEVHANDLE hDev, - BYTE *pbKey, - ULONG ulAlgID, - HANDLE *phKey); - -/* 7.6.26 */ -ULONG DEVAPI SKF_EncryptInit( - HANDLE hKey, - BLOCKCIPHERPARAM EncryptParam); - -/* 7.6.27 */ -ULONG DEVAPI SKF_Encrypt( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen); - -/* 7.6.28 */ -ULONG DEVAPI SKF_EncryptUpdate( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen); - -/* 7.6.29 */ -ULONG DEVAPI SKF_EncryptFinal( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG *pulEncryptedDataLen); - -/* 7.6.30 */ -ULONG DEVAPI SKF_DecryptInit( - HANDLE hKey, - BLOCKCIPHERPARAM DecryptParam); - -/* 7.6.31 */ -ULONG DEVAPI SKF_Decrypt( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen); - -/* 7.6.32 */ -ULONG DEVAPI SKF_DecryptUpdate( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen); - -/* 7.6.33 */ -ULONG DEVAPI SKF_DecryptFinal( - HANDLE hKey, - BYTE *pbDecryptedData, - ULONG *pulDecryptedDataLen); - -/* 7.6.34 */ -ULONG DEVAPI SKF_DigestInit( - DEVHANDLE hDev, - ULONG ulAlgID, - ECCPUBLICKEYBLOB *pPubKey, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phHash); - -/* 7.6.35 */ -ULONG DEVAPI SKF_Digest( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbHashData, - ULONG *pulHashLen); - -/* 7.6.36 */ -ULONG DEVAPI SKF_DigestUpdate( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen); - -/* 7.6.37 */ -ULONG DEVAPI SKF_DigestFinal( - HANDLE hHash, - BYTE *pHashData, - ULONG *pulHashLen); - -/* 7.6.38 */ -ULONG DEVAPI SKF_MacInit( - HANDLE hKey, - BLOCKCIPHERPARAM *pMacParam, - HANDLE *phMac); - -/* 7.6.39 */ -ULONG DEVAPI SKF_Mac( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbMacData, - ULONG *pulMacLen); - -/* 7.6.40 */ -ULONG DEVAPI SKF_MacUpdate( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen); - -/* 7.6.41 */ -ULONG DEVAPI SKF_MacFinal( - HANDLE hMac, - BYTE *pbMacData, - ULONG *pulMacDataLen); - -/* 7.6.42 */ -ULONG DEVAPI SKF_CloseHandle( - HANDLE hHandle); - - -#define SAR_OK 0x00000000 -#define SAR_FAIL 0x0A000001 -#define SAR_UNKNOWNERR 0x0A000002 -#define SAR_NOTSUPPORTYETERR 0x0A000003 -#define SAR_FILEERR 0x0A000004 -#define SAR_INVALIDHANDLEERR 0x0A000005 -#define SAR_INVALIDPARAMERR 0x0A000006 -#define SAR_READFILEERR 0x0A000007 -#define SAR_WRITEFILEERR 0x0A000008 -#define SAR_NAMELENERR 0x0A000009 -#define SAR_KEYUSAGEERR 0x0A00000A -#define SAR_MODULUSLENERR 0x0A00000B -#define SAR_NOTINITIALIZEERR 0x0A00000C -#define SAR_OBJERR 0x0A00000D -#define SAR_MEMORYERR 0x0A00000E -#define SAR_TIMEOUTERR 0x0A00000F -#define SAR_INDATALENERR 0x0A000010 -#define SAR_INDATAERR 0x0A000011 -#define SAR_GENRANDERR 0x0A000012 -#define SAR_HASHOBJERR 0x0A000013 -#define SAR_HASHERR 0x0A000014 -#define SAR_GENRSAKEYERR 0x0A000015 -#define SAR_RSAMODULUSLENERR 0x0A000016 -#define SAR_CSPIMPRTPUBKEYERR 0x0A000017 -#define SAR_RSAENCERR 0x0A000018 -#define SAR_RSADECERR 0x0A000019 -#define SAR_HASHNOTEQUALERR 0x0A00001A -#define SAR_KEYNOTFOUNTERR 0x0A00001B -#define SAR_CERTNOTFOUNTERR 0x0A00001C -#define SAR_NOTEXPORTERR 0x0A00001D -#define SAR_DECRYPTPADERR 0x0A00001E -#define SAR_MACLENERR 0x0A00001F -#define SAR_BUFFER_TOO_SMALL 0x0A000020 -#define SAR_KEYINFOTYPEERR 0x0A000021 -#define SAR_NOT_EVENTERR 0x0A000022 -#define SAR_DEVICE_REMOVED 0x0A000023 -#define SAR_PIN_INCORRECT 0x0A000024 -#define SAR_PIN_LOCKED 0x0A000025 -#define SAR_PIN_INVALID 0x0A000026 -#define SAR_PIN_LEN_RANGE 0x0A000027 -#define SAR_USER_ALREADY_LOGGED_IN 0x0A000028 -#define SAR_USER_PIN_NOT_INITIALIZED 0x0A000029 -#define SAR_USER_TYPE_INVALID 0x0A00002A -#define SAR_APPLICATION_NAME_INVALID 0x0A00002B -#define SAR_APPLICATION_EXISTS 0x0A00002C -#define SAR_USER_NOT_LOGGED_IN 0x0A00002D -#define SAR_APPLICATION_NOT_EXISTS 0x0A00002E -#define SAR_FILE_ALREADY_EXIST 0x0A00002F -#define SAR_NO_ROOM 0x0A000030 -#define SAR_FILE_NOT_EXIST 0x0A000031 -#define SAR_REACH_MAX_CONTAINER_COUNT 0x0A000032 - - -#ifdef __cplusplus -} -#endif -#endif + +/* This header file is from the official specification with minor + * modification. + */ + +#ifndef SKFUTIL_SKF_H +#define SKFUTIL_SKF_H + + +#include "../sgd.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(1) +typedef struct Struct_Version{ + BYTE major; + BYTE minor; +} VERSION; + +typedef struct Struct_DEVINFO { + VERSION Version; + CHAR Manufacturer[64]; + CHAR Issuer[64]; + CHAR Label[32]; + CHAR SerialNumber[32]; + VERSION HWVersion; + VERSION FirmwareVersion; + ULONG AlgSymCap; + ULONG AlgAsymCap; + ULONG AlgHashCap; + ULONG DevAuthAlgId; + ULONG TotalSpace; + ULONG FreeSpace; + ULONG MaxECCBufferSize; + ULONG MaxBufferSize; + BYTE Reserved[64]; +} DEVINFO, *PDEVINFO; + +typedef struct Struct_RSAPUBLICKEYBLOB { + ULONG AlgID; + ULONG BitLen; + BYTE Modulus[MAX_RSA_MODULUS_LEN]; + BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; +} RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB; + +typedef struct Struct_RSAPRIVATEKEYBLOB { + ULONG AlgID; + ULONG BitLen; + BYTE Modulus[MAX_RSA_MODULUS_LEN]; + BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; + BYTE PrivateExponent[MAX_RSA_MODULUS_LEN]; + BYTE Prime1[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime2[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime1Exponent[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime2Exponent[MAX_RSA_MODULUS_LEN/2]; + BYTE Coefficient[MAX_RSA_MODULUS_LEN/2]; +} RSAPRIVATEKEYBLOB, *PRSAPRIVATEKEYBLOB; + +typedef struct Struct_ECCPUBLICKEYBLOB { + ULONG BitLen; + BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8]; +} ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB; + +typedef struct Struct_ECCPRIVATEKEYBLOB { + ULONG BitLen; + BYTE PrivateKey[ECC_MAX_MODULUS_BITS_LEN/8]; +} ECCPRIVATEKEYBLOB, *PECCPRIVATEKEYBLOB; + +typedef struct Struct_ECCCIPHERBLOB { + BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE YCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE HASH[32]; + ULONG CipherLen; + BYTE Cipher[1]; +} ECCCIPHERBLOB, *PECCCIPHERBLOB; + +typedef struct Struct_ECCSIGNATUREBLOB { + BYTE r[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE s[ECC_MAX_XCOORDINATE_BITS_LEN/8]; +} ECCSIGNATUREBLOB, *PECCSIGNATUREBLOB; + +typedef struct Struct_BLOCKCIPHERPARAM { + BYTE IV[MAX_IV_LEN]; + ULONG IVLen; + ULONG PaddingType; + ULONG FeedBitLen; +} BLOCKCIPHERPARAM, *PBLOCKCIPHERPARAM; + +typedef struct SKF_ENVELOPEDKEYBLOB { + ULONG Version; + ULONG ulSymmAlgID; + ULONG ulBits; + BYTE cbEncryptedPriKey[64]; + ECCPUBLICKEYBLOB PubKey; + ECCCIPHERBLOB ECCCipherBlob; +} ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB; + +typedef struct Struct_FILEATTRIBUTE { + CHAR FileName[MAX_FILE_NAME_SIZE]; + ULONG FileSize; + ULONG ReadRights; + ULONG WriteRights; +} FILEATTRIBUTE, *PFILEATTRIBUTE; +#pragma pack() + +/* 7.1.2 */ +ULONG DEVAPI SKF_WaitForDevEvent( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent); + +/* 7.1.3 */ +ULONG DEVAPI SKF_CancelWaitForDevEvent( + void); + +/* 7.1.4 */ +ULONG DEVAPI SKF_EnumDev( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize); + +/* 7.1.5 */ +ULONG DEVAPI SKF_ConnectDev( + LPSTR szName, + DEVHANDLE *phDev); + +/* 7.1.6 */ +ULONG DEVAPI SKF_DisConnectDev( + DEVHANDLE hDev); + +/* 7.1.7 */ +ULONG DEVAPI SKF_GetDevState( + LPSTR szDevName, + ULONG *pulDevState); + +/* 7.1.8 */ +ULONG DEVAPI SKF_SetLabel( + DEVHANDLE hDev, + LPSTR szLabel); + +/* 7.1.9 */ +ULONG DEVAPI SKF_GetDevInfo( + DEVHANDLE hDev, + DEVINFO *pDevInfo); + +/* 7.1.10 */ +ULONG DEVAPI SKF_LockDev( + DEVHANDLE hDev, + ULONG ulTimeOut); + +/* 7.1.11 */ +ULONG DEVAPI SKF_UnlockDev( + DEVHANDLE hDev); + +/* 7.1.12 */ +ULONG DEVAPI SKF_Transmit( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.2.2 */ +ULONG DEVAPI SKF_ChangeDevAuthKey( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen); + +/* 7.2.3 */ +ULONG DEVAPI SKF_DevAuth( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen); + +/* 7.2.4 */ +ULONG DEVAPI SKF_ChangePIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount); + +/* 7.2.5 */ +LONG DEVAPI SKF_GetPINInfo( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin); + +/* 7.2.6 */ +ULONG DEVAPI SKF_VerifyPIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount); + +/* 7.2.7 */ +ULONG DEVAPI SKF_UnblockPIN( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount); + +/* 7.2.8 */ +ULONG DEVAPI SKF_ClearSecureState( + HAPPLICATION hApplication); + +/* 7.3.2 */ +ULONG DEVAPI SKF_CreateApplication( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication); + +/* 7.3.3 */ +ULONG DEVAPI SKF_EnumApplication( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize); + +/* 7.3.4 */ +ULONG DEVAPI SKF_DeleteApplication( + DEVHANDLE hDev, + LPSTR szAppName); + +/* 7.3.5 */ +ULONG DEVAPI SKF_OpenApplication( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication); + +/* 7.3.6 */ +ULONG DEVAPI SKF_CloseApplication( + HAPPLICATION hApplication); + +/* 7.4.2 */ +ULONG DEVAPI SKF_CreateFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights); + +/* 7.4.3 */ +ULONG DEVAPI SKF_DeleteFile( + HAPPLICATION hApplication, + LPSTR szFileName); + +/* 7.4.4 */ +ULONG DEVAPI SKF_EnumFiles( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize); + +/* 7.4.5 */ +ULONG DEVAPI SKF_GetFileInfo( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo); + +/* 7.4.6 */ +ULONG DEVAPI SKF_ReadFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen); + +/* 7.4.7 */ +ULONG DEVAPI SKF_WriteFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize); + +/* 7.5.2 */ +ULONG DEVAPI SKF_CreateContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +/* 7.5.3 */ +ULONG DEVAPI SKF_DeleteContainer( + HAPPLICATION hApplication, + LPSTR szContainerName); + +/* 7.5.4 */ +ULONG DEVAPI SKF_OpenContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +/* 7.5.5 */ +ULONG DEVAPI SKF_CloseContainer( + HCONTAINER hContainer); + +/* 7.5.6 */ +ULONG DEVAPI SKF_EnumContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize); + +/* 7.5.7 */ +ULONG DEVAPI SKF_GetContainerType( + HCONTAINER hContainer, + ULONG *pulContainerType); + +/* 7.5.8 */ +ULONG DEVAPI SKF_ImportCertificate( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen); + +/* 7.5.9 */ +ULONG DEVAPI SKF_ExportCertificate( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen); + +/* 7.6.2 */ +ULONG DEVAPI SKF_GenRandom( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen); + +/* 7.6.3 */ +ULONG DEVAPI SKF_GenExtRSAKey( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob); + +/* 7.6.4 */ +ULONG DEVAPI SKF_GenRSAKeyPair( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob); + +/* 7.6.5 */ +ULONG DEVAPI SKF_ImportRSAKeyPair( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen); + +/* 7.6.6 */ +ULONG DEVAPI SKF_RSASignData( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen); + +/* 7.6.7 */ +ULONG DEVAPI SKF_RSAVerify( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen); + +/* 7.6.8 */ +ULONG DEVAPI SKF_RSAExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey); + +/* 7.6.9 */ +ULONG DEVAPI SKF_ExtRSAPubKeyOperation( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +/* 7.6.10 */ +ULONG DEVAPI SKF_ExtRSAPriKeyOperation( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +/* 7.6.11 */ +ULONG DEVAPI SKF_GenECCKeyPair( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob); + +/* 7.6.12 */ +ULONG DEVAPI SKF_ImportECCKeyPair( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); + +/* 7.6.13 */ +ULONG DEVAPI SKF_ECCSignData( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature); + +#ifdef SKF_HAS_ECCDECRYPT +ULONG DEVAPI SKF_ECCDecrypt( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherBlob, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); +#endif + +/* 7.6.14 */ +ULONG DEVAPI SKF_ECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.15 */ +ULONG DEVAPI SKF_ECCExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey); + +/* 7.6.16 */ +ULONG DEVAPI SKF_ExtECCEncrypt( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText); + +/* 7.6.17 */ +ULONG DEVAPI SKF_ExtECCDecrypt( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +/* 7.6.18 */ +ULONG DEVAPI SKF_ExtECCSign( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.19 */ +ULONG DEVAPI SKF_ExtECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.20 */ +ULONG DEVAPI SKF_GenerateAgreementDataWithECC( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle); + +/* 7.6.21 */ +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle); + +/* 7.6.22 */ +ULONG DEVAPI SKF_GenerateKeyWithECC( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle); + +/* 7.6.23 */ +ULONG DEVAPI SKF_ExportPublicKey( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen); + +/* 7.6.24 */ +ULONG DEVAPI SKF_ImportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey); + +/* 7.6.25 */ +ULONG DEVAPI SKF_SetSymmKey( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey); + +/* 7.6.26 */ +ULONG DEVAPI SKF_EncryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam); + +/* 7.6.27 */ +ULONG DEVAPI SKF_Encrypt( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +/* 7.6.28 */ +ULONG DEVAPI SKF_EncryptUpdate( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +/* 7.6.29 */ +ULONG DEVAPI SKF_EncryptFinal( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen); + +/* 7.6.30 */ +ULONG DEVAPI SKF_DecryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam); + +/* 7.6.31 */ +ULONG DEVAPI SKF_Decrypt( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.6.32 */ +ULONG DEVAPI SKF_DecryptUpdate( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.6.33 */ +ULONG DEVAPI SKF_DecryptFinal( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen); + +/* 7.6.34 */ +ULONG DEVAPI SKF_DigestInit( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash); + +/* 7.6.35 */ +ULONG DEVAPI SKF_Digest( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen); + +/* 7.6.36 */ +ULONG DEVAPI SKF_DigestUpdate( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen); + +/* 7.6.37 */ +ULONG DEVAPI SKF_DigestFinal( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen); + +/* 7.6.38 */ +ULONG DEVAPI SKF_MacInit( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac); + +/* 7.6.39 */ +ULONG DEVAPI SKF_Mac( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen); + +/* 7.6.40 */ +ULONG DEVAPI SKF_MacUpdate( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen); + +/* 7.6.41 */ +ULONG DEVAPI SKF_MacFinal( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen); + +/* 7.6.42 */ +ULONG DEVAPI SKF_CloseHandle( + HANDLE hHandle); + + +#define SAR_OK 0x00000000 +#define SAR_FAIL 0x0A000001 +#define SAR_UNKNOWNERR 0x0A000002 +#define SAR_NOTSUPPORTYETERR 0x0A000003 +#define SAR_FILEERR 0x0A000004 +#define SAR_INVALIDHANDLEERR 0x0A000005 +#define SAR_INVALIDPARAMERR 0x0A000006 +#define SAR_READFILEERR 0x0A000007 +#define SAR_WRITEFILEERR 0x0A000008 +#define SAR_NAMELENERR 0x0A000009 +#define SAR_KEYUSAGEERR 0x0A00000A +#define SAR_MODULUSLENERR 0x0A00000B +#define SAR_NOTINITIALIZEERR 0x0A00000C +#define SAR_OBJERR 0x0A00000D +#define SAR_MEMORYERR 0x0A00000E +#define SAR_TIMEOUTERR 0x0A00000F +#define SAR_INDATALENERR 0x0A000010 +#define SAR_INDATAERR 0x0A000011 +#define SAR_GENRANDERR 0x0A000012 +#define SAR_HASHOBJERR 0x0A000013 +#define SAR_HASHERR 0x0A000014 +#define SAR_GENRSAKEYERR 0x0A000015 +#define SAR_RSAMODULUSLENERR 0x0A000016 +#define SAR_CSPIMPRTPUBKEYERR 0x0A000017 +#define SAR_RSAENCERR 0x0A000018 +#define SAR_RSADECERR 0x0A000019 +#define SAR_HASHNOTEQUALERR 0x0A00001A +#define SAR_KEYNOTFOUNTERR 0x0A00001B +#define SAR_CERTNOTFOUNTERR 0x0A00001C +#define SAR_NOTEXPORTERR 0x0A00001D +#define SAR_DECRYPTPADERR 0x0A00001E +#define SAR_MACLENERR 0x0A00001F +#define SAR_BUFFER_TOO_SMALL 0x0A000020 +#define SAR_KEYINFOTYPEERR 0x0A000021 +#define SAR_NOT_EVENTERR 0x0A000022 +#define SAR_DEVICE_REMOVED 0x0A000023 +#define SAR_PIN_INCORRECT 0x0A000024 +#define SAR_PIN_LOCKED 0x0A000025 +#define SAR_PIN_INVALID 0x0A000026 +#define SAR_PIN_LEN_RANGE 0x0A000027 +#define SAR_USER_ALREADY_LOGGED_IN 0x0A000028 +#define SAR_USER_PIN_NOT_INITIALIZED 0x0A000029 +#define SAR_USER_TYPE_INVALID 0x0A00002A +#define SAR_APPLICATION_NAME_INVALID 0x0A00002B +#define SAR_APPLICATION_EXISTS 0x0A00002C +#define SAR_USER_NOT_LOGGED_IN 0x0A00002D +#define SAR_APPLICATION_NOT_EXISTS 0x0A00002E +#define SAR_FILE_ALREADY_EXIST 0x0A00002F +#define SAR_NO_ROOM 0x0A000030 +#define SAR_FILE_NOT_EXIST 0x0A000031 +#define SAR_REACH_MAX_CONTAINER_COUNT 0x0A000032 + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/skf/skf_dummy.c b/src/skf/skf_dummy.c index 0a37f4cb..56b4fff1 100644 --- a/src/skf/skf_dummy.c +++ b/src/skf/skf_dummy.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,6 +7,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ + #include #include diff --git a/src/skf/skf_ext.c b/src/skf/skf_ext.c index 88ddb651..f086a0aa 100644 --- a/src/skf/skf_ext.c +++ b/src/skf/skf_ext.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,562 +7,563 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include "skf_int.h" -#include "skf_ext.h" -#include "skf.h" - - -#define SKFerr(f,e) - -ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob) -{ - ECCCIPHERBLOB *ret = NULL; - - if (!(ret = malloc(sizeof(ECCCIPHERBLOB) - 1 + ulCipherLen))) { - SKFerr(SKF_F_SKF_NEWECCCIPHER, ERR_R_MALLOC_FAILURE); - return SAR_MEMORYERR; - } - - ret->CipherLen = ulCipherLen; - *cipherBlob = ret; - return SAR_OK; -} - -ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob) -{ - ENVELOPEDKEYBLOB *ret = NULL; - - if (!(ret = malloc(sizeof(ENVELOPEDKEYBLOB) - 1 + ulCipherLen))) { - SKFerr(SKF_F_SKF_NEWENVELOPEDKEY, ERR_R_MALLOC_FAILURE); - return SAR_MEMORYERR; - } - - ret->ECCCipherBlob.CipherLen = ulCipherLen; - *envelopedKeyBlob = ret; - return SAR_OK; -} - -ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev) -{ - ULONG rv; - DEVHANDLE hDev = NULL; - HANDLE hKey = NULL; - ULONG ulTimeOut = 0xffffffff; - BYTE authRand[16] = {0}; - BYTE authData[16] = {0}; - ULONG authRandLen = SKF_AUTHRAND_LENGTH; - ULONG authDataLen = sizeof(authData); - BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; - - if ((rv = SKF_ConnectDev((LPSTR)devName, &hDev)) != SAR_OK - || (rv = SKF_GetDevInfo(hDev, devInfo)) != SAR_OK - || (rv = SKF_LockDev(hDev, ulTimeOut)) != SAR_OK - || (rv = SKF_GenRandom(hDev, authRand, authRandLen)) != SAR_OK - || (rv = SKF_SetSymmKey(hDev, authKey, devInfo->DevAuthAlgId, &hKey)) != SAR_OK - || (rv = SKF_EncryptInit(hKey, encParam)) != SAR_OK - || (rv = SKF_Encrypt(hKey, authRand, sizeof(authRand), authData, &authDataLen)) != SAR_OK - || (rv =SKF_DevAuth(hDev, authData, authDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); - goto end; - } - *phDev = hDev; - hDev = NULL; - -end: - //OPENSSL_cleanse(authRand, sizeof(authRand)); - //OPENSSL_cleanse(authData, sizeof(authData)); - if (hKey && (rv = SKF_CloseHandle(hKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); - } - if (hDev && (rv = SKF_DisConnectDev(hDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); - } - return rv; -} - -ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev) -{ - ULONG rv; - if ((rv = SKF_UnlockDev(hDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); - } - if ((rv = SKF_DisConnectDev(hDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); - } - return rv; -} - -#if 0 -ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, - EC_KEY *ec_key, ULONG symmAlgId) -{ - int ret = 0; - ULONG rv; - ULONG containerType; - ECCPRIVATEKEYBLOB eccPriKeyBlob; - BYTE symmKey[16]; - HANDLE hSymmKey = NULL; - BLOCKCIPHERPARAM encParam; - ULONG encedPriKeyLen; - SKF_PUBLICKEYBLOB signPubKeyBlob; - ULONG signPubKeyLen = sizeof(signPubKeyBlob); - ENVELOPEDKEYBLOB envelopedKeyBlob; - - /* check container type */ - if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - return rv; - } - if (containerType != SKF_CONTAINER_TYPE_ECC) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); - return SAR_FAIL; - } - - /* get private key and public key */ - if (!EC_KEY_get_ECCPRIVATEKEYBLOB(ec_key, &eccPriKeyBlob) - || !EC_KEY_get_ECCPUBLICKEYBLOB(ec_key, &(envelopedKeyBlob.PubKey))) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_GMAPI_LIB); - rv = SAR_FAIL; - goto end; - } - - /* set Version, ulSymmAlgID, ulBits */ - envelopedKeyBlob.Version = SKF_ENVELOPEDKEYBLOB_VERSION; - envelopedKeyBlob.ulSymmAlgID = symmAlgId; - envelopedKeyBlob.ulBits = eccPriKeyBlob.BitLen; - - /* encrypt private key with random generated symmkey */ - if (!rand_bytes(symmKey, sizeof(symmKey))) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - rv = SAR_FAIL; - goto end; - } - if ((rv = SKF_SetSymmKey(hDev, symmKey, symmAlgId, &hSymmKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - encParam.IVLen = 0; - encParam.PaddingType = SKF_NO_PADDING; - if ((rv = SKF_EncryptInit(hSymmKey, encParam)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - encedPriKeyLen = sizeof(envelopedKeyBlob.cbEncryptedPriKey); - if ((rv = SKF_Encrypt(hSymmKey, - eccPriKeyBlob.PrivateKey, sizeof(eccPriKeyBlob.PrivateKey), - (BYTE *)&(envelopedKeyBlob.cbEncryptedPriKey), &encedPriKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - if (encedPriKeyLen != sizeof(eccPriKeyBlob.PrivateKey)) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - rv = SAR_FAIL; - goto end; - } - - /* encrypt symmKey */ - if ((rv = SKF_ExportPublicKey(hContainer, TRUE, - (BYTE *)&signPubKeyBlob, &signPubKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - if (signPubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - rv = SAR_FAIL; - goto end; - } - if ((rv = SKF_ExtECCEncrypt(hDev, (ECCPUBLICKEYBLOB *)&signPubKeyBlob, - symmKey, sizeof(symmKey), &(envelopedKeyBlob.ECCCipherBlob))) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - - ret = 1; -end: - OPENSSL_cleanse(&eccPriKeyBlob, sizeof(eccPriKeyBlob)); - OPENSSL_cleanse(symmKey, sizeof(symmKey)); - if (hSymmKey && SKF_CloseHandle(hSymmKey) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); - ret = 0; - } - return ret; -} - -ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, - RSA *rsa, ULONG symmAlgId) -{ - ULONG rv; - ULONG containerType; - RSAPRIVATEKEYBLOB rsaPriKeyBlob; - unsigned char symmKey[16]; - RSAPUBLICKEYBLOB rsaPubKeyBlob; - ULONG rsaPubKeyLen = sizeof(rsaPubKeyBlob); - BYTE wrappedKey[MAX_RSA_MODULUS_LEN]; - ULONG wrappedKeyLen = sizeof(wrappedKey); - EVP_CIPHER_CTX *cctx = NULL; - unsigned char *p; - int len; - BYTE encedPriKey[sizeof(RSAPRIVATEKEYBLOB) + 16*2]; - ULONG encedPriKeyLen = sizeof(encedPriKey); - - - if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - return rv; - } - if (containerType != SKF_CONTAINER_TYPE_RSA) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - return SAR_FAIL; - } - - if (!RSA_get_RSAPRIVATEKEYBLOB(rsa, &rsaPriKeyBlob)) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - - /* generate symmkey */ - /* wrap symmkey with signing public key */ - if (!rand_bytes(symmKey, sizeof(symmKey))) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - if ((rv = SKF_ExportPublicKey(hContainer, SGD_TRUE, - (BYTE *)&rsaPubKeyBlob, &rsaPubKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - if (!(rsa = RSA_new_from_RSAPUBLICKEYBLOB(&rsaPubKeyBlob))) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - if ((len = RSA_public_encrypt(sizeof(symmKey), symmKey, wrappedKey, - rsa, RSA_PKCS1_PADDING)) != rsaPriKeyBlob.BitLen / 8) { - goto end; - } - wrappedKeyLen = (ULONG)len; - - /* encrypt private key with symmkey in ECB mode */ - if (!(cctx = EVP_CIPHER_CTX_new())) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto end; - } - if (!EVP_EncryptInit_ex(cctx, EVP_sms4_ecb(), NULL, symmKey, NULL)) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); - goto end; - } - p = encedPriKey; - if (!EVP_EncryptUpdate(cctx, p, &len, (unsigned char *)&rsaPriKeyBlob, - sizeof(RSAPRIVATEKEYBLOB))) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); - goto end; - } - p += len; - if (!EVP_EncryptFinal_ex(cctx, p, &len)) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); - goto end; - } - p += len; - encedPriKeyLen = p - encedPriKey; - - /* import */ - if ((rv = SKF_ImportRSAKeyPair(hContainer, symmAlgId, wrappedKey, wrappedKeyLen, - encedPriKey, encedPriKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); - goto end; - } - -end: - OPENSSL_cleanse(&rsaPriKeyBlob, sizeof(rsaPriKeyBlob)); - OPENSSL_cleanse(symmKey, sizeof(symmKey)); - OPENSSL_cleanse(wrappedKey, sizeof(wrappedKey)); - EVP_CIPHER_CTX_free(cctx); - return rv; -} - -ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, - EVP_PKEY *pkey, ULONG symmAlgId) -{ - ULONG rv; - switch (EVP_PKEY_id(pkey)) { - case EVP_PKEY_EC: - if ((rv = SKF_ImportECCPrivateKey(hDev, hContainer, - EVP_PKEY_get0_EC_KEY(pkey), symmAlgId)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); - return rv; - } - break; - case EVP_PKEY_RSA: - if ((rv = SKF_ImportRSAPrivateKey(hDev, hContainer, - EVP_PKEY_get0_RSA(pkey), symmAlgId)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); - return rv; - } - break; - default: - SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, - SKF_R_UNSUPPORTED_PRIVATE_KEY_TYPE); - return SAR_FAIL; - } - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **ec_key) -{ - ULONG rv; - ULONG containerType; - BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; - ECCPUBLICKEYBLOB *pubKey = (ECCPUBLICKEYBLOB *)pubKeyBlob; - ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); - - if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); - return rv; - } - if (containerType != SKF_CONTAINER_TYPE_ECC) { - SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); - return SAR_FAIL; - } - - if ((rv = SKF_ExportPublicKey(hContainer, bSign, - pubKeyBlob, &pubKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); - return rv; - } - if (pubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { - SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); - return SAR_FAIL; - } - - if (!(*ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pubKey))) { - SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_INVALID_ECC_PUBLIC_KEY); - return SAR_FAIL; - } - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **rsa) -{ - ULONG rv; - ULONG containerType; - BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; - RSAPUBLICKEYBLOB *pubKey = (RSAPUBLICKEYBLOB *)pubKeyBlob; - ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); - - if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); - return rv; - } - if (containerType != SKF_CONTAINER_TYPE_RSA) { - SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); - return SAR_FAIL; - } - - if ((rv = SKF_ExportPublicKey(hContainer, bSign, - pubKeyBlob, &pubKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); - return rv; - } - if (pubKeyLen != sizeof(RSAPUBLICKEYBLOB)) { - SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); - return SAR_FAIL; - } - - if (!(*rsa = RSA_new_from_RSAPUBLICKEYBLOB(pubKey))) { - SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_INVALID_RSA_PUBLIC_KEY); - return SAR_FAIL; - } - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp) -{ - ULONG rv; - ULONG containerType; - EVP_PKEY *pkey = NULL; - - if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); - return rv; - } - - if (!(pkey = EVP_PKEY_new())) { - SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_MALLOC_FAILURE); - return SAR_MEMORYERR; - } - - if (containerType == SKF_CONTAINER_TYPE_ECC) { - EC_KEY *ec_key = NULL; - if ((rv = SKF_ExportECCPublicKey(hContainer, bSign, - &ec_key)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); - goto end; - } - if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { - EC_KEY_free(ec_key); - rv = SAR_FAIL; - goto end; - } - - } else if (containerType == SKF_CONTAINER_TYPE_RSA) { - RSA *rsa = NULL; - if ((rv = SKF_ExportRSAPublicKey(hContainer, bSign, - &rsa)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); - goto end; - } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); - rv = SAR_FAIL; - goto end; - } - - } else { - SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, SKF_R_INVALID_CONTAINER_TYPE); - rv = SAR_FAIL; - goto end; - } - - *pp = pkey; - pkey = NULL; - rv = SAR_OK; - -end: - EVP_PKEY_free(pkey); - return rv; -} -#endif - -/* -ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509) -{ - int ret = 0; - ULONG containerType; - unsigned char *cert = NULL; - unsigned char *p; - int len; - - if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { - return 0; - } - if (containerType == SKF_CONTAINER_TYPE_UNDEF) { - return 0; - } - - switch (EVP_PKEY_id(X509_get0_pubkey(x509))) { - case EVP_PKEY_EC: - if (containerType != SKF_CONTAINER_TYPE_ECC) { - goto end; - } - if (!EC_KEY_is_sm2p256v1(EVP_PKEY_get0_EC_KEY(X509_get0_pubkey(x509)))) { - goto end; - } - break; - - case EVP_PKEY_RSA: - if (containerType != SKF_CONTAINER_TYPE_RSA) { - goto end; - } - break; - default: - goto end; - } - - if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| - KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { - bSign = SGD_TRUE; - } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| - KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { - bSign = SGD_FALSE; - } else { - goto end; - } - - if ((len = i2d_X509(x509, NULL)) <= 0 - || !(p = cert = malloc(len)) - || (len = i2d_X509(x509, &p)) <= 0) { - goto end; - } - - if (SKF_ImportCertificate(hContainer, bSign, cert, (ULONG)len) != SAR_OK) { - goto end; - } - - ret = 1; -end: - X509_free(x509); - OPENSSL_free(cert); - return ret; -} - -ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509) -{ - ULONG rv; - BOOL bSign; - - if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| - KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { - bSign = SGD_TRUE; - } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| - KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { - bSign = SGD_FALSE; - } else { - SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, - SKF_R_UNKNOWN_CERTIFICATE_KEYUSAGE); - return SAR_FAIL; - } - - if ((rv = SKF_ImportX509Certificate(hContainer, bSign, x509)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, ERR_R_SKF_LIB); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509) -{ - ULONG rv = SAR_FAIL; - BYTE *pbCert = NULL; - ULONG ulCertLen; - const unsigned char *p; - X509 *x509 = NULL; - - ulCertLen = SKF_MAX_CERTIFICATE_SIZE; - if (!(pbCert = malloc(ulCertLen))) { - SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_MALLOC_FAILURE); - rv = SAR_MEMORYERR; - goto end; - } - if ((rv = SKF_ExportCertificate(hContainer, bSign, - pbCert, &ulCertLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_SKF_LIB); - goto end; - } - - p = pbCert; - if (!(x509 = d2i_X509(NULL, &p, (long)ulCertLen))) { - SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, - SKF_R_PARSE_CERTIFICATE_FAILURE); - goto end; - } - if (p - pbCert != ulCertLen) { - SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, - SKF_R_PARSE_CERTIFICATE_FAILURE); - goto end; - } - - *px509 = x509; - x509 = NULL; - rv = SAR_OK; - -end: - OPENSSL_free(pbCert); - X509_free(x509); - return rv; -} -*/ + + +#include +#include +#include +#include +#include "skf_int.h" +#include "skf_ext.h" +#include "skf.h" + + +#define SKFerr(f,e) + +ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob) +{ + ECCCIPHERBLOB *ret = NULL; + + if (!(ret = malloc(sizeof(ECCCIPHERBLOB) - 1 + ulCipherLen))) { + SKFerr(SKF_F_SKF_NEWECCCIPHER, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + ret->CipherLen = ulCipherLen; + *cipherBlob = ret; + return SAR_OK; +} + +ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob) +{ + ENVELOPEDKEYBLOB *ret = NULL; + + if (!(ret = malloc(sizeof(ENVELOPEDKEYBLOB) - 1 + ulCipherLen))) { + SKFerr(SKF_F_SKF_NEWENVELOPEDKEY, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + ret->ECCCipherBlob.CipherLen = ulCipherLen; + *envelopedKeyBlob = ret; + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev) +{ + ULONG rv; + DEVHANDLE hDev = NULL; + HANDLE hKey = NULL; + ULONG ulTimeOut = 0xffffffff; + BYTE authRand[16] = {0}; + BYTE authData[16] = {0}; + ULONG authRandLen = SKF_AUTHRAND_LENGTH; + ULONG authDataLen = sizeof(authData); + BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; + + if ((rv = SKF_ConnectDev((LPSTR)devName, &hDev)) != SAR_OK + || (rv = SKF_GetDevInfo(hDev, devInfo)) != SAR_OK + || (rv = SKF_LockDev(hDev, ulTimeOut)) != SAR_OK + || (rv = SKF_GenRandom(hDev, authRand, authRandLen)) != SAR_OK + || (rv = SKF_SetSymmKey(hDev, authKey, devInfo->DevAuthAlgId, &hKey)) != SAR_OK + || (rv = SKF_EncryptInit(hKey, encParam)) != SAR_OK + || (rv = SKF_Encrypt(hKey, authRand, sizeof(authRand), authData, &authDataLen)) != SAR_OK + || (rv =SKF_DevAuth(hDev, authData, authDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + goto end; + } + *phDev = hDev; + hDev = NULL; + +end: + //OPENSSL_cleanse(authRand, sizeof(authRand)); + //OPENSSL_cleanse(authData, sizeof(authData)); + if (hKey && (rv = SKF_CloseHandle(hKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + } + if (hDev && (rv = SKF_DisConnectDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + } + return rv; +} + +ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev) +{ + ULONG rv; + if ((rv = SKF_UnlockDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); + } + if ((rv = SKF_DisConnectDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); + } + return rv; +} + +#if 0 +ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + EC_KEY *ec_key, ULONG symmAlgId) +{ + int ret = 0; + ULONG rv; + ULONG containerType; + ECCPRIVATEKEYBLOB eccPriKeyBlob; + BYTE symmKey[16]; + HANDLE hSymmKey = NULL; + BLOCKCIPHERPARAM encParam; + ULONG encedPriKeyLen; + SKF_PUBLICKEYBLOB signPubKeyBlob; + ULONG signPubKeyLen = sizeof(signPubKeyBlob); + ENVELOPEDKEYBLOB envelopedKeyBlob; + + /* check container type */ + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + /* get private key and public key */ + if (!EC_KEY_get_ECCPRIVATEKEYBLOB(ec_key, &eccPriKeyBlob) + || !EC_KEY_get_ECCPUBLICKEYBLOB(ec_key, &(envelopedKeyBlob.PubKey))) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_GMAPI_LIB); + rv = SAR_FAIL; + goto end; + } + + /* set Version, ulSymmAlgID, ulBits */ + envelopedKeyBlob.Version = SKF_ENVELOPEDKEYBLOB_VERSION; + envelopedKeyBlob.ulSymmAlgID = symmAlgId; + envelopedKeyBlob.ulBits = eccPriKeyBlob.BitLen; + + /* encrypt private key with random generated symmkey */ + if (!rand_bytes(symmKey, sizeof(symmKey))) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + if ((rv = SKF_SetSymmKey(hDev, symmKey, symmAlgId, &hSymmKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + encParam.IVLen = 0; + encParam.PaddingType = SKF_NO_PADDING; + if ((rv = SKF_EncryptInit(hSymmKey, encParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + encedPriKeyLen = sizeof(envelopedKeyBlob.cbEncryptedPriKey); + if ((rv = SKF_Encrypt(hSymmKey, + eccPriKeyBlob.PrivateKey, sizeof(eccPriKeyBlob.PrivateKey), + (BYTE *)&(envelopedKeyBlob.cbEncryptedPriKey), &encedPriKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (encedPriKeyLen != sizeof(eccPriKeyBlob.PrivateKey)) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + + /* encrypt symmKey */ + if ((rv = SKF_ExportPublicKey(hContainer, TRUE, + (BYTE *)&signPubKeyBlob, &signPubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (signPubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + if ((rv = SKF_ExtECCEncrypt(hDev, (ECCPUBLICKEYBLOB *)&signPubKeyBlob, + symmKey, sizeof(symmKey), &(envelopedKeyBlob.ECCCipherBlob))) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + + ret = 1; +end: + OPENSSL_cleanse(&eccPriKeyBlob, sizeof(eccPriKeyBlob)); + OPENSSL_cleanse(symmKey, sizeof(symmKey)); + if (hSymmKey && SKF_CloseHandle(hSymmKey) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + ret = 0; + } + return ret; +} + +ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + RSA *rsa, ULONG symmAlgId) +{ + ULONG rv; + ULONG containerType; + RSAPRIVATEKEYBLOB rsaPriKeyBlob; + unsigned char symmKey[16]; + RSAPUBLICKEYBLOB rsaPubKeyBlob; + ULONG rsaPubKeyLen = sizeof(rsaPubKeyBlob); + BYTE wrappedKey[MAX_RSA_MODULUS_LEN]; + ULONG wrappedKeyLen = sizeof(wrappedKey); + EVP_CIPHER_CTX *cctx = NULL; + unsigned char *p; + int len; + BYTE encedPriKey[sizeof(RSAPRIVATEKEYBLOB) + 16*2]; + ULONG encedPriKeyLen = sizeof(encedPriKey); + + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_RSA) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!RSA_get_RSAPRIVATEKEYBLOB(rsa, &rsaPriKeyBlob)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + + /* generate symmkey */ + /* wrap symmkey with signing public key */ + if (!rand_bytes(symmKey, sizeof(symmKey))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if ((rv = SKF_ExportPublicKey(hContainer, SGD_TRUE, + (BYTE *)&rsaPubKeyBlob, &rsaPubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (!(rsa = RSA_new_from_RSAPUBLICKEYBLOB(&rsaPubKeyBlob))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if ((len = RSA_public_encrypt(sizeof(symmKey), symmKey, wrappedKey, + rsa, RSA_PKCS1_PADDING)) != rsaPriKeyBlob.BitLen / 8) { + goto end; + } + wrappedKeyLen = (ULONG)len; + + /* encrypt private key with symmkey in ECB mode */ + if (!(cctx = EVP_CIPHER_CTX_new())) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!EVP_EncryptInit_ex(cctx, EVP_sms4_ecb(), NULL, symmKey, NULL)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p = encedPriKey; + if (!EVP_EncryptUpdate(cctx, p, &len, (unsigned char *)&rsaPriKeyBlob, + sizeof(RSAPRIVATEKEYBLOB))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p += len; + if (!EVP_EncryptFinal_ex(cctx, p, &len)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p += len; + encedPriKeyLen = p - encedPriKey; + + /* import */ + if ((rv = SKF_ImportRSAKeyPair(hContainer, symmAlgId, wrappedKey, wrappedKeyLen, + encedPriKey, encedPriKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + +end: + OPENSSL_cleanse(&rsaPriKeyBlob, sizeof(rsaPriKeyBlob)); + OPENSSL_cleanse(symmKey, sizeof(symmKey)); + OPENSSL_cleanse(wrappedKey, sizeof(wrappedKey)); + EVP_CIPHER_CTX_free(cctx); + return rv; +} + +ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + EVP_PKEY *pkey, ULONG symmAlgId) +{ + ULONG rv; + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_EC: + if ((rv = SKF_ImportECCPrivateKey(hDev, hContainer, + EVP_PKEY_get0_EC_KEY(pkey), symmAlgId)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + break; + case EVP_PKEY_RSA: + if ((rv = SKF_ImportRSAPrivateKey(hDev, hContainer, + EVP_PKEY_get0_RSA(pkey), symmAlgId)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + break; + default: + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, + SKF_R_UNSUPPORTED_PRIVATE_KEY_TYPE); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **ec_key) +{ + ULONG rv; + ULONG containerType; + BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; + ECCPUBLICKEYBLOB *pubKey = (ECCPUBLICKEYBLOB *)pubKeyBlob; + ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + if ((rv = SKF_ExportPublicKey(hContainer, bSign, + pubKeyBlob, &pubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (pubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!(*ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pubKey))) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_INVALID_ECC_PUBLIC_KEY); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **rsa) +{ + ULONG rv; + ULONG containerType; + BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; + RSAPUBLICKEYBLOB *pubKey = (RSAPUBLICKEYBLOB *)pubKeyBlob; + ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_RSA) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + if ((rv = SKF_ExportPublicKey(hContainer, bSign, + pubKeyBlob, &pubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (pubKeyLen != sizeof(RSAPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!(*rsa = RSA_new_from_RSAPUBLICKEYBLOB(pubKey))) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_INVALID_RSA_PUBLIC_KEY); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp) +{ + ULONG rv; + ULONG containerType; + EVP_PKEY *pkey = NULL; + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + + if (!(pkey = EVP_PKEY_new())) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + if (containerType == SKF_CONTAINER_TYPE_ECC) { + EC_KEY *ec_key = NULL; + if ((rv = SKF_ExportECCPublicKey(hContainer, bSign, + &ec_key)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + goto end; + } + if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { + EC_KEY_free(ec_key); + rv = SAR_FAIL; + goto end; + } + + } else if (containerType == SKF_CONTAINER_TYPE_RSA) { + RSA *rsa = NULL; + if ((rv = SKF_ExportRSAPublicKey(hContainer, bSign, + &rsa)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + goto end; + } + if (!EVP_PKEY_assign_RSA(pkey, rsa)) { + RSA_free(rsa); + rv = SAR_FAIL; + goto end; + } + + } else { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, SKF_R_INVALID_CONTAINER_TYPE); + rv = SAR_FAIL; + goto end; + } + + *pp = pkey; + pkey = NULL; + rv = SAR_OK; + +end: + EVP_PKEY_free(pkey); + return rv; +} +#endif + +/* +ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509) +{ + int ret = 0; + ULONG containerType; + unsigned char *cert = NULL; + unsigned char *p; + int len; + + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + return 0; + } + if (containerType == SKF_CONTAINER_TYPE_UNDEF) { + return 0; + } + + switch (EVP_PKEY_id(X509_get0_pubkey(x509))) { + case EVP_PKEY_EC: + if (containerType != SKF_CONTAINER_TYPE_ECC) { + goto end; + } + if (!EC_KEY_is_sm2p256v1(EVP_PKEY_get0_EC_KEY(X509_get0_pubkey(x509)))) { + goto end; + } + break; + + case EVP_PKEY_RSA: + if (containerType != SKF_CONTAINER_TYPE_RSA) { + goto end; + } + break; + default: + goto end; + } + + if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| + KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { + bSign = SGD_TRUE; + } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| + KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { + bSign = SGD_FALSE; + } else { + goto end; + } + + if ((len = i2d_X509(x509, NULL)) <= 0 + || !(p = cert = malloc(len)) + || (len = i2d_X509(x509, &p)) <= 0) { + goto end; + } + + if (SKF_ImportCertificate(hContainer, bSign, cert, (ULONG)len) != SAR_OK) { + goto end; + } + + ret = 1; +end: + X509_free(x509); + OPENSSL_free(cert); + return ret; +} + +ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509) +{ + ULONG rv; + BOOL bSign; + + if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| + KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { + bSign = SGD_TRUE; + } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| + KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { + bSign = SGD_FALSE; + } else { + SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, + SKF_R_UNKNOWN_CERTIFICATE_KEYUSAGE); + return SAR_FAIL; + } + + if ((rv = SKF_ImportX509Certificate(hContainer, bSign, x509)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, ERR_R_SKF_LIB); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509) +{ + ULONG rv = SAR_FAIL; + BYTE *pbCert = NULL; + ULONG ulCertLen; + const unsigned char *p; + X509 *x509 = NULL; + + ulCertLen = SKF_MAX_CERTIFICATE_SIZE; + if (!(pbCert = malloc(ulCertLen))) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_MALLOC_FAILURE); + rv = SAR_MEMORYERR; + goto end; + } + if ((rv = SKF_ExportCertificate(hContainer, bSign, + pbCert, &ulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_SKF_LIB); + goto end; + } + + p = pbCert; + if (!(x509 = d2i_X509(NULL, &p, (long)ulCertLen))) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, + SKF_R_PARSE_CERTIFICATE_FAILURE); + goto end; + } + if (p - pbCert != ulCertLen) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, + SKF_R_PARSE_CERTIFICATE_FAILURE); + goto end; + } + + *px509 = x509; + x509 = NULL; + rv = SAR_OK; + +end: + OPENSSL_free(pbCert); + X509_free(x509); + return rv; +} +*/ diff --git a/src/skf/skf_ext.h b/src/skf/skf_ext.h index 69506af5..146e9fa1 100644 --- a/src/skf/skf_ext.h +++ b/src/skf/skf_ext.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,88 +7,89 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef SKFUTIL_SKF_EXT_H -#define SKFUTIL_SKF_EXT_H - - -#include -#include "skf.h" - - -#define SKF_NO_PADDING 0 -#define SKF_PKCS5_PADDING 1 - -#define SKF_DEV_STATE_ABSENT 0x00000000 -#define SKF_DEV_STATE_PRESENT 0x00000001 -#define SKF_DEV_STATE_UNKNOW 0x00000010 - -#define SKF_CONTAINER_TYPE_UNDEF 0 -#define SKF_CONTAINER_TYPE_RSA 1 -#define SKF_CONTAINER_TYPE_ECC 2 - -#define SKF_ENVELOPEDKEYBLOB_VERSION 1 -#define SKF_AUTHKEY_LENGTH 16 -#define SKF_AUTHRAND_LENGTH 16 -#define SKF_MAX_FILE_SIZE (256*1024) -#define SKF_MAX_CERTIFICATE_SIZE (8*1024) - - -#define SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT 6 -#define SKF_DEFAULT_USER_PIN_RETRY_COUNT 6 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - union { - ECCPUBLICKEYBLOB ecc; - RSAPUBLICKEYBLOB rsa; - } u; -} SKF_PUBLICKEYBLOB; -#define SKF_MAX_PUBLICKEYBOLB_LENGTH sizeof(SKF_PUBLICKEYBLOB) - -typedef struct { - char *name; - unsigned char *buf; - int offset; - int length; -} SKF_FILE_OP_PARAMS; - - -ULONG DEVAPI SKF_LoadLibrary(LPSTR so_path, LPSTR vendor); -ULONG DEVAPI SKF_UnloadLibrary(void); -ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev); -ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev); -ULONG DEVAPI SKF_GetDevStateName(ULONG ulDevState, LPSTR *szName); -ULONG DEVAPI SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName); -ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName); -ULONG DEVAPI SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo); -ULONG DEVAPI SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob); -ULONG DEVAPI SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob); -ULONG DEVAPI SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob); -ULONG DEVAPI SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob); -ULONG DEVAPI SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob); -ULONG DEVAPI SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob); -ULONG DEVAPI SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr); -ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob); -ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob); - -/* -ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EC_KEY *ec_key, ULONG symmAlgId); -ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, RSA *rsa, ULONG symmAlgId); -ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EVP_PKEY *pkey, ULONG symmAlgId); -ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **pp); -ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **pp); -ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp); -ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509); -ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509); -ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509); -*/ - - -#ifdef __cplusplus -} -#endif -#endif + + +#ifndef SKFUTIL_SKF_EXT_H +#define SKFUTIL_SKF_EXT_H + + +#include +#include "skf.h" + + +#define SKF_NO_PADDING 0 +#define SKF_PKCS5_PADDING 1 + +#define SKF_DEV_STATE_ABSENT 0x00000000 +#define SKF_DEV_STATE_PRESENT 0x00000001 +#define SKF_DEV_STATE_UNKNOW 0x00000010 + +#define SKF_CONTAINER_TYPE_UNDEF 0 +#define SKF_CONTAINER_TYPE_RSA 1 +#define SKF_CONTAINER_TYPE_ECC 2 + +#define SKF_ENVELOPEDKEYBLOB_VERSION 1 +#define SKF_AUTHKEY_LENGTH 16 +#define SKF_AUTHRAND_LENGTH 16 +#define SKF_MAX_FILE_SIZE (256*1024) +#define SKF_MAX_CERTIFICATE_SIZE (8*1024) + + +#define SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT 6 +#define SKF_DEFAULT_USER_PIN_RETRY_COUNT 6 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + union { + ECCPUBLICKEYBLOB ecc; + RSAPUBLICKEYBLOB rsa; + } u; +} SKF_PUBLICKEYBLOB; +#define SKF_MAX_PUBLICKEYBOLB_LENGTH sizeof(SKF_PUBLICKEYBLOB) + +typedef struct { + char *name; + unsigned char *buf; + int offset; + int length; +} SKF_FILE_OP_PARAMS; + + +ULONG DEVAPI SKF_LoadLibrary(LPSTR so_path, LPSTR vendor); +ULONG DEVAPI SKF_UnloadLibrary(void); +ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev); +ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev); +ULONG DEVAPI SKF_GetDevStateName(ULONG ulDevState, LPSTR *szName); +ULONG DEVAPI SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName); +ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName); +ULONG DEVAPI SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo); +ULONG DEVAPI SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob); +ULONG DEVAPI SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob); +ULONG DEVAPI SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob); +ULONG DEVAPI SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr); +ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob); +ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob); + +/* +ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EC_KEY *ec_key, ULONG symmAlgId); +ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, RSA *rsa, ULONG symmAlgId); +ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EVP_PKEY *pkey, ULONG symmAlgId); +ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **pp); +ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **pp); +ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp); +ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509); +ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509); +ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509); +*/ + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/skf/skf_int.h b/src/skf/skf_int.h index ff3b4a78..b14299f8 100644 --- a/src/skf/skf_int.h +++ b/src/skf/skf_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,572 +7,573 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef SKFUTIL_SKF_INT_H -#define SKFUTIL_SKF_INT_H - -#include "../sgd.h" -#include "skf.h" - - -typedef ULONG (DEVAPI *SKF_WaitForDevEvent_FuncPtr)( - LPSTR szDevName, - ULONG *pulDevNameLen, - ULONG *pulEvent); - -typedef ULONG (DEVAPI *SKF_CancelWaitForDevEvent_FuncPtr)( - void); - -typedef ULONG (DEVAPI *SKF_EnumDev_FuncPtr)( - BOOL bPresent, - LPSTR szNameList, - ULONG *pulSize); - -typedef ULONG (DEVAPI *SKF_ConnectDev_FuncPtr)( - LPSTR szName, - DEVHANDLE *phDev); - -typedef ULONG (DEVAPI *SKF_DisConnectDev_FuncPtr)( - DEVHANDLE hDev); - -typedef ULONG (DEVAPI *SKF_GetDevState_FuncPtr)( - LPSTR szDevName, - ULONG *pulDevState); - -typedef ULONG (DEVAPI *SKF_SetLabel_FuncPtr)( - DEVHANDLE hDev, - LPSTR szLabel); - -typedef ULONG (DEVAPI *SKF_GetDevInfo_FuncPtr)( - DEVHANDLE hDev, - DEVINFO *pDevInfo); - -typedef ULONG (DEVAPI *SKF_LockDev_FuncPtr)( - DEVHANDLE hDev, - ULONG ulTimeOut); - -typedef ULONG (DEVAPI *SKF_UnlockDev_FuncPtr)( - DEVHANDLE hDev); - -typedef ULONG (DEVAPI *SKF_Transmit_FuncPtr)( - DEVHANDLE hDev, - BYTE *pbCommand, - ULONG ulCommandLen, - BYTE *pbData, - ULONG *pulDataLen); - -typedef ULONG (DEVAPI *SKF_ChangeDevAuthKey_FuncPtr)( - DEVHANDLE hDev, - BYTE *pbKeyValue, - ULONG ulKeyLen); - -typedef ULONG (DEVAPI *SKF_DevAuth_FuncPtr)( - DEVHANDLE hDev, - BYTE *pbAuthData, - ULONG ulLen); - -typedef ULONG (DEVAPI *SKF_ChangePIN_FuncPtr)( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szOldPin, - LPSTR szNewPin, - ULONG *pulRetryCount); - -typedef LONG (DEVAPI *SKF_GetPINInfo_FuncPtr)( - HAPPLICATION hApplication, - ULONG ulPINType, - ULONG *pulMaxRetryCount, - ULONG *pulRemainRetryCount, - BOOL *pbDefaultPin); - -typedef ULONG (DEVAPI *SKF_VerifyPIN_FuncPtr)( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szPIN, - ULONG *pulRetryCount); - -typedef ULONG (DEVAPI *SKF_UnblockPIN_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szAdminPIN, - LPSTR szNewUserPIN, - ULONG *pulRetryCount); - -typedef ULONG (DEVAPI *SKF_ClearSecureState_FuncPtr)( - HAPPLICATION hApplication); - -typedef ULONG (DEVAPI *SKF_CreateApplication_FuncPtr)( - DEVHANDLE hDev, - LPSTR szAppName, - LPSTR szAdminPin, - DWORD dwAdminPinRetryCount, - LPSTR szUserPin, - DWORD dwUserPinRetryCount, - DWORD dwCreateFileRights, - HAPPLICATION *phApplication); - -typedef ULONG (DEVAPI *SKF_EnumApplication_FuncPtr)( - DEVHANDLE hDev, - LPSTR szAppName, - ULONG *pulSize); - -typedef ULONG (DEVAPI *SKF_DeleteApplication_FuncPtr)( - DEVHANDLE hDev, - LPSTR szAppName); - -typedef ULONG (DEVAPI *SKF_OpenApplication_FuncPtr)( - DEVHANDLE hDev, - LPSTR szAppName, - HAPPLICATION *phApplication); - -typedef ULONG (DEVAPI *SKF_CloseApplication_FuncPtr)( - HAPPLICATION hApplication); - -typedef ULONG (DEVAPI *SKF_CreateObject_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulFileSize, - ULONG ulReadRights, - ULONG ulWriteRights); - -typedef ULONG (DEVAPI *SKF_DeleteObject_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileName); - -typedef ULONG (DEVAPI *SKF_EnumObjects_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileList, - ULONG *pulSize); - -typedef ULONG (DEVAPI *SKF_GetObjectInfo_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileName, - FILEATTRIBUTE *pFileInfo); - -typedef ULONG (DEVAPI *SKF_ReadObject_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - ULONG ulSize, - BYTE *pbOutData, - ULONG *pulOutLen); - -typedef ULONG (DEVAPI *SKF_WriteObject_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - BYTE *pbData, - ULONG ulSize); - -typedef ULONG (DEVAPI *SKF_CreateContainer_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer); - -typedef ULONG (DEVAPI *SKF_DeleteContainer_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szContainerName); - -typedef ULONG (DEVAPI *SKF_EnumContainer_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szContainerName, - ULONG *pulSize); - -typedef ULONG (DEVAPI *SKF_OpenContainer_FuncPtr)( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer); - -typedef ULONG (DEVAPI *SKF_CloseContainer_FuncPtr)( - HCONTAINER hContainer); - -typedef ULONG (DEVAPI *SKF_GetContainerType_FuncPtr)( - HCONTAINER hContainer, - ULONG *pulContainerType); - -typedef ULONG (DEVAPI *SKF_ImportCertificate_FuncPtr)( - HCONTAINER hContainer, - BOOL bExportSignKey, - BYTE *pbCert, - ULONG ulCertLen); - -typedef ULONG (DEVAPI *SKF_ExportCertificate_FuncPtr)( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbCert, - ULONG *pulCertLen); - -typedef ULONG (DEVAPI *SKF_ExportPublicKey_FuncPtr)( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbBlob, - ULONG *pulBlobLen); - -typedef ULONG (DEVAPI *SKF_GenRandom_FuncPtr)( - DEVHANDLE hDev, - BYTE *pbRandom, - ULONG ulRandomLen); - -typedef ULONG (DEVAPI *SKF_GenExtRSAKey_FuncPtr)( - DEVHANDLE hDev, - ULONG ulBitsLen, - RSAPRIVATEKEYBLOB *pBlob); - -typedef ULONG (DEVAPI *SKF_GenRSAKeyPair_FuncPtr)( - HCONTAINER hContainer, - ULONG ulBitsLen, - RSAPUBLICKEYBLOB *pBlob); - -typedef ULONG (DEVAPI *SKF_ImportRSAKeyPair_FuncPtr)( - HCONTAINER hContainer, - ULONG ulSymAlgId, - BYTE *pbWrappedKey, - ULONG ulWrappedKeyLen, - BYTE *pbEncryptedData, - ULONG ulEncryptedDataLen); - -typedef ULONG (DEVAPI *SKF_RSASignData_FuncPtr)( - HCONTAINER hContainer, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG *pulSignLen); - -typedef ULONG (DEVAPI *SKF_RSAVerify_FuncPtr)( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG ulSignLen); - -typedef ULONG (DEVAPI *SKF_RSAExportSessionKey_FuncPtr)( - HCONTAINER hContainer, - ULONG ulAlgId, - RSAPUBLICKEYBLOB *pPubKey, - BYTE *pbData, - ULONG *pulDataLen, - HANDLE *phSessionKey); - -typedef ULONG (DEVAPI *SKF_ExtRSAPubKeyOperation_FuncPtr)( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen); - -typedef ULONG (DEVAPI *SKF_ExtRSAPriKeyOperation_FuncPtr)( - DEVHANDLE hDev, - RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen); - -typedef ULONG (DEVAPI *SKF_GenECCKeyPair_FuncPtr)( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pBlob); - -typedef ULONG (DEVAPI *SKF_ImportECCKeyPair_FuncPtr)( - HCONTAINER hContainer, - ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); - -typedef ULONG (DEVAPI *SKF_ECCSignData_FuncPtr)( - HCONTAINER hContainer, - BYTE *pbDigest, - ULONG ulDigestLen, - ECCSIGNATUREBLOB *pSignature); - -typedef ULONG (DEVAPI *SKF_ECCVerify_FuncPtr)( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -typedef ULONG (DEVAPI *SKF_ECCExportSessionKey_FuncPtr)( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pPubKey, - ECCCIPHERBLOB *pData, - HANDLE *phSessionKey); - -typedef ULONG (DEVAPI *SKF_ExtECCEncrypt_FuncPtr)( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbPlainText, - ULONG ulPlainTextLen, - ECCCIPHERBLOB *pCipherText); - -typedef ULONG (DEVAPI *SKF_ECCDecrypt_FuncPtr)( - HCONTAINER hContainer, - ECCCIPHERBLOB *pCipherText, - BYTE *pbPlainText, - ULONG *pulPlainTextLen); - -typedef ULONG (DEVAPI *SKF_ExtECCDecrypt_FuncPtr)( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - ECCCIPHERBLOB *pCipherText, - BYTE *pbPlainText, - ULONG *pulPlainTextLen); - -typedef ULONG (DEVAPI *SKF_ExtECCSign_FuncPtr)( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -typedef ULONG (DEVAPI *SKF_ExtECCVerify_FuncPtr)( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature); - -typedef ULONG (DEVAPI *SKF_GenerateAgreementDataWithECC_FuncPtr)( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phAgreementHandle); - -typedef ULONG (DEVAPI *SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr)( - HANDLE hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, - ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - BYTE *pbSponsorID, - ULONG ulSponsorIDLen, - HANDLE *phKeyHandle); - -typedef ULONG (DEVAPI *SKF_GenerateKeyWithECC_FuncPtr)( - HANDLE hAgreementHandle, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phKeyHandle); - -typedef ULONG (DEVAPI *SKF_ImportSessionKey_FuncPtr)( - HCONTAINER hContainer, - ULONG ulAlgId, - BYTE *pbWrapedData, - ULONG ulWrapedLen, - HANDLE *phKey); - -typedef ULONG (DEVAPI *SKF_SetSymmKey_FuncPtr)( - DEVHANDLE hDev, - BYTE *pbKey, - ULONG ulAlgID, - HANDLE *phKey); - -typedef ULONG (DEVAPI *SKF_EncryptInit_FuncPtr)( - HANDLE hKey, - BLOCKCIPHERPARAM EncryptParam); - -typedef ULONG (DEVAPI *SKF_Encrypt_FuncPtr)( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen); - -typedef ULONG (DEVAPI *SKF_EncryptUpdate_FuncPtr)( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen); - -typedef ULONG (DEVAPI *SKF_EncryptFinal_FuncPtr)( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG *pulEncryptedDataLen); - -typedef ULONG (DEVAPI *SKF_DecryptInit_FuncPtr)( - HANDLE hKey, - BLOCKCIPHERPARAM DecryptParam); - -typedef ULONG (DEVAPI *SKF_Decrypt_FuncPtr)( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen); - -typedef ULONG (DEVAPI *SKF_DecryptUpdate_FuncPtr)( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen); - -typedef ULONG (DEVAPI *SKF_DecryptFinal_FuncPtr)( - HANDLE hKey, - BYTE *pbDecryptedData, - ULONG *pulDecryptedDataLen); - -typedef ULONG (DEVAPI *SKF_DigestInit_FuncPtr)( - DEVHANDLE hDev, - ULONG ulAlgID, - ECCPUBLICKEYBLOB *pPubKey, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phHash); - -typedef ULONG (DEVAPI *SKF_Digest_FuncPtr)( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbHashData, - ULONG *pulHashLen); - -typedef ULONG (DEVAPI *SKF_DigestUpdate_FuncPtr)( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen); - -typedef ULONG (DEVAPI *SKF_DigestFinal_FuncPtr)( - HANDLE hHash, - BYTE *pHashData, - ULONG *pulHashLen); - -typedef ULONG (DEVAPI *SKF_MacInit_FuncPtr)( - HANDLE hKey, - BLOCKCIPHERPARAM *pMacParam, - HANDLE *phMac); - -typedef ULONG (DEVAPI *SKF_Mac_FuncPtr)( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbMacData, - ULONG *pulMacLen); - -typedef ULONG (DEVAPI *SKF_MacUpdate_FuncPtr)( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen); - -typedef ULONG (DEVAPI *SKF_MacFinal_FuncPtr)( - HANDLE hMac, - BYTE *pbMacData, - ULONG *pulMacDataLen); - -typedef ULONG (DEVAPI *SKF_CloseHandle_FuncPtr)( - HANDLE hHandle); - - -typedef struct skf_method_st { - char *name; - void *dso; - SKF_WaitForDevEvent_FuncPtr WaitForDevEvent; - SKF_CancelWaitForDevEvent_FuncPtr CancelWaitForDevEvent; - SKF_EnumDev_FuncPtr EnumDev; - SKF_ConnectDev_FuncPtr ConnectDev; - SKF_DisConnectDev_FuncPtr DisConnectDev; - SKF_GetDevState_FuncPtr GetDevState; - SKF_SetLabel_FuncPtr SetLabel; - SKF_GetDevInfo_FuncPtr GetDevInfo; - SKF_LockDev_FuncPtr LockDev; - SKF_UnlockDev_FuncPtr UnlockDev; - SKF_Transmit_FuncPtr Transmit; - SKF_ChangeDevAuthKey_FuncPtr ChangeDevAuthKey; - SKF_DevAuth_FuncPtr DevAuth; - SKF_ChangePIN_FuncPtr ChangePIN; - SKF_GetPINInfo_FuncPtr GetPINInfo; - SKF_VerifyPIN_FuncPtr VerifyPIN; - SKF_UnblockPIN_FuncPtr UnblockPIN; - SKF_ClearSecureState_FuncPtr ClearSecureState; - SKF_CreateApplication_FuncPtr CreateApplication; - SKF_EnumApplication_FuncPtr EnumApplication; - SKF_DeleteApplication_FuncPtr DeleteApplication; - SKF_OpenApplication_FuncPtr OpenApplication; - SKF_CloseApplication_FuncPtr CloseApplication; - SKF_CreateObject_FuncPtr CreateObject; - SKF_DeleteObject_FuncPtr DeleteObject; - SKF_EnumObjects_FuncPtr EnumObjects; - SKF_GetObjectInfo_FuncPtr GetObjectInfo; - SKF_ReadObject_FuncPtr ReadObject; - SKF_WriteObject_FuncPtr WriteObject; - SKF_CreateContainer_FuncPtr CreateContainer; - SKF_DeleteContainer_FuncPtr DeleteContainer; - SKF_EnumContainer_FuncPtr EnumContainer; - SKF_OpenContainer_FuncPtr OpenContainer; - SKF_CloseContainer_FuncPtr CloseContainer; - SKF_GetContainerType_FuncPtr GetContainerType; - SKF_ImportCertificate_FuncPtr ImportCertificate; - SKF_ExportCertificate_FuncPtr ExportCertificate; - SKF_ExportPublicKey_FuncPtr ExportPublicKey; - SKF_GenRandom_FuncPtr GenRandom; - SKF_GenExtRSAKey_FuncPtr GenExtRSAKey; - SKF_GenRSAKeyPair_FuncPtr GenRSAKeyPair; - SKF_ImportRSAKeyPair_FuncPtr ImportRSAKeyPair; - SKF_RSASignData_FuncPtr RSASignData; - SKF_RSAVerify_FuncPtr RSAVerify; - SKF_RSAExportSessionKey_FuncPtr RSAExportSessionKey; - SKF_ExtRSAPubKeyOperation_FuncPtr ExtRSAPubKeyOperation; - SKF_ExtRSAPriKeyOperation_FuncPtr ExtRSAPriKeyOperation; - SKF_GenECCKeyPair_FuncPtr GenECCKeyPair; - SKF_ImportECCKeyPair_FuncPtr ImportECCKeyPair; - SKF_ECCSignData_FuncPtr ECCSignData; - SKF_ECCVerify_FuncPtr ECCVerify; - SKF_ECCExportSessionKey_FuncPtr ECCExportSessionKey; - SKF_ExtECCEncrypt_FuncPtr ExtECCEncrypt; - SKF_ExtECCDecrypt_FuncPtr ExtECCDecrypt; - SKF_ECCDecrypt_FuncPtr ECCDecrypt; - SKF_ExtECCSign_FuncPtr ExtECCSign; - SKF_ExtECCVerify_FuncPtr ExtECCVerify; - SKF_GenerateAgreementDataWithECC_FuncPtr GenerateAgreementDataWithECC; - SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr GenerateAgreementDataAndKeyWithECC; - SKF_GenerateKeyWithECC_FuncPtr GenerateKeyWithECC; - SKF_ImportSessionKey_FuncPtr ImportSessionKey; - SKF_SetSymmKey_FuncPtr SetSymmKey; - SKF_EncryptInit_FuncPtr EncryptInit; - SKF_Encrypt_FuncPtr Encrypt; - SKF_EncryptUpdate_FuncPtr EncryptUpdate; - SKF_EncryptFinal_FuncPtr EncryptFinal; - SKF_DecryptInit_FuncPtr DecryptInit; - SKF_Decrypt_FuncPtr Decrypt; - SKF_DecryptUpdate_FuncPtr DecryptUpdate; - SKF_DecryptFinal_FuncPtr DecryptFinal; - SKF_DigestInit_FuncPtr DigestInit; - SKF_Digest_FuncPtr Digest; - SKF_DigestUpdate_FuncPtr DigestUpdate; - SKF_DigestFinal_FuncPtr DigestFinal; - SKF_MacInit_FuncPtr MacInit; - SKF_Mac_FuncPtr Mac; - SKF_MacUpdate_FuncPtr MacUpdate; - SKF_MacFinal_FuncPtr MacFinal; - SKF_CloseHandle_FuncPtr CloseHandle; -} SKF_METHOD; - -SKF_METHOD *SKF_METHOD_load_library(const char *so_path); -void SKF_METHOD_free(SKF_METHOD *meth); - - -typedef struct skf_vendor_st { - char *name; - unsigned int authrand_length; - ULONG (*get_cipher_algor)(ULONG vendor_id); - ULONG (*get_cipher_cap)(ULONG vendor_cap); - ULONG (*get_digest_algor)(ULONG vendor_id); - ULONG (*get_digest_cap)(ULONG vendor_cap); - ULONG (*get_pkey_algor)(ULONG vendor_id); - ULONG (*get_pkey_cap)(ULONG vendor_cap); - unsigned long (*get_error_reason)(ULONG err); -} SKF_VENDOR; - -typedef struct { - ULONG err; - unsigned long reason; -} SKF_ERR_REASON; - -#endif + + +#ifndef SKFUTIL_SKF_INT_H +#define SKFUTIL_SKF_INT_H + +#include "../sgd.h" +#include "skf.h" + + +typedef ULONG (DEVAPI *SKF_WaitForDevEvent_FuncPtr)( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent); + +typedef ULONG (DEVAPI *SKF_CancelWaitForDevEvent_FuncPtr)( + void); + +typedef ULONG (DEVAPI *SKF_EnumDev_FuncPtr)( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_ConnectDev_FuncPtr)( + LPSTR szName, + DEVHANDLE *phDev); + +typedef ULONG (DEVAPI *SKF_DisConnectDev_FuncPtr)( + DEVHANDLE hDev); + +typedef ULONG (DEVAPI *SKF_GetDevState_FuncPtr)( + LPSTR szDevName, + ULONG *pulDevState); + +typedef ULONG (DEVAPI *SKF_SetLabel_FuncPtr)( + DEVHANDLE hDev, + LPSTR szLabel); + +typedef ULONG (DEVAPI *SKF_GetDevInfo_FuncPtr)( + DEVHANDLE hDev, + DEVINFO *pDevInfo); + +typedef ULONG (DEVAPI *SKF_LockDev_FuncPtr)( + DEVHANDLE hDev, + ULONG ulTimeOut); + +typedef ULONG (DEVAPI *SKF_UnlockDev_FuncPtr)( + DEVHANDLE hDev); + +typedef ULONG (DEVAPI *SKF_Transmit_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_ChangeDevAuthKey_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen); + +typedef ULONG (DEVAPI *SKF_DevAuth_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen); + +typedef ULONG (DEVAPI *SKF_ChangePIN_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount); + +typedef LONG (DEVAPI *SKF_GetPINInfo_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin); + +typedef ULONG (DEVAPI *SKF_VerifyPIN_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount); + +typedef ULONG (DEVAPI *SKF_UnblockPIN_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount); + +typedef ULONG (DEVAPI *SKF_ClearSecureState_FuncPtr)( + HAPPLICATION hApplication); + +typedef ULONG (DEVAPI *SKF_CreateApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication); + +typedef ULONG (DEVAPI *SKF_EnumApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_DeleteApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName); + +typedef ULONG (DEVAPI *SKF_OpenApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication); + +typedef ULONG (DEVAPI *SKF_CloseApplication_FuncPtr)( + HAPPLICATION hApplication); + +typedef ULONG (DEVAPI *SKF_CreateObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights); + +typedef ULONG (DEVAPI *SKF_DeleteObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName); + +typedef ULONG (DEVAPI *SKF_EnumObjects_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_GetObjectInfo_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo); + +typedef ULONG (DEVAPI *SKF_ReadObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen); + +typedef ULONG (DEVAPI *SKF_WriteObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize); + +typedef ULONG (DEVAPI *SKF_CreateContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +typedef ULONG (DEVAPI *SKF_DeleteContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName); + +typedef ULONG (DEVAPI *SKF_EnumContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_OpenContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +typedef ULONG (DEVAPI *SKF_CloseContainer_FuncPtr)( + HCONTAINER hContainer); + +typedef ULONG (DEVAPI *SKF_GetContainerType_FuncPtr)( + HCONTAINER hContainer, + ULONG *pulContainerType); + +typedef ULONG (DEVAPI *SKF_ImportCertificate_FuncPtr)( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen); + +typedef ULONG (DEVAPI *SKF_ExportCertificate_FuncPtr)( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen); + +typedef ULONG (DEVAPI *SKF_ExportPublicKey_FuncPtr)( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen); + +typedef ULONG (DEVAPI *SKF_GenRandom_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen); + +typedef ULONG (DEVAPI *SKF_GenExtRSAKey_FuncPtr)( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_GenRSAKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_ImportRSAKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen); + +typedef ULONG (DEVAPI *SKF_RSASignData_FuncPtr)( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen); + +typedef ULONG (DEVAPI *SKF_RSAVerify_FuncPtr)( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen); + +typedef ULONG (DEVAPI *SKF_RSAExportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey); + +typedef ULONG (DEVAPI *SKF_ExtRSAPubKeyOperation_FuncPtr)( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +typedef ULONG (DEVAPI *SKF_ExtRSAPriKeyOperation_FuncPtr)( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +typedef ULONG (DEVAPI *SKF_GenECCKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_ImportECCKeyPair_FuncPtr)( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); + +typedef ULONG (DEVAPI *SKF_ECCSignData_FuncPtr)( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ECCVerify_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ECCExportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey); + +typedef ULONG (DEVAPI *SKF_ExtECCEncrypt_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText); + +typedef ULONG (DEVAPI *SKF_ECCDecrypt_FuncPtr)( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +typedef ULONG (DEVAPI *SKF_ExtECCDecrypt_FuncPtr)( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +typedef ULONG (DEVAPI *SKF_ExtECCSign_FuncPtr)( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ExtECCVerify_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_GenerateAgreementDataWithECC_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle); + +typedef ULONG (DEVAPI *SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr)( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle); + +typedef ULONG (DEVAPI *SKF_GenerateKeyWithECC_FuncPtr)( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle); + +typedef ULONG (DEVAPI *SKF_ImportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey); + +typedef ULONG (DEVAPI *SKF_SetSymmKey_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey); + +typedef ULONG (DEVAPI *SKF_EncryptInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam); + +typedef ULONG (DEVAPI *SKF_Encrypt_FuncPtr)( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +typedef ULONG (DEVAPI *SKF_EncryptUpdate_FuncPtr)( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +typedef ULONG (DEVAPI *SKF_EncryptFinal_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam); + +typedef ULONG (DEVAPI *SKF_Decrypt_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptUpdate_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptFinal_FuncPtr)( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen); + +typedef ULONG (DEVAPI *SKF_DigestInit_FuncPtr)( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash); + +typedef ULONG (DEVAPI *SKF_Digest_FuncPtr)( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen); + +typedef ULONG (DEVAPI *SKF_DigestUpdate_FuncPtr)( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen); + +typedef ULONG (DEVAPI *SKF_DigestFinal_FuncPtr)( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen); + +typedef ULONG (DEVAPI *SKF_MacInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac); + +typedef ULONG (DEVAPI *SKF_Mac_FuncPtr)( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen); + +typedef ULONG (DEVAPI *SKF_MacUpdate_FuncPtr)( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen); + +typedef ULONG (DEVAPI *SKF_MacFinal_FuncPtr)( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen); + +typedef ULONG (DEVAPI *SKF_CloseHandle_FuncPtr)( + HANDLE hHandle); + + +typedef struct skf_method_st { + char *name; + void *dso; + SKF_WaitForDevEvent_FuncPtr WaitForDevEvent; + SKF_CancelWaitForDevEvent_FuncPtr CancelWaitForDevEvent; + SKF_EnumDev_FuncPtr EnumDev; + SKF_ConnectDev_FuncPtr ConnectDev; + SKF_DisConnectDev_FuncPtr DisConnectDev; + SKF_GetDevState_FuncPtr GetDevState; + SKF_SetLabel_FuncPtr SetLabel; + SKF_GetDevInfo_FuncPtr GetDevInfo; + SKF_LockDev_FuncPtr LockDev; + SKF_UnlockDev_FuncPtr UnlockDev; + SKF_Transmit_FuncPtr Transmit; + SKF_ChangeDevAuthKey_FuncPtr ChangeDevAuthKey; + SKF_DevAuth_FuncPtr DevAuth; + SKF_ChangePIN_FuncPtr ChangePIN; + SKF_GetPINInfo_FuncPtr GetPINInfo; + SKF_VerifyPIN_FuncPtr VerifyPIN; + SKF_UnblockPIN_FuncPtr UnblockPIN; + SKF_ClearSecureState_FuncPtr ClearSecureState; + SKF_CreateApplication_FuncPtr CreateApplication; + SKF_EnumApplication_FuncPtr EnumApplication; + SKF_DeleteApplication_FuncPtr DeleteApplication; + SKF_OpenApplication_FuncPtr OpenApplication; + SKF_CloseApplication_FuncPtr CloseApplication; + SKF_CreateObject_FuncPtr CreateObject; + SKF_DeleteObject_FuncPtr DeleteObject; + SKF_EnumObjects_FuncPtr EnumObjects; + SKF_GetObjectInfo_FuncPtr GetObjectInfo; + SKF_ReadObject_FuncPtr ReadObject; + SKF_WriteObject_FuncPtr WriteObject; + SKF_CreateContainer_FuncPtr CreateContainer; + SKF_DeleteContainer_FuncPtr DeleteContainer; + SKF_EnumContainer_FuncPtr EnumContainer; + SKF_OpenContainer_FuncPtr OpenContainer; + SKF_CloseContainer_FuncPtr CloseContainer; + SKF_GetContainerType_FuncPtr GetContainerType; + SKF_ImportCertificate_FuncPtr ImportCertificate; + SKF_ExportCertificate_FuncPtr ExportCertificate; + SKF_ExportPublicKey_FuncPtr ExportPublicKey; + SKF_GenRandom_FuncPtr GenRandom; + SKF_GenExtRSAKey_FuncPtr GenExtRSAKey; + SKF_GenRSAKeyPair_FuncPtr GenRSAKeyPair; + SKF_ImportRSAKeyPair_FuncPtr ImportRSAKeyPair; + SKF_RSASignData_FuncPtr RSASignData; + SKF_RSAVerify_FuncPtr RSAVerify; + SKF_RSAExportSessionKey_FuncPtr RSAExportSessionKey; + SKF_ExtRSAPubKeyOperation_FuncPtr ExtRSAPubKeyOperation; + SKF_ExtRSAPriKeyOperation_FuncPtr ExtRSAPriKeyOperation; + SKF_GenECCKeyPair_FuncPtr GenECCKeyPair; + SKF_ImportECCKeyPair_FuncPtr ImportECCKeyPair; + SKF_ECCSignData_FuncPtr ECCSignData; + SKF_ECCVerify_FuncPtr ECCVerify; + SKF_ECCExportSessionKey_FuncPtr ECCExportSessionKey; + SKF_ExtECCEncrypt_FuncPtr ExtECCEncrypt; + SKF_ExtECCDecrypt_FuncPtr ExtECCDecrypt; + SKF_ECCDecrypt_FuncPtr ECCDecrypt; + SKF_ExtECCSign_FuncPtr ExtECCSign; + SKF_ExtECCVerify_FuncPtr ExtECCVerify; + SKF_GenerateAgreementDataWithECC_FuncPtr GenerateAgreementDataWithECC; + SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr GenerateAgreementDataAndKeyWithECC; + SKF_GenerateKeyWithECC_FuncPtr GenerateKeyWithECC; + SKF_ImportSessionKey_FuncPtr ImportSessionKey; + SKF_SetSymmKey_FuncPtr SetSymmKey; + SKF_EncryptInit_FuncPtr EncryptInit; + SKF_Encrypt_FuncPtr Encrypt; + SKF_EncryptUpdate_FuncPtr EncryptUpdate; + SKF_EncryptFinal_FuncPtr EncryptFinal; + SKF_DecryptInit_FuncPtr DecryptInit; + SKF_Decrypt_FuncPtr Decrypt; + SKF_DecryptUpdate_FuncPtr DecryptUpdate; + SKF_DecryptFinal_FuncPtr DecryptFinal; + SKF_DigestInit_FuncPtr DigestInit; + SKF_Digest_FuncPtr Digest; + SKF_DigestUpdate_FuncPtr DigestUpdate; + SKF_DigestFinal_FuncPtr DigestFinal; + SKF_MacInit_FuncPtr MacInit; + SKF_Mac_FuncPtr Mac; + SKF_MacUpdate_FuncPtr MacUpdate; + SKF_MacFinal_FuncPtr MacFinal; + SKF_CloseHandle_FuncPtr CloseHandle; +} SKF_METHOD; + +SKF_METHOD *SKF_METHOD_load_library(const char *so_path); +void SKF_METHOD_free(SKF_METHOD *meth); + + +typedef struct skf_vendor_st { + char *name; + unsigned int authrand_length; + ULONG (*get_cipher_algor)(ULONG vendor_id); + ULONG (*get_cipher_cap)(ULONG vendor_cap); + ULONG (*get_digest_algor)(ULONG vendor_id); + ULONG (*get_digest_cap)(ULONG vendor_cap); + ULONG (*get_pkey_algor)(ULONG vendor_id); + ULONG (*get_pkey_cap)(ULONG vendor_cap); + unsigned long (*get_error_reason)(ULONG err); +} SKF_VENDOR; + +typedef struct { + ULONG err; + unsigned long reason; +} SKF_ERR_REASON; + +#endif diff --git a/src/skf/skf_lib.c b/src/skf/skf_lib.c index 4187e363..c3b7688d 100644 --- a/src/skf/skf_lib.c +++ b/src/skf/skf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,2732 +7,2733 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include "skf_int.h" - - - -SKF_METHOD *skf_method = NULL; -SKF_VENDOR *skf_vendor = NULL; -extern SKF_VENDOR skf_wisec; - - -#define SKFerr(f,e) - - -ULONG SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) -{ - if (skf_method) { - SKF_METHOD_free(skf_method); - skf_method = NULL; - } - - if (!(skf_method = SKF_METHOD_load_library((char *)so_path))) { - SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_LOAD_LIBRARY_FAILURE); - return SAR_FAIL; - } - - if (vendor) { - if (strcmp((char *)vendor, skf_wisec.name) == 0) { - skf_vendor = &skf_wisec; - } else { - SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_UNKNOWN_VENDOR); - return SAR_FAIL; - } - } - - return SAR_OK; -} - -ULONG SKF_UnloadLibrary(void) -{ - SKF_METHOD_free(skf_method); - skf_method = NULL; - skf_vendor = NULL; - return SAR_OK; -} - -/* -static SKF_ERR_REASON skf_errors[] = { - { SAR_OK, SKF_R_SUCCESS }, - { SAR_FAIL, SKF_R_FAILURE }, - { SAR_UNKNOWNERR, SKF_R_UNKNOWN_ERROR }, - { SAR_NOTSUPPORTYETERR, SKF_R_OPERATION_NOT_SUPPORTED }, - { SAR_FILEERR, SKF_R_FILE_ERROR }, - { SAR_INVALIDHANDLEERR, SKF_R_INVALID_HANDLE }, - { SAR_INVALIDPARAMERR, SKF_R_INVALID_PARAMETER }, - { SAR_READFILEERR, SKF_R_READ_FILE_FAILURE }, - { SAR_WRITEFILEERR, SKF_R_WRITE_FILE_FAILURE }, - { SAR_NAMELENERR, SKF_R_INVALID_NAME_LENGTH }, - { SAR_KEYUSAGEERR, SKF_R_INVALID_KEY_USAGE }, - { SAR_MODULUSLENERR, SKF_R_INVALID_MODULUS_LENGTH }, - { SAR_NOTINITIALIZEERR, SKF_R_NOT_INITIALIZED }, - { SAR_OBJERR, SKF_R_INVALID_OBJECT }, - { SAR_MEMORYERR, SKF_R_MEMORY_ERROR }, - { SAR_TIMEOUTERR, SKF_R_TIMEOUT }, - { SAR_INDATALENERR, SKF_R_INVALID_INPUT_LENGTH }, - { SAR_INDATAERR, SKF_R_INVALID_INPUT_VALUE }, - { SAR_GENRANDERR, SKF_R_RANDOM_GENERATION_FAILED }, - { SAR_HASHOBJERR, SKF_R_INVALID_DIGEST_HANDLE }, - { SAR_HASHERR, SKF_R_DIGEST_ERROR }, - { SAR_GENRSAKEYERR, SKF_R_RSA_KEY_GENERATION_FAILURE }, - { SAR_RSAMODULUSLENERR, SKF_R_INVALID_RSA_MODULUS_LENGTH }, - { SAR_CSPIMPRTPUBKEYERR, SKF_R_CSP_IMPORT_PUBLIC_KEY_ERROR }, - { SAR_RSAENCERR, SKF_R_RSA_ENCRYPTION_FAILURE }, - { SAR_RSADECERR, SKF_R_RSA_DECRYPTION_FAILURE }, - { SAR_HASHNOTEQUALERR, SKF_R_HASH_NOT_EQUAL }, - { SAR_KEYNOTFOUNTERR, SKF_R_KEY_NOT_FOUND }, - { SAR_CERTNOTFOUNTERR, SKF_R_CERTIFICATE_NOT_FOUND }, - { SAR_NOTEXPORTERR, SKF_R_EXPORT_FAILED }, - { SAR_DECRYPTPADERR, SKF_R_DECRYPT_INVALID_PADDING }, - { SAR_MACLENERR, SKF_R_INVALID_MAC_LENGTH }, - { SAR_BUFFER_TOO_SMALL, SKF_R_BUFFER_TOO_SMALL }, - { SAR_KEYINFOTYPEERR, SKF_R_INVALID_KEY_INFO_TYPE }, - { SAR_NOT_EVENTERR, SKF_R_NO_EVENT }, - { SAR_DEVICE_REMOVED, SKF_R_DEVICE_REMOVED }, - { SAR_PIN_INCORRECT, SKF_R_PIN_INCORRECT }, - { SAR_PIN_LOCKED, SKF_R_PIN_LOCKED }, - { SAR_PIN_INVALID, SKF_R_INVALID_PIN }, - { SAR_PIN_LEN_RANGE, SKF_R_INVALID_PIN_LENGTH }, - { SAR_USER_ALREADY_LOGGED_IN, SKF_R_USER_ALREADY_LOGGED_IN }, - { SAR_USER_PIN_NOT_INITIALIZED, SKF_R_USER_PIN_NOT_INITIALIZED }, - { SAR_USER_TYPE_INVALID, SKF_R_INVALID_USER_TYPE }, - { SAR_APPLICATION_NAME_INVALID, SKF_R_INVALID_APPLICATION_NAME }, - { SAR_APPLICATION_EXISTS, SKF_R_APPLICATION_ALREADY_EXIST }, - { SAR_USER_NOT_LOGGED_IN, SKF_R_USER_NOT_LOGGED_IN }, - { SAR_APPLICATION_NOT_EXISTS, SKF_R_APPLICATION_NOT_EXIST }, - { SAR_FILE_ALREADY_EXIST, SKF_R_FILE_ALREADY_EXIST }, - { SAR_NO_ROOM, SKF_R_NO_SPACE }, - { SAR_FILE_NOT_EXIST, SKF_R_FILE_NOT_EXIST }, -}; -*/ - -static unsigned long skf_get_error_reason(ULONG ulError) -{ -/* - int i; - for (i = 0; i < OSSL_NELEM(skf_errors); i++) { - if (ulError == skf_errors[i].err) { - return skf_errors[i].reason; - } - } - if (skf_vendor) { - return skf_vendor->get_error_reason(ulError); - } -*/ - return 0; -} - -ULONG SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr) -{ - unsigned long reason; - - if ((reason = skf_get_error_reason(ulError)) != 0) { - //*szErrorStr = (LPSTR)ERR_reason_error_string(reason); - } else { - *szErrorStr = (LPSTR)"(unknown)"; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_WaitForDevEvent( - LPSTR szDevName, - ULONG *pulDevNameLen, - ULONG *pulEvent) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_WAITFORDEVEVENT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->WaitForDevEvent) { - SKFerr(SKF_F_SKF_WAITFORDEVEVENT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->WaitForDevEvent( - szDevName, - pulDevNameLen, - pulEvent)) != SAR_OK) { - SKFerr(SKF_F_SKF_WAITFORDEVEVENT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CancelWaitForDevEvent( - void) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CancelWaitForDevEvent) { - SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_method->CancelWaitForDevEvent) { - return skf_method->CancelWaitForDevEvent(); - } - - if ((rv = skf_method->CancelWaitForDevEvent()) != SAR_OK) { - SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EnumDev( - BOOL bPresent, - LPSTR szNameList, - ULONG *pulSize) -{ - ULONG rv; - - - // check output of all enum functions !!!! - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENUMDEV, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EnumDev) { - SKFerr(SKF_F_SKF_ENUMDEV, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (szNameList) { - memset(szNameList, 0, *pulSize); - } - - if ((rv = skf_method->EnumDev( - bPresent, - szNameList, - pulSize)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENUMDEV, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ConnectDev( - LPSTR szName, - DEVHANDLE *phDev) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CONNECTDEV, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ConnectDev) { - SKFerr(SKF_F_SKF_CONNECTDEV, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ConnectDev( - szName, - phDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_CONNECTDEV, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DisConnectDev( - DEVHANDLE hDev) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DISCONNECTDEV, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DisConnectDev) { - SKFerr(SKF_F_SKF_DISCONNECTDEV, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DisConnectDev( - hDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_DISCONNECTDEV, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GetDevState( - LPSTR szDevName, - ULONG *pulDevState) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GETDEVSTATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GetDevState) { - SKFerr(SKF_F_SKF_GETDEVSTATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GetDevState( - szDevName, - pulDevState)) != SAR_OK) { - SKFerr(SKF_F_SKF_GETDEVSTATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_SetLabel( - DEVHANDLE hDev, - LPSTR szLabel) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_SETLABEL, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->SetLabel) { - SKFerr(SKF_F_SKF_SETLABEL, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->SetLabel( - hDev, - szLabel)) != SAR_OK) { - SKFerr(SKF_F_SKF_SETLABEL, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GetDevInfo( - DEVHANDLE hDev, - DEVINFO *pDevInfo) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GETDEVINFO, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GetDevInfo) { - SKFerr(SKF_F_SKF_GETDEVINFO, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - memset(pDevInfo, 0, sizeof(DEVINFO)); - - if ((rv = skf_method->GetDevInfo( - hDev, - pDevInfo)) != SAR_OK) { - SKFerr(SKF_F_SKF_GETDEVINFO, skf_get_error_reason(rv)); - printf("rv = %8x\n", rv); - return rv; - } - - if (skf_vendor) { - pDevInfo->AlgSymCap = skf_vendor->get_cipher_cap(pDevInfo->AlgSymCap); - pDevInfo->AlgAsymCap = skf_vendor->get_pkey_cap(pDevInfo->AlgAsymCap); - pDevInfo->AlgHashCap = skf_vendor->get_digest_cap(pDevInfo->AlgHashCap); - pDevInfo->DevAuthAlgId = skf_vendor->get_cipher_cap(pDevInfo->DevAuthAlgId); - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_LockDev( - DEVHANDLE hDev, - ULONG ulTimeOut) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_LOCKDEV, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->LockDev) { - SKFerr(SKF_F_SKF_LOCKDEV, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->LockDev( - hDev, - ulTimeOut)) != SAR_OK) { - SKFerr(SKF_F_SKF_LOCKDEV, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_UnlockDev( - DEVHANDLE hDev) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_UNLOCKDEV, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->UnlockDev) { - SKFerr(SKF_F_SKF_UNLOCKDEV, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->UnlockDev( - hDev)) != SAR_OK) { - SKFerr(SKF_F_SKF_UNLOCKDEV, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_Transmit( - DEVHANDLE hDev, - BYTE *pbCommand, - ULONG ulCommandLen, - BYTE *pbData, - ULONG *pulDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_TRANSMIT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->Transmit) { - SKFerr(SKF_F_SKF_TRANSMIT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->Transmit( - hDev, - pbCommand, - ulCommandLen, - pbData, - pulDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_TRANSMIT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ChangeDevAuthKey( - DEVHANDLE hDev, - BYTE *pbKeyValue, - ULONG ulKeyLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ChangeDevAuthKey) { - SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ChangeDevAuthKey( - hDev, - pbKeyValue, - ulKeyLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DevAuth( - DEVHANDLE hDev, - BYTE *pbAuthData, - ULONG ulLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DEVAUTH, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DevAuth) { - SKFerr(SKF_F_SKF_DEVAUTH, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DevAuth( - hDev, - pbAuthData, - ulLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DEVAUTH, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ChangePIN( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szOldPin, - LPSTR szNewPin, - ULONG *pulRetryCount) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CHANGEPIN, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ChangePIN) { - SKFerr(SKF_F_SKF_CHANGEPIN, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ChangePIN( - hApplication, - ulPINType, - szOldPin, - szNewPin, - pulRetryCount)) != SAR_OK) { - SKFerr(SKF_F_SKF_CHANGEPIN, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -LONG DEVAPI SKF_GetPINInfo( - HAPPLICATION hApplication, - ULONG ulPINType, - ULONG *pulMaxRetryCount, - ULONG *pulRemainRetryCount, - BOOL *pbDefaultPin) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GETPININFO, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GetPINInfo) { - SKFerr(SKF_F_SKF_GETPININFO, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GetPINInfo( - hApplication, - ulPINType, - pulMaxRetryCount, - pulRemainRetryCount, - pbDefaultPin)) != SAR_OK) { - SKFerr(SKF_F_SKF_GETPININFO, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_VerifyPIN( - HAPPLICATION hApplication, - ULONG ulPINType, - LPSTR szPIN, - ULONG *pulRetryCount) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_VERIFYPIN, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->VerifyPIN) { - SKFerr(SKF_F_SKF_VERIFYPIN, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->VerifyPIN( - hApplication, - ulPINType, - szPIN, - pulRetryCount)) != SAR_OK) { - SKFerr(SKF_F_SKF_VERIFYPIN, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_UnblockPIN( - HAPPLICATION hApplication, - LPSTR szAdminPIN, - LPSTR szNewUserPIN, - ULONG *pulRetryCount) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_UNBLOCKPIN, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->UnblockPIN) { - SKFerr(SKF_F_SKF_UNBLOCKPIN, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->UnblockPIN( - hApplication, - szAdminPIN, - szNewUserPIN, - pulRetryCount)) != SAR_OK) { - SKFerr(SKF_F_SKF_UNBLOCKPIN, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ClearSecureState( - HAPPLICATION hApplication) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CLEARSECURESTATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ClearSecureState) { - SKFerr(SKF_F_SKF_CLEARSECURESTATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ClearSecureState( - hApplication)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLEARSECURESTATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CreateApplication( - DEVHANDLE hDev, - LPSTR szAppName, - LPSTR szAdminPin, - DWORD dwAdminPinRetryCount, - LPSTR szUserPin, - DWORD dwUserPinRetryCount, - DWORD dwCreateFileRights, - HAPPLICATION *phApplication) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CREATEAPPLICATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CreateApplication) { - SKFerr(SKF_F_SKF_CREATEAPPLICATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CreateApplication( - hDev, - szAppName, - szAdminPin, - dwAdminPinRetryCount, - szUserPin, - dwUserPinRetryCount, - dwCreateFileRights, - phApplication)) != SAR_OK) { - SKFerr(SKF_F_SKF_CREATEAPPLICATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EnumApplication( - DEVHANDLE hDev, - LPSTR szAppName, - ULONG *pulSize) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENUMAPPLICATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EnumApplication) { - SKFerr(SKF_F_SKF_ENUMAPPLICATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EnumApplication( - hDev, - szAppName, - pulSize)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENUMAPPLICATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DeleteApplication( - DEVHANDLE hDev, - LPSTR szAppName) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DELETEAPPLICATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DeleteApplication) { - SKFerr(SKF_F_SKF_DELETEAPPLICATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DeleteApplication( - hDev, - szAppName)) != SAR_OK) { - SKFerr(SKF_F_SKF_DELETEAPPLICATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_OpenApplication( - DEVHANDLE hDev, - LPSTR szAppName, - HAPPLICATION *phApplication) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_OPENAPPLICATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->OpenApplication) { - SKFerr(SKF_F_SKF_OPENAPPLICATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->OpenApplication( - hDev, - szAppName, - phApplication)) != SAR_OK) { - SKFerr(SKF_F_SKF_OPENAPPLICATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CloseApplication( - HAPPLICATION hApplication) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CLOSEAPPLICATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CloseApplication) { - SKFerr(SKF_F_SKF_CLOSEAPPLICATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CloseApplication( - hApplication)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLOSEAPPLICATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CreateFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulFileSize, - ULONG ulReadRights, - ULONG ulWriteRights) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CREATEFILE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CreateObject) { - SKFerr(SKF_F_SKF_CREATEFILE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CreateObject( - hApplication, - szFileName, - ulFileSize, - ulReadRights, - ulWriteRights)) != SAR_OK) { - SKFerr(SKF_F_SKF_CREATEFILE, skf_get_error_reason(rv)); - - //LPSTR str = NULL; - //printf("error = %08X\n", rv); - //SKF_GetErrorString(rv, &str); - //printf("error = %s\n", (char *)str); - - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DeleteFile( - HAPPLICATION hApplication, - LPSTR szFileName) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DELETEFILE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DeleteObject) { - SKFerr(SKF_F_SKF_DELETEFILE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DeleteObject( - hApplication, - szFileName)) != SAR_OK) { - SKFerr(SKF_F_SKF_DELETEFILE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EnumFiles( - HAPPLICATION hApplication, - LPSTR szFileList, - ULONG *pulSize) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENUMFILES, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EnumObjects) { - SKFerr(SKF_F_SKF_ENUMFILES, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EnumObjects( - hApplication, - szFileList, - pulSize)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENUMFILES, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GetFileInfo( - HAPPLICATION hApplication, - LPSTR szFileName, - FILEATTRIBUTE *pFileInfo) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GETFILEINFO, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GetObjectInfo) { - SKFerr(SKF_F_SKF_GETFILEINFO, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - memset(pFileInfo, 0, sizeof(FILEATTRIBUTE)); - - if ((rv = skf_method->GetObjectInfo( - hApplication, - szFileName, - pFileInfo)) != SAR_OK) { - SKFerr(SKF_F_SKF_GETFILEINFO, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ReadFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - ULONG ulSize, - BYTE *pbOutData, - ULONG *pulOutLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_READFILE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ReadObject) { - SKFerr(SKF_F_SKF_READFILE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ReadObject( - hApplication, - szFileName, - ulOffset, - ulSize, - pbOutData, - pulOutLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_READFILE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_WriteFile( - HAPPLICATION hApplication, - LPSTR szFileName, - ULONG ulOffset, - BYTE *pbData, - ULONG ulSize) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_WRITEFILE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->WriteObject) { - SKFerr(SKF_F_SKF_WRITEFILE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->WriteObject( - hApplication, - szFileName, - ulOffset, - pbData, - ulSize)) != SAR_OK) { - SKFerr(SKF_F_SKF_WRITEFILE, skf_get_error_reason(rv)); - - printf("error = %08X\n", rv); - - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CreateContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CREATECONTAINER, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CreateContainer) { - SKFerr(SKF_F_SKF_CREATECONTAINER, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CreateContainer( - hApplication, - szContainerName, - phContainer)) != SAR_OK) { - SKFerr(SKF_F_SKF_CREATECONTAINER, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DeleteContainer( - HAPPLICATION hApplication, - LPSTR szContainerName) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DELETECONTAINER, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DeleteContainer) { - SKFerr(SKF_F_SKF_DELETECONTAINER, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DeleteContainer( - hApplication, - szContainerName)) != SAR_OK) { - SKFerr(SKF_F_SKF_DELETECONTAINER, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EnumContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - ULONG *pulSize) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENUMCONTAINER, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EnumContainer) { - SKFerr(SKF_F_SKF_ENUMCONTAINER, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EnumContainer( - hApplication, - szContainerName, - pulSize)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENUMCONTAINER, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_OpenContainer( - HAPPLICATION hApplication, - LPSTR szContainerName, - HCONTAINER *phContainer) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_OPENCONTAINER, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->OpenContainer) { - SKFerr(SKF_F_SKF_OPENCONTAINER, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->OpenContainer( - hApplication, - szContainerName, - phContainer)) != SAR_OK) { - SKFerr(SKF_F_SKF_OPENCONTAINER, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CloseContainer( - HCONTAINER hContainer) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CLOSECONTAINER, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CloseContainer) { - SKFerr(SKF_F_SKF_CLOSECONTAINER, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CloseContainer( - hContainer)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLOSECONTAINER, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GetContainerType( - HCONTAINER hContainer, - ULONG *pulContainerType) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GETCONTAINERTYPE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GetContainerType) { - SKFerr(SKF_F_SKF_GETCONTAINERTYPE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GetContainerType( - hContainer, - pulContainerType)) != SAR_OK) { - SKFerr(SKF_F_SKF_GETCONTAINERTYPE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ImportCertificate( - HCONTAINER hContainer, - BOOL bExportSignKey, - BYTE *pbCert, - ULONG ulCertLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ImportCertificate) { - SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ImportCertificate( - hContainer, - bExportSignKey, - pbCert, - ulCertLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportCertificate( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbCert, - ULONG *pulCertLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExportCertificate) { - SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExportCertificate( - hContainer, - bSignFlag, - pbCert, - pulCertLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExportPublicKey( - HCONTAINER hContainer, - BOOL bSignFlag, - BYTE *pbBlob, - ULONG *pulBlobLen) -{ - ULONG rv; - - // TODO: check the output length, clear the memmory. - // if pbBlob is NULL, return the length - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExportPublicKey) { - SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExportPublicKey( - hContainer, - bSignFlag, - pbBlob, - pulBlobLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenRandom( - DEVHANDLE hDev, - BYTE *pbRandom, - ULONG ulRandomLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENRANDOM, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenRandom) { - SKFerr(SKF_F_SKF_GENRANDOM, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GenRandom( - hDev, - pbRandom, - ulRandomLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENRANDOM, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenExtRSAKey( - DEVHANDLE hDev, - ULONG ulBitsLen, - RSAPRIVATEKEYBLOB *pBlob) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENEXTRSAKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenExtRSAKey) { - SKFerr(SKF_F_SKF_GENEXTRSAKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GenExtRSAKey( - hDev, - ulBitsLen, - pBlob)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENEXTRSAKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenRSAKeyPair( - HCONTAINER hContainer, - ULONG ulBitsLen, - RSAPUBLICKEYBLOB *pBlob) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENRSAKEYPAIR, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenRSAKeyPair) { - SKFerr(SKF_F_SKF_GENRSAKEYPAIR, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - memset(pBlob, 0, sizeof(RSAPUBLICKEYBLOB)); - if ((rv = skf_method->GenRSAKeyPair( - hContainer, - ulBitsLen, - pBlob)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENRSAKEYPAIR, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ImportRSAKeyPair( - HCONTAINER hContainer, - ULONG ulSymAlgId, - BYTE *pbWrappedKey, - ULONG ulWrappedKeyLen, - BYTE *pbEncryptedData, - ULONG ulEncryptedDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ImportRSAKeyPair) { - SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulSymAlgId = skf_vendor->get_cipher_algor(ulSymAlgId))) { - SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->ImportRSAKeyPair( - hContainer, - ulSymAlgId, - pbWrappedKey, - ulWrappedKeyLen, - pbEncryptedData, - ulEncryptedDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_RSASignData( - HCONTAINER hContainer, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG *pulSignLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_RSASIGNDATA, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->RSASignData) { - SKFerr(SKF_F_SKF_RSASIGNDATA, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->RSASignData( - hContainer, - pbData, - ulDataLen, - pbSignature, - pulSignLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_RSASIGNDATA, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_RSAVerify( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbSignature, - ULONG ulSignLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_RSAVERIFY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->RSAVerify) { - SKFerr(SKF_F_SKF_RSAVERIFY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->RSAVerify( - hDev, - pRSAPubKeyBlob, - pbData, - ulDataLen, - pbSignature, - ulSignLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_RSAVERIFY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_RSAExportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - RSAPUBLICKEYBLOB *pPubKey, - BYTE *pbData, - ULONG *pulDataLen, - HANDLE *phSessionKey) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->RSAExportSessionKey) { - SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->RSAExportSessionKey( - hContainer, - ulAlgId, - pPubKey, - pbData, - pulDataLen, - phSessionKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtRSAPubKeyOperation( - DEVHANDLE hDev, - RSAPUBLICKEYBLOB *pRSAPubKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtRSAPubKeyOperation) { - SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtRSAPubKeyOperation( - hDev, - pRSAPubKeyBlob, - pbInput, - ulInputLen, - pbOutput, - pulOutputLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtRSAPriKeyOperation( - DEVHANDLE hDev, - RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, - BYTE *pbInput, - ULONG ulInputLen, - BYTE *pbOutput, - ULONG *pulOutputLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtRSAPriKeyOperation) { - SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtRSAPriKeyOperation( - hDev, - pRSAPriKeyBlob, - pbInput, - ulInputLen, - pbOutput, - pulOutputLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenECCKeyPair( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pBlob) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENECCKEYPAIR, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenECCKeyPair) { - SKFerr(SKF_F_SKF_GENECCKEYPAIR, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_pkey_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_GENECCKEYPAIR, - SKF_R_NOT_SUPPORTED_PKEY_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - memset(pBlob, 0, sizeof(ECCPUBLICKEYBLOB)); - if ((rv = skf_method->GenECCKeyPair( - hContainer, - ulAlgId, - pBlob)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENECCKEYPAIR, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ImportECCKeyPair( - HCONTAINER hContainer, - ENVELOPEDKEYBLOB *pEnvelopedKeyBlob) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ImportECCKeyPair) { - SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ImportECCKeyPair( - hContainer, - pEnvelopedKeyBlob)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, skf_get_error_reason(rv)); - printf("%s %d: error = %08X\n", __FILE__, __LINE__, rv); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ECCSignData( - HCONTAINER hContainer, - BYTE *pbDigest, - ULONG ulDigestLen, - ECCSIGNATUREBLOB *pSignature) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ECCSIGNDATA, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ECCSignData) { - SKFerr(SKF_F_SKF_ECCSIGNDATA, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ECCSignData( - hContainer, - pbDigest, - ulDigestLen, - pSignature)) != SAR_OK) { - SKFerr(SKF_F_SKF_ECCSIGNDATA, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ECCVerify( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ECCVERIFY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ECCVerify) { - SKFerr(SKF_F_SKF_ECCVERIFY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ECCVerify( - hDev, - pECCPubKeyBlob, - pbData, - ulDataLen, - pSignature)) != SAR_OK) { - SKFerr(SKF_F_SKF_ECCVERIFY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ECCExportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pPubKey, - ECCCIPHERBLOB *pData, - HANDLE *phSessionKey) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ECCExportSessionKey) { - SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->ECCExportSessionKey( - hContainer, - ulAlgId, - pPubKey, - pData, - phSessionKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ECCDecrypt( - HCONTAINER hContainer, - ECCCIPHERBLOB *pCipherText, - BYTE *pbPlainText, - ULONG *pulPlainTextLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ECCDECRYPT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ECCDecrypt) { - SKFerr(SKF_F_SKF_ECCDECRYPT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ECCDecrypt( - hContainer, - pCipherText, - pbPlainText, - pulPlainTextLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_ECCDECRYPT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtECCEncrypt( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbPlainText, - ULONG ulPlainTextLen, - ECCCIPHERBLOB *pCipherText) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTECCENCRYPT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtECCEncrypt) { - SKFerr(SKF_F_SKF_EXTECCENCRYPT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtECCEncrypt( - hDev, - pECCPubKeyBlob, - pbPlainText, - ulPlainTextLen, - pCipherText)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTECCENCRYPT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtECCDecrypt( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - ECCCIPHERBLOB *pCipherText, - BYTE *pbPlainText, - ULONG *pulPlainTextLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTECCDECRYPT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtECCDecrypt) { - SKFerr(SKF_F_SKF_EXTECCDECRYPT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtECCDecrypt( - hDev, - pECCPriKeyBlob, - pCipherText, - pbPlainText, - pulPlainTextLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTECCDECRYPT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtECCSign( - DEVHANDLE hDev, - ECCPRIVATEKEYBLOB *pECCPriKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTECCSIGN, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtECCSign) { - SKFerr(SKF_F_SKF_EXTECCSIGN, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtECCSign( - hDev, - pECCPriKeyBlob, - pbData, - ulDataLen, - pSignature)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTECCSIGN, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ExtECCVerify( - DEVHANDLE hDev, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - BYTE *pbData, - ULONG ulDataLen, - ECCSIGNATUREBLOB *pSignature) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_EXTECCVERIFY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ExtECCVerify) { - SKFerr(SKF_F_SKF_EXTECCVERIFY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->ExtECCVerify( - hDev, - pECCPubKeyBlob, - pbData, - ulDataLen, - pSignature)) != SAR_OK) { - SKFerr(SKF_F_SKF_EXTECCVERIFY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenerateAgreementDataWithECC( - HCONTAINER hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phAgreementHandle) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenerateAgreementDataWithECC) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->GenerateAgreementDataWithECC( - hContainer, - ulAlgId, - pTempECCPubKeyBlob, - pbID, - ulIDLen, - phAgreementHandle)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( - HANDLE hContainer, - ULONG ulAlgId, - ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, - ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - BYTE *pbSponsorID, - ULONG ulSponsorIDLen, - HANDLE *phKeyHandle) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenerateAgreementDataAndKeyWithECC) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->GenerateAgreementDataAndKeyWithECC( - hContainer, - ulAlgId, - pSponsorECCPubKeyBlob, - pSponsorTempECCPubKeyBlob, - pTempECCPubKeyBlob, - pbID, - ulIDLen, - pbSponsorID, - ulSponsorIDLen, - phKeyHandle)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_GenerateKeyWithECC( - HANDLE hAgreementHandle, - ECCPUBLICKEYBLOB *pECCPubKeyBlob, - ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phKeyHandle) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->GenerateKeyWithECC) { - SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->GenerateKeyWithECC( - hAgreementHandle, - pECCPubKeyBlob, - pTempECCPubKeyBlob, - pbID, - ulIDLen, - phKeyHandle)) != SAR_OK) { - SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_ImportSessionKey( - HCONTAINER hContainer, - ULONG ulAlgId, - BYTE *pbWrapedData, - ULONG ulWrapedLen, - HANDLE *phKey) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->ImportSessionKey) { - SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { - SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->ImportSessionKey( - hContainer, - ulAlgId, - pbWrapedData, - ulWrapedLen, - phKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_SetSymmKey( - DEVHANDLE hDev, - BYTE *pbKey, - ULONG ulAlgID, - HANDLE *phKey) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_SETSYMMKEY, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->SetSymmKey) { - SKFerr(SKF_F_SKF_SETSYMMKEY, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgID = skf_vendor->get_cipher_algor(ulAlgID))) { - SKFerr(SKF_F_SKF_SETSYMMKEY, - SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->SetSymmKey( - hDev, - pbKey, - ulAlgID, - phKey)) != SAR_OK) { - SKFerr(SKF_F_SKF_SETSYMMKEY, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EncryptInit( - HANDLE hKey, - BLOCKCIPHERPARAM EncryptParam) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENCRYPTINIT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EncryptInit) { - SKFerr(SKF_F_SKF_ENCRYPTINIT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EncryptInit( - hKey, - EncryptParam)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENCRYPTINIT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_Encrypt( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENCRYPT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->Encrypt) { - SKFerr(SKF_F_SKF_ENCRYPT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->Encrypt( - hKey, - pbData, - ulDataLen, - pbEncryptedData, - pulEncryptedLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENCRYPT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EncryptUpdate( - HANDLE hKey, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbEncryptedData, - ULONG *pulEncryptedLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENCRYPTUPDATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EncryptUpdate) { - SKFerr(SKF_F_SKF_ENCRYPTUPDATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EncryptUpdate( - hKey, - pbData, - ulDataLen, - pbEncryptedData, - pulEncryptedLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENCRYPTUPDATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_EncryptFinal( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG *pulEncryptedDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_ENCRYPTFINAL, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->EncryptFinal) { - SKFerr(SKF_F_SKF_ENCRYPTFINAL, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->EncryptFinal( - hKey, - pbEncryptedData, - pulEncryptedDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_ENCRYPTFINAL, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DecryptInit( - HANDLE hKey, - BLOCKCIPHERPARAM DecryptParam) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DECRYPTINIT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DecryptInit) { - SKFerr(SKF_F_SKF_DECRYPTINIT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DecryptInit( - hKey, - DecryptParam)) != SAR_OK) { - SKFerr(SKF_F_SKF_DECRYPTINIT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_Decrypt( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DECRYPT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->Decrypt) { - SKFerr(SKF_F_SKF_DECRYPT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->Decrypt( - hKey, - pbEncryptedData, - ulEncryptedLen, - pbData, - pulDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DECRYPT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DecryptUpdate( - HANDLE hKey, - BYTE *pbEncryptedData, - ULONG ulEncryptedLen, - BYTE *pbData, - ULONG *pulDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DECRYPTUPDATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DecryptUpdate) { - SKFerr(SKF_F_SKF_DECRYPTUPDATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DecryptUpdate( - hKey, - pbEncryptedData, - ulEncryptedLen, - pbData, - pulDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DECRYPTUPDATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DecryptFinal( - HANDLE hKey, - BYTE *pbDecryptedData, - ULONG *pulDecryptedDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DECRYPTFINAL, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DecryptFinal) { - SKFerr(SKF_F_SKF_DECRYPTFINAL, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DecryptFinal( - hKey, - pbDecryptedData, - pulDecryptedDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DECRYPTFINAL, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DigestInit( - DEVHANDLE hDev, - ULONG ulAlgID, - ECCPUBLICKEYBLOB *pPubKey, - BYTE *pbID, - ULONG ulIDLen, - HANDLE *phHash) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DIGESTINIT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DigestInit) { - SKFerr(SKF_F_SKF_DIGESTINIT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if (skf_vendor) { - if (!(ulAlgID = skf_vendor->get_digest_algor(ulAlgID))) { - SKFerr(SKF_F_SKF_DIGESTINIT, - SKF_R_NOT_SUPPORTED_DIGEST_ALGOR); - return SAR_NOTSUPPORTYETERR; - } - } - - if ((rv = skf_method->DigestInit( - hDev, - ulAlgID, - pPubKey, - pbID, - ulIDLen, - phHash)) != SAR_OK) { - SKFerr(SKF_F_SKF_DIGESTINIT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_Digest( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbHashData, - ULONG *pulHashLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DIGEST, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->Digest) { - SKFerr(SKF_F_SKF_DIGEST, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->Digest( - hHash, - pbData, - ulDataLen, - pbHashData, - pulHashLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DIGEST, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DigestUpdate( - HANDLE hHash, - BYTE *pbData, - ULONG ulDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DIGESTUPDATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DigestUpdate) { - SKFerr(SKF_F_SKF_DIGESTUPDATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DigestUpdate( - hHash, - pbData, - ulDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DIGESTUPDATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_DigestFinal( - HANDLE hHash, - BYTE *pHashData, - ULONG *pulHashLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_DIGESTFINAL, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->DigestFinal) { - SKFerr(SKF_F_SKF_DIGESTFINAL, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->DigestFinal( - hHash, - pHashData, - pulHashLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_DIGESTFINAL, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_MacInit( - HANDLE hKey, - BLOCKCIPHERPARAM *pMacParam, - HANDLE *phMac) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_MACINIT, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->MacInit) { - SKFerr(SKF_F_SKF_MACINIT, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->MacInit( - hKey, - pMacParam, - phMac)) != SAR_OK) { - SKFerr(SKF_F_SKF_MACINIT, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_Mac( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen, - BYTE *pbMacData, - ULONG *pulMacLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_MAC, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->Mac) { - SKFerr(SKF_F_SKF_MAC, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->Mac( - hMac, - pbData, - ulDataLen, - pbMacData, - pulMacLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_MAC, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_MacUpdate( - HANDLE hMac, - BYTE *pbData, - ULONG ulDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_MACUPDATE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->MacUpdate) { - SKFerr(SKF_F_SKF_MACUPDATE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->MacUpdate( - hMac, - pbData, - ulDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_MACUPDATE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_MacFinal( - HANDLE hMac, - BYTE *pbMacData, - ULONG *pulMacDataLen) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_MACFINAL, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->MacFinal) { - SKFerr(SKF_F_SKF_MACFINAL, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->MacFinal( - hMac, - pbMacData, - pulMacDataLen)) != SAR_OK) { - SKFerr(SKF_F_SKF_MACFINAL, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - -ULONG DEVAPI SKF_CloseHandle( - HANDLE hHandle) -{ - ULONG rv; - - if (!skf_method) { - SKFerr(SKF_F_SKF_CLOSEHANDLE, - SKF_R_SKF_METHOD_NOT_INITIALIZED); - return SAR_NOTINITIALIZEERR; - } - - if (!skf_method->CloseHandle) { - SKFerr(SKF_F_SKF_CLOSEHANDLE, - SKF_R_FUNCTION_NOT_SUPPORTED); - return SAR_NOTSUPPORTYETERR; - } - - if ((rv = skf_method->CloseHandle( - hHandle)) != SAR_OK) { - SKFerr(SKF_F_SKF_CLOSEHANDLE, skf_get_error_reason(rv)); - return rv; - } - - return SAR_OK; -} - + + +#include +#include +#include +#include "skf_int.h" + + + +SKF_METHOD *skf_method = NULL; +SKF_VENDOR *skf_vendor = NULL; +extern SKF_VENDOR skf_wisec; + + +#define SKFerr(f,e) + + +ULONG SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) +{ + if (skf_method) { + SKF_METHOD_free(skf_method); + skf_method = NULL; + } + + if (!(skf_method = SKF_METHOD_load_library((char *)so_path))) { + SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_LOAD_LIBRARY_FAILURE); + return SAR_FAIL; + } + + if (vendor) { + if (strcmp((char *)vendor, skf_wisec.name) == 0) { + skf_vendor = &skf_wisec; + } else { + SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_UNKNOWN_VENDOR); + return SAR_FAIL; + } + } + + return SAR_OK; +} + +ULONG SKF_UnloadLibrary(void) +{ + SKF_METHOD_free(skf_method); + skf_method = NULL; + skf_vendor = NULL; + return SAR_OK; +} + +/* +static SKF_ERR_REASON skf_errors[] = { + { SAR_OK, SKF_R_SUCCESS }, + { SAR_FAIL, SKF_R_FAILURE }, + { SAR_UNKNOWNERR, SKF_R_UNKNOWN_ERROR }, + { SAR_NOTSUPPORTYETERR, SKF_R_OPERATION_NOT_SUPPORTED }, + { SAR_FILEERR, SKF_R_FILE_ERROR }, + { SAR_INVALIDHANDLEERR, SKF_R_INVALID_HANDLE }, + { SAR_INVALIDPARAMERR, SKF_R_INVALID_PARAMETER }, + { SAR_READFILEERR, SKF_R_READ_FILE_FAILURE }, + { SAR_WRITEFILEERR, SKF_R_WRITE_FILE_FAILURE }, + { SAR_NAMELENERR, SKF_R_INVALID_NAME_LENGTH }, + { SAR_KEYUSAGEERR, SKF_R_INVALID_KEY_USAGE }, + { SAR_MODULUSLENERR, SKF_R_INVALID_MODULUS_LENGTH }, + { SAR_NOTINITIALIZEERR, SKF_R_NOT_INITIALIZED }, + { SAR_OBJERR, SKF_R_INVALID_OBJECT }, + { SAR_MEMORYERR, SKF_R_MEMORY_ERROR }, + { SAR_TIMEOUTERR, SKF_R_TIMEOUT }, + { SAR_INDATALENERR, SKF_R_INVALID_INPUT_LENGTH }, + { SAR_INDATAERR, SKF_R_INVALID_INPUT_VALUE }, + { SAR_GENRANDERR, SKF_R_RANDOM_GENERATION_FAILED }, + { SAR_HASHOBJERR, SKF_R_INVALID_DIGEST_HANDLE }, + { SAR_HASHERR, SKF_R_DIGEST_ERROR }, + { SAR_GENRSAKEYERR, SKF_R_RSA_KEY_GENERATION_FAILURE }, + { SAR_RSAMODULUSLENERR, SKF_R_INVALID_RSA_MODULUS_LENGTH }, + { SAR_CSPIMPRTPUBKEYERR, SKF_R_CSP_IMPORT_PUBLIC_KEY_ERROR }, + { SAR_RSAENCERR, SKF_R_RSA_ENCRYPTION_FAILURE }, + { SAR_RSADECERR, SKF_R_RSA_DECRYPTION_FAILURE }, + { SAR_HASHNOTEQUALERR, SKF_R_HASH_NOT_EQUAL }, + { SAR_KEYNOTFOUNTERR, SKF_R_KEY_NOT_FOUND }, + { SAR_CERTNOTFOUNTERR, SKF_R_CERTIFICATE_NOT_FOUND }, + { SAR_NOTEXPORTERR, SKF_R_EXPORT_FAILED }, + { SAR_DECRYPTPADERR, SKF_R_DECRYPT_INVALID_PADDING }, + { SAR_MACLENERR, SKF_R_INVALID_MAC_LENGTH }, + { SAR_BUFFER_TOO_SMALL, SKF_R_BUFFER_TOO_SMALL }, + { SAR_KEYINFOTYPEERR, SKF_R_INVALID_KEY_INFO_TYPE }, + { SAR_NOT_EVENTERR, SKF_R_NO_EVENT }, + { SAR_DEVICE_REMOVED, SKF_R_DEVICE_REMOVED }, + { SAR_PIN_INCORRECT, SKF_R_PIN_INCORRECT }, + { SAR_PIN_LOCKED, SKF_R_PIN_LOCKED }, + { SAR_PIN_INVALID, SKF_R_INVALID_PIN }, + { SAR_PIN_LEN_RANGE, SKF_R_INVALID_PIN_LENGTH }, + { SAR_USER_ALREADY_LOGGED_IN, SKF_R_USER_ALREADY_LOGGED_IN }, + { SAR_USER_PIN_NOT_INITIALIZED, SKF_R_USER_PIN_NOT_INITIALIZED }, + { SAR_USER_TYPE_INVALID, SKF_R_INVALID_USER_TYPE }, + { SAR_APPLICATION_NAME_INVALID, SKF_R_INVALID_APPLICATION_NAME }, + { SAR_APPLICATION_EXISTS, SKF_R_APPLICATION_ALREADY_EXIST }, + { SAR_USER_NOT_LOGGED_IN, SKF_R_USER_NOT_LOGGED_IN }, + { SAR_APPLICATION_NOT_EXISTS, SKF_R_APPLICATION_NOT_EXIST }, + { SAR_FILE_ALREADY_EXIST, SKF_R_FILE_ALREADY_EXIST }, + { SAR_NO_ROOM, SKF_R_NO_SPACE }, + { SAR_FILE_NOT_EXIST, SKF_R_FILE_NOT_EXIST }, +}; +*/ + +static unsigned long skf_get_error_reason(ULONG ulError) +{ +/* + int i; + for (i = 0; i < OSSL_NELEM(skf_errors); i++) { + if (ulError == skf_errors[i].err) { + return skf_errors[i].reason; + } + } + if (skf_vendor) { + return skf_vendor->get_error_reason(ulError); + } +*/ + return 0; +} + +ULONG SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr) +{ + unsigned long reason; + + if ((reason = skf_get_error_reason(ulError)) != 0) { + //*szErrorStr = (LPSTR)ERR_reason_error_string(reason); + } else { + *szErrorStr = (LPSTR)"(unknown)"; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_WaitForDevEvent( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->WaitForDevEvent) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->WaitForDevEvent( + szDevName, + pulDevNameLen, + pulEvent)) != SAR_OK) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CancelWaitForDevEvent( + void) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CancelWaitForDevEvent) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_method->CancelWaitForDevEvent) { + return skf_method->CancelWaitForDevEvent(); + } + + if ((rv = skf_method->CancelWaitForDevEvent()) != SAR_OK) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumDev( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize) +{ + ULONG rv; + + + // check output of all enum functions !!!! + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumDev) { + SKFerr(SKF_F_SKF_ENUMDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (szNameList) { + memset(szNameList, 0, *pulSize); + } + + if ((rv = skf_method->EnumDev( + bPresent, + szNameList, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ConnectDev( + LPSTR szName, + DEVHANDLE *phDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CONNECTDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ConnectDev) { + SKFerr(SKF_F_SKF_CONNECTDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ConnectDev( + szName, + phDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CONNECTDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DisConnectDev( + DEVHANDLE hDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DisConnectDev) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DisConnectDev( + hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevState( + LPSTR szDevName, + ULONG *pulDevState) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETDEVSTATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetDevState) { + SKFerr(SKF_F_SKF_GETDEVSTATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetDevState( + szDevName, + pulDevState)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETDEVSTATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_SetLabel( + DEVHANDLE hDev, + LPSTR szLabel) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_SETLABEL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->SetLabel) { + SKFerr(SKF_F_SKF_SETLABEL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->SetLabel( + hDev, + szLabel)) != SAR_OK) { + SKFerr(SKF_F_SKF_SETLABEL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevInfo( + DEVHANDLE hDev, + DEVINFO *pDevInfo) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETDEVINFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetDevInfo) { + SKFerr(SKF_F_SKF_GETDEVINFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pDevInfo, 0, sizeof(DEVINFO)); + + if ((rv = skf_method->GetDevInfo( + hDev, + pDevInfo)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETDEVINFO, skf_get_error_reason(rv)); + printf("rv = %8x\n", rv); + return rv; + } + + if (skf_vendor) { + pDevInfo->AlgSymCap = skf_vendor->get_cipher_cap(pDevInfo->AlgSymCap); + pDevInfo->AlgAsymCap = skf_vendor->get_pkey_cap(pDevInfo->AlgAsymCap); + pDevInfo->AlgHashCap = skf_vendor->get_digest_cap(pDevInfo->AlgHashCap); + pDevInfo->DevAuthAlgId = skf_vendor->get_cipher_cap(pDevInfo->DevAuthAlgId); + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_LockDev( + DEVHANDLE hDev, + ULONG ulTimeOut) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_LOCKDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->LockDev) { + SKFerr(SKF_F_SKF_LOCKDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->LockDev( + hDev, + ulTimeOut)) != SAR_OK) { + SKFerr(SKF_F_SKF_LOCKDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_UnlockDev( + DEVHANDLE hDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_UNLOCKDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->UnlockDev) { + SKFerr(SKF_F_SKF_UNLOCKDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->UnlockDev( + hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_UNLOCKDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Transmit( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_TRANSMIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Transmit) { + SKFerr(SKF_F_SKF_TRANSMIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Transmit( + hDev, + pbCommand, + ulCommandLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_TRANSMIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangeDevAuthKey( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ChangeDevAuthKey) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ChangeDevAuthKey( + hDev, + pbKeyValue, + ulKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DevAuth( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DEVAUTH, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DevAuth) { + SKFerr(SKF_F_SKF_DEVAUTH, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DevAuth( + hDev, + pbAuthData, + ulLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DEVAUTH, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangePIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CHANGEPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ChangePIN) { + SKFerr(SKF_F_SKF_CHANGEPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ChangePIN( + hApplication, + ulPINType, + szOldPin, + szNewPin, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_CHANGEPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +LONG DEVAPI SKF_GetPINInfo( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETPININFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetPINInfo) { + SKFerr(SKF_F_SKF_GETPININFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetPINInfo( + hApplication, + ulPINType, + pulMaxRetryCount, + pulRemainRetryCount, + pbDefaultPin)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETPININFO, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_VerifyPIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_VERIFYPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->VerifyPIN) { + SKFerr(SKF_F_SKF_VERIFYPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->VerifyPIN( + hApplication, + ulPINType, + szPIN, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_VERIFYPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_UnblockPIN( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->UnblockPIN) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->UnblockPIN( + hApplication, + szAdminPIN, + szNewUserPIN, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ClearSecureState( + HAPPLICATION hApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ClearSecureState) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ClearSecureState( + hApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateApplication( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateApplication) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateApplication( + hDev, + szAppName, + szAdminPin, + dwAdminPinRetryCount, + szUserPin, + dwUserPinRetryCount, + dwCreateFileRights, + phApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumApplication( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumApplication) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumApplication( + hDev, + szAppName, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteApplication( + DEVHANDLE hDev, + LPSTR szAppName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteApplication) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteApplication( + hDev, + szAppName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenApplication( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->OpenApplication) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->OpenApplication( + hDev, + szAppName, + phApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseApplication( + HAPPLICATION hApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseApplication) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseApplication( + hApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateObject) { + SKFerr(SKF_F_SKF_CREATEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateObject( + hApplication, + szFileName, + ulFileSize, + ulReadRights, + ulWriteRights)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATEFILE, skf_get_error_reason(rv)); + + //LPSTR str = NULL; + //printf("error = %08X\n", rv); + //SKF_GetErrorString(rv, &str); + //printf("error = %s\n", (char *)str); + + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteFile( + HAPPLICATION hApplication, + LPSTR szFileName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteObject) { + SKFerr(SKF_F_SKF_DELETEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteObject( + hApplication, + szFileName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETEFILE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumFiles( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMFILES, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumObjects) { + SKFerr(SKF_F_SKF_ENUMFILES, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumObjects( + hApplication, + szFileList, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMFILES, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetFileInfo( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETFILEINFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetObjectInfo) { + SKFerr(SKF_F_SKF_GETFILEINFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pFileInfo, 0, sizeof(FILEATTRIBUTE)); + + if ((rv = skf_method->GetObjectInfo( + hApplication, + szFileName, + pFileInfo)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETFILEINFO, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ReadFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_READFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ReadObject) { + SKFerr(SKF_F_SKF_READFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ReadObject( + hApplication, + szFileName, + ulOffset, + ulSize, + pbOutData, + pulOutLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_READFILE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_WriteFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_WRITEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->WriteObject) { + SKFerr(SKF_F_SKF_WRITEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->WriteObject( + hApplication, + szFileName, + ulOffset, + pbData, + ulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_WRITEFILE, skf_get_error_reason(rv)); + + printf("error = %08X\n", rv); + + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateContainer) { + SKFerr(SKF_F_SKF_CREATECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateContainer( + hApplication, + szContainerName, + phContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteContainer( + HAPPLICATION hApplication, + LPSTR szContainerName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteContainer) { + SKFerr(SKF_F_SKF_DELETECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteContainer( + hApplication, + szContainerName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumContainer) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumContainer( + hApplication, + szContainerName, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_OPENCONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->OpenContainer) { + SKFerr(SKF_F_SKF_OPENCONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->OpenContainer( + hApplication, + szContainerName, + phContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENCONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseContainer( + HCONTAINER hContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseContainer) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseContainer( + hContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetContainerType( + HCONTAINER hContainer, + ULONG *pulContainerType) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetContainerType) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetContainerType( + hContainer, + pulContainerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportCertificate( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportCertificate) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ImportCertificate( + hContainer, + bExportSignKey, + pbCert, + ulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportCertificate( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExportCertificate) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExportCertificate( + hContainer, + bSignFlag, + pbCert, + pulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportPublicKey( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen) +{ + ULONG rv; + + // TODO: check the output length, clear the memmory. + // if pbBlob is NULL, return the length + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExportPublicKey) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExportPublicKey( + hContainer, + bSignFlag, + pbBlob, + pulBlobLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRandom( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENRANDOM, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenRandom) { + SKFerr(SKF_F_SKF_GENRANDOM, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenRandom( + hDev, + pbRandom, + ulRandomLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENRANDOM, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenExtRSAKey( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenExtRSAKey) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenExtRSAKey( + hDev, + ulBitsLen, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRSAKeyPair( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenRSAKeyPair) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pBlob, 0, sizeof(RSAPUBLICKEYBLOB)); + if ((rv = skf_method->GenRSAKeyPair( + hContainer, + ulBitsLen, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportRSAKeyPair( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportRSAKeyPair) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulSymAlgId = skf_vendor->get_cipher_algor(ulSymAlgId))) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ImportRSAKeyPair( + hContainer, + ulSymAlgId, + pbWrappedKey, + ulWrappedKeyLen, + pbEncryptedData, + ulEncryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSASignData( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSASIGNDATA, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSASignData) { + SKFerr(SKF_F_SKF_RSASIGNDATA, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->RSASignData( + hContainer, + pbData, + ulDataLen, + pbSignature, + pulSignLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSASIGNDATA, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAVerify( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSAVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSAVerify) { + SKFerr(SKF_F_SKF_RSAVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->RSAVerify( + hDev, + pRSAPubKeyBlob, + pbData, + ulDataLen, + pbSignature, + ulSignLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSAVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSAExportSessionKey) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->RSAExportSessionKey( + hContainer, + ulAlgId, + pPubKey, + pbData, + pulDataLen, + phSessionKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPubKeyOperation( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtRSAPubKeyOperation) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtRSAPubKeyOperation( + hDev, + pRSAPubKeyBlob, + pbInput, + ulInputLen, + pbOutput, + pulOutputLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPriKeyOperation( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtRSAPriKeyOperation) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtRSAPriKeyOperation( + hDev, + pRSAPriKeyBlob, + pbInput, + ulInputLen, + pbOutput, + pulOutputLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenECCKeyPair( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenECCKeyPair) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_pkey_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_NOT_SUPPORTED_PKEY_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + memset(pBlob, 0, sizeof(ECCPUBLICKEYBLOB)); + if ((rv = skf_method->GenECCKeyPair( + hContainer, + ulAlgId, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportECCKeyPair( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportECCKeyPair) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ImportECCKeyPair( + hContainer, + pEnvelopedKeyBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, skf_get_error_reason(rv)); + printf("%s %d: error = %08X\n", __FILE__, __LINE__, rv); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCSignData( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCSignData) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCSignData( + hContainer, + pbDigest, + ulDigestLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCVerify) { + SKFerr(SKF_F_SKF_ECCVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCVerify( + hDev, + pECCPubKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCExportSessionKey) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ECCExportSessionKey( + hContainer, + ulAlgId, + pPubKey, + pData, + phSessionKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCDecrypt( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCDECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCDecrypt) { + SKFerr(SKF_F_SKF_ECCDECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCDecrypt( + hContainer, + pCipherText, + pbPlainText, + pulPlainTextLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCDECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCEncrypt( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCEncrypt) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCEncrypt( + hDev, + pECCPubKeyBlob, + pbPlainText, + ulPlainTextLen, + pCipherText)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCDecrypt( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCDecrypt) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCDecrypt( + hDev, + pECCPriKeyBlob, + pCipherText, + pbPlainText, + pulPlainTextLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCSign( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCSIGN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCSign) { + SKFerr(SKF_F_SKF_EXTECCSIGN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCSign( + hDev, + pECCPriKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCSIGN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCVerify) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCVerify( + hDev, + pECCPubKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataWithECC( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateAgreementDataWithECC) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->GenerateAgreementDataWithECC( + hContainer, + ulAlgId, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + phAgreementHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateAgreementDataAndKeyWithECC) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->GenerateAgreementDataAndKeyWithECC( + hContainer, + ulAlgId, + pSponsorECCPubKeyBlob, + pSponsorTempECCPubKeyBlob, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + pbSponsorID, + ulSponsorIDLen, + phKeyHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateKeyWithECC( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateKeyWithECC) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenerateKeyWithECC( + hAgreementHandle, + pECCPubKeyBlob, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + phKeyHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportSessionKey) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ImportSessionKey( + hContainer, + ulAlgId, + pbWrapedData, + ulWrapedLen, + phKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_SetSymmKey( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->SetSymmKey) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgID = skf_vendor->get_cipher_algor(ulAlgID))) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->SetSymmKey( + hDev, + pbKey, + ulAlgID, + phKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_SETSYMMKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptInit) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptInit( + hKey, + EncryptParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Encrypt( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Encrypt) { + SKFerr(SKF_F_SKF_ENCRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Encrypt( + hKey, + pbData, + ulDataLen, + pbEncryptedData, + pulEncryptedLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptUpdate( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptUpdate) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptUpdate( + hKey, + pbData, + ulDataLen, + pbEncryptedData, + pulEncryptedLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptFinal( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptFinal) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptFinal( + hKey, + pbEncryptedData, + pulEncryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptInit) { + SKFerr(SKF_F_SKF_DECRYPTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptInit( + hKey, + DecryptParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Decrypt( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Decrypt) { + SKFerr(SKF_F_SKF_DECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Decrypt( + hKey, + pbEncryptedData, + ulEncryptedLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptUpdate( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptUpdate) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptUpdate( + hKey, + pbEncryptedData, + ulEncryptedLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptFinal( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptFinal) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptFinal( + hKey, + pbDecryptedData, + pulDecryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestInit( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestInit) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgID = skf_vendor->get_digest_algor(ulAlgID))) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_NOT_SUPPORTED_DIGEST_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->DigestInit( + hDev, + ulAlgID, + pPubKey, + pbID, + ulIDLen, + phHash)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Digest( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGEST, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Digest) { + SKFerr(SKF_F_SKF_DIGEST, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Digest( + hHash, + pbData, + ulDataLen, + pbHashData, + pulHashLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGEST, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestUpdate( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestUpdate) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DigestUpdate( + hHash, + pbData, + ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestFinal( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestFinal) { + SKFerr(SKF_F_SKF_DIGESTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DigestFinal( + hHash, + pHashData, + pulHashLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacInit( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacInit) { + SKFerr(SKF_F_SKF_MACINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacInit( + hKey, + pMacParam, + phMac)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Mac( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MAC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Mac) { + SKFerr(SKF_F_SKF_MAC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Mac( + hMac, + pbData, + ulDataLen, + pbMacData, + pulMacLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MAC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacUpdate( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacUpdate) { + SKFerr(SKF_F_SKF_MACUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacUpdate( + hMac, + pbData, + ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacFinal( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacFinal) { + SKFerr(SKF_F_SKF_MACFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacFinal( + hMac, + pbMacData, + pulMacDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseHandle( + HANDLE hHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseHandle) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseHandle( + hHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + diff --git a/src/skf/skf_meth.c b/src/skf/skf_meth.c index 48a91ec4..e10746c3 100644 --- a/src/skf/skf_meth.c +++ b/src/skf/skf_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,131 +7,132 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include "skf.h" -#include "skf_ext.h" -#include "skf_int.h" - -#define SKFerr(e,r) - -#define SKF_METHOD_BIND_FUNCTION_EX(func,name) \ - skf->func = (SKF_##func##_FuncPtr)dlsym(skf->dso, "SKF_"#name) - -#define SKF_METHOD_BIND_FUNCTION(func) \ - SKF_METHOD_BIND_FUNCTION_EX(func,func) - - -SKF_METHOD *SKF_METHOD_load_library(const char *so_path) -{ - SKF_METHOD *ret = NULL; - SKF_METHOD *skf = NULL; - - if (!(skf = malloc(sizeof(*skf)))) { - SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); - goto end; - } - if (!(skf->dso = dlopen(so_path, RTLD_LAZY))) { - SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, SKF_R_DSO_LOAD_FAILURE); - goto end; - } - - SKF_METHOD_BIND_FUNCTION(WaitForDevEvent); - SKF_METHOD_BIND_FUNCTION(CancelWaitForDevEvent); - SKF_METHOD_BIND_FUNCTION(EnumDev); - SKF_METHOD_BIND_FUNCTION(ConnectDev); - SKF_METHOD_BIND_FUNCTION(DisConnectDev); - SKF_METHOD_BIND_FUNCTION(GetDevState); - SKF_METHOD_BIND_FUNCTION(SetLabel); - SKF_METHOD_BIND_FUNCTION(GetDevInfo); - SKF_METHOD_BIND_FUNCTION(LockDev); - SKF_METHOD_BIND_FUNCTION(UnlockDev); - SKF_METHOD_BIND_FUNCTION(Transmit); - SKF_METHOD_BIND_FUNCTION(ChangeDevAuthKey); - SKF_METHOD_BIND_FUNCTION(DevAuth); - SKF_METHOD_BIND_FUNCTION(ChangePIN); - SKF_METHOD_BIND_FUNCTION(GetPINInfo); - SKF_METHOD_BIND_FUNCTION(VerifyPIN); - SKF_METHOD_BIND_FUNCTION(UnblockPIN); - SKF_METHOD_BIND_FUNCTION(ClearSecureState); - SKF_METHOD_BIND_FUNCTION(CreateApplication); - SKF_METHOD_BIND_FUNCTION(EnumApplication); - SKF_METHOD_BIND_FUNCTION(DeleteApplication); - SKF_METHOD_BIND_FUNCTION(OpenApplication); - SKF_METHOD_BIND_FUNCTION(CloseApplication); - SKF_METHOD_BIND_FUNCTION_EX(CreateObject,CreateFile); - SKF_METHOD_BIND_FUNCTION_EX(DeleteObject,DeleteFile); - SKF_METHOD_BIND_FUNCTION_EX(EnumObjects,EnumFiles); - SKF_METHOD_BIND_FUNCTION_EX(GetObjectInfo,GetFileInfo); - SKF_METHOD_BIND_FUNCTION_EX(ReadObject,ReadFile); - SKF_METHOD_BIND_FUNCTION_EX(WriteObject,WriteFile); - SKF_METHOD_BIND_FUNCTION(CreateContainer); - SKF_METHOD_BIND_FUNCTION(DeleteContainer); - SKF_METHOD_BIND_FUNCTION(EnumContainer); - SKF_METHOD_BIND_FUNCTION(OpenContainer); - SKF_METHOD_BIND_FUNCTION(CloseContainer); - SKF_METHOD_BIND_FUNCTION(GetContainerType); - SKF_METHOD_BIND_FUNCTION(ImportCertificate); - SKF_METHOD_BIND_FUNCTION(ExportCertificate); - SKF_METHOD_BIND_FUNCTION(ExportPublicKey); - SKF_METHOD_BIND_FUNCTION(GenRandom); - SKF_METHOD_BIND_FUNCTION(GenExtRSAKey); - SKF_METHOD_BIND_FUNCTION(GenRSAKeyPair); - SKF_METHOD_BIND_FUNCTION(ImportRSAKeyPair); - SKF_METHOD_BIND_FUNCTION(RSASignData); - SKF_METHOD_BIND_FUNCTION(RSAVerify); - SKF_METHOD_BIND_FUNCTION(RSAExportSessionKey); - SKF_METHOD_BIND_FUNCTION(ExtRSAPubKeyOperation); - SKF_METHOD_BIND_FUNCTION(ExtRSAPriKeyOperation); - SKF_METHOD_BIND_FUNCTION(GenECCKeyPair); - SKF_METHOD_BIND_FUNCTION(ImportECCKeyPair); - SKF_METHOD_BIND_FUNCTION(ECCSignData); - SKF_METHOD_BIND_FUNCTION(ECCVerify); - SKF_METHOD_BIND_FUNCTION(ECCExportSessionKey); - SKF_METHOD_BIND_FUNCTION(ExtECCEncrypt); - SKF_METHOD_BIND_FUNCTION(ExtECCDecrypt); - SKF_METHOD_BIND_FUNCTION(ExtECCSign); - SKF_METHOD_BIND_FUNCTION(ExtECCVerify); - SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataWithECC); - SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataAndKeyWithECC); - SKF_METHOD_BIND_FUNCTION(GenerateKeyWithECC); - SKF_METHOD_BIND_FUNCTION(ImportSessionKey); - SKF_METHOD_BIND_FUNCTION(SetSymmKey); - SKF_METHOD_BIND_FUNCTION(EncryptInit); - SKF_METHOD_BIND_FUNCTION(Encrypt); - SKF_METHOD_BIND_FUNCTION(EncryptUpdate); - SKF_METHOD_BIND_FUNCTION(EncryptFinal); - SKF_METHOD_BIND_FUNCTION(DecryptInit); - SKF_METHOD_BIND_FUNCTION(Decrypt); - SKF_METHOD_BIND_FUNCTION(DecryptUpdate); - SKF_METHOD_BIND_FUNCTION(DecryptFinal); - SKF_METHOD_BIND_FUNCTION(DigestInit); - SKF_METHOD_BIND_FUNCTION(Digest); - SKF_METHOD_BIND_FUNCTION(DigestUpdate); - SKF_METHOD_BIND_FUNCTION(DigestFinal); - SKF_METHOD_BIND_FUNCTION(MacInit); - SKF_METHOD_BIND_FUNCTION(Mac); - SKF_METHOD_BIND_FUNCTION(MacUpdate); - SKF_METHOD_BIND_FUNCTION(MacFinal); - SKF_METHOD_BIND_FUNCTION(CloseHandle); -#ifdef SKF_HAS_ECCDECRYPT - SKF_METHOD_BIND_FUNCTION(ECCDecrypt); -#endif - - ret = skf; - skf = NULL; - -end: - SKF_METHOD_free(skf); - return ret; -} - -void SKF_METHOD_free(SKF_METHOD *meth) -{ - if (meth) - free(meth->dso); - free(meth); -} + + +#include +#include +#include +#include +#include "skf.h" +#include "skf_ext.h" +#include "skf_int.h" + +#define SKFerr(e,r) + +#define SKF_METHOD_BIND_FUNCTION_EX(func,name) \ + skf->func = (SKF_##func##_FuncPtr)dlsym(skf->dso, "SKF_"#name) + +#define SKF_METHOD_BIND_FUNCTION(func) \ + SKF_METHOD_BIND_FUNCTION_EX(func,func) + + +SKF_METHOD *SKF_METHOD_load_library(const char *so_path) +{ + SKF_METHOD *ret = NULL; + SKF_METHOD *skf = NULL; + + if (!(skf = malloc(sizeof(*skf)))) { + SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!(skf->dso = dlopen(so_path, RTLD_LAZY))) { + SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, SKF_R_DSO_LOAD_FAILURE); + goto end; + } + + SKF_METHOD_BIND_FUNCTION(WaitForDevEvent); + SKF_METHOD_BIND_FUNCTION(CancelWaitForDevEvent); + SKF_METHOD_BIND_FUNCTION(EnumDev); + SKF_METHOD_BIND_FUNCTION(ConnectDev); + SKF_METHOD_BIND_FUNCTION(DisConnectDev); + SKF_METHOD_BIND_FUNCTION(GetDevState); + SKF_METHOD_BIND_FUNCTION(SetLabel); + SKF_METHOD_BIND_FUNCTION(GetDevInfo); + SKF_METHOD_BIND_FUNCTION(LockDev); + SKF_METHOD_BIND_FUNCTION(UnlockDev); + SKF_METHOD_BIND_FUNCTION(Transmit); + SKF_METHOD_BIND_FUNCTION(ChangeDevAuthKey); + SKF_METHOD_BIND_FUNCTION(DevAuth); + SKF_METHOD_BIND_FUNCTION(ChangePIN); + SKF_METHOD_BIND_FUNCTION(GetPINInfo); + SKF_METHOD_BIND_FUNCTION(VerifyPIN); + SKF_METHOD_BIND_FUNCTION(UnblockPIN); + SKF_METHOD_BIND_FUNCTION(ClearSecureState); + SKF_METHOD_BIND_FUNCTION(CreateApplication); + SKF_METHOD_BIND_FUNCTION(EnumApplication); + SKF_METHOD_BIND_FUNCTION(DeleteApplication); + SKF_METHOD_BIND_FUNCTION(OpenApplication); + SKF_METHOD_BIND_FUNCTION(CloseApplication); + SKF_METHOD_BIND_FUNCTION_EX(CreateObject,CreateFile); + SKF_METHOD_BIND_FUNCTION_EX(DeleteObject,DeleteFile); + SKF_METHOD_BIND_FUNCTION_EX(EnumObjects,EnumFiles); + SKF_METHOD_BIND_FUNCTION_EX(GetObjectInfo,GetFileInfo); + SKF_METHOD_BIND_FUNCTION_EX(ReadObject,ReadFile); + SKF_METHOD_BIND_FUNCTION_EX(WriteObject,WriteFile); + SKF_METHOD_BIND_FUNCTION(CreateContainer); + SKF_METHOD_BIND_FUNCTION(DeleteContainer); + SKF_METHOD_BIND_FUNCTION(EnumContainer); + SKF_METHOD_BIND_FUNCTION(OpenContainer); + SKF_METHOD_BIND_FUNCTION(CloseContainer); + SKF_METHOD_BIND_FUNCTION(GetContainerType); + SKF_METHOD_BIND_FUNCTION(ImportCertificate); + SKF_METHOD_BIND_FUNCTION(ExportCertificate); + SKF_METHOD_BIND_FUNCTION(ExportPublicKey); + SKF_METHOD_BIND_FUNCTION(GenRandom); + SKF_METHOD_BIND_FUNCTION(GenExtRSAKey); + SKF_METHOD_BIND_FUNCTION(GenRSAKeyPair); + SKF_METHOD_BIND_FUNCTION(ImportRSAKeyPair); + SKF_METHOD_BIND_FUNCTION(RSASignData); + SKF_METHOD_BIND_FUNCTION(RSAVerify); + SKF_METHOD_BIND_FUNCTION(RSAExportSessionKey); + SKF_METHOD_BIND_FUNCTION(ExtRSAPubKeyOperation); + SKF_METHOD_BIND_FUNCTION(ExtRSAPriKeyOperation); + SKF_METHOD_BIND_FUNCTION(GenECCKeyPair); + SKF_METHOD_BIND_FUNCTION(ImportECCKeyPair); + SKF_METHOD_BIND_FUNCTION(ECCSignData); + SKF_METHOD_BIND_FUNCTION(ECCVerify); + SKF_METHOD_BIND_FUNCTION(ECCExportSessionKey); + SKF_METHOD_BIND_FUNCTION(ExtECCEncrypt); + SKF_METHOD_BIND_FUNCTION(ExtECCDecrypt); + SKF_METHOD_BIND_FUNCTION(ExtECCSign); + SKF_METHOD_BIND_FUNCTION(ExtECCVerify); + SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataWithECC); + SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataAndKeyWithECC); + SKF_METHOD_BIND_FUNCTION(GenerateKeyWithECC); + SKF_METHOD_BIND_FUNCTION(ImportSessionKey); + SKF_METHOD_BIND_FUNCTION(SetSymmKey); + SKF_METHOD_BIND_FUNCTION(EncryptInit); + SKF_METHOD_BIND_FUNCTION(Encrypt); + SKF_METHOD_BIND_FUNCTION(EncryptUpdate); + SKF_METHOD_BIND_FUNCTION(EncryptFinal); + SKF_METHOD_BIND_FUNCTION(DecryptInit); + SKF_METHOD_BIND_FUNCTION(Decrypt); + SKF_METHOD_BIND_FUNCTION(DecryptUpdate); + SKF_METHOD_BIND_FUNCTION(DecryptFinal); + SKF_METHOD_BIND_FUNCTION(DigestInit); + SKF_METHOD_BIND_FUNCTION(Digest); + SKF_METHOD_BIND_FUNCTION(DigestUpdate); + SKF_METHOD_BIND_FUNCTION(DigestFinal); + SKF_METHOD_BIND_FUNCTION(MacInit); + SKF_METHOD_BIND_FUNCTION(Mac); + SKF_METHOD_BIND_FUNCTION(MacUpdate); + SKF_METHOD_BIND_FUNCTION(MacFinal); + SKF_METHOD_BIND_FUNCTION(CloseHandle); +#ifdef SKF_HAS_ECCDECRYPT + SKF_METHOD_BIND_FUNCTION(ECCDecrypt); +#endif + + ret = skf; + skf = NULL; + +end: + SKF_METHOD_free(skf); + return ret; +} + +void SKF_METHOD_free(SKF_METHOD *meth) +{ + if (meth) + free(meth->dso); + free(meth); +} diff --git a/src/skf/skf_prn.c b/src/skf/skf_prn.c index 04238d41..8bf3b07d 100644 --- a/src/skf/skf_prn.c +++ b/src/skf/skf_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,280 +7,281 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include "skf.h" -#include "skf_int.h" -#include "skf_ext.h" - - - -static char *skf_algor_name(ULONG ulAlgID) -{ - switch (ulAlgID) { - case SGD_SM1_ECB: return "sm1-ecb"; - case SGD_SM1_CBC: return "sm1-cbc"; - case SGD_SM1_CFB: return "sm1-cfb"; - case SGD_SM1_OFB: return "sm1-ofb128"; - case SGD_SM1_MAC: return "sm1-mac"; - case SGD_SM4_ECB: return "sms4-ecb"; - case SGD_SM4_CBC: return "sms4-cbc"; - case SGD_SM4_CFB: return "sms4-cfb"; - case SGD_SM4_OFB: return "sms4-ofb128"; - case SGD_SM4_MAC: return "sms4-mac"; - case SGD_SSF33_ECB: return "ssf33-ecb"; - case SGD_SSF33_CBC: return "ssf33-cbc"; - case SGD_SSF33_CFB: return "ssf33-cfb"; - case SGD_SSF33_OFB: return "ssf33-ofb128"; - case SGD_SSF33_MAC: return "ssf33-mac"; - case SGD_RSA: return "rsa"; - case SGD_SM2_1: return "sm2sign"; - case SGD_SM2_2: return "sm2encrypt"; - case SGD_SM2_3: return "sm2keyagreement"; - case SGD_SM3: return "sm3"; - case SGD_SHA1: return "sha1"; - case SGD_SHA256: return "sha256"; - } - return NULL; -} - -ULONG SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) -{ - if (!szDevStateName) { - return SAR_INDATALENERR; - } - - switch (ulDevState) { - case SKF_DEV_STATE_ABSENT: - *szDevStateName = (LPSTR)"Absent"; - break; - case SKF_DEV_STATE_PRESENT: - *szDevStateName = (LPSTR)"Present"; - break; - case SKF_DEV_STATE_UNKNOW: - *szDevStateName = (LPSTR)"Unknown"; - break; - default: - *szDevStateName = (LPSTR)"(Error)"; - return SAR_INDATALENERR; - } - - return SAR_OK; -} - -ULONG SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName) -{ - switch (ulContainerType) { - case SKF_CONTAINER_TYPE_UNDEF: - *szName = (LPSTR)"(undef)"; - break; - case SKF_CONTAINER_TYPE_RSA: - *szName = (LPSTR)"RSA"; - break; - case SKF_CONTAINER_TYPE_ECC: - *szName = (LPSTR)"EC"; - break; - default: - *szName = (LPSTR)"(unknown)"; - } - /* always success for help functions */ - return SAR_OK; -} - -typedef struct { - ULONG id; - char *name; -} table_item_t; - -static table_item_t skf_cipher_caps[] = { - { SGD_SM1_ECB, "sm1-ecb" }, - { SGD_SM1_CBC, "sm1-cbc" }, - { SGD_SM1_CFB, "sm1-cfb" }, - { SGD_SM1_OFB, "sm1-ofb128" }, - { SGD_SM1_MAC, "cbcmac-sm1" }, - { SGD_SSF33_ECB, "ssf33-ecb" }, - { SGD_SSF33_CBC, "ssf33-cbc" }, - { SGD_SSF33_CFB, "ssf33-cfb" }, - { SGD_SSF33_OFB, "ssf33-ofb128" }, - { SGD_SSF33_MAC, "cbcmac-ssf33" }, - { SGD_SM4_ECB, "sms4-ecb" }, - { SGD_SM4_CBC, "sms4-cbc" }, - { SGD_SM4_CFB, "sms4-cfb" }, - { SGD_SM4_OFB, "sms4-ofb128" }, - { SGD_SM4_MAC, "cbcmac-sms4" }, - { SGD_ZUC_EEA3, "zuc_128eea3" }, - { SGD_ZUC_EIA3, "zuc_128eia3" } -}; - -static table_item_t skf_digest_caps[] = { - { SGD_SM3, "sm3" }, - { SGD_SHA1, "sha1" }, - { SGD_SHA256, "sha256" }, -}; - -static table_item_t skf_pkey_caps[] = { - { SGD_RSA_SIGN, "rsa" }, - { SGD_RSA_ENC, "rsaEncryption" }, - { SGD_SM2_1, "sm2sign" }, - { SGD_SM2_2, "sm2exchange" }, - { SGD_SM2_3, "sm2encrypt" } -}; - -ULONG SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) -{ - size_t i, n; - int fmt = 0, ind = 4; - - format_print(fp, fmt, ind, "Version: %d.%d\n", devInfo->Version.major, devInfo->Version.minor); - format_print(fp, fmt, ind, "Manufacturer: %s\n", devInfo->Manufacturer); - format_print(fp, fmt, ind, "Issuer: %s\n", devInfo->Issuer); - format_print(fp, fmt, ind, "Label: %s\n", devInfo->Label); - format_bytes(fp, fmt, ind, "SerialNumber", devInfo->SerialNumber, strlen((char *)devInfo->SerialNumber)); - format_print(fp, fmt, ind, "FirmwareVersion: %d.%d\n", devInfo->HWVersion.major, devInfo->HWVersion.minor); - - format_print(fp, fmt, ind, "Ciphers: "); - for (i = n = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { - if ((devInfo->AlgSymCap & skf_cipher_caps[i].id) == - skf_cipher_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_cipher_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - - format_print(fp, fmt, ind, "Public Keys: "); - for (i = n = 0; i < sizeof(skf_pkey_caps)/sizeof(skf_pkey_caps[0]); i++) { - if ((devInfo->AlgAsymCap & skf_pkey_caps[i].id) == - skf_pkey_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_pkey_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - - format_print(fp, fmt, ind, "Digests: "); - for (i = n = 0; i < sizeof(skf_digest_caps)/sizeof(skf_digest_caps[0]); i++) { - if ((devInfo->AlgHashCap & skf_digest_caps[i].id) == - skf_digest_caps[i].id) { - format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_digest_caps[i].name); - n++; - } - } - format_print(fp, fmt, 0, "\n"); - - format_print(fp, fmt, ind, "AuthCipher"); - for (i = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { - if (devInfo->DevAuthAlgId == skf_cipher_caps[i].id) { - format_print(fp, fmt, 0, "%s\n", skf_cipher_caps[i].name); - break; - } - } - if (i == sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0])) { - format_print(fp, fmt, 0, "(unknown)\n"); - } - format_print(fp, fmt, 0, "\n"); - - - - if (devInfo->TotalSpace == UINT_MAX) - format_print(fp, fmt, ind, "Total Sapce: %s\n", "(unlimited)"); - else format_print(fp, fmt, ind, "Total Sapce: %u\n", devInfo->TotalSpace); - - if (devInfo->FreeSpace == UINT_MAX) - format_print(fp, fmt, ind, "Free Space: %s\n", "(unlimited)"); - else format_print(fp, fmt, ind, "Free Space: %u\n", devInfo->FreeSpace); - - if (devInfo->MaxECCBufferSize == UINT_MAX) - format_print(fp, fmt, ind, "MAX ECC Input: %s\n", "(unlimited)"); - else format_print(fp, fmt, ind, "MAX ECC Input: %u\n", devInfo->MaxECCBufferSize); - - if (devInfo->MaxBufferSize == UINT_MAX) - format_print(fp, fmt, ind, "MAX Cipher Input: %s\n", "(unlimited)"); - else format_print(fp, fmt, ind, "MAX Cipher Input: %u\n", devInfo->MaxBufferSize); - - return SAR_OK; -} - -ULONG SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) -{ - int fmt = 0, ind = 4; - format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); - format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); - format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); - format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); - return SAR_OK; -} - -ULONG SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) -{ - int fmt = 0, ind = 4; - format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); - format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); - format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); - format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); - format_bytes(fp, fmt, ind, "PrivateExponent", blob->PrivateExponent, MAX_RSA_MODULUS_LEN); - format_bytes(fp, fmt, ind, "Prime1", blob->Prime1, MAX_RSA_MODULUS_LEN/2); - format_bytes(fp, fmt, ind, "Prime2", blob->Prime2, MAX_RSA_MODULUS_LEN/2); - format_bytes(fp, fmt, ind, "Prime1Exponent", blob->Prime1Exponent, MAX_RSA_MODULUS_LEN/2); - format_bytes(fp, fmt, ind, "Prime2Exponent", blob->Prime2Exponent, MAX_RSA_MODULUS_LEN/2); - format_bytes(fp, fmt, ind, "Coefficient", blob->Coefficient, MAX_RSA_MODULUS_LEN/2); - return SAR_OK; -} - -ULONG SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) -{ - int fmt = 0, ind = 4; - format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); - format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); - format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); - return SAR_OK; -} - -ULONG SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) -{ - int fmt = 0, ind = 4; - format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); - format_bytes(fp, fmt, ind, "PrivateKey", blob->PrivateKey, ECC_MAX_MODULUS_BITS_LEN/8); - return SAR_OK; -} - -ULONG SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) -{ - int fmt = 0, ind = 4; - format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); - format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); - format_bytes(fp, fmt, ind, "HASH", blob->HASH, 32); - format_print(fp, fmt, ind, "CipherLen: %u\n", blob->CipherLen); - format_bytes(fp, fmt, ind, "Cipher", blob->Cipher, blob->CipherLen); - return SAR_OK; -} - -ULONG SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob) -{ - int fmt = 0, ind = 4; - format_bytes(fp, fmt, ind, "r", blob->r, ECC_MAX_XCOORDINATE_BITS_LEN/8); - format_bytes(fp, fmt, ind, "s", blob->s, ECC_MAX_XCOORDINATE_BITS_LEN/8); - return SAR_OK; -} - -ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName) -{ - char *name; - if ((name = skf_algor_name(ulAlgID)) != NULL) { - *szName = (LPSTR)&name; - return SAR_OK; - } - return SAR_FAIL; -} - -ULONG DEVAPI SKF_PrintErrorString(FILE *fp, ULONG ulError) -{ - LPSTR str = NULL; - SKF_GetErrorString(ulError, &str); - fprintf(fp, "SKF Error: %s\n", (char *)str); - return SAR_OK; -} + + +#include +#include +#include +#include +#include +#include "skf.h" +#include "skf_int.h" +#include "skf_ext.h" + + + +static char *skf_algor_name(ULONG ulAlgID) +{ + switch (ulAlgID) { + case SGD_SM1_ECB: return "sm1-ecb"; + case SGD_SM1_CBC: return "sm1-cbc"; + case SGD_SM1_CFB: return "sm1-cfb"; + case SGD_SM1_OFB: return "sm1-ofb128"; + case SGD_SM1_MAC: return "sm1-mac"; + case SGD_SM4_ECB: return "sms4-ecb"; + case SGD_SM4_CBC: return "sms4-cbc"; + case SGD_SM4_CFB: return "sms4-cfb"; + case SGD_SM4_OFB: return "sms4-ofb128"; + case SGD_SM4_MAC: return "sms4-mac"; + case SGD_SSF33_ECB: return "ssf33-ecb"; + case SGD_SSF33_CBC: return "ssf33-cbc"; + case SGD_SSF33_CFB: return "ssf33-cfb"; + case SGD_SSF33_OFB: return "ssf33-ofb128"; + case SGD_SSF33_MAC: return "ssf33-mac"; + case SGD_RSA: return "rsa"; + case SGD_SM2_1: return "sm2sign"; + case SGD_SM2_2: return "sm2encrypt"; + case SGD_SM2_3: return "sm2keyagreement"; + case SGD_SM3: return "sm3"; + case SGD_SHA1: return "sha1"; + case SGD_SHA256: return "sha256"; + } + return NULL; +} + +ULONG SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) +{ + if (!szDevStateName) { + return SAR_INDATALENERR; + } + + switch (ulDevState) { + case SKF_DEV_STATE_ABSENT: + *szDevStateName = (LPSTR)"Absent"; + break; + case SKF_DEV_STATE_PRESENT: + *szDevStateName = (LPSTR)"Present"; + break; + case SKF_DEV_STATE_UNKNOW: + *szDevStateName = (LPSTR)"Unknown"; + break; + default: + *szDevStateName = (LPSTR)"(Error)"; + return SAR_INDATALENERR; + } + + return SAR_OK; +} + +ULONG SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName) +{ + switch (ulContainerType) { + case SKF_CONTAINER_TYPE_UNDEF: + *szName = (LPSTR)"(undef)"; + break; + case SKF_CONTAINER_TYPE_RSA: + *szName = (LPSTR)"RSA"; + break; + case SKF_CONTAINER_TYPE_ECC: + *szName = (LPSTR)"EC"; + break; + default: + *szName = (LPSTR)"(unknown)"; + } + /* always success for help functions */ + return SAR_OK; +} + +typedef struct { + ULONG id; + char *name; +} table_item_t; + +static table_item_t skf_cipher_caps[] = { + { SGD_SM1_ECB, "sm1-ecb" }, + { SGD_SM1_CBC, "sm1-cbc" }, + { SGD_SM1_CFB, "sm1-cfb" }, + { SGD_SM1_OFB, "sm1-ofb128" }, + { SGD_SM1_MAC, "cbcmac-sm1" }, + { SGD_SSF33_ECB, "ssf33-ecb" }, + { SGD_SSF33_CBC, "ssf33-cbc" }, + { SGD_SSF33_CFB, "ssf33-cfb" }, + { SGD_SSF33_OFB, "ssf33-ofb128" }, + { SGD_SSF33_MAC, "cbcmac-ssf33" }, + { SGD_SM4_ECB, "sms4-ecb" }, + { SGD_SM4_CBC, "sms4-cbc" }, + { SGD_SM4_CFB, "sms4-cfb" }, + { SGD_SM4_OFB, "sms4-ofb128" }, + { SGD_SM4_MAC, "cbcmac-sms4" }, + { SGD_ZUC_EEA3, "zuc_128eea3" }, + { SGD_ZUC_EIA3, "zuc_128eia3" } +}; + +static table_item_t skf_digest_caps[] = { + { SGD_SM3, "sm3" }, + { SGD_SHA1, "sha1" }, + { SGD_SHA256, "sha256" }, +}; + +static table_item_t skf_pkey_caps[] = { + { SGD_RSA_SIGN, "rsa" }, + { SGD_RSA_ENC, "rsaEncryption" }, + { SGD_SM2_1, "sm2sign" }, + { SGD_SM2_2, "sm2exchange" }, + { SGD_SM2_3, "sm2encrypt" } +}; + +ULONG SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) +{ + size_t i, n; + int fmt = 0, ind = 4; + + format_print(fp, fmt, ind, "Version: %d.%d\n", devInfo->Version.major, devInfo->Version.minor); + format_print(fp, fmt, ind, "Manufacturer: %s\n", devInfo->Manufacturer); + format_print(fp, fmt, ind, "Issuer: %s\n", devInfo->Issuer); + format_print(fp, fmt, ind, "Label: %s\n", devInfo->Label); + format_bytes(fp, fmt, ind, "SerialNumber", devInfo->SerialNumber, strlen((char *)devInfo->SerialNumber)); + format_print(fp, fmt, ind, "FirmwareVersion: %d.%d\n", devInfo->HWVersion.major, devInfo->HWVersion.minor); + + format_print(fp, fmt, ind, "Ciphers: "); + for (i = n = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { + if ((devInfo->AlgSymCap & skf_cipher_caps[i].id) == + skf_cipher_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_cipher_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "Public Keys: "); + for (i = n = 0; i < sizeof(skf_pkey_caps)/sizeof(skf_pkey_caps[0]); i++) { + if ((devInfo->AlgAsymCap & skf_pkey_caps[i].id) == + skf_pkey_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_pkey_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "Digests: "); + for (i = n = 0; i < sizeof(skf_digest_caps)/sizeof(skf_digest_caps[0]); i++) { + if ((devInfo->AlgHashCap & skf_digest_caps[i].id) == + skf_digest_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_digest_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "AuthCipher"); + for (i = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { + if (devInfo->DevAuthAlgId == skf_cipher_caps[i].id) { + format_print(fp, fmt, 0, "%s\n", skf_cipher_caps[i].name); + break; + } + } + if (i == sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0])) { + format_print(fp, fmt, 0, "(unknown)\n"); + } + format_print(fp, fmt, 0, "\n"); + + + + if (devInfo->TotalSpace == UINT_MAX) + format_print(fp, fmt, ind, "Total Sapce: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "Total Sapce: %u\n", devInfo->TotalSpace); + + if (devInfo->FreeSpace == UINT_MAX) + format_print(fp, fmt, ind, "Free Space: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "Free Space: %u\n", devInfo->FreeSpace); + + if (devInfo->MaxECCBufferSize == UINT_MAX) + format_print(fp, fmt, ind, "MAX ECC Input: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "MAX ECC Input: %u\n", devInfo->MaxECCBufferSize); + + if (devInfo->MaxBufferSize == UINT_MAX) + format_print(fp, fmt, ind, "MAX Cipher Input: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "MAX Cipher Input: %u\n", devInfo->MaxBufferSize); + + return SAR_OK; +} + +ULONG SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); + return SAR_OK; +} + +ULONG SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); + format_bytes(fp, fmt, ind, "PrivateExponent", blob->PrivateExponent, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "Prime1", blob->Prime1, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime2", blob->Prime2, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime1Exponent", blob->Prime1Exponent, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime2Exponent", blob->Prime2Exponent, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Coefficient", blob->Coefficient, MAX_RSA_MODULUS_LEN/2); + return SAR_OK; +} + +ULONG SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + return SAR_OK; +} + +ULONG SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "PrivateKey", blob->PrivateKey, ECC_MAX_MODULUS_BITS_LEN/8); + return SAR_OK; +} + +ULONG SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) +{ + int fmt = 0, ind = 4; + format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "HASH", blob->HASH, 32); + format_print(fp, fmt, ind, "CipherLen: %u\n", blob->CipherLen); + format_bytes(fp, fmt, ind, "Cipher", blob->Cipher, blob->CipherLen); + return SAR_OK; +} + +ULONG SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob) +{ + int fmt = 0, ind = 4; + format_bytes(fp, fmt, ind, "r", blob->r, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "s", blob->s, ECC_MAX_XCOORDINATE_BITS_LEN/8); + return SAR_OK; +} + +ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName) +{ + char *name; + if ((name = skf_algor_name(ulAlgID)) != NULL) { + *szName = (LPSTR)&name; + return SAR_OK; + } + return SAR_FAIL; +} + +ULONG DEVAPI SKF_PrintErrorString(FILE *fp, ULONG ulError) +{ + LPSTR str = NULL; + SKF_GetErrorString(ulError, &str); + fprintf(fp, "SKF Error: %s\n", (char *)str); + return SAR_OK; +} diff --git a/src/skf/skf_wisec.c b/src/skf/skf_wisec.c index 67844ed2..b5c9f120 100644 --- a/src/skf/skf_wisec.c +++ b/src/skf/skf_wisec.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,140 +7,141 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include "skf_int.h" -#include "skf_wisec.h" - - -typedef struct { - ULONG std_id; - ULONG vendor_id; -} SKF_ALGOR_PAIR; - -static SKF_ALGOR_PAIR wisec_ciphers[] = { - { SGD_SM1, WISEC_SM1 }, - { SGD_SM1_ECB, WISEC_SM1_ECB }, - { SGD_SM1_CBC, WISEC_SM1_CBC }, - { SGD_SM1_CFB, WISEC_SM1_CFB }, - { SGD_SM1_OFB, WISEC_SM1_OFB }, - { SGD_SM1_MAC, WISEC_SM1_MAC }, - { SGD_SM4, WISEC_SM4 }, - { SGD_SM4_ECB, WISEC_SM4_ECB }, - { SGD_SM4_CBC, WISEC_SM4_CBC }, - { SGD_SM4_CFB, WISEC_SM4_CFB }, - { SGD_SM4_OFB, WISEC_SM4_OFB }, - { SGD_SM4_MAC, WISEC_SM4_MAC }, - { SGD_SSF33, WISEC_SSF33 }, - { SGD_SSF33_ECB, WISEC_SSF33_ECB }, - { SGD_SSF33_CBC, WISEC_SSF33_CBC }, - { SGD_SSF33_CFB, WISEC_SSF33_CFB }, - { SGD_SSF33_OFB, WISEC_SSF33_OFB }, - { SGD_SSF33_MAC, WISEC_SSF33_MAC }, -}; - -static ULONG wisec_get_cipher_algor(ULONG vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { - if (vendor_id == wisec_ciphers[i].vendor_id) { - return wisec_ciphers[i].std_id; - } - } - return 0; -} - -static ULONG wisec_get_cipher_cap(ULONG vendor_cap) -{ - ULONG std_cap = 0; - size_t i; - for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { - if (vendor_cap & wisec_ciphers[i].vendor_id) { - std_cap |= wisec_ciphers[i].std_id; - } - } - return std_cap; -} - -static SKF_ALGOR_PAIR wisec_digests[] = { - { SGD_SM3, WISEC_SM3 }, - { SGD_SHA1, WISEC_SHA1 }, - { SGD_SHA256, WISEC_SHA256 }, -}; - -static ULONG wisec_get_digest_algor(ULONG vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { - if (vendor_id == wisec_digests[i].vendor_id) { - return wisec_digests[i].std_id; - } - } - return 0; -} - -static ULONG wisec_get_digest_cap(ULONG vendor_cap) -{ - ULONG std_cap = 0; - size_t i; - for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { - if (vendor_cap & wisec_digests[i].vendor_id) { - std_cap |= wisec_digests[i].std_id; - } - } - return std_cap; -} - -static SKF_ALGOR_PAIR wisec_pkeys[] = { - { SGD_RSA, WISEC_RSA }, - { SGD_RSA_SIGN, WISEC_RSA_SIGN }, - { SGD_RSA_ENC, WISEC_RSA_ENC }, - { SGD_SM2, WISEC_SM2 }, - { SGD_SM2_1, WISEC_SM2_1 }, - { SGD_SM2_2, WISEC_SM2_2 }, - { SGD_SM2_3, WISEC_SM2_3 }, -}; - -static ULONG wisec_get_pkey_algor(ULONG vendor_id) -{ - size_t i; - for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { - if (vendor_id == wisec_pkeys[i].vendor_id) { - return wisec_pkeys[i].std_id; - } - } - return 0; -} - -static ULONG wisec_get_pkey_cap(ULONG vendor_cap) -{ - ULONG std_cap = 0; - size_t i; - for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { - if (vendor_cap & wisec_pkeys[i].vendor_id) { - std_cap |= wisec_pkeys[i].std_id; - } - } - return std_cap; -} - -static unsigned long wisec_get_error_reason(ULONG err) -{ - return 0; -} - -SKF_VENDOR skf_wisec = { - "wisec", - 16, - wisec_get_cipher_algor, - wisec_get_cipher_cap, - wisec_get_digest_algor, - wisec_get_digest_cap, - wisec_get_pkey_algor, - wisec_get_pkey_cap, - wisec_get_error_reason, -}; + + + +#include +#include +#include +#include +#include "skf_int.h" +#include "skf_wisec.h" + + +typedef struct { + ULONG std_id; + ULONG vendor_id; +} SKF_ALGOR_PAIR; + +static SKF_ALGOR_PAIR wisec_ciphers[] = { + { SGD_SM1, WISEC_SM1 }, + { SGD_SM1_ECB, WISEC_SM1_ECB }, + { SGD_SM1_CBC, WISEC_SM1_CBC }, + { SGD_SM1_CFB, WISEC_SM1_CFB }, + { SGD_SM1_OFB, WISEC_SM1_OFB }, + { SGD_SM1_MAC, WISEC_SM1_MAC }, + { SGD_SM4, WISEC_SM4 }, + { SGD_SM4_ECB, WISEC_SM4_ECB }, + { SGD_SM4_CBC, WISEC_SM4_CBC }, + { SGD_SM4_CFB, WISEC_SM4_CFB }, + { SGD_SM4_OFB, WISEC_SM4_OFB }, + { SGD_SM4_MAC, WISEC_SM4_MAC }, + { SGD_SSF33, WISEC_SSF33 }, + { SGD_SSF33_ECB, WISEC_SSF33_ECB }, + { SGD_SSF33_CBC, WISEC_SSF33_CBC }, + { SGD_SSF33_CFB, WISEC_SSF33_CFB }, + { SGD_SSF33_OFB, WISEC_SSF33_OFB }, + { SGD_SSF33_MAC, WISEC_SSF33_MAC }, +}; + +static ULONG wisec_get_cipher_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { + if (vendor_id == wisec_ciphers[i].vendor_id) { + return wisec_ciphers[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_cipher_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { + if (vendor_cap & wisec_ciphers[i].vendor_id) { + std_cap |= wisec_ciphers[i].std_id; + } + } + return std_cap; +} + +static SKF_ALGOR_PAIR wisec_digests[] = { + { SGD_SM3, WISEC_SM3 }, + { SGD_SHA1, WISEC_SHA1 }, + { SGD_SHA256, WISEC_SHA256 }, +}; + +static ULONG wisec_get_digest_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { + if (vendor_id == wisec_digests[i].vendor_id) { + return wisec_digests[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_digest_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { + if (vendor_cap & wisec_digests[i].vendor_id) { + std_cap |= wisec_digests[i].std_id; + } + } + return std_cap; +} + +static SKF_ALGOR_PAIR wisec_pkeys[] = { + { SGD_RSA, WISEC_RSA }, + { SGD_RSA_SIGN, WISEC_RSA_SIGN }, + { SGD_RSA_ENC, WISEC_RSA_ENC }, + { SGD_SM2, WISEC_SM2 }, + { SGD_SM2_1, WISEC_SM2_1 }, + { SGD_SM2_2, WISEC_SM2_2 }, + { SGD_SM2_3, WISEC_SM2_3 }, +}; + +static ULONG wisec_get_pkey_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { + if (vendor_id == wisec_pkeys[i].vendor_id) { + return wisec_pkeys[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_pkey_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { + if (vendor_cap & wisec_pkeys[i].vendor_id) { + std_cap |= wisec_pkeys[i].std_id; + } + } + return std_cap; +} + +static unsigned long wisec_get_error_reason(ULONG err) +{ + return 0; +} + +SKF_VENDOR skf_wisec = { + "wisec", + 16, + wisec_get_cipher_algor, + wisec_get_cipher_cap, + wisec_get_digest_algor, + wisec_get_digest_cap, + wisec_get_pkey_algor, + wisec_get_pkey_cap, + wisec_get_error_reason, +}; diff --git a/src/skf/skf_wisec.h b/src/skf/skf_wisec.h index 455ccf1e..584f8af9 100644 --- a/src/skf/skf_wisec.h +++ b/src/skf/skf_wisec.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,111 +7,112 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef HEADER_SKF_WISEC_H -#define HEADER_SKF_WISEC_H - -#include "skf.h" - - -#define WISEC_SM1 (SGD_SM1) -#define WISEC_SM1_ECB (SGD_SM1_ECB) -#define WISEC_SM1_CBC (SGD_SM1_CBC) -#define WISEC_SM1_CFB (SGD_SM1_CFB) -#define WISEC_SM1_OFB (SGD_SM1_OFB) -#define WISEC_SM1_MAC (SGD_SM1_MAC) - -#define WISEC_SSF33 (SGD_SSF33) -#define WISEC_SSF33_ECB (SGD_SSF33_ECB) -#define WISEC_SSF33_CBC (SGD_SSF33_CBC) -#define WISEC_SSF33_CFB (SGD_SSF33_CFB) -#define WISEC_SSF33_OFB (SGD_SSF33_OFB) -#define WISEC_SSF33_MAC (SGD_SSF33_MAC) - -#define WISEC_SM4 (SGD_SM4) -#define WISEC_SM4_ECB (WISEC_SM4|SGD_ECB) -#define WISEC_SM4_CBC (WISEC_SM4|SGD_CBC) -#define WISEC_SM4_CFB (WISEC_SM4|SGD_CFB) -#define WISEC_SM4_OFB (WISEC_SM4|SGD_OFB) -#define WISEC_SM4_MAC (WISEC_SM4|SGD_MAC) - -#define WISEC_AES 0x00000800 -#define WISEC_128 0x00000000 -#define WISEC_192 0x00000010 -#define WISEC_256 0x00000020 -#define WISEC_AES128 (WISEC_AES|WISEC_128) -#define WISEC_AES192 (WISEC_AES|WISEC_192) -#define WISEC_AES256 (WISEC_AES|WISEC_256) -#define WISEC_AES128_ECB (WISEC_AES128|SGD_ECB) -#define WISEC_AES128_CBC (WISEC_AES128|SGD_CBC) -#define WISEC_AES128_CFB (WISEC_AES128|SGD_CFB) -#define WISEC_AES128_OFB (WISEC_AES128|SGD_OFB) -#define WISEC_AES128_MAC (WISEC_AES128|SGD_MAC) -#define WISEC_AES192_ECB (WISEC_AES192|SGD_ECB) -#define WISEC_AES192_CBC (WISEC_AES192|SGD_CBC) -#define WISEC_AES192_CFB (WISEC_AES192|SGD_CFB) -#define WISEC_AES192_OFB (WISEC_AES192|SGD_OFB) -#define WISEC_AES192_MAC (WISEC_AES192|SGD_MAC) -#define WISEC_AES256_ECB (WISEC_AES256|SGD_ECB) -#define WISEC_AES256_CBC (WISEC_AES256|SGD_CBC) -#define WISEC_AES256_CFB (WISEC_AES256|SGD_CFB) -#define WISEC_AES256_OFB (WISEC_AES256|SGD_OFB) -#define WISEC_AES256_MAC (WISEC_AES256|SGD_MAC) - -#define WISEC_DES 0x00001000 -#define WISEC_DES_ECB (WISEC_DES|SGD_ECB) -#define WISEC_DES_CBC (WISEC_DES|SGD_CBC) -#define WISEC_DES_CFB (WISEC_DES|SGD_CFB) -#define WISEC_DES_OFB (WISEC_DES|SGD_OFB) -#define WISEC_DES_MAC (WISEC_DES|SGD_MAC) - -#define WISEC_D3DES 0x00001010 -#define WISEC_D3DES_ECB (WISEC_D3DES|SGD_ECB) -#define WISEC_D3DES_CBC (WISEC_D3DES|SGD_CBC) -#define WISEC_D3DES_CFB (WISEC_D3DES|SGD_CFB) -#define WISEC_D3DES_OFB (WISEC_D3DES|SGD_OFB) -#define WISEC_D3DES_MAC (WISEC_D3DES|SGD_MAC) - -#define WISEC_T3DES 0x00001020 -#define WISEC_T3DES_ECB (WISEC_T3DES|SGD_ECB) -#define WISEC_T3DES_CBC (WISEC_T3DES|SGD_CBC) -#define WISEC_T3DES_CFB (WISEC_T3DES|SGD_CFB) -#define WISEC_T3DES_OFB (WISEC_T3DES|SGD_OFB) -#define WISEC_T3DES_MAC (WISEC_T3DES|SGD_MAC) - -#define WISEC_SM3 (SGD_SM3) -#define WISEC_SHA1 (SGD_SHA1) -#define WISEC_SHA256 (SGD_SHA256) - -#define WISEC_RSA (SGD_RSA) -#define WISEC_RSA_SIGN (SGD_RSA_SIGN) -#define WISEC_RSA_ENC (SGD_RSA_ENC) -#define WISEC_SM2 (SGD_SM2) -#define WISEC_SM2_1 (SGD_SM2_1) -#define WISEC_SM2_2 (SGD_SM2_2) -#define WISEC_SM2_3 (SGD_SM2_3) - - -#define WISEC_AUTH_BLOCKED 0x0A000033 -#define WISEC_CERTNOUSAGEERR 0x0A000034 -#define WISEC_INVALIDCONTAINERERR 0x0A000035 -#define WISEC_CONTAINER_NOT_EXISTS 0x0A000036 -#define WISEC_CONTAINER_EXISTS 0x0A000037 -#define WISEC_CERTUSAGEERR 0x0A000038 -#define WISEC_KEYNOUSAGEERR 0x0A000039 -#define WISEC_FILEATTRIBUTEERR 0x0A00003A -#define WISEC_DEVNOAUTH 0x0A00003B - -/* -ULONG DEVAPI SKFE_SetSN(DEVHANDLE hDev, CHAR *SN, UINT SNLen); -ULONG DEVAPI SKFE_GenExtECCKey(DEVHANDLE hDev, PECCPRIVATEKEYBLOB pPriBlob, PECCPUBLICKEYBLOB pPubBlob); -ULONG DEVAPI SKF_ECCDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbPlainText,ULONG *pulPlainTextLen); -ULONG DEVAPI SKF_GenerateKey(HCONTAINER hContainer, ULONG ulAlgId, HANDLE *phSessionKey) ; -ULONG DEVAPI SKF_ECCExportSessionKeyByHandle(HANDLE phSessionKey, ECCPUBLICKEYBLOB *pPubKey,PECCCIPHERBLOB pData); -ULONG DEVAPI SKF_RSAExportSessionKeyByHandle(HANDLE phSessionKey, RSAPUBLICKEYBLOB*pPubKey,BYTE *pbData, ULONG *pulDataLen); -ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); -ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, ULONG ulType, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); -ULONG DEVAPI SKF_RSAPrvKeyDecrypt(HCONTAINER hContainer, BYTE *pCipherData, ULONG pCipherDataLen, BYTE *pbData, ULONG *pbDataLen); -*/ - -#endif + + +#ifndef HEADER_SKF_WISEC_H +#define HEADER_SKF_WISEC_H + +#include "skf.h" + + +#define WISEC_SM1 (SGD_SM1) +#define WISEC_SM1_ECB (SGD_SM1_ECB) +#define WISEC_SM1_CBC (SGD_SM1_CBC) +#define WISEC_SM1_CFB (SGD_SM1_CFB) +#define WISEC_SM1_OFB (SGD_SM1_OFB) +#define WISEC_SM1_MAC (SGD_SM1_MAC) + +#define WISEC_SSF33 (SGD_SSF33) +#define WISEC_SSF33_ECB (SGD_SSF33_ECB) +#define WISEC_SSF33_CBC (SGD_SSF33_CBC) +#define WISEC_SSF33_CFB (SGD_SSF33_CFB) +#define WISEC_SSF33_OFB (SGD_SSF33_OFB) +#define WISEC_SSF33_MAC (SGD_SSF33_MAC) + +#define WISEC_SM4 (SGD_SM4) +#define WISEC_SM4_ECB (WISEC_SM4|SGD_ECB) +#define WISEC_SM4_CBC (WISEC_SM4|SGD_CBC) +#define WISEC_SM4_CFB (WISEC_SM4|SGD_CFB) +#define WISEC_SM4_OFB (WISEC_SM4|SGD_OFB) +#define WISEC_SM4_MAC (WISEC_SM4|SGD_MAC) + +#define WISEC_AES 0x00000800 +#define WISEC_128 0x00000000 +#define WISEC_192 0x00000010 +#define WISEC_256 0x00000020 +#define WISEC_AES128 (WISEC_AES|WISEC_128) +#define WISEC_AES192 (WISEC_AES|WISEC_192) +#define WISEC_AES256 (WISEC_AES|WISEC_256) +#define WISEC_AES128_ECB (WISEC_AES128|SGD_ECB) +#define WISEC_AES128_CBC (WISEC_AES128|SGD_CBC) +#define WISEC_AES128_CFB (WISEC_AES128|SGD_CFB) +#define WISEC_AES128_OFB (WISEC_AES128|SGD_OFB) +#define WISEC_AES128_MAC (WISEC_AES128|SGD_MAC) +#define WISEC_AES192_ECB (WISEC_AES192|SGD_ECB) +#define WISEC_AES192_CBC (WISEC_AES192|SGD_CBC) +#define WISEC_AES192_CFB (WISEC_AES192|SGD_CFB) +#define WISEC_AES192_OFB (WISEC_AES192|SGD_OFB) +#define WISEC_AES192_MAC (WISEC_AES192|SGD_MAC) +#define WISEC_AES256_ECB (WISEC_AES256|SGD_ECB) +#define WISEC_AES256_CBC (WISEC_AES256|SGD_CBC) +#define WISEC_AES256_CFB (WISEC_AES256|SGD_CFB) +#define WISEC_AES256_OFB (WISEC_AES256|SGD_OFB) +#define WISEC_AES256_MAC (WISEC_AES256|SGD_MAC) + +#define WISEC_DES 0x00001000 +#define WISEC_DES_ECB (WISEC_DES|SGD_ECB) +#define WISEC_DES_CBC (WISEC_DES|SGD_CBC) +#define WISEC_DES_CFB (WISEC_DES|SGD_CFB) +#define WISEC_DES_OFB (WISEC_DES|SGD_OFB) +#define WISEC_DES_MAC (WISEC_DES|SGD_MAC) + +#define WISEC_D3DES 0x00001010 +#define WISEC_D3DES_ECB (WISEC_D3DES|SGD_ECB) +#define WISEC_D3DES_CBC (WISEC_D3DES|SGD_CBC) +#define WISEC_D3DES_CFB (WISEC_D3DES|SGD_CFB) +#define WISEC_D3DES_OFB (WISEC_D3DES|SGD_OFB) +#define WISEC_D3DES_MAC (WISEC_D3DES|SGD_MAC) + +#define WISEC_T3DES 0x00001020 +#define WISEC_T3DES_ECB (WISEC_T3DES|SGD_ECB) +#define WISEC_T3DES_CBC (WISEC_T3DES|SGD_CBC) +#define WISEC_T3DES_CFB (WISEC_T3DES|SGD_CFB) +#define WISEC_T3DES_OFB (WISEC_T3DES|SGD_OFB) +#define WISEC_T3DES_MAC (WISEC_T3DES|SGD_MAC) + +#define WISEC_SM3 (SGD_SM3) +#define WISEC_SHA1 (SGD_SHA1) +#define WISEC_SHA256 (SGD_SHA256) + +#define WISEC_RSA (SGD_RSA) +#define WISEC_RSA_SIGN (SGD_RSA_SIGN) +#define WISEC_RSA_ENC (SGD_RSA_ENC) +#define WISEC_SM2 (SGD_SM2) +#define WISEC_SM2_1 (SGD_SM2_1) +#define WISEC_SM2_2 (SGD_SM2_2) +#define WISEC_SM2_3 (SGD_SM2_3) + + +#define WISEC_AUTH_BLOCKED 0x0A000033 +#define WISEC_CERTNOUSAGEERR 0x0A000034 +#define WISEC_INVALIDCONTAINERERR 0x0A000035 +#define WISEC_CONTAINER_NOT_EXISTS 0x0A000036 +#define WISEC_CONTAINER_EXISTS 0x0A000037 +#define WISEC_CERTUSAGEERR 0x0A000038 +#define WISEC_KEYNOUSAGEERR 0x0A000039 +#define WISEC_FILEATTRIBUTEERR 0x0A00003A +#define WISEC_DEVNOAUTH 0x0A00003B + +/* +ULONG DEVAPI SKFE_SetSN(DEVHANDLE hDev, CHAR *SN, UINT SNLen); +ULONG DEVAPI SKFE_GenExtECCKey(DEVHANDLE hDev, PECCPRIVATEKEYBLOB pPriBlob, PECCPUBLICKEYBLOB pPubBlob); +ULONG DEVAPI SKF_ECCDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbPlainText,ULONG *pulPlainTextLen); +ULONG DEVAPI SKF_GenerateKey(HCONTAINER hContainer, ULONG ulAlgId, HANDLE *phSessionKey) ; +ULONG DEVAPI SKF_ECCExportSessionKeyByHandle(HANDLE phSessionKey, ECCPUBLICKEYBLOB *pPubKey,PECCCIPHERBLOB pData); +ULONG DEVAPI SKF_RSAExportSessionKeyByHandle(HANDLE phSessionKey, RSAPUBLICKEYBLOB*pPubKey,BYTE *pbData, ULONG *pulDataLen); +ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); +ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, ULONG ulType, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); +ULONG DEVAPI SKF_RSAPrvKeyDecrypt(HCONTAINER hContainer, BYTE *pCipherData, ULONG pCipherDataLen, BYTE *pbData, ULONG *pbDataLen); +*/ + +#endif diff --git a/src/sm2_alg.c b/src/sm2_alg.c index 4165f3e6..88fc269d 100644 --- a/src/sm2_alg.c +++ b/src/sm2_alg.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1185 +7,1186 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中 - - - -const SM2_BN SM2_P = { - 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, -}; - -const SM2_BN SM2_B = { - 0x4d940e93, 0xddbcbd41, 0x15ab8f92, 0xf39789f5, - 0xcf6509a7, 0x4d5a9e4b, 0x9d9f5e34, 0x28e9fa9e, -}; - -const SM2_JACOBIAN_POINT _SM2_G = { - { - 0x334c74c7, 0x715a4589, 0xf2660be1, 0x8fe30bbf, - 0x6a39c994, 0x5f990446, 0x1f198119, 0x32c4ae2c, - }, - { - 0x2139f0a0, 0x02df32e5, 0xc62a4740, 0xd0a9877c, - 0x6b692153, 0x59bdcee3, 0xf4f6779c, 0xbc3736a2, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, - }, -}; -const SM2_JACOBIAN_POINT *SM2_G = &_SM2_G; - -const SM2_BN SM2_N = { - 0x39d54123, 0x53bbf409, 0x21c6052b, 0x7203df6b, - 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, -}; - -// u = (p - 1)/4, u + 1 = (p + 1)/4 -const SM2_BN SM2_U_PLUS_ONE = { - 0x00000000, 0x40000000, 0xc0000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xbfffffff, 0x3fffffff, -}; - -const SM2_BN SM2_ONE = {1,0,0,0,0,0,0,0}; -const SM2_BN SM2_TWO = {2,0,0,0,0,0,0,0}; -const SM2_BN SM2_THREE = {3,0,0,0,0,0,0,0}; - - - -int sm2_bn_check(const SM2_BN a) -{ - int err = 0; - int i; - for (i = 0; i < 8; i++) { - if (a[i] > 0xffffffff) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - err++; - } - } - if (err) - return -1; - else return 1; -} - -int sm2_bn_is_zero(const SM2_BN a) -{ - int i; - for (i = 0; i < 8; i++) { - if (a[i] != 0) - return 0; - } - return 1; -} - -int sm2_bn_is_one(const SM2_BN a) -{ - int i; - if (a[0] != 1) - return 0; - for (i = 1; i < 8; i++) { - if (a[i] != 0) - return 0; - } - return 1; -} - -void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]) -{ - int i; - uint8_t *p = out; - - /* - fprintf(stderr, "sm2_bn_to_bytes:\n"); - for (i = 0; i < 8; i++) { - fprintf(stderr, "%016lx ", a[i]); - } - fprintf(stderr, "\n"); - */ - - for (i = 7; i >= 0; i--) { - uint32_t ai = (uint32_t)a[i]; - PUTU32(out, ai); - out += sizeof(uint32_t); - } - - /* - for (i = 0; i < 32; i++) { - fprintf(stderr, "%02X ", p[i]); - } - */ - -} - -void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]) -{ - int i; - for (i = 7; i >= 0; i--) { - r[i] = GETU32(in); - in += sizeof(uint32_t); - } -} - -static int hexchar2int(char c) -{ - if ('0' <= c && c <= '9') return c - '0'; - else if ('a' <= c && c <= 'f') return c - 'a' + 10; - else if ('A' <= c && c <= 'F') return c - 'A' + 10; - else return -1; -} - -static int hex2bin(const char *in, size_t inlen, uint8_t *out) -{ - int c; - if (inlen % 2) - return -1; - - while (inlen) { - if ((c = hexchar2int(*in++)) < 0) - return -1; - *out = (uint8_t)c << 4; - if ((c = hexchar2int(*in++)) < 0) - return -1; - *out |= (uint8_t)c; - inlen -= 2; - out++; - } - return 1; -} - -void sm2_bn_to_hex(const SM2_BN a, char hex[64]) -{ - int i; - for (i = 7; i >= 0; i--) { - int len; - len = sprintf(hex, "%08x", (uint32_t)a[i]); - assert(len == 8); - hex += 8; - } -} - -int sm2_bn_from_hex(SM2_BN r, const char hex[64]) -{ - uint8_t buf[32]; - if (hex2bin(hex, 64, buf) < 0) - return -1; - sm2_bn_from_bytes(r, buf); - return 1; -} - -int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen) -{ - uint8_t buf[32] = {0}; - if (!d || dlen == 0) { - error_print(); - return -1; - } - if (dlen > sizeof(buf)) { - error_print(); - return -1; - } - memcmp(buf + sizeof(buf) - dlen, d, dlen); - sm2_bn_from_bytes(r, buf); - return 1; -} - -int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a) -{ - int ret = 0, i; - format_print(fp, fmt, ind, "%s: ", label); - - for (i = 7; i >= 0; i--) { - if (a[i] >= ((uint64_t)1 << 32)) { - printf("bn_print check failed\n"); - } - ret += fprintf(fp, "%08x", (uint32_t)a[i]); - } - ret += fprintf(fp, "\n"); - return ret; -} - -void sm2_bn_to_bits(const SM2_BN a, char bits[256]) -{ - int i, j; - for (i = 7; i >= 0; i--) { - uint32_t w = a[i]; - for (j = 0; j < 32; j++) { - *bits++ = (w & 0x80000000) ? '1' : '0'; - w <<= 1; - } - } -} - -int sm2_bn_cmp(const SM2_BN a, const SM2_BN b) -{ - int i; - for (i = 7; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - -int sm2_bn_equ_hex(const SM2_BN a, const char *hex) -{ - char buf[65] = {0}; - char *p = buf; - int i; - - for (i = 7; i >= 0; i--) { - sprintf(p, "%08x", (uint32_t)a[i]); - p += 8; - } - return (strcmp(buf, hex) == 0); -} - -int sm2_bn_is_odd(const SM2_BN a) -{ - return a[0] & 0x01; -} - -void sm2_bn_set_word(SM2_BN r, uint32_t a) -{ - int i; - r[0] = a; - for (i = 1; i < 8; i++) { - r[i] = 0; - } -} - -void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b) -{ - int i; - r[0] = a[0] + b[0]; - - for (i = 1; i < 8; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 7; i++) { - r[i] &= 0xffffffff; - } -} - -void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b) -{ - int i; - SM2_BN r; - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 7; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - sm2_bn_copy(ret, r); -} - -// FIXME: get random from outside -void sm2_bn_rand_range(SM2_BN r, const SM2_BN range) -{ - uint8_t buf[32]; - do { - (void)rand_bytes(buf, sizeof(buf)); - sm2_bn_from_bytes(r, buf); - } while (sm2_bn_cmp(r, range) >= 0); -} - -void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - sm2_bn_add(r, a, b); - if (sm2_bn_cmp(r, SM2_P) >= 0) { - sm2_bn_sub(r, r, SM2_P); - } -} - -void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - if (sm2_bn_cmp(a, b) >= 0) { - sm2_bn_sub(r, a, b); - } else { - SM2_BN t; - sm2_bn_sub(t, SM2_P, b); - sm2_bn_add(r, t, a); - } -} - -void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a) -{ - sm2_fp_add(r, a, a); -} - -void sm2_fp_tri(SM2_Fp r, const SM2_Fp a) -{ - SM2_BN t; - sm2_fp_dbl(t, a); - sm2_fp_add(r, t, a); -} - -void sm2_fp_div2(SM2_Fp r, const SM2_Fp a) -{ - int i; - sm2_bn_copy(r, a); - if (r[0] & 0x01) { - sm2_bn_add(r, r, SM2_P); - } - for (i = 0; i < 7; i++) { - r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); - } - r[i] >>= 1; -} - -void sm2_fp_neg(SM2_Fp r, const SM2_Fp a) -{ - if (sm2_bn_is_zero(a)) { - sm2_bn_copy(r, a); - } else { - sm2_bn_sub(r, SM2_P, a); - } -} - -void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - int i, j; - uint64_t s[16] = {0}; - SM2_BN d = {0}; - uint64_t u; - - // s = a * b - for (i = 0; i < 8; i++) { - u = 0; - for (j = 0; j < 8; j++) { - u = s[i + j] + a[i] * b[j] + u; - s[i + j] = u & 0xffffffff; - u >>= 32; - } - s[i + 8] = u; - } - - r[0] = s[0] + s[ 8] + s[ 9] + s[10] + s[11] + s[12] + ((s[13] + s[14] + s[15]) << 1); - r[1] = s[1] + s[ 9] + s[10] + s[11] + s[12] + s[13] + ((s[14] + s[15]) << 1); - r[2] = s[2]; - r[3] = s[3] + s[ 8] + s[11] + s[12] + s[14] + s[15] + (s[13] << 1); - r[4] = s[4] + s[ 9] + s[12] + s[13] + s[15] + (s[14] << 1); - r[5] = s[5] + s[10] + s[13] + s[14] + (s[15] << 1); - r[6] = s[6] + s[11] + s[14] + s[15]; - r[7] = s[7] + s[ 8] + s[ 9] + s[10] + s[11] + s[15] + ((s[12] + s[13] + s[14] + s[15]) << 1); - - for (i = 1; i < 8; i++) { - r[i] += r[i - 1] >> 32; - r[i - 1] &= 0xffffffff; - } - - d[2] = s[8] + s[9] + s[13] + s[14]; - d[3] = d[2] >> 32; - d[2] &= 0xffffffff; - sm2_bn_sub(r, r, d); - - // max times ? - while (sm2_bn_cmp(r, SM2_P) >= 0) { - sm2_bn_sub(r, r, SM2_P); - } -} - -void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a) -{ - sm2_fp_mul(r, a, a); -} - -void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e) -{ - SM2_BN t; - uint32_t w; - int i, j; - - sm2_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm2_fp_sqr(t, t); - if (w & 0x80000000) - sm2_fp_mul(t, t, a); - w <<= 1; - } - } - - sm2_bn_copy(r, t); -} - -void sm2_fp_inv(SM2_Fp r, const SM2_Fp a) -{ - SM2_BN a1; - SM2_BN a2; - SM2_BN a3; - SM2_BN a4; - SM2_BN a5; - int i; - - sm2_fp_sqr(a1, a); - sm2_fp_mul(a2, a1, a); - sm2_fp_sqr(a3, a2); - sm2_fp_sqr(a3, a3); - sm2_fp_mul(a3, a3, a2); - sm2_fp_sqr(a4, a3); - sm2_fp_sqr(a4, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_mul(a4, a4, a3); - sm2_fp_sqr(a5, a4); - for (i = 1; i < 8; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a4); - for (i = 0; i < 8; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a4); - for (i = 0; i < 4; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a3); - sm2_fp_sqr(a5, a5); - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a2); - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a); - sm2_fp_sqr(a4, a5); - sm2_fp_mul(a3, a4, a1); - sm2_fp_sqr(a5, a4); - for (i = 1; i< 31; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a4, a5, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_mul(a4, a4, a); - sm2_fp_mul(a3, a4, a2); - for (i = 0; i < 33; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(r, a4, a5); - - sm2_bn_clean(a1); - sm2_bn_clean(a2); - sm2_bn_clean(a3); - sm2_bn_clean(a4); - sm2_bn_clean(a5); -} - -void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) -{ - sm2_bn_add(r, a, b); - if (sm2_bn_cmp(r, SM2_N) >= 0) { - sm2_bn_sub(r, r, SM2_N); - } -} - -void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) -{ - if (sm2_bn_cmp(a, b) >= 0) { - sm2_bn_sub(r, a, b); - } else { - SM2_BN t; - sm2_bn_add(t, a, SM2_N); - sm2_bn_sub(r, t, b); - } -} - -void sm2_fn_neg(SM2_Fn r, const SM2_Fn a) -{ - if (sm2_bn_is_zero(a)) { - sm2_bn_copy(r, a); - } else { - sm2_bn_sub(r, SM2_N, a); - } -} - -/* bn288 only used in barrett reduction */ -static int sm2_bn288_cmp(const uint64_t a[9], const uint64_t b[9]) -{ - int i; - for (i = 8; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - -static void sm2_bn288_add(uint64_t r[9], const uint64_t a[9], const uint64_t b[9]) -{ - int i; - r[0] = a[0] + b[0]; - for (i = 1; i < 9; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 8; i++) { - r[i] &= 0xffffffff; - } -} - -static void sm2_bn288_sub(uint64_t ret[9], const uint64_t a[9], const uint64_t b[9]) -{ - int i; - uint64_t r[9]; - - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 8; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - - for (i = 0; i < 9; i++) { - ret[i] = r[i]; - } -} - -void sm2_fn_mul(SM2_BN r, const SM2_BN a, const SM2_BN b) -{ - static const uint64_t mu[8] = { - 0xf15149a0, 0x12ac6361, 0xfa323c01, 0x8dfc2096, - 1, 1, 1, 0x100000001, - }; - - uint64_t s[17]; - uint64_t zh[9]; - uint64_t zl[9]; - uint64_t q[9]; - uint64_t w; - int i, j; - - - /* z = a * b */ - for (i = 0; i < 8; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + a[i] * b[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - - /* zl = z mod (2^32)^9 = z[0..8] - * zh = z // (2^32)^7 = z[7..15] */ - for (i = 0; i < 9; i++) { - zl[i] = s[i]; - zh[i] = s[7 + i]; - } - //printf("zl = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); - //printf("zh = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zh[i]); printf("\n"); - - /* q = zh * mu // (2^32)^9 */ - for (i = 0; i < 9; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + zh[i] * mu[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 8; i++) { - q[i] = s[9 + i]; - } - //printf("q = "); for (i = 7; i >= 0; i--) printf("%08x", (uint32_t)q[i]); printf("\n"); - - - /* q = q * n mod (2^32)^9 */ - for (i = 0; i < 8; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + q[i] * SM2_N[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[i]; - } - //printf("qn = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)q[i]); printf("\n"); - - /* r = zl - q (mod (2^32)^9) */ - - if (sm2_bn288_cmp(zl, q)) { - sm2_bn288_sub(zl, zl, q); - } else { - uint64_t c[9] = {0,0,0,0,0,0,0,0,0x100000000}; - sm2_bn288_sub(q, c, q); - sm2_bn288_add(zl, q, zl); - } - - //printf("r = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); - - for (i = 0; i < 8; i++) { - r[i] = zl[i]; - } - r[7] += zl[8] << 32; - - /* while r >= p do: r = r - n */ - while (sm2_bn_cmp(r, SM2_N) >= 0) { - sm2_bn_sub(r, r, SM2_N); - //printf("r = r -n = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); - } -} - -void sm2_fn_sqr(SM2_BN r, const SM2_BN a) -{ - sm2_fn_mul(r, a, a); -} - -void sm2_fn_exp(SM2_BN r, const SM2_BN a, const SM2_BN e) -{ - SM2_BN t; - uint32_t w; - int i, j; - - sm2_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm2_fn_sqr(t, t); - if (w & 0x80000000) { - sm2_fn_mul(t, t, a); - } - w <<= 1; - } - } - - sm2_bn_copy(r, t); -} - -void sm2_fn_inv(SM2_BN r, const SM2_BN a) -{ - SM2_BN e; - sm2_bn_sub(e, SM2_N, SM2_TWO); - sm2_fn_exp(r, a, e); -} - -void sm2_fn_rand(SM2_BN r) -{ - sm2_bn_rand_range(r, SM2_N); -} - - - -void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R) -{ - memset(R, 0, sizeof(SM2_JACOBIAN_POINT)); - R->X[0] = 1; - R->Y[0] = 1; -} - -int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P) -{ - return sm2_bn_is_zero(P->Z); -} - -void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y) -{ - sm2_bn_copy(R->X, x); - sm2_bn_copy(R->Y, y); - sm2_bn_set_one(R->Z); -} - -void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y) -{ - SM2_BN z_inv; - - if (sm2_bn_is_one(P->Z)) { - sm2_bn_copy(x, P->X); - sm2_bn_copy(y, P->Y); - } else { - sm2_fp_inv(z_inv, P->Z); - if (y) - sm2_fp_mul(y, P->Y, z_inv); - sm2_fp_sqr(z_inv, z_inv); - sm2_fp_mul(x, P->X, z_inv); - if (y) - sm2_fp_mul(y, y, z_inv); - } -} - -int sm2_jacobian_pointpoint_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P) -{ - int len = 0; - SM2_BN x; - SM2_BN y; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - sm2_jacobian_point_get_xy(P, x, y); - - sm2_bn_print(fp, fmt, ind, "x", x); - sm2_bn_print(fp, fmt, ind, "y", y); - - return 1; -} - -int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P) -{ - SM2_BN t0; - SM2_BN t1; - SM2_BN t2; - - if (sm2_bn_is_one(P->Z)) { - sm2_fp_sqr(t0, P->Y); - sm2_fp_add(t0, t0, P->X); - sm2_fp_add(t0, t0, P->X); - sm2_fp_add(t0, t0, P->X); - sm2_fp_sqr(t1, P->X); - sm2_fp_mul(t1, t1, P->X); - sm2_fp_add(t1, t1, SM2_B); - } else { - sm2_fp_sqr(t0, P->Y); - sm2_fp_sqr(t1, P->Z); - sm2_fp_sqr(t2, t1); - sm2_fp_mul(t1, t1, t2); - sm2_fp_mul(t1, t1, SM2_B); - sm2_fp_mul(t2, t2, P->X); - sm2_fp_add(t0, t0, t2); - sm2_fp_add(t0, t0, t2); - sm2_fp_add(t0, t0, t2); - sm2_fp_sqr(t2, P->X); - sm2_fp_mul(t2, t2, P->X); - sm2_fp_add(t1, t1, t2); - } - - if (sm2_bn_cmp(t0, t1) != 0) { - error_print(); - return -1; - } - return 1; -} - -void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) -{ - sm2_bn_copy(R->X, P->X); - sm2_fp_neg(R->Y, P->Y); - sm2_bn_copy(R->Z, P->Z); -} - -void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) -{ - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - SM2_BN T1; - SM2_BN T2; - SM2_BN T3; - SM2_BN X3; - SM2_BN Y3; - SM2_BN Z3; - //printf("X1 = "); print_bn(X1); - //printf("Y1 = "); print_bn(Y1); - //printf("Z1 = "); print_bn(Z1); - - if (sm2_jacobian_point_is_at_infinity(P)) { - sm2_jacobian_point_copy(R, P); - return; - } - - sm2_fp_sqr(T1, Z1); //printf("T1 = Z1^2 = "); print_bn(T1); - sm2_fp_sub(T2, X1, T1); //printf("T2 = X1 - T1 = "); print_bn(T2); - sm2_fp_add(T1, X1, T1); //printf("T1 = X1 + T1 = "); print_bn(T1); - sm2_fp_mul(T2, T2, T1); //printf("T2 = T2 * T1 = "); print_bn(T2); - sm2_fp_tri(T2, T2); //printf("T2 = 3 * T2 = "); print_bn(T2); - sm2_fp_dbl(Y3, Y1); //printf("Y3 = 2 * Y1 = "); print_bn(Y3); - sm2_fp_mul(Z3, Y3, Z1); //printf("Z3 = Y3 * Z1 = "); print_bn(Z3); - sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); - sm2_fp_mul(T3, Y3, X1); //printf("T3 = Y3 * X1 = "); print_bn(T3); - sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); - sm2_fp_div2(Y3, Y3); //printf("Y3 = Y3/2 = "); print_bn(Y3); - sm2_fp_sqr(X3, T2); //printf("X3 = T2^2 = "); print_bn(X3); - sm2_fp_dbl(T1, T3); //printf("T1 = 2 * T1 = "); print_bn(T1); - sm2_fp_sub(X3, X3, T1); //printf("X3 = X3 - T1 = "); print_bn(X3); - sm2_fp_sub(T1, T3, X3); //printf("T1 = T3 - X3 = "); print_bn(T1); - sm2_fp_mul(T1, T1, T2); //printf("T1 = T1 * T2 = "); print_bn(T1); - sm2_fp_sub(Y3, T1, Y3); //printf("Y3 = T1 - Y3 = "); print_bn(Y3); - - sm2_bn_copy(R->X, X3); - sm2_bn_copy(R->Y, Y3); - sm2_bn_copy(R->Z, Z3); - - //printf("X3 = "); print_bn(R->X); - //printf("Y3 = "); print_bn(R->Y); - //printf("Z3 = "); print_bn(R->Z); - -} - -void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) -{ - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - const uint64_t *x2 = Q->X; - const uint64_t *y2 = Q->Y; - SM2_BN T1; - SM2_BN T2; - SM2_BN T3; - SM2_BN T4; - SM2_BN X3; - SM2_BN Y3; - SM2_BN Z3; - - if (sm2_jacobian_point_is_at_infinity(Q)) { - sm2_jacobian_point_copy(R, P); - return; - } - - if (sm2_jacobian_point_is_at_infinity(P)) { - sm2_jacobian_point_copy(R, Q); - return; - } - - assert(sm2_bn_is_one(Q->Z)); - - sm2_fp_sqr(T1, Z1); - sm2_fp_mul(T2, T1, Z1); - sm2_fp_mul(T1, T1, x2); - sm2_fp_mul(T2, T2, y2); - sm2_fp_sub(T1, T1, X1); - sm2_fp_sub(T2, T2, Y1); - if (sm2_bn_is_zero(T1)) { - if (sm2_bn_is_zero(T2)) { - SM2_JACOBIAN_POINT _Q, *Q = &_Q; - sm2_jacobian_point_set_xy(Q, x2, y2); - - sm2_jacobian_point_dbl(R, Q); - return; - } else { - sm2_jacobian_point_set_infinity(R); - return; - } - } - sm2_fp_mul(Z3, Z1, T1); - sm2_fp_sqr(T3, T1); - sm2_fp_mul(T4, T3, T1); - sm2_fp_mul(T3, T3, X1); - sm2_fp_dbl(T1, T3); - sm2_fp_sqr(X3, T2); - sm2_fp_sub(X3, X3, T1); - sm2_fp_sub(X3, X3, T4); - sm2_fp_sub(T3, T3, X3); - sm2_fp_mul(T3, T3, T2); - sm2_fp_mul(T4, T4, Y1); - sm2_fp_sub(Y3, T3, T4); - - sm2_bn_copy(R->X, X3); - sm2_bn_copy(R->Y, Y3); - sm2_bn_copy(R->Z, Z3); -} - -void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) -{ - SM2_JACOBIAN_POINT _T, *T = &_T; - sm2_jacobian_point_neg(T, Q); - sm2_jacobian_point_add(R, P, T); -} - -void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P) -{ - char bits[257] = {0}; - SM2_JACOBIAN_POINT _Q, *Q = &_Q; - SM2_JACOBIAN_POINT _T, *T = &_T; - int i; - - // FIXME: point_add need affine, so we can not use point_add - if (!sm2_bn_is_one(P->Z)) { - SM2_BN x; - SM2_BN y; - sm2_jacobian_point_get_xy(P, x, y); - sm2_jacobian_point_set_xy(T, x, y); - P = T; - } - - sm2_jacobian_point_set_infinity(Q); - sm2_bn_to_bits(k, bits); - for (i = 0; i < 256; i++) { - sm2_jacobian_point_dbl(Q, Q); - if (bits[i] == '1') { - sm2_jacobian_point_add(Q, Q, P); - } - } - sm2_jacobian_point_copy(R, Q); -} - -void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]) -{ - SM2_BN x; - SM2_BN y; - sm2_jacobian_point_get_xy(P, x, y); - sm2_bn_to_bytes(x, out); - sm2_bn_to_bytes(y, out + 32); -} - -void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]) -{ - sm2_bn_from_bytes(P->X, in); - sm2_bn_from_bytes(P->Y, in + 32); - sm2_bn_set_word(P->Z, 1); - /* should we check if sm2_jacobian_point_is_on_curve */ -} - -void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k) -{ - sm2_jacobian_point_mul(R, k, SM2_G); -} - -/* R = t * P + s * G */ -void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s) -{ - SM2_JACOBIAN_POINT _sG, *sG = &_sG; - SM2_BN x; - SM2_BN y; - - /* T = s * G */ - sm2_jacobian_point_mul_generator(sG, s); - - // R = t * P - sm2_jacobian_point_mul(R, t, P); - sm2_jacobian_point_get_xy(R, x, y); - sm2_jacobian_point_set_xy(R, x, y); - - // R = R + T - sm2_jacobian_point_add(R, sG, R); -} - -void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]) -{ - sm2_bn_from_hex(P->X, hex); - sm2_bn_from_hex(P->Y, hex + 64); - sm2_bn_set_one(P->Z); -} - -int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]) -{ - SM2_BN x; - SM2_BN y; - SM2_JACOBIAN_POINT _T, *T = &_T; - - sm2_jacobian_point_get_xy(P, x, y); - sm2_jacobian_point_from_hex(T, hex); - - return (sm2_bn_cmp(x, T->X) == 0) && (sm2_bn_cmp(y, T->Y) == 0); -} - - - -int sm2_point_is_on_curve(const SM2_POINT *P) -{ - SM2_JACOBIAN_POINT T; - sm2_jacobian_point_from_bytes(&T, (const uint8_t *)P); - return sm2_jacobian_point_is_on_curve(&T); -} - -int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y) -{ - SM2_BN _x, _y, _g, _z; - sm2_bn_from_bytes(_x, x); - - // g = x^3 - 3x + b = (x^2 - 3)*x + b - sm2_fp_sqr(_g, _x); - sm2_fp_sub(_g, _g, SM2_THREE); - sm2_fp_mul(_g, _g, _x); - sm2_fp_add(_g, _g, SM2_B); - - // y = g^(u + 1) mod p, u = (p - 3)/4 - sm2_fp_exp(_y, _g, SM2_U_PLUS_ONE); - - // z = y^2 mod p - sm2_fp_sqr(_z, _y); - if (sm2_bn_cmp(_z, _g)) { - error_print(); - return -1; - } - - if ((y == 0x02 && sm2_bn_is_odd(_y)) || (y == 0x03) && !sm2_bn_is_odd(_y)) { - sm2_fp_neg(_y, _y); - } - - sm2_bn_to_bytes(_x, P->x); - sm2_bn_to_bytes(_y, P->y); - - sm2_bn_clean(_x); - sm2_bn_clean(_y); - sm2_bn_clean(_g); - sm2_bn_clean(_z); - - if (!sm2_point_is_on_curve(P)) { - error_print(); - return -1; - } - return 1; -} - -int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]) -{ - memcpy(P->x, x, 32); - memcpy(P->y, y, 32); - return sm2_point_is_on_curve(P); -} - -int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _P; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); - sm2_jacobian_point_mul(&_P, _k, &_P); - sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); - - sm2_bn_clean(_k); - return 1; -} - -int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _R; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_mul_generator(&_R, _k); - sm2_jacobian_point_to_bytes(&_R, (uint8_t *)R); - - sm2_bn_clean(_k); - return 1; -} - -int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _P; - SM2_BN _s; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); - sm2_bn_from_bytes(_s, s); - sm2_jacobian_point_mul_sum(&_P, _k, &_P, _s); - sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); - - sm2_bn_clean(_k); - sm2_bn_clean(_s); - return 1; -} - -int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - format_bytes(fp, fmt, ind, "x", P->x, 32); - format_bytes(fp, fmt, ind, "y", P->y, 32); - return 1; -} - -void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]) -{ - *out++ = (P->y[31] & 0x01) ? 0x03 : 0x02; - memcpy(out, P->x, 32); -} - -void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]) -{ - *out++ = 0x04; - memcpy(out, P, 64); -} - -int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen) -{ - if ((*in == 0x02 || *in == 0x03) && inlen == 33) { - if (sm2_point_from_x(P, in + 1, *in) != 1) { - error_print(); - return -1; - } - } else if (*in == 0x04 && inlen == 65) { - if (sm2_point_from_xy(P, in + 1, in + 33) != 1) { - error_print(); - return -1; - } - } else { - error_print(); - return -1; - } - return 1; -} - -int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen) -{ - uint8_t octets[65]; - if (!P) { - return 0; - } - sm2_point_to_uncompressed_octets(P, octets); - if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (dlen != 65) { - error_print(); - return -1; - } - if (sm2_point_from_octets(P, d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中 + + + +const SM2_BN SM2_P = { + 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, +}; + +const SM2_BN SM2_B = { + 0x4d940e93, 0xddbcbd41, 0x15ab8f92, 0xf39789f5, + 0xcf6509a7, 0x4d5a9e4b, 0x9d9f5e34, 0x28e9fa9e, +}; + +const SM2_JACOBIAN_POINT _SM2_G = { + { + 0x334c74c7, 0x715a4589, 0xf2660be1, 0x8fe30bbf, + 0x6a39c994, 0x5f990446, 0x1f198119, 0x32c4ae2c, + }, + { + 0x2139f0a0, 0x02df32e5, 0xc62a4740, 0xd0a9877c, + 0x6b692153, 0x59bdcee3, 0xf4f6779c, 0xbc3736a2, + }, + { + 1, 0, 0, 0, 0, 0, 0, 0, + }, +}; +const SM2_JACOBIAN_POINT *SM2_G = &_SM2_G; + +const SM2_BN SM2_N = { + 0x39d54123, 0x53bbf409, 0x21c6052b, 0x7203df6b, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, +}; + +// u = (p - 1)/4, u + 1 = (p + 1)/4 +const SM2_BN SM2_U_PLUS_ONE = { + 0x00000000, 0x40000000, 0xc0000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xbfffffff, 0x3fffffff, +}; + +const SM2_BN SM2_ONE = {1,0,0,0,0,0,0,0}; +const SM2_BN SM2_TWO = {2,0,0,0,0,0,0,0}; +const SM2_BN SM2_THREE = {3,0,0,0,0,0,0,0}; + + + +int sm2_bn_check(const SM2_BN a) +{ + int err = 0; + int i; + for (i = 0; i < 8; i++) { + if (a[i] > 0xffffffff) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + err++; + } + } + if (err) + return -1; + else return 1; +} + +int sm2_bn_is_zero(const SM2_BN a) +{ + int i; + for (i = 0; i < 8; i++) { + if (a[i] != 0) + return 0; + } + return 1; +} + +int sm2_bn_is_one(const SM2_BN a) +{ + int i; + if (a[0] != 1) + return 0; + for (i = 1; i < 8; i++) { + if (a[i] != 0) + return 0; + } + return 1; +} + +void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]) +{ + int i; + uint8_t *p = out; + + /* + fprintf(stderr, "sm2_bn_to_bytes:\n"); + for (i = 0; i < 8; i++) { + fprintf(stderr, "%016lx ", a[i]); + } + fprintf(stderr, "\n"); + */ + + for (i = 7; i >= 0; i--) { + uint32_t ai = (uint32_t)a[i]; + PUTU32(out, ai); + out += sizeof(uint32_t); + } + + /* + for (i = 0; i < 32; i++) { + fprintf(stderr, "%02X ", p[i]); + } + */ + +} + +void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]) +{ + int i; + for (i = 7; i >= 0; i--) { + r[i] = GETU32(in); + in += sizeof(uint32_t); + } +} + +static int hexchar2int(char c) +{ + if ('0' <= c && c <= '9') return c - '0'; + else if ('a' <= c && c <= 'f') return c - 'a' + 10; + else if ('A' <= c && c <= 'F') return c - 'A' + 10; + else return -1; +} + +static int hex2bin(const char *in, size_t inlen, uint8_t *out) +{ + int c; + if (inlen % 2) + return -1; + + while (inlen) { + if ((c = hexchar2int(*in++)) < 0) + return -1; + *out = (uint8_t)c << 4; + if ((c = hexchar2int(*in++)) < 0) + return -1; + *out |= (uint8_t)c; + inlen -= 2; + out++; + } + return 1; +} + +void sm2_bn_to_hex(const SM2_BN a, char hex[64]) +{ + int i; + for (i = 7; i >= 0; i--) { + int len; + len = sprintf(hex, "%08x", (uint32_t)a[i]); + assert(len == 8); + hex += 8; + } +} + +int sm2_bn_from_hex(SM2_BN r, const char hex[64]) +{ + uint8_t buf[32]; + if (hex2bin(hex, 64, buf) < 0) + return -1; + sm2_bn_from_bytes(r, buf); + return 1; +} + +int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen) +{ + uint8_t buf[32] = {0}; + if (!d || dlen == 0) { + error_print(); + return -1; + } + if (dlen > sizeof(buf)) { + error_print(); + return -1; + } + memcmp(buf + sizeof(buf) - dlen, d, dlen); + sm2_bn_from_bytes(r, buf); + return 1; +} + +int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a) +{ + int ret = 0, i; + format_print(fp, fmt, ind, "%s: ", label); + + for (i = 7; i >= 0; i--) { + if (a[i] >= ((uint64_t)1 << 32)) { + printf("bn_print check failed\n"); + } + ret += fprintf(fp, "%08x", (uint32_t)a[i]); + } + ret += fprintf(fp, "\n"); + return ret; +} + +void sm2_bn_to_bits(const SM2_BN a, char bits[256]) +{ + int i, j; + for (i = 7; i >= 0; i--) { + uint32_t w = a[i]; + for (j = 0; j < 32; j++) { + *bits++ = (w & 0x80000000) ? '1' : '0'; + w <<= 1; + } + } +} + +int sm2_bn_cmp(const SM2_BN a, const SM2_BN b) +{ + int i; + for (i = 7; i >= 0; i--) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + return 0; +} + +int sm2_bn_equ_hex(const SM2_BN a, const char *hex) +{ + char buf[65] = {0}; + char *p = buf; + int i; + + for (i = 7; i >= 0; i--) { + sprintf(p, "%08x", (uint32_t)a[i]); + p += 8; + } + return (strcmp(buf, hex) == 0); +} + +int sm2_bn_is_odd(const SM2_BN a) +{ + return a[0] & 0x01; +} + +void sm2_bn_set_word(SM2_BN r, uint32_t a) +{ + int i; + r[0] = a; + for (i = 1; i < 8; i++) { + r[i] = 0; + } +} + +void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b) +{ + int i; + r[0] = a[0] + b[0]; + + for (i = 1; i < 8; i++) { + r[i] = a[i] + b[i] + (r[i-1] >> 32); + } + for (i = 0; i < 7; i++) { + r[i] &= 0xffffffff; + } +} + +void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b) +{ + int i; + SM2_BN r; + r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; + for (i = 1; i < 7; i++) { + r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); + r[i - 1] &= 0xffffffff; + } + r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; + r[i - 1] &= 0xffffffff; + sm2_bn_copy(ret, r); +} + +// FIXME: get random from outside +void sm2_bn_rand_range(SM2_BN r, const SM2_BN range) +{ + uint8_t buf[32]; + do { + (void)rand_bytes(buf, sizeof(buf)); + sm2_bn_from_bytes(r, buf); + } while (sm2_bn_cmp(r, range) >= 0); +} + +void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) +{ + sm2_bn_add(r, a, b); + if (sm2_bn_cmp(r, SM2_P) >= 0) { + sm2_bn_sub(r, r, SM2_P); + } +} + +void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) +{ + if (sm2_bn_cmp(a, b) >= 0) { + sm2_bn_sub(r, a, b); + } else { + SM2_BN t; + sm2_bn_sub(t, SM2_P, b); + sm2_bn_add(r, t, a); + } +} + +void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a) +{ + sm2_fp_add(r, a, a); +} + +void sm2_fp_tri(SM2_Fp r, const SM2_Fp a) +{ + SM2_BN t; + sm2_fp_dbl(t, a); + sm2_fp_add(r, t, a); +} + +void sm2_fp_div2(SM2_Fp r, const SM2_Fp a) +{ + int i; + sm2_bn_copy(r, a); + if (r[0] & 0x01) { + sm2_bn_add(r, r, SM2_P); + } + for (i = 0; i < 7; i++) { + r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); + } + r[i] >>= 1; +} + +void sm2_fp_neg(SM2_Fp r, const SM2_Fp a) +{ + if (sm2_bn_is_zero(a)) { + sm2_bn_copy(r, a); + } else { + sm2_bn_sub(r, SM2_P, a); + } +} + +void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) +{ + int i, j; + uint64_t s[16] = {0}; + SM2_BN d = {0}; + uint64_t u; + + // s = a * b + for (i = 0; i < 8; i++) { + u = 0; + for (j = 0; j < 8; j++) { + u = s[i + j] + a[i] * b[j] + u; + s[i + j] = u & 0xffffffff; + u >>= 32; + } + s[i + 8] = u; + } + + r[0] = s[0] + s[ 8] + s[ 9] + s[10] + s[11] + s[12] + ((s[13] + s[14] + s[15]) << 1); + r[1] = s[1] + s[ 9] + s[10] + s[11] + s[12] + s[13] + ((s[14] + s[15]) << 1); + r[2] = s[2]; + r[3] = s[3] + s[ 8] + s[11] + s[12] + s[14] + s[15] + (s[13] << 1); + r[4] = s[4] + s[ 9] + s[12] + s[13] + s[15] + (s[14] << 1); + r[5] = s[5] + s[10] + s[13] + s[14] + (s[15] << 1); + r[6] = s[6] + s[11] + s[14] + s[15]; + r[7] = s[7] + s[ 8] + s[ 9] + s[10] + s[11] + s[15] + ((s[12] + s[13] + s[14] + s[15]) << 1); + + for (i = 1; i < 8; i++) { + r[i] += r[i - 1] >> 32; + r[i - 1] &= 0xffffffff; + } + + d[2] = s[8] + s[9] + s[13] + s[14]; + d[3] = d[2] >> 32; + d[2] &= 0xffffffff; + sm2_bn_sub(r, r, d); + + // max times ? + while (sm2_bn_cmp(r, SM2_P) >= 0) { + sm2_bn_sub(r, r, SM2_P); + } +} + +void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a) +{ + sm2_fp_mul(r, a, a); +} + +void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e) +{ + SM2_BN t; + uint32_t w; + int i, j; + + sm2_bn_set_one(t); + for (i = 7; i >= 0; i--) { + w = (uint32_t)e[i]; + for (j = 0; j < 32; j++) { + sm2_fp_sqr(t, t); + if (w & 0x80000000) + sm2_fp_mul(t, t, a); + w <<= 1; + } + } + + sm2_bn_copy(r, t); +} + +void sm2_fp_inv(SM2_Fp r, const SM2_Fp a) +{ + SM2_BN a1; + SM2_BN a2; + SM2_BN a3; + SM2_BN a4; + SM2_BN a5; + int i; + + sm2_fp_sqr(a1, a); + sm2_fp_mul(a2, a1, a); + sm2_fp_sqr(a3, a2); + sm2_fp_sqr(a3, a3); + sm2_fp_mul(a3, a3, a2); + sm2_fp_sqr(a4, a3); + sm2_fp_sqr(a4, a4); + sm2_fp_sqr(a4, a4); + sm2_fp_sqr(a4, a4); + sm2_fp_mul(a4, a4, a3); + sm2_fp_sqr(a5, a4); + for (i = 1; i < 8; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a5, a5, a4); + for (i = 0; i < 8; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a5, a5, a4); + for (i = 0; i < 4; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a5, a5, a3); + sm2_fp_sqr(a5, a5); + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a5, a5, a2); + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a5, a5, a); + sm2_fp_sqr(a4, a5); + sm2_fp_mul(a3, a4, a1); + sm2_fp_sqr(a5, a4); + for (i = 1; i< 31; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a4, a5, a4); + sm2_fp_sqr(a4, a4); + sm2_fp_mul(a4, a4, a); + sm2_fp_mul(a3, a4, a2); + for (i = 0; i < 33; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a2, a5, a3); + sm2_fp_mul(a3, a2, a3); + for (i = 0; i < 32; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a2, a5, a3); + sm2_fp_mul(a3, a2, a3); + sm2_fp_mul(a4, a2, a4); + for (i = 0; i < 32; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a2, a5, a3); + sm2_fp_mul(a3, a2, a3); + sm2_fp_mul(a4, a2, a4); + for (i = 0; i < 32; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a2, a5, a3); + sm2_fp_mul(a3, a2, a3); + sm2_fp_mul(a4, a2, a4); + for (i = 0; i < 32; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(a2, a5, a3); + sm2_fp_mul(a3, a2, a3); + sm2_fp_mul(a4, a2, a4); + for (i = 0; i < 32; i++) + sm2_fp_sqr(a5, a5); + sm2_fp_mul(r, a4, a5); + + sm2_bn_clean(a1); + sm2_bn_clean(a2); + sm2_bn_clean(a3); + sm2_bn_clean(a4); + sm2_bn_clean(a5); +} + +void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) +{ + sm2_bn_add(r, a, b); + if (sm2_bn_cmp(r, SM2_N) >= 0) { + sm2_bn_sub(r, r, SM2_N); + } +} + +void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) +{ + if (sm2_bn_cmp(a, b) >= 0) { + sm2_bn_sub(r, a, b); + } else { + SM2_BN t; + sm2_bn_add(t, a, SM2_N); + sm2_bn_sub(r, t, b); + } +} + +void sm2_fn_neg(SM2_Fn r, const SM2_Fn a) +{ + if (sm2_bn_is_zero(a)) { + sm2_bn_copy(r, a); + } else { + sm2_bn_sub(r, SM2_N, a); + } +} + +/* bn288 only used in barrett reduction */ +static int sm2_bn288_cmp(const uint64_t a[9], const uint64_t b[9]) +{ + int i; + for (i = 8; i >= 0; i--) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + return 0; +} + +static void sm2_bn288_add(uint64_t r[9], const uint64_t a[9], const uint64_t b[9]) +{ + int i; + r[0] = a[0] + b[0]; + for (i = 1; i < 9; i++) { + r[i] = a[i] + b[i] + (r[i-1] >> 32); + } + for (i = 0; i < 8; i++) { + r[i] &= 0xffffffff; + } +} + +static void sm2_bn288_sub(uint64_t ret[9], const uint64_t a[9], const uint64_t b[9]) +{ + int i; + uint64_t r[9]; + + r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; + for (i = 1; i < 8; i++) { + r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); + r[i - 1] &= 0xffffffff; + } + r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; + r[i - 1] &= 0xffffffff; + + for (i = 0; i < 9; i++) { + ret[i] = r[i]; + } +} + +void sm2_fn_mul(SM2_BN r, const SM2_BN a, const SM2_BN b) +{ + static const uint64_t mu[8] = { + 0xf15149a0, 0x12ac6361, 0xfa323c01, 0x8dfc2096, + 1, 1, 1, 0x100000001, + }; + + uint64_t s[17]; + uint64_t zh[9]; + uint64_t zl[9]; + uint64_t q[9]; + uint64_t w; + int i, j; + + + /* z = a * b */ + for (i = 0; i < 8; i++) { + s[i] = 0; + } + for (i = 0; i < 8; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + a[i] * b[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + + /* zl = z mod (2^32)^9 = z[0..8] + * zh = z // (2^32)^7 = z[7..15] */ + for (i = 0; i < 9; i++) { + zl[i] = s[i]; + zh[i] = s[7 + i]; + } + //printf("zl = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); + //printf("zh = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zh[i]); printf("\n"); + + /* q = zh * mu // (2^32)^9 */ + for (i = 0; i < 9; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + zh[i] * mu[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + for (i = 0; i < 8; i++) { + q[i] = s[9 + i]; + } + //printf("q = "); for (i = 7; i >= 0; i--) printf("%08x", (uint32_t)q[i]); printf("\n"); + + + /* q = q * n mod (2^32)^9 */ + for (i = 0; i < 8; i++) { + s[i] = 0; + } + for (i = 0; i < 8; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + q[i] * SM2_N[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[i]; + } + //printf("qn = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)q[i]); printf("\n"); + + /* r = zl - q (mod (2^32)^9) */ + + if (sm2_bn288_cmp(zl, q)) { + sm2_bn288_sub(zl, zl, q); + } else { + uint64_t c[9] = {0,0,0,0,0,0,0,0,0x100000000}; + sm2_bn288_sub(q, c, q); + sm2_bn288_add(zl, q, zl); + } + + //printf("r = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); + + for (i = 0; i < 8; i++) { + r[i] = zl[i]; + } + r[7] += zl[8] << 32; + + /* while r >= p do: r = r - n */ + while (sm2_bn_cmp(r, SM2_N) >= 0) { + sm2_bn_sub(r, r, SM2_N); + //printf("r = r -n = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); + } +} + +void sm2_fn_sqr(SM2_BN r, const SM2_BN a) +{ + sm2_fn_mul(r, a, a); +} + +void sm2_fn_exp(SM2_BN r, const SM2_BN a, const SM2_BN e) +{ + SM2_BN t; + uint32_t w; + int i, j; + + sm2_bn_set_one(t); + for (i = 7; i >= 0; i--) { + w = (uint32_t)e[i]; + for (j = 0; j < 32; j++) { + sm2_fn_sqr(t, t); + if (w & 0x80000000) { + sm2_fn_mul(t, t, a); + } + w <<= 1; + } + } + + sm2_bn_copy(r, t); +} + +void sm2_fn_inv(SM2_BN r, const SM2_BN a) +{ + SM2_BN e; + sm2_bn_sub(e, SM2_N, SM2_TWO); + sm2_fn_exp(r, a, e); +} + +void sm2_fn_rand(SM2_BN r) +{ + sm2_bn_rand_range(r, SM2_N); +} + + + +void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R) +{ + memset(R, 0, sizeof(SM2_JACOBIAN_POINT)); + R->X[0] = 1; + R->Y[0] = 1; +} + +int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P) +{ + return sm2_bn_is_zero(P->Z); +} + +void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y) +{ + sm2_bn_copy(R->X, x); + sm2_bn_copy(R->Y, y); + sm2_bn_set_one(R->Z); +} + +void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y) +{ + SM2_BN z_inv; + + if (sm2_bn_is_one(P->Z)) { + sm2_bn_copy(x, P->X); + sm2_bn_copy(y, P->Y); + } else { + sm2_fp_inv(z_inv, P->Z); + if (y) + sm2_fp_mul(y, P->Y, z_inv); + sm2_fp_sqr(z_inv, z_inv); + sm2_fp_mul(x, P->X, z_inv); + if (y) + sm2_fp_mul(y, y, z_inv); + } +} + +int sm2_jacobian_pointpoint_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P) +{ + int len = 0; + SM2_BN x; + SM2_BN y; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + sm2_jacobian_point_get_xy(P, x, y); + + sm2_bn_print(fp, fmt, ind, "x", x); + sm2_bn_print(fp, fmt, ind, "y", y); + + return 1; +} + +int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P) +{ + SM2_BN t0; + SM2_BN t1; + SM2_BN t2; + + if (sm2_bn_is_one(P->Z)) { + sm2_fp_sqr(t0, P->Y); + sm2_fp_add(t0, t0, P->X); + sm2_fp_add(t0, t0, P->X); + sm2_fp_add(t0, t0, P->X); + sm2_fp_sqr(t1, P->X); + sm2_fp_mul(t1, t1, P->X); + sm2_fp_add(t1, t1, SM2_B); + } else { + sm2_fp_sqr(t0, P->Y); + sm2_fp_sqr(t1, P->Z); + sm2_fp_sqr(t2, t1); + sm2_fp_mul(t1, t1, t2); + sm2_fp_mul(t1, t1, SM2_B); + sm2_fp_mul(t2, t2, P->X); + sm2_fp_add(t0, t0, t2); + sm2_fp_add(t0, t0, t2); + sm2_fp_add(t0, t0, t2); + sm2_fp_sqr(t2, P->X); + sm2_fp_mul(t2, t2, P->X); + sm2_fp_add(t1, t1, t2); + } + + if (sm2_bn_cmp(t0, t1) != 0) { + error_print(); + return -1; + } + return 1; +} + +void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) +{ + sm2_bn_copy(R->X, P->X); + sm2_fp_neg(R->Y, P->Y); + sm2_bn_copy(R->Z, P->Z); +} + +void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) +{ + const uint64_t *X1 = P->X; + const uint64_t *Y1 = P->Y; + const uint64_t *Z1 = P->Z; + SM2_BN T1; + SM2_BN T2; + SM2_BN T3; + SM2_BN X3; + SM2_BN Y3; + SM2_BN Z3; + //printf("X1 = "); print_bn(X1); + //printf("Y1 = "); print_bn(Y1); + //printf("Z1 = "); print_bn(Z1); + + if (sm2_jacobian_point_is_at_infinity(P)) { + sm2_jacobian_point_copy(R, P); + return; + } + + sm2_fp_sqr(T1, Z1); //printf("T1 = Z1^2 = "); print_bn(T1); + sm2_fp_sub(T2, X1, T1); //printf("T2 = X1 - T1 = "); print_bn(T2); + sm2_fp_add(T1, X1, T1); //printf("T1 = X1 + T1 = "); print_bn(T1); + sm2_fp_mul(T2, T2, T1); //printf("T2 = T2 * T1 = "); print_bn(T2); + sm2_fp_tri(T2, T2); //printf("T2 = 3 * T2 = "); print_bn(T2); + sm2_fp_dbl(Y3, Y1); //printf("Y3 = 2 * Y1 = "); print_bn(Y3); + sm2_fp_mul(Z3, Y3, Z1); //printf("Z3 = Y3 * Z1 = "); print_bn(Z3); + sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); + sm2_fp_mul(T3, Y3, X1); //printf("T3 = Y3 * X1 = "); print_bn(T3); + sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); + sm2_fp_div2(Y3, Y3); //printf("Y3 = Y3/2 = "); print_bn(Y3); + sm2_fp_sqr(X3, T2); //printf("X3 = T2^2 = "); print_bn(X3); + sm2_fp_dbl(T1, T3); //printf("T1 = 2 * T1 = "); print_bn(T1); + sm2_fp_sub(X3, X3, T1); //printf("X3 = X3 - T1 = "); print_bn(X3); + sm2_fp_sub(T1, T3, X3); //printf("T1 = T3 - X3 = "); print_bn(T1); + sm2_fp_mul(T1, T1, T2); //printf("T1 = T1 * T2 = "); print_bn(T1); + sm2_fp_sub(Y3, T1, Y3); //printf("Y3 = T1 - Y3 = "); print_bn(Y3); + + sm2_bn_copy(R->X, X3); + sm2_bn_copy(R->Y, Y3); + sm2_bn_copy(R->Z, Z3); + + //printf("X3 = "); print_bn(R->X); + //printf("Y3 = "); print_bn(R->Y); + //printf("Z3 = "); print_bn(R->Z); + +} + +void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) +{ + const uint64_t *X1 = P->X; + const uint64_t *Y1 = P->Y; + const uint64_t *Z1 = P->Z; + const uint64_t *x2 = Q->X; + const uint64_t *y2 = Q->Y; + SM2_BN T1; + SM2_BN T2; + SM2_BN T3; + SM2_BN T4; + SM2_BN X3; + SM2_BN Y3; + SM2_BN Z3; + + if (sm2_jacobian_point_is_at_infinity(Q)) { + sm2_jacobian_point_copy(R, P); + return; + } + + if (sm2_jacobian_point_is_at_infinity(P)) { + sm2_jacobian_point_copy(R, Q); + return; + } + + assert(sm2_bn_is_one(Q->Z)); + + sm2_fp_sqr(T1, Z1); + sm2_fp_mul(T2, T1, Z1); + sm2_fp_mul(T1, T1, x2); + sm2_fp_mul(T2, T2, y2); + sm2_fp_sub(T1, T1, X1); + sm2_fp_sub(T2, T2, Y1); + if (sm2_bn_is_zero(T1)) { + if (sm2_bn_is_zero(T2)) { + SM2_JACOBIAN_POINT _Q, *Q = &_Q; + sm2_jacobian_point_set_xy(Q, x2, y2); + + sm2_jacobian_point_dbl(R, Q); + return; + } else { + sm2_jacobian_point_set_infinity(R); + return; + } + } + sm2_fp_mul(Z3, Z1, T1); + sm2_fp_sqr(T3, T1); + sm2_fp_mul(T4, T3, T1); + sm2_fp_mul(T3, T3, X1); + sm2_fp_dbl(T1, T3); + sm2_fp_sqr(X3, T2); + sm2_fp_sub(X3, X3, T1); + sm2_fp_sub(X3, X3, T4); + sm2_fp_sub(T3, T3, X3); + sm2_fp_mul(T3, T3, T2); + sm2_fp_mul(T4, T4, Y1); + sm2_fp_sub(Y3, T3, T4); + + sm2_bn_copy(R->X, X3); + sm2_bn_copy(R->Y, Y3); + sm2_bn_copy(R->Z, Z3); +} + +void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) +{ + SM2_JACOBIAN_POINT _T, *T = &_T; + sm2_jacobian_point_neg(T, Q); + sm2_jacobian_point_add(R, P, T); +} + +void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P) +{ + char bits[257] = {0}; + SM2_JACOBIAN_POINT _Q, *Q = &_Q; + SM2_JACOBIAN_POINT _T, *T = &_T; + int i; + + // FIXME: point_add need affine, so we can not use point_add + if (!sm2_bn_is_one(P->Z)) { + SM2_BN x; + SM2_BN y; + sm2_jacobian_point_get_xy(P, x, y); + sm2_jacobian_point_set_xy(T, x, y); + P = T; + } + + sm2_jacobian_point_set_infinity(Q); + sm2_bn_to_bits(k, bits); + for (i = 0; i < 256; i++) { + sm2_jacobian_point_dbl(Q, Q); + if (bits[i] == '1') { + sm2_jacobian_point_add(Q, Q, P); + } + } + sm2_jacobian_point_copy(R, Q); +} + +void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]) +{ + SM2_BN x; + SM2_BN y; + sm2_jacobian_point_get_xy(P, x, y); + sm2_bn_to_bytes(x, out); + sm2_bn_to_bytes(y, out + 32); +} + +void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]) +{ + sm2_bn_from_bytes(P->X, in); + sm2_bn_from_bytes(P->Y, in + 32); + sm2_bn_set_word(P->Z, 1); + /* should we check if sm2_jacobian_point_is_on_curve */ +} + +void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k) +{ + sm2_jacobian_point_mul(R, k, SM2_G); +} + +/* R = t * P + s * G */ +void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s) +{ + SM2_JACOBIAN_POINT _sG, *sG = &_sG; + SM2_BN x; + SM2_BN y; + + /* T = s * G */ + sm2_jacobian_point_mul_generator(sG, s); + + // R = t * P + sm2_jacobian_point_mul(R, t, P); + sm2_jacobian_point_get_xy(R, x, y); + sm2_jacobian_point_set_xy(R, x, y); + + // R = R + T + sm2_jacobian_point_add(R, sG, R); +} + +void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]) +{ + sm2_bn_from_hex(P->X, hex); + sm2_bn_from_hex(P->Y, hex + 64); + sm2_bn_set_one(P->Z); +} + +int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]) +{ + SM2_BN x; + SM2_BN y; + SM2_JACOBIAN_POINT _T, *T = &_T; + + sm2_jacobian_point_get_xy(P, x, y); + sm2_jacobian_point_from_hex(T, hex); + + return (sm2_bn_cmp(x, T->X) == 0) && (sm2_bn_cmp(y, T->Y) == 0); +} + + + +int sm2_point_is_on_curve(const SM2_POINT *P) +{ + SM2_JACOBIAN_POINT T; + sm2_jacobian_point_from_bytes(&T, (const uint8_t *)P); + return sm2_jacobian_point_is_on_curve(&T); +} + +int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y) +{ + SM2_BN _x, _y, _g, _z; + sm2_bn_from_bytes(_x, x); + + // g = x^3 - 3x + b = (x^2 - 3)*x + b + sm2_fp_sqr(_g, _x); + sm2_fp_sub(_g, _g, SM2_THREE); + sm2_fp_mul(_g, _g, _x); + sm2_fp_add(_g, _g, SM2_B); + + // y = g^(u + 1) mod p, u = (p - 3)/4 + sm2_fp_exp(_y, _g, SM2_U_PLUS_ONE); + + // z = y^2 mod p + sm2_fp_sqr(_z, _y); + if (sm2_bn_cmp(_z, _g)) { + error_print(); + return -1; + } + + if ((y == 0x02 && sm2_bn_is_odd(_y)) || (y == 0x03) && !sm2_bn_is_odd(_y)) { + sm2_fp_neg(_y, _y); + } + + sm2_bn_to_bytes(_x, P->x); + sm2_bn_to_bytes(_y, P->y); + + sm2_bn_clean(_x); + sm2_bn_clean(_y); + sm2_bn_clean(_g); + sm2_bn_clean(_z); + + if (!sm2_point_is_on_curve(P)) { + error_print(); + return -1; + } + return 1; +} + +int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]) +{ + memcpy(P->x, x, 32); + memcpy(P->y, y, 32); + return sm2_point_is_on_curve(P); +} + +int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P) +{ + SM2_BN _k; + SM2_JACOBIAN_POINT _P; + + sm2_bn_from_bytes(_k, k); + sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); + sm2_jacobian_point_mul(&_P, _k, &_P); + sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); + + sm2_bn_clean(_k); + return 1; +} + +int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]) +{ + SM2_BN _k; + SM2_JACOBIAN_POINT _R; + + sm2_bn_from_bytes(_k, k); + sm2_jacobian_point_mul_generator(&_R, _k); + sm2_jacobian_point_to_bytes(&_R, (uint8_t *)R); + + sm2_bn_clean(_k); + return 1; +} + +int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]) +{ + SM2_BN _k; + SM2_JACOBIAN_POINT _P; + SM2_BN _s; + + sm2_bn_from_bytes(_k, k); + sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); + sm2_bn_from_bytes(_s, s); + sm2_jacobian_point_mul_sum(&_P, _k, &_P, _s); + sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); + + sm2_bn_clean(_k); + sm2_bn_clean(_s); + return 1; +} + +int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + format_bytes(fp, fmt, ind, "x", P->x, 32); + format_bytes(fp, fmt, ind, "y", P->y, 32); + return 1; +} + +void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]) +{ + *out++ = (P->y[31] & 0x01) ? 0x03 : 0x02; + memcpy(out, P->x, 32); +} + +void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]) +{ + *out++ = 0x04; + memcpy(out, P, 64); +} + +int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen) +{ + if ((*in == 0x02 || *in == 0x03) && inlen == 33) { + if (sm2_point_from_x(P, in + 1, *in) != 1) { + error_print(); + return -1; + } + } else if (*in == 0x04 && inlen == 65) { + if (sm2_point_from_xy(P, in + 1, in + 33) != 1) { + error_print(); + return -1; + } + } else { + error_print(); + return -1; + } + return 1; +} + +int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen) +{ + uint8_t octets[65]; + if (!P) { + return 0; + } + sm2_point_to_uncompressed_octets(P, octets); + if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (dlen != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(P, d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} diff --git a/src/sm2_key.c b/src/sm2_key.c index 234edd5a..a1f3f26b 100644 --- a/src/sm2_key.c +++ b/src/sm2_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,625 +7,626 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int sm2_key_generate(SM2_KEY *key) -{ - SM2_BN x; - SM2_BN y; - SM2_JACOBIAN_POINT _P, *P = &_P; - - if (!key) { - error_print(); - return -1; - } - memset(key, 0, sizeof(SM2_KEY)); - - do { - sm2_bn_rand_range(x, SM2_N); - } while (sm2_bn_is_zero(x)); - sm2_bn_to_bytes(x, key->private_key); - - sm2_jacobian_point_mul_generator(P, x); - sm2_jacobian_point_get_xy(P, x, y); - sm2_bn_to_bytes(x, key->public_key.x); - sm2_bn_to_bytes(y, key->public_key.y); - return 1; -} - -int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]) -{ - memcpy(&key->private_key, private_key, 32); - // FIXEM:检查私钥是否在有效的范围内 - - if (sm2_point_mul_generator(&key->public_key, private_key) != 1) { - error_print(); - return -1; - } - - - return 1; -} - -int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key) -{ - if (!key || !public_key) { - error_print(); - return -1; - } - memset(key, 0, sizeof(SM2_KEY)); - key->public_key = *public_key; - return 1; -} - -int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm2_public_key_print(fp, fmt, ind, "publicKey", key); - format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32); - return 1; -} - -int sm2_public_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen) -{ - uint8_t buf[65]; - size_t len = 0; - - if (!key) { - return 0; - } - sm2_point_to_uncompressed_octets(&key->public_key, buf); - if (asn1_bit_octets_to_der(buf, sizeof(buf), out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_public_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - SM2_POINT P; - - if ((ret = asn1_bit_octets_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (dlen != 65) { - error_print(); - return -1; - } - if (sm2_point_from_octets(&P, d, dlen) != 1 - || sm2_key_set_public_key(key, &P) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key) -{ - return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key); -} - -int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen) -{ - if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen) -{ - int ret; - int oid; - int curve; - - if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (oid != OID_ec_public_key) { - printf("%s %d: oid = %d\n", __FILE__, __LINE__, oid); - error_print(); - return -1; - } - if (curve != OID_sm2) { - error_print(); - return -1; - } - return 1; -} - -int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - uint8_t params[64]; - uint8_t pubkey[128]; - uint8_t *params_ptr = params; - uint8_t *pubkey_ptr = pubkey; - size_t params_len = 0; - size_t pubkey_len = 0; - - if (ec_named_curve_to_der(OID_sm2, ¶ms_ptr, ¶ms_len) != 1 - || sm2_public_key_to_der(key, &pubkey_ptr, &pubkey_len) != 1) { - error_print(); - return -1; - } - if (asn1_int_to_der(EC_private_key_version, NULL, &len) != 1 - || asn1_octet_string_to_der(key->private_key, 32, NULL, &len) != 1 - || asn1_explicit_to_der(0, params, params_len, NULL, &len) != 1 - || asn1_explicit_to_der(1, pubkey, pubkey_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(EC_private_key_version, out, outlen) != 1 - || asn1_octet_string_to_der(key->private_key, 32, out, outlen) != 1 - || asn1_explicit_to_der(0, params, params_len, out, outlen) != 1 - || asn1_explicit_to_der(1, pubkey, pubkey_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - int ver; - const uint8_t *prikey; - const uint8_t *params; - const uint8_t *pubkey; - size_t prikey_len, params_len, pubkey_len; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(&ver, &d, &dlen) != 1 - || asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1 - || asn1_explicit_from_der(0, ¶ms, ¶ms_len, &d, &dlen) != 1 - || asn1_explicit_from_der(1, &pubkey, &pubkey_len, &d, &dlen) != 1 - || asn1_check(ver == EC_private_key_version) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (params) { - int curve; - if (ec_named_curve_from_der(&curve, ¶ms, ¶ms_len) != 1 - || asn1_check(curve == OID_sm2) != 1 - || asn1_length_is_zero(params_len) != 1) { - error_print(); - return -1; - } - } - if (asn1_check(prikey_len == 32) != 1 - || sm2_key_set_private_key(key, prikey) != 1) { - error_print(); - return -1; - } - // 这里的逻辑上应该是用一个新的公钥来接收公钥,并且判断这个和私钥是否一致 - if (pubkey) { - SM2_KEY tmp_key; - if (sm2_public_key_from_der(&tmp_key, &pubkey, &pubkey_len) != 1 - || asn1_length_is_zero(pubkey_len) != 1) { - error_print(); - return -1; - } - if (sm2_public_key_equ(key, &tmp_key) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - return ec_private_key_print(fp, fmt, ind, label, d, dlen); -} - - -#define SM2_PRIVATE_KEY_MAX_SIZE 512 // 需要测试这个buffer的最大值 - -int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - uint8_t prikey[SM2_PRIVATE_KEY_MAX_SIZE]; - uint8_t *p = prikey; - size_t prikey_len = 0; - - if (sm2_private_key_to_der(sm2_key, &p, &prikey_len) != 1) { - error_print(); - return -1; - } - if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1 - || sm2_public_key_algor_to_der(NULL, &len) != 1 - || asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1 - || sm2_public_key_algor_to_der(out, outlen) != 1 - || asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) { - memset(prikey, 0, sizeof(prikey)); - error_print(); - return -1; - } - memset(prikey, 0, sizeof(prikey)); - return 1; -} - -int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - int version; - const uint8_t *prikey; - size_t prikey_len; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(&version, &d, &dlen) != 1 - || sm2_public_key_algor_from_der(&d, &dlen) != 1 - || asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1 - || asn1_implicit_set_from_der(0, attrs, attrslen, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (asn1_check(version == PKCS8_private_key_info_version) != 1 - || sm2_private_key_from_der(sm2_key, &prikey, &prikey_len) != 1 - || asn1_length_is_zero(prikey_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - int val; - const uint8_t *prikey; - size_t prikey_len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %d\n", val); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_public_key_algor_print(fp, fmt, ind, "privateKeyAlgorithm", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - if (asn1_sequence_from_der(&prikey, &prikey_len, &p, &len) != 1) goto err; - ec_private_key_print(fp, fmt, ind + 4, "privateKey", prikey, prikey_len); - if (asn1_length_is_zero(len) != 1) goto err; - if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - else if (ret) format_bytes(fp, fmt, ind, "attributes", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -#if 0 // 私钥的BASE64编解码可能受到侧信道攻击 -#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // TODO:计算长度 - -int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp) -{ - uint8_t buf[SM2_PRIVATE_KEY_INFO_MAX_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_private_key_info_to_der(key, &p, &len) != 1 - || pem_write(fp, "PRIVATE KEY", buf, len) != 1) { - memset(buf, 0, sizeof(buf)); - error_print(); - return -1; - } - memset(buf, 0, sizeof(buf)); - return 1; -} - -int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, FILE *fp) -{ - uint8_t buf[512]; // 这个可能是不够用的,因为attributes可能很长 - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, "PRIVATE KEY", buf, &len, sizeof(buf)) != 1 - || sm2_private_key_info_from_der(sm2_key, attrs, attrslen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} -#endif - -int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (sm2_public_key_algor_to_der(NULL, &len) != 1 - || sm2_public_key_to_der(pub_key, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || sm2_public_key_algor_to_der(out, outlen) != 1 - || sm2_public_key_to_der(pub_key, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (sm2_public_key_algor_from_der(&d, &dlen) != 1 - || sm2_public_key_from_der(pub_key, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -#if 0 // 私钥的BASE64编解码可能受到侧信道攻击 -int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp) -{ - uint8_t buf[512]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_private_key_to_der(a, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, "EC PRIVATE KEY", buf, len) <= 0) { - error_print(); - return -1; - } - return 1; -} - -int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, "EC PRIVATE KEY", buf, &len, sizeof(buf)) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_from_der(a, &cp, &len) != 1 - || len > 0) { - error_print(); - return -1; - } - return 1; -} -#endif - -int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp) -{ - uint8_t buf[512]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_public_key_info_to_der(a, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, "PUBLIC KEY", buf, len) <= 0) { - error_print(); - return -1; - } - return 1; -} - -int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, "PUBLIC KEY", buf, &len, sizeof(buf)) != 1) { - error_print(); - return -1; - } - if (sm2_public_key_info_from_der(a, &cp, &len) != 1 - || len > 0) { - return -1; - } - return 1; -} - -int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key) -{ - if (memcmp(sm2_key, pub_key, sizeof(SM2_POINT)) == 0) { - return 1; - } - return 0; -} - -int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key) -{ - return sm2_key_set_public_key(sm2_key, &pub_key->public_key); -} - -int sm2_public_key_digest(const SM2_KEY *sm2_key, uint8_t dgst[32]) -{ - uint8_t bits[65]; - sm2_point_to_uncompressed_octets(&sm2_key->public_key, bits); - sm3_digest(bits, sizeof(bits), dgst); - return 1; -} - -int sm2_private_key_info_encrypt_to_der(const SM2_KEY *sm2_key, const char *pass, - uint8_t **out, size_t *outlen) -{ - int ret = -1; - uint8_t pkey_info[2560]; - uint8_t *p = pkey_info; - size_t pkey_info_len = 0; - uint8_t salt[16]; - int iter = 65536; - uint8_t iv[16]; - uint8_t key[16]; - SM4_KEY sm4_key; - uint8_t enced_pkey_info[5120]; - size_t enced_pkey_info_len; - - if (sm2_private_key_info_to_der(sm2_key, &p, &pkey_info_len) != 1 - || rand_bytes(salt, sizeof(salt)) != 1 - || rand_bytes(iv, sizeof(iv)) != 1 - || pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), - salt, sizeof(salt), iter, sizeof(key), key) != 1) { - error_print(); - goto end; - } - sm4_set_encrypt_key(&sm4_key, key); - if (sm4_cbc_padding_encrypt( - &sm4_key, iv, pkey_info, pkey_info_len, - enced_pkey_info, &enced_pkey_info_len) != 1 - || pkcs8_enced_private_key_info_to_der( - salt, sizeof(salt), iter, sizeof(key), OID_hmac_sm3, - OID_sm4_cbc, iv, sizeof(iv), - enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) { - error_print(); - goto end; - } - ret = 1; -end: - memset(pkey_info, 0, sizeof(pkey_info)); - memset(key, 0, sizeof(key)); - memset(&sm4_key, 0, sizeof(sm4_key)); - return ret; -} - -int sm2_private_key_info_decrypt_from_der(SM2_KEY *sm2, - const uint8_t **attrs, size_t *attrs_len, - const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - const uint8_t *salt; - size_t saltlen; - int iter; - int keylen; - int prf; - int cipher; - const uint8_t *iv; - size_t ivlen; - uint8_t key[16]; - SM4_KEY sm4_key; - const uint8_t *enced_pkey_info; - size_t enced_pkey_info_len; - uint8_t pkey_info[256]; - const uint8_t *cp = pkey_info; - size_t pkey_info_len; - - if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf, - &cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1 - || asn1_check(keylen == -1 || keylen == 16) != 1 - || asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == 16) != 1 - || asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) { - error_print(); - return -1; - } - if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { - error_print(); - goto end; - } - sm4_set_decrypt_key(&sm4_key, key); - if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len, - pkey_info, &pkey_info_len) != 1 - || sm2_private_key_info_from_der(sm2, attrs, attrs_len, &cp, &pkey_info_len) != 1 - || asn1_length_is_zero(pkey_info_len) != 1) { - error_print(); - - if (pkey_info_len) { - format_bytes(stderr, 0, 0, "700", cp, pkey_info_len); - } - - - goto end; - } - ret = 1; -end: - memset(&sm4_key, 0, sizeof(sm4_key)); - memset(key, 0, sizeof(key)); - memset(pkey_info, 0, sizeof(pkey_info)); - return ret; -} - -int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *sm2_key, const char *pass, FILE *fp) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_private_key_info_encrypt_to_der(sm2_key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, "ENCRYPTED PRIVATE KEY", buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; - size_t len; - const uint8_t *attrs; - size_t attrs_len; - - if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1 - || sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1) { - error_print(); - return -1; - } - if (asn1_length_is_zero(len) != 1) { - format_bytes(stderr, 0, 0, "", cp, len); - error_print(); - return -1; - } - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int sm2_key_generate(SM2_KEY *key) +{ + SM2_BN x; + SM2_BN y; + SM2_JACOBIAN_POINT _P, *P = &_P; + + if (!key) { + error_print(); + return -1; + } + memset(key, 0, sizeof(SM2_KEY)); + + do { + sm2_bn_rand_range(x, SM2_N); + } while (sm2_bn_is_zero(x)); + sm2_bn_to_bytes(x, key->private_key); + + sm2_jacobian_point_mul_generator(P, x); + sm2_jacobian_point_get_xy(P, x, y); + sm2_bn_to_bytes(x, key->public_key.x); + sm2_bn_to_bytes(y, key->public_key.y); + return 1; +} + +int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]) +{ + memcpy(&key->private_key, private_key, 32); + // FIXEM:检查私钥是否在有效的范围内 + + if (sm2_point_mul_generator(&key->public_key, private_key) != 1) { + error_print(); + return -1; + } + + + return 1; +} + +int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key) +{ + if (!key || !public_key) { + error_print(); + return -1; + } + memset(key, 0, sizeof(SM2_KEY)); + key->public_key = *public_key; + return 1; +} + +int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm2_public_key_print(fp, fmt, ind, "publicKey", key); + format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32); + return 1; +} + +int sm2_public_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen) +{ + uint8_t buf[65]; + size_t len = 0; + + if (!key) { + return 0; + } + sm2_point_to_uncompressed_octets(&key->public_key, buf); + if (asn1_bit_octets_to_der(buf, sizeof(buf), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_public_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + SM2_POINT P; + + if ((ret = asn1_bit_octets_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (dlen != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(&P, d, dlen) != 1 + || sm2_key_set_public_key(key, &P) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key) +{ + return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key); +} + +int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen) +{ + if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen) +{ + int ret; + int oid; + int curve; + + if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (oid != OID_ec_public_key) { + printf("%s %d: oid = %d\n", __FILE__, __LINE__, oid); + error_print(); + return -1; + } + if (curve != OID_sm2) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + uint8_t params[64]; + uint8_t pubkey[128]; + uint8_t *params_ptr = params; + uint8_t *pubkey_ptr = pubkey; + size_t params_len = 0; + size_t pubkey_len = 0; + + if (ec_named_curve_to_der(OID_sm2, ¶ms_ptr, ¶ms_len) != 1 + || sm2_public_key_to_der(key, &pubkey_ptr, &pubkey_len) != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(EC_private_key_version, NULL, &len) != 1 + || asn1_octet_string_to_der(key->private_key, 32, NULL, &len) != 1 + || asn1_explicit_to_der(0, params, params_len, NULL, &len) != 1 + || asn1_explicit_to_der(1, pubkey, pubkey_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(EC_private_key_version, out, outlen) != 1 + || asn1_octet_string_to_der(key->private_key, 32, out, outlen) != 1 + || asn1_explicit_to_der(0, params, params_len, out, outlen) != 1 + || asn1_explicit_to_der(1, pubkey, pubkey_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + int ver; + const uint8_t *prikey; + const uint8_t *params; + const uint8_t *pubkey; + size_t prikey_len, params_len, pubkey_len; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(&ver, &d, &dlen) != 1 + || asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1 + || asn1_explicit_from_der(0, ¶ms, ¶ms_len, &d, &dlen) != 1 + || asn1_explicit_from_der(1, &pubkey, &pubkey_len, &d, &dlen) != 1 + || asn1_check(ver == EC_private_key_version) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (params) { + int curve; + if (ec_named_curve_from_der(&curve, ¶ms, ¶ms_len) != 1 + || asn1_check(curve == OID_sm2) != 1 + || asn1_length_is_zero(params_len) != 1) { + error_print(); + return -1; + } + } + if (asn1_check(prikey_len == 32) != 1 + || sm2_key_set_private_key(key, prikey) != 1) { + error_print(); + return -1; + } + // 这里的逻辑上应该是用一个新的公钥来接收公钥,并且判断这个和私钥是否一致 + if (pubkey) { + SM2_KEY tmp_key; + if (sm2_public_key_from_der(&tmp_key, &pubkey, &pubkey_len) != 1 + || asn1_length_is_zero(pubkey_len) != 1) { + error_print(); + return -1; + } + if (sm2_public_key_equ(key, &tmp_key) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + return ec_private_key_print(fp, fmt, ind, label, d, dlen); +} + + +#define SM2_PRIVATE_KEY_MAX_SIZE 512 // 需要测试这个buffer的最大值 + +int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + uint8_t prikey[SM2_PRIVATE_KEY_MAX_SIZE]; + uint8_t *p = prikey; + size_t prikey_len = 0; + + if (sm2_private_key_to_der(sm2_key, &p, &prikey_len) != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1 + || sm2_public_key_algor_to_der(NULL, &len) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1 + || sm2_public_key_algor_to_der(out, outlen) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) { + memset(prikey, 0, sizeof(prikey)); + error_print(); + return -1; + } + memset(prikey, 0, sizeof(prikey)); + return 1; +} + +int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + int version; + const uint8_t *prikey; + size_t prikey_len; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(&version, &d, &dlen) != 1 + || sm2_public_key_algor_from_der(&d, &dlen) != 1 + || asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, attrs, attrslen, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (asn1_check(version == PKCS8_private_key_info_version) != 1 + || sm2_private_key_from_der(sm2_key, &prikey, &prikey_len) != 1 + || asn1_length_is_zero(prikey_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int val; + const uint8_t *prikey; + size_t prikey_len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %d\n", val); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_public_key_algor_print(fp, fmt, ind, "privateKeyAlgorithm", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + if (asn1_sequence_from_der(&prikey, &prikey_len, &p, &len) != 1) goto err; + ec_private_key_print(fp, fmt, ind + 4, "privateKey", prikey, prikey_len); + if (asn1_length_is_zero(len) != 1) goto err; + if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + else if (ret) format_bytes(fp, fmt, ind, "attributes", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +#if 0 // 私钥的BASE64编解码可能受到侧信道攻击 +#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // TODO:计算长度 + +int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp) +{ + uint8_t buf[SM2_PRIVATE_KEY_INFO_MAX_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_private_key_info_to_der(key, &p, &len) != 1 + || pem_write(fp, "PRIVATE KEY", buf, len) != 1) { + memset(buf, 0, sizeof(buf)); + error_print(); + return -1; + } + memset(buf, 0, sizeof(buf)); + return 1; +} + +int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen, FILE *fp) +{ + uint8_t buf[512]; // 这个可能是不够用的,因为attributes可能很长 + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, "PRIVATE KEY", buf, &len, sizeof(buf)) != 1 + || sm2_private_key_info_from_der(sm2_key, attrs, attrslen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} +#endif + +int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (sm2_public_key_algor_to_der(NULL, &len) != 1 + || sm2_public_key_to_der(pub_key, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || sm2_public_key_algor_to_der(out, outlen) != 1 + || sm2_public_key_to_der(pub_key, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (sm2_public_key_algor_from_der(&d, &dlen) != 1 + || sm2_public_key_from_der(pub_key, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +#if 0 // 私钥的BASE64编解码可能受到侧信道攻击 +int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp) +{ + uint8_t buf[512]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_private_key_to_der(a, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, "EC PRIVATE KEY", buf, len) <= 0) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, "EC PRIVATE KEY", buf, &len, sizeof(buf)) != 1) { + error_print(); + return -1; + } + if (sm2_private_key_from_der(a, &cp, &len) != 1 + || len > 0) { + error_print(); + return -1; + } + return 1; +} +#endif + +int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp) +{ + uint8_t buf[512]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_public_key_info_to_der(a, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, "PUBLIC KEY", buf, len) <= 0) { + error_print(); + return -1; + } + return 1; +} + +int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, "PUBLIC KEY", buf, &len, sizeof(buf)) != 1) { + error_print(); + return -1; + } + if (sm2_public_key_info_from_der(a, &cp, &len) != 1 + || len > 0) { + return -1; + } + return 1; +} + +int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key) +{ + if (memcmp(sm2_key, pub_key, sizeof(SM2_POINT)) == 0) { + return 1; + } + return 0; +} + +int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key) +{ + return sm2_key_set_public_key(sm2_key, &pub_key->public_key); +} + +int sm2_public_key_digest(const SM2_KEY *sm2_key, uint8_t dgst[32]) +{ + uint8_t bits[65]; + sm2_point_to_uncompressed_octets(&sm2_key->public_key, bits); + sm3_digest(bits, sizeof(bits), dgst); + return 1; +} + +int sm2_private_key_info_encrypt_to_der(const SM2_KEY *sm2_key, const char *pass, + uint8_t **out, size_t *outlen) +{ + int ret = -1; + uint8_t pkey_info[2560]; + uint8_t *p = pkey_info; + size_t pkey_info_len = 0; + uint8_t salt[16]; + int iter = 65536; + uint8_t iv[16]; + uint8_t key[16]; + SM4_KEY sm4_key; + uint8_t enced_pkey_info[5120]; + size_t enced_pkey_info_len; + + if (sm2_private_key_info_to_der(sm2_key, &p, &pkey_info_len) != 1 + || rand_bytes(salt, sizeof(salt)) != 1 + || rand_bytes(iv, sizeof(iv)) != 1 + || pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), + salt, sizeof(salt), iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_encrypt_key(&sm4_key, key); + if (sm4_cbc_padding_encrypt( + &sm4_key, iv, pkey_info, pkey_info_len, + enced_pkey_info, &enced_pkey_info_len) != 1 + || pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, sizeof(key), OID_hmac_sm3, + OID_sm4_cbc, iv, sizeof(iv), + enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + memset(pkey_info, 0, sizeof(pkey_info)); + memset(key, 0, sizeof(key)); + memset(&sm4_key, 0, sizeof(sm4_key)); + return ret; +} + +int sm2_private_key_info_decrypt_from_der(SM2_KEY *sm2, + const uint8_t **attrs, size_t *attrs_len, + const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + const uint8_t *salt; + size_t saltlen; + int iter; + int keylen; + int prf; + int cipher; + const uint8_t *iv; + size_t ivlen; + uint8_t key[16]; + SM4_KEY sm4_key; + const uint8_t *enced_pkey_info; + size_t enced_pkey_info_len; + uint8_t pkey_info[256]; + const uint8_t *cp = pkey_info; + size_t pkey_info_len; + + if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf, + &cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1 + || asn1_check(keylen == -1 || keylen == 16) != 1 + || asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == 16) != 1 + || asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) { + error_print(); + return -1; + } + if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_decrypt_key(&sm4_key, key); + if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len, + pkey_info, &pkey_info_len) != 1 + || sm2_private_key_info_from_der(sm2, attrs, attrs_len, &cp, &pkey_info_len) != 1 + || asn1_length_is_zero(pkey_info_len) != 1) { + error_print(); + + if (pkey_info_len) { + format_bytes(stderr, 0, 0, "700", cp, pkey_info_len); + } + + + goto end; + } + ret = 1; +end: + memset(&sm4_key, 0, sizeof(sm4_key)); + memset(key, 0, sizeof(key)); + memset(pkey_info, 0, sizeof(pkey_info)); + return ret; +} + +int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *sm2_key, const char *pass, FILE *fp) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_private_key_info_encrypt_to_der(sm2_key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, "ENCRYPTED PRIVATE KEY", buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + const uint8_t *attrs; + size_t attrs_len; + + if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1 + || sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1) { + error_print(); + return -1; + } + if (asn1_length_is_zero(len) != 1) { + format_bytes(stderr, 0, 0, "", cp, len); + error_print(); + return -1; + } + return 1; +} diff --git a/src/sm2_lib.c b/src/sm2_lib.c index b1295008..f84a2051 100644 --- a/src/sm2_lib.c +++ b/src/sm2_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,688 +7,689 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define print_bn(str,a) sm2_bn_print(stderr,0,4,str,a) - -int sm2_do_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], SM2_SIGNATURE *sig) -{ - SM2_JACOBIAN_POINT _P, *P = &_P; - SM2_BN d; - SM2_BN e; - SM2_BN k; - SM2_BN x; - SM2_BN r; - SM2_BN s; - -retry: - sm2_bn_from_bytes(d, key->private_key); - - // e = H(M) - sm2_bn_from_bytes(e, dgst); //print_bn("e", e); - // e被重用了,注意retry的位置! - - // rand k in [1, n - 1] - do { - sm2_fn_rand(k); - } while (sm2_bn_is_zero(k)); - //print_bn("k", k); - - // (x, y) = kG - sm2_jacobian_point_mul_generator(P, k); - sm2_jacobian_point_get_xy(P, x, NULL); - //print_bn("x", x); - - - // r = e + x (mod n) - sm2_fn_add(r, e, x); //print_bn("r = e + x (mod n)", r); - - /* if r == 0 or r + k == n re-generate k */ - if (sm2_bn_is_zero(r)) { - goto retry; - } - sm2_bn_add(x, r, k); - if (sm2_bn_cmp(x, SM2_N) == 0) { - goto retry; - } - - /* s = ((1 + d)^-1 * (k - r * d)) mod n */ - - sm2_fn_mul(e, r, d); //print_bn("r*d", e); - sm2_fn_sub(k, k, e); //print_bn("k-r*d", k); - sm2_fn_add(e, SM2_ONE, d); //print_bn("1 +d", e); - sm2_fn_inv(e, e); //print_bn("(1+d)^-1", e); - sm2_fn_mul(s, e, k); //print_bn("s = ((1 + d)^-1 * (k - r * d)) mod n", s); - - sm2_bn_to_bytes(r, sig->r); //print_bn("r", r); - sm2_bn_to_bytes(s, sig->s); //print_bn("s", s); - - if (fixed_outlen) { - uint8_t buf[72]; - uint8_t *p = buf; - size_t len = 0; - sm2_signature_to_der(sig, &p, &len); - if (len != 71) { - goto retry; - } - } - - gmssl_secure_clear(d, sizeof(d)); - gmssl_secure_clear(e, sizeof(e)); - gmssl_secure_clear(k, sizeof(k)); - gmssl_secure_clear(x, sizeof(x)); - return 1; -} - -int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig) -{ - return sm2_do_sign_ex(key, 0, dgst, sig); -} - -int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig) -{ - SM2_JACOBIAN_POINT _P, *P = &_P; - SM2_JACOBIAN_POINT _R, *R = &_R; - SM2_BN r; - SM2_BN s; - SM2_BN e; - SM2_BN x; - SM2_BN t; - - // parse signature values - sm2_bn_from_bytes(r, sig->r); //print_bn("r", r); - sm2_bn_from_bytes(s, sig->s); //print_bn("s", s); - if (sm2_bn_is_zero(r) == 1 - || sm2_bn_cmp(r, SM2_N) >= 0 - || sm2_bn_is_zero(s) == 1 - || sm2_bn_cmp(s, SM2_N) >= 0) { - error_print(); - return -1; - } - - // parse public key - sm2_jacobian_point_from_bytes(P, (const uint8_t *)&key->public_key); - //print_point("P", P); - - // t = r + s (mod n) - // check t != 0 - sm2_fn_add(t, r, s); //print_bn("t = r + s (mod n)", t); - if (sm2_bn_is_zero(t)) { - error_print(); - return -1; - } - - // Q = s * G + t * P - sm2_jacobian_point_mul_sum(R, t, P, s); - sm2_jacobian_point_get_xy(R, x, NULL); - //print_bn("x", x); - - // e = H(M) - // r' = e + x (mod n) - sm2_bn_from_bytes(e, dgst); //print_bn("e = H(M)", e); - sm2_fn_add(e, e, x); //print_bn("e + x (mod n)", e); - - - // check if r == r' - if (sm2_bn_cmp(e, r) != 0) { - return 0; - } - return 1; -} - -int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (!sig) { - return 0; - } - if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1 - || asn1_integer_to_der(sig->s, 32, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_integer_to_der(sig->r, 32, out, outlen) != 1 - || asn1_integer_to_der(sig->s, 32, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *r; - size_t rlen; - const uint8_t *s; - size_t slen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_integer_from_der(&r, &rlen, &d, &dlen) != 1 - || asn1_integer_from_der(&s, &slen, &d, &dlen) != 1 - || asn1_length_le(rlen, 32) != 1 - || asn1_length_le(slen, 32) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(sig, 0, sizeof(*sig)); - memcpy(sig->r + 32 - rlen, r, rlen); // 需要测试当r, s是比较小的整数时 - memcpy(sig->s + 32 - slen, s, slen); - return 1; -} - -int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - SM2_SIGNATURE sig; - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - if (sm2_signature_from_der(&sig, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "r", sig.r, 32); - format_bytes(fp, fmt, ind, "s", sig.s, 32); - return 1; -} - -#define SM2_SIGNATURE_MAX_DER_SIZE 77 - -int sm2_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) -{ - SM2_SIGNATURE signature; - uint8_t *p; - - if (!key - || !dgst - || !sig - || !siglen) { - error_print(); - return -1; - } - - p = sig; - *siglen = 0; - if (sm2_do_sign_ex(key, fixed_outlen, dgst, &signature) != 1 - || sm2_signature_to_der(&signature, &p, siglen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) -{ - return sm2_sign_ex(key, 0, dgst, sig, siglen); -} - -int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen) -{ - int ret; - SM2_SIGNATURE signature; - const uint8_t *p; - size_t len; - - if (!key - || !dgst - || !sig - || !siglen) { - error_print(); - return -1; - } - - p = sig; - if (sm2_signature_from_der(&signature, &p, &siglen) != 1 - || asn1_length_is_zero(siglen) != 1) { - error_print(); - return -1; - } - if ((ret = sm2_do_verify(key, dgst, &signature)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -extern void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t blocks); - -int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen) -{ - SM3_CTX ctx; - uint8_t zin[18 + 32 * 6] = { - 0x00, 0x80, - 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, - 0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,0x9E,0x4B,0xCF,0x65,0x09,0xA7, - 0xF3,0x97,0x89,0xF5,0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94,0x0E,0x93, - 0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,0x04,0x46,0x6A,0x39,0xC9,0x94, - 0x8F,0xE3,0x0B,0xBF,0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C,0x74,0xC7, - 0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,0xCE,0xE3,0x6B,0x69,0x21,0x53, - 0xD0,0xA9,0x87,0x7C,0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39,0xF0,0xA0, - }; - - if (!z || !pub || !id) { - error_print(); - return -1; - } - - memcpy(&zin[18 + 32 * 4], pub->x, 32); - memcpy(&zin[18 + 32 * 5], pub->y, 32); - - sm3_init(&ctx); - if (strcmp(id, SM2_DEFAULT_ID) == 0) { - sm3_update(&ctx, zin, sizeof(zin)); - } else { - uint8_t idbits[2]; - idbits[0] = (uint8_t)(idlen >> 5); - idbits[1] = (uint8_t)(idlen << 3); - sm3_update(&ctx, idbits, 2); - sm3_update(&ctx, (uint8_t *)id, idlen); - sm3_update(&ctx, zin + 18, 32 * 6); - } - sm3_finish(&ctx, z); - return 1; -} - -int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen) -{ - if (!ctx || !key) { - error_print(); - return -1; - } - ctx->key = *key; - sm3_init(&ctx->sm3_ctx); - - if (id) { - uint8_t z[SM3_DIGEST_SIZE]; - if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) { - error_print(); - return -1; - } - sm2_compute_z(z, &key->public_key, id, idlen); - sm3_update(&ctx->sm3_ctx, z, sizeof(z)); - } - return 1; -} - -int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) -{ - if (!ctx) { - error_print(); - return -1; - } - if (data && datalen > 0) { - sm3_update(&ctx->sm3_ctx, data, datalen); - } - return 1; -} - -int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen) -{ - int ret; - uint8_t dgst[SM3_DIGEST_SIZE]; - - if (!ctx || !sig || !siglen) { - error_print(); - return -1; - } - sm3_finish(&ctx->sm3_ctx, dgst); - if ((ret = sm2_sign(&ctx->key, dgst, sig, siglen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen) -{ - if (!ctx || !key) { - error_print(); - return -1; - } - ctx->key = *key; - sm3_init(&ctx->sm3_ctx); - - if (id) { - uint8_t z[SM3_DIGEST_SIZE]; - if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) { - error_print(); - return -1; - } - sm2_compute_z(z, &key->public_key, id, idlen); - sm3_update(&ctx->sm3_ctx, z, sizeof(z)); - } - return 1; -} - -int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) -{ - if (!ctx) { - error_print(); - return -1; - } - if (data && datalen > 0) { - sm3_update(&ctx->sm3_ctx, data, datalen); - } - return 1; -} - -int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen) -{ - int ret; - uint8_t dgst[SM3_DIGEST_SIZE]; - - if (!ctx || !sig) { - error_print(); - return -1; - } - sm3_finish(&ctx->sm3_ctx, dgst); - if ((ret = sm2_verify(&ctx->key, dgst, sig, siglen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out) -{ - SM3_CTX ctx; - uint8_t counter_be[4]; - uint8_t dgst[SM3_DIGEST_SIZE]; - uint32_t counter = 1; - size_t len; - - while (outlen) { - PUTU32(counter_be, counter); - counter++; - - sm3_init(&ctx); - sm3_update(&ctx, in, inlen); - sm3_update(&ctx, counter_be, sizeof(counter_be)); - sm3_finish(&ctx, dgst); - - len = outlen < SM3_DIGEST_SIZE ? outlen : SM3_DIGEST_SIZE; - memcpy(out, dgst, len); - out += len; - outlen -= len; - } - - memset(&ctx, 0, sizeof(SM3_CTX)); - memset(dgst, 0, sizeof(dgst)); - return 1; -} - -int sm2_do_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out) -{ - SM2_BN k; - SM2_JACOBIAN_POINT _P, *P = &_P; - SM3_CTX sm3_ctx; - uint8_t buf[64]; - int i; - -retry: - // rand k in [1, n - 1] - sm2_bn_rand_range(k, SM2_N); - if (sm2_bn_is_zero(k)) goto retry; - - // C1 = k * G = (x1, y1) - sm2_jacobian_point_mul_generator(P, k); - sm2_jacobian_point_to_bytes(P, (uint8_t *)&out->point); - - if (fixed_outlen) { - size_t xlen = 0, ylen = 0; - asn1_integer_to_der(out->point.x, 32, NULL, &xlen); - if (xlen != 34) goto retry; - asn1_integer_to_der(out->point.y, 32, NULL, &ylen); - if (ylen != 34) goto retry; - } - - // Q = k * P = (x2, y2) - sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key); - - sm2_jacobian_point_mul(P, k, P); - - sm2_jacobian_point_to_bytes(P, buf); - - - // t = KDF(x2 || y2, klen) - sm2_kdf(buf, sizeof(buf), inlen, out->ciphertext); - - - // C2 = M xor t - for (i = 0; i < inlen; i++) { - out->ciphertext[i] ^= in[i]; - } - out->ciphertext_size = (uint32_t)inlen; - - // C3 = Hash(x2 || m || y2) - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, buf, 32); - sm3_update(&sm3_ctx, in, inlen); - sm3_update(&sm3_ctx, buf + 32, 32); - sm3_finish(&sm3_ctx, out->hash); - - return 1; -} - -int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out) -{ - return sm2_do_encrypt_ex(key, 0, in, inlen, out); -} - -int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen) -{ - uint32_t inlen; - SM2_BN d; - SM2_JACOBIAN_POINT _P, *P = &_P; - SM3_CTX sm3_ctx; - uint8_t buf[64]; - uint8_t hash[32]; - int i; - - // FIXME: check SM2_CIPHERTEXT format - - // check C1 - sm2_jacobian_point_from_bytes(P, (uint8_t *)&in->point); - //point_print(stdout, P, 0, 2); - - /* - if (!sm2_jacobian_point_is_on_curve(P)) { - fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); - return -1; - } - */ - - // d * C1 = (x2, y2) - sm2_bn_from_bytes(d, key->private_key); - sm2_jacobian_point_mul(P, d, P); - sm2_bn_clean(d); - sm2_jacobian_point_to_bytes(P, buf); - - // t = KDF(x2 || y2, klen) - if ((inlen = in->ciphertext_size) <= 0) { - fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); - return -1; - } - - sm2_kdf(buf, sizeof(buf), inlen, out); - - // M = C2 xor t - for (i = 0; i < inlen; i++) { - out[i] ^= in->ciphertext[i]; - } - *outlen = inlen; - - // u = Hash(x2 || M || y2) - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, buf, 32); - sm3_update(&sm3_ctx, out, inlen); - sm3_update(&sm3_ctx, buf + 32, 32); - sm3_finish(&sm3_ctx, hash); - - // check if u == C3 - if (memcmp(in->hash, hash, sizeof(hash)) != 0) { - fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); - return -1; - } - - return 1; -} - -int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *C, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (!C) { - return 0; - } - if (asn1_integer_to_der(C->point.x, 32, NULL, &len) != 1 - || asn1_integer_to_der(C->point.y, 32, NULL, &len) != 1 - || asn1_octet_string_to_der(C->hash, 32, NULL, &len) != 1 - || asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_integer_to_der(C->point.x, 32, out, outlen) != 1 - || asn1_integer_to_der(C->point.y, 32, out, outlen) != 1 - || asn1_octet_string_to_der(C->hash, 32, out, outlen) != 1 - || asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *x; - const uint8_t *y; - const uint8_t *hash; - const uint8_t *c; - size_t xlen, ylen, hashlen, clen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_integer_from_der(&x, &xlen, &d, &dlen) != 1 - || asn1_integer_from_der(&y, &ylen, &d, &dlen) != 1 - || asn1_octet_string_from_der(&hash, &hashlen, &d, &dlen) != 1 - || asn1_octet_string_from_der(&c, &clen, &d, &dlen) != 1 - || asn1_length_le(xlen, 32) != 1 - || asn1_length_le(ylen, 32) != 1 - || asn1_check(hashlen == 32) != 1 - || asn1_length_le(clen, SM2_MAX_PLAINTEXT_SIZE) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(C, 0, sizeof(SM2_CIPHERTEXT)); - memcpy(C->point.x + 32 - xlen, x, xlen); - memcpy(C->point.y + 32 - ylen, y, ylen); - if (sm2_point_is_on_curve(&C->point) != 1) { - error_print(); - return -1; - } - memcpy(C->hash, hash, hashlen); - memcpy(C->ciphertext, c, clen); - C->ciphertext_size = (uint8_t)clen; - return 1; -} - -int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - uint8_t buf[512] = {0}; - SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)buf; - int i; - - if (sm2_ciphertext_from_der(c, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - format_bytes(fp, fmt, ind, "XCoordinate", c->point.x, 32); - format_bytes(fp, fmt, ind, "YCoordinate", c->point.y, 32); - format_bytes(fp, fmt, ind, "HASH", c->hash, 32); - format_bytes(fp, fmt, ind, "CipherText", c->ciphertext, c->ciphertext_size); - return 1; -} - -int sm2_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM2_CIPHERTEXT C; - - if (!key || !in || !out || !outlen) { - error_print(); - return -1; - } - if (inlen < SM2_MIN_PLAINTEXT_SIZE || inlen > SM2_MAX_PLAINTEXT_SIZE) { - error_print(); - return -1; - } - if (sm2_do_encrypt_ex(key, fixed_outlen, in, inlen, &C) != 1) { - error_print(); - return -1; - } - *outlen = 0; - if (sm2_ciphertext_to_der(&C, &out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - return sm2_encrypt_ex(key, 0, in, inlen, out, outlen); -} - -int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM2_CIPHERTEXT C; - - if (!key || !in || !out || !outlen) { - error_print(); - return -1; - } - if (sm2_ciphertext_from_der(&C, &in, &inlen) != 1 - || asn1_length_is_zero(inlen) != 1) { - error_print(); - return -1; - } - if (sm2_do_decrypt(key, &C, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out) -{ - if (!key || !peer_public || !out) { - error_print(); - return -1; - } - if (sm2_point_mul(out, key->private_key, peer_public) != 1) { - error_print(); - return -1; - } - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define print_bn(str,a) sm2_bn_print(stderr,0,4,str,a) + +int sm2_do_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], SM2_SIGNATURE *sig) +{ + SM2_JACOBIAN_POINT _P, *P = &_P; + SM2_BN d; + SM2_BN e; + SM2_BN k; + SM2_BN x; + SM2_BN r; + SM2_BN s; + +retry: + sm2_bn_from_bytes(d, key->private_key); + + // e = H(M) + sm2_bn_from_bytes(e, dgst); //print_bn("e", e); + // e被重用了,注意retry的位置! + + // rand k in [1, n - 1] + do { + sm2_fn_rand(k); + } while (sm2_bn_is_zero(k)); + //print_bn("k", k); + + // (x, y) = kG + sm2_jacobian_point_mul_generator(P, k); + sm2_jacobian_point_get_xy(P, x, NULL); + //print_bn("x", x); + + + // r = e + x (mod n) + sm2_fn_add(r, e, x); //print_bn("r = e + x (mod n)", r); + + /* if r == 0 or r + k == n re-generate k */ + if (sm2_bn_is_zero(r)) { + goto retry; + } + sm2_bn_add(x, r, k); + if (sm2_bn_cmp(x, SM2_N) == 0) { + goto retry; + } + + /* s = ((1 + d)^-1 * (k - r * d)) mod n */ + + sm2_fn_mul(e, r, d); //print_bn("r*d", e); + sm2_fn_sub(k, k, e); //print_bn("k-r*d", k); + sm2_fn_add(e, SM2_ONE, d); //print_bn("1 +d", e); + sm2_fn_inv(e, e); //print_bn("(1+d)^-1", e); + sm2_fn_mul(s, e, k); //print_bn("s = ((1 + d)^-1 * (k - r * d)) mod n", s); + + sm2_bn_to_bytes(r, sig->r); //print_bn("r", r); + sm2_bn_to_bytes(s, sig->s); //print_bn("s", s); + + if (fixed_outlen) { + uint8_t buf[72]; + uint8_t *p = buf; + size_t len = 0; + sm2_signature_to_der(sig, &p, &len); + if (len != 71) { + goto retry; + } + } + + gmssl_secure_clear(d, sizeof(d)); + gmssl_secure_clear(e, sizeof(e)); + gmssl_secure_clear(k, sizeof(k)); + gmssl_secure_clear(x, sizeof(x)); + return 1; +} + +int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig) +{ + return sm2_do_sign_ex(key, 0, dgst, sig); +} + +int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig) +{ + SM2_JACOBIAN_POINT _P, *P = &_P; + SM2_JACOBIAN_POINT _R, *R = &_R; + SM2_BN r; + SM2_BN s; + SM2_BN e; + SM2_BN x; + SM2_BN t; + + // parse signature values + sm2_bn_from_bytes(r, sig->r); //print_bn("r", r); + sm2_bn_from_bytes(s, sig->s); //print_bn("s", s); + if (sm2_bn_is_zero(r) == 1 + || sm2_bn_cmp(r, SM2_N) >= 0 + || sm2_bn_is_zero(s) == 1 + || sm2_bn_cmp(s, SM2_N) >= 0) { + error_print(); + return -1; + } + + // parse public key + sm2_jacobian_point_from_bytes(P, (const uint8_t *)&key->public_key); + //print_point("P", P); + + // t = r + s (mod n) + // check t != 0 + sm2_fn_add(t, r, s); //print_bn("t = r + s (mod n)", t); + if (sm2_bn_is_zero(t)) { + error_print(); + return -1; + } + + // Q = s * G + t * P + sm2_jacobian_point_mul_sum(R, t, P, s); + sm2_jacobian_point_get_xy(R, x, NULL); + //print_bn("x", x); + + // e = H(M) + // r' = e + x (mod n) + sm2_bn_from_bytes(e, dgst); //print_bn("e = H(M)", e); + sm2_fn_add(e, e, x); //print_bn("e + x (mod n)", e); + + + // check if r == r' + if (sm2_bn_cmp(e, r) != 0) { + return 0; + } + return 1; +} + +int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (!sig) { + return 0; + } + if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1 + || asn1_integer_to_der(sig->s, 32, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(sig->r, 32, out, outlen) != 1 + || asn1_integer_to_der(sig->s, 32, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *r; + size_t rlen; + const uint8_t *s; + size_t slen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&r, &rlen, &d, &dlen) != 1 + || asn1_integer_from_der(&s, &slen, &d, &dlen) != 1 + || asn1_length_le(rlen, 32) != 1 + || asn1_length_le(slen, 32) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(sig, 0, sizeof(*sig)); + memcpy(sig->r + 32 - rlen, r, rlen); // 需要测试当r, s是比较小的整数时 + memcpy(sig->s + 32 - slen, s, slen); + return 1; +} + +int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + SM2_SIGNATURE sig; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if (sm2_signature_from_der(&sig, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "r", sig.r, 32); + format_bytes(fp, fmt, ind, "s", sig.s, 32); + return 1; +} + +#define SM2_SIGNATURE_MAX_DER_SIZE 77 + +int sm2_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) +{ + SM2_SIGNATURE signature; + uint8_t *p; + + if (!key + || !dgst + || !sig + || !siglen) { + error_print(); + return -1; + } + + p = sig; + *siglen = 0; + if (sm2_do_sign_ex(key, fixed_outlen, dgst, &signature) != 1 + || sm2_signature_to_der(&signature, &p, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) +{ + return sm2_sign_ex(key, 0, dgst, sig, siglen); +} + +int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen) +{ + int ret; + SM2_SIGNATURE signature; + const uint8_t *p; + size_t len; + + if (!key + || !dgst + || !sig + || !siglen) { + error_print(); + return -1; + } + + p = sig; + if (sm2_signature_from_der(&signature, &p, &siglen) != 1 + || asn1_length_is_zero(siglen) != 1) { + error_print(); + return -1; + } + if ((ret = sm2_do_verify(key, dgst, &signature)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +extern void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t blocks); + +int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen) +{ + SM3_CTX ctx; + uint8_t zin[18 + 32 * 6] = { + 0x00, 0x80, + 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC, + 0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,0x9E,0x4B,0xCF,0x65,0x09,0xA7, + 0xF3,0x97,0x89,0xF5,0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94,0x0E,0x93, + 0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,0x04,0x46,0x6A,0x39,0xC9,0x94, + 0x8F,0xE3,0x0B,0xBF,0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C,0x74,0xC7, + 0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,0xCE,0xE3,0x6B,0x69,0x21,0x53, + 0xD0,0xA9,0x87,0x7C,0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39,0xF0,0xA0, + }; + + if (!z || !pub || !id) { + error_print(); + return -1; + } + + memcpy(&zin[18 + 32 * 4], pub->x, 32); + memcpy(&zin[18 + 32 * 5], pub->y, 32); + + sm3_init(&ctx); + if (strcmp(id, SM2_DEFAULT_ID) == 0) { + sm3_update(&ctx, zin, sizeof(zin)); + } else { + uint8_t idbits[2]; + idbits[0] = (uint8_t)(idlen >> 5); + idbits[1] = (uint8_t)(idlen << 3); + sm3_update(&ctx, idbits, 2); + sm3_update(&ctx, (uint8_t *)id, idlen); + sm3_update(&ctx, zin + 18, 32 * 6); + } + sm3_finish(&ctx, z); + return 1; +} + +int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen) +{ + if (!ctx || !key) { + error_print(); + return -1; + } + ctx->key = *key; + sm3_init(&ctx->sm3_ctx); + + if (id) { + uint8_t z[SM3_DIGEST_SIZE]; + if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) { + error_print(); + return -1; + } + sm2_compute_z(z, &key->public_key, id, idlen); + sm3_update(&ctx->sm3_ctx, z, sizeof(z)); + } + return 1; +} + +int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (!ctx) { + error_print(); + return -1; + } + if (data && datalen > 0) { + sm3_update(&ctx->sm3_ctx, data, datalen); + } + return 1; +} + +int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen) +{ + int ret; + uint8_t dgst[SM3_DIGEST_SIZE]; + + if (!ctx || !sig || !siglen) { + error_print(); + return -1; + } + sm3_finish(&ctx->sm3_ctx, dgst); + if ((ret = sm2_sign(&ctx->key, dgst, sig, siglen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen) +{ + if (!ctx || !key) { + error_print(); + return -1; + } + ctx->key = *key; + sm3_init(&ctx->sm3_ctx); + + if (id) { + uint8_t z[SM3_DIGEST_SIZE]; + if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) { + error_print(); + return -1; + } + sm2_compute_z(z, &key->public_key, id, idlen); + sm3_update(&ctx->sm3_ctx, z, sizeof(z)); + } + return 1; +} + +int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (!ctx) { + error_print(); + return -1; + } + if (data && datalen > 0) { + sm3_update(&ctx->sm3_ctx, data, datalen); + } + return 1; +} + +int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen) +{ + int ret; + uint8_t dgst[SM3_DIGEST_SIZE]; + + if (!ctx || !sig) { + error_print(); + return -1; + } + sm3_finish(&ctx->sm3_ctx, dgst); + if ((ret = sm2_verify(&ctx->key, dgst, sig, siglen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out) +{ + SM3_CTX ctx; + uint8_t counter_be[4]; + uint8_t dgst[SM3_DIGEST_SIZE]; + uint32_t counter = 1; + size_t len; + + while (outlen) { + PUTU32(counter_be, counter); + counter++; + + sm3_init(&ctx); + sm3_update(&ctx, in, inlen); + sm3_update(&ctx, counter_be, sizeof(counter_be)); + sm3_finish(&ctx, dgst); + + len = outlen < SM3_DIGEST_SIZE ? outlen : SM3_DIGEST_SIZE; + memcpy(out, dgst, len); + out += len; + outlen -= len; + } + + memset(&ctx, 0, sizeof(SM3_CTX)); + memset(dgst, 0, sizeof(dgst)); + return 1; +} + +int sm2_do_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out) +{ + SM2_BN k; + SM2_JACOBIAN_POINT _P, *P = &_P; + SM3_CTX sm3_ctx; + uint8_t buf[64]; + int i; + +retry: + // rand k in [1, n - 1] + sm2_bn_rand_range(k, SM2_N); + if (sm2_bn_is_zero(k)) goto retry; + + // C1 = k * G = (x1, y1) + sm2_jacobian_point_mul_generator(P, k); + sm2_jacobian_point_to_bytes(P, (uint8_t *)&out->point); + + if (fixed_outlen) { + size_t xlen = 0, ylen = 0; + asn1_integer_to_der(out->point.x, 32, NULL, &xlen); + if (xlen != 34) goto retry; + asn1_integer_to_der(out->point.y, 32, NULL, &ylen); + if (ylen != 34) goto retry; + } + + // Q = k * P = (x2, y2) + sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key); + + sm2_jacobian_point_mul(P, k, P); + + sm2_jacobian_point_to_bytes(P, buf); + + + // t = KDF(x2 || y2, klen) + sm2_kdf(buf, sizeof(buf), inlen, out->ciphertext); + + + // C2 = M xor t + for (i = 0; i < inlen; i++) { + out->ciphertext[i] ^= in[i]; + } + out->ciphertext_size = (uint32_t)inlen; + + // C3 = Hash(x2 || m || y2) + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, buf, 32); + sm3_update(&sm3_ctx, in, inlen); + sm3_update(&sm3_ctx, buf + 32, 32); + sm3_finish(&sm3_ctx, out->hash); + + return 1; +} + +int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out) +{ + return sm2_do_encrypt_ex(key, 0, in, inlen, out); +} + +int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen) +{ + uint32_t inlen; + SM2_BN d; + SM2_JACOBIAN_POINT _P, *P = &_P; + SM3_CTX sm3_ctx; + uint8_t buf[64]; + uint8_t hash[32]; + int i; + + // FIXME: check SM2_CIPHERTEXT format + + // check C1 + sm2_jacobian_point_from_bytes(P, (uint8_t *)&in->point); + //point_print(stdout, P, 0, 2); + + /* + if (!sm2_jacobian_point_is_on_curve(P)) { + fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); + return -1; + } + */ + + // d * C1 = (x2, y2) + sm2_bn_from_bytes(d, key->private_key); + sm2_jacobian_point_mul(P, d, P); + sm2_bn_clean(d); + sm2_jacobian_point_to_bytes(P, buf); + + // t = KDF(x2 || y2, klen) + if ((inlen = in->ciphertext_size) <= 0) { + fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); + return -1; + } + + sm2_kdf(buf, sizeof(buf), inlen, out); + + // M = C2 xor t + for (i = 0; i < inlen; i++) { + out[i] ^= in->ciphertext[i]; + } + *outlen = inlen; + + // u = Hash(x2 || M || y2) + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, buf, 32); + sm3_update(&sm3_ctx, out, inlen); + sm3_update(&sm3_ctx, buf + 32, 32); + sm3_finish(&sm3_ctx, hash); + + // check if u == C3 + if (memcmp(in->hash, hash, sizeof(hash)) != 0) { + fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__); + return -1; + } + + return 1; +} + +int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *C, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (!C) { + return 0; + } + if (asn1_integer_to_der(C->point.x, 32, NULL, &len) != 1 + || asn1_integer_to_der(C->point.y, 32, NULL, &len) != 1 + || asn1_octet_string_to_der(C->hash, 32, NULL, &len) != 1 + || asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(C->point.x, 32, out, outlen) != 1 + || asn1_integer_to_der(C->point.y, 32, out, outlen) != 1 + || asn1_octet_string_to_der(C->hash, 32, out, outlen) != 1 + || asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *x; + const uint8_t *y; + const uint8_t *hash; + const uint8_t *c; + size_t xlen, ylen, hashlen, clen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&x, &xlen, &d, &dlen) != 1 + || asn1_integer_from_der(&y, &ylen, &d, &dlen) != 1 + || asn1_octet_string_from_der(&hash, &hashlen, &d, &dlen) != 1 + || asn1_octet_string_from_der(&c, &clen, &d, &dlen) != 1 + || asn1_length_le(xlen, 32) != 1 + || asn1_length_le(ylen, 32) != 1 + || asn1_check(hashlen == 32) != 1 + || asn1_length_le(clen, SM2_MAX_PLAINTEXT_SIZE) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(C, 0, sizeof(SM2_CIPHERTEXT)); + memcpy(C->point.x + 32 - xlen, x, xlen); + memcpy(C->point.y + 32 - ylen, y, ylen); + if (sm2_point_is_on_curve(&C->point) != 1) { + error_print(); + return -1; + } + memcpy(C->hash, hash, hashlen); + memcpy(C->ciphertext, c, clen); + C->ciphertext_size = (uint8_t)clen; + return 1; +} + +int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + uint8_t buf[512] = {0}; + SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)buf; + int i; + + if (sm2_ciphertext_from_der(c, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + format_bytes(fp, fmt, ind, "XCoordinate", c->point.x, 32); + format_bytes(fp, fmt, ind, "YCoordinate", c->point.y, 32); + format_bytes(fp, fmt, ind, "HASH", c->hash, 32); + format_bytes(fp, fmt, ind, "CipherText", c->ciphertext, c->ciphertext_size); + return 1; +} + +int sm2_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM2_CIPHERTEXT C; + + if (!key || !in || !out || !outlen) { + error_print(); + return -1; + } + if (inlen < SM2_MIN_PLAINTEXT_SIZE || inlen > SM2_MAX_PLAINTEXT_SIZE) { + error_print(); + return -1; + } + if (sm2_do_encrypt_ex(key, fixed_outlen, in, inlen, &C) != 1) { + error_print(); + return -1; + } + *outlen = 0; + if (sm2_ciphertext_to_der(&C, &out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + return sm2_encrypt_ex(key, 0, in, inlen, out, outlen); +} + +int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM2_CIPHERTEXT C; + + if (!key || !in || !out || !outlen) { + error_print(); + return -1; + } + if (sm2_ciphertext_from_der(&C, &in, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + error_print(); + return -1; + } + if (sm2_do_decrypt(key, &C, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out) +{ + if (!key || !peer_public || !out) { + error_print(); + return -1; + } + if (sm2_point_mul(out, key->private_key, peer_public) != 1) { + error_print(); + return -1; + } + return 1; +} diff --git a/src/sm3.c b/src/sm3.c index 8765bbe1..692ef228 100644 --- a/src/sm3.c +++ b/src/sm3.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,369 +7,370 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - - -#ifdef SM3_SSE3 -# include -# include - -# define _mm_rotl_epi32(X,i) \ - _mm_xor_si128(_mm_slli_epi32((X),(i)), _mm_srli_epi32((X),32-(i))) -#endif - - -#define ROTL(x,n) (((x)<<(n)) | ((x)>>(32-(n)))) -#define P0(x) ((x) ^ ROL32((x), 9) ^ ROL32((x),17)) -#define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) - -#define FF00(x,y,z) ((x) ^ (y) ^ (z)) -#define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) -#define GG00(x,y,z) ((x) ^ (y) ^ (z)) -#define GG16(x,y,z) ((((y)^(z)) & (x)) ^ (z)) - -#define R(A, B, C, D, E, F, G, H, xx) \ - SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); \ - SS2 = SS1 ^ ROL32(A, 12); \ - TT1 = FF##xx(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); \ - TT2 = GG##xx(E, F, G) + H + SS1 + W[j]; \ - B = ROL32(B, 9); \ - H = TT1; \ - F = ROL32(F, 19); \ - D = P0(TT2); \ - j++ - -#define R8(A, B, C, D, E, F, G, H, xx) \ - R(A, B, C, D, E, F, G, H, xx); \ - R(H, A, B, C, D, E, F, G, xx); \ - R(G, H, A, B, C, D, E, F, xx); \ - R(F, G, H, A, B, C, D, E, xx); \ - R(E, F, G, H, A, B, C, D, xx); \ - R(D, E, F, G, H, A, B, C, xx); \ - R(C, D, E, F, G, H, A, B, xx); \ - R(B, C, D, E, F, G, H, A, xx) - - - -#define T00 0x79cc4519U -#define T16 0x7a879d8aU - -#define K0 0x79cc4519U -#define K1 0xf3988a32U -#define K2 0xe7311465U -#define K3 0xce6228cbU -#define K4 0x9cc45197U -#define K5 0x3988a32fU -#define K6 0x7311465eU -#define K7 0xe6228cbcU -#define K8 0xcc451979U -#define K9 0x988a32f3U -#define K10 0x311465e7U -#define K11 0x6228cbceU -#define K12 0xc451979cU -#define K13 0x88a32f39U -#define K14 0x11465e73U -#define K15 0x228cbce6U -#define K16 0x9d8a7a87U -#define K17 0x3b14f50fU -#define K18 0x7629ea1eU -#define K19 0xec53d43cU -#define K20 0xd8a7a879U -#define K21 0xb14f50f3U -#define K22 0x629ea1e7U -#define K23 0xc53d43ceU -#define K24 0x8a7a879dU -#define K25 0x14f50f3bU -#define K26 0x29ea1e76U -#define K27 0x53d43cecU -#define K28 0xa7a879d8U -#define K29 0x4f50f3b1U -#define K30 0x9ea1e762U -#define K31 0x3d43cec5U -#define K32 0x7a879d8aU -#define K33 0xf50f3b14U -#define K34 0xea1e7629U -#define K35 0xd43cec53U -#define K36 0xa879d8a7U -#define K37 0x50f3b14fU -#define K38 0xa1e7629eU -#define K39 0x43cec53dU -#define K40 0x879d8a7aU -#define K41 0x0f3b14f5U -#define K42 0x1e7629eaU -#define K43 0x3cec53d4U -#define K44 0x79d8a7a8U -#define K45 0xf3b14f50U -#define K46 0xe7629ea1U -#define K47 0xcec53d43U -#define K48 0x9d8a7a87U -#define K49 0x3b14f50fU -#define K50 0x7629ea1eU -#define K51 0xec53d43cU -#define K52 0xd8a7a879U -#define K53 0xb14f50f3U -#define K54 0x629ea1e7U -#define K55 0xc53d43ceU -#define K56 0x8a7a879dU -#define K57 0x14f50f3bU -#define K58 0x29ea1e76U -#define K59 0x53d43cecU -#define K60 0xa7a879d8U -#define K61 0x4f50f3b1U -#define K62 0x9ea1e762U -#define K63 0x3d43cec5U - -static uint32_t K[64] = { - K0, K1, K2, K3, K4, K5, K6, K7, - K8, K9, K10, K11, K12, K13, K14, K15, - K16, K17, K18, K19, K20, K21, K22, K23, - K24, K25, K26, K27, K28, K29, K30, K31, - K32, K33, K34, K35, K36, K37, K38, K39, - K40, K41, K42, K43, K44, K45, K46, K47, - K48, K49, K50, K51, K52, K53, K54, K55, - K56, K57, K58, K59, K60, K61, K62, K63, - /* - 0x79cc4519U, 0xf3988a32U, 0xe7311465U, 0xce6228cbU, - 0x9cc45197U, 0x3988a32fU, 0x7311465eU, 0xe6228cbcU, - 0xcc451979U, 0x988a32f3U, 0x311465e7U, 0x6228cbceU, - 0xc451979cU, 0x88a32f39U, 0x11465e73U, 0x228cbce6U, - 0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU, - 0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU, - 0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU, - 0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U, - 0x7a879d8aU, 0xf50f3b14U, 0xea1e7629U, 0xd43cec53U, - 0xa879d8a7U, 0x50f3b14fU, 0xa1e7629eU, 0x43cec53dU, - 0x879d8a7aU, 0x0f3b14f5U, 0x1e7629eaU, 0x3cec53d4U, - 0x79d8a7a8U, 0xf3b14f50U, 0xe7629ea1U, 0xcec53d43U, - 0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU, - 0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU, - 0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU, - 0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U, - */ -}; - -void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t blocks) -{ - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - uint32_t E; - uint32_t F; - uint32_t G; - uint32_t H; - uint32_t W[68]; - uint32_t SS1, SS2, TT1, TT2; - int j; - -#ifdef SM3_SSE3 - __m128i X, T, R; - __m128i M = _mm_setr_epi32(0, 0, 0, 0xffffffff); - __m128i V = _mm_setr_epi8(3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12); -#endif - - while (blocks--) { - - A = digest[0]; - B = digest[1]; - C = digest[2]; - D = digest[3]; - E = digest[4]; - F = digest[5]; - G = digest[6]; - H = digest[7]; - - -#ifdef SM3_SSE3 - - for (j = 0; j < 16; j += 4) { - X = _mm_loadu_si128((__m128i *)(data + j * 4)); - X = _mm_shuffle_epi8(X, V); - _mm_storeu_si128((__m128i *)(W + j), X); - } - - for (j = 16; j < 68; j += 4) { - /* X = (W[j - 3], W[j - 2], W[j - 1], 0) */ - X = _mm_loadu_si128((__m128i *)(W + j - 3)); - X = _mm_andnot_si128(M, X); - - X = _mm_rotl_epi32(X, 15); - T = _mm_loadu_si128((__m128i *)(W + j - 9)); - X = _mm_xor_si128(X, T); - T = _mm_loadu_si128((__m128i *)(W + j - 16)); - X = _mm_xor_si128(X, T); - - /* P1() */ - T = _mm_rotl_epi32(X, (23 - 15)); - T = _mm_xor_si128(T, X); - T = _mm_rotl_epi32(T, 15); - X = _mm_xor_si128(X, T); - - T = _mm_loadu_si128((__m128i *)(W + j - 13)); - T = _mm_rotl_epi32(T, 7); - X = _mm_xor_si128(X, T); - T = _mm_loadu_si128((__m128i *)(W + j - 6)); - X = _mm_xor_si128(X, T); - - /* W[j + 3] ^= P1(ROL32(W[j + 1], 15)) */ - R = _mm_shuffle_epi32(X, 0); - R = _mm_and_si128(R, M); - T = _mm_rotl_epi32(R, 15); - T = _mm_xor_si128(T, R); - T = _mm_rotl_epi32(T, 9); - R = _mm_xor_si128(R, T); - R = _mm_rotl_epi32(R, 6); - X = _mm_xor_si128(X, R); - - _mm_storeu_si128((__m128i *)(W + j), X); - } -#else - for (j = 0; j < 16; j++) - W[j] = GETU32(data + j*4); - - for (; j < 68; j++) - W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) - ^ ROL32(W[j - 13], 7) ^ W[j - 6]; -#endif - - - j = 0; - -#define FULL_UNROLL -#ifdef FULL_UNROLL - R8(A, B, C, D, E, F, G, H, 00); - R8(A, B, C, D, E, F, G, H, 00); - R8(A, B, C, D, E, F, G, H, 16); - R8(A, B, C, D, E, F, G, H, 16); - R8(A, B, C, D, E, F, G, H, 16); - R8(A, B, C, D, E, F, G, H, 16); - R8(A, B, C, D, E, F, G, H, 16); - R8(A, B, C, D, E, F, G, H, 16); -#else - for (; j < 16; j++) { - SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7); - SS2 = SS1 ^ ROL32(A, 12); - TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); - TT2 = GG00(E, F, G) + H + SS1 + W[j]; - D = C; - C = ROL32(B, 9); - B = A; - A = TT1; - H = G; - G = ROL32(F, 19); - F = E; - E = P0(TT2); - } - - for (; j < 64; j++) { - SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7); - SS2 = SS1 ^ ROL32(A, 12); - TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); - TT2 = GG16(E, F, G) + H + SS1 + W[j]; - D = C; - C = ROL32(B, 9); - B = A; - A = TT1; - H = G; - G = ROL32(F, 19); - F = E; - E = P0(TT2); - } -#endif - - digest[0] ^= A; - digest[1] ^= B; - digest[2] ^= C; - digest[3] ^= D; - digest[4] ^= E; - digest[5] ^= F; - digest[6] ^= G; - digest[7] ^= H; - - data += 64; - } -} - - -void sm3_init(SM3_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->digest[0] = 0x7380166F; - ctx->digest[1] = 0x4914B2B9; - ctx->digest[2] = 0x172442D7; - ctx->digest[3] = 0xDA8A0600; - ctx->digest[4] = 0xA96F30BC; - ctx->digest[5] = 0x163138AA; - ctx->digest[6] = 0xE38DEE4D; - ctx->digest[7] = 0xB0FB0E4E; -} - -void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t data_len) -{ - size_t blocks; - - - ctx->num &= 0x3f; - if (ctx->num) { - unsigned int left = SM3_BLOCK_SIZE - ctx->num; - if (data_len < left) { - memcpy(ctx->block + ctx->num, data, data_len); - ctx->num += data_len; - return; - } else { - memcpy(ctx->block + ctx->num, data, left); - sm3_compress_blocks(ctx->digest, ctx->block, 1); - ctx->nblocks++; - data += left; - data_len -= left; - } - } - - blocks = data_len / SM3_BLOCK_SIZE; - sm3_compress_blocks(ctx->digest, data, blocks); - ctx->nblocks += blocks; - data += SM3_BLOCK_SIZE * blocks; - data_len -= SM3_BLOCK_SIZE * blocks; - - ctx->num = data_len; - if (data_len) { - memcpy(ctx->block, data, data_len); - } -} - -void sm3_finish(SM3_CTX *ctx, uint8_t *digest) -{ - int i; - - ctx->num &= 0x3f; - ctx->block[ctx->num] = 0x80; - - if (ctx->num <= SM3_BLOCK_SIZE - 9) { - memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); - } else { - memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); - sm3_compress_blocks(ctx->digest, ctx->block, 1); - memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); - } - PUTU32(ctx->block + 56, ctx->nblocks >> 23); - PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); - - sm3_compress_blocks(ctx->digest, ctx->block, 1); - for (i = 0; i < 8; i++) { - PUTU32(digest + i*4, ctx->digest[i]); - } - memset(ctx, 0, sizeof(SM3_CTX)); -} - -void sm3_digest(const uint8_t *msg, size_t msglen, - uint8_t dgst[SM3_DIGEST_SIZE]) -{ - SM3_CTX ctx; - sm3_init(&ctx); - sm3_update(&ctx, msg, msglen); - sm3_finish(&ctx, dgst); -} + + +#include +#include +#include +#include + + +#ifdef SM3_SSE3 +# include +# include + +# define _mm_rotl_epi32(X,i) \ + _mm_xor_si128(_mm_slli_epi32((X),(i)), _mm_srli_epi32((X),32-(i))) +#endif + + +#define ROTL(x,n) (((x)<<(n)) | ((x)>>(32-(n)))) +#define P0(x) ((x) ^ ROL32((x), 9) ^ ROL32((x),17)) +#define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) + +#define FF00(x,y,z) ((x) ^ (y) ^ (z)) +#define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) +#define GG00(x,y,z) ((x) ^ (y) ^ (z)) +#define GG16(x,y,z) ((((y)^(z)) & (x)) ^ (z)) + +#define R(A, B, C, D, E, F, G, H, xx) \ + SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); \ + SS2 = SS1 ^ ROL32(A, 12); \ + TT1 = FF##xx(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); \ + TT2 = GG##xx(E, F, G) + H + SS1 + W[j]; \ + B = ROL32(B, 9); \ + H = TT1; \ + F = ROL32(F, 19); \ + D = P0(TT2); \ + j++ + +#define R8(A, B, C, D, E, F, G, H, xx) \ + R(A, B, C, D, E, F, G, H, xx); \ + R(H, A, B, C, D, E, F, G, xx); \ + R(G, H, A, B, C, D, E, F, xx); \ + R(F, G, H, A, B, C, D, E, xx); \ + R(E, F, G, H, A, B, C, D, xx); \ + R(D, E, F, G, H, A, B, C, xx); \ + R(C, D, E, F, G, H, A, B, xx); \ + R(B, C, D, E, F, G, H, A, xx) + + + +#define T00 0x79cc4519U +#define T16 0x7a879d8aU + +#define K0 0x79cc4519U +#define K1 0xf3988a32U +#define K2 0xe7311465U +#define K3 0xce6228cbU +#define K4 0x9cc45197U +#define K5 0x3988a32fU +#define K6 0x7311465eU +#define K7 0xe6228cbcU +#define K8 0xcc451979U +#define K9 0x988a32f3U +#define K10 0x311465e7U +#define K11 0x6228cbceU +#define K12 0xc451979cU +#define K13 0x88a32f39U +#define K14 0x11465e73U +#define K15 0x228cbce6U +#define K16 0x9d8a7a87U +#define K17 0x3b14f50fU +#define K18 0x7629ea1eU +#define K19 0xec53d43cU +#define K20 0xd8a7a879U +#define K21 0xb14f50f3U +#define K22 0x629ea1e7U +#define K23 0xc53d43ceU +#define K24 0x8a7a879dU +#define K25 0x14f50f3bU +#define K26 0x29ea1e76U +#define K27 0x53d43cecU +#define K28 0xa7a879d8U +#define K29 0x4f50f3b1U +#define K30 0x9ea1e762U +#define K31 0x3d43cec5U +#define K32 0x7a879d8aU +#define K33 0xf50f3b14U +#define K34 0xea1e7629U +#define K35 0xd43cec53U +#define K36 0xa879d8a7U +#define K37 0x50f3b14fU +#define K38 0xa1e7629eU +#define K39 0x43cec53dU +#define K40 0x879d8a7aU +#define K41 0x0f3b14f5U +#define K42 0x1e7629eaU +#define K43 0x3cec53d4U +#define K44 0x79d8a7a8U +#define K45 0xf3b14f50U +#define K46 0xe7629ea1U +#define K47 0xcec53d43U +#define K48 0x9d8a7a87U +#define K49 0x3b14f50fU +#define K50 0x7629ea1eU +#define K51 0xec53d43cU +#define K52 0xd8a7a879U +#define K53 0xb14f50f3U +#define K54 0x629ea1e7U +#define K55 0xc53d43ceU +#define K56 0x8a7a879dU +#define K57 0x14f50f3bU +#define K58 0x29ea1e76U +#define K59 0x53d43cecU +#define K60 0xa7a879d8U +#define K61 0x4f50f3b1U +#define K62 0x9ea1e762U +#define K63 0x3d43cec5U + +static uint32_t K[64] = { + K0, K1, K2, K3, K4, K5, K6, K7, + K8, K9, K10, K11, K12, K13, K14, K15, + K16, K17, K18, K19, K20, K21, K22, K23, + K24, K25, K26, K27, K28, K29, K30, K31, + K32, K33, K34, K35, K36, K37, K38, K39, + K40, K41, K42, K43, K44, K45, K46, K47, + K48, K49, K50, K51, K52, K53, K54, K55, + K56, K57, K58, K59, K60, K61, K62, K63, + /* + 0x79cc4519U, 0xf3988a32U, 0xe7311465U, 0xce6228cbU, + 0x9cc45197U, 0x3988a32fU, 0x7311465eU, 0xe6228cbcU, + 0xcc451979U, 0x988a32f3U, 0x311465e7U, 0x6228cbceU, + 0xc451979cU, 0x88a32f39U, 0x11465e73U, 0x228cbce6U, + 0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU, + 0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU, + 0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU, + 0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U, + 0x7a879d8aU, 0xf50f3b14U, 0xea1e7629U, 0xd43cec53U, + 0xa879d8a7U, 0x50f3b14fU, 0xa1e7629eU, 0x43cec53dU, + 0x879d8a7aU, 0x0f3b14f5U, 0x1e7629eaU, 0x3cec53d4U, + 0x79d8a7a8U, 0xf3b14f50U, 0xe7629ea1U, 0xcec53d43U, + 0x9d8a7a87U, 0x3b14f50fU, 0x7629ea1eU, 0xec53d43cU, + 0xd8a7a879U, 0xb14f50f3U, 0x629ea1e7U, 0xc53d43ceU, + 0x8a7a879dU, 0x14f50f3bU, 0x29ea1e76U, 0x53d43cecU, + 0xa7a879d8U, 0x4f50f3b1U, 0x9ea1e762U, 0x3d43cec5U, + */ +}; + +void sm3_compress_blocks(uint32_t digest[8], const uint8_t *data, size_t blocks) +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; + uint32_t F; + uint32_t G; + uint32_t H; + uint32_t W[68]; + uint32_t SS1, SS2, TT1, TT2; + int j; + +#ifdef SM3_SSE3 + __m128i X, T, R; + __m128i M = _mm_setr_epi32(0, 0, 0, 0xffffffff); + __m128i V = _mm_setr_epi8(3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12); +#endif + + while (blocks--) { + + A = digest[0]; + B = digest[1]; + C = digest[2]; + D = digest[3]; + E = digest[4]; + F = digest[5]; + G = digest[6]; + H = digest[7]; + + +#ifdef SM3_SSE3 + + for (j = 0; j < 16; j += 4) { + X = _mm_loadu_si128((__m128i *)(data + j * 4)); + X = _mm_shuffle_epi8(X, V); + _mm_storeu_si128((__m128i *)(W + j), X); + } + + for (j = 16; j < 68; j += 4) { + /* X = (W[j - 3], W[j - 2], W[j - 1], 0) */ + X = _mm_loadu_si128((__m128i *)(W + j - 3)); + X = _mm_andnot_si128(M, X); + + X = _mm_rotl_epi32(X, 15); + T = _mm_loadu_si128((__m128i *)(W + j - 9)); + X = _mm_xor_si128(X, T); + T = _mm_loadu_si128((__m128i *)(W + j - 16)); + X = _mm_xor_si128(X, T); + + /* P1() */ + T = _mm_rotl_epi32(X, (23 - 15)); + T = _mm_xor_si128(T, X); + T = _mm_rotl_epi32(T, 15); + X = _mm_xor_si128(X, T); + + T = _mm_loadu_si128((__m128i *)(W + j - 13)); + T = _mm_rotl_epi32(T, 7); + X = _mm_xor_si128(X, T); + T = _mm_loadu_si128((__m128i *)(W + j - 6)); + X = _mm_xor_si128(X, T); + + /* W[j + 3] ^= P1(ROL32(W[j + 1], 15)) */ + R = _mm_shuffle_epi32(X, 0); + R = _mm_and_si128(R, M); + T = _mm_rotl_epi32(R, 15); + T = _mm_xor_si128(T, R); + T = _mm_rotl_epi32(T, 9); + R = _mm_xor_si128(R, T); + R = _mm_rotl_epi32(R, 6); + X = _mm_xor_si128(X, R); + + _mm_storeu_si128((__m128i *)(W + j), X); + } +#else + for (j = 0; j < 16; j++) + W[j] = GETU32(data + j*4); + + for (; j < 68; j++) + W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) + ^ ROL32(W[j - 13], 7) ^ W[j - 6]; +#endif + + + j = 0; + +#define FULL_UNROLL +#ifdef FULL_UNROLL + R8(A, B, C, D, E, F, G, H, 00); + R8(A, B, C, D, E, F, G, H, 00); + R8(A, B, C, D, E, F, G, H, 16); + R8(A, B, C, D, E, F, G, H, 16); + R8(A, B, C, D, E, F, G, H, 16); + R8(A, B, C, D, E, F, G, H, 16); + R8(A, B, C, D, E, F, G, H, 16); + R8(A, B, C, D, E, F, G, H, 16); +#else + for (; j < 16; j++) { + SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7); + SS2 = SS1 ^ ROL32(A, 12); + TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); + TT2 = GG00(E, F, G) + H + SS1 + W[j]; + D = C; + C = ROL32(B, 9); + B = A; + A = TT1; + H = G; + G = ROL32(F, 19); + F = E; + E = P0(TT2); + } + + for (; j < 64; j++) { + SS1 = ROL32((ROL32(A, 12) + E + K(j)), 7); + SS2 = SS1 ^ ROL32(A, 12); + TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); + TT2 = GG16(E, F, G) + H + SS1 + W[j]; + D = C; + C = ROL32(B, 9); + B = A; + A = TT1; + H = G; + G = ROL32(F, 19); + F = E; + E = P0(TT2); + } +#endif + + digest[0] ^= A; + digest[1] ^= B; + digest[2] ^= C; + digest[3] ^= D; + digest[4] ^= E; + digest[5] ^= F; + digest[6] ^= G; + digest[7] ^= H; + + data += 64; + } +} + + +void sm3_init(SM3_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->digest[0] = 0x7380166F; + ctx->digest[1] = 0x4914B2B9; + ctx->digest[2] = 0x172442D7; + ctx->digest[3] = 0xDA8A0600; + ctx->digest[4] = 0xA96F30BC; + ctx->digest[5] = 0x163138AA; + ctx->digest[6] = 0xE38DEE4D; + ctx->digest[7] = 0xB0FB0E4E; +} + +void sm3_update(SM3_CTX *ctx, const uint8_t *data, size_t data_len) +{ + size_t blocks; + + + ctx->num &= 0x3f; + if (ctx->num) { + unsigned int left = SM3_BLOCK_SIZE - ctx->num; + if (data_len < left) { + memcpy(ctx->block + ctx->num, data, data_len); + ctx->num += data_len; + return; + } else { + memcpy(ctx->block + ctx->num, data, left); + sm3_compress_blocks(ctx->digest, ctx->block, 1); + ctx->nblocks++; + data += left; + data_len -= left; + } + } + + blocks = data_len / SM3_BLOCK_SIZE; + sm3_compress_blocks(ctx->digest, data, blocks); + ctx->nblocks += blocks; + data += SM3_BLOCK_SIZE * blocks; + data_len -= SM3_BLOCK_SIZE * blocks; + + ctx->num = data_len; + if (data_len) { + memcpy(ctx->block, data, data_len); + } +} + +void sm3_finish(SM3_CTX *ctx, uint8_t *digest) +{ + int i; + + ctx->num &= 0x3f; + ctx->block[ctx->num] = 0x80; + + if (ctx->num <= SM3_BLOCK_SIZE - 9) { + memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); + } else { + memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); + sm3_compress_blocks(ctx->digest, ctx->block, 1); + memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); + } + PUTU32(ctx->block + 56, ctx->nblocks >> 23); + PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); + + sm3_compress_blocks(ctx->digest, ctx->block, 1); + for (i = 0; i < 8; i++) { + PUTU32(digest + i*4, ctx->digest[i]); + } + memset(ctx, 0, sizeof(SM3_CTX)); +} + +void sm3_digest(const uint8_t *msg, size_t msglen, + uint8_t dgst[SM3_DIGEST_SIZE]) +{ + SM3_CTX ctx; + sm3_init(&ctx); + sm3_update(&ctx, msg, msglen); + sm3_finish(&ctx, dgst); +} diff --git a/src/sm3_hmac.c b/src/sm3_hmac.c index ef056779..6cf3d77f 100644 --- a/src/sm3_hmac.c +++ b/src/sm3_hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,80 +7,81 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include - -/** - * HMAC_k(m) = H((k ^ opad) || H((k ^ ipad) || m)) - * pseudo-code: - * function hmac(key, message) - * opad = [0x5c * blocksize] - * ipad = [0x36 * blocksize] - * if (length(key) > blocksize) then - * key = hash(key) - * end if - * for i from 0 to length(key) - 1 step 1 - * ipad[i] = ipad[i] XOR key[i] - * opad[i] = opad[i] XOR key[i] - * end for - * return hash(opad || hash(ipad || message)) - * end function - */ - - -#define IPAD 0x36 -#define OPAD 0x5C - -void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t key_len) -{ - int i; - - if (key_len <= SM3_BLOCK_SIZE) { - memcpy(ctx->key, key, key_len); - memset(ctx->key + key_len, 0, SM3_BLOCK_SIZE - key_len); - } else { - sm3_init(&ctx->sm3_ctx); - sm3_update(&ctx->sm3_ctx, key, key_len); - sm3_finish(&ctx->sm3_ctx, ctx->key); - memset(ctx->key + SM3_DIGEST_SIZE, 0, - SM3_BLOCK_SIZE - SM3_DIGEST_SIZE); - } - for (i = 0; i < SM3_BLOCK_SIZE; i++) { - ctx->key[i] ^= IPAD; - } - - sm3_init(&ctx->sm3_ctx); - sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE); -} - -void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t data_len) -{ - sm3_update(&ctx->sm3_ctx, data, data_len); -} - -void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE]) -{ - int i; - for (i = 0; i < SM3_BLOCK_SIZE; i++) { - ctx->key[i] ^= (IPAD ^ OPAD); - } - sm3_finish(&ctx->sm3_ctx, mac); - sm3_init(&ctx->sm3_ctx); - sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE); - sm3_update(&ctx->sm3_ctx, mac, SM3_DIGEST_SIZE); - sm3_finish(&ctx->sm3_ctx, mac); - memset(ctx, 0, sizeof(*ctx)); -} - -void sm3_hmac(const uint8_t *key, size_t key_len, - const uint8_t *data, size_t data_len, - uint8_t mac[SM3_HMAC_SIZE]) -{ - SM3_HMAC_CTX ctx; - sm3_hmac_init(&ctx, key, key_len); - sm3_hmac_update(&ctx, data, data_len); - sm3_hmac_finish(&ctx, mac); -} + + + +#include +#include +#include + +/** + * HMAC_k(m) = H((k ^ opad) || H((k ^ ipad) || m)) + * pseudo-code: + * function hmac(key, message) + * opad = [0x5c * blocksize] + * ipad = [0x36 * blocksize] + * if (length(key) > blocksize) then + * key = hash(key) + * end if + * for i from 0 to length(key) - 1 step 1 + * ipad[i] = ipad[i] XOR key[i] + * opad[i] = opad[i] XOR key[i] + * end for + * return hash(opad || hash(ipad || message)) + * end function + */ + + +#define IPAD 0x36 +#define OPAD 0x5C + +void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t key_len) +{ + int i; + + if (key_len <= SM3_BLOCK_SIZE) { + memcpy(ctx->key, key, key_len); + memset(ctx->key + key_len, 0, SM3_BLOCK_SIZE - key_len); + } else { + sm3_init(&ctx->sm3_ctx); + sm3_update(&ctx->sm3_ctx, key, key_len); + sm3_finish(&ctx->sm3_ctx, ctx->key); + memset(ctx->key + SM3_DIGEST_SIZE, 0, + SM3_BLOCK_SIZE - SM3_DIGEST_SIZE); + } + for (i = 0; i < SM3_BLOCK_SIZE; i++) { + ctx->key[i] ^= IPAD; + } + + sm3_init(&ctx->sm3_ctx); + sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE); +} + +void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t data_len) +{ + sm3_update(&ctx->sm3_ctx, data, data_len); +} + +void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE]) +{ + int i; + for (i = 0; i < SM3_BLOCK_SIZE; i++) { + ctx->key[i] ^= (IPAD ^ OPAD); + } + sm3_finish(&ctx->sm3_ctx, mac); + sm3_init(&ctx->sm3_ctx); + sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE); + sm3_update(&ctx->sm3_ctx, mac, SM3_DIGEST_SIZE); + sm3_finish(&ctx->sm3_ctx, mac); + memset(ctx, 0, sizeof(*ctx)); +} + +void sm3_hmac(const uint8_t *key, size_t key_len, + const uint8_t *data, size_t data_len, + uint8_t mac[SM3_HMAC_SIZE]) +{ + SM3_HMAC_CTX ctx; + sm3_hmac_init(&ctx, key, key_len); + sm3_hmac_update(&ctx, data, data_len); + sm3_hmac_finish(&ctx, mac); +} diff --git a/src/sm3_kdf.c b/src/sm3_kdf.c index 5858ea4f..d3b6fa59 100644 --- a/src/sm3_kdf.c +++ b/src/sm3_kdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,48 +7,49 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include - - -void sm3_kdf_init(SM3_KDF_CTX *ctx, size_t outlen) -{ - sm3_init(&ctx->sm3_ctx); - ctx->outlen = outlen; -} - -void sm3_kdf_update(SM3_KDF_CTX *ctx, const uint8_t *data, size_t datalen) -{ - sm3_update(&ctx->sm3_ctx, data, datalen); -} - -void sm3_kdf_finish(SM3_KDF_CTX *ctx, uint8_t *out) -{ - SM3_CTX sm3_ctx; - size_t outlen = ctx->outlen; - uint8_t counter_be[4]; - uint8_t dgst[SM3_DIGEST_SIZE]; - uint32_t counter = 1; - size_t len; - - while (outlen) { - PUTU32(counter_be, counter); - counter++; - - sm3_ctx = ctx->sm3_ctx; - sm3_update(&sm3_ctx, counter_be, sizeof(counter_be)); - sm3_finish(&sm3_ctx, dgst); - - len = outlen < SM3_DIGEST_SIZE ? outlen : SM3_DIGEST_SIZE; - memcpy(out, dgst, len); - out += len; - outlen -= len; - } - - memset(&sm3_ctx, 0, sizeof(SM3_CTX)); - memset(dgst, 0, sizeof(dgst)); -} + + + +#include +#include +#include +#include + + +void sm3_kdf_init(SM3_KDF_CTX *ctx, size_t outlen) +{ + sm3_init(&ctx->sm3_ctx); + ctx->outlen = outlen; +} + +void sm3_kdf_update(SM3_KDF_CTX *ctx, const uint8_t *data, size_t datalen) +{ + sm3_update(&ctx->sm3_ctx, data, datalen); +} + +void sm3_kdf_finish(SM3_KDF_CTX *ctx, uint8_t *out) +{ + SM3_CTX sm3_ctx; + size_t outlen = ctx->outlen; + uint8_t counter_be[4]; + uint8_t dgst[SM3_DIGEST_SIZE]; + uint32_t counter = 1; + size_t len; + + while (outlen) { + PUTU32(counter_be, counter); + counter++; + + sm3_ctx = ctx->sm3_ctx; + sm3_update(&sm3_ctx, counter_be, sizeof(counter_be)); + sm3_finish(&sm3_ctx, dgst); + + len = outlen < SM3_DIGEST_SIZE ? outlen : SM3_DIGEST_SIZE; + memcpy(out, dgst, len); + out += len; + outlen -= len; + } + + memset(&sm3_ctx, 0, sizeof(SM3_CTX)); + memset(dgst, 0, sizeof(dgst)); +} diff --git a/src/sm4_common.c b/src/sm4_common.c index 956dbc68..913bfb3a 100644 --- a/src/sm4_common.c +++ b/src/sm4_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,108 +7,109 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include "sm4_lcl.h" - - -const uint8_t SM4_S[256] = { - 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, - 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, - 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, - 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, - 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, - 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, - 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, - 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, - 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, - 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, - 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, - 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, - 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, - 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, - 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, - 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, - 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, - 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, - 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, - 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, - 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, - 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, - 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, - 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, - 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, - 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, - 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, - 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, - 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, - 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, - 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, - 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, -}; - -const uint32_t SM4_T[256] = { - 0x8ed55b5bU, 0xd0924242U, 0x4deaa7a7U, 0x06fdfbfbU, - 0xfccf3333U, 0x65e28787U, 0xc93df4f4U, 0x6bb5dedeU, - 0x4e165858U, 0x6eb4dadaU, 0x44145050U, 0xcac10b0bU, - 0x8828a0a0U, 0x17f8efefU, 0x9c2cb0b0U, 0x11051414U, - 0x872bacacU, 0xfb669d9dU, 0xf2986a6aU, 0xae77d9d9U, - 0x822aa8a8U, 0x46bcfafaU, 0x14041010U, 0xcfc00f0fU, - 0x02a8aaaaU, 0x54451111U, 0x5f134c4cU, 0xbe269898U, - 0x6d482525U, 0x9e841a1aU, 0x1e061818U, 0xfd9b6666U, - 0xec9e7272U, 0x4a430909U, 0x10514141U, 0x24f7d3d3U, - 0xd5934646U, 0x53ecbfbfU, 0xf89a6262U, 0x927be9e9U, - 0xff33ccccU, 0x04555151U, 0x270b2c2cU, 0x4f420d0dU, - 0x59eeb7b7U, 0xf3cc3f3fU, 0x1caeb2b2U, 0xea638989U, - 0x74e79393U, 0x7fb1ceceU, 0x6c1c7070U, 0x0daba6a6U, - 0xedca2727U, 0x28082020U, 0x48eba3a3U, 0xc1975656U, - 0x80820202U, 0xa3dc7f7fU, 0xc4965252U, 0x12f9ebebU, - 0xa174d5d5U, 0xb38d3e3eU, 0xc33ffcfcU, 0x3ea49a9aU, - 0x5b461d1dU, 0x1b071c1cU, 0x3ba59e9eU, 0x0cfff3f3U, - 0x3ff0cfcfU, 0xbf72cdcdU, 0x4b175c5cU, 0x52b8eaeaU, - 0x8f810e0eU, 0x3d586565U, 0xcc3cf0f0U, 0x7d196464U, - 0x7ee59b9bU, 0x91871616U, 0x734e3d3dU, 0x08aaa2a2U, - 0xc869a1a1U, 0xc76aadadU, 0x85830606U, 0x7ab0cacaU, - 0xb570c5c5U, 0xf4659191U, 0xb2d96b6bU, 0xa7892e2eU, - 0x18fbe3e3U, 0x47e8afafU, 0x330f3c3cU, 0x674a2d2dU, - 0xb071c1c1U, 0x0e575959U, 0xe99f7676U, 0xe135d4d4U, - 0x661e7878U, 0xb4249090U, 0x360e3838U, 0x265f7979U, - 0xef628d8dU, 0x38596161U, 0x95d24747U, 0x2aa08a8aU, - 0xb1259494U, 0xaa228888U, 0x8c7df1f1U, 0xd73bececU, - 0x05010404U, 0xa5218484U, 0x9879e1e1U, 0x9b851e1eU, - 0x84d75353U, 0x00000000U, 0x5e471919U, 0x0b565d5dU, - 0xe39d7e7eU, 0x9fd04f4fU, 0xbb279c9cU, 0x1a534949U, - 0x7c4d3131U, 0xee36d8d8U, 0x0a020808U, 0x7be49f9fU, - 0x20a28282U, 0xd4c71313U, 0xe8cb2323U, 0xe69c7a7aU, - 0x42e9ababU, 0x43bdfefeU, 0xa2882a2aU, 0x9ad14b4bU, - 0x40410101U, 0xdbc41f1fU, 0xd838e0e0U, 0x61b7d6d6U, - 0x2fa18e8eU, 0x2bf4dfdfU, 0x3af1cbcbU, 0xf6cd3b3bU, - 0x1dfae7e7U, 0xe5608585U, 0x41155454U, 0x25a38686U, - 0x60e38383U, 0x16acbabaU, 0x295c7575U, 0x34a69292U, - 0xf7996e6eU, 0xe434d0d0U, 0x721a6868U, 0x01545555U, - 0x19afb6b6U, 0xdf914e4eU, 0xfa32c8c8U, 0xf030c0c0U, - 0x21f6d7d7U, 0xbc8e3232U, 0x75b3c6c6U, 0x6fe08f8fU, - 0x691d7474U, 0x2ef5dbdbU, 0x6ae18b8bU, 0x962eb8b8U, - 0x8a800a0aU, 0xfe679999U, 0xe2c92b2bU, 0xe0618181U, - 0xc0c30303U, 0x8d29a4a4U, 0xaf238c8cU, 0x07a9aeaeU, - 0x390d3434U, 0x1f524d4dU, 0x764f3939U, 0xd36ebdbdU, - 0x81d65757U, 0xb7d86f6fU, 0xeb37dcdcU, 0x51441515U, - 0xa6dd7b7bU, 0x09fef7f7U, 0xb68c3a3aU, 0x932fbcbcU, - 0x0f030c0cU, 0x03fcffffU, 0xc26ba9a9U, 0xba73c9c9U, - 0xd96cb5b5U, 0xdc6db1b1U, 0x375a6d6dU, 0x15504545U, - 0xb98f3636U, 0x771b6c6cU, 0x13adbebeU, 0xda904a4aU, - 0x57b9eeeeU, 0xa9de7777U, 0x4cbef2f2U, 0x837efdfdU, - 0x55114444U, 0xbdda6767U, 0x2c5d7171U, 0x45400505U, - 0x631f7c7cU, 0x50104040U, 0x325b6969U, 0xb8db6363U, - 0x220a2828U, 0xc5c20707U, 0xf531c4c4U, 0xa88a2222U, - 0x31a79696U, 0xf9ce3737U, 0x977aededU, 0x49bff6f6U, - 0x992db4b4U, 0xa475d1d1U, 0x90d34343U, 0x5a124848U, - 0x58bae2e2U, 0x71e69797U, 0x64b6d2d2U, 0x70b2c2c2U, - 0xad8b2626U, 0xcd68a5a5U, 0xcb955e5eU, 0x624b2929U, - 0x3c0c3030U, 0xce945a5aU, 0xab76ddddU, 0x867ff9f9U, - 0xf1649595U, 0x5dbbe6e6U, 0x35f2c7c7U, 0x2d092424U, - 0xd1c61717U, 0xd66fb9b9U, 0xdec51b1bU, 0x94861212U, - 0x78186060U, 0x30f3c3c3U, 0x897cf5f5U, 0x5cefb3b3U, - 0xd23ae8e8U, 0xacdf7373U, 0x794c3535U, 0xa0208080U, - 0x9d78e5e5U, 0x56edbbbbU, 0x235e7d7dU, 0xc63ef8f8U, - 0x8bd45f5fU, 0xe7c82f2fU, 0xdd39e4e4U, 0x68492121U, -}; + + +#include "sm4_lcl.h" + + +const uint8_t SM4_S[256] = { + 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, + 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, + 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, + 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, + 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, + 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, + 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, + 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, + 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, + 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, + 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, + 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, + 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, + 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, + 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, + 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, + 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, + 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, + 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, + 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, + 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, + 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, + 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, + 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, + 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, + 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, + 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, + 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, + 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, + 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, + 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, + 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, +}; + +const uint32_t SM4_T[256] = { + 0x8ed55b5bU, 0xd0924242U, 0x4deaa7a7U, 0x06fdfbfbU, + 0xfccf3333U, 0x65e28787U, 0xc93df4f4U, 0x6bb5dedeU, + 0x4e165858U, 0x6eb4dadaU, 0x44145050U, 0xcac10b0bU, + 0x8828a0a0U, 0x17f8efefU, 0x9c2cb0b0U, 0x11051414U, + 0x872bacacU, 0xfb669d9dU, 0xf2986a6aU, 0xae77d9d9U, + 0x822aa8a8U, 0x46bcfafaU, 0x14041010U, 0xcfc00f0fU, + 0x02a8aaaaU, 0x54451111U, 0x5f134c4cU, 0xbe269898U, + 0x6d482525U, 0x9e841a1aU, 0x1e061818U, 0xfd9b6666U, + 0xec9e7272U, 0x4a430909U, 0x10514141U, 0x24f7d3d3U, + 0xd5934646U, 0x53ecbfbfU, 0xf89a6262U, 0x927be9e9U, + 0xff33ccccU, 0x04555151U, 0x270b2c2cU, 0x4f420d0dU, + 0x59eeb7b7U, 0xf3cc3f3fU, 0x1caeb2b2U, 0xea638989U, + 0x74e79393U, 0x7fb1ceceU, 0x6c1c7070U, 0x0daba6a6U, + 0xedca2727U, 0x28082020U, 0x48eba3a3U, 0xc1975656U, + 0x80820202U, 0xa3dc7f7fU, 0xc4965252U, 0x12f9ebebU, + 0xa174d5d5U, 0xb38d3e3eU, 0xc33ffcfcU, 0x3ea49a9aU, + 0x5b461d1dU, 0x1b071c1cU, 0x3ba59e9eU, 0x0cfff3f3U, + 0x3ff0cfcfU, 0xbf72cdcdU, 0x4b175c5cU, 0x52b8eaeaU, + 0x8f810e0eU, 0x3d586565U, 0xcc3cf0f0U, 0x7d196464U, + 0x7ee59b9bU, 0x91871616U, 0x734e3d3dU, 0x08aaa2a2U, + 0xc869a1a1U, 0xc76aadadU, 0x85830606U, 0x7ab0cacaU, + 0xb570c5c5U, 0xf4659191U, 0xb2d96b6bU, 0xa7892e2eU, + 0x18fbe3e3U, 0x47e8afafU, 0x330f3c3cU, 0x674a2d2dU, + 0xb071c1c1U, 0x0e575959U, 0xe99f7676U, 0xe135d4d4U, + 0x661e7878U, 0xb4249090U, 0x360e3838U, 0x265f7979U, + 0xef628d8dU, 0x38596161U, 0x95d24747U, 0x2aa08a8aU, + 0xb1259494U, 0xaa228888U, 0x8c7df1f1U, 0xd73bececU, + 0x05010404U, 0xa5218484U, 0x9879e1e1U, 0x9b851e1eU, + 0x84d75353U, 0x00000000U, 0x5e471919U, 0x0b565d5dU, + 0xe39d7e7eU, 0x9fd04f4fU, 0xbb279c9cU, 0x1a534949U, + 0x7c4d3131U, 0xee36d8d8U, 0x0a020808U, 0x7be49f9fU, + 0x20a28282U, 0xd4c71313U, 0xe8cb2323U, 0xe69c7a7aU, + 0x42e9ababU, 0x43bdfefeU, 0xa2882a2aU, 0x9ad14b4bU, + 0x40410101U, 0xdbc41f1fU, 0xd838e0e0U, 0x61b7d6d6U, + 0x2fa18e8eU, 0x2bf4dfdfU, 0x3af1cbcbU, 0xf6cd3b3bU, + 0x1dfae7e7U, 0xe5608585U, 0x41155454U, 0x25a38686U, + 0x60e38383U, 0x16acbabaU, 0x295c7575U, 0x34a69292U, + 0xf7996e6eU, 0xe434d0d0U, 0x721a6868U, 0x01545555U, + 0x19afb6b6U, 0xdf914e4eU, 0xfa32c8c8U, 0xf030c0c0U, + 0x21f6d7d7U, 0xbc8e3232U, 0x75b3c6c6U, 0x6fe08f8fU, + 0x691d7474U, 0x2ef5dbdbU, 0x6ae18b8bU, 0x962eb8b8U, + 0x8a800a0aU, 0xfe679999U, 0xe2c92b2bU, 0xe0618181U, + 0xc0c30303U, 0x8d29a4a4U, 0xaf238c8cU, 0x07a9aeaeU, + 0x390d3434U, 0x1f524d4dU, 0x764f3939U, 0xd36ebdbdU, + 0x81d65757U, 0xb7d86f6fU, 0xeb37dcdcU, 0x51441515U, + 0xa6dd7b7bU, 0x09fef7f7U, 0xb68c3a3aU, 0x932fbcbcU, + 0x0f030c0cU, 0x03fcffffU, 0xc26ba9a9U, 0xba73c9c9U, + 0xd96cb5b5U, 0xdc6db1b1U, 0x375a6d6dU, 0x15504545U, + 0xb98f3636U, 0x771b6c6cU, 0x13adbebeU, 0xda904a4aU, + 0x57b9eeeeU, 0xa9de7777U, 0x4cbef2f2U, 0x837efdfdU, + 0x55114444U, 0xbdda6767U, 0x2c5d7171U, 0x45400505U, + 0x631f7c7cU, 0x50104040U, 0x325b6969U, 0xb8db6363U, + 0x220a2828U, 0xc5c20707U, 0xf531c4c4U, 0xa88a2222U, + 0x31a79696U, 0xf9ce3737U, 0x977aededU, 0x49bff6f6U, + 0x992db4b4U, 0xa475d1d1U, 0x90d34343U, 0x5a124848U, + 0x58bae2e2U, 0x71e69797U, 0x64b6d2d2U, 0x70b2c2c2U, + 0xad8b2626U, 0xcd68a5a5U, 0xcb955e5eU, 0x624b2929U, + 0x3c0c3030U, 0xce945a5aU, 0xab76ddddU, 0x867ff9f9U, + 0xf1649595U, 0x5dbbe6e6U, 0x35f2c7c7U, 0x2d092424U, + 0xd1c61717U, 0xd66fb9b9U, 0xdec51b1bU, 0x94861212U, + 0x78186060U, 0x30f3c3c3U, 0x897cf5f5U, 0x5cefb3b3U, + 0xd23ae8e8U, 0xacdf7373U, 0x794c3535U, 0xa0208080U, + 0x9d78e5e5U, 0x56edbbbbU, 0x235e7d7dU, 0xc63ef8f8U, + 0x8bd45f5fU, 0xe7c82f2fU, 0xdd39e4e4U, 0x68492121U, +}; diff --git a/src/sm4_enc.c b/src/sm4_enc.c index b5ed0491..ad0dbf44 100644 --- a/src/sm4_enc.c +++ b/src/sm4_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,82 +7,83 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include "sm4_lcl.h" - - -#define L32(x) \ - ((x) ^ \ - ROL32((x), 2) ^ \ - ROL32((x), 10) ^ \ - ROL32((x), 18) ^ \ - ROL32((x), 24)) - -#define ROUND_SBOX(x0, x1, x2, x3, x4, i) \ - x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \ - x4 = S32(x4); \ - x4 = x0 ^ L32(x4) - -#define ROUND_TBOX(x0, x1, x2, x3, x4, i) \ - x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \ - t0 = ROL32(SM4_T[(uint8_t)x4], 8); \ - x4 >>= 8; \ - x0 ^= t0; \ - t0 = ROL32(SM4_T[(uint8_t)x4], 16); \ - x4 >>= 8; \ - x0 ^= t0; \ - t0 = ROL32(SM4_T[(uint8_t)x4], 24); \ - x4 >>= 8; \ - x0 ^= t0; \ - t1 = SM4_T[x4]; \ - x4 = x0 ^ t1 - -#define ROUND ROUND_TBOX - - -void sm4_encrypt(const SM4_KEY *key, const unsigned char in[16], unsigned char out[16]) -{ - const uint32_t *rk = key->rk; - uint32_t x0, x1, x2, x3, x4; - uint32_t t0, t1; - - x0 = GETU32(in ); - x1 = GETU32(in + 4); - x2 = GETU32(in + 8); - x3 = GETU32(in + 12); - ROUNDS(x0, x1, x2, x3, x4); - PUTU32(out , x0); - PUTU32(out + 4, x4); - PUTU32(out + 8, x3); - PUTU32(out + 12, x2); -} - -/* caller make sure counter not overflow */ -void sm4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t blocks, const SM4_KEY *key, const unsigned char iv[16]) -{ - const uint32_t *rk = key->rk; - unsigned int c0 = GETU32(iv ); - unsigned int c1 = GETU32(iv + 4); - unsigned int c2 = GETU32(iv + 8); - unsigned int c3 = GETU32(iv + 12); - uint32_t x0, x1, x2, x3, x4; - uint32_t t0, t1; - - while (blocks--) { - x0 = c0; - x1 = c1; - x2 = c2; - x3 = c3; - ROUNDS(x0, x1, x2, x3, x4); - PUTU32(out , GETU32(in ) ^ x0); - PUTU32(out + 4, GETU32(in + 4) ^ x4); - PUTU32(out + 8, GETU32(in + 8) ^ x3); - PUTU32(out + 12, GETU32(in + 12) ^ x2); - in += 16; - out += 16; - c3++; - } -} + + +#include +#include +#include "sm4_lcl.h" + + +#define L32(x) \ + ((x) ^ \ + ROL32((x), 2) ^ \ + ROL32((x), 10) ^ \ + ROL32((x), 18) ^ \ + ROL32((x), 24)) + +#define ROUND_SBOX(x0, x1, x2, x3, x4, i) \ + x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \ + x4 = S32(x4); \ + x4 = x0 ^ L32(x4) + +#define ROUND_TBOX(x0, x1, x2, x3, x4, i) \ + x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \ + t0 = ROL32(SM4_T[(uint8_t)x4], 8); \ + x4 >>= 8; \ + x0 ^= t0; \ + t0 = ROL32(SM4_T[(uint8_t)x4], 16); \ + x4 >>= 8; \ + x0 ^= t0; \ + t0 = ROL32(SM4_T[(uint8_t)x4], 24); \ + x4 >>= 8; \ + x0 ^= t0; \ + t1 = SM4_T[x4]; \ + x4 = x0 ^ t1 + +#define ROUND ROUND_TBOX + + +void sm4_encrypt(const SM4_KEY *key, const unsigned char in[16], unsigned char out[16]) +{ + const uint32_t *rk = key->rk; + uint32_t x0, x1, x2, x3, x4; + uint32_t t0, t1; + + x0 = GETU32(in ); + x1 = GETU32(in + 4); + x2 = GETU32(in + 8); + x3 = GETU32(in + 12); + ROUNDS(x0, x1, x2, x3, x4); + PUTU32(out , x0); + PUTU32(out + 4, x4); + PUTU32(out + 8, x3); + PUTU32(out + 12, x2); +} + +/* caller make sure counter not overflow */ +void sm4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t blocks, const SM4_KEY *key, const unsigned char iv[16]) +{ + const uint32_t *rk = key->rk; + unsigned int c0 = GETU32(iv ); + unsigned int c1 = GETU32(iv + 4); + unsigned int c2 = GETU32(iv + 8); + unsigned int c3 = GETU32(iv + 12); + uint32_t x0, x1, x2, x3, x4; + uint32_t t0, t1; + + while (blocks--) { + x0 = c0; + x1 = c1; + x2 = c2; + x3 = c3; + ROUNDS(x0, x1, x2, x3, x4); + PUTU32(out , GETU32(in ) ^ x0); + PUTU32(out + 4, GETU32(in + 4) ^ x4); + PUTU32(out + 8, GETU32(in + 8) ^ x3); + PUTU32(out + 12, GETU32(in + 12) ^ x2); + in += 16; + out += 16; + c3++; + } +} diff --git a/src/sm4_lcl.h b/src/sm4_lcl.h index ae5ab9c6..ebad556d 100644 --- a/src/sm4_lcl.h +++ b/src/sm4_lcl.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,54 +7,55 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#ifndef GMSSL_SM4_LCL_H -#define GMSSL_SM4_LCL_H - -#include - -extern const uint8_t SM4_S[256]; -extern const uint32_t SM4_T[256]; -extern const uint32_t SM4_D[65536]; - -#define S32(A) \ - ((SM4_S[((A) >> 24) ] << 24) ^ \ - (SM4_S[((A) >> 16) & 0xff] << 16) ^ \ - (SM4_S[((A) >> 8) & 0xff] << 8) ^ \ - (SM4_S[((A)) & 0xff])) - -#define ROUNDS(x0, x1, x2, x3, x4) \ - ROUND(x0, x1, x2, x3, x4, 0); \ - ROUND(x1, x2, x3, x4, x0, 1); \ - ROUND(x2, x3, x4, x0, x1, 2); \ - ROUND(x3, x4, x0, x1, x2, 3); \ - ROUND(x4, x0, x1, x2, x3, 4); \ - ROUND(x0, x1, x2, x3, x4, 5); \ - ROUND(x1, x2, x3, x4, x0, 6); \ - ROUND(x2, x3, x4, x0, x1, 7); \ - ROUND(x3, x4, x0, x1, x2, 8); \ - ROUND(x4, x0, x1, x2, x3, 9); \ - ROUND(x0, x1, x2, x3, x4, 10); \ - ROUND(x1, x2, x3, x4, x0, 11); \ - ROUND(x2, x3, x4, x0, x1, 12); \ - ROUND(x3, x4, x0, x1, x2, 13); \ - ROUND(x4, x0, x1, x2, x3, 14); \ - ROUND(x0, x1, x2, x3, x4, 15); \ - ROUND(x1, x2, x3, x4, x0, 16); \ - ROUND(x2, x3, x4, x0, x1, 17); \ - ROUND(x3, x4, x0, x1, x2, 18); \ - ROUND(x4, x0, x1, x2, x3, 19); \ - ROUND(x0, x1, x2, x3, x4, 20); \ - ROUND(x1, x2, x3, x4, x0, 21); \ - ROUND(x2, x3, x4, x0, x1, 22); \ - ROUND(x3, x4, x0, x1, x2, 23); \ - ROUND(x4, x0, x1, x2, x3, 24); \ - ROUND(x0, x1, x2, x3, x4, 25); \ - ROUND(x1, x2, x3, x4, x0, 26); \ - ROUND(x2, x3, x4, x0, x1, 27); \ - ROUND(x3, x4, x0, x1, x2, 28); \ - ROUND(x4, x0, x1, x2, x3, 29); \ - ROUND(x0, x1, x2, x3, x4, 30); \ - ROUND(x1, x2, x3, x4, x0, 31) - -#endif + + +#ifndef GMSSL_SM4_LCL_H +#define GMSSL_SM4_LCL_H + +#include + +extern const uint8_t SM4_S[256]; +extern const uint32_t SM4_T[256]; +extern const uint32_t SM4_D[65536]; + +#define S32(A) \ + ((SM4_S[((A) >> 24) ] << 24) ^ \ + (SM4_S[((A) >> 16) & 0xff] << 16) ^ \ + (SM4_S[((A) >> 8) & 0xff] << 8) ^ \ + (SM4_S[((A)) & 0xff])) + +#define ROUNDS(x0, x1, x2, x3, x4) \ + ROUND(x0, x1, x2, x3, x4, 0); \ + ROUND(x1, x2, x3, x4, x0, 1); \ + ROUND(x2, x3, x4, x0, x1, 2); \ + ROUND(x3, x4, x0, x1, x2, 3); \ + ROUND(x4, x0, x1, x2, x3, 4); \ + ROUND(x0, x1, x2, x3, x4, 5); \ + ROUND(x1, x2, x3, x4, x0, 6); \ + ROUND(x2, x3, x4, x0, x1, 7); \ + ROUND(x3, x4, x0, x1, x2, 8); \ + ROUND(x4, x0, x1, x2, x3, 9); \ + ROUND(x0, x1, x2, x3, x4, 10); \ + ROUND(x1, x2, x3, x4, x0, 11); \ + ROUND(x2, x3, x4, x0, x1, 12); \ + ROUND(x3, x4, x0, x1, x2, 13); \ + ROUND(x4, x0, x1, x2, x3, 14); \ + ROUND(x0, x1, x2, x3, x4, 15); \ + ROUND(x1, x2, x3, x4, x0, 16); \ + ROUND(x2, x3, x4, x0, x1, 17); \ + ROUND(x3, x4, x0, x1, x2, 18); \ + ROUND(x4, x0, x1, x2, x3, 19); \ + ROUND(x0, x1, x2, x3, x4, 20); \ + ROUND(x1, x2, x3, x4, x0, 21); \ + ROUND(x2, x3, x4, x0, x1, 22); \ + ROUND(x3, x4, x0, x1, x2, 23); \ + ROUND(x4, x0, x1, x2, x3, 24); \ + ROUND(x0, x1, x2, x3, x4, 25); \ + ROUND(x1, x2, x3, x4, x0, 26); \ + ROUND(x2, x3, x4, x0, x1, 27); \ + ROUND(x3, x4, x0, x1, x2, 28); \ + ROUND(x4, x0, x1, x2, x3, 29); \ + ROUND(x0, x1, x2, x3, x4, 30); \ + ROUND(x1, x2, x3, x4, x0, 31) + +#endif diff --git a/src/sm4_modes.c b/src/sm4_modes.c index d66b72e2..63757d66 100644 --- a/src/sm4_modes.c +++ b/src/sm4_modes.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,396 +7,397 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t nblocks, uint8_t *out) -{ - while (nblocks--) { - gmssl_memxor(out, in, iv, 16); - sm4_encrypt(key, out, out); - iv = out; - in += 16; - out += 16; - } -} - -void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t nblocks, uint8_t *out) -{ - while (nblocks--) { - sm4_encrypt(key, in, out); - memxor(out, iv, 16); - iv = in; - in += 16; - out += 16; - } -} - -int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - uint8_t block[16]; - size_t rem = inlen % 16; - int padding = 16 - inlen % 16; - - if (in) { - memcpy(block, in + inlen - rem, rem); - } - memset(block + rem, padding, padding); - if (inlen/16) { - sm4_cbc_encrypt(key, iv, in, inlen/16, out); - out += inlen - rem; - iv = out - 16; - } - sm4_cbc_encrypt(key, iv, block, 1, out); - *outlen = inlen - rem + 16; - return 1; -} - -int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16], - const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - uint8_t block[16]; - size_t len = sizeof(block); - int padding; - - if (inlen == 0) { - error_puts("warning: input lenght = 0"); - return 0; - } - if (inlen%16 != 0 || inlen < 16) { - error_puts("invalid cbc ciphertext length"); - return -1; - } - if (inlen > 16) { - sm4_cbc_decrypt(key, iv, in, inlen/16 - 1, out); - iv = in + inlen - 32; - } - sm4_cbc_decrypt(key, iv, in + inlen - 16, 1, block); - - padding = block[15]; - if (padding < 1 || padding > 16) { - error_print(); - return -1; - } - len -= padding; - memcpy(out + inlen - 16, block, len); - *outlen = inlen - padding; - return 1; -} - -static void ctr_incr(uint8_t a[16]) -{ - int i; - for (i = 15; i > 0; i--) { - a[i]++; - if (a[i]) break; - } -} - -void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out) -{ - uint8_t block[16]; - size_t len; - - while (inlen) { - len = inlen < 16 ? inlen : 16; - sm4_encrypt(key, ctr, block); - gmssl_memxor(out, in, block, len); - ctr_incr(ctr); - in += len; - out += len; - inlen -= len; - } -} - -int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - uint8_t *out, size_t taglen, uint8_t *tag) -{ - const uint8_t *pin = in; - uint8_t *pout = out; - size_t left = inlen; - uint8_t H[16] = {0}; - uint8_t Y[16]; - uint8_t T[16]; - - if (taglen > SM4_GCM_MAX_TAG_SIZE) { - error_print(); - return -1; - } - - sm4_encrypt(key, H, H); - - if (ivlen == 12) { - memcpy(Y, iv, 12); - Y[12] = Y[13] = Y[14] = 0; - Y[15] = 1; - } else { - ghash(H, NULL, 0, iv, ivlen, Y); - } - - sm4_encrypt(key, Y, T); - - while (left) { - uint8_t block[16]; - size_t len = left < 16 ? left : 16; - ctr_incr(Y); - sm4_encrypt(key, Y, block); - gmssl_memxor(pout, pin, block, len); - pin += len; - pout += len; - left -= len; - } - - ghash(H, aad, aadlen, out, inlen, H); - gmssl_memxor(tag, T, H, taglen); - return 1; -} - -int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, - const uint8_t *tag, size_t taglen, uint8_t *out) -{ - const uint8_t *pin = in; - uint8_t *pout = out; - size_t left = inlen; - uint8_t H[16] = {0}; - uint8_t Y[16]; - uint8_t T[16]; - - sm4_encrypt(key, H, H); - - if (ivlen == 12) { - memcpy(Y, iv, 12); - Y[12] = Y[13] = Y[14] = 0; - Y[15] = 1; - } else { - ghash(H, NULL, 0, iv, ivlen, Y); - } - - ghash(H, aad, aadlen, in, inlen, H); - sm4_encrypt(key, Y, T); - gmssl_memxor(T, T, H, taglen); - if (memcmp(T, tag, taglen) != 0) { - error_print(); - return -1; - } - - while (left) { - uint8_t block[16]; - size_t len = left < 16 ? left : 16; - ctr_incr(Y); - sm4_encrypt(key, Y, block); - gmssl_memxor(pout, pin, block, len); - pin += len; - pout += len; - left -= len; - } - return 1; -} - -int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, - const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]) -{ - sm4_set_encrypt_key(&ctx->sm4_key, key); - memcpy(ctx->iv, iv, SM4_BLOCK_SIZE); - memset(ctx->block, 0, SM4_BLOCK_SIZE); - ctx->block_nbytes = 0; - return 1; -} - -int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - size_t left; - size_t nblocks; - size_t len; - - if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - *outlen = 0; - if (ctx->block_nbytes) { - left = SM4_BLOCK_SIZE - ctx->block_nbytes; - if (inlen < left) { - memcpy(ctx->block + ctx->block_nbytes, in, inlen); - ctx->block_nbytes += inlen; - return 1; - } - memcpy(ctx->block + ctx->block_nbytes, in, left); - sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out); - memcpy(ctx->iv, out, SM4_BLOCK_SIZE); - in += left; - inlen -= left; - out += SM4_BLOCK_SIZE; - *outlen += SM4_BLOCK_SIZE; - } - if (inlen >= SM4_BLOCK_SIZE) { - nblocks = inlen / SM4_BLOCK_SIZE; - len = nblocks * SM4_BLOCK_SIZE; - sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out); - memcpy(ctx->iv, out + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE); - in += len; - inlen -= len; - out += len; - *outlen += len; - } - if (inlen) { - memcpy(ctx->block, in, inlen); - } - ctx->block_nbytes = inlen; - return 1; -} - -int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) -{ - size_t left; - size_t i; - - if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - if (sm4_cbc_padding_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, - const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]) -{ - sm4_set_decrypt_key(&ctx->sm4_key, key); - memcpy(ctx->iv, iv, SM4_BLOCK_SIZE); - memset(ctx->block, 0, SM4_BLOCK_SIZE); - ctx->block_nbytes = 0; - return 1; -} - -int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - size_t left, len, nblocks; - - if (ctx->block_nbytes > SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - - *outlen = 0; - if (ctx->block_nbytes) { - left = SM4_BLOCK_SIZE - ctx->block_nbytes; - if (inlen <= left) { - memcpy(ctx->block + ctx->block_nbytes, in, inlen); - ctx->block_nbytes += inlen; - return 1; - } - memcpy(ctx->block + ctx->block_nbytes, in, left); - sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out); - memcpy(ctx->iv, ctx->block, SM4_BLOCK_SIZE); - in += left; - inlen -= left; - out += SM4_BLOCK_SIZE; - *outlen += SM4_BLOCK_SIZE; - } - if (inlen > SM4_BLOCK_SIZE) { - nblocks = (inlen-1) / SM4_BLOCK_SIZE; - len = nblocks * SM4_BLOCK_SIZE; - sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out); - memcpy(ctx->iv, in + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE); - in += len; - inlen -= len; - out += len; - *outlen += len; - } - memcpy(ctx->block, in, inlen); - ctx->block_nbytes = inlen; - return 1; -} - -int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) -{ - if (ctx->block_nbytes != SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - if (sm4_cbc_padding_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, SM4_BLOCK_SIZE, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, - const uint8_t key[SM4_BLOCK_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]) -{ - sm4_set_encrypt_key(&ctx->sm4_key, key); - memcpy(ctx->ctr, ctr, SM4_BLOCK_SIZE); - memset(ctx->block, 0, SM4_BLOCK_SIZE); - ctx->block_nbytes = 0; - return 1; -} - -int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - size_t left; - size_t nblocks; - size_t len; - - if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - *outlen = 0; - if (ctx->block_nbytes) { - left = SM4_BLOCK_SIZE - ctx->block_nbytes; - if (inlen < left) { - memcpy(ctx->block + ctx->block_nbytes, in, inlen); - ctx->block_nbytes += inlen; - return 1; - } - memcpy(ctx->block + ctx->block_nbytes, in, left); - sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, ctx->block, SM4_BLOCK_SIZE, out); - in += left; - inlen -= left; - out += SM4_BLOCK_SIZE; - *outlen += SM4_BLOCK_SIZE; - } - if (inlen >= SM4_BLOCK_SIZE) { - nblocks = inlen / SM4_BLOCK_SIZE; - len = nblocks * SM4_BLOCK_SIZE; - sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, in, len, out); - in += len; - inlen -= len; - out += len; - *outlen += len; - } - if (inlen) { - memcpy(ctx->block, in, inlen); - } - ctx->block_nbytes = inlen; - return 1; -} - -int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen) -{ - size_t left; - if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { - error_print(); - return -1; - } - sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, ctx->block, ctx->block_nbytes, out); - *outlen = ctx->block_nbytes; - return 1; -} + + +#include +#include +#include +#include + +void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t nblocks, uint8_t *out) +{ + while (nblocks--) { + gmssl_memxor(out, in, iv, 16); + sm4_encrypt(key, out, out); + iv = out; + in += 16; + out += 16; + } +} + +void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t nblocks, uint8_t *out) +{ + while (nblocks--) { + sm4_encrypt(key, in, out); + memxor(out, iv, 16); + iv = in; + in += 16; + out += 16; + } +} + +int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + uint8_t block[16]; + size_t rem = inlen % 16; + int padding = 16 - inlen % 16; + + if (in) { + memcpy(block, in + inlen - rem, rem); + } + memset(block + rem, padding, padding); + if (inlen/16) { + sm4_cbc_encrypt(key, iv, in, inlen/16, out); + out += inlen - rem; + iv = out - 16; + } + sm4_cbc_encrypt(key, iv, block, 1, out); + *outlen = inlen - rem + 16; + return 1; +} + +int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16], + const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + uint8_t block[16]; + size_t len = sizeof(block); + int padding; + + if (inlen == 0) { + error_puts("warning: input lenght = 0"); + return 0; + } + if (inlen%16 != 0 || inlen < 16) { + error_puts("invalid cbc ciphertext length"); + return -1; + } + if (inlen > 16) { + sm4_cbc_decrypt(key, iv, in, inlen/16 - 1, out); + iv = in + inlen - 32; + } + sm4_cbc_decrypt(key, iv, in + inlen - 16, 1, block); + + padding = block[15]; + if (padding < 1 || padding > 16) { + error_print(); + return -1; + } + len -= padding; + memcpy(out + inlen - 16, block, len); + *outlen = inlen - padding; + return 1; +} + +static void ctr_incr(uint8_t a[16]) +{ + int i; + for (i = 15; i > 0; i--) { + a[i]++; + if (a[i]) break; + } +} + +void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out) +{ + uint8_t block[16]; + size_t len; + + while (inlen) { + len = inlen < 16 ? inlen : 16; + sm4_encrypt(key, ctr, block); + gmssl_memxor(out, in, block, len); + ctr_incr(ctr); + in += len; + out += len; + inlen -= len; + } +} + +int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag) +{ + const uint8_t *pin = in; + uint8_t *pout = out; + size_t left = inlen; + uint8_t H[16] = {0}; + uint8_t Y[16]; + uint8_t T[16]; + + if (taglen > SM4_GCM_MAX_TAG_SIZE) { + error_print(); + return -1; + } + + sm4_encrypt(key, H, H); + + if (ivlen == 12) { + memcpy(Y, iv, 12); + Y[12] = Y[13] = Y[14] = 0; + Y[15] = 1; + } else { + ghash(H, NULL, 0, iv, ivlen, Y); + } + + sm4_encrypt(key, Y, T); + + while (left) { + uint8_t block[16]; + size_t len = left < 16 ? left : 16; + ctr_incr(Y); + sm4_encrypt(key, Y, block); + gmssl_memxor(pout, pin, block, len); + pin += len; + pout += len; + left -= len; + } + + ghash(H, aad, aadlen, out, inlen, H); + gmssl_memxor(tag, T, H, taglen); + return 1; +} + +int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out) +{ + const uint8_t *pin = in; + uint8_t *pout = out; + size_t left = inlen; + uint8_t H[16] = {0}; + uint8_t Y[16]; + uint8_t T[16]; + + sm4_encrypt(key, H, H); + + if (ivlen == 12) { + memcpy(Y, iv, 12); + Y[12] = Y[13] = Y[14] = 0; + Y[15] = 1; + } else { + ghash(H, NULL, 0, iv, ivlen, Y); + } + + ghash(H, aad, aadlen, in, inlen, H); + sm4_encrypt(key, Y, T); + gmssl_memxor(T, T, H, taglen); + if (memcmp(T, tag, taglen) != 0) { + error_print(); + return -1; + } + + while (left) { + uint8_t block[16]; + size_t len = left < 16 ? left : 16; + ctr_incr(Y); + sm4_encrypt(key, Y, block); + gmssl_memxor(pout, pin, block, len); + pin += len; + pout += len; + left -= len; + } + return 1; +} + +int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, + const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]) +{ + sm4_set_encrypt_key(&ctx->sm4_key, key); + memcpy(ctx->iv, iv, SM4_BLOCK_SIZE); + memset(ctx->block, 0, SM4_BLOCK_SIZE); + ctx->block_nbytes = 0; + return 1; +} + +int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t left; + size_t nblocks; + size_t len; + + if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + *outlen = 0; + if (ctx->block_nbytes) { + left = SM4_BLOCK_SIZE - ctx->block_nbytes; + if (inlen < left) { + memcpy(ctx->block + ctx->block_nbytes, in, inlen); + ctx->block_nbytes += inlen; + return 1; + } + memcpy(ctx->block + ctx->block_nbytes, in, left); + sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out); + memcpy(ctx->iv, out, SM4_BLOCK_SIZE); + in += left; + inlen -= left; + out += SM4_BLOCK_SIZE; + *outlen += SM4_BLOCK_SIZE; + } + if (inlen >= SM4_BLOCK_SIZE) { + nblocks = inlen / SM4_BLOCK_SIZE; + len = nblocks * SM4_BLOCK_SIZE; + sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out); + memcpy(ctx->iv, out + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE); + in += len; + inlen -= len; + out += len; + *outlen += len; + } + if (inlen) { + memcpy(ctx->block, in, inlen); + } + ctx->block_nbytes = inlen; + return 1; +} + +int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + size_t left; + size_t i; + + if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + if (sm4_cbc_padding_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, + const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]) +{ + sm4_set_decrypt_key(&ctx->sm4_key, key); + memcpy(ctx->iv, iv, SM4_BLOCK_SIZE); + memset(ctx->block, 0, SM4_BLOCK_SIZE); + ctx->block_nbytes = 0; + return 1; +} + +int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t left, len, nblocks; + + if (ctx->block_nbytes > SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + + *outlen = 0; + if (ctx->block_nbytes) { + left = SM4_BLOCK_SIZE - ctx->block_nbytes; + if (inlen <= left) { + memcpy(ctx->block + ctx->block_nbytes, in, inlen); + ctx->block_nbytes += inlen; + return 1; + } + memcpy(ctx->block + ctx->block_nbytes, in, left); + sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out); + memcpy(ctx->iv, ctx->block, SM4_BLOCK_SIZE); + in += left; + inlen -= left; + out += SM4_BLOCK_SIZE; + *outlen += SM4_BLOCK_SIZE; + } + if (inlen > SM4_BLOCK_SIZE) { + nblocks = (inlen-1) / SM4_BLOCK_SIZE; + len = nblocks * SM4_BLOCK_SIZE; + sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out); + memcpy(ctx->iv, in + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE); + in += len; + inlen -= len; + out += len; + *outlen += len; + } + memcpy(ctx->block, in, inlen); + ctx->block_nbytes = inlen; + return 1; +} + +int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + if (ctx->block_nbytes != SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + if (sm4_cbc_padding_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, SM4_BLOCK_SIZE, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, + const uint8_t key[SM4_BLOCK_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]) +{ + sm4_set_encrypt_key(&ctx->sm4_key, key); + memcpy(ctx->ctr, ctr, SM4_BLOCK_SIZE); + memset(ctx->block, 0, SM4_BLOCK_SIZE); + ctx->block_nbytes = 0; + return 1; +} + +int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t left; + size_t nblocks; + size_t len; + + if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + *outlen = 0; + if (ctx->block_nbytes) { + left = SM4_BLOCK_SIZE - ctx->block_nbytes; + if (inlen < left) { + memcpy(ctx->block + ctx->block_nbytes, in, inlen); + ctx->block_nbytes += inlen; + return 1; + } + memcpy(ctx->block + ctx->block_nbytes, in, left); + sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, ctx->block, SM4_BLOCK_SIZE, out); + in += left; + inlen -= left; + out += SM4_BLOCK_SIZE; + *outlen += SM4_BLOCK_SIZE; + } + if (inlen >= SM4_BLOCK_SIZE) { + nblocks = inlen / SM4_BLOCK_SIZE; + len = nblocks * SM4_BLOCK_SIZE; + sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, in, len, out); + in += len; + inlen -= len; + out += len; + *outlen += len; + } + if (inlen) { + memcpy(ctx->block, in, inlen); + } + ctx->block_nbytes = inlen; + return 1; +} + +int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen) +{ + size_t left; + if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { + error_print(); + return -1; + } + sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, ctx->block, ctx->block_nbytes, out); + *outlen = ctx->block_nbytes; + return 1; +} diff --git a/src/sm4_setkey.c b/src/sm4_setkey.c index 3c232616..e67d858d 100644 --- a/src/sm4_setkey.c +++ b/src/sm4_setkey.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,73 +7,74 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include "sm4_lcl.h" - -static uint32_t FK[4] = { - 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc, -}; - -static uint32_t CK[32] = { - 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, - 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, - 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, - 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, - 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, - 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, - 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, - 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279, -}; - -#define L32_(x) \ - ((x) ^ \ - ROL32((x), 13) ^ \ - ROL32((x), 23)) - -#define ENC_ROUND(x0, x1, x2, x3, x4, i) \ - x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \ - x4 = S32(x4); \ - x4 = x0 ^ L32_(x4); \ - *(rk + i) = x4 - -#define DEC_ROUND(x0, x1, x2, x3, x4, i) \ - x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \ - x4 = S32(x4); \ - x4 = x0 ^ L32_(x4); \ - *(rk + 31 - i) = x4 - -void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t user_key[16]) -{ - uint32_t *rk = key->rk; - uint32_t x0, x1, x2, x3, x4; - - x0 = GETU32(user_key ) ^ FK[0]; - x1 = GETU32(user_key + 4) ^ FK[1]; - x2 = GETU32(user_key + 8) ^ FK[2]; - x3 = GETU32(user_key + 12) ^ FK[3]; - -#define ROUND ENC_ROUND - ROUNDS(x0, x1, x2, x3, x4); -#undef ROUND - - x0 = x1 = x2 = x3 = x4 = 0; -} - -void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t user_key[16]) -{ - uint32_t *rk = key->rk; - uint32_t x0, x1, x2, x3, x4; - - x0 = GETU32(user_key ) ^ FK[0]; - x1 = GETU32(user_key + 4) ^ FK[1]; - x2 = GETU32(user_key + 8) ^ FK[2]; - x3 = GETU32(user_key + 12) ^ FK[3]; - -#define ROUND DEC_ROUND - ROUNDS(x0, x1, x2, x3, x4); -#undef ROUND - - x0 = x1 = x2 = x3 = x4 = 0; -} + + +#include +#include +#include "sm4_lcl.h" + +static uint32_t FK[4] = { + 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc, +}; + +static uint32_t CK[32] = { + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279, +}; + +#define L32_(x) \ + ((x) ^ \ + ROL32((x), 13) ^ \ + ROL32((x), 23)) + +#define ENC_ROUND(x0, x1, x2, x3, x4, i) \ + x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \ + x4 = S32(x4); \ + x4 = x0 ^ L32_(x4); \ + *(rk + i) = x4 + +#define DEC_ROUND(x0, x1, x2, x3, x4, i) \ + x4 = x1 ^ x2 ^ x3 ^ *(CK + i); \ + x4 = S32(x4); \ + x4 = x0 ^ L32_(x4); \ + *(rk + 31 - i) = x4 + +void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t user_key[16]) +{ + uint32_t *rk = key->rk; + uint32_t x0, x1, x2, x3, x4; + + x0 = GETU32(user_key ) ^ FK[0]; + x1 = GETU32(user_key + 4) ^ FK[1]; + x2 = GETU32(user_key + 8) ^ FK[2]; + x3 = GETU32(user_key + 12) ^ FK[3]; + +#define ROUND ENC_ROUND + ROUNDS(x0, x1, x2, x3, x4); +#undef ROUND + + x0 = x1 = x2 = x3 = x4 = 0; +} + +void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t user_key[16]) +{ + uint32_t *rk = key->rk; + uint32_t x0, x1, x2, x3, x4; + + x0 = GETU32(user_key ) ^ FK[0]; + x1 = GETU32(user_key + 4) ^ FK[1]; + x2 = GETU32(user_key + 8) ^ FK[2]; + x3 = GETU32(user_key + 12) ^ FK[3]; + +#define ROUND DEC_ROUND + ROUNDS(x0, x1, x2, x3, x4); +#undef ROUND + + x0 = x1 = x2 = x3 = x4 = 0; +} diff --git a/src/sm9_alg.c b/src/sm9_alg.c index c7b9364d..7e78eaa2 100644 --- a/src/sm9_alg.c +++ b/src/sm9_alg.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,2339 +7,2340 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -const sm9_bn_t SM9_ZERO = {0,0,0,0,0,0,0,0}; -const sm9_bn_t SM9_ONE = {1,0,0,0,0,0,0,0}; -static const sm9_bn_t SM9_TWO = {2,0,0,0,0,0,0,0}; -static const sm9_bn_t SM9_FIVE = {5,0,0,0,0,0,0,0}; - - -// p = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d -// n = b640000002a3a6f1d603ab4ff58ec74449f2934b18ea8beee56ee19cd69ecf25 -// mu_p = 2^512 // p = 167980e0beb5759a655f73aebdcd1312af2665f6d1e36081c71188f90d5c22146 -// mu_n = 2^512 // n -const sm9_bn_t SM9_P = {0xe351457d, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; -const sm9_bn_t SM9_N = {0xd69ecf25, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; -static const sm9_bn_t SM9_P_MINUS_ONE = {0xe351457c, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; -static const sm9_bn_t SM9_N_MINUS_ONE = {0xd69ecf24, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; -static const sm9_barrett_bn_t SM9_MU_P = {0xd5c22146, 0x71188f90, 0x1e36081c, 0xf2665f6d, 0xdcd1312a, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; -static const sm9_barrett_bn_t SM9_MU_N = {0xdfc97c2f, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; -static const sm9_barrett_bn_t SM9_MU_N_MINUS_ONE = {0xdfc97c31, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; - - -// P1.X 0x93DE051D62BF718FF5ED0704487D01D6E1E4086909DC3280E8C4E4817C66DDDD -// P1.Y 0x21FE8DDA4F21E607631065125C395BBC1C1C00CBFA6024350C464CD70A3EA616 -const SM9_POINT _SM9_P1 = { - {0x7c66dddd, 0xe8c4e481, 0x09dc3280, 0xe1e40869, 0x487d01d6, 0xf5ed0704, 0x62bf718f, 0x93de051d}, - {0x0a3ea616, 0x0c464cd7, 0xfa602435, 0x1c1c00cb, 0x5c395bbc, 0x63106512, 0x4f21e607, 0x21fe8dda}, - {1,0,0,0,0,0,0,0} -}; -const SM9_POINT *SM9_P1 = &_SM9_P1; - - -/* - X : [0x3722755292130b08d2aab97fd34ec120ee265948d19c17abf9b7213baf82d65bn, - 0x85aef3d078640c98597b6027b441a01ff1dd2c190f5e93c454806c11d8806141n], - Y : [0xa7cf28d519be3da65f3170153d278ff247efba98a71a08116215bba5c999a7c7n, - 0x17509b092e845c1266ba0d262cbee6ed0736a96fa347c8bd856dc76b84ebeb96n], - Z : [1n, 0n], -*/ -const SM9_TWIST_POINT _SM9_P2 = { - {{0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948, 0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552}, - {0xD8806141, 0x54806C11, 0x0F5E93C4, 0xF1DD2C19, 0xB441A01F, 0x597B6027, 0x78640C98, 0x85AEF3D0}}, - {{0xC999A7C7, 0x6215BBA5, 0xA71A0811, 0x47EFBA98, 0x3D278FF2, 0x5F317015, 0x19BE3DA6, 0xA7CF28D5}, - {0x84EBEB96, 0x856DC76B, 0xA347C8BD, 0x0736A96F, 0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09}}, - {{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}, -}; -const SM9_TWIST_POINT *SM9_P2 = &_SM9_P2; - - -const SM9_TWIST_POINT _SM9_Ppubs = { - {{0x96EA5E32, 0x8F14D656, 0x386A92DD, 0x414D2177, 0x24A3B573, 0x6CE843ED, 0x152D1F78, 0x29DBA116}, - {0x1B94C408, 0x0AB1B679, 0x5E392CFB, 0x1CE0711C, 0x41B56501, 0xE48AFF4B, 0x3084F733, 0x9F64080B}}, - {{0xB4E3216D, 0x0E75C05F, 0x5CDFF073, 0x1006E85F, 0xB7A46F74, 0x1A7CE027, 0xDDA532DA, 0x41E00A53}, - {0xD0EF1C25, 0xE89E1408, 0x1A77F335, 0xAD3E2FDB, 0x47E3A0CB, 0xB57329F4, 0xABEA0112, 0x69850938}}, - {{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}, -}; -const SM9_TWIST_POINT *SM9_Ppubs = &_SM9_Ppubs; - - -void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32]) -{ - int i; - for (i = 7; i >= 0; i--) { - PUTU32(out, (uint32_t)a[i]); - out += sizeof(uint32_t); - } -} - -void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32]) -{ - int i; - for (i = 7; i >= 0; i--) { - r[i] = GETU32(in); - in += sizeof(uint32_t); - } -} - -int sm9_bn_from_hex(sm9_bn_t r, const char hex[64]) -{ - uint8_t buf[32]; - size_t len; - if (hex_to_bytes(hex, 64, buf, &len) < 0) { - return -1; - } - sm9_bn_from_bytes(r, buf); - return 1; -} - -void sm9_bn_to_hex(const sm9_bn_t a, char hex[64]) -{ - int i; - for (i = 7; i >= 0; i--) { - (void)sprintf(hex + 8*(7-i), "%08x", (uint32_t)a[i]); - //hex += 8; - } -} - -void sm9_print_bn(const char *prefix, const sm9_bn_t a) -{ - char hex[65] = {0}; - sm9_bn_to_hex(a, hex); - printf("%s\n%s\n", prefix, hex); -} - -void sm9_bn_to_bits(const sm9_bn_t a, char bits[256]) -{ - int i, j; - for (i = 7; i >= 0; i--) { - uint32_t w = a[i]; - for (j = 0; j < 32; j++) { - *bits++ = (w & 0x80000000) ? '1' : '0'; - w <<= 1; - } - } -} - -int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b) -{ - int i; - for (i = 7; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - - - - -void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a) -{ - memcpy(r, a, sizeof(sm9_bn_t)); -} - -void sm9_bn_set_word(sm9_bn_t r, uint32_t a) -{ - sm9_bn_set_zero(r); - r[0] = a; -} - -void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b) -{ - int i; - r[0] = a[0] + b[0]; - for (i = 1; i < 8; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 7; i++) { - r[i] &= 0xffffffff; - } -} - -void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b) -{ - int i; - sm9_bn_t r; - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 7; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - sm9_bn_copy(ret, r); -} - -int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range) -{ - FILE *fp; - uint8_t buf[256]; - - fp = fopen("/dev/urandom", "rb"); - do { - fread(buf, 1, 256, fp); - sm9_bn_from_bytes(r, buf); - } while (sm9_bn_cmp(r, range) >= 0); - fclose(fp); - return 1; -} - -int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b) -{ - int i; - for (i = 0; i < 8; i++) { - if (a[i] != b[i]) - return 0; - } - return 1; -} - -void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) -{ - sm9_bn_add(r, a, b); - if (sm9_bn_cmp(r, SM9_P) >= 0) - return sm9_bn_sub(r, r, SM9_P); -} - -void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) -{ - if (sm9_bn_cmp(a, b) >= 0) { - sm9_bn_sub(r, a, b); - } else { - sm9_bn_t t; - sm9_bn_sub(t, SM9_P, b); - sm9_bn_add(r, t, a); - } -} - -void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a) -{ - sm9_fp_add(r, a, a); -} - -void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a) -{ - sm9_fp_t t; - sm9_fp_dbl(t, a); - sm9_fp_add(r, t, a); -} - -void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a) -{ - int i; - sm9_bn_copy(r, a); - if (r[0] & 0x01) { - sm9_bn_add(r, r, SM9_P); - } - for (i = 0; i < 7; i++) { - r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); - } - r[i] >>= 1; -} - -void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a) -{ - if (sm9_bn_is_zero(a)) { - sm9_bn_copy(r, a); - } else { - sm9_bn_sub(r, SM9_P, a); - } -} - -int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a) -{ - uint8_t buf[32]; - sm9_bn_to_bytes(a, buf); - format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); - return 1; -} - -int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) -{ - int i; - for (i = 8; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - -void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) -{ - int i; - r[0] = a[0] + b[0]; - for (i = 1; i < 9; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 8; i++) { - r[i] &= 0xffffffff; - } -} - -void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) -{ - sm9_barrett_bn_t r; - int i; - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 8; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - for (i = 0; i < 9; i++) { - ret[i] = r[i]; - } -} - -void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) -{ - uint64_t s[18]; - sm9_barrett_bn_t zh, zl, q; - uint64_t w; - int i, j; - - /* z = a * b */ - for (i = 0; i < 8; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + a[i] * b[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - - /* zl = z mod (2^32)^9 = z[0..8] - * zh = z // (2^32)^7 = z[7..15] */ - for (i = 0; i < 9; i++) { - zl[i] = s[i]; - zh[i] = s[7 + i]; - } - - /* q = zh * mu // (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 9; j++) { - w += s[i + j] + zh[i] * SM9_MU_P[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 9] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[9 + i]; - } - - /* q = q * p mod (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + q[i] * SM9_P[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[i]; - } - - /* r = zl - q (mod (2^32)^9) */ - - if (sm9_barrett_bn_cmp(zl, q)) { - sm9_barrett_bn_sub(zl, zl, q); - } else { - sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; - sm9_barrett_bn_sub(q, c, q); - sm9_barrett_bn_add(zl, q, zl); - } - - - for (i = 0; i < 8; i++) { - r[i] = zl[i]; - } - - r[7] += (zl[8] << 32); - - /* while r >= p do: r = r - p */ - while (sm9_bn_cmp(r, SM9_P) >= 0) { - - sm9_bn_sub(r, r, SM9_P); - } -} - -void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a) -{ - sm9_fp_mul(r, a, a); -} - -void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e) -{ - sm9_fp_t t; - uint32_t w; - int i, j; - - assert(sm9_bn_cmp(e, SM9_P_MINUS_ONE) < 0); - - sm9_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm9_fp_sqr(t, t); - if (w & 0x80000000) - sm9_fp_mul(t, t, a); - w <<= 1; - } - } - sm9_bn_copy(r, t); -} - -void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a) -{ - sm9_fp_t e; - sm9_bn_sub(e, SM9_P, SM9_TWO); - sm9_fp_pow(r, a, e); -} - -int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32]) -{ - sm9_bn_from_bytes(r, buf); - if (sm9_bn_cmp(r, SM9_P) >= 0) { - error_print(); - return -1; - } - return 1; -} - -int sm9_fp_from_hex(sm9_fp_t r, const char hex[64]) -{ - if (sm9_bn_from_hex(r, hex) != 1) { - error_print(); - return -1; - } - if (sm9_bn_cmp(r, SM9_P) >= 0) { - error_print(); - return -1; - } - return 1; -} - - -const sm9_fp2_t SM9_FP2_ZERO = {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; -const sm9_fp2_t SM9_FP2_ONE = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; -const sm9_fp2_t SM9_FP2_U = {{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}}; -static const sm9_fp2_t SM9_FP2_5U = {{0,0,0,0,0,0,0,0},{5,0,0,0,0,0,0,0}}; - -int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b) -{ - return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp2_t)) == 0); -} - -void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a) -{ - memcpy(r, a, sizeof(sm9_fp2_t)); -} - -int sm9_fp2_rand(sm9_fp2_t r) -{ - if (sm9_fp_rand(r[0]) != 1 - || sm9_fp_rand(r[1]) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm9_fp2_to_bytes(const sm9_fp2_t a, uint8_t buf[64]) -{ - sm9_fp_to_bytes(a[1], buf); - sm9_fp_to_bytes(a[0], buf + 32); -} - -int sm9_fp2_from_bytes(sm9_fp2_t r, const uint8_t buf[64]) -{ - if (sm9_fp_from_bytes(r[1], buf) != 1 - || sm9_fp_from_bytes(r[0], buf + 32) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129]) -{ - if (sm9_fp_from_hex(r[1], hex) != 1 - || sm9_fp_from_hex(r[0], hex + 65) != 1) { - error_print(); - return -1; - } - /* - if (hex[64] != SM9_HEX_SEP) { - error_print(); - return -1; - } - */ - return 1; -} - -void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129]) -{ - sm9_fp_to_hex(a[1], hex); - hex[64] = SM9_HEX_SEP; - sm9_fp_to_hex(a[0], hex + 65); -} - -void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a) -{ - sm9_fp_copy(r[0], a); - sm9_fp_set_zero(r[1]); -} - -void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1) -{ - sm9_fp_copy(r[0], a0); - sm9_fp_copy(r[1], a1); -} - -void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) -{ - sm9_fp_add(r[0], a[0], b[0]); - sm9_fp_add(r[1], a[1], b[1]); -} - -void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_dbl(r[0], a[0]); - sm9_fp_dbl(r[1], a[1]); -} - -void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_tri(r[0], a[0]); - sm9_fp_tri(r[1], a[1]); -} - -void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) -{ - sm9_fp_sub(r[0], a[0], b[0]); - sm9_fp_sub(r[1], a[1], b[1]); -} - -void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_neg(r[0], a[0]); - sm9_fp_neg(r[1], a[1]); -} - -void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) -{ - sm9_fp_t r0, r1, t; - - // r0 = a0 * b0 - 2 * a1 * b1 - sm9_fp_mul(r0, a[0], b[0]); - sm9_fp_mul(t, a[1], b[1]); - sm9_fp_dbl(t, t); - sm9_fp_sub(r0, r0, t); - - // r1 = a0 * b1 + a1 * b0 - sm9_fp_mul(r1, a[0], b[1]); - sm9_fp_mul(t, a[1], b[0]); - sm9_fp_add(r1, r1, t); - - sm9_fp_copy(r[0], r0); - sm9_fp_copy(r[1], r1); -} - -void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) -{ - sm9_fp_t r0, r1, t; - - // r0 = -2 * (a0 * b1 + a1 * b0) - sm9_fp_mul(r0, a[0], b[1]); - sm9_fp_mul(t, a[1], b[0]); - sm9_fp_add(r0, r0, t); - sm9_fp_dbl(r0, r0); - sm9_fp_neg(r0, r0); - - // r1 = a0 * b0 - 2 * a1 * b1 - sm9_fp_mul(r1, a[0], b[0]); - sm9_fp_mul(t, a[1], b[1]); - sm9_fp_dbl(t, t); - sm9_fp_sub(r1, r1, t); - - sm9_fp_copy(r[0], r0); - sm9_fp_copy(r[1], r1); -} - -void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k) -{ - sm9_fp_mul(r[0], a[0], k); - sm9_fp_mul(r[1], a[1], k); -} - -void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_t r0, r1, t; - - // a0^2 - 2 * a1^2 - sm9_fp_sqr(r0, a[0]); - sm9_fp_sqr(t, a[1]); - sm9_fp_dbl(t, t); - sm9_fp_sub(r0, r0, t); - - // r1 = 2 * a0 * a1 - sm9_fp_mul(r1, a[0], a[1]); - sm9_fp_dbl(r1, r1); - - sm9_bn_copy(r[0], r0); - sm9_bn_copy(r[1], r1); -} - -void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_t r0, r1, t; - - // r0 = -4 * a0 * a1 - sm9_fp_mul(r0, a[0], a[1]); - sm9_fp_dbl(r0, r0); - sm9_fp_dbl(r0, r0); - sm9_fp_neg(r0, r0); - - // r1 = a0^2 - 2 * a1^2 - sm9_fp_sqr(r1, a[0]); - sm9_fp_sqr(t, a[1]); - sm9_fp_dbl(t, t); - sm9_fp_sub(r1, r1, t); - - sm9_fp_copy(r[0], r0); - sm9_fp_copy(r[1], r1); - -} - -void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a) -{ - if (sm9_fp_is_zero(a[0])) { - // r0 = 0 - sm9_fp_set_zero(r[0]); - // r1 = -(2 * a1)^-1 - sm9_fp_dbl(r[1], a[1]); - sm9_fp_inv(r[1], r[1]); - sm9_fp_neg(r[1], r[1]); - - } else if (sm9_fp_is_zero(a[1])) { - /* r1 = 0 */ - sm9_fp_set_zero(r[1]); - /* r0 = a0^-1 */ - sm9_fp_inv(r[0], a[0]); - - } else { - sm9_fp_t k, t; - - // k = (a[0]^2 + 2 * a[1]^2)^-1 - sm9_fp_sqr(k, a[0]); - sm9_fp_sqr(t, a[1]); - sm9_fp_dbl(t, t); - sm9_fp_add(k, k, t); - sm9_fp_inv(k, k); - - // r[0] = a[0] * k - sm9_fp_mul(r[0], a[0], k); - - // r[1] = -a[1] * k - sm9_fp_mul(r[1], a[1], k); - sm9_fp_neg(r[1], r[1]); - } -} - -void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) -{ - sm9_fp2_t t; - sm9_fp2_inv(t, b); - sm9_fp2_mul(r, a, t); -} - -void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_div2(r[0], a[0]); - sm9_fp_div2(r[1], a[1]); -} - -int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a) -{ - return 1; -} - - -const sm9_fp4_t SM9_FP4_ZERO = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; -const sm9_fp4_t SM9_FP4_ONE = {{{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; -const sm9_fp4_t SM9_FP4_U = {{{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; -const sm9_fp4_t SM9_FP4_V = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; - -int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b) -{ - return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp4_t)) == 0); -} - -int sm9_fp4_rand(sm9_fp4_t r) -{ - if (sm9_fp2_rand(r[1]) != 1 - || sm9_fp2_rand(r[0]) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a) -{ - memcpy(r, a, sizeof(sm9_fp4_t)); -} - -void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128]) -{ - sm9_fp2_to_bytes(a[1], buf); - sm9_fp2_to_bytes(a[0], buf + 64); -} - -int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128]) -{ - if (sm9_fp2_from_bytes(r[1], buf) != 1 - || sm9_fp2_from_bytes(r[0], buf + 64) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[65 * 4]) -{ - if (sm9_fp2_from_hex(r[1], hex) != 1 - || hex[129] != SM9_HEX_SEP - || sm9_fp2_from_hex(r[0], hex + 130) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259]) -{ - sm9_fp2_to_hex(a[1], hex); - hex[129] = SM9_HEX_SEP; - sm9_fp2_to_hex(a[0], hex + 130); -} - -void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a) -{ - sm9_fp2_set_fp(r[0], a); - sm9_fp2_set_zero(r[1]); -} - -void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a) -{ - sm9_fp2_copy(r[0], a); - sm9_fp2_set_zero(r[1]); -} - -void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1) -{ - sm9_fp2_copy(r[0], a0); - sm9_fp2_copy(r[1], a1); -} - -void sm9_fp4_set_u(sm9_fp4_t r) -{ - sm9_fp2_set_u(r[0]); - sm9_fp2_set_zero(r[1]); -} - -void sm9_fp4_set_v(sm9_fp4_t r) -{ - sm9_fp2_set_zero(r[0]); - sm9_fp2_set_one(r[1]); -} - -void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) -{ - sm9_fp2_add(r[0], a[0], b[0]); - sm9_fp2_add(r[1], a[1], b[1]); -} - -void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_dbl(r[0], a[0]); - sm9_fp2_dbl(r[1], a[1]); -} - -void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) -{ - sm9_fp2_sub(r[0], a[0], b[0]); - sm9_fp2_sub(r[1], a[1], b[1]); -} - -void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_neg(r[0], a[0]); - sm9_fp2_neg(r[1], a[1]); -} - -void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) -{ - sm9_fp2_t r0, r1, t; - - sm9_fp2_mul(r0, a[0], b[0]); - sm9_fp2_mul_u(t, a[1], b[1]); - sm9_fp2_add(r0, r0, t); - - sm9_fp2_mul(r1, a[0], b[1]); - sm9_fp2_mul(t, a[1], b[0]); - sm9_fp2_add(r1, r1, t); - - sm9_fp2_copy(r[0], r0); - sm9_fp2_copy(r[1], r1); -} - -void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k) -{ - sm9_fp2_mul_fp(r[0], a[0], k); - sm9_fp2_mul_fp(r[1], a[1], k); -} - -void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0) -{ - sm9_fp2_mul(r[0], a[0], b0); - sm9_fp2_mul(r[1], a[1], b0); -} - -void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) -{ - sm9_fp2_t r0, r1, t; - - sm9_fp2_mul_u(r0, a[0], b[1]); - sm9_fp2_mul_u(t, a[1], b[0]); - sm9_fp2_add(r0, r0, t); - - sm9_fp2_mul(r1, a[0], b[0]); - sm9_fp2_mul_u(t, a[1], b[1]); - sm9_fp2_add(r1, r1, t); - - sm9_fp2_copy(r[0], r0); - sm9_fp2_copy(r[1], r1); -} - -void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_t r0, r1, t; - - sm9_fp2_sqr(r0, a[0]); - sm9_fp2_sqr_u(t, a[1]); - sm9_fp2_add(r0, r0, t); - - sm9_fp2_mul(r1, a[0], a[1]); - sm9_fp2_dbl(r1, r1); - sm9_fp2_copy(r[0], r0); - sm9_fp2_copy(r[1], r1); -} - -void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_t r0, r1, t; - - sm9_fp2_mul_u(t, a[0], a[1]); - sm9_fp2_dbl(r0, t); - - sm9_fp2_sqr(r1, a[0]); - sm9_fp2_sqr_u(t, a[1]); - sm9_fp2_add(r1, r1, t); - - sm9_fp2_copy(r[0], r0); - sm9_fp2_copy(r[1], r1); -} - -void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_t r0, r1, k; - - sm9_fp2_sqr_u(k, a[1]); - sm9_fp2_sqr(r0, a[0]); - sm9_fp2_sub(k, k, r0); - sm9_fp2_inv(k, k); - - sm9_fp2_mul(r0, a[0], k); - sm9_fp2_neg(r0, r0); - - sm9_fp2_mul(r1, a[1], k); - - sm9_fp2_copy(r[0], r0); - sm9_fp2_copy(r[1], r1); -} - -void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a) -{ - sm9_fp4_copy(r[0], a[0]); - sm9_fp4_copy(r[1], a[1]); - sm9_fp4_copy(r[2], a[2]); -} - -int sm9_fp12_rand(sm9_fp12_t r) -{ - if (sm9_fp4_rand(r[0]) != 1 - || sm9_fp4_rand(r[1]) != 1 - || sm9_fp4_rand(r[2]) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm9_fp12_set_zero(sm9_fp12_t r) -{ - sm9_fp4_set_zero(r[0]); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_one(sm9_fp12_t r) -{ - sm9_fp4_set_one(r[0]); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -int sm9_fp12_is_one(const sm9_fp12_t a) -{ - return sm9_fp4_is_one(a[0]) - && sm9_fp4_is_zero(a[1]) - && sm9_fp4_is_zero(a[2]); -} - -int sm9_fp12_is_zero(const sm9_fp12_t a) -{ - return sm9_fp4_is_zero(a[0]) - && sm9_fp4_is_zero(a[1]) - && sm9_fp4_is_zero(a[2]); -} - -int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12 - 1]) -{ - if (sm9_fp4_from_hex(r[2], hex) != 1 - || hex[65 * 4 - 1] != SM9_HEX_SEP - || sm9_fp4_from_hex(r[1], hex + 65 * 4) != 1 - || hex[65 * 4 - 1] != SM9_HEX_SEP - || sm9_fp4_from_hex(r[0], hex + 65 * 8) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12 - 1]) -{ - sm9_fp4_to_hex(a[2], hex); - hex[65 * 4 - 1] = SM9_HEX_SEP; - sm9_fp4_to_hex(a[1], hex + 65 * 4); - hex[65 * 8 - 1] = SM9_HEX_SEP; - sm9_fp4_to_hex(a[0], hex + 65 * 8); -} - -void sm9_fp12_print(const char *prefix, const sm9_fp12_t a) -{ - char hex[65 * 12]; - sm9_fp12_to_hex(a, hex); - printf("%s\n%s\n", prefix, hex); -} - -void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2) -{ - sm9_fp4_copy(r[0], a0); - sm9_fp4_copy(r[1], a1); - sm9_fp4_copy(r[2], a2); -} - -void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a) -{ - sm9_fp4_set_fp(r[0], a); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a) -{ - sm9_fp4_set_fp2(r[0], a); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a) -{ - sm9_fp4_copy(r[0], a); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_u(sm9_fp12_t r) -{ - sm9_fp4_set_u(r[0]); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_v(sm9_fp12_t r) -{ - sm9_fp4_set_v(r[0]); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_w(sm9_fp12_t r) -{ - sm9_fp4_set_zero(r[0]); - sm9_fp4_set_one(r[1]); - sm9_fp4_set_zero(r[2]); -} - -void sm9_fp12_set_w_sqr(sm9_fp12_t r) -{ - sm9_fp4_set_zero(r[0]); - sm9_fp4_set_zero(r[1]); - sm9_fp4_set_one(r[2]); -} - -int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b) -{ - return sm9_fp4_equ(a[0], b[0]) - && sm9_fp4_equ(a[1], b[1]) - && sm9_fp4_equ(a[2], b[2]); -} - -void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) -{ - sm9_fp4_add(r[0], a[0], b[0]); - sm9_fp4_add(r[1], a[1], b[1]); - sm9_fp4_add(r[2], a[2], b[2]); -} - -void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a) -{ - sm9_fp4_dbl(r[0], a[0]); - sm9_fp4_dbl(r[1], a[1]); - sm9_fp4_dbl(r[2], a[2]); -} - -void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a) -{ - sm9_fp12_t t; - sm9_fp12_dbl(t, a); - sm9_fp12_add(r, t, a); -} - -void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) -{ - sm9_fp4_sub(r[0], a[0], b[0]); - sm9_fp4_sub(r[1], a[1], b[1]); - sm9_fp4_sub(r[2], a[2], b[2]); -} - -void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a) -{ - sm9_fp4_neg(r[0], a[0]); - sm9_fp4_neg(r[1], a[1]); - sm9_fp4_neg(r[2], a[2]); -} - -void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) -{ - sm9_fp4_t r0, r1, r2, t; - - sm9_fp4_mul(r0, a[0], b[0]); - sm9_fp4_mul_v(t, a[1], b[2]); - sm9_fp4_add(r0, r0, t); - sm9_fp4_mul_v(t, a[2], b[1]); - sm9_fp4_add(r0, r0, t); - - sm9_fp4_mul(r1, a[0], b[1]); - sm9_fp4_mul(t, a[1], b[0]); - sm9_fp4_add(r1, r1, t); - sm9_fp4_mul_v(t, a[2], b[2]); - sm9_fp4_add(r1, r1, t); - - sm9_fp4_mul(r2, a[0], b[2]); - sm9_fp4_mul(t, a[1], b[1]); - sm9_fp4_add(r2, r2, t); - sm9_fp4_mul(t, a[2], b[0]); - sm9_fp4_add(r2, r2, t); - - sm9_fp4_copy(r[0], r0); - sm9_fp4_copy(r[1], r1); - sm9_fp4_copy(r[2], r2); -} - -void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a) -{ - sm9_fp4_t r0, r1, r2, t; - - sm9_fp4_sqr(r0, a[0]); - sm9_fp4_mul_v(t, a[1], a[2]); - sm9_fp4_dbl(t, t); - sm9_fp4_add(r0, r0, t); - - sm9_fp4_mul(r1, a[0], a[1]); - sm9_fp4_dbl(r1, r1); - sm9_fp4_sqr_v(t, a[2]); - sm9_fp4_add(r1, r1, t); - - sm9_fp4_mul(r2, a[0], a[2]); - sm9_fp4_dbl(r2, r2); - sm9_fp4_sqr(t, a[1]); - sm9_fp4_add(r2, r2, t); - - sm9_fp4_copy(r[0], r0); - sm9_fp4_copy(r[1], r1); - sm9_fp4_copy(r[2], r2); -} - -void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a) -{ - if (sm9_fp4_is_zero(a[2])) { - sm9_fp4_t k, t; - - sm9_fp4_sqr(k, a[0]); - sm9_fp4_mul(k, k, a[0]); - sm9_fp4_sqr_v(t, a[1]); - sm9_fp4_mul(t, t, a[1]); - sm9_fp4_add(k, k, t); - sm9_fp4_inv(k, k); - - sm9_fp4_sqr(r[2], a[1]); - sm9_fp4_mul(r[2], r[2], k); - - sm9_fp4_mul(r[1], a[0], a[1]); - sm9_fp4_mul(r[1], r[1], k); - sm9_fp4_neg(r[1], r[1]); - - sm9_fp4_sqr(r[0], a[0]); - sm9_fp4_mul(r[0], r[0], k); - - } else { - sm9_fp4_t t0, t1, t2, t3; - - sm9_fp4_sqr(t0, a[1]); - sm9_fp4_mul(t1, a[0], a[2]); - sm9_fp4_sub(t0, t0, t1); - - sm9_fp4_mul(t1, a[0], a[1]); - sm9_fp4_sqr_v(t2, a[2]); - sm9_fp4_sub(t1, t1, t2); - - sm9_fp4_sqr(t2, a[0]); - sm9_fp4_mul_v(t3, a[1], a[2]); - sm9_fp4_sub(t2, t2, t3); - - sm9_fp4_sqr(t3, t1); - sm9_fp4_mul(r[0], t0, t2); - sm9_fp4_sub(t3, t3, r[0]); - sm9_fp4_inv(t3, t3); - sm9_fp4_mul(t3, a[2], t3); - - sm9_fp4_mul(r[0], t2, t3); - - sm9_fp4_mul(r[1], t1, t3); - sm9_fp4_neg(r[1], r[1]); - - sm9_fp4_mul(r[2], t0, t3); - } -} - -void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k) -{ - char kbits[257]; - sm9_fp12_t t; - int i; - - assert(sm9_bn_cmp(k, SM9_P_MINUS_ONE) < 0); - sm9_fp12_set_zero(t); - - sm9_bn_to_bits(k, kbits); - sm9_fp12_set_one(t); - for (i = 0; i < 256; i++) { - sm9_fp12_sqr(t, t); - if (kbits[i] == '1') { - sm9_fp12_mul(t, t, a); - } - } - sm9_fp12_copy(r, t); -} - -void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a) -{ - sm9_fp_copy(r[0], a[0]); - sm9_fp_neg (r[1], a[1]); - -} - -void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a) -{ - return sm9_fp2_conjugate(r, a); -} - -// beta = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011 -// alpha1 = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698b -// alpha2 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 -// alpha3 = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011 -// alpha4 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65333 -// alpha5 = 0x2d40a38cf6983351711e5f99520347cc57d778a9f8ff4c8a4c949c7fa2a96686 -static const sm9_fp2_t SM9_BETA = {{0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5}, {0}}; -static const sm9_fp_t SM9_ALPHA1 = {0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e, 0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58}; -static const sm9_fp_t SM9_ALPHA2 = {0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0, 0x0 }; -static const sm9_fp_t SM9_ALPHA3 = {0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5}; -static const sm9_fp_t SM9_ALPHA4 = {0x7be65333, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0, 0x0 }; -static const sm9_fp_t SM9_ALPHA5 = {0xa2a96686, 0x4c949c7f, 0xf8ff4c8a, 0x57d778a9, 0x520347cc, 0x711e5f99, 0xf6983351, 0x2d40a38c}; - - -void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_conjugate(r[0], a[0]); - sm9_fp2_conjugate(r[1], a[1]); - sm9_fp2_mul(r[1], r[1], SM9_BETA); -} - -void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_copy(r[0], a[0]); - sm9_fp2_neg(r[1], a[1]); -} - -void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a) -{ - return sm9_fp4_conjugate(r, a); -} - -void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a) -{ - sm9_fp2_conjugate(r[0], a[0]); - sm9_fp2_conjugate(r[1], a[1]); - sm9_fp2_mul(r[1], r[1], SM9_BETA); - sm9_fp2_neg(r[1], r[1]); -} - -void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x) -{ - const sm9_fp2_t *xa = x[0]; - const sm9_fp2_t *xb = x[1]; - const sm9_fp2_t *xc = x[2]; - sm9_fp4_t ra; - sm9_fp4_t rb; - sm9_fp4_t rc; - - sm9_fp2_conjugate(ra[0], xa[0]); - sm9_fp2_conjugate(ra[1], xa[1]); - sm9_fp2_mul_fp(ra[1], ra[1], SM9_ALPHA3); - - sm9_fp2_conjugate(rb[0], xb[0]); - sm9_fp2_mul_fp(rb[0], rb[0], SM9_ALPHA1); - sm9_fp2_conjugate(rb[1], xb[1]); - sm9_fp2_mul_fp(rb[1], rb[1], SM9_ALPHA4); - - sm9_fp2_conjugate(rc[0], xc[0]); - sm9_fp2_mul_fp(rc[0], rc[0], SM9_ALPHA2); - sm9_fp2_conjugate(rc[1], xc[1]); - sm9_fp2_mul_fp(rc[1], rc[1], SM9_ALPHA5); - - sm9_fp12_set(r, ra, rb, rc); -} - -void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x) -{ - sm9_fp4_t a; - sm9_fp4_t b; - sm9_fp4_t c; - - sm9_fp4_conjugate(a, x[0]); - sm9_fp4_conjugate(b, x[1]); - sm9_fp4_mul_fp(b, b, SM9_ALPHA2); - sm9_fp4_conjugate(c, x[2]); - sm9_fp4_mul_fp(c, c, SM9_ALPHA4); - - sm9_fp4_copy(r[0], a); - sm9_fp4_copy(r[1], b); - sm9_fp4_copy(r[2], c); -} - -void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x) -{ - const sm9_fp2_t *xa = x[0]; - const sm9_fp2_t *xb = x[1]; - const sm9_fp2_t *xc = x[2]; - sm9_fp4_t ra; - sm9_fp4_t rb; - sm9_fp4_t rc; - - sm9_fp2_conjugate(ra[0], xa[0]); - sm9_fp2_conjugate(ra[1], xa[1]); - sm9_fp2_mul(ra[1], ra[1], SM9_BETA); - sm9_fp2_neg(ra[1], ra[1]); - - sm9_fp2_conjugate(rb[0], xb[0]); - sm9_fp2_mul(rb[0], rb[0], SM9_BETA); - sm9_fp2_conjugate(rb[1], xb[1]); - - sm9_fp2_conjugate(rc[0], xc[0]); - sm9_fp2_neg(rc[0], rc[0]); - sm9_fp2_conjugate(rc[1], xc[1]); - sm9_fp2_mul(rc[1], rc[1], SM9_BETA); - - sm9_fp4_copy(r[0], ra); - sm9_fp4_copy(r[1], rb); - sm9_fp4_copy(r[2], rc); -} - -void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x) -{ - sm9_fp4_t a; - sm9_fp4_t b; - sm9_fp4_t c; - - sm9_fp4_copy(a, x[0]); - sm9_fp4_copy(b, x[1]); - sm9_fp4_copy(c, x[2]); - - sm9_fp4_conjugate(a, a); - sm9_fp4_conjugate(b, b); - sm9_fp4_neg(b, b); - sm9_fp4_conjugate(c, c); - - sm9_fp4_copy(r[0], a); - sm9_fp4_copy(r[1], b); - sm9_fp4_copy(r[2], c); -} - - - -void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2]) -{ - sm9_bn_from_hex(R->X, hex); - sm9_bn_from_hex(R->Y, hex + 65); - sm9_bn_set_one(R->Z); -} - -int sm9_point_is_at_infinity(const SM9_POINT *P) { - return sm9_fp_is_zero(P->Z); -} - -void sm9_point_set_infinity(SM9_POINT *R) { - sm9_fp_set_one(R->X); - sm9_fp_set_one(R->Y); - sm9_fp_set_zero(R->Z); -} - -void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P) -{ - *R = *P; -} - -void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y) -{ - sm9_fp_t z_inv; - - assert(!sm9_fp_is_zero(P->Z)); - - if (sm9_fp_is_one(P->Z)) { - sm9_fp_copy(x, P->X); - sm9_fp_copy(y, P->Y); - } - - sm9_fp_inv(z_inv, P->Z); - if (y) - sm9_fp_mul(y, P->Y, z_inv); - sm9_fp_sqr(z_inv, z_inv); - sm9_fp_mul(x, P->X, z_inv); - if (y) - sm9_fp_mul(y, y, z_inv); -} - -int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q) -{ - sm9_fp_t t1, t2, t3, t4; - sm9_fp_sqr(t1, P->Z); - sm9_fp_sqr(t2, Q->Z); - sm9_fp_mul(t3, P->X, t2); - sm9_fp_mul(t4, Q->X, t1); - if (!sm9_fp_equ(t3, t4)) { - return 0; - } - sm9_fp_mul(t1, t1, P->Z); - sm9_fp_mul(t2, t2, Q->Z); - sm9_fp_mul(t3, P->Y, t2); - sm9_fp_mul(t4, Q->Y, t1); - return sm9_fp_equ(t3, t4); -} - -int sm9_point_is_on_curve(const SM9_POINT *P) -{ - sm9_fp_t t0, t1, t2; - if (sm9_fp_is_one(P->Z)) { - sm9_fp_sqr(t0, P->Y); - sm9_fp_sqr(t1, P->X); - sm9_fp_mul(t1, t1, P->X); - sm9_fp_add(t1, t1, SM9_FIVE); - } else { - sm9_fp_sqr(t0, P->X); - sm9_fp_mul(t0, t0, P->X); - sm9_fp_sqr(t1, P->Z); - sm9_fp_sqr(t2, t1); - sm9_fp_mul(t1, t1, t2); - sm9_fp_mul(t1, t1, SM9_FIVE); - sm9_fp_add(t1, t0, t1); - sm9_fp_sqr(t0, P->Y); - } - if (sm9_fp_equ(t0, t1) != 1) { - error_print(); - return 0; - } - return 1; -} - -void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P) -{ - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - sm9_fp_t X3, Y3, Z3, T1, T2, T3; - - if (sm9_point_is_at_infinity(P)) { - sm9_point_copy(R, P); - return; - } - - sm9_fp_sqr(T2, X1); - sm9_fp_tri(T2, T2); - sm9_fp_dbl(Y3, Y1); - sm9_fp_mul(Z3, Y3, Z1); - sm9_fp_sqr(Y3, Y3); - sm9_fp_mul(T3, Y3, X1); - sm9_fp_sqr(Y3, Y3); - sm9_fp_div2(Y3, Y3); - sm9_fp_sqr(X3, T2); - sm9_fp_dbl(T1, T3); - sm9_fp_sub(X3, X3, T1); - sm9_fp_sub(T1, T3, X3); - sm9_fp_mul(T1, T1, T2); - sm9_fp_sub(Y3, T1, Y3); - - sm9_fp_copy(R->X, X3); - sm9_fp_copy(R->Y, Y3); - sm9_fp_copy(R->Z, Z3); -} - -void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q) -{ - sm9_fp_t x; - sm9_fp_t y; - sm9_point_get_xy(Q, x, y); - - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - const uint64_t *x2 = x; - const uint64_t *y2 = y; - sm9_fp_t X3, Y3, Z3, T1, T2, T3, T4; - - if (sm9_point_is_at_infinity(Q)) { - sm9_point_copy(R, P); - return; - } - if (sm9_point_is_at_infinity(P)) { - sm9_point_copy(R, Q); - return; - } - - sm9_fp_sqr(T1, Z1); - sm9_fp_mul(T2, T1, Z1); - sm9_fp_mul(T1, T1, x2); - sm9_fp_mul(T2, T2, y2); - sm9_fp_sub(T1, T1, X1); - sm9_fp_sub(T2, T2, Y1); - - if (sm9_fp_is_zero(T1)) { - if (sm9_fp_is_zero(T2)) { - sm9_point_dbl(R, Q); - return; - } else { - sm9_point_set_infinity(R); - return; - } - } - - sm9_fp_mul(Z3, Z1, T1); - sm9_fp_sqr(T3, T1); - sm9_fp_mul(T4, T3, T1); - sm9_fp_mul(T3, T3, X1); - sm9_fp_dbl(T1, T3); - sm9_fp_sqr(X3, T2); - sm9_fp_sub(X3, X3, T1); - sm9_fp_sub(X3, X3, T4); - sm9_fp_sub(T3, T3, X3); - sm9_fp_mul(T3, T3, T2); - sm9_fp_mul(T4, T4, Y1); - sm9_fp_sub(Y3, T3, T4); - - sm9_fp_copy(R->X, X3); - sm9_fp_copy(R->Y, Y3); - sm9_fp_copy(R->Z, Z3); -} - -void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P) -{ - sm9_fp_copy(R->X, P->X); - sm9_fp_neg(R->Y, P->Y); - sm9_fp_copy(R->Z, P->Z); -} - -void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q) -{ - SM9_POINT _T, *T = &_T; - sm9_point_neg(T, Q); - sm9_point_add(R, P, T); -} - -void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P) -{ - char kbits[257]; - SM9_POINT _Q, *Q = &_Q; - int i; - - sm9_bn_to_bits(k, kbits); - sm9_point_set_infinity(Q); - for (i = 0; i < 256; i++) { - sm9_point_dbl(Q, Q); - if (kbits[i] == '1') { - sm9_point_add(Q, Q, P); - } - } - sm9_point_copy(R, Q); -} - -void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k) -{ - sm9_point_mul(R, k, SM9_P1); -} - - -int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P) -{ - uint8_t buf[65]; - sm9_point_to_uncompressed_octets(P, buf); - format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); - return 1; -} - -int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P) -{ - uint8_t buf[129]; - sm9_twist_point_to_uncompressed_octets(P, buf); - format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); - return 1; -} - -void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4]) -{ - sm9_fp2_from_hex(R->X, hex); - sm9_fp2_from_hex(R->Y, hex + 65 * 2); - sm9_fp2_set_one(R->Z); -} - -int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P) -{ - return sm9_fp2_is_zero(P->Z); -} - -void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R) -{ - sm9_fp2_set_one(R->X); - sm9_fp2_set_one(R->Y); - sm9_fp2_set_zero(R->Z); -} - -void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y) -{ - sm9_fp2_t z_inv; - - assert(!sm9_fp2_is_zero(P->Z)); - - if (sm9_fp2_is_one(P->Z)) { - sm9_fp2_copy(x, P->X); - sm9_fp2_copy(y, P->Y); - } - - sm9_fp2_inv(z_inv, P->Z); - if (y) - sm9_fp2_mul(y, P->Y, z_inv); - sm9_fp2_sqr(z_inv, z_inv); - sm9_fp2_mul(x, P->X, z_inv); - if (y) - sm9_fp2_mul(y, y, z_inv); -} - - -int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) -{ - sm9_fp2_t t1, t2, t3, t4; - - sm9_fp2_sqr(t1, P->Z); - sm9_fp2_sqr(t2, Q->Z); - sm9_fp2_mul(t3, P->X, t2); - sm9_fp2_mul(t4, Q->X, t1); - if (!sm9_fp2_equ(t3, t4)) { - return 0; - } - sm9_fp2_mul(t1, t1, P->Z); - sm9_fp2_mul(t2, t2, Q->Z); - sm9_fp2_mul(t3, P->Y, t2); - sm9_fp2_mul(t4, Q->Y, t1); - return sm9_fp2_equ(t3, t4); -} - -int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P) -{ - sm9_fp2_t t0, t1, t2; - - if (sm9_fp2_is_one(P->Z)) { - sm9_fp2_sqr(t0, P->Y); - sm9_fp2_sqr(t1, P->X); - sm9_fp2_mul(t1, t1, P->X); - sm9_fp2_add(t1, t1, SM9_FP2_5U); - - } else { - sm9_fp2_sqr(t0, P->X); - sm9_fp2_mul(t0, t0, P->X); - sm9_fp2_sqr(t1, P->Z); - sm9_fp2_sqr(t2, t1); - sm9_fp2_mul(t1, t1, t2); - sm9_fp2_mul(t1, t1, SM9_FP2_5U); - sm9_fp2_add(t1, t0, t1); - sm9_fp2_sqr(t0, P->Y); - } - - return sm9_fp2_equ(t0, t1); -} - -void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) -{ - sm9_fp2_copy(R->X, P->X); - sm9_fp2_neg(R->Y, P->Y); - sm9_fp2_copy(R->Z, P->Z); -} - -void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) -{ - const sm9_fp_t *X1 = P->X; - const sm9_fp_t *Y1 = P->Y; - const sm9_fp_t *Z1 = P->Z; - sm9_fp2_t X3, Y3, Z3, T1, T2, T3; - - if (sm9_twist_point_is_at_infinity(P)) { - sm9_twist_point_copy(R, P); - return; - } - sm9_fp2_sqr(T2, X1); - sm9_fp2_tri(T2, T2); - sm9_fp2_dbl(Y3, Y1); - sm9_fp2_mul(Z3, Y3, Z1); - sm9_fp2_sqr(Y3, Y3); - sm9_fp2_mul(T3, Y3, X1); - sm9_fp2_sqr(Y3, Y3); - sm9_fp2_div2(Y3, Y3); - sm9_fp2_sqr(X3, T2); - sm9_fp2_dbl(T1, T3); - sm9_fp2_sub(X3, X3, T1); - sm9_fp2_sub(T1, T3, X3); - sm9_fp2_mul(T1, T1, T2); - sm9_fp2_sub(Y3, T1, Y3); - - sm9_fp2_copy(R->X, X3); - sm9_fp2_copy(R->Y, Y3); - sm9_fp2_copy(R->Z, Z3); -} - -void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) -{ - const sm9_fp_t *X1 = P->X; - const sm9_fp_t *Y1 = P->Y; - const sm9_fp_t *Z1 = P->Z; - const sm9_fp_t *x2 = Q->X; - const sm9_fp_t *y2 = Q->Y; - sm9_fp2_t X3, Y3, Z3, T1, T2, T3, T4; - - if (sm9_twist_point_is_at_infinity(Q)) { - sm9_twist_point_copy(R, P); - return; - } - if (sm9_twist_point_is_at_infinity(P)) { - sm9_twist_point_copy(R, Q); - return; - } - - sm9_fp2_sqr(T1, Z1); - sm9_fp2_mul(T2, T1, Z1); - sm9_fp2_mul(T1, T1, x2); - sm9_fp2_mul(T2, T2, y2); - sm9_fp2_sub(T1, T1, X1); - sm9_fp2_sub(T2, T2, Y1); - if (sm9_fp2_is_zero(T1)) { - if (sm9_fp2_is_zero(T2)) { - sm9_twist_point_dbl(R, Q); - return; - } else { - sm9_twist_point_set_infinity(R); - return; - } - } - sm9_fp2_mul(Z3, Z1, T1); - sm9_fp2_sqr(T3, T1); - sm9_fp2_mul(T4, T3, T1); - sm9_fp2_mul(T3, T3, X1); - sm9_fp2_dbl(T1, T3); - sm9_fp2_sqr(X3, T2); - sm9_fp2_sub(X3, X3, T1); - sm9_fp2_sub(X3, X3, T4); - sm9_fp2_sub(T3, T3, X3); - sm9_fp2_mul(T3, T3, T2); - sm9_fp2_mul(T4, T4, Y1); - sm9_fp2_sub(Y3, T3, T4); - - sm9_fp2_copy(R->X, X3); - sm9_fp2_copy(R->Y, Y3); - sm9_fp2_copy(R->Z, Z3); -} - -void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) -{ - SM9_TWIST_POINT _T, *T = &_T; - sm9_twist_point_neg(T, Q); - sm9_twist_point_add_full(R, P, T); -} - -void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) -{ - const sm9_fp_t *X1 = P->X; - const sm9_fp_t *Y1 = P->Y; - const sm9_fp_t *Z1 = P->Z; - const sm9_fp_t *X2 = Q->X; - const sm9_fp_t *Y2 = Q->Y; - const sm9_fp_t *Z2 = Q->Z; - sm9_fp2_t T1, T2, T3, T4, T5, T6, T7, T8; - - if (sm9_twist_point_is_at_infinity(Q)) { - sm9_twist_point_copy(R, P); - return; - } - if (sm9_twist_point_is_at_infinity(P)) { - sm9_twist_point_copy(R, Q); - return; - } - - sm9_fp2_sqr(T1, Z1); - sm9_fp2_sqr(T2, Z2); - sm9_fp2_mul(T3, X2, T1); - sm9_fp2_mul(T4, X1, T2); - sm9_fp2_add(T5, T3, T4); - sm9_fp2_sub(T3, T3, T4); - sm9_fp2_mul(T1, T1, Z1); - sm9_fp2_mul(T1, T1, Y2); - sm9_fp2_mul(T2, T2, Z2); - sm9_fp2_mul(T2, T2, Y1); - sm9_fp2_add(T6, T1, T2); - sm9_fp2_sub(T1, T1, T2); - - if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T3)) { - return sm9_twist_point_dbl(R, P); - } - if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T6)) { - return sm9_twist_point_set_infinity(R); - } - - sm9_fp2_sqr(T6, T1); - sm9_fp2_mul(T7, T3, Z1); - sm9_fp2_mul(T7, T7, Z2); - sm9_fp2_sqr(T8, T3); - sm9_fp2_mul(T5, T5, T8); - sm9_fp2_mul(T3, T3, T8); - sm9_fp2_mul(T4, T4, T8); - sm9_fp2_sub(T6, T6, T5); - sm9_fp2_sub(T4, T4, T6); - sm9_fp2_mul(T1, T1, T4); - sm9_fp2_mul(T2, T2, T3); - sm9_fp2_sub(T1, T1, T2); - - sm9_fp2_copy(R->X, T6); - sm9_fp2_copy(R->Y, T1); - sm9_fp2_copy(R->Z, T7); -} - -void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P) -{ - SM9_TWIST_POINT _Q, *Q = &_Q; - char kbits[256]; - int i; - - sm9_bn_to_bits(k, kbits); - sm9_twist_point_set_infinity(Q); - for (i = 0; i < 256; i++) { - sm9_twist_point_dbl(Q, Q); - if (kbits[i] == '1') { - sm9_twist_point_add_full(Q, Q, P); - } - } - sm9_twist_point_copy(R, Q); -} - -void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k) -{ - sm9_twist_point_mul(R, k, SM9_P2); -} - -void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q) -{ - sm9_fp_t x; - sm9_fp_t y; - sm9_point_get_xy(Q, x, y); - - const sm9_fp_t *XP = P->X; - const sm9_fp_t *YP = P->Y; - const sm9_fp_t *ZP = P->Z; - const uint64_t *xQ = x; - const uint64_t *yQ = y; - - sm9_fp_t *a0 = num[0][0]; - sm9_fp_t *a1 = num[0][1]; - sm9_fp_t *a4 = num[2][0]; - sm9_fp_t *b1 = den[0][1]; - - sm9_fp2_t t0; - sm9_fp2_t t1; - sm9_fp2_t t2; - - - sm9_fp12_set_zero(num); - sm9_fp12_set_zero(den); - - sm9_fp2_sqr(t0, ZP); - sm9_fp2_mul(t1, t0, ZP); - sm9_fp2_mul(b1, t1, YP); - - sm9_fp2_mul_fp(t2, b1, yQ); - sm9_fp2_neg(a1, t2); - - sm9_fp2_sqr(t1, XP); - sm9_fp2_mul(t0, t0, t1); - sm9_fp2_mul_fp(t0, t0, xQ); - sm9_fp2_tri(t0, t0); - sm9_fp2_div2(a4, t0); - - sm9_fp2_mul(t1, t1, XP); - sm9_fp2_tri(t1, t1); - sm9_fp2_div2(t1, t1); - sm9_fp2_sqr(t0, YP); - sm9_fp2_sub(a0, t0, t1); -} - -void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q) -{ - sm9_fp_t x; - sm9_fp_t y; - sm9_point_get_xy(Q, x, y); - - const sm9_fp_t *XT = T->X; - const sm9_fp_t *YT = T->Y; - const sm9_fp_t *ZT = T->Z; - const sm9_fp_t *XP = P->X; - const sm9_fp_t *YP = P->Y; - const sm9_fp_t *ZP = P->Z; - const uint64_t *xQ = x; - const uint64_t *yQ = y; - - sm9_fp_t *a0 = num[0][0]; - sm9_fp_t *a1 = num[0][1]; - sm9_fp_t *a4 = num[2][0]; - sm9_fp_t *b1 = den[0][1]; - - sm9_fp2_t T0, T1, T2, T3, T4; - - - sm9_fp12_set_zero(num); - sm9_fp12_set_zero(den); - - sm9_fp2_sqr(T0, ZP); - sm9_fp2_mul(T1, T0, XT); - sm9_fp2_mul(T0, T0, ZP); - sm9_fp2_sqr(T2, ZT); - sm9_fp2_mul(T3, T2, XP); - sm9_fp2_mul(T2, T2, ZT); - sm9_fp2_mul(T2, T2, YP); - sm9_fp2_sub(T1, T1, T3); - sm9_fp2_mul(T1, T1, ZT); - sm9_fp2_mul(T1, T1, ZP); - sm9_fp2_mul(T4, T1, T0); - sm9_fp2_copy(b1, T4); - sm9_fp2_mul(T1, T1, YP); - sm9_fp2_mul(T3, T0, YT); - sm9_fp2_sub(T3, T3, T2); - sm9_fp2_mul(T0, T0, T3); - sm9_fp2_mul_fp(T0, T0, xQ); - sm9_fp2_copy(a4, T0); - sm9_fp2_mul(T3, T3, XP); - sm9_fp2_mul(T3, T3, ZP); - sm9_fp2_sub(T1, T1, T3); - sm9_fp2_copy(a0, T1); - sm9_fp2_mul_fp(T2, T4, yQ); - sm9_fp2_neg(T2, T2); - sm9_fp2_copy(a1, T2); -} - -void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) -{ - //const c = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698bn; - const sm9_fp_t c = { - 0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e, - 0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58, - }; - sm9_fp2_conjugate(R->X, P->X); - sm9_fp2_conjugate(R->Y, P->Y); - sm9_fp2_conjugate(R->Z, P->Z); - sm9_fp2_mul_fp(R->Z, R->Z, c); - -} - -void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) -{ - //c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 - const sm9_fp_t c = { - 0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, - 0x02a3a6f2, 0xf3000000, 0, 0, - }; - sm9_fp2_copy(R->X, P->X); - sm9_fp2_copy(R->Y, P->Y); - sm9_fp2_mul_fp(R->Z, P->Z, c); -} - -void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) -{ - // c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 - const sm9_fp_t c = { - 0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, - 0x02a3a6f2, 0xf3000000, 0, 0, - }; - sm9_fp2_copy(R->X, P->X); - sm9_fp2_neg(R->Y, P->Y); - sm9_fp2_mul_fp(R->Z, P->Z, c); -} - - -void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f) -{ - // a2 = 0xd8000000019062ed0000b98b0cb27659 - // a3 = 0x2400000000215d941 - const sm9_bn_t a2 = {0xcb27659, 0x0000b98b, 0x019062ed, 0xd8000000, 0, 0, 0, 0}; - const sm9_bn_t a3 = {0x215d941, 0x40000000, 0x2, 0, 0, 0, 0, 0}; - const sm9_bn_t nine = {9,0,0,0,0,0,0,0}; - sm9_fp12_t t0, t1, t2, t3; - - sm9_fp12_pow(t0, f, a3); - sm9_fp12_inv(t0, t0); - sm9_fp12_frobenius(t1, t0); - sm9_fp12_mul(t1, t0, t1); - - sm9_fp12_mul(t0, t0, t1); - sm9_fp12_frobenius(t2, f); - sm9_fp12_mul(t3, t2, f); - sm9_fp12_pow(t3, t3, nine); - - sm9_fp12_mul(t0, t0, t3); - sm9_fp12_sqr(t3, f); - sm9_fp12_sqr(t3, t3); - sm9_fp12_mul(t0, t0, t3); - sm9_fp12_sqr(t2, t2); - sm9_fp12_mul(t2, t2, t1); - sm9_fp12_frobenius2(t1, f); - sm9_fp12_mul(t1, t1, t2); - - sm9_fp12_pow(t2, t1, a2); - sm9_fp12_mul(t0, t2, t0); - sm9_fp12_frobenius3(t1, f); - sm9_fp12_mul(t1, t1, t0); - - sm9_fp12_copy(r, t1); -} - -void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f) -{ - sm9_fp12_t t0; - sm9_fp12_t t1; - - sm9_fp12_frobenius6(t0, f); - sm9_fp12_inv(t1, f); - sm9_fp12_mul(t0, t0, t1); - sm9_fp12_frobenius2(t1, t0); - sm9_fp12_mul(t0, t0, t1); - sm9_final_exponent_hard_part(t0, t0); - - sm9_fp12_copy(r, t0); -} - -void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P) { - const char *abits = "00100000000000000000000000000000000000010000101011101100100111110"; - - SM9_TWIST_POINT _T, *T = &_T; - SM9_TWIST_POINT _Q1, *Q1 = &_Q1; - SM9_TWIST_POINT _Q2, *Q2 = &_Q2; - - sm9_fp12_t f_num; - sm9_fp12_t f_den; - sm9_fp12_t g_num; - sm9_fp12_t g_den; - int i; - - sm9_twist_point_copy(T, Q); - - sm9_fp12_set_one(f_num); - sm9_fp12_set_one(f_den); - - for (i = 0; i < strlen(abits); i++) { - - sm9_fp12_sqr(f_num, f_num); - sm9_fp12_sqr(f_den, f_den); - sm9_eval_g_tangent(g_num, g_den, T, P); - sm9_fp12_mul(f_num, f_num, g_num); - sm9_fp12_mul(f_den, f_den, g_den); - - sm9_twist_point_dbl(T, T); - - if (abits[i] == '1') { - sm9_eval_g_line(g_num, g_den, T, Q, P); - sm9_fp12_mul(f_num, f_num, g_num); - sm9_fp12_mul(f_den, f_den, g_den); - sm9_twist_point_add_full(T, T, Q); - } - } - - sm9_twist_point_pi1(Q1, Q); - sm9_twist_point_neg_pi2(Q2, Q); - - sm9_eval_g_line(g_num, g_den, T, Q1, P); - sm9_fp12_mul(f_num, f_num, g_num); - sm9_fp12_mul(f_den, f_den, g_den); - sm9_twist_point_add_full(T, T, Q1); - - sm9_eval_g_line(g_num, g_den, T, Q2, P); - sm9_fp12_mul(f_num, f_num, g_num); - sm9_fp12_mul(f_den, f_den, g_den); - sm9_twist_point_add_full(T, T, Q2); - - sm9_fp12_inv(f_den, f_den); - sm9_fp12_mul(r, f_num, f_den); - - sm9_final_exponent(r, r); -} - -void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) -{ - sm9_bn_add(r, a, b); - if (sm9_bn_cmp(r, SM9_N) >= 0) - return sm9_bn_sub(r, r, SM9_N); -} - -void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) -{ - if (sm9_bn_cmp(a, b) >= 0) { - sm9_bn_sub(r, a, b); - } else { - sm9_bn_t t; - sm9_bn_sub(t, SM9_N, b); - sm9_bn_add(r, t, a); - } -} - -void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) -{ - uint64_t s[18]; - sm9_barrett_bn_t zh, zl, q; - uint64_t w; - int i, j; - - /* z = a * b */ - for (i = 0; i < 8; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + a[i] * b[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - - /* zl = z mod (2^32)^9 = z[0..8] - * zh = z // (2^32)^7 = z[7..15] */ - for (i = 0; i < 9; i++) { - zl[i] = s[i]; - zh[i] = s[7 + i]; - } - - /* q = zh * mu // (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 9; j++) { - w += s[i + j] + zh[i] * SM9_MU_N[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 9] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[9 + i]; - } - - /* q = q * n mod (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + q[i] * SM9_N[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[i]; - } - - /* r = zl - q (mod (2^32)^9) */ - - if (sm9_barrett_bn_cmp(zl, q)) { - sm9_barrett_bn_sub(zl, zl, q); - } else { - sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; - sm9_barrett_bn_sub(q, c, q); - sm9_barrett_bn_add(zl, q, zl); - } - - - for (i = 0; i < 8; i++) { - r[i] = zl[i]; - } - - r[7] += (zl[8] << 32); - - /* while r >= n do: r = r - n */ - while (sm9_bn_cmp(r, SM9_N) >= 0) { - sm9_bn_sub(r, r, SM9_N); - } -} - -void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e) -{ - sm9_fn_t t; - uint32_t w; - int i, j; - - assert(sm9_bn_cmp(e, SM9_N_MINUS_ONE) < 0); - - sm9_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm9_fn_mul(t, t, t); - if (w & 0x80000000) - sm9_fn_mul(t, t, a); - w <<= 1; - } - } - sm9_bn_copy(r, t); -} - -void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a) -{ - sm9_fn_t e; - sm9_bn_sub(e, SM9_N, SM9_TWO); - sm9_fn_pow(r, a, e); -} - - -// for H1() and H2() -// h = (Ha mod (n-1)) + 1; h in [1, n-1], n is the curve order, Ha is 40 bytes from hash -void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40]) -{ - uint64_t s[18] = {0}; - sm9_barrett_bn_t zh, zl, q; - uint64_t w; - int i, j; - - /* s = Ha -> int */ - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 4; j++) { - s[i] <<= 8; - s[i] += Ha[4 * (9-i) + j]; - } - } - - /* zl = z mod (2^32)^9 = z[0..8] - * zh = z // (2^32)^7 = z[7..15] */ - for (i = 0; i < 9; i++) { - zl[i] = s[i]; - zh[i] = s[7 + i]; - } - - /* q = zh * mu // (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 9; j++) { - w += s[i + j] + zh[i] * SM9_MU_N_MINUS_ONE[j]; // - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 9] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[9 + i]; - } - - /* q = q * p mod (2^32)^9 */ - for (i = 0; i < 18; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + q[i] * SM9_N_MINUS_ONE[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[i]; - } - - /* h = zl - q (mod (2^32)^9) */ - - if (sm9_barrett_bn_cmp(zl, q)) { - sm9_barrett_bn_sub(zl, zl, q); - } else { - sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; - sm9_barrett_bn_sub(q, c, q); - sm9_barrett_bn_add(zl, q, zl); - } - - for (i = 0; i < 8; i++) { - h[i] = zl[i]; - } - - h[7] += (zl[8] << 32); - - /* while h >= (n-1) do: h = h - (n-1) */ - while (sm9_bn_cmp(h, SM9_N_MINUS_ONE) >= 0) { - sm9_bn_sub(h, h, SM9_N_MINUS_ONE); - } - - sm9_fn_add(h, h, SM9_ONE); -} - -void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12]) -{ - sm9_fp4_to_bytes(a[2], buf); - sm9_fp4_to_bytes(a[1], buf + 32 * 4); - sm9_fp4_to_bytes(a[0], buf + 32 * 8); -} - -int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32]) -{ - sm9_bn_from_bytes(a, in); - return 1; -} - -int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65]) -{ - sm9_fp_t x; - sm9_fp_t y; - sm9_point_get_xy(P, x, y); - octets[0] = 0x04; - sm9_bn_to_bytes(x, octets + 1); - sm9_bn_to_bytes(y, octets + 32 + 1); - return 1; -} - -int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65]) -{ - if (octets[0] != 0x04) { - error_print(); - return -1; - } - memset(P, 0, sizeof(*P)); - sm9_bn_from_bytes(P->X, octets + 1); - sm9_bn_from_bytes(P->Y, octets + 32 + 1); - sm9_fp_set_one(P->Z); - if (!sm9_point_is_on_curve(P)) { - error_print(); - return -1; - } - return 1; -} - -int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129]) -{ - octets[0] = 0x04; - sm9_fp2_t x; - sm9_fp2_t y; - sm9_twist_point_get_xy(P, x, y); - sm9_fp2_to_bytes(x, octets + 1); - sm9_fp2_to_bytes(y, octets + 32 * 2 + 1); - return 1; -} - -int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129]) -{ - assert(octets[0] == 0x04); - sm9_fp2_from_bytes(P->X, octets + 1); - sm9_fp2_from_bytes(P->Y, octets + 32 * 2 + 1); - sm9_fp2_set_one(P->Z); - if (!sm9_twist_point_is_on_curve(P)) return -1; - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const sm9_bn_t SM9_ZERO = {0,0,0,0,0,0,0,0}; +const sm9_bn_t SM9_ONE = {1,0,0,0,0,0,0,0}; +static const sm9_bn_t SM9_TWO = {2,0,0,0,0,0,0,0}; +static const sm9_bn_t SM9_FIVE = {5,0,0,0,0,0,0,0}; + + +// p = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d +// n = b640000002a3a6f1d603ab4ff58ec74449f2934b18ea8beee56ee19cd69ecf25 +// mu_p = 2^512 // p = 167980e0beb5759a655f73aebdcd1312af2665f6d1e36081c71188f90d5c22146 +// mu_n = 2^512 // n +const sm9_bn_t SM9_P = {0xe351457d, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; +const sm9_bn_t SM9_N = {0xd69ecf25, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; +static const sm9_bn_t SM9_P_MINUS_ONE = {0xe351457c, 0xe56f9b27, 0x1a7aeedb, 0x21f2934b, 0xf58ec745, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; +static const sm9_bn_t SM9_N_MINUS_ONE = {0xd69ecf24, 0xe56ee19c, 0x18ea8bee, 0x49f2934b, 0xf58ec744, 0xd603ab4f, 0x02a3a6f1, 0xb6400000}; +static const sm9_barrett_bn_t SM9_MU_P = {0xd5c22146, 0x71188f90, 0x1e36081c, 0xf2665f6d, 0xdcd1312a, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; +static const sm9_barrett_bn_t SM9_MU_N = {0xdfc97c2f, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; +static const sm9_barrett_bn_t SM9_MU_N_MINUS_ONE = {0xdfc97c31, 0x74df4fd4, 0xc9c073b0, 0x9c95d85e, 0xdcd1312c, 0x55f73aeb, 0xeb5759a6, 0x67980e0b, 0x00000001}; + + +// P1.X 0x93DE051D62BF718FF5ED0704487D01D6E1E4086909DC3280E8C4E4817C66DDDD +// P1.Y 0x21FE8DDA4F21E607631065125C395BBC1C1C00CBFA6024350C464CD70A3EA616 +const SM9_POINT _SM9_P1 = { + {0x7c66dddd, 0xe8c4e481, 0x09dc3280, 0xe1e40869, 0x487d01d6, 0xf5ed0704, 0x62bf718f, 0x93de051d}, + {0x0a3ea616, 0x0c464cd7, 0xfa602435, 0x1c1c00cb, 0x5c395bbc, 0x63106512, 0x4f21e607, 0x21fe8dda}, + {1,0,0,0,0,0,0,0} +}; +const SM9_POINT *SM9_P1 = &_SM9_P1; + + +/* + X : [0x3722755292130b08d2aab97fd34ec120ee265948d19c17abf9b7213baf82d65bn, + 0x85aef3d078640c98597b6027b441a01ff1dd2c190f5e93c454806c11d8806141n], + Y : [0xa7cf28d519be3da65f3170153d278ff247efba98a71a08116215bba5c999a7c7n, + 0x17509b092e845c1266ba0d262cbee6ed0736a96fa347c8bd856dc76b84ebeb96n], + Z : [1n, 0n], +*/ +const SM9_TWIST_POINT _SM9_P2 = { + {{0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948, 0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552}, + {0xD8806141, 0x54806C11, 0x0F5E93C4, 0xF1DD2C19, 0xB441A01F, 0x597B6027, 0x78640C98, 0x85AEF3D0}}, + {{0xC999A7C7, 0x6215BBA5, 0xA71A0811, 0x47EFBA98, 0x3D278FF2, 0x5F317015, 0x19BE3DA6, 0xA7CF28D5}, + {0x84EBEB96, 0x856DC76B, 0xA347C8BD, 0x0736A96F, 0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09}}, + {{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}, +}; +const SM9_TWIST_POINT *SM9_P2 = &_SM9_P2; + + +const SM9_TWIST_POINT _SM9_Ppubs = { + {{0x96EA5E32, 0x8F14D656, 0x386A92DD, 0x414D2177, 0x24A3B573, 0x6CE843ED, 0x152D1F78, 0x29DBA116}, + {0x1B94C408, 0x0AB1B679, 0x5E392CFB, 0x1CE0711C, 0x41B56501, 0xE48AFF4B, 0x3084F733, 0x9F64080B}}, + {{0xB4E3216D, 0x0E75C05F, 0x5CDFF073, 0x1006E85F, 0xB7A46F74, 0x1A7CE027, 0xDDA532DA, 0x41E00A53}, + {0xD0EF1C25, 0xE89E1408, 0x1A77F335, 0xAD3E2FDB, 0x47E3A0CB, 0xB57329F4, 0xABEA0112, 0x69850938}}, + {{1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}, +}; +const SM9_TWIST_POINT *SM9_Ppubs = &_SM9_Ppubs; + + +void sm9_bn_to_bytes(const sm9_bn_t a, uint8_t out[32]) +{ + int i; + for (i = 7; i >= 0; i--) { + PUTU32(out, (uint32_t)a[i]); + out += sizeof(uint32_t); + } +} + +void sm9_bn_from_bytes(sm9_bn_t r, const uint8_t in[32]) +{ + int i; + for (i = 7; i >= 0; i--) { + r[i] = GETU32(in); + in += sizeof(uint32_t); + } +} + +int sm9_bn_from_hex(sm9_bn_t r, const char hex[64]) +{ + uint8_t buf[32]; + size_t len; + if (hex_to_bytes(hex, 64, buf, &len) < 0) { + return -1; + } + sm9_bn_from_bytes(r, buf); + return 1; +} + +void sm9_bn_to_hex(const sm9_bn_t a, char hex[64]) +{ + int i; + for (i = 7; i >= 0; i--) { + (void)sprintf(hex + 8*(7-i), "%08x", (uint32_t)a[i]); + //hex += 8; + } +} + +void sm9_print_bn(const char *prefix, const sm9_bn_t a) +{ + char hex[65] = {0}; + sm9_bn_to_hex(a, hex); + printf("%s\n%s\n", prefix, hex); +} + +void sm9_bn_to_bits(const sm9_bn_t a, char bits[256]) +{ + int i, j; + for (i = 7; i >= 0; i--) { + uint32_t w = a[i]; + for (j = 0; j < 32; j++) { + *bits++ = (w & 0x80000000) ? '1' : '0'; + w <<= 1; + } + } +} + +int sm9_bn_cmp(const sm9_bn_t a, const sm9_bn_t b) +{ + int i; + for (i = 7; i >= 0; i--) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + return 0; +} + + + + +void sm9_bn_copy(sm9_bn_t r, const sm9_bn_t a) +{ + memcpy(r, a, sizeof(sm9_bn_t)); +} + +void sm9_bn_set_word(sm9_bn_t r, uint32_t a) +{ + sm9_bn_set_zero(r); + r[0] = a; +} + +void sm9_bn_add(sm9_bn_t r, const sm9_bn_t a, const sm9_bn_t b) +{ + int i; + r[0] = a[0] + b[0]; + for (i = 1; i < 8; i++) { + r[i] = a[i] + b[i] + (r[i-1] >> 32); + } + for (i = 0; i < 7; i++) { + r[i] &= 0xffffffff; + } +} + +void sm9_bn_sub(sm9_bn_t ret, const sm9_bn_t a, const sm9_bn_t b) +{ + int i; + sm9_bn_t r; + r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; + for (i = 1; i < 7; i++) { + r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); + r[i - 1] &= 0xffffffff; + } + r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; + r[i - 1] &= 0xffffffff; + sm9_bn_copy(ret, r); +} + +int sm9_bn_rand_range(sm9_bn_t r, const sm9_bn_t range) +{ + FILE *fp; + uint8_t buf[256]; + + fp = fopen("/dev/urandom", "rb"); + do { + fread(buf, 1, 256, fp); + sm9_bn_from_bytes(r, buf); + } while (sm9_bn_cmp(r, range) >= 0); + fclose(fp); + return 1; +} + +int sm9_bn_equ(const sm9_bn_t a, const sm9_bn_t b) +{ + int i; + for (i = 0; i < 8; i++) { + if (a[i] != b[i]) + return 0; + } + return 1; +} + +void sm9_fp_add(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) +{ + sm9_bn_add(r, a, b); + if (sm9_bn_cmp(r, SM9_P) >= 0) + return sm9_bn_sub(r, r, SM9_P); +} + +void sm9_fp_sub(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) +{ + if (sm9_bn_cmp(a, b) >= 0) { + sm9_bn_sub(r, a, b); + } else { + sm9_bn_t t; + sm9_bn_sub(t, SM9_P, b); + sm9_bn_add(r, t, a); + } +} + +void sm9_fp_dbl(sm9_fp_t r, const sm9_fp_t a) +{ + sm9_fp_add(r, a, a); +} + +void sm9_fp_tri(sm9_fp_t r, const sm9_fp_t a) +{ + sm9_fp_t t; + sm9_fp_dbl(t, a); + sm9_fp_add(r, t, a); +} + +void sm9_fp_div2(sm9_fp_t r, const sm9_fp_t a) +{ + int i; + sm9_bn_copy(r, a); + if (r[0] & 0x01) { + sm9_bn_add(r, r, SM9_P); + } + for (i = 0; i < 7; i++) { + r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); + } + r[i] >>= 1; +} + +void sm9_fp_neg(sm9_fp_t r, const sm9_fp_t a) +{ + if (sm9_bn_is_zero(a)) { + sm9_bn_copy(r, a); + } else { + sm9_bn_sub(r, SM9_P, a); + } +} + +int sm9_bn_print(FILE *fp, int fmt, int ind, const char *label, const sm9_bn_t a) +{ + uint8_t buf[32]; + sm9_bn_to_bytes(a, buf); + format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); + return 1; +} + +int sm9_barrett_bn_cmp(const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) +{ + int i; + for (i = 8; i >= 0; i--) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + return 0; +} + +void sm9_barrett_bn_add(sm9_barrett_bn_t r, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) +{ + int i; + r[0] = a[0] + b[0]; + for (i = 1; i < 9; i++) { + r[i] = a[i] + b[i] + (r[i-1] >> 32); + } + for (i = 0; i < 8; i++) { + r[i] &= 0xffffffff; + } +} + +void sm9_barrett_bn_sub(sm9_barrett_bn_t ret, const sm9_barrett_bn_t a, const sm9_barrett_bn_t b) +{ + sm9_barrett_bn_t r; + int i; + r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; + for (i = 1; i < 8; i++) { + r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); + r[i - 1] &= 0xffffffff; + } + r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; + r[i - 1] &= 0xffffffff; + for (i = 0; i < 9; i++) { + ret[i] = r[i]; + } +} + +void sm9_fp_mul(sm9_fp_t r, const sm9_fp_t a, const sm9_fp_t b) +{ + uint64_t s[18]; + sm9_barrett_bn_t zh, zl, q; + uint64_t w; + int i, j; + + /* z = a * b */ + for (i = 0; i < 8; i++) { + s[i] = 0; + } + for (i = 0; i < 8; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + a[i] * b[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + + /* zl = z mod (2^32)^9 = z[0..8] + * zh = z // (2^32)^7 = z[7..15] */ + for (i = 0; i < 9; i++) { + zl[i] = s[i]; + zh[i] = s[7 + i]; + } + + /* q = zh * mu // (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 9; j++) { + w += s[i + j] + zh[i] * SM9_MU_P[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 9] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[9 + i]; + } + + /* q = q * p mod (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + q[i] * SM9_P[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[i]; + } + + /* r = zl - q (mod (2^32)^9) */ + + if (sm9_barrett_bn_cmp(zl, q)) { + sm9_barrett_bn_sub(zl, zl, q); + } else { + sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; + sm9_barrett_bn_sub(q, c, q); + sm9_barrett_bn_add(zl, q, zl); + } + + + for (i = 0; i < 8; i++) { + r[i] = zl[i]; + } + + r[7] += (zl[8] << 32); + + /* while r >= p do: r = r - p */ + while (sm9_bn_cmp(r, SM9_P) >= 0) { + + sm9_bn_sub(r, r, SM9_P); + } +} + +void sm9_fp_sqr(sm9_fp_t r, const sm9_fp_t a) +{ + sm9_fp_mul(r, a, a); +} + +void sm9_fp_pow(sm9_fp_t r, const sm9_fp_t a, const sm9_bn_t e) +{ + sm9_fp_t t; + uint32_t w; + int i, j; + + assert(sm9_bn_cmp(e, SM9_P_MINUS_ONE) < 0); + + sm9_bn_set_one(t); + for (i = 7; i >= 0; i--) { + w = (uint32_t)e[i]; + for (j = 0; j < 32; j++) { + sm9_fp_sqr(t, t); + if (w & 0x80000000) + sm9_fp_mul(t, t, a); + w <<= 1; + } + } + sm9_bn_copy(r, t); +} + +void sm9_fp_inv(sm9_fp_t r, const sm9_fp_t a) +{ + sm9_fp_t e; + sm9_bn_sub(e, SM9_P, SM9_TWO); + sm9_fp_pow(r, a, e); +} + +int sm9_fp_from_bytes(sm9_fp_t r, const uint8_t buf[32]) +{ + sm9_bn_from_bytes(r, buf); + if (sm9_bn_cmp(r, SM9_P) >= 0) { + error_print(); + return -1; + } + return 1; +} + +int sm9_fp_from_hex(sm9_fp_t r, const char hex[64]) +{ + if (sm9_bn_from_hex(r, hex) != 1) { + error_print(); + return -1; + } + if (sm9_bn_cmp(r, SM9_P) >= 0) { + error_print(); + return -1; + } + return 1; +} + + +const sm9_fp2_t SM9_FP2_ZERO = {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; +const sm9_fp2_t SM9_FP2_ONE = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; +const sm9_fp2_t SM9_FP2_U = {{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}}; +static const sm9_fp2_t SM9_FP2_5U = {{0,0,0,0,0,0,0,0},{5,0,0,0,0,0,0,0}}; + +int sm9_fp2_equ(const sm9_fp2_t a, const sm9_fp2_t b) +{ + return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp2_t)) == 0); +} + +void sm9_fp2_copy(sm9_fp2_t r, const sm9_fp2_t a) +{ + memcpy(r, a, sizeof(sm9_fp2_t)); +} + +int sm9_fp2_rand(sm9_fp2_t r) +{ + if (sm9_fp_rand(r[0]) != 1 + || sm9_fp_rand(r[1]) != 1) { + error_print(); + return -1; + } + return 1; +} + +void sm9_fp2_to_bytes(const sm9_fp2_t a, uint8_t buf[64]) +{ + sm9_fp_to_bytes(a[1], buf); + sm9_fp_to_bytes(a[0], buf + 32); +} + +int sm9_fp2_from_bytes(sm9_fp2_t r, const uint8_t buf[64]) +{ + if (sm9_fp_from_bytes(r[1], buf) != 1 + || sm9_fp_from_bytes(r[0], buf + 32) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_fp2_from_hex(sm9_fp2_t r, const char hex[129]) +{ + if (sm9_fp_from_hex(r[1], hex) != 1 + || sm9_fp_from_hex(r[0], hex + 65) != 1) { + error_print(); + return -1; + } + /* + if (hex[64] != SM9_HEX_SEP) { + error_print(); + return -1; + } + */ + return 1; +} + +void sm9_fp2_to_hex(const sm9_fp2_t a, char hex[129]) +{ + sm9_fp_to_hex(a[1], hex); + hex[64] = SM9_HEX_SEP; + sm9_fp_to_hex(a[0], hex + 65); +} + +void sm9_fp2_set_fp(sm9_fp2_t r, const sm9_fp_t a) +{ + sm9_fp_copy(r[0], a); + sm9_fp_set_zero(r[1]); +} + +void sm9_fp2_set(sm9_fp2_t r, const sm9_fp_t a0, const sm9_fp_t a1) +{ + sm9_fp_copy(r[0], a0); + sm9_fp_copy(r[1], a1); +} + +void sm9_fp2_add(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) +{ + sm9_fp_add(r[0], a[0], b[0]); + sm9_fp_add(r[1], a[1], b[1]); +} + +void sm9_fp2_dbl(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_dbl(r[0], a[0]); + sm9_fp_dbl(r[1], a[1]); +} + +void sm9_fp2_tri(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_tri(r[0], a[0]); + sm9_fp_tri(r[1], a[1]); +} + +void sm9_fp2_sub(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) +{ + sm9_fp_sub(r[0], a[0], b[0]); + sm9_fp_sub(r[1], a[1], b[1]); +} + +void sm9_fp2_neg(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_neg(r[0], a[0]); + sm9_fp_neg(r[1], a[1]); +} + +void sm9_fp2_mul(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) +{ + sm9_fp_t r0, r1, t; + + // r0 = a0 * b0 - 2 * a1 * b1 + sm9_fp_mul(r0, a[0], b[0]); + sm9_fp_mul(t, a[1], b[1]); + sm9_fp_dbl(t, t); + sm9_fp_sub(r0, r0, t); + + // r1 = a0 * b1 + a1 * b0 + sm9_fp_mul(r1, a[0], b[1]); + sm9_fp_mul(t, a[1], b[0]); + sm9_fp_add(r1, r1, t); + + sm9_fp_copy(r[0], r0); + sm9_fp_copy(r[1], r1); +} + +void sm9_fp2_mul_u(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) +{ + sm9_fp_t r0, r1, t; + + // r0 = -2 * (a0 * b1 + a1 * b0) + sm9_fp_mul(r0, a[0], b[1]); + sm9_fp_mul(t, a[1], b[0]); + sm9_fp_add(r0, r0, t); + sm9_fp_dbl(r0, r0); + sm9_fp_neg(r0, r0); + + // r1 = a0 * b0 - 2 * a1 * b1 + sm9_fp_mul(r1, a[0], b[0]); + sm9_fp_mul(t, a[1], b[1]); + sm9_fp_dbl(t, t); + sm9_fp_sub(r1, r1, t); + + sm9_fp_copy(r[0], r0); + sm9_fp_copy(r[1], r1); +} + +void sm9_fp2_mul_fp(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp_t k) +{ + sm9_fp_mul(r[0], a[0], k); + sm9_fp_mul(r[1], a[1], k); +} + +void sm9_fp2_sqr(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_t r0, r1, t; + + // a0^2 - 2 * a1^2 + sm9_fp_sqr(r0, a[0]); + sm9_fp_sqr(t, a[1]); + sm9_fp_dbl(t, t); + sm9_fp_sub(r0, r0, t); + + // r1 = 2 * a0 * a1 + sm9_fp_mul(r1, a[0], a[1]); + sm9_fp_dbl(r1, r1); + + sm9_bn_copy(r[0], r0); + sm9_bn_copy(r[1], r1); +} + +void sm9_fp2_sqr_u(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_t r0, r1, t; + + // r0 = -4 * a0 * a1 + sm9_fp_mul(r0, a[0], a[1]); + sm9_fp_dbl(r0, r0); + sm9_fp_dbl(r0, r0); + sm9_fp_neg(r0, r0); + + // r1 = a0^2 - 2 * a1^2 + sm9_fp_sqr(r1, a[0]); + sm9_fp_sqr(t, a[1]); + sm9_fp_dbl(t, t); + sm9_fp_sub(r1, r1, t); + + sm9_fp_copy(r[0], r0); + sm9_fp_copy(r[1], r1); + +} + +void sm9_fp2_inv(sm9_fp2_t r, const sm9_fp2_t a) +{ + if (sm9_fp_is_zero(a[0])) { + // r0 = 0 + sm9_fp_set_zero(r[0]); + // r1 = -(2 * a1)^-1 + sm9_fp_dbl(r[1], a[1]); + sm9_fp_inv(r[1], r[1]); + sm9_fp_neg(r[1], r[1]); + + } else if (sm9_fp_is_zero(a[1])) { + /* r1 = 0 */ + sm9_fp_set_zero(r[1]); + /* r0 = a0^-1 */ + sm9_fp_inv(r[0], a[0]); + + } else { + sm9_fp_t k, t; + + // k = (a[0]^2 + 2 * a[1]^2)^-1 + sm9_fp_sqr(k, a[0]); + sm9_fp_sqr(t, a[1]); + sm9_fp_dbl(t, t); + sm9_fp_add(k, k, t); + sm9_fp_inv(k, k); + + // r[0] = a[0] * k + sm9_fp_mul(r[0], a[0], k); + + // r[1] = -a[1] * k + sm9_fp_mul(r[1], a[1], k); + sm9_fp_neg(r[1], r[1]); + } +} + +void sm9_fp2_div(sm9_fp2_t r, const sm9_fp2_t a, const sm9_fp2_t b) +{ + sm9_fp2_t t; + sm9_fp2_inv(t, b); + sm9_fp2_mul(r, a, t); +} + +void sm9_fp2_div2(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_div2(r[0], a[0]); + sm9_fp_div2(r[1], a[1]); +} + +int sm9_fp2_print(FILE *fp, int fmt, int ind, const char *label, const sm9_fp2_t a) +{ + return 1; +} + + +const sm9_fp4_t SM9_FP4_ZERO = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; +const sm9_fp4_t SM9_FP4_ONE = {{{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; +const sm9_fp4_t SM9_FP4_U = {{{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; +const sm9_fp4_t SM9_FP4_V = {{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}}; + +int sm9_fp4_equ(const sm9_fp4_t a, const sm9_fp4_t b) +{ + return (gmssl_secure_memcmp(a, b, sizeof(sm9_fp4_t)) == 0); +} + +int sm9_fp4_rand(sm9_fp4_t r) +{ + if (sm9_fp2_rand(r[1]) != 1 + || sm9_fp2_rand(r[0]) != 1) { + error_print(); + return -1; + } + return 1; +} + +void sm9_fp4_copy(sm9_fp4_t r, const sm9_fp4_t a) +{ + memcpy(r, a, sizeof(sm9_fp4_t)); +} + +void sm9_fp4_to_bytes(const sm9_fp4_t a, uint8_t buf[128]) +{ + sm9_fp2_to_bytes(a[1], buf); + sm9_fp2_to_bytes(a[0], buf + 64); +} + +int sm9_fp4_from_bytes(sm9_fp4_t r, const uint8_t buf[128]) +{ + if (sm9_fp2_from_bytes(r[1], buf) != 1 + || sm9_fp2_from_bytes(r[0], buf + 64) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_fp4_from_hex(sm9_fp4_t r, const char hex[65 * 4]) +{ + if (sm9_fp2_from_hex(r[1], hex) != 1 + || hex[129] != SM9_HEX_SEP + || sm9_fp2_from_hex(r[0], hex + 130) != 1) { + error_print(); + return -1; + } + return 1; +} + +void sm9_fp4_to_hex(const sm9_fp4_t a, char hex[259]) +{ + sm9_fp2_to_hex(a[1], hex); + hex[129] = SM9_HEX_SEP; + sm9_fp2_to_hex(a[0], hex + 130); +} + +void sm9_fp4_set_fp(sm9_fp4_t r, const sm9_fp_t a) +{ + sm9_fp2_set_fp(r[0], a); + sm9_fp2_set_zero(r[1]); +} + +void sm9_fp4_set_fp2(sm9_fp4_t r, const sm9_fp2_t a) +{ + sm9_fp2_copy(r[0], a); + sm9_fp2_set_zero(r[1]); +} + +void sm9_fp4_set(sm9_fp4_t r, const sm9_fp2_t a0, const sm9_fp2_t a1) +{ + sm9_fp2_copy(r[0], a0); + sm9_fp2_copy(r[1], a1); +} + +void sm9_fp4_set_u(sm9_fp4_t r) +{ + sm9_fp2_set_u(r[0]); + sm9_fp2_set_zero(r[1]); +} + +void sm9_fp4_set_v(sm9_fp4_t r) +{ + sm9_fp2_set_zero(r[0]); + sm9_fp2_set_one(r[1]); +} + +void sm9_fp4_add(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) +{ + sm9_fp2_add(r[0], a[0], b[0]); + sm9_fp2_add(r[1], a[1], b[1]); +} + +void sm9_fp4_dbl(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_dbl(r[0], a[0]); + sm9_fp2_dbl(r[1], a[1]); +} + +void sm9_fp4_sub(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) +{ + sm9_fp2_sub(r[0], a[0], b[0]); + sm9_fp2_sub(r[1], a[1], b[1]); +} + +void sm9_fp4_neg(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_neg(r[0], a[0]); + sm9_fp2_neg(r[1], a[1]); +} + +void sm9_fp4_mul(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) +{ + sm9_fp2_t r0, r1, t; + + sm9_fp2_mul(r0, a[0], b[0]); + sm9_fp2_mul_u(t, a[1], b[1]); + sm9_fp2_add(r0, r0, t); + + sm9_fp2_mul(r1, a[0], b[1]); + sm9_fp2_mul(t, a[1], b[0]); + sm9_fp2_add(r1, r1, t); + + sm9_fp2_copy(r[0], r0); + sm9_fp2_copy(r[1], r1); +} + +void sm9_fp4_mul_fp(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp_t k) +{ + sm9_fp2_mul_fp(r[0], a[0], k); + sm9_fp2_mul_fp(r[1], a[1], k); +} + +void sm9_fp4_mul_fp2(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp2_t b0) +{ + sm9_fp2_mul(r[0], a[0], b0); + sm9_fp2_mul(r[1], a[1], b0); +} + +void sm9_fp4_mul_v(sm9_fp4_t r, const sm9_fp4_t a, const sm9_fp4_t b) +{ + sm9_fp2_t r0, r1, t; + + sm9_fp2_mul_u(r0, a[0], b[1]); + sm9_fp2_mul_u(t, a[1], b[0]); + sm9_fp2_add(r0, r0, t); + + sm9_fp2_mul(r1, a[0], b[0]); + sm9_fp2_mul_u(t, a[1], b[1]); + sm9_fp2_add(r1, r1, t); + + sm9_fp2_copy(r[0], r0); + sm9_fp2_copy(r[1], r1); +} + +void sm9_fp4_sqr(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_t r0, r1, t; + + sm9_fp2_sqr(r0, a[0]); + sm9_fp2_sqr_u(t, a[1]); + sm9_fp2_add(r0, r0, t); + + sm9_fp2_mul(r1, a[0], a[1]); + sm9_fp2_dbl(r1, r1); + sm9_fp2_copy(r[0], r0); + sm9_fp2_copy(r[1], r1); +} + +void sm9_fp4_sqr_v(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_t r0, r1, t; + + sm9_fp2_mul_u(t, a[0], a[1]); + sm9_fp2_dbl(r0, t); + + sm9_fp2_sqr(r1, a[0]); + sm9_fp2_sqr_u(t, a[1]); + sm9_fp2_add(r1, r1, t); + + sm9_fp2_copy(r[0], r0); + sm9_fp2_copy(r[1], r1); +} + +void sm9_fp4_inv(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_t r0, r1, k; + + sm9_fp2_sqr_u(k, a[1]); + sm9_fp2_sqr(r0, a[0]); + sm9_fp2_sub(k, k, r0); + sm9_fp2_inv(k, k); + + sm9_fp2_mul(r0, a[0], k); + sm9_fp2_neg(r0, r0); + + sm9_fp2_mul(r1, a[1], k); + + sm9_fp2_copy(r[0], r0); + sm9_fp2_copy(r[1], r1); +} + +void sm9_fp12_copy(sm9_fp12_t r, const sm9_fp12_t a) +{ + sm9_fp4_copy(r[0], a[0]); + sm9_fp4_copy(r[1], a[1]); + sm9_fp4_copy(r[2], a[2]); +} + +int sm9_fp12_rand(sm9_fp12_t r) +{ + if (sm9_fp4_rand(r[0]) != 1 + || sm9_fp4_rand(r[1]) != 1 + || sm9_fp4_rand(r[2]) != 1) { + error_print(); + return -1; + } + return 1; +} + +void sm9_fp12_set_zero(sm9_fp12_t r) +{ + sm9_fp4_set_zero(r[0]); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_one(sm9_fp12_t r) +{ + sm9_fp4_set_one(r[0]); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +int sm9_fp12_is_one(const sm9_fp12_t a) +{ + return sm9_fp4_is_one(a[0]) + && sm9_fp4_is_zero(a[1]) + && sm9_fp4_is_zero(a[2]); +} + +int sm9_fp12_is_zero(const sm9_fp12_t a) +{ + return sm9_fp4_is_zero(a[0]) + && sm9_fp4_is_zero(a[1]) + && sm9_fp4_is_zero(a[2]); +} + +int sm9_fp12_from_hex(sm9_fp12_t r, const char hex[65 * 12 - 1]) +{ + if (sm9_fp4_from_hex(r[2], hex) != 1 + || hex[65 * 4 - 1] != SM9_HEX_SEP + || sm9_fp4_from_hex(r[1], hex + 65 * 4) != 1 + || hex[65 * 4 - 1] != SM9_HEX_SEP + || sm9_fp4_from_hex(r[0], hex + 65 * 8) != 1) { + error_print(); + return -1; + } + return 1; +} + +void sm9_fp12_to_hex(const sm9_fp12_t a, char hex[65 * 12 - 1]) +{ + sm9_fp4_to_hex(a[2], hex); + hex[65 * 4 - 1] = SM9_HEX_SEP; + sm9_fp4_to_hex(a[1], hex + 65 * 4); + hex[65 * 8 - 1] = SM9_HEX_SEP; + sm9_fp4_to_hex(a[0], hex + 65 * 8); +} + +void sm9_fp12_print(const char *prefix, const sm9_fp12_t a) +{ + char hex[65 * 12]; + sm9_fp12_to_hex(a, hex); + printf("%s\n%s\n", prefix, hex); +} + +void sm9_fp12_set(sm9_fp12_t r, const sm9_fp4_t a0, const sm9_fp4_t a1, const sm9_fp4_t a2) +{ + sm9_fp4_copy(r[0], a0); + sm9_fp4_copy(r[1], a1); + sm9_fp4_copy(r[2], a2); +} + +void sm9_fp12_set_fp(sm9_fp12_t r, const sm9_fp_t a) +{ + sm9_fp4_set_fp(r[0], a); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_fp2(sm9_fp12_t r, const sm9_fp2_t a) +{ + sm9_fp4_set_fp2(r[0], a); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_fp4(sm9_fp12_t r, const sm9_fp4_t a) +{ + sm9_fp4_copy(r[0], a); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_u(sm9_fp12_t r) +{ + sm9_fp4_set_u(r[0]); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_v(sm9_fp12_t r) +{ + sm9_fp4_set_v(r[0]); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_w(sm9_fp12_t r) +{ + sm9_fp4_set_zero(r[0]); + sm9_fp4_set_one(r[1]); + sm9_fp4_set_zero(r[2]); +} + +void sm9_fp12_set_w_sqr(sm9_fp12_t r) +{ + sm9_fp4_set_zero(r[0]); + sm9_fp4_set_zero(r[1]); + sm9_fp4_set_one(r[2]); +} + +int sm9_fp12_equ(const sm9_fp12_t a, const sm9_fp12_t b) +{ + return sm9_fp4_equ(a[0], b[0]) + && sm9_fp4_equ(a[1], b[1]) + && sm9_fp4_equ(a[2], b[2]); +} + +void sm9_fp12_add(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) +{ + sm9_fp4_add(r[0], a[0], b[0]); + sm9_fp4_add(r[1], a[1], b[1]); + sm9_fp4_add(r[2], a[2], b[2]); +} + +void sm9_fp12_dbl(sm9_fp12_t r, const sm9_fp12_t a) +{ + sm9_fp4_dbl(r[0], a[0]); + sm9_fp4_dbl(r[1], a[1]); + sm9_fp4_dbl(r[2], a[2]); +} + +void sm9_fp12_tri(sm9_fp12_t r, const sm9_fp12_t a) +{ + sm9_fp12_t t; + sm9_fp12_dbl(t, a); + sm9_fp12_add(r, t, a); +} + +void sm9_fp12_sub(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) +{ + sm9_fp4_sub(r[0], a[0], b[0]); + sm9_fp4_sub(r[1], a[1], b[1]); + sm9_fp4_sub(r[2], a[2], b[2]); +} + +void sm9_fp12_neg(sm9_fp12_t r, const sm9_fp12_t a) +{ + sm9_fp4_neg(r[0], a[0]); + sm9_fp4_neg(r[1], a[1]); + sm9_fp4_neg(r[2], a[2]); +} + +void sm9_fp12_mul(sm9_fp12_t r, const sm9_fp12_t a, const sm9_fp12_t b) +{ + sm9_fp4_t r0, r1, r2, t; + + sm9_fp4_mul(r0, a[0], b[0]); + sm9_fp4_mul_v(t, a[1], b[2]); + sm9_fp4_add(r0, r0, t); + sm9_fp4_mul_v(t, a[2], b[1]); + sm9_fp4_add(r0, r0, t); + + sm9_fp4_mul(r1, a[0], b[1]); + sm9_fp4_mul(t, a[1], b[0]); + sm9_fp4_add(r1, r1, t); + sm9_fp4_mul_v(t, a[2], b[2]); + sm9_fp4_add(r1, r1, t); + + sm9_fp4_mul(r2, a[0], b[2]); + sm9_fp4_mul(t, a[1], b[1]); + sm9_fp4_add(r2, r2, t); + sm9_fp4_mul(t, a[2], b[0]); + sm9_fp4_add(r2, r2, t); + + sm9_fp4_copy(r[0], r0); + sm9_fp4_copy(r[1], r1); + sm9_fp4_copy(r[2], r2); +} + +void sm9_fp12_sqr(sm9_fp12_t r, const sm9_fp12_t a) +{ + sm9_fp4_t r0, r1, r2, t; + + sm9_fp4_sqr(r0, a[0]); + sm9_fp4_mul_v(t, a[1], a[2]); + sm9_fp4_dbl(t, t); + sm9_fp4_add(r0, r0, t); + + sm9_fp4_mul(r1, a[0], a[1]); + sm9_fp4_dbl(r1, r1); + sm9_fp4_sqr_v(t, a[2]); + sm9_fp4_add(r1, r1, t); + + sm9_fp4_mul(r2, a[0], a[2]); + sm9_fp4_dbl(r2, r2); + sm9_fp4_sqr(t, a[1]); + sm9_fp4_add(r2, r2, t); + + sm9_fp4_copy(r[0], r0); + sm9_fp4_copy(r[1], r1); + sm9_fp4_copy(r[2], r2); +} + +void sm9_fp12_inv(sm9_fp12_t r, const sm9_fp12_t a) +{ + if (sm9_fp4_is_zero(a[2])) { + sm9_fp4_t k, t; + + sm9_fp4_sqr(k, a[0]); + sm9_fp4_mul(k, k, a[0]); + sm9_fp4_sqr_v(t, a[1]); + sm9_fp4_mul(t, t, a[1]); + sm9_fp4_add(k, k, t); + sm9_fp4_inv(k, k); + + sm9_fp4_sqr(r[2], a[1]); + sm9_fp4_mul(r[2], r[2], k); + + sm9_fp4_mul(r[1], a[0], a[1]); + sm9_fp4_mul(r[1], r[1], k); + sm9_fp4_neg(r[1], r[1]); + + sm9_fp4_sqr(r[0], a[0]); + sm9_fp4_mul(r[0], r[0], k); + + } else { + sm9_fp4_t t0, t1, t2, t3; + + sm9_fp4_sqr(t0, a[1]); + sm9_fp4_mul(t1, a[0], a[2]); + sm9_fp4_sub(t0, t0, t1); + + sm9_fp4_mul(t1, a[0], a[1]); + sm9_fp4_sqr_v(t2, a[2]); + sm9_fp4_sub(t1, t1, t2); + + sm9_fp4_sqr(t2, a[0]); + sm9_fp4_mul_v(t3, a[1], a[2]); + sm9_fp4_sub(t2, t2, t3); + + sm9_fp4_sqr(t3, t1); + sm9_fp4_mul(r[0], t0, t2); + sm9_fp4_sub(t3, t3, r[0]); + sm9_fp4_inv(t3, t3); + sm9_fp4_mul(t3, a[2], t3); + + sm9_fp4_mul(r[0], t2, t3); + + sm9_fp4_mul(r[1], t1, t3); + sm9_fp4_neg(r[1], r[1]); + + sm9_fp4_mul(r[2], t0, t3); + } +} + +void sm9_fp12_pow(sm9_fp12_t r, const sm9_fp12_t a, const sm9_bn_t k) +{ + char kbits[257]; + sm9_fp12_t t; + int i; + + assert(sm9_bn_cmp(k, SM9_P_MINUS_ONE) < 0); + sm9_fp12_set_zero(t); + + sm9_bn_to_bits(k, kbits); + sm9_fp12_set_one(t); + for (i = 0; i < 256; i++) { + sm9_fp12_sqr(t, t); + if (kbits[i] == '1') { + sm9_fp12_mul(t, t, a); + } + } + sm9_fp12_copy(r, t); +} + +void sm9_fp2_conjugate(sm9_fp2_t r, const sm9_fp2_t a) +{ + sm9_fp_copy(r[0], a[0]); + sm9_fp_neg (r[1], a[1]); + +} + +void sm9_fp2_frobenius(sm9_fp2_t r, const sm9_fp2_t a) +{ + return sm9_fp2_conjugate(r, a); +} + +// beta = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011 +// alpha1 = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698b +// alpha2 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 +// alpha3 = 0x6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011 +// alpha4 = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65333 +// alpha5 = 0x2d40a38cf6983351711e5f99520347cc57d778a9f8ff4c8a4c949c7fa2a96686 +static const sm9_fp2_t SM9_BETA = {{0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5}, {0}}; +static const sm9_fp_t SM9_ALPHA1 = {0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e, 0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58}; +static const sm9_fp_t SM9_ALPHA2 = {0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0, 0x0 }; +static const sm9_fp_t SM9_ALPHA3 = {0xda24d011, 0xf5b21fd3, 0x06dc5177, 0x9f9d4118, 0xee0baf15, 0xf55acc93, 0xdc0a3f2c, 0x6c648de5}; +static const sm9_fp_t SM9_ALPHA4 = {0x7be65333, 0xd5fc1196, 0x4f8b78f4, 0x78027235, 0x02a3a6f2, 0xf3000000, 0x0, 0x0 }; +static const sm9_fp_t SM9_ALPHA5 = {0xa2a96686, 0x4c949c7f, 0xf8ff4c8a, 0x57d778a9, 0x520347cc, 0x711e5f99, 0xf6983351, 0x2d40a38c}; + + +void sm9_fp4_frobenius(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_conjugate(r[0], a[0]); + sm9_fp2_conjugate(r[1], a[1]); + sm9_fp2_mul(r[1], r[1], SM9_BETA); +} + +void sm9_fp4_conjugate(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_copy(r[0], a[0]); + sm9_fp2_neg(r[1], a[1]); +} + +void sm9_fp4_frobenius2(sm9_fp4_t r, const sm9_fp4_t a) +{ + return sm9_fp4_conjugate(r, a); +} + +void sm9_fp4_frobenius3(sm9_fp4_t r, const sm9_fp4_t a) +{ + sm9_fp2_conjugate(r[0], a[0]); + sm9_fp2_conjugate(r[1], a[1]); + sm9_fp2_mul(r[1], r[1], SM9_BETA); + sm9_fp2_neg(r[1], r[1]); +} + +void sm9_fp12_frobenius(sm9_fp12_t r, const sm9_fp12_t x) +{ + const sm9_fp2_t *xa = x[0]; + const sm9_fp2_t *xb = x[1]; + const sm9_fp2_t *xc = x[2]; + sm9_fp4_t ra; + sm9_fp4_t rb; + sm9_fp4_t rc; + + sm9_fp2_conjugate(ra[0], xa[0]); + sm9_fp2_conjugate(ra[1], xa[1]); + sm9_fp2_mul_fp(ra[1], ra[1], SM9_ALPHA3); + + sm9_fp2_conjugate(rb[0], xb[0]); + sm9_fp2_mul_fp(rb[0], rb[0], SM9_ALPHA1); + sm9_fp2_conjugate(rb[1], xb[1]); + sm9_fp2_mul_fp(rb[1], rb[1], SM9_ALPHA4); + + sm9_fp2_conjugate(rc[0], xc[0]); + sm9_fp2_mul_fp(rc[0], rc[0], SM9_ALPHA2); + sm9_fp2_conjugate(rc[1], xc[1]); + sm9_fp2_mul_fp(rc[1], rc[1], SM9_ALPHA5); + + sm9_fp12_set(r, ra, rb, rc); +} + +void sm9_fp12_frobenius2(sm9_fp12_t r, const sm9_fp12_t x) +{ + sm9_fp4_t a; + sm9_fp4_t b; + sm9_fp4_t c; + + sm9_fp4_conjugate(a, x[0]); + sm9_fp4_conjugate(b, x[1]); + sm9_fp4_mul_fp(b, b, SM9_ALPHA2); + sm9_fp4_conjugate(c, x[2]); + sm9_fp4_mul_fp(c, c, SM9_ALPHA4); + + sm9_fp4_copy(r[0], a); + sm9_fp4_copy(r[1], b); + sm9_fp4_copy(r[2], c); +} + +void sm9_fp12_frobenius3(sm9_fp12_t r, const sm9_fp12_t x) +{ + const sm9_fp2_t *xa = x[0]; + const sm9_fp2_t *xb = x[1]; + const sm9_fp2_t *xc = x[2]; + sm9_fp4_t ra; + sm9_fp4_t rb; + sm9_fp4_t rc; + + sm9_fp2_conjugate(ra[0], xa[0]); + sm9_fp2_conjugate(ra[1], xa[1]); + sm9_fp2_mul(ra[1], ra[1], SM9_BETA); + sm9_fp2_neg(ra[1], ra[1]); + + sm9_fp2_conjugate(rb[0], xb[0]); + sm9_fp2_mul(rb[0], rb[0], SM9_BETA); + sm9_fp2_conjugate(rb[1], xb[1]); + + sm9_fp2_conjugate(rc[0], xc[0]); + sm9_fp2_neg(rc[0], rc[0]); + sm9_fp2_conjugate(rc[1], xc[1]); + sm9_fp2_mul(rc[1], rc[1], SM9_BETA); + + sm9_fp4_copy(r[0], ra); + sm9_fp4_copy(r[1], rb); + sm9_fp4_copy(r[2], rc); +} + +void sm9_fp12_frobenius6(sm9_fp12_t r, const sm9_fp12_t x) +{ + sm9_fp4_t a; + sm9_fp4_t b; + sm9_fp4_t c; + + sm9_fp4_copy(a, x[0]); + sm9_fp4_copy(b, x[1]); + sm9_fp4_copy(c, x[2]); + + sm9_fp4_conjugate(a, a); + sm9_fp4_conjugate(b, b); + sm9_fp4_neg(b, b); + sm9_fp4_conjugate(c, c); + + sm9_fp4_copy(r[0], a); + sm9_fp4_copy(r[1], b); + sm9_fp4_copy(r[2], c); +} + + + +void sm9_point_from_hex(SM9_POINT *R, const char hex[65 * 2]) +{ + sm9_bn_from_hex(R->X, hex); + sm9_bn_from_hex(R->Y, hex + 65); + sm9_bn_set_one(R->Z); +} + +int sm9_point_is_at_infinity(const SM9_POINT *P) { + return sm9_fp_is_zero(P->Z); +} + +void sm9_point_set_infinity(SM9_POINT *R) { + sm9_fp_set_one(R->X); + sm9_fp_set_one(R->Y); + sm9_fp_set_zero(R->Z); +} + +void sm9_point_copy(SM9_POINT *R, const SM9_POINT *P) +{ + *R = *P; +} + +void sm9_point_get_xy(const SM9_POINT *P, sm9_fp_t x, sm9_fp_t y) +{ + sm9_fp_t z_inv; + + assert(!sm9_fp_is_zero(P->Z)); + + if (sm9_fp_is_one(P->Z)) { + sm9_fp_copy(x, P->X); + sm9_fp_copy(y, P->Y); + } + + sm9_fp_inv(z_inv, P->Z); + if (y) + sm9_fp_mul(y, P->Y, z_inv); + sm9_fp_sqr(z_inv, z_inv); + sm9_fp_mul(x, P->X, z_inv); + if (y) + sm9_fp_mul(y, y, z_inv); +} + +int sm9_point_equ(const SM9_POINT *P, const SM9_POINT *Q) +{ + sm9_fp_t t1, t2, t3, t4; + sm9_fp_sqr(t1, P->Z); + sm9_fp_sqr(t2, Q->Z); + sm9_fp_mul(t3, P->X, t2); + sm9_fp_mul(t4, Q->X, t1); + if (!sm9_fp_equ(t3, t4)) { + return 0; + } + sm9_fp_mul(t1, t1, P->Z); + sm9_fp_mul(t2, t2, Q->Z); + sm9_fp_mul(t3, P->Y, t2); + sm9_fp_mul(t4, Q->Y, t1); + return sm9_fp_equ(t3, t4); +} + +int sm9_point_is_on_curve(const SM9_POINT *P) +{ + sm9_fp_t t0, t1, t2; + if (sm9_fp_is_one(P->Z)) { + sm9_fp_sqr(t0, P->Y); + sm9_fp_sqr(t1, P->X); + sm9_fp_mul(t1, t1, P->X); + sm9_fp_add(t1, t1, SM9_FIVE); + } else { + sm9_fp_sqr(t0, P->X); + sm9_fp_mul(t0, t0, P->X); + sm9_fp_sqr(t1, P->Z); + sm9_fp_sqr(t2, t1); + sm9_fp_mul(t1, t1, t2); + sm9_fp_mul(t1, t1, SM9_FIVE); + sm9_fp_add(t1, t0, t1); + sm9_fp_sqr(t0, P->Y); + } + if (sm9_fp_equ(t0, t1) != 1) { + error_print(); + return 0; + } + return 1; +} + +void sm9_point_dbl(SM9_POINT *R, const SM9_POINT *P) +{ + const uint64_t *X1 = P->X; + const uint64_t *Y1 = P->Y; + const uint64_t *Z1 = P->Z; + sm9_fp_t X3, Y3, Z3, T1, T2, T3; + + if (sm9_point_is_at_infinity(P)) { + sm9_point_copy(R, P); + return; + } + + sm9_fp_sqr(T2, X1); + sm9_fp_tri(T2, T2); + sm9_fp_dbl(Y3, Y1); + sm9_fp_mul(Z3, Y3, Z1); + sm9_fp_sqr(Y3, Y3); + sm9_fp_mul(T3, Y3, X1); + sm9_fp_sqr(Y3, Y3); + sm9_fp_div2(Y3, Y3); + sm9_fp_sqr(X3, T2); + sm9_fp_dbl(T1, T3); + sm9_fp_sub(X3, X3, T1); + sm9_fp_sub(T1, T3, X3); + sm9_fp_mul(T1, T1, T2); + sm9_fp_sub(Y3, T1, Y3); + + sm9_fp_copy(R->X, X3); + sm9_fp_copy(R->Y, Y3); + sm9_fp_copy(R->Z, Z3); +} + +void sm9_point_add(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q) +{ + sm9_fp_t x; + sm9_fp_t y; + sm9_point_get_xy(Q, x, y); + + const uint64_t *X1 = P->X; + const uint64_t *Y1 = P->Y; + const uint64_t *Z1 = P->Z; + const uint64_t *x2 = x; + const uint64_t *y2 = y; + sm9_fp_t X3, Y3, Z3, T1, T2, T3, T4; + + if (sm9_point_is_at_infinity(Q)) { + sm9_point_copy(R, P); + return; + } + if (sm9_point_is_at_infinity(P)) { + sm9_point_copy(R, Q); + return; + } + + sm9_fp_sqr(T1, Z1); + sm9_fp_mul(T2, T1, Z1); + sm9_fp_mul(T1, T1, x2); + sm9_fp_mul(T2, T2, y2); + sm9_fp_sub(T1, T1, X1); + sm9_fp_sub(T2, T2, Y1); + + if (sm9_fp_is_zero(T1)) { + if (sm9_fp_is_zero(T2)) { + sm9_point_dbl(R, Q); + return; + } else { + sm9_point_set_infinity(R); + return; + } + } + + sm9_fp_mul(Z3, Z1, T1); + sm9_fp_sqr(T3, T1); + sm9_fp_mul(T4, T3, T1); + sm9_fp_mul(T3, T3, X1); + sm9_fp_dbl(T1, T3); + sm9_fp_sqr(X3, T2); + sm9_fp_sub(X3, X3, T1); + sm9_fp_sub(X3, X3, T4); + sm9_fp_sub(T3, T3, X3); + sm9_fp_mul(T3, T3, T2); + sm9_fp_mul(T4, T4, Y1); + sm9_fp_sub(Y3, T3, T4); + + sm9_fp_copy(R->X, X3); + sm9_fp_copy(R->Y, Y3); + sm9_fp_copy(R->Z, Z3); +} + +void sm9_point_neg(SM9_POINT *R, const SM9_POINT *P) +{ + sm9_fp_copy(R->X, P->X); + sm9_fp_neg(R->Y, P->Y); + sm9_fp_copy(R->Z, P->Z); +} + +void sm9_point_sub(SM9_POINT *R, const SM9_POINT *P, const SM9_POINT *Q) +{ + SM9_POINT _T, *T = &_T; + sm9_point_neg(T, Q); + sm9_point_add(R, P, T); +} + +void sm9_point_mul(SM9_POINT *R, const sm9_bn_t k, const SM9_POINT *P) +{ + char kbits[257]; + SM9_POINT _Q, *Q = &_Q; + int i; + + sm9_bn_to_bits(k, kbits); + sm9_point_set_infinity(Q); + for (i = 0; i < 256; i++) { + sm9_point_dbl(Q, Q); + if (kbits[i] == '1') { + sm9_point_add(Q, Q, P); + } + } + sm9_point_copy(R, Q); +} + +void sm9_point_mul_generator(SM9_POINT *R, const sm9_bn_t k) +{ + sm9_point_mul(R, k, SM9_P1); +} + + +int sm9_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_POINT *P) +{ + uint8_t buf[65]; + sm9_point_to_uncompressed_octets(P, buf); + format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); + return 1; +} + +int sm9_twist_point_print(FILE *fp, int fmt, int ind, const char *label, const SM9_TWIST_POINT *P) +{ + uint8_t buf[129]; + sm9_twist_point_to_uncompressed_octets(P, buf); + format_bytes(fp, fmt, ind, label, buf, sizeof(buf)); + return 1; +} + +void sm9_twist_point_from_hex(SM9_TWIST_POINT *R, const char hex[65 * 4]) +{ + sm9_fp2_from_hex(R->X, hex); + sm9_fp2_from_hex(R->Y, hex + 65 * 2); + sm9_fp2_set_one(R->Z); +} + +int sm9_twist_point_is_at_infinity(const SM9_TWIST_POINT *P) +{ + return sm9_fp2_is_zero(P->Z); +} + +void sm9_twist_point_set_infinity(SM9_TWIST_POINT *R) +{ + sm9_fp2_set_one(R->X); + sm9_fp2_set_one(R->Y); + sm9_fp2_set_zero(R->Z); +} + +void sm9_twist_point_get_xy(const SM9_TWIST_POINT *P, sm9_fp2_t x, sm9_fp2_t y) +{ + sm9_fp2_t z_inv; + + assert(!sm9_fp2_is_zero(P->Z)); + + if (sm9_fp2_is_one(P->Z)) { + sm9_fp2_copy(x, P->X); + sm9_fp2_copy(y, P->Y); + } + + sm9_fp2_inv(z_inv, P->Z); + if (y) + sm9_fp2_mul(y, P->Y, z_inv); + sm9_fp2_sqr(z_inv, z_inv); + sm9_fp2_mul(x, P->X, z_inv); + if (y) + sm9_fp2_mul(y, y, z_inv); +} + + +int sm9_twist_point_equ(const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) +{ + sm9_fp2_t t1, t2, t3, t4; + + sm9_fp2_sqr(t1, P->Z); + sm9_fp2_sqr(t2, Q->Z); + sm9_fp2_mul(t3, P->X, t2); + sm9_fp2_mul(t4, Q->X, t1); + if (!sm9_fp2_equ(t3, t4)) { + return 0; + } + sm9_fp2_mul(t1, t1, P->Z); + sm9_fp2_mul(t2, t2, Q->Z); + sm9_fp2_mul(t3, P->Y, t2); + sm9_fp2_mul(t4, Q->Y, t1); + return sm9_fp2_equ(t3, t4); +} + +int sm9_twist_point_is_on_curve(const SM9_TWIST_POINT *P) +{ + sm9_fp2_t t0, t1, t2; + + if (sm9_fp2_is_one(P->Z)) { + sm9_fp2_sqr(t0, P->Y); + sm9_fp2_sqr(t1, P->X); + sm9_fp2_mul(t1, t1, P->X); + sm9_fp2_add(t1, t1, SM9_FP2_5U); + + } else { + sm9_fp2_sqr(t0, P->X); + sm9_fp2_mul(t0, t0, P->X); + sm9_fp2_sqr(t1, P->Z); + sm9_fp2_sqr(t2, t1); + sm9_fp2_mul(t1, t1, t2); + sm9_fp2_mul(t1, t1, SM9_FP2_5U); + sm9_fp2_add(t1, t0, t1); + sm9_fp2_sqr(t0, P->Y); + } + + return sm9_fp2_equ(t0, t1); +} + +void sm9_twist_point_neg(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) +{ + sm9_fp2_copy(R->X, P->X); + sm9_fp2_neg(R->Y, P->Y); + sm9_fp2_copy(R->Z, P->Z); +} + +void sm9_twist_point_dbl(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) +{ + const sm9_fp_t *X1 = P->X; + const sm9_fp_t *Y1 = P->Y; + const sm9_fp_t *Z1 = P->Z; + sm9_fp2_t X3, Y3, Z3, T1, T2, T3; + + if (sm9_twist_point_is_at_infinity(P)) { + sm9_twist_point_copy(R, P); + return; + } + sm9_fp2_sqr(T2, X1); + sm9_fp2_tri(T2, T2); + sm9_fp2_dbl(Y3, Y1); + sm9_fp2_mul(Z3, Y3, Z1); + sm9_fp2_sqr(Y3, Y3); + sm9_fp2_mul(T3, Y3, X1); + sm9_fp2_sqr(Y3, Y3); + sm9_fp2_div2(Y3, Y3); + sm9_fp2_sqr(X3, T2); + sm9_fp2_dbl(T1, T3); + sm9_fp2_sub(X3, X3, T1); + sm9_fp2_sub(T1, T3, X3); + sm9_fp2_mul(T1, T1, T2); + sm9_fp2_sub(Y3, T1, Y3); + + sm9_fp2_copy(R->X, X3); + sm9_fp2_copy(R->Y, Y3); + sm9_fp2_copy(R->Z, Z3); +} + +void sm9_twist_point_add(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) +{ + const sm9_fp_t *X1 = P->X; + const sm9_fp_t *Y1 = P->Y; + const sm9_fp_t *Z1 = P->Z; + const sm9_fp_t *x2 = Q->X; + const sm9_fp_t *y2 = Q->Y; + sm9_fp2_t X3, Y3, Z3, T1, T2, T3, T4; + + if (sm9_twist_point_is_at_infinity(Q)) { + sm9_twist_point_copy(R, P); + return; + } + if (sm9_twist_point_is_at_infinity(P)) { + sm9_twist_point_copy(R, Q); + return; + } + + sm9_fp2_sqr(T1, Z1); + sm9_fp2_mul(T2, T1, Z1); + sm9_fp2_mul(T1, T1, x2); + sm9_fp2_mul(T2, T2, y2); + sm9_fp2_sub(T1, T1, X1); + sm9_fp2_sub(T2, T2, Y1); + if (sm9_fp2_is_zero(T1)) { + if (sm9_fp2_is_zero(T2)) { + sm9_twist_point_dbl(R, Q); + return; + } else { + sm9_twist_point_set_infinity(R); + return; + } + } + sm9_fp2_mul(Z3, Z1, T1); + sm9_fp2_sqr(T3, T1); + sm9_fp2_mul(T4, T3, T1); + sm9_fp2_mul(T3, T3, X1); + sm9_fp2_dbl(T1, T3); + sm9_fp2_sqr(X3, T2); + sm9_fp2_sub(X3, X3, T1); + sm9_fp2_sub(X3, X3, T4); + sm9_fp2_sub(T3, T3, X3); + sm9_fp2_mul(T3, T3, T2); + sm9_fp2_mul(T4, T4, Y1); + sm9_fp2_sub(Y3, T3, T4); + + sm9_fp2_copy(R->X, X3); + sm9_fp2_copy(R->Y, Y3); + sm9_fp2_copy(R->Z, Z3); +} + +void sm9_twist_point_sub(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) +{ + SM9_TWIST_POINT _T, *T = &_T; + sm9_twist_point_neg(T, Q); + sm9_twist_point_add_full(R, P, T); +} + +void sm9_twist_point_add_full(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P, const SM9_TWIST_POINT *Q) +{ + const sm9_fp_t *X1 = P->X; + const sm9_fp_t *Y1 = P->Y; + const sm9_fp_t *Z1 = P->Z; + const sm9_fp_t *X2 = Q->X; + const sm9_fp_t *Y2 = Q->Y; + const sm9_fp_t *Z2 = Q->Z; + sm9_fp2_t T1, T2, T3, T4, T5, T6, T7, T8; + + if (sm9_twist_point_is_at_infinity(Q)) { + sm9_twist_point_copy(R, P); + return; + } + if (sm9_twist_point_is_at_infinity(P)) { + sm9_twist_point_copy(R, Q); + return; + } + + sm9_fp2_sqr(T1, Z1); + sm9_fp2_sqr(T2, Z2); + sm9_fp2_mul(T3, X2, T1); + sm9_fp2_mul(T4, X1, T2); + sm9_fp2_add(T5, T3, T4); + sm9_fp2_sub(T3, T3, T4); + sm9_fp2_mul(T1, T1, Z1); + sm9_fp2_mul(T1, T1, Y2); + sm9_fp2_mul(T2, T2, Z2); + sm9_fp2_mul(T2, T2, Y1); + sm9_fp2_add(T6, T1, T2); + sm9_fp2_sub(T1, T1, T2); + + if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T3)) { + return sm9_twist_point_dbl(R, P); + } + if (sm9_fp2_is_zero(T1) && sm9_fp2_is_zero(T6)) { + return sm9_twist_point_set_infinity(R); + } + + sm9_fp2_sqr(T6, T1); + sm9_fp2_mul(T7, T3, Z1); + sm9_fp2_mul(T7, T7, Z2); + sm9_fp2_sqr(T8, T3); + sm9_fp2_mul(T5, T5, T8); + sm9_fp2_mul(T3, T3, T8); + sm9_fp2_mul(T4, T4, T8); + sm9_fp2_sub(T6, T6, T5); + sm9_fp2_sub(T4, T4, T6); + sm9_fp2_mul(T1, T1, T4); + sm9_fp2_mul(T2, T2, T3); + sm9_fp2_sub(T1, T1, T2); + + sm9_fp2_copy(R->X, T6); + sm9_fp2_copy(R->Y, T1); + sm9_fp2_copy(R->Z, T7); +} + +void sm9_twist_point_mul(SM9_TWIST_POINT *R, const sm9_bn_t k, const SM9_TWIST_POINT *P) +{ + SM9_TWIST_POINT _Q, *Q = &_Q; + char kbits[256]; + int i; + + sm9_bn_to_bits(k, kbits); + sm9_twist_point_set_infinity(Q); + for (i = 0; i < 256; i++) { + sm9_twist_point_dbl(Q, Q); + if (kbits[i] == '1') { + sm9_twist_point_add_full(Q, Q, P); + } + } + sm9_twist_point_copy(R, Q); +} + +void sm9_twist_point_mul_generator(SM9_TWIST_POINT *R, const sm9_bn_t k) +{ + sm9_twist_point_mul(R, k, SM9_P2); +} + +void sm9_eval_g_tangent(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *P, const SM9_POINT *Q) +{ + sm9_fp_t x; + sm9_fp_t y; + sm9_point_get_xy(Q, x, y); + + const sm9_fp_t *XP = P->X; + const sm9_fp_t *YP = P->Y; + const sm9_fp_t *ZP = P->Z; + const uint64_t *xQ = x; + const uint64_t *yQ = y; + + sm9_fp_t *a0 = num[0][0]; + sm9_fp_t *a1 = num[0][1]; + sm9_fp_t *a4 = num[2][0]; + sm9_fp_t *b1 = den[0][1]; + + sm9_fp2_t t0; + sm9_fp2_t t1; + sm9_fp2_t t2; + + + sm9_fp12_set_zero(num); + sm9_fp12_set_zero(den); + + sm9_fp2_sqr(t0, ZP); + sm9_fp2_mul(t1, t0, ZP); + sm9_fp2_mul(b1, t1, YP); + + sm9_fp2_mul_fp(t2, b1, yQ); + sm9_fp2_neg(a1, t2); + + sm9_fp2_sqr(t1, XP); + sm9_fp2_mul(t0, t0, t1); + sm9_fp2_mul_fp(t0, t0, xQ); + sm9_fp2_tri(t0, t0); + sm9_fp2_div2(a4, t0); + + sm9_fp2_mul(t1, t1, XP); + sm9_fp2_tri(t1, t1); + sm9_fp2_div2(t1, t1); + sm9_fp2_sqr(t0, YP); + sm9_fp2_sub(a0, t0, t1); +} + +void sm9_eval_g_line(sm9_fp12_t num, sm9_fp12_t den, const SM9_TWIST_POINT *T, const SM9_TWIST_POINT *P, const SM9_POINT *Q) +{ + sm9_fp_t x; + sm9_fp_t y; + sm9_point_get_xy(Q, x, y); + + const sm9_fp_t *XT = T->X; + const sm9_fp_t *YT = T->Y; + const sm9_fp_t *ZT = T->Z; + const sm9_fp_t *XP = P->X; + const sm9_fp_t *YP = P->Y; + const sm9_fp_t *ZP = P->Z; + const uint64_t *xQ = x; + const uint64_t *yQ = y; + + sm9_fp_t *a0 = num[0][0]; + sm9_fp_t *a1 = num[0][1]; + sm9_fp_t *a4 = num[2][0]; + sm9_fp_t *b1 = den[0][1]; + + sm9_fp2_t T0, T1, T2, T3, T4; + + + sm9_fp12_set_zero(num); + sm9_fp12_set_zero(den); + + sm9_fp2_sqr(T0, ZP); + sm9_fp2_mul(T1, T0, XT); + sm9_fp2_mul(T0, T0, ZP); + sm9_fp2_sqr(T2, ZT); + sm9_fp2_mul(T3, T2, XP); + sm9_fp2_mul(T2, T2, ZT); + sm9_fp2_mul(T2, T2, YP); + sm9_fp2_sub(T1, T1, T3); + sm9_fp2_mul(T1, T1, ZT); + sm9_fp2_mul(T1, T1, ZP); + sm9_fp2_mul(T4, T1, T0); + sm9_fp2_copy(b1, T4); + sm9_fp2_mul(T1, T1, YP); + sm9_fp2_mul(T3, T0, YT); + sm9_fp2_sub(T3, T3, T2); + sm9_fp2_mul(T0, T0, T3); + sm9_fp2_mul_fp(T0, T0, xQ); + sm9_fp2_copy(a4, T0); + sm9_fp2_mul(T3, T3, XP); + sm9_fp2_mul(T3, T3, ZP); + sm9_fp2_sub(T1, T1, T3); + sm9_fp2_copy(a0, T1); + sm9_fp2_mul_fp(T2, T4, yQ); + sm9_fp2_neg(T2, T2); + sm9_fp2_copy(a1, T2); +} + +void sm9_twist_point_pi1(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) +{ + //const c = 0x3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698bn; + const sm9_fp_t c = { + 0x377b698b, 0xa91d8354, 0x0ddd04ed, 0x47c5c86e, + 0x9c086749, 0x843c6cfa, 0xe5720bdb, 0x3f23ea58, + }; + sm9_fp2_conjugate(R->X, P->X); + sm9_fp2_conjugate(R->Y, P->Y); + sm9_fp2_conjugate(R->Z, P->Z); + sm9_fp2_mul_fp(R->Z, R->Z, c); + +} + +void sm9_twist_point_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) +{ + //c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 + const sm9_fp_t c = { + 0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, + 0x02a3a6f2, 0xf3000000, 0, 0, + }; + sm9_fp2_copy(R->X, P->X); + sm9_fp2_copy(R->Y, P->Y); + sm9_fp2_mul_fp(R->Z, P->Z, c); +} + +void sm9_twist_point_neg_pi2(SM9_TWIST_POINT *R, const SM9_TWIST_POINT *P) +{ + // c = 0xf300000002a3a6f2780272354f8b78f4d5fc11967be65334 + const sm9_fp_t c = { + 0x7be65334, 0xd5fc1196, 0x4f8b78f4, 0x78027235, + 0x02a3a6f2, 0xf3000000, 0, 0, + }; + sm9_fp2_copy(R->X, P->X); + sm9_fp2_neg(R->Y, P->Y); + sm9_fp2_mul_fp(R->Z, P->Z, c); +} + + +void sm9_final_exponent_hard_part(sm9_fp12_t r, const sm9_fp12_t f) +{ + // a2 = 0xd8000000019062ed0000b98b0cb27659 + // a3 = 0x2400000000215d941 + const sm9_bn_t a2 = {0xcb27659, 0x0000b98b, 0x019062ed, 0xd8000000, 0, 0, 0, 0}; + const sm9_bn_t a3 = {0x215d941, 0x40000000, 0x2, 0, 0, 0, 0, 0}; + const sm9_bn_t nine = {9,0,0,0,0,0,0,0}; + sm9_fp12_t t0, t1, t2, t3; + + sm9_fp12_pow(t0, f, a3); + sm9_fp12_inv(t0, t0); + sm9_fp12_frobenius(t1, t0); + sm9_fp12_mul(t1, t0, t1); + + sm9_fp12_mul(t0, t0, t1); + sm9_fp12_frobenius(t2, f); + sm9_fp12_mul(t3, t2, f); + sm9_fp12_pow(t3, t3, nine); + + sm9_fp12_mul(t0, t0, t3); + sm9_fp12_sqr(t3, f); + sm9_fp12_sqr(t3, t3); + sm9_fp12_mul(t0, t0, t3); + sm9_fp12_sqr(t2, t2); + sm9_fp12_mul(t2, t2, t1); + sm9_fp12_frobenius2(t1, f); + sm9_fp12_mul(t1, t1, t2); + + sm9_fp12_pow(t2, t1, a2); + sm9_fp12_mul(t0, t2, t0); + sm9_fp12_frobenius3(t1, f); + sm9_fp12_mul(t1, t1, t0); + + sm9_fp12_copy(r, t1); +} + +void sm9_final_exponent(sm9_fp12_t r, const sm9_fp12_t f) +{ + sm9_fp12_t t0; + sm9_fp12_t t1; + + sm9_fp12_frobenius6(t0, f); + sm9_fp12_inv(t1, f); + sm9_fp12_mul(t0, t0, t1); + sm9_fp12_frobenius2(t1, t0); + sm9_fp12_mul(t0, t0, t1); + sm9_final_exponent_hard_part(t0, t0); + + sm9_fp12_copy(r, t0); +} + +void sm9_pairing(sm9_fp12_t r, const SM9_TWIST_POINT *Q, const SM9_POINT *P) { + const char *abits = "00100000000000000000000000000000000000010000101011101100100111110"; + + SM9_TWIST_POINT _T, *T = &_T; + SM9_TWIST_POINT _Q1, *Q1 = &_Q1; + SM9_TWIST_POINT _Q2, *Q2 = &_Q2; + + sm9_fp12_t f_num; + sm9_fp12_t f_den; + sm9_fp12_t g_num; + sm9_fp12_t g_den; + int i; + + sm9_twist_point_copy(T, Q); + + sm9_fp12_set_one(f_num); + sm9_fp12_set_one(f_den); + + for (i = 0; i < strlen(abits); i++) { + + sm9_fp12_sqr(f_num, f_num); + sm9_fp12_sqr(f_den, f_den); + sm9_eval_g_tangent(g_num, g_den, T, P); + sm9_fp12_mul(f_num, f_num, g_num); + sm9_fp12_mul(f_den, f_den, g_den); + + sm9_twist_point_dbl(T, T); + + if (abits[i] == '1') { + sm9_eval_g_line(g_num, g_den, T, Q, P); + sm9_fp12_mul(f_num, f_num, g_num); + sm9_fp12_mul(f_den, f_den, g_den); + sm9_twist_point_add_full(T, T, Q); + } + } + + sm9_twist_point_pi1(Q1, Q); + sm9_twist_point_neg_pi2(Q2, Q); + + sm9_eval_g_line(g_num, g_den, T, Q1, P); + sm9_fp12_mul(f_num, f_num, g_num); + sm9_fp12_mul(f_den, f_den, g_den); + sm9_twist_point_add_full(T, T, Q1); + + sm9_eval_g_line(g_num, g_den, T, Q2, P); + sm9_fp12_mul(f_num, f_num, g_num); + sm9_fp12_mul(f_den, f_den, g_den); + sm9_twist_point_add_full(T, T, Q2); + + sm9_fp12_inv(f_den, f_den); + sm9_fp12_mul(r, f_num, f_den); + + sm9_final_exponent(r, r); +} + +void sm9_fn_add(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) +{ + sm9_bn_add(r, a, b); + if (sm9_bn_cmp(r, SM9_N) >= 0) + return sm9_bn_sub(r, r, SM9_N); +} + +void sm9_fn_sub(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) +{ + if (sm9_bn_cmp(a, b) >= 0) { + sm9_bn_sub(r, a, b); + } else { + sm9_bn_t t; + sm9_bn_sub(t, SM9_N, b); + sm9_bn_add(r, t, a); + } +} + +void sm9_fn_mul(sm9_fn_t r, const sm9_fn_t a, const sm9_fn_t b) +{ + uint64_t s[18]; + sm9_barrett_bn_t zh, zl, q; + uint64_t w; + int i, j; + + /* z = a * b */ + for (i = 0; i < 8; i++) { + s[i] = 0; + } + for (i = 0; i < 8; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + a[i] * b[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + + /* zl = z mod (2^32)^9 = z[0..8] + * zh = z // (2^32)^7 = z[7..15] */ + for (i = 0; i < 9; i++) { + zl[i] = s[i]; + zh[i] = s[7 + i]; + } + + /* q = zh * mu // (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 9; j++) { + w += s[i + j] + zh[i] * SM9_MU_N[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 9] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[9 + i]; + } + + /* q = q * n mod (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + q[i] * SM9_N[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[i]; + } + + /* r = zl - q (mod (2^32)^9) */ + + if (sm9_barrett_bn_cmp(zl, q)) { + sm9_barrett_bn_sub(zl, zl, q); + } else { + sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; + sm9_barrett_bn_sub(q, c, q); + sm9_barrett_bn_add(zl, q, zl); + } + + + for (i = 0; i < 8; i++) { + r[i] = zl[i]; + } + + r[7] += (zl[8] << 32); + + /* while r >= n do: r = r - n */ + while (sm9_bn_cmp(r, SM9_N) >= 0) { + sm9_bn_sub(r, r, SM9_N); + } +} + +void sm9_fn_pow(sm9_fn_t r, const sm9_fn_t a, const sm9_bn_t e) +{ + sm9_fn_t t; + uint32_t w; + int i, j; + + assert(sm9_bn_cmp(e, SM9_N_MINUS_ONE) < 0); + + sm9_bn_set_one(t); + for (i = 7; i >= 0; i--) { + w = (uint32_t)e[i]; + for (j = 0; j < 32; j++) { + sm9_fn_mul(t, t, t); + if (w & 0x80000000) + sm9_fn_mul(t, t, a); + w <<= 1; + } + } + sm9_bn_copy(r, t); +} + +void sm9_fn_inv(sm9_fn_t r, const sm9_fn_t a) +{ + sm9_fn_t e; + sm9_bn_sub(e, SM9_N, SM9_TWO); + sm9_fn_pow(r, a, e); +} + + +// for H1() and H2() +// h = (Ha mod (n-1)) + 1; h in [1, n-1], n is the curve order, Ha is 40 bytes from hash +void sm9_fn_from_hash(sm9_fn_t h, const uint8_t Ha[40]) +{ + uint64_t s[18] = {0}; + sm9_barrett_bn_t zh, zl, q; + uint64_t w; + int i, j; + + /* s = Ha -> int */ + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 4; j++) { + s[i] <<= 8; + s[i] += Ha[4 * (9-i) + j]; + } + } + + /* zl = z mod (2^32)^9 = z[0..8] + * zh = z // (2^32)^7 = z[7..15] */ + for (i = 0; i < 9; i++) { + zl[i] = s[i]; + zh[i] = s[7 + i]; + } + + /* q = zh * mu // (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 9; j++) { + w += s[i + j] + zh[i] * SM9_MU_N_MINUS_ONE[j]; // + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 9] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[9 + i]; + } + + /* q = q * p mod (2^32)^9 */ + for (i = 0; i < 18; i++) { + s[i] = 0; + } + for (i = 0; i < 9; i++) { + w = 0; + for (j = 0; j < 8; j++) { + w += s[i + j] + q[i] * SM9_N_MINUS_ONE[j]; + s[i + j] = w & 0xffffffff; + w >>= 32; + } + s[i + 8] = w; + } + for (i = 0; i < 9; i++) { + q[i] = s[i]; + } + + /* h = zl - q (mod (2^32)^9) */ + + if (sm9_barrett_bn_cmp(zl, q)) { + sm9_barrett_bn_sub(zl, zl, q); + } else { + sm9_barrett_bn_t c = {0,0,0,0,0,0,0,0,0x100000000}; + sm9_barrett_bn_sub(q, c, q); + sm9_barrett_bn_add(zl, q, zl); + } + + for (i = 0; i < 8; i++) { + h[i] = zl[i]; + } + + h[7] += (zl[8] << 32); + + /* while h >= (n-1) do: h = h - (n-1) */ + while (sm9_bn_cmp(h, SM9_N_MINUS_ONE) >= 0) { + sm9_bn_sub(h, h, SM9_N_MINUS_ONE); + } + + sm9_fn_add(h, h, SM9_ONE); +} + +void sm9_fp12_to_bytes(const sm9_fp12_t a, uint8_t buf[32 * 12]) +{ + sm9_fp4_to_bytes(a[2], buf); + sm9_fp4_to_bytes(a[1], buf + 32 * 4); + sm9_fp4_to_bytes(a[0], buf + 32 * 8); +} + +int sm9_fn_from_bytes(sm9_fn_t a, const uint8_t in[32]) +{ + sm9_bn_from_bytes(a, in); + return 1; +} + +int sm9_point_to_uncompressed_octets(const SM9_POINT *P, uint8_t octets[65]) +{ + sm9_fp_t x; + sm9_fp_t y; + sm9_point_get_xy(P, x, y); + octets[0] = 0x04; + sm9_bn_to_bytes(x, octets + 1); + sm9_bn_to_bytes(y, octets + 32 + 1); + return 1; +} + +int sm9_point_from_uncompressed_octets(SM9_POINT *P, const uint8_t octets[65]) +{ + if (octets[0] != 0x04) { + error_print(); + return -1; + } + memset(P, 0, sizeof(*P)); + sm9_bn_from_bytes(P->X, octets + 1); + sm9_bn_from_bytes(P->Y, octets + 32 + 1); + sm9_fp_set_one(P->Z); + if (!sm9_point_is_on_curve(P)) { + error_print(); + return -1; + } + return 1; +} + +int sm9_twist_point_to_uncompressed_octets(const SM9_TWIST_POINT *P, uint8_t octets[129]) +{ + octets[0] = 0x04; + sm9_fp2_t x; + sm9_fp2_t y; + sm9_twist_point_get_xy(P, x, y); + sm9_fp2_to_bytes(x, octets + 1); + sm9_fp2_to_bytes(y, octets + 32 * 2 + 1); + return 1; +} + +int sm9_twist_point_from_uncompressed_octets(SM9_TWIST_POINT *P, const uint8_t octets[129]) +{ + assert(octets[0] == 0x04); + sm9_fp2_from_bytes(P->X, octets + 1); + sm9_fp2_from_bytes(P->Y, octets + 32 * 2 + 1); + sm9_fp2_set_one(P->Z); + if (!sm9_twist_point_is_on_curve(P)) return -1; + return 1; +} diff --git a/src/sm9_key.c b/src/sm9_key.c index 13b2f5c4..c008bd8f 100644 --- a/src/sm9_key.c +++ b/src/sm9_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1148 +7,1149 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// generate h1 in [1, n-1] -int sm9_hash1(sm9_bn_t h1, const char *id, size_t idlen, uint8_t hid) -{ - SM3_CTX ctx; - uint8_t prefix[1] = { SM9_HASH1_PREFIX }; - uint8_t ct1[4] = {0x00, 0x00, 0x00, 0x01}; - uint8_t ct2[4] = {0x00, 0x00, 0x00, 0x02}; - uint8_t Ha[64]; - - sm3_init(&ctx); - sm3_update(&ctx, prefix, sizeof(prefix)); - sm3_update(&ctx, (uint8_t *)id, idlen); - sm3_update(&ctx, &hid, 1); - sm3_update(&ctx, ct1, sizeof(ct1)); - sm3_finish(&ctx, Ha); - - sm3_init(&ctx); - sm3_update(&ctx, prefix, sizeof(prefix)); - sm3_update(&ctx, (uint8_t *)id, idlen); - sm3_update(&ctx, &hid, 1); - sm3_update(&ctx, ct2, sizeof(ct2)); - sm3_finish(&ctx, Ha + 32); - - sm9_fn_from_hash(h1, Ha); - return 1; -} - -int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen) -{ - uint8_t ks[32]; - uint8_t Ppubs[1 + 32 * 4]; - size_t len = 0; - - sm9_fn_to_bytes(msk->ks, ks); - sm9_twist_point_to_uncompressed_octets(&msk->Ppubs, Ppubs); - - if (asn1_integer_to_der(ks, sizeof(ks), NULL, &len) != 1 - || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_integer_to_der(ks, sizeof(ks), out, outlen) != 1 - || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { - gmssl_secure_clear(ks, sizeof(ks)); - error_print(); - return -1; - } - gmssl_secure_clear(ks, sizeof(ks)); - return 1; -} - -int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *ks; - size_t kslen; - const uint8_t *Ppubs; - size_t Ppubslen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_integer_from_der(&ks, &kslen, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 - || asn1_check(kslen == 32) != 1 - || asn1_check(Ppubslen == 1 + 32 * 4) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(msk, 0, sizeof(*msk)); - if (sm9_fn_from_bytes(msk->ks, ks) != 1 - || sm9_twist_point_from_uncompressed_octets(&msk->Ppubs, Ppubs) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen) -{ - uint8_t Ppubs[1 + 32 * 4]; - size_t len = 0; - - sm9_twist_point_to_uncompressed_octets(&mpk->Ppubs, Ppubs); - if (asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *Ppubs; - size_t Ppubslen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 - || asn1_check(Ppubslen == 1 + 32 * 4) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(mpk, 0, sizeof(*mpk)); - if (sm9_twist_point_from_uncompressed_octets(&mpk->Ppubs, Ppubs) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen) -{ - uint8_t ds[65]; - uint8_t Ppubs[129]; - size_t len = 0; - - sm9_point_to_uncompressed_octets(&key->ds, ds); - sm9_twist_point_to_uncompressed_octets(&key->Ppubs, Ppubs); - - if (asn1_bit_octets_to_der(ds, sizeof(ds), NULL, &len) != 1 - || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_bit_octets_to_der(ds, sizeof(ds), out, outlen) != 1 - || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { - gmssl_secure_clear(ds, sizeof(ds)); - error_print(); - return -1; - } - gmssl_secure_clear(ds, sizeof(ds)); - return 1; -} - -int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *ds; - size_t dslen; - const uint8_t *Ppubs; - size_t Ppubslen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_bit_octets_from_der(&ds, &dslen, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 - || asn1_check(dslen == 65) != 1 - || asn1_check(Ppubslen == 129) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(key, 0, sizeof(*key)); - if (sm9_point_from_uncompressed_octets(&key->ds, ds) != 1 - || sm9_twist_point_from_uncompressed_octets(&key->Ppubs, Ppubs) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen) -{ - uint8_t ke[32]; - uint8_t Ppube[1 + 32 * 2]; - size_t len = 0; - - sm9_fn_to_bytes(msk->ke, ke); - sm9_point_to_uncompressed_octets(&msk->Ppube, Ppube); - - if (asn1_integer_to_der(ke, sizeof(ke), NULL, &len) != 1 - || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_integer_to_der(ke, sizeof(ke), out, outlen) != 1 - || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { - gmssl_secure_clear(ke, sizeof(ke)); - error_print(); - return -1; - } - gmssl_secure_clear(ke, sizeof(ke)); - return 1; -} - -int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *ke; - size_t kelen; - const uint8_t *Ppube; - size_t Ppubelen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_integer_from_der(&ke, &kelen, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 - || asn1_check(kelen == 32) != 1 - || asn1_check(Ppubelen == 1 + 32 * 2) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(msk, 0, sizeof(*msk)); - if (sm9_fn_from_bytes(msk->ke, ke) != 1 - || sm9_point_from_uncompressed_octets(&msk->Ppube, Ppube) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen) -{ - uint8_t Ppube[1 + 32 * 2]; - size_t len = 0; - - sm9_point_to_uncompressed_octets(&mpk->Ppube, Ppube); - - if (asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *Ppube; - size_t Ppubelen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 - || asn1_check(Ppubelen == 1 + 32 * 2) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(mpk, 0, sizeof(*mpk)); - if (sm9_point_from_uncompressed_octets(&mpk->Ppube, Ppube) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen) -{ - uint8_t de[129]; - uint8_t Ppube[65]; - size_t len = 0; - - sm9_twist_point_to_uncompressed_octets(&key->de, de); - sm9_point_to_uncompressed_octets(&key->Ppube, Ppube); - - if (asn1_bit_octets_to_der(de, sizeof(de), NULL, &len) != 1 - || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_bit_octets_to_der(de, sizeof(de), out, outlen) != 1 - || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { - gmssl_secure_clear(de, sizeof(de)); - error_print(); - return -1; - } - gmssl_secure_clear(de, sizeof(de)); - return 1; -} - -int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *de; - size_t delen; - const uint8_t *Ppube; - size_t Ppubelen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_bit_octets_from_der(&de, &delen, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 - || asn1_check(delen == 129) != 1 - || asn1_check(Ppubelen == 65) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - memset(key, 0, sizeof(*key)); - if (sm9_twist_point_from_uncompressed_octets(&key->de, de) != 1 - || sm9_point_from_uncompressed_octets(&key->Ppube, Ppube) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *msk) -{ - if (!msk) { - error_print(); - return -1; - } - // k = rand(1, n-1) - if (sm9_fn_rand(msk->ks) != 1) { - error_print(); - return -1; - } - // Ppubs = k * P2 in E'(F_p^2) - sm9_twist_point_mul_generator(&msk->Ppubs, msk->ks); - return 1; -} - -int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *msk) -{ - // k = rand(1, n-1) - if (sm9_fn_rand(msk->ke) != 1) { - error_print(); - return -1; - } - // Ppube = ke * P1 in E(F_p) - sm9_point_mul_generator(&msk->Ppube, msk->ke); - return 1; -} - -int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *msk, const char *id, size_t idlen, SM9_SIGN_KEY *key) -{ - sm9_fn_t t; - - // t1 = H1(ID || hid, N) + ks - sm9_hash1(t, id, idlen, SM9_HID_SIGN); - sm9_fn_add(t, t, msk->ks); - if (sm9_fn_is_zero(t)) { - // 这是一个严重问题,意味着整个msk都需要作废了 - error_print(); - return -1; - } - - // t2 = ks * t1^-1 - sm9_fn_inv(t, t); - sm9_fn_mul(t, t, msk->ks); - - // ds = t2 * P1 - sm9_point_mul_generator(&key->ds, t); - key->Ppubs = msk->Ppubs; - - return 1; -} - -int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *msk, const char *id, size_t idlen, - SM9_ENC_KEY *key) -{ - sm9_fn_t t; - - // t1 = H1(ID || hid, N) + ke - sm9_hash1(t, id, idlen, SM9_HID_ENC); - sm9_fn_add(t, t, msk->ke); - if (sm9_fn_is_zero(t)) { - error_print(); - return -1; - } - - // t2 = ke * t1^-1 - sm9_fn_inv(t, t); - sm9_fn_mul(t, t, msk->ke); - - // de = t2 * P2 - sm9_twist_point_mul_generator(&key->de, t); - key->Ppube = msk->Ppube; - - return 1; -} - - -#define OID_SM9 oid_sm_algors,302 -static uint32_t oid_sm9[] = { OID_SM9 }; -static uint32_t oid_sm9sign[] = { OID_SM9,1 }; -static uint32_t oid_sm9keyagreement[] = { OID_SM9,2 }; -static uint32_t oid_sm9encrypt[] = { OID_SM9,3 }; - -static const ASN1_OID_INFO sm9_oids[] = { - { OID_sm9, "sm9", oid_sm9, sizeof(oid_sm9)/sizeof(int) }, - { OID_sm9sign, "sm9sign", oid_sm9sign, sizeof(oid_sm9sign)/sizeof(int) }, - { OID_sm9keyagreement, "sm9keyagreement", oid_sm9keyagreement, sizeof(oid_sm9keyagreement)/sizeof(int) }, - { OID_sm9encrypt, "sm9encrypt", oid_sm9encrypt, sizeof(oid_sm9encrypt)/sizeof(int) }, -}; - -static const int sm9_oids_count = sizeof(sm9_oids)/sizeof(sm9_oids[0]); - - -const char *sm9_oid_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int sm9_oid_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(sm9_oids, sm9_oids_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (oid == -1) { - // TODO: 检查其他的oid_to_der是否支持这个default == -1 的特性 - return 0; - } - if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - - if ((ret = asn1_oid_info_from_der(&info, sm9_oids, sm9_oids_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - -int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (sm9_oid_to_der(alg, NULL, &len) != 1 - || sm9_oid_to_der(params, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || sm9_oid_to_der(alg, out, outlen) != 1 - || sm9_oid_to_der(params, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (sm9_oid_from_der(alg, &d, &dlen) != 1 - || sm9_oid_from_der(params, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -static int sm9_private_key_info_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (prikey_len > SM9_MAX_PRIVATE_KEY_SIZE) { - error_print(); - return -1; - } - if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1 - || sm9_algor_to_der(alg, params, NULL, &len) != 1 - || asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1 - || sm9_algor_to_der(alg, params, out, outlen) != 1 - || asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) { - error_print(); - return -1; - } - //printf("alg %s params %s prikey_len %zu: SM9_PRIVATE_KEY_INFO_SIZE %zu\n", sm9_oid_name(alg), sm9_oid_name(params), prikey_len, *outlen); - return 1; -} - -static int sm9_private_key_info_from_der(int *alg, int *params, const uint8_t **prikey, size_t *prikey_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - int ver; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return ret; - } - if (asn1_int_from_der(&ver, &d, &dlen) != 1 - || sm9_algor_from_der(alg, params, &d, &dlen) != 1 - || asn1_octet_string_from_der(prikey, prikey_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (ver != PKCS8_private_key_info_version) { - error_print(); - return -1; - } - if (*prikey_len > SM9_MAX_PRIVATE_KEY_SIZE) { - error_print(); - return -1; - } - return 1; -} - -static int sm9_private_key_info_encrypt_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len, - const char *pass, uint8_t **out, size_t *outlen) -{ - int ret = -1; - uint8_t pkey_info[SM9_MAX_PRIVATE_KEY_INFO_SIZE]; - uint8_t *p = pkey_info; - size_t pkey_info_len = 0; - uint8_t salt[16]; - int iter = 65536; - uint8_t iv[16]; - uint8_t key[16]; - SM4_KEY sm4_key; - uint8_t enced_pkey_info[sizeof(pkey_info) + 16]; // cbc-padding of pkey_info - size_t enced_pkey_info_len; - - if (sm9_private_key_info_to_der(alg, params, prikey, prikey_len, &p, &pkey_info_len) != 1 - || rand_bytes(salt, sizeof(salt)) != 1 - || rand_bytes(iv, sizeof(iv)) != 1 - || pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, sizeof(salt), iter, sizeof(key), key) != 1) { - error_print(); - goto end; - } - sm4_set_encrypt_key(&sm4_key, key); - if (sm4_cbc_padding_encrypt(&sm4_key, iv, pkey_info, pkey_info_len, enced_pkey_info, &enced_pkey_info_len) != 1 - || pkcs8_enced_private_key_info_to_der(salt, sizeof(salt), iter, sizeof(key), - OID_hmac_sm3, OID_sm4_cbc, iv, sizeof(iv), - enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) { - error_print(); - goto end; - } - //printf("SM9_ENCED_PRIVATE_KEY_INFO_SIZE %zu\n", *outlen); - ret = 1; -end: - gmssl_secure_clear(pkey_info, sizeof(pkey_info)); - gmssl_secure_clear(salt, sizeof(salt)); - gmssl_secure_clear(iv, sizeof(iv)); - gmssl_secure_clear(key, sizeof(key)); - return ret; -} - -static int sm9_private_key_info_decrypt_from_der(int *alg, int *params, uint8_t *prikey, size_t *prikey_len, - const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - const uint8_t *salt; - size_t saltlen; - int iter; - int keylen; - int prf; - int cipher; - const uint8_t *iv; - size_t ivlen; - uint8_t key[16]; - SM4_KEY sm4_key; - const uint8_t *enced_pkey_info; - size_t enced_pkey_info_len; - uint8_t pkey_info[SM9_MAX_PRIVATE_KEY_INFO_SIZE]; - const uint8_t *cp = pkey_info; - size_t pkey_info_len; - const uint8_t *cp_prikey; - - if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf, - &cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1 - || asn1_check(keylen == -1 || keylen == 16) != 1 - || asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == 16) != 1 - || asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) { - error_print(); - return -1; - } - if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { - error_print(); - goto end; - } - sm4_set_decrypt_key(&sm4_key, key); - if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len, - pkey_info, &pkey_info_len) != 1 - || sm9_private_key_info_from_der(alg, params, &cp_prikey, prikey_len, // 注意这里的是const uint8_t *,必须拷贝到外面 - &cp, &pkey_info_len) != 1 - || asn1_length_is_zero(pkey_info_len) != 1) { - error_print(); - goto end; - } - memcpy(prikey, cp_prikey, *prikey_len); - ret = 1; -end: - gmssl_secure_clear(&sm4_key, sizeof(sm4_key)); - gmssl_secure_clear(key, sizeof(key)); - gmssl_secure_clear(pkey_info, sizeof(pkey_info)); - return ret; -} - - - -int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen) -{ - uint8_t buf[SM9_SIGN_MASTER_KEY_MAX_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_sign_master_key_to_der(msk, &p, &len) != 1 - || sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9sign, buf, len, pass, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - - -int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - int alg, params; - uint8_t prikey[SM9_MAX_PRIVATE_KEY_SIZE]; - size_t prikey_len; - const uint8_t *cp = prikey; - - if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { - error_print(); - goto end; - } - if (alg != OID_sm9) { - error_print(); - goto end; - } - if (params != OID_sm9sign) { - error_print(); - goto end; - } - if (sm9_sign_master_key_from_der(msk, &cp, &prikey_len) != 1 - || asn1_length_is_zero(prikey_len) != 1) { - error_print(); - goto end; - } - ret = 1; -end: - gmssl_secure_clear(prikey, sizeof(prikey)); - return ret; -} - -int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_sign_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_SIGN_MASTER_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_SIGN_MASTER_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_sign_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp) -{ - uint8_t buf[SM9_SIGN_MASTER_PUBLIC_KEY_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_sign_master_public_key_to_der(mpk, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_sign_master_public_key_from_der(mpk, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen) -{ - uint8_t buf[SM9_SIGN_KEY_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_sign_key_to_der(key, &p, &len) != 1 - || sm9_private_key_info_encrypt_to_der(OID_sm9sign, -1, buf, len, pass, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - int alg, params; - uint8_t prikey[512]; - size_t prikey_len; - const uint8_t *cp = prikey; - - if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { - error_print(); - goto end; - } - if (alg != OID_sm9sign) { - error_print(); - goto end; - } - if (params != -1) { - error_print(); - goto end; - } - if (sm9_sign_key_from_der(key, &cp, &prikey_len) != 1 - || asn1_length_is_zero(prikey_len) != 1) { - error_print(); - goto end; - } - ret = 1; -end: - gmssl_secure_clear(prikey, sizeof(prikey)); - return ret; -} - -int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_sign_key_info_encrypt_to_der(key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_sign_key_info_decrypt_from_der(key, pass, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen) -{ - uint8_t buf[256]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_enc_master_key_to_der(msk, &p, &len) != 1 - || sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9encrypt, buf, len, pass, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - int alg, params; - uint8_t prikey[512]; - size_t prikey_len; - const uint8_t *cp = prikey; - - if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { - error_print(); - goto end; - } - if (alg != OID_sm9) { - error_print(); - goto end; - } - if (params != OID_sm9encrypt) { - error_print(); - goto end; - } - if (sm9_enc_master_key_from_der(msk, &cp, &prikey_len) != 1 - || asn1_length_is_zero(prikey_len) != 1) { - error_print(); - goto end; - } - ret = 1; -end: - gmssl_secure_clear(prikey, sizeof(prikey)); - return 1; -} - -int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_enc_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_ENC_MASTER_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_ENC_MASTER_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_enc_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_enc_master_public_key_to_der(mpk, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp) -{ - uint8_t buf[512]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_enc_master_public_key_from_der(mpk, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_enc_key_to_der(key, &p, &len) != 1 - || sm9_private_key_info_encrypt_to_der(OID_sm9encrypt, -1, buf, len, pass, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen) -{ - int ret = -1; - int alg, params; - uint8_t prikey[512]; - size_t prikey_len; - const uint8_t *cp = prikey; - - if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { - error_print(); - goto end; - } - if (alg != OID_sm9encrypt) { - error_print(); - goto end; - } - if (params != -1) { - error_print(); - goto end; - } - if (sm9_enc_key_from_der(key, &cp, &prikey_len) != 1 - || asn1_length_is_zero(prikey_len) != 1) { - error_print(); - goto end; - } - ret = 1; -end: - gmssl_secure_clear(prikey, sizeof(prikey)); - return ret; -} - -int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - uint8_t *p = buf; - size_t len = 0; - - if (sm9_enc_key_info_encrypt_to_der(key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (pem_write(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp) -{ - uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; - const uint8_t *cp = buf; - size_t len; - - if (pem_read(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1 - || sm9_enc_key_info_decrypt_from_der(key, pass, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_fn_print(fp, fmt, ind, "ks", msk->ks); - sm9_twist_point_print(fp, fmt, ind, "Ppubs", &msk->Ppubs); - return 1; -} - -int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_twist_point_print(fp, fmt, ind, "Ppubs", &mpk->Ppubs); - return 1; -} - -int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_point_print(fp, fmt, ind, "ds", &key->ds); - sm9_twist_point_print(fp, fmt, ind, "Ppubs", &key->Ppubs); - return 1; -} - -int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_fn_print(fp, fmt, ind, "ke", msk->ke); - sm9_point_print(fp, fmt, ind, "Ppube", &msk->Ppube); - return 1; -} - -int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_point_print(fp, fmt, ind, "Ppube", &mpk->Ppube); - return 1; -} - -int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key) -{ - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - sm9_twist_point_print(fp, fmt, ind, "de", &key->de); - sm9_point_print(fp, fmt, ind, "Ppube", &key->Ppube); - return 1; -} - -int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen) -{ - const uint8_t *d; - size_t dlen; - const uint8_t *p; - size_t len; - - if (asn1_sequence_from_der(&d, &dlen, &sig, &siglen) != 1 - || asn1_length_is_zero(siglen) != 1) { - error_print(); - return -1; - } - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "h", p, len); - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "S", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - const uint8_t *d; - size_t dlen; - int val; - const uint8_t *p; - size_t len; - - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "EnType: %d\n", val); - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "C1", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "C3", p, len); - if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "CipherText", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// generate h1 in [1, n-1] +int sm9_hash1(sm9_bn_t h1, const char *id, size_t idlen, uint8_t hid) +{ + SM3_CTX ctx; + uint8_t prefix[1] = { SM9_HASH1_PREFIX }; + uint8_t ct1[4] = {0x00, 0x00, 0x00, 0x01}; + uint8_t ct2[4] = {0x00, 0x00, 0x00, 0x02}; + uint8_t Ha[64]; + + sm3_init(&ctx); + sm3_update(&ctx, prefix, sizeof(prefix)); + sm3_update(&ctx, (uint8_t *)id, idlen); + sm3_update(&ctx, &hid, 1); + sm3_update(&ctx, ct1, sizeof(ct1)); + sm3_finish(&ctx, Ha); + + sm3_init(&ctx); + sm3_update(&ctx, prefix, sizeof(prefix)); + sm3_update(&ctx, (uint8_t *)id, idlen); + sm3_update(&ctx, &hid, 1); + sm3_update(&ctx, ct2, sizeof(ct2)); + sm3_finish(&ctx, Ha + 32); + + sm9_fn_from_hash(h1, Ha); + return 1; +} + +int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen) +{ + uint8_t ks[32]; + uint8_t Ppubs[1 + 32 * 4]; + size_t len = 0; + + sm9_fn_to_bytes(msk->ks, ks); + sm9_twist_point_to_uncompressed_octets(&msk->Ppubs, Ppubs); + + if (asn1_integer_to_der(ks, sizeof(ks), NULL, &len) != 1 + || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(ks, sizeof(ks), out, outlen) != 1 + || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { + gmssl_secure_clear(ks, sizeof(ks)); + error_print(); + return -1; + } + gmssl_secure_clear(ks, sizeof(ks)); + return 1; +} + +int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *ks; + size_t kslen; + const uint8_t *Ppubs; + size_t Ppubslen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&ks, &kslen, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 + || asn1_check(kslen == 32) != 1 + || asn1_check(Ppubslen == 1 + 32 * 4) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(msk, 0, sizeof(*msk)); + if (sm9_fn_from_bytes(msk->ks, ks) != 1 + || sm9_twist_point_from_uncompressed_octets(&msk->Ppubs, Ppubs) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen) +{ + uint8_t Ppubs[1 + 32 * 4]; + size_t len = 0; + + sm9_twist_point_to_uncompressed_octets(&mpk->Ppubs, Ppubs); + if (asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *Ppubs; + size_t Ppubslen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 + || asn1_check(Ppubslen == 1 + 32 * 4) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(mpk, 0, sizeof(*mpk)); + if (sm9_twist_point_from_uncompressed_octets(&mpk->Ppubs, Ppubs) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen) +{ + uint8_t ds[65]; + uint8_t Ppubs[129]; + size_t len = 0; + + sm9_point_to_uncompressed_octets(&key->ds, ds); + sm9_twist_point_to_uncompressed_octets(&key->Ppubs, Ppubs); + + if (asn1_bit_octets_to_der(ds, sizeof(ds), NULL, &len) != 1 + || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_bit_octets_to_der(ds, sizeof(ds), out, outlen) != 1 + || asn1_bit_octets_to_der(Ppubs, sizeof(Ppubs), out, outlen) != 1) { + gmssl_secure_clear(ds, sizeof(ds)); + error_print(); + return -1; + } + gmssl_secure_clear(ds, sizeof(ds)); + return 1; +} + +int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *ds; + size_t dslen; + const uint8_t *Ppubs; + size_t Ppubslen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_bit_octets_from_der(&ds, &dslen, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&Ppubs, &Ppubslen, &d, &dlen) != 1 + || asn1_check(dslen == 65) != 1 + || asn1_check(Ppubslen == 129) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(key, 0, sizeof(*key)); + if (sm9_point_from_uncompressed_octets(&key->ds, ds) != 1 + || sm9_twist_point_from_uncompressed_octets(&key->Ppubs, Ppubs) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen) +{ + uint8_t ke[32]; + uint8_t Ppube[1 + 32 * 2]; + size_t len = 0; + + sm9_fn_to_bytes(msk->ke, ke); + sm9_point_to_uncompressed_octets(&msk->Ppube, Ppube); + + if (asn1_integer_to_der(ke, sizeof(ke), NULL, &len) != 1 + || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(ke, sizeof(ke), out, outlen) != 1 + || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { + gmssl_secure_clear(ke, sizeof(ke)); + error_print(); + return -1; + } + gmssl_secure_clear(ke, sizeof(ke)); + return 1; +} + +int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *ke; + size_t kelen; + const uint8_t *Ppube; + size_t Ppubelen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(&ke, &kelen, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 + || asn1_check(kelen == 32) != 1 + || asn1_check(Ppubelen == 1 + 32 * 2) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(msk, 0, sizeof(*msk)); + if (sm9_fn_from_bytes(msk->ke, ke) != 1 + || sm9_point_from_uncompressed_octets(&msk->Ppube, Ppube) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen) +{ + uint8_t Ppube[1 + 32 * 2]; + size_t len = 0; + + sm9_point_to_uncompressed_octets(&mpk->Ppube, Ppube); + + if (asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *Ppube; + size_t Ppubelen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 + || asn1_check(Ppubelen == 1 + 32 * 2) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(mpk, 0, sizeof(*mpk)); + if (sm9_point_from_uncompressed_octets(&mpk->Ppube, Ppube) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen) +{ + uint8_t de[129]; + uint8_t Ppube[65]; + size_t len = 0; + + sm9_twist_point_to_uncompressed_octets(&key->de, de); + sm9_point_to_uncompressed_octets(&key->Ppube, Ppube); + + if (asn1_bit_octets_to_der(de, sizeof(de), NULL, &len) != 1 + || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_bit_octets_to_der(de, sizeof(de), out, outlen) != 1 + || asn1_bit_octets_to_der(Ppube, sizeof(Ppube), out, outlen) != 1) { + gmssl_secure_clear(de, sizeof(de)); + error_print(); + return -1; + } + gmssl_secure_clear(de, sizeof(de)); + return 1; +} + +int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *de; + size_t delen; + const uint8_t *Ppube; + size_t Ppubelen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_bit_octets_from_der(&de, &delen, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&Ppube, &Ppubelen, &d, &dlen) != 1 + || asn1_check(delen == 129) != 1 + || asn1_check(Ppubelen == 65) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + memset(key, 0, sizeof(*key)); + if (sm9_twist_point_from_uncompressed_octets(&key->de, de) != 1 + || sm9_point_from_uncompressed_octets(&key->Ppube, Ppube) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *msk) +{ + if (!msk) { + error_print(); + return -1; + } + // k = rand(1, n-1) + if (sm9_fn_rand(msk->ks) != 1) { + error_print(); + return -1; + } + // Ppubs = k * P2 in E'(F_p^2) + sm9_twist_point_mul_generator(&msk->Ppubs, msk->ks); + return 1; +} + +int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *msk) +{ + // k = rand(1, n-1) + if (sm9_fn_rand(msk->ke) != 1) { + error_print(); + return -1; + } + // Ppube = ke * P1 in E(F_p) + sm9_point_mul_generator(&msk->Ppube, msk->ke); + return 1; +} + +int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *msk, const char *id, size_t idlen, SM9_SIGN_KEY *key) +{ + sm9_fn_t t; + + // t1 = H1(ID || hid, N) + ks + sm9_hash1(t, id, idlen, SM9_HID_SIGN); + sm9_fn_add(t, t, msk->ks); + if (sm9_fn_is_zero(t)) { + // 这是一个严重问题,意味着整个msk都需要作废了 + error_print(); + return -1; + } + + // t2 = ks * t1^-1 + sm9_fn_inv(t, t); + sm9_fn_mul(t, t, msk->ks); + + // ds = t2 * P1 + sm9_point_mul_generator(&key->ds, t); + key->Ppubs = msk->Ppubs; + + return 1; +} + +int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *msk, const char *id, size_t idlen, + SM9_ENC_KEY *key) +{ + sm9_fn_t t; + + // t1 = H1(ID || hid, N) + ke + sm9_hash1(t, id, idlen, SM9_HID_ENC); + sm9_fn_add(t, t, msk->ke); + if (sm9_fn_is_zero(t)) { + error_print(); + return -1; + } + + // t2 = ke * t1^-1 + sm9_fn_inv(t, t); + sm9_fn_mul(t, t, msk->ke); + + // de = t2 * P2 + sm9_twist_point_mul_generator(&key->de, t); + key->Ppube = msk->Ppube; + + return 1; +} + + +#define OID_SM9 oid_sm_algors,302 +static uint32_t oid_sm9[] = { OID_SM9 }; +static uint32_t oid_sm9sign[] = { OID_SM9,1 }; +static uint32_t oid_sm9keyagreement[] = { OID_SM9,2 }; +static uint32_t oid_sm9encrypt[] = { OID_SM9,3 }; + +static const ASN1_OID_INFO sm9_oids[] = { + { OID_sm9, "sm9", oid_sm9, sizeof(oid_sm9)/sizeof(int) }, + { OID_sm9sign, "sm9sign", oid_sm9sign, sizeof(oid_sm9sign)/sizeof(int) }, + { OID_sm9keyagreement, "sm9keyagreement", oid_sm9keyagreement, sizeof(oid_sm9keyagreement)/sizeof(int) }, + { OID_sm9encrypt, "sm9encrypt", oid_sm9encrypt, sizeof(oid_sm9encrypt)/sizeof(int) }, +}; + +static const int sm9_oids_count = sizeof(sm9_oids)/sizeof(sm9_oids[0]); + + +const char *sm9_oid_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int sm9_oid_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(sm9_oids, sm9_oids_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int sm9_oid_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (oid == -1) { + // TODO: 检查其他的oid_to_der是否支持这个default == -1 的特性 + return 0; + } + if (!(info = asn1_oid_info_from_oid(sm9_oids, sm9_oids_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_oid_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + + if ((ret = asn1_oid_info_from_der(&info, sm9_oids, sm9_oids_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + +int sm9_algor_to_der(int alg, int params, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (sm9_oid_to_der(alg, NULL, &len) != 1 + || sm9_oid_to_der(params, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || sm9_oid_to_der(alg, out, outlen) != 1 + || sm9_oid_to_der(params, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int sm9_algor_from_der(int *alg, int *params, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (sm9_oid_from_der(alg, &d, &dlen) != 1 + || sm9_oid_from_der(params, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +static int sm9_private_key_info_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (prikey_len > SM9_MAX_PRIVATE_KEY_SIZE) { + error_print(); + return -1; + } + if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1 + || sm9_algor_to_der(alg, params, NULL, &len) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1 + || sm9_algor_to_der(alg, params, out, outlen) != 1 + || asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) { + error_print(); + return -1; + } + //printf("alg %s params %s prikey_len %zu: SM9_PRIVATE_KEY_INFO_SIZE %zu\n", sm9_oid_name(alg), sm9_oid_name(params), prikey_len, *outlen); + return 1; +} + +static int sm9_private_key_info_from_der(int *alg, int *params, const uint8_t **prikey, size_t *prikey_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + int ver; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return ret; + } + if (asn1_int_from_der(&ver, &d, &dlen) != 1 + || sm9_algor_from_der(alg, params, &d, &dlen) != 1 + || asn1_octet_string_from_der(prikey, prikey_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (ver != PKCS8_private_key_info_version) { + error_print(); + return -1; + } + if (*prikey_len > SM9_MAX_PRIVATE_KEY_SIZE) { + error_print(); + return -1; + } + return 1; +} + +static int sm9_private_key_info_encrypt_to_der(int alg, int params, const uint8_t *prikey, size_t prikey_len, + const char *pass, uint8_t **out, size_t *outlen) +{ + int ret = -1; + uint8_t pkey_info[SM9_MAX_PRIVATE_KEY_INFO_SIZE]; + uint8_t *p = pkey_info; + size_t pkey_info_len = 0; + uint8_t salt[16]; + int iter = 65536; + uint8_t iv[16]; + uint8_t key[16]; + SM4_KEY sm4_key; + uint8_t enced_pkey_info[sizeof(pkey_info) + 16]; // cbc-padding of pkey_info + size_t enced_pkey_info_len; + + if (sm9_private_key_info_to_der(alg, params, prikey, prikey_len, &p, &pkey_info_len) != 1 + || rand_bytes(salt, sizeof(salt)) != 1 + || rand_bytes(iv, sizeof(iv)) != 1 + || pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, sizeof(salt), iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_encrypt_key(&sm4_key, key); + if (sm4_cbc_padding_encrypt(&sm4_key, iv, pkey_info, pkey_info_len, enced_pkey_info, &enced_pkey_info_len) != 1 + || pkcs8_enced_private_key_info_to_der(salt, sizeof(salt), iter, sizeof(key), + OID_hmac_sm3, OID_sm4_cbc, iv, sizeof(iv), + enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) { + error_print(); + goto end; + } + //printf("SM9_ENCED_PRIVATE_KEY_INFO_SIZE %zu\n", *outlen); + ret = 1; +end: + gmssl_secure_clear(pkey_info, sizeof(pkey_info)); + gmssl_secure_clear(salt, sizeof(salt)); + gmssl_secure_clear(iv, sizeof(iv)); + gmssl_secure_clear(key, sizeof(key)); + return ret; +} + +static int sm9_private_key_info_decrypt_from_der(int *alg, int *params, uint8_t *prikey, size_t *prikey_len, + const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + const uint8_t *salt; + size_t saltlen; + int iter; + int keylen; + int prf; + int cipher; + const uint8_t *iv; + size_t ivlen; + uint8_t key[16]; + SM4_KEY sm4_key; + const uint8_t *enced_pkey_info; + size_t enced_pkey_info_len; + uint8_t pkey_info[SM9_MAX_PRIVATE_KEY_INFO_SIZE]; + const uint8_t *cp = pkey_info; + size_t pkey_info_len; + const uint8_t *cp_prikey; + + if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf, + &cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1 + || asn1_check(keylen == -1 || keylen == 16) != 1 + || asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == 16) != 1 + || asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) { + error_print(); + return -1; + } + if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) { + error_print(); + goto end; + } + sm4_set_decrypt_key(&sm4_key, key); + if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len, + pkey_info, &pkey_info_len) != 1 + || sm9_private_key_info_from_der(alg, params, &cp_prikey, prikey_len, // 注意这里的是const uint8_t *,必须拷贝到外面 + &cp, &pkey_info_len) != 1 + || asn1_length_is_zero(pkey_info_len) != 1) { + error_print(); + goto end; + } + memcpy(prikey, cp_prikey, *prikey_len); + ret = 1; +end: + gmssl_secure_clear(&sm4_key, sizeof(sm4_key)); + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(pkey_info, sizeof(pkey_info)); + return ret; +} + + + +int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen) +{ + uint8_t buf[SM9_SIGN_MASTER_KEY_MAX_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_sign_master_key_to_der(msk, &p, &len) != 1 + || sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9sign, buf, len, pass, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + + +int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + int alg, params; + uint8_t prikey[SM9_MAX_PRIVATE_KEY_SIZE]; + size_t prikey_len; + const uint8_t *cp = prikey; + + if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { + error_print(); + goto end; + } + if (alg != OID_sm9) { + error_print(); + goto end; + } + if (params != OID_sm9sign) { + error_print(); + goto end; + } + if (sm9_sign_master_key_from_der(msk, &cp, &prikey_len) != 1 + || asn1_length_is_zero(prikey_len) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + gmssl_secure_clear(prikey, sizeof(prikey)); + return ret; +} + +int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_sign_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_SIGN_MASTER_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_SIGN_MASTER_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_sign_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp) +{ + uint8_t buf[SM9_SIGN_MASTER_PUBLIC_KEY_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_sign_master_public_key_to_der(mpk, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_SIGN_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_sign_master_public_key_from_der(mpk, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen) +{ + uint8_t buf[SM9_SIGN_KEY_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_sign_key_to_der(key, &p, &len) != 1 + || sm9_private_key_info_encrypt_to_der(OID_sm9sign, -1, buf, len, pass, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + int alg, params; + uint8_t prikey[512]; + size_t prikey_len; + const uint8_t *cp = prikey; + + if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { + error_print(); + goto end; + } + if (alg != OID_sm9sign) { + error_print(); + goto end; + } + if (params != -1) { + error_print(); + goto end; + } + if (sm9_sign_key_from_der(key, &cp, &prikey_len) != 1 + || asn1_length_is_zero(prikey_len) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + gmssl_secure_clear(prikey, sizeof(prikey)); + return ret; +} + +int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_sign_key_info_encrypt_to_der(key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_SIGN_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_sign_key_info_decrypt_from_der(key, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen) +{ + uint8_t buf[256]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_enc_master_key_to_der(msk, &p, &len) != 1 + || sm9_private_key_info_encrypt_to_der(OID_sm9, OID_sm9encrypt, buf, len, pass, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + int alg, params; + uint8_t prikey[512]; + size_t prikey_len; + const uint8_t *cp = prikey; + + if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { + error_print(); + goto end; + } + if (alg != OID_sm9) { + error_print(); + goto end; + } + if (params != OID_sm9encrypt) { + error_print(); + goto end; + } + if (sm9_enc_master_key_from_der(msk, &cp, &prikey_len) != 1 + || asn1_length_is_zero(prikey_len) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + gmssl_secure_clear(prikey, sizeof(prikey)); + return 1; +} + +int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_enc_master_key_info_encrypt_to_der(msk, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_ENC_MASTER_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_ENC_MASTER_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_enc_master_key_info_decrypt_from_der(msk, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_enc_master_public_key_to_der(mpk, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp) +{ + uint8_t buf[512]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_ENC_MASTER_PUBLIC_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_enc_master_public_key_from_der(mpk, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_enc_key_to_der(key, &p, &len) != 1 + || sm9_private_key_info_encrypt_to_der(OID_sm9encrypt, -1, buf, len, pass, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen) +{ + int ret = -1; + int alg, params; + uint8_t prikey[512]; + size_t prikey_len; + const uint8_t *cp = prikey; + + if (sm9_private_key_info_decrypt_from_der(&alg, ¶ms, prikey, &prikey_len, pass, in, inlen) != 1) { + error_print(); + goto end; + } + if (alg != OID_sm9encrypt) { + error_print(); + goto end; + } + if (params != -1) { + error_print(); + goto end; + } + if (sm9_enc_key_from_der(key, &cp, &prikey_len) != 1 + || asn1_length_is_zero(prikey_len) != 1) { + error_print(); + goto end; + } + ret = 1; +end: + gmssl_secure_clear(prikey, sizeof(prikey)); + return ret; +} + +int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + uint8_t *p = buf; + size_t len = 0; + + if (sm9_enc_key_info_encrypt_to_der(key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (pem_write(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp) +{ + uint8_t buf[SM9_MAX_ENCED_PRIVATE_KEY_INFO_SIZE]; + const uint8_t *cp = buf; + size_t len; + + if (pem_read(fp, PEM_SM9_ENC_PRIVATE_KEY, buf, &len, sizeof(buf)) != 1 + || sm9_enc_key_info_decrypt_from_der(key, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_fn_print(fp, fmt, ind, "ks", msk->ks); + sm9_twist_point_print(fp, fmt, ind, "Ppubs", &msk->Ppubs); + return 1; +} + +int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_twist_point_print(fp, fmt, ind, "Ppubs", &mpk->Ppubs); + return 1; +} + +int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_point_print(fp, fmt, ind, "ds", &key->ds); + sm9_twist_point_print(fp, fmt, ind, "Ppubs", &key->Ppubs); + return 1; +} + +int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_fn_print(fp, fmt, ind, "ke", msk->ke); + sm9_point_print(fp, fmt, ind, "Ppube", &msk->Ppube); + return 1; +} + +int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_point_print(fp, fmt, ind, "Ppube", &mpk->Ppube); + return 1; +} + +int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key) +{ + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sm9_twist_point_print(fp, fmt, ind, "de", &key->de); + sm9_point_print(fp, fmt, ind, "Ppube", &key->Ppube); + return 1; +} + +int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen) +{ + const uint8_t *d; + size_t dlen; + const uint8_t *p; + size_t len; + + if (asn1_sequence_from_der(&d, &dlen, &sig, &siglen) != 1 + || asn1_length_is_zero(siglen) != 1) { + error_print(); + return -1; + } + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "h", p, len); + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "S", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + const uint8_t *d; + size_t dlen; + int val; + const uint8_t *p; + size_t len; + + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "EnType: %d\n", val); + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "C1", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "C3", p, len); + if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "CipherText", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} diff --git a/src/sm9_lib.c b/src/sm9_lib.c index cf96e705..dcc31d65 100644 --- a/src/sm9_lib.c +++ b/src/sm9_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,492 +7,493 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen) -{ - uint8_t hbuf[32]; - uint8_t Sbuf[65]; - size_t len = 0; - - sm9_fn_to_bytes(sig->h, hbuf); - sm9_point_to_uncompressed_octets(&sig->S, Sbuf); - - if (asn1_octet_string_to_der(hbuf, sizeof(hbuf), NULL, &len) != 1 - || asn1_bit_octets_to_der(Sbuf, sizeof(Sbuf), NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_octet_string_to_der(hbuf, sizeof(hbuf), out, outlen) != 1 - || asn1_bit_octets_to_der(Sbuf, sizeof(Sbuf), out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *h; - size_t hlen; - const uint8_t *S; - size_t Slen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_octet_string_from_der(&h, &hlen, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&S, &Slen, &d, &dlen) != 1 - || asn1_check(hlen == 32) != 1 - || asn1_check(Slen == 65) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (sm9_fn_from_bytes(sig->h, h) != 1 - || sm9_point_from_uncompressed_octets(&sig->S, S) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_sign_init(SM9_SIGN_CTX *ctx) -{ - const uint8_t prefix[1] = { SM9_HASH2_PREFIX }; - sm3_init(&ctx->sm3_ctx); - sm3_update(&ctx->sm3_ctx, prefix, sizeof(prefix)); - return 1; -} - -int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) -{ - sm3_update(&ctx->sm3_ctx, data, datalen); - return 1; -} - -int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen) -{ - SM9_SIGNATURE signature; - - if (sm9_do_sign(key, &ctx->sm3_ctx, &signature) != 1) { - error_print(); - return -1; - } - *siglen = 0; - if (sm9_signature_to_der(&signature, &sig, siglen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig) -{ - sm9_fn_t r; - sm9_fp12_t g; - uint8_t wbuf[32 * 12]; - SM3_CTX ctx = *sm3_ctx; - SM3_CTX tmp_ctx; - uint8_t ct1[4] = {0,0,0,1}; - uint8_t ct2[4] = {0,0,0,2}; - uint8_t Ha[64]; - - // A1: g = e(P1, Ppubs) - sm9_pairing(g, &key->Ppubs, SM9_P1); - - do { - // A2: rand r in [1, N-1] - if (sm9_fn_rand(r) != 1) { - error_print(); - return -1; - } - //sm9_fn_from_hex(r, "00033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE"); // for testing - - // A3: w = g^r - sm9_fp12_pow(g, g, r); - sm9_fp12_to_bytes(g, wbuf); - - // A4: h = H2(M || w, N) - sm3_update(&ctx, wbuf, sizeof(wbuf)); - tmp_ctx = ctx; - sm3_update(&ctx, ct1, sizeof(ct1)); - sm3_finish(&ctx, Ha); - sm3_update(&tmp_ctx, ct2, sizeof(ct2)); - sm3_finish(&tmp_ctx, Ha + 32); - sm9_fn_from_hash(sig->h, Ha); - - // A5: l = (r - h) mod N, if l = 0, goto A2 - sm9_fn_sub(r, r, sig->h); - - } while (sm9_fn_is_zero(r)); - - // A6: S = l * dsA - sm9_point_mul(&sig->S, r, &key->ds); - - gmssl_secure_clear(&r, sizeof(r)); - gmssl_secure_clear(&g, sizeof(g)); - gmssl_secure_clear(wbuf, sizeof(wbuf)); - gmssl_secure_clear(&tmp_ctx, sizeof(tmp_ctx)); - gmssl_secure_clear(Ha, sizeof(Ha)); - - return 1; -} - -int sm9_verify_init(SM9_SIGN_CTX *ctx) -{ - const uint8_t prefix[1] = { SM9_HASH2_PREFIX }; - sm3_init(&ctx->sm3_ctx); - sm3_update(&ctx->sm3_ctx, prefix, sizeof(prefix)); - return 1; -} - -int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) -{ - sm3_update(&ctx->sm3_ctx, data, datalen); - return 1; -} - -int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, - const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen) -{ - int ret; - SM9_SIGNATURE signature; - - if (sm9_signature_from_der(&signature, &sig, &siglen) != 1 - || asn1_length_is_zero(siglen) != 1) { - error_print(); - return -1; - } - - if ((ret = sm9_do_verify(mpk, id, idlen, &ctx->sm3_ctx, &signature)) < 0) { - error_print(); - return -1; - } - return ret; -} - -int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, - const SM3_CTX *sm3_ctx, const SM9_SIGNATURE *sig) -{ - sm9_fn_t h1; - sm9_fn_t h2; - sm9_fp12_t g; - sm9_fp12_t t; - sm9_fp12_t u; - sm9_fp12_t w; - SM9_TWIST_POINT P; - uint8_t wbuf[32 * 12]; - SM3_CTX ctx = *sm3_ctx; - SM3_CTX tmp_ctx; - uint8_t ct1[4] = {0,0,0,1}; - uint8_t ct2[4] = {0,0,0,2}; - uint8_t Ha[64]; - - // B1: check h in [1, N-1] - - // B2: check S in G1 - - // B3: g = e(P1, Ppubs) - sm9_pairing(g, &mpk->Ppubs, SM9_P1); - - // B4: t = g^h - sm9_fp12_pow(t, g, sig->h); - - // B5: h1 = H1(ID || hid, N) - sm9_hash1(h1, id, idlen, SM9_HID_SIGN); - - // B6: P = h1 * P2 + Ppubs - sm9_twist_point_mul_generator(&P, h1); - sm9_twist_point_add_full(&P, &P, &mpk->Ppubs); - - // B7: u = e(S, P) - sm9_pairing(u, &P, &sig->S); - - // B8: w = u * t - sm9_fp12_mul(w, u, t); - sm9_fp12_to_bytes(w, wbuf); - - // B9: h2 = H2(M || w, N), check h2 == h - sm3_update(&ctx, wbuf, sizeof(wbuf)); - tmp_ctx = ctx; - sm3_update(&ctx, ct1, sizeof(ct1)); - sm3_finish(&ctx, Ha); - sm3_update(&tmp_ctx, ct2, sizeof(ct2)); - sm3_finish(&tmp_ctx, Ha + 32); - sm9_fn_from_hash(h2, Ha); - if (sm9_fn_equ(h2, sig->h) != 1) { - return 0; - } - - return 1; -} - -int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, - size_t klen, uint8_t *kbuf, SM9_POINT *C) -{ - sm9_fn_t r; - sm9_fp12_t w; - uint8_t wbuf[32 * 12]; - uint8_t cbuf[65]; - SM3_KDF_CTX kdf_ctx; - - // A1: Q = H1(ID||hid,N) * P1 + Ppube - sm9_hash1(r, id, idlen, SM9_HID_ENC); - sm9_point_mul(C, r, SM9_P1); - sm9_point_add(C, C, &mpk->Ppube); - - do { - // A2: rand r in [1, N-1] - if (sm9_fn_rand(r) != 1) { - error_print(); - return -1; - } - - // A3: C1 = r * Q - sm9_point_mul(C, r, C); - sm9_point_to_uncompressed_octets(C, cbuf); - - // A4: g = e(Ppube, P2) - sm9_pairing(w, SM9_P2, &mpk->Ppube); - - // A5: w = g^r - sm9_fp12_pow(w, w, r); - sm9_fp12_to_bytes(w, wbuf); - - // A6: K = KDF(C || w || ID_B, klen), if K == 0, goto A2 - sm3_kdf_init(&kdf_ctx, klen); - sm3_kdf_update(&kdf_ctx, cbuf + 1, 64); - sm3_kdf_update(&kdf_ctx, wbuf, sizeof(wbuf)); - sm3_kdf_update(&kdf_ctx, (uint8_t *)id, idlen); - sm3_kdf_finish(&kdf_ctx, kbuf); - - } while (mem_is_zero(kbuf, klen) == 1); - - gmssl_secure_clear(&r, sizeof(r)); - gmssl_secure_clear(&w, sizeof(w)); - gmssl_secure_clear(wbuf, sizeof(wbuf)); - gmssl_secure_clear(&kdf_ctx, sizeof(kdf_ctx)); - - // A7: output (K, C) - return 1; -} - -int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const SM9_POINT *C, - size_t klen, uint8_t *kbuf) -{ - sm9_fp12_t w; - uint8_t wbuf[32 * 12]; - uint8_t cbuf[65]; - SM3_KDF_CTX kdf_ctx; - - // B1: check C in G1 - sm9_point_to_uncompressed_octets(C, cbuf); - - // B2: w = e(C, de); - sm9_pairing(w, &key->de, C); - sm9_fp12_to_bytes(w, wbuf); - - // B3: K = KDF(C || w || ID, klen) - sm3_kdf_init(&kdf_ctx, klen); - sm3_kdf_update(&kdf_ctx, cbuf + 1, 64); - sm3_kdf_update(&kdf_ctx, wbuf, sizeof(wbuf)); - sm3_kdf_update(&kdf_ctx, (uint8_t *)id, idlen); - sm3_kdf_finish(&kdf_ctx, kbuf); - - if (mem_is_zero(kbuf, klen)) { - error_print(); - return -1; - } - - gmssl_secure_clear(&w, sizeof(w)); - gmssl_secure_clear(wbuf, sizeof(wbuf)); - gmssl_secure_clear(&kdf_ctx, sizeof(kdf_ctx)); - - // B4: output K - return 1; -} - -int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, - SM9_POINT *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]) -{ - SM3_HMAC_CTX hmac_ctx; - uint8_t K[inlen + 32]; - - if (sm9_kem_encrypt(mpk, id, idlen, sizeof(K), K, C1) != 1) { - error_print(); - return -1; - } - gmssl_memxor(c2, K, in, inlen); - - //sm3_hmac(K + inlen, 32, c2, inlen, c3); - sm3_hmac_init(&hmac_ctx, K + inlen, SM3_HMAC_SIZE); - sm3_hmac_update(&hmac_ctx, c2, inlen); - sm3_hmac_finish(&hmac_ctx, c3); - gmssl_secure_clear(&hmac_ctx, sizeof(hmac_ctx)); - return 1; -} - -int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, - const SM9_POINT *C1, const uint8_t *c2, size_t c2len, const uint8_t c3[SM3_HMAC_SIZE], - uint8_t *out) -{ - SM3_HMAC_CTX hmac_ctx; - uint8_t k[c2len + SM3_HMAC_SIZE]; - uint8_t mac[SM3_HMAC_SIZE]; - - if (sm9_kem_decrypt(key, id, idlen, C1, sizeof(k), k) != 1) { - error_print(); - return -1; - } - //sm3_hmac(k + c2len, SM3_HMAC_SIZE, c2, c2len, mac); - sm3_hmac_init(&hmac_ctx, k + c2len, SM3_HMAC_SIZE); - sm3_hmac_update(&hmac_ctx, c2, c2len); - sm3_hmac_finish(&hmac_ctx, mac); - gmssl_secure_clear(&hmac_ctx, sizeof(hmac_ctx)); - - if (gmssl_secure_memcmp(c3, mac, sizeof(mac)) != 0) { - error_print(); - return -1; - } - gmssl_memxor(out, k, c2, c2len); - return 1; -} - -#define SM9_ENC_TYPE_XOR 0 -#define SM9_ENC_TYPE_ECB 1 -#define SM9_ENC_TYPE_CBC 2 -#define SM9_ENC_TYPE_OFB 4 -#define SM9_ENC_TYPE_CFB 8 - -/* -SM9Cipher ::= SEQUENCE { - EnType INTEGER, -- 0 for XOR - C1 BIT STRING, -- uncompressed octets of ECPoint - C3 OCTET STRING, -- 32 bytes HMAC-SM3 tag - CipherText OCTET STRING, -} -*/ -int sm9_ciphertext_to_der(const SM9_POINT *C1, const uint8_t *c2, size_t c2len, - const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen) -{ - int en_type = SM9_ENC_TYPE_XOR; - uint8_t c1[65]; - size_t len = 0; - - if (sm9_point_to_uncompressed_octets(C1, c1) != 1) { - error_print(); - return -1; - } - if (asn1_int_to_der(en_type, NULL, &len) != 1 - || asn1_bit_octets_to_der(c1, sizeof(c1), NULL, &len) != 1 - || asn1_octet_string_to_der(c3, SM3_HMAC_SIZE, NULL, &len) != 1 - || asn1_octet_string_to_der(c2, c2len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(en_type, out, outlen) != 1 - || asn1_bit_octets_to_der(c1, sizeof(c1), out, outlen) != 1 - || asn1_octet_string_to_der(c3, SM3_HMAC_SIZE, out, outlen) != 1 - || asn1_octet_string_to_der(c2, c2len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_ciphertext_from_der(SM9_POINT *C1, const uint8_t **c2, size_t *c2len, - const uint8_t **c3, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - int en_type; - const uint8_t *c1; - size_t c1len; - size_t c3len; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(&en_type, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&c1, &c1len, &d, &dlen) != 1 - || asn1_octet_string_from_der(c3, &c3len, &d, &dlen) != 1 - || asn1_octet_string_from_der(c2, c2len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (en_type != SM9_ENC_TYPE_XOR) { - error_print(); - return -1; - } - if (c1len != 65) { - error_print(); - return -1; - } - if (c3len != SM3_HMAC_SIZE) { - error_print(); - return -1; - } - if (sm9_point_from_uncompressed_octets(C1, c1) != 1) { - error_print(); - return -1; - } - return 1; -} - -int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM9_POINT C1; - uint8_t c2[inlen]; - uint8_t c3[SM3_HMAC_SIZE]; - - if (sm9_do_encrypt(mpk, id, idlen, in, inlen, &C1, c2, c3) != 1) { - error_print(); - return -1; - } - *outlen = 0; - if (sm9_ciphertext_to_der(&C1, c2, inlen, c3, &out, outlen) != 1) { // FIXME: when out == NULL - error_print(); - return -1; - } - return 1; -} - -int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM9_POINT C1; - const uint8_t *c2; - size_t c2len; - const uint8_t *c3; - - if (sm9_ciphertext_from_der(&C1, &c2, &c2len, &c3, &in, &inlen) != 1 - || asn1_length_is_zero(inlen) != 1) { - error_print(); - return -1; - } - *outlen = c2len; - if (!out) { - return 1; - } - if (sm9_do_decrypt(key, id, idlen, &C1, c2, c2len, c3, out) != 1) { - error_print(); - return -1; - } - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen) +{ + uint8_t hbuf[32]; + uint8_t Sbuf[65]; + size_t len = 0; + + sm9_fn_to_bytes(sig->h, hbuf); + sm9_point_to_uncompressed_octets(&sig->S, Sbuf); + + if (asn1_octet_string_to_der(hbuf, sizeof(hbuf), NULL, &len) != 1 + || asn1_bit_octets_to_der(Sbuf, sizeof(Sbuf), NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_octet_string_to_der(hbuf, sizeof(hbuf), out, outlen) != 1 + || asn1_bit_octets_to_der(Sbuf, sizeof(Sbuf), out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *h; + size_t hlen; + const uint8_t *S; + size_t Slen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_octet_string_from_der(&h, &hlen, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&S, &Slen, &d, &dlen) != 1 + || asn1_check(hlen == 32) != 1 + || asn1_check(Slen == 65) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (sm9_fn_from_bytes(sig->h, h) != 1 + || sm9_point_from_uncompressed_octets(&sig->S, S) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_sign_init(SM9_SIGN_CTX *ctx) +{ + const uint8_t prefix[1] = { SM9_HASH2_PREFIX }; + sm3_init(&ctx->sm3_ctx); + sm3_update(&ctx->sm3_ctx, prefix, sizeof(prefix)); + return 1; +} + +int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + sm3_update(&ctx->sm3_ctx, data, datalen); + return 1; +} + +int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen) +{ + SM9_SIGNATURE signature; + + if (sm9_do_sign(key, &ctx->sm3_ctx, &signature) != 1) { + error_print(); + return -1; + } + *siglen = 0; + if (sm9_signature_to_der(&signature, &sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_do_sign(const SM9_SIGN_KEY *key, const SM3_CTX *sm3_ctx, SM9_SIGNATURE *sig) +{ + sm9_fn_t r; + sm9_fp12_t g; + uint8_t wbuf[32 * 12]; + SM3_CTX ctx = *sm3_ctx; + SM3_CTX tmp_ctx; + uint8_t ct1[4] = {0,0,0,1}; + uint8_t ct2[4] = {0,0,0,2}; + uint8_t Ha[64]; + + // A1: g = e(P1, Ppubs) + sm9_pairing(g, &key->Ppubs, SM9_P1); + + do { + // A2: rand r in [1, N-1] + if (sm9_fn_rand(r) != 1) { + error_print(); + return -1; + } + //sm9_fn_from_hex(r, "00033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE"); // for testing + + // A3: w = g^r + sm9_fp12_pow(g, g, r); + sm9_fp12_to_bytes(g, wbuf); + + // A4: h = H2(M || w, N) + sm3_update(&ctx, wbuf, sizeof(wbuf)); + tmp_ctx = ctx; + sm3_update(&ctx, ct1, sizeof(ct1)); + sm3_finish(&ctx, Ha); + sm3_update(&tmp_ctx, ct2, sizeof(ct2)); + sm3_finish(&tmp_ctx, Ha + 32); + sm9_fn_from_hash(sig->h, Ha); + + // A5: l = (r - h) mod N, if l = 0, goto A2 + sm9_fn_sub(r, r, sig->h); + + } while (sm9_fn_is_zero(r)); + + // A6: S = l * dsA + sm9_point_mul(&sig->S, r, &key->ds); + + gmssl_secure_clear(&r, sizeof(r)); + gmssl_secure_clear(&g, sizeof(g)); + gmssl_secure_clear(wbuf, sizeof(wbuf)); + gmssl_secure_clear(&tmp_ctx, sizeof(tmp_ctx)); + gmssl_secure_clear(Ha, sizeof(Ha)); + + return 1; +} + +int sm9_verify_init(SM9_SIGN_CTX *ctx) +{ + const uint8_t prefix[1] = { SM9_HASH2_PREFIX }; + sm3_init(&ctx->sm3_ctx); + sm3_update(&ctx->sm3_ctx, prefix, sizeof(prefix)); + return 1; +} + +int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + sm3_update(&ctx->sm3_ctx, data, datalen); + return 1; +} + +int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, + const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen) +{ + int ret; + SM9_SIGNATURE signature; + + if (sm9_signature_from_der(&signature, &sig, &siglen) != 1 + || asn1_length_is_zero(siglen) != 1) { + error_print(); + return -1; + } + + if ((ret = sm9_do_verify(mpk, id, idlen, &ctx->sm3_ctx, &signature)) < 0) { + error_print(); + return -1; + } + return ret; +} + +int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, + const SM3_CTX *sm3_ctx, const SM9_SIGNATURE *sig) +{ + sm9_fn_t h1; + sm9_fn_t h2; + sm9_fp12_t g; + sm9_fp12_t t; + sm9_fp12_t u; + sm9_fp12_t w; + SM9_TWIST_POINT P; + uint8_t wbuf[32 * 12]; + SM3_CTX ctx = *sm3_ctx; + SM3_CTX tmp_ctx; + uint8_t ct1[4] = {0,0,0,1}; + uint8_t ct2[4] = {0,0,0,2}; + uint8_t Ha[64]; + + // B1: check h in [1, N-1] + + // B2: check S in G1 + + // B3: g = e(P1, Ppubs) + sm9_pairing(g, &mpk->Ppubs, SM9_P1); + + // B4: t = g^h + sm9_fp12_pow(t, g, sig->h); + + // B5: h1 = H1(ID || hid, N) + sm9_hash1(h1, id, idlen, SM9_HID_SIGN); + + // B6: P = h1 * P2 + Ppubs + sm9_twist_point_mul_generator(&P, h1); + sm9_twist_point_add_full(&P, &P, &mpk->Ppubs); + + // B7: u = e(S, P) + sm9_pairing(u, &P, &sig->S); + + // B8: w = u * t + sm9_fp12_mul(w, u, t); + sm9_fp12_to_bytes(w, wbuf); + + // B9: h2 = H2(M || w, N), check h2 == h + sm3_update(&ctx, wbuf, sizeof(wbuf)); + tmp_ctx = ctx; + sm3_update(&ctx, ct1, sizeof(ct1)); + sm3_finish(&ctx, Ha); + sm3_update(&tmp_ctx, ct2, sizeof(ct2)); + sm3_finish(&tmp_ctx, Ha + 32); + sm9_fn_from_hash(h2, Ha); + if (sm9_fn_equ(h2, sig->h) != 1) { + return 0; + } + + return 1; +} + +int sm9_kem_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, + size_t klen, uint8_t *kbuf, SM9_POINT *C) +{ + sm9_fn_t r; + sm9_fp12_t w; + uint8_t wbuf[32 * 12]; + uint8_t cbuf[65]; + SM3_KDF_CTX kdf_ctx; + + // A1: Q = H1(ID||hid,N) * P1 + Ppube + sm9_hash1(r, id, idlen, SM9_HID_ENC); + sm9_point_mul(C, r, SM9_P1); + sm9_point_add(C, C, &mpk->Ppube); + + do { + // A2: rand r in [1, N-1] + if (sm9_fn_rand(r) != 1) { + error_print(); + return -1; + } + + // A3: C1 = r * Q + sm9_point_mul(C, r, C); + sm9_point_to_uncompressed_octets(C, cbuf); + + // A4: g = e(Ppube, P2) + sm9_pairing(w, SM9_P2, &mpk->Ppube); + + // A5: w = g^r + sm9_fp12_pow(w, w, r); + sm9_fp12_to_bytes(w, wbuf); + + // A6: K = KDF(C || w || ID_B, klen), if K == 0, goto A2 + sm3_kdf_init(&kdf_ctx, klen); + sm3_kdf_update(&kdf_ctx, cbuf + 1, 64); + sm3_kdf_update(&kdf_ctx, wbuf, sizeof(wbuf)); + sm3_kdf_update(&kdf_ctx, (uint8_t *)id, idlen); + sm3_kdf_finish(&kdf_ctx, kbuf); + + } while (mem_is_zero(kbuf, klen) == 1); + + gmssl_secure_clear(&r, sizeof(r)); + gmssl_secure_clear(&w, sizeof(w)); + gmssl_secure_clear(wbuf, sizeof(wbuf)); + gmssl_secure_clear(&kdf_ctx, sizeof(kdf_ctx)); + + // A7: output (K, C) + return 1; +} + +int sm9_kem_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const SM9_POINT *C, + size_t klen, uint8_t *kbuf) +{ + sm9_fp12_t w; + uint8_t wbuf[32 * 12]; + uint8_t cbuf[65]; + SM3_KDF_CTX kdf_ctx; + + // B1: check C in G1 + sm9_point_to_uncompressed_octets(C, cbuf); + + // B2: w = e(C, de); + sm9_pairing(w, &key->de, C); + sm9_fp12_to_bytes(w, wbuf); + + // B3: K = KDF(C || w || ID, klen) + sm3_kdf_init(&kdf_ctx, klen); + sm3_kdf_update(&kdf_ctx, cbuf + 1, 64); + sm3_kdf_update(&kdf_ctx, wbuf, sizeof(wbuf)); + sm3_kdf_update(&kdf_ctx, (uint8_t *)id, idlen); + sm3_kdf_finish(&kdf_ctx, kbuf); + + if (mem_is_zero(kbuf, klen)) { + error_print(); + return -1; + } + + gmssl_secure_clear(&w, sizeof(w)); + gmssl_secure_clear(wbuf, sizeof(wbuf)); + gmssl_secure_clear(&kdf_ctx, sizeof(kdf_ctx)); + + // B4: output K + return 1; +} + +int sm9_do_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, + SM9_POINT *C1, uint8_t *c2, uint8_t c3[SM3_HMAC_SIZE]) +{ + SM3_HMAC_CTX hmac_ctx; + uint8_t K[inlen + 32]; + + if (sm9_kem_encrypt(mpk, id, idlen, sizeof(K), K, C1) != 1) { + error_print(); + return -1; + } + gmssl_memxor(c2, K, in, inlen); + + //sm3_hmac(K + inlen, 32, c2, inlen, c3); + sm3_hmac_init(&hmac_ctx, K + inlen, SM3_HMAC_SIZE); + sm3_hmac_update(&hmac_ctx, c2, inlen); + sm3_hmac_finish(&hmac_ctx, c3); + gmssl_secure_clear(&hmac_ctx, sizeof(hmac_ctx)); + return 1; +} + +int sm9_do_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, + const SM9_POINT *C1, const uint8_t *c2, size_t c2len, const uint8_t c3[SM3_HMAC_SIZE], + uint8_t *out) +{ + SM3_HMAC_CTX hmac_ctx; + uint8_t k[c2len + SM3_HMAC_SIZE]; + uint8_t mac[SM3_HMAC_SIZE]; + + if (sm9_kem_decrypt(key, id, idlen, C1, sizeof(k), k) != 1) { + error_print(); + return -1; + } + //sm3_hmac(k + c2len, SM3_HMAC_SIZE, c2, c2len, mac); + sm3_hmac_init(&hmac_ctx, k + c2len, SM3_HMAC_SIZE); + sm3_hmac_update(&hmac_ctx, c2, c2len); + sm3_hmac_finish(&hmac_ctx, mac); + gmssl_secure_clear(&hmac_ctx, sizeof(hmac_ctx)); + + if (gmssl_secure_memcmp(c3, mac, sizeof(mac)) != 0) { + error_print(); + return -1; + } + gmssl_memxor(out, k, c2, c2len); + return 1; +} + +#define SM9_ENC_TYPE_XOR 0 +#define SM9_ENC_TYPE_ECB 1 +#define SM9_ENC_TYPE_CBC 2 +#define SM9_ENC_TYPE_OFB 4 +#define SM9_ENC_TYPE_CFB 8 + +/* +SM9Cipher ::= SEQUENCE { + EnType INTEGER, -- 0 for XOR + C1 BIT STRING, -- uncompressed octets of ECPoint + C3 OCTET STRING, -- 32 bytes HMAC-SM3 tag + CipherText OCTET STRING, +} +*/ +int sm9_ciphertext_to_der(const SM9_POINT *C1, const uint8_t *c2, size_t c2len, + const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen) +{ + int en_type = SM9_ENC_TYPE_XOR; + uint8_t c1[65]; + size_t len = 0; + + if (sm9_point_to_uncompressed_octets(C1, c1) != 1) { + error_print(); + return -1; + } + if (asn1_int_to_der(en_type, NULL, &len) != 1 + || asn1_bit_octets_to_der(c1, sizeof(c1), NULL, &len) != 1 + || asn1_octet_string_to_der(c3, SM3_HMAC_SIZE, NULL, &len) != 1 + || asn1_octet_string_to_der(c2, c2len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(en_type, out, outlen) != 1 + || asn1_bit_octets_to_der(c1, sizeof(c1), out, outlen) != 1 + || asn1_octet_string_to_der(c3, SM3_HMAC_SIZE, out, outlen) != 1 + || asn1_octet_string_to_der(c2, c2len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_ciphertext_from_der(SM9_POINT *C1, const uint8_t **c2, size_t *c2len, + const uint8_t **c3, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + int en_type; + const uint8_t *c1; + size_t c1len; + size_t c3len; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(&en_type, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&c1, &c1len, &d, &dlen) != 1 + || asn1_octet_string_from_der(c3, &c3len, &d, &dlen) != 1 + || asn1_octet_string_from_der(c2, c2len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (en_type != SM9_ENC_TYPE_XOR) { + error_print(); + return -1; + } + if (c1len != 65) { + error_print(); + return -1; + } + if (c3len != SM3_HMAC_SIZE) { + error_print(); + return -1; + } + if (sm9_point_from_uncompressed_octets(C1, c1) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM9_POINT C1; + uint8_t c2[inlen]; + uint8_t c3[SM3_HMAC_SIZE]; + + if (sm9_do_encrypt(mpk, id, idlen, in, inlen, &C1, c2, c3) != 1) { + error_print(); + return -1; + } + *outlen = 0; + if (sm9_ciphertext_to_der(&C1, c2, inlen, c3, &out, outlen) != 1) { // FIXME: when out == NULL + error_print(); + return -1; + } + return 1; +} + +int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM9_POINT C1; + const uint8_t *c2; + size_t c2len; + const uint8_t *c3; + + if (sm9_ciphertext_from_der(&C1, &c2, &c2len, &c3, &in, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + error_print(); + return -1; + } + *outlen = c2len; + if (!out) { + return 1; + } + if (sm9_do_decrypt(key, id, idlen, &C1, c2, c2len, c3, out) != 1) { + error_print(); + return -1; + } + return 1; +} diff --git a/src/tlcp.c b/src/tlcp.c index 15173e7b..e6d65342 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1012 +7,1013 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 }; -static const size_t tlcp_ciphers_count = sizeof(tlcp_ciphers)/sizeof(tlcp_ciphers[0]); - -int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) -{ - // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 - // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) - format |= tlcp_ciphers[0] << 8; - return tls_record_print(fp, record, recordlen, format, indent); -} - -int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *recordlen, - const uint8_t *sig, size_t siglen) -{ - int type = TLS_handshake_server_key_exchange; - uint8_t *p; - size_t len = 0; - - if (!record || !recordlen || !sig || !siglen) { - error_print(); - return -1; - } - if (siglen > SM2_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - if (tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - return -1; - } - p = tls_handshake_data(tls_record_data(record)); - // 注意TLCP的ServerKeyExchange中的签名值需要封装在uint16array中 - // 但是CertificateVerify中直接装载签名值DER - tls_uint16array_to_bytes(sig, siglen, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - return 1; -} - -int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record, - const uint8_t **sig, size_t *siglen) -{ - int type; - const uint8_t *p; - size_t len; - - if (!record || !sig || !siglen) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_server_key_exchange) { - error_print(); - return -1; - } - if (tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1) { - error_print(); - return -1; - } - if (len) { - error_print(); - return -1; - } - return 1; -} - -int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - const uint8_t *sig; - size_t siglen; - - format_print(fp, format, indent, "ServerKeyExchange\n"); - indent += 4; - if (tls_uint16array_from_bytes(&sig, &siglen, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, format, indent, "signature", sig, siglen); - if (datalen) { - error_print(); - return -1; - } - return 1; -} - -int tlcp_do_connect(TLS_CONNECT *conn) -{ - int ret = -1; - uint8_t *record = conn->record; - uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; - size_t recordlen, finished_record_len; - - uint8_t client_random[32]; - uint8_t server_random[32]; - int protocol; - int cipher_suite; - const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - const uint8_t *exts; - size_t exts_len; - - SM2_KEY server_sign_key; - SM2_KEY server_enc_key; - SM2_SIGN_CTX verify_ctx; - SM2_SIGN_CTX sign_ctx; - const uint8_t *sig; - size_t siglen; - uint8_t pre_master_secret[48]; - uint8_t enced_pre_master_secret[SM2_MAX_CIPHERTEXT_SIZE]; - size_t enced_pre_master_secret_len; - SM3_CTX sm3_ctx; - SM3_CTX tmp_sm3_ctx; - uint8_t sm3_hash[32]; - const uint8_t *verify_data; - size_t verify_data_len; - uint8_t local_verify_data[12]; - - int handshake_type; - const uint8_t *server_enc_cert; - size_t server_enc_cert_len; - uint8_t server_enc_cert_lenbuf[3]; - const uint8_t *cp; - uint8_t *p; - size_t len; - - int depth = 5; - int alert = 0; - int verify_result; - - - // 初始化记录缓冲 - tls_record_set_protocol(record, TLS_protocol_tlcp); - tls_record_set_protocol(finished_record, TLS_protocol_tlcp); - - // 准备Finished Context(和ClientVerify) - sm3_init(&sm3_ctx); - if (conn->client_certs_len) - sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - - - // send ClientHello - tls_random_generate(client_random); - if (tls_record_set_handshake_client_hello(record, &recordlen, - TLS_protocol_tlcp, client_random, NULL, 0, - tlcp_ciphers, tlcp_ciphers_count, NULL, 0) != 1) { - error_print(); - goto end; - } - tls_trace("send ClientHello\n"); - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerHello - tls_trace("recv ServerHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - if (tls_record_get_handshake_server_hello(record, - &protocol, &random, &session_id, &session_id_len, &cipher_suite, - &exts, &exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (protocol != TLS_protocol_tlcp) { - tls_send_alert(conn, TLS_alert_protocol_version); - error_print(); - goto end; - } - if (tls_cipher_suite_in_list(cipher_suite, tlcp_ciphers, tlcp_ciphers_count) != 1) { - tls_send_alert(conn, TLS_alert_handshake_failure); - error_print(); - goto end; - } - if (exts) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - memcpy(server_random, random, 32); - memcpy(conn->session_id, session_id, session_id_len); - conn->cipher_suite = cipher_suite; - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerCertificate - tls_trace("recv ServerCertificate\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - - if (tls_record_get_handshake_certificate(record, - conn->server_certs, &conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // verify ServerCertificate - if (conn->ca_certs_len) { - // 只有提供了CA证书才验证服务器证书链 - // FIXME: 逻辑需要再检查 - if (x509_certs_verify_tlcp(conn->server_certs, conn->server_certs_len, - conn->ca_certs, conn->ca_certs_len, depth, &verify_result) != 1) { - error_print(); - tls_send_alert(conn, alert); - goto end; - } - } - - // recv ServerKeyExchange - tls_trace("recv ServerKeyExchange\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tlcp_record_get_handshake_server_key_exchange_pke(record, &sig, &siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // verify ServerKeyExchange - if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 - || x509_cert_get_subject_public_key(cp, len, &server_sign_key) != 1 - || x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 1, &server_enc_cert, &server_enc_cert_len) != 1 - || x509_cert_get_subject_public_key(server_enc_cert, server_enc_cert_len, &server_enc_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - p = server_enc_cert_lenbuf; len = 0; - tls_uint24_to_bytes(server_enc_cert_len, &p, &len); - if (sm2_verify_init(&verify_ctx, &server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 - || sm2_verify_update(&verify_ctx, client_random, 32) != 1 - || sm2_verify_update(&verify_ctx, server_random, 32) != 1 - || sm2_verify_update(&verify_ctx, server_enc_cert_lenbuf, 3) != 1 - || sm2_verify_update(&verify_ctx, server_enc_cert, server_enc_cert_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (sm2_verify_finish(&verify_ctx, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - - // recv CertificateRequest or ServerHelloDone - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp - || tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (handshake_type == TLS_handshake_certificate_request) { - const uint8_t *cert_types; - size_t cert_types_len; - const uint8_t *ca_names; - size_t ca_names_len; - - // recv CertificateRequest - tls_trace("recv CertificateRequest\n"); - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate_request(record, - &cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if(!conn->client_certs_len) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1 - || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unsupported_certificate); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerHelloDone - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - } else { - // 这个得处理一下 - conn->client_certs_len = 0; - gmssl_secure_clear(&conn->sign_key, sizeof(SM2_KEY)); - //client_sign_key = NULL; - } - tls_trace("recv ServerHelloDone\n"); - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_server_hello_done(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // send ClientCertificate - if (conn->client_certs_len) { - tls_trace("send ClientCertificate\n"); - if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - } - - // generate MASTER_SECRET - tls_trace("generate secrets\n"); - if (tls_pre_master_secret_generate(pre_master_secret, TLS_protocol_tlcp) != 1 - || tls_prf(pre_master_secret, 48, "master secret", - client_random, 32, server_random, 32, - 48, conn->master_secret) != 1 - || tls_prf(conn->master_secret, 48, "key expansion", - server_random, 32, client_random, 32, - 96, conn->key_block) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); - sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); - sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); - sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - /* - tls_secrets_print(stderr, - pre_master_secret, 48, - client_random, server_random, - conn->master_secret, - conn->key_block, 96, - 0, 4); - */ - - // send ClientKeyExchange - tls_trace("send ClientKeyExchange\n"); - if (sm2_encrypt(&server_enc_key, pre_master_secret, 48, - enced_pre_master_secret, &enced_pre_master_secret_len) != 1 - || tls_record_set_handshake_client_key_exchange_pke(record, &recordlen, - enced_pre_master_secret, enced_pre_master_secret_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // send CertificateVerify - if (conn->client_certs_len) { - tls_trace("send CertificateVerify\n"); - uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; - if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 - || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - } - - // send [ChangeCipherSpec] - tls_trace("send [ChangeCipherSpec]\n"); - if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // send Client Finished - tls_trace("send Finished\n"); - memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); - sm3_finish(&tmp_sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "client finished", - sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1 - || tls_record_set_handshake_finished(finished_record, &finished_record_len, - local_verify_data, sizeof(local_verify_data)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); - sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); - - // encrypt Client Finished - tls_trace("encrypt Finished\n"); - if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, - conn->client_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_seq_num_incr(conn->client_seq_num); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // [ChangeCipherSpec] - tls_trace("recv [ChangeCipherSpec]\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_change_cipher_spec(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - - // Finished - tls_trace("recv Finished\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (recordlen > sizeof(finished_record)) { - error_print(); // 解密可能导致 finished_record 溢出 - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_trace("decrypt Finished\n"); - if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, - conn->server_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); - tls_seq_num_incr(conn->server_seq_num); - if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (verify_data_len != sizeof(local_verify_data)) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_finish(&sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "server finished", - sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - fprintf(stderr, "Connection established!\n"); - - - conn->protocol = TLS_protocol_tlcp; - conn->cipher_suite = cipher_suite; - - ret = 1; - -end: - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - return 1; -} - -int tlcp_do_accept(TLS_CONNECT *conn) -{ - int ret = -1; - - int client_verify = 0; - - uint8_t *record = conn->record; - uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; // 解密可能导致前面的record被覆盖 - size_t recordlen, finished_record_len; - const int server_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 }; // 未来应该支持GCM/CBC两个套件 - - // ClientHello, ServerHello - uint8_t client_random[32]; - uint8_t server_random[32]; - int protocol; - const uint8_t *random; - const uint8_t *session_id; // TLCP服务器忽略客户端SessionID,也不主动设置SessionID - size_t session_id_len; - const uint8_t *client_ciphers; - size_t client_ciphers_len; - const uint8_t *exts; - size_t exts_len; - - // ServerKeyExchange - const uint8_t *server_enc_cert; - size_t server_enc_cert_len; - uint8_t server_enc_cert_lenbuf[3]; - SM2_SIGN_CTX sign_ctx; - uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - // ClientCertificate, CertificateVerify - TLS_CLIENT_VERIFY_CTX client_verify_ctx; - SM2_KEY client_sign_key; - const uint8_t *sig; - const int verify_depth = 5; - int verify_result; - - // ClientKeyExchange - const uint8_t *enced_pms; - size_t enced_pms_len; - uint8_t pre_master_secret[SM2_MAX_PLAINTEXT_SIZE]; // sm2_decrypt 保证输出不会溢出 - size_t pre_master_secret_len; - - // Finished - SM3_CTX sm3_ctx; - SM3_CTX tmp_sm3_ctx; - uint8_t sm3_hash[32]; - uint8_t local_verify_data[12]; - const uint8_t *verify_data; - size_t verify_data_len; - - uint8_t *p; - const uint8_t *cp; - size_t len; - - - // 服务器端如果设置了CA - if (conn->ca_certs_len) - client_verify = 1; - - // 初始化Finished和客户端验证环境 - sm3_init(&sm3_ctx); - if (client_verify) - tls_client_verify_init(&client_verify_ctx); - - - // recv ClientHello - tls_trace("recv ClientHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - if (tls_record_get_handshake_client_hello(record, - &protocol, &random, &session_id, &session_id_len, - &client_ciphers, &client_ciphers_len, - &exts, &exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (protocol != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - memcpy(client_random, random, 32); - if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, - server_ciphers, sizeof(server_ciphers)/sizeof(server_ciphers[0]), - &conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_insufficient_security); - goto end; - } - if (exts) { - // 忽略客户端扩展错误可以兼容错误的TLCP客户端实现 - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - - // send ServerHello - tls_trace("send ServerHello\n"); - tls_random_generate(server_random); - if (tls_record_set_handshake_server_hello(record, &recordlen, - TLS_protocol_tlcp, server_random, NULL, 0, - conn->cipher_suite, NULL, 0) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send ServerCertificate - tls_trace("send ServerCertificate\n"); - if (tls_record_set_handshake_certificate(record, &recordlen, - conn->server_certs, conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send ServerKeyExchange - tls_trace("send ServerKeyExchange\n"); - if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 1, - &server_enc_cert, &server_enc_cert_len) != 1) { - error_print(); - goto end; - } - p = server_enc_cert_lenbuf; len = 0; - tls_uint24_to_bytes(server_enc_cert_len, &p, &len); - if (sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 - || sm2_sign_update(&sign_ctx, client_random, 32) != 1 - || sm2_sign_update(&sign_ctx, server_random, 32) != 1 - || sm2_sign_update(&sign_ctx, server_enc_cert_lenbuf, 3) != 1 - || sm2_sign_update(&sign_ctx, server_enc_cert, server_enc_cert_len) != 1 - || sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tlcp_record_set_handshake_server_key_exchange_pke(record, &recordlen, sigbuf, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send CertificateRequest - if (client_verify) { - const uint8_t cert_types[] = { TLS_cert_type_ecdsa_sign }; - uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; // TODO: 根据客户端验证CA证书列计算缓冲大小,或直接输出到record缓冲 - size_t ca_names_len = 0; - - tls_trace("send CertificateRequest\n"); - if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), - conn->ca_certs, conn->ca_certs_len) != 1) { - error_print(); - goto end; - } - if (tls_record_set_handshake_certificate_request(record, &recordlen, - cert_types, sizeof(cert_types), - ca_names, ca_names_len) != 1) { - error_print(); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - } - - // send ServerHelloDone - tls_trace("send ServerHelloDone\n"); - tls_record_set_handshake_server_hello_done(record, &recordlen); - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // recv ClientCertificate - if (conn->ca_certs_len) { - tls_trace("recv ClientCertificate\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate(record, conn->client_certs, &conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (x509_certs_verify(conn->client_certs, conn->client_certs_len, - conn->ca_certs, conn->ca_certs_len, verify_depth, &verify_result) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - } - - // ClientKeyExchange - tls_trace("recv ClientKeyExchange\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_client_key_exchange_pke(record, &enced_pms, &enced_pms_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (sm2_decrypt(&conn->kenc_key, enced_pms, enced_pms_len, - pre_master_secret, &pre_master_secret_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - if (pre_master_secret_len != 48) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // recv CertificateVerify - if (client_verify) { - tls_trace("recv CertificateVerify\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - tls_send_alert(conn, TLS_alert_unexpected_message); - error_print(); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate_verify(record, &sig, &siglen) != 1) { - tls_send_alert(conn, TLS_alert_unexpected_message); - error_print(); - goto end; - } - if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cp, &len) != 1 - || x509_cert_get_subject_public_key(cp, len, &client_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - } - - // generate secrets - tls_trace("generate secrets\n"); - if (tls_prf(pre_master_secret, 48, "master secret", - client_random, 32, server_random, 32, - 48, conn->master_secret) != 1 - || tls_prf(conn->master_secret, 48, "key expansion", - server_random, 32, client_random, 32, - 96, conn->key_block) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); - sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); - sm4_set_decrypt_key(&conn->client_write_enc_key, conn->key_block + 64); - sm4_set_encrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - /* - tls_secrets_print(stderr, - pre_master_secret, 48, - client_random, server_random, - conn->master_secret, - conn->key_block, 96, - 0, 4); - */ - - // recv [ChangeCipherSpec] - tls_trace("recv [ChangeCipherSpec]\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_change_cipher_spec(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - - // recv ClientFinished - tls_trace("recv Finished\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != TLS_protocol_tlcp) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (recordlen > sizeof(finished_record)) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - - // decrypt ClientFinished - tls_trace("decrypt Finished\n"); - if (tls_record_decrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, - conn->client_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); - tls_seq_num_incr(conn->client_seq_num); - if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - if (verify_data_len != sizeof(local_verify_data)) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - - // verify ClientFinished - memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(SM3_CTX)); - sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); - sm3_finish(&tmp_sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "client finished", sm3_hash, 32, NULL, 0, - sizeof(local_verify_data), local_verify_data) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { - error_puts("client_finished.verify_data verification failure"); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - - // send [ChangeCipherSpec] - tls_trace("send [ChangeCipherSpec]\n"); - if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // send ServerFinished - tls_trace("send Finished\n"); - sm3_finish(&sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "server finished", sm3_hash, 32, NULL, 0, - sizeof(local_verify_data), local_verify_data) != 1 - || tls_record_set_handshake_finished(finished_record, &finished_record_len, - local_verify_data, sizeof(local_verify_data)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); - if (tls_record_encrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, - conn->server_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls_trace("encrypt Finished\n"); - tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_seq_num_incr(conn->server_seq_num); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - conn->protocol = TLS_protocol_tlcp; - - fprintf(stderr, "Connection Established!\n\n"); - ret = 1; - -end: - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - if (client_verify) tls_client_verify_cleanup(&client_verify_ctx); - return ret; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 }; +static const size_t tlcp_ciphers_count = sizeof(tlcp_ciphers)/sizeof(tlcp_ciphers[0]); + +int tlcp_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 + // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) + format |= tlcp_ciphers[0] << 8; + return tls_record_print(fp, record, recordlen, format, indent); +} + +int tlcp_record_set_handshake_server_key_exchange_pke(uint8_t *record, size_t *recordlen, + const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_server_key_exchange; + uint8_t *p; + size_t len = 0; + + if (!record || !recordlen || !sig || !siglen) { + error_print(); + return -1; + } + if (siglen > SM2_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + if (tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + return -1; + } + p = tls_handshake_data(tls_record_data(record)); + // 注意TLCP的ServerKeyExchange中的签名值需要封装在uint16array中 + // 但是CertificateVerify中直接装载签名值DER + tls_uint16array_to_bytes(sig, siglen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tlcp_record_get_handshake_server_key_exchange_pke(const uint8_t *record, + const uint8_t **sig, size_t *siglen) +{ + int type; + const uint8_t *p; + size_t len; + + if (!record || !sig || !siglen) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_server_key_exchange) { + error_print(); + return -1; + } + if (tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1) { + error_print(); + return -1; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + +int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + const uint8_t *sig; + size_t siglen; + + format_print(fp, format, indent, "ServerKeyExchange\n"); + indent += 4; + if (tls_uint16array_from_bytes(&sig, &siglen, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, format, indent, "signature", sig, siglen); + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +int tlcp_do_connect(TLS_CONNECT *conn) +{ + int ret = -1; + uint8_t *record = conn->record; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; + size_t recordlen, finished_record_len; + + uint8_t client_random[32]; + uint8_t server_random[32]; + int protocol; + int cipher_suite; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *exts; + size_t exts_len; + + SM2_KEY server_sign_key; + SM2_KEY server_enc_key; + SM2_SIGN_CTX verify_ctx; + SM2_SIGN_CTX sign_ctx; + const uint8_t *sig; + size_t siglen; + uint8_t pre_master_secret[48]; + uint8_t enced_pre_master_secret[SM2_MAX_CIPHERTEXT_SIZE]; + size_t enced_pre_master_secret_len; + SM3_CTX sm3_ctx; + SM3_CTX tmp_sm3_ctx; + uint8_t sm3_hash[32]; + const uint8_t *verify_data; + size_t verify_data_len; + uint8_t local_verify_data[12]; + + int handshake_type; + const uint8_t *server_enc_cert; + size_t server_enc_cert_len; + uint8_t server_enc_cert_lenbuf[3]; + const uint8_t *cp; + uint8_t *p; + size_t len; + + int depth = 5; + int alert = 0; + int verify_result; + + + // 初始化记录缓冲 + tls_record_set_protocol(record, TLS_protocol_tlcp); + tls_record_set_protocol(finished_record, TLS_protocol_tlcp); + + // 准备Finished Context(和ClientVerify) + sm3_init(&sm3_ctx); + if (conn->client_certs_len) + sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + + + // send ClientHello + tls_random_generate(client_random); + if (tls_record_set_handshake_client_hello(record, &recordlen, + TLS_protocol_tlcp, client_random, NULL, 0, + tlcp_ciphers, tlcp_ciphers_count, NULL, 0) != 1) { + error_print(); + goto end; + } + tls_trace("send ClientHello\n"); + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHello + tls_trace("recv ServerHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + if (tls_record_get_handshake_server_hello(record, + &protocol, &random, &session_id, &session_id_len, &cipher_suite, + &exts, &exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (protocol != TLS_protocol_tlcp) { + tls_send_alert(conn, TLS_alert_protocol_version); + error_print(); + goto end; + } + if (tls_cipher_suite_in_list(cipher_suite, tlcp_ciphers, tlcp_ciphers_count) != 1) { + tls_send_alert(conn, TLS_alert_handshake_failure); + error_print(); + goto end; + } + if (exts) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->cipher_suite = cipher_suite; + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerCertificate + tls_trace("recv ServerCertificate\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + + if (tls_record_get_handshake_certificate(record, + conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerCertificate + if (conn->ca_certs_len) { + // 只有提供了CA证书才验证服务器证书链 + // FIXME: 逻辑需要再检查 + if (x509_certs_verify_tlcp(conn->server_certs, conn->server_certs_len, + conn->ca_certs, conn->ca_certs_len, depth, &verify_result) != 1) { + error_print(); + tls_send_alert(conn, alert); + goto end; + } + } + + // recv ServerKeyExchange + tls_trace("recv ServerKeyExchange\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tlcp_record_get_handshake_server_key_exchange_pke(record, &sig, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerKeyExchange + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 + || x509_cert_get_subject_public_key(cp, len, &server_sign_key) != 1 + || x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 1, &server_enc_cert, &server_enc_cert_len) != 1 + || x509_cert_get_subject_public_key(server_enc_cert, server_enc_cert_len, &server_enc_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + p = server_enc_cert_lenbuf; len = 0; + tls_uint24_to_bytes(server_enc_cert_len, &p, &len); + if (sm2_verify_init(&verify_ctx, &server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 + || sm2_verify_update(&verify_ctx, client_random, 32) != 1 + || sm2_verify_update(&verify_ctx, server_random, 32) != 1 + || sm2_verify_update(&verify_ctx, server_enc_cert_lenbuf, 3) != 1 + || sm2_verify_update(&verify_ctx, server_enc_cert, server_enc_cert_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (sm2_verify_finish(&verify_ctx, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + + // recv CertificateRequest or ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp + || tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (handshake_type == TLS_handshake_certificate_request) { + const uint8_t *cert_types; + size_t cert_types_len; + const uint8_t *ca_names; + size_t ca_names_len; + + // recv CertificateRequest + tls_trace("recv CertificateRequest\n"); + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate_request(record, + &cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if(!conn->client_certs_len) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1 + || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unsupported_certificate); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + } else { + // 这个得处理一下 + conn->client_certs_len = 0; + gmssl_secure_clear(&conn->sign_key, sizeof(SM2_KEY)); + //client_sign_key = NULL; + } + tls_trace("recv ServerHelloDone\n"); + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_server_hello_done(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send ClientCertificate + if (conn->client_certs_len) { + tls_trace("send ClientCertificate\n"); + if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + } + + // generate MASTER_SECRET + tls_trace("generate secrets\n"); + if (tls_pre_master_secret_generate(pre_master_secret, TLS_protocol_tlcp) != 1 + || tls_prf(pre_master_secret, 48, "master secret", + client_random, 32, server_random, 32, + 48, conn->master_secret) != 1 + || tls_prf(conn->master_secret, 48, "key expansion", + server_random, 32, client_random, 32, + 96, conn->key_block) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); + sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); + sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); + sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); + /* + tls_secrets_print(stderr, + pre_master_secret, 48, + client_random, server_random, + conn->master_secret, + conn->key_block, 96, + 0, 4); + */ + + // send ClientKeyExchange + tls_trace("send ClientKeyExchange\n"); + if (sm2_encrypt(&server_enc_key, pre_master_secret, 48, + enced_pre_master_secret, &enced_pre_master_secret_len) != 1 + || tls_record_set_handshake_client_key_exchange_pke(record, &recordlen, + enced_pre_master_secret, enced_pre_master_secret_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send CertificateVerify + if (conn->client_certs_len) { + tls_trace("send CertificateVerify\n"); + uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; + if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 + || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + } + + // send [ChangeCipherSpec] + tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // send Client Finished + tls_trace("send Finished\n"); + memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); + sm3_finish(&tmp_sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "client finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1 + || tls_record_set_handshake_finished(finished_record, &finished_record_len, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); + sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); + + // encrypt Client Finished + tls_trace("encrypt Finished\n"); + if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, + conn->client_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // [ChangeCipherSpec] + tls_trace("recv [ChangeCipherSpec]\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + // Finished + tls_trace("recv Finished\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (recordlen > sizeof(finished_record)) { + error_print(); // 解密可能导致 finished_record 溢出 + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_trace("decrypt Finished\n"); + if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, + conn->server_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_finish(&sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "server finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + fprintf(stderr, "Connection established!\n"); + + + conn->protocol = TLS_protocol_tlcp; + conn->cipher_suite = cipher_suite; + + ret = 1; + +end: + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); + return 1; +} + +int tlcp_do_accept(TLS_CONNECT *conn) +{ + int ret = -1; + + int client_verify = 0; + + uint8_t *record = conn->record; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; // 解密可能导致前面的record被覆盖 + size_t recordlen, finished_record_len; + const int server_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3 }; // 未来应该支持GCM/CBC两个套件 + + // ClientHello, ServerHello + uint8_t client_random[32]; + uint8_t server_random[32]; + int protocol; + const uint8_t *random; + const uint8_t *session_id; // TLCP服务器忽略客户端SessionID,也不主动设置SessionID + size_t session_id_len; + const uint8_t *client_ciphers; + size_t client_ciphers_len; + const uint8_t *exts; + size_t exts_len; + + // ServerKeyExchange + const uint8_t *server_enc_cert; + size_t server_enc_cert_len; + uint8_t server_enc_cert_lenbuf[3]; + SM2_SIGN_CTX sign_ctx; + uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + // ClientCertificate, CertificateVerify + TLS_CLIENT_VERIFY_CTX client_verify_ctx; + SM2_KEY client_sign_key; + const uint8_t *sig; + const int verify_depth = 5; + int verify_result; + + // ClientKeyExchange + const uint8_t *enced_pms; + size_t enced_pms_len; + uint8_t pre_master_secret[SM2_MAX_PLAINTEXT_SIZE]; // sm2_decrypt 保证输出不会溢出 + size_t pre_master_secret_len; + + // Finished + SM3_CTX sm3_ctx; + SM3_CTX tmp_sm3_ctx; + uint8_t sm3_hash[32]; + uint8_t local_verify_data[12]; + const uint8_t *verify_data; + size_t verify_data_len; + + uint8_t *p; + const uint8_t *cp; + size_t len; + + + // 服务器端如果设置了CA + if (conn->ca_certs_len) + client_verify = 1; + + // 初始化Finished和客户端验证环境 + sm3_init(&sm3_ctx); + if (client_verify) + tls_client_verify_init(&client_verify_ctx); + + + // recv ClientHello + tls_trace("recv ClientHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + if (tls_record_get_handshake_client_hello(record, + &protocol, &random, &session_id, &session_id_len, + &client_ciphers, &client_ciphers_len, + &exts, &exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (protocol != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + memcpy(client_random, random, 32); + if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, + server_ciphers, sizeof(server_ciphers)/sizeof(server_ciphers[0]), + &conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + goto end; + } + if (exts) { + // 忽略客户端扩展错误可以兼容错误的TLCP客户端实现 + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + + // send ServerHello + tls_trace("send ServerHello\n"); + tls_random_generate(server_random); + if (tls_record_set_handshake_server_hello(record, &recordlen, + TLS_protocol_tlcp, server_random, NULL, 0, + conn->cipher_suite, NULL, 0) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send ServerCertificate + tls_trace("send ServerCertificate\n"); + if (tls_record_set_handshake_certificate(record, &recordlen, + conn->server_certs, conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send ServerKeyExchange + tls_trace("send ServerKeyExchange\n"); + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 1, + &server_enc_cert, &server_enc_cert_len) != 1) { + error_print(); + goto end; + } + p = server_enc_cert_lenbuf; len = 0; + tls_uint24_to_bytes(server_enc_cert_len, &p, &len); + if (sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 + || sm2_sign_update(&sign_ctx, client_random, 32) != 1 + || sm2_sign_update(&sign_ctx, server_random, 32) != 1 + || sm2_sign_update(&sign_ctx, server_enc_cert_lenbuf, 3) != 1 + || sm2_sign_update(&sign_ctx, server_enc_cert, server_enc_cert_len) != 1 + || sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tlcp_record_set_handshake_server_key_exchange_pke(record, &recordlen, sigbuf, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send CertificateRequest + if (client_verify) { + const uint8_t cert_types[] = { TLS_cert_type_ecdsa_sign }; + uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; // TODO: 根据客户端验证CA证书列计算缓冲大小,或直接输出到record缓冲 + size_t ca_names_len = 0; + + tls_trace("send CertificateRequest\n"); + if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), + conn->ca_certs, conn->ca_certs_len) != 1) { + error_print(); + goto end; + } + if (tls_record_set_handshake_certificate_request(record, &recordlen, + cert_types, sizeof(cert_types), + ca_names, ca_names_len) != 1) { + error_print(); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + } + + // send ServerHelloDone + tls_trace("send ServerHelloDone\n"); + tls_record_set_handshake_server_hello_done(record, &recordlen); + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // recv ClientCertificate + if (conn->ca_certs_len) { + tls_trace("recv ClientCertificate\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate(record, conn->client_certs, &conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (x509_certs_verify(conn->client_certs, conn->client_certs_len, + conn->ca_certs, conn->ca_certs_len, verify_depth, &verify_result) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + } + + // ClientKeyExchange + tls_trace("recv ClientKeyExchange\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_client_key_exchange_pke(record, &enced_pms, &enced_pms_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (sm2_decrypt(&conn->kenc_key, enced_pms, enced_pms_len, + pre_master_secret, &pre_master_secret_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + if (pre_master_secret_len != 48) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // recv CertificateVerify + if (client_verify) { + tls_trace("recv CertificateVerify\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + tls_send_alert(conn, TLS_alert_unexpected_message); + error_print(); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate_verify(record, &sig, &siglen) != 1) { + tls_send_alert(conn, TLS_alert_unexpected_message); + error_print(); + goto end; + } + if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cp, &len) != 1 + || x509_cert_get_subject_public_key(cp, len, &client_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + } + + // generate secrets + tls_trace("generate secrets\n"); + if (tls_prf(pre_master_secret, 48, "master secret", + client_random, 32, server_random, 32, + 48, conn->master_secret) != 1 + || tls_prf(conn->master_secret, 48, "key expansion", + server_random, 32, client_random, 32, + 96, conn->key_block) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); + sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); + sm4_set_decrypt_key(&conn->client_write_enc_key, conn->key_block + 64); + sm4_set_encrypt_key(&conn->server_write_enc_key, conn->key_block + 80); + /* + tls_secrets_print(stderr, + pre_master_secret, 48, + client_random, server_random, + conn->master_secret, + conn->key_block, 96, + 0, 4); + */ + + // recv [ChangeCipherSpec] + tls_trace("recv [ChangeCipherSpec]\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + // recv ClientFinished + tls_trace("recv Finished\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != TLS_protocol_tlcp) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (recordlen > sizeof(finished_record)) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + + // decrypt ClientFinished + tls_trace("decrypt Finished\n"); + if (tls_record_decrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, + conn->client_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + + // verify ClientFinished + memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(SM3_CTX)); + sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); + sm3_finish(&tmp_sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "client finished", sm3_hash, 32, NULL, 0, + sizeof(local_verify_data), local_verify_data) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_puts("client_finished.verify_data verification failure"); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + + // send [ChangeCipherSpec] + tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // send ServerFinished + tls_trace("send Finished\n"); + sm3_finish(&sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "server finished", sm3_hash, 32, NULL, 0, + sizeof(local_verify_data), local_verify_data) != 1 + || tls_record_set_handshake_finished(finished_record, &finished_record_len, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tlcp_record_trace(stderr, finished_record, finished_record_len, 0, 0); + if (tls_record_encrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, + conn->server_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls_trace("encrypt Finished\n"); + tlcp_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_seq_num_incr(conn->server_seq_num); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + conn->protocol = TLS_protocol_tlcp; + + fprintf(stderr, "Connection Established!\n\n"); + ret = 1; + +end: + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); + if (client_verify) tls_client_verify_cleanup(&client_verify_ctx); + return ret; +} diff --git a/src/tls.c b/src/tls.c index 0877ffb7..bcccf4e1 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,2302 +7,2303 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -void tls_uint8_to_bytes(uint8_t a, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - *(*out)++ = a; - } - (*outlen)++; -} - -void tls_uint16_to_bytes(uint16_t a, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - *(*out)++ = (uint8_t)(a >> 8); - *(*out)++ = (uint8_t)a; - } - *outlen += 2; -} - -void tls_uint24_to_bytes(uint24_t a, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - *(*out)++ = (uint8_t)(a >> 16); - *(*out)++ = (uint8_t)(a >> 8); - *(*out)++ = (uint8_t)(a); - } - (*outlen) += 3; -} - -void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - *(*out)++ = (uint8_t)(a >> 24); - *(*out)++ = (uint8_t)(a >> 16); - *(*out)++ = (uint8_t)(a >> 8); - *(*out)++ = (uint8_t)(a ); - } - (*outlen) += 4; -} - -void tls_array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) -{ - if (out && *out) { - if (data) { - memcpy(*out, data, datalen); - } - *out += datalen; - } - *outlen += datalen; -} - -/* -这几个函数要区分data = NULL, datalen = 0 和 data = NULL, datalen != 0的情况 -前者意味着数据为空,因此输出的就是一个长度 -后者意味着数据不为空,只是我们不想输出数据,只输出头部的长度,并且更新整个的输出长度。 这种情况应该避免! - -*/ - -void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) -{ - tls_uint8_to_bytes((uint8_t)datalen, out, outlen); - tls_array_to_bytes(data, datalen, out, outlen); -} - -void tls_uint16array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) -{ - tls_uint16_to_bytes((uint16_t)datalen, out, outlen); - tls_array_to_bytes(data, datalen, out, outlen); -} - -void tls_uint24array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) -{ - tls_uint24_to_bytes((uint24_t)datalen, out, outlen); - tls_array_to_bytes(data, datalen, out, outlen); -} - -int tls_uint8_from_bytes(uint8_t *a, const uint8_t **in, size_t *inlen) -{ - if (*inlen < 1) { - error_print(); - return -1; - } - *a = *(*in)++; - (*inlen)--; - return 1; -} - -int tls_uint16_from_bytes(uint16_t *a, const uint8_t **in, size_t *inlen) -{ - if (*inlen < 2) { - error_print(); - return -1; - } - *a = *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *inlen -= 2; - return 1; -} - -int tls_uint24_from_bytes(uint24_t *a, const uint8_t **in, size_t *inlen) -{ - if (*inlen < 3) { - error_print(); - return -1; - } - *a = *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *inlen -= 3; - return 1; -} - -int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen) -{ - if (*inlen < 4) { - error_print(); - return -1; - } - *a = *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *a <<= 8; - *a |= *(*in)++; - *inlen -= 4; - return 1; -} - -int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen) -{ - if (*inlen < datalen) { - error_print(); - return -1; - } - *data = *in; - *in += datalen; - *inlen -= datalen; - return 1; -} - -int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) -{ - uint8_t len; - if (tls_uint8_from_bytes(&len, in, inlen) != 1 - || tls_array_from_bytes(data, len, in, inlen) != 1) { - error_print(); - return -1; - } - if (!len) { - *data = NULL; - } - *datalen = len; - return 1; -} - -int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) -{ - uint16_t len; - if (tls_uint16_from_bytes(&len, in, inlen) != 1 - || tls_array_from_bytes(data, len, in, inlen) != 1) { - error_print(); - return -1; - } - if (!len) { - *data = NULL; - } - *datalen = len; - return 1; -} - -int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) -{ - uint24_t len; - if (tls_uint24_from_bytes(&len, in, inlen) != 1 - || tls_array_from_bytes(data, len, in, inlen) != 1) { - error_print(); - return -1; - } - if (!len) { - *data = NULL; - } - *datalen = len; - return 1; -} - -int tls_length_is_zero(size_t len) -{ - if (len) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_type(uint8_t *record, int type) -{ - if (!tls_record_type_name(type)) { - error_print(); - return -1; - } - record[0] = type; - return 1; -} - -int tls_record_set_protocol(uint8_t *record, int protocol) -{ - if (!tls_protocol_name(protocol)) { - error_print(); - return -1; - } - record[1] = protocol >> 8; - record[2] = protocol; - return 1; -} - -int tls_record_set_length(uint8_t *record, size_t length) -{ - uint8_t *p = record + 3; - size_t len; - if (length > TLS_MAX_CIPHERTEXT_SIZE) { - error_print(); - return -1; - } - tls_uint16_to_bytes(length, &p, &len); - return 1; -} - -int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen) -{ - if (tls_record_set_length(record, datalen) != 1) { - error_print(); - return -1; - } - memcpy(tls_record_data(record), data, datalen); - return 1; -} - -int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, - const uint8_t seq_num[8], const uint8_t header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM3_HMAC_CTX hmac_ctx; - uint8_t last_blocks[32 + 16] = {0}; - uint8_t *mac, *padding, *iv; - int rem, padding_len; - int i; - - if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) { - error_print(); - return -1; - } - if (inlen > (1 << 14)) { - error_print_msg("invalid tls record data length %zu\n", inlen); - return -1; - } - if ((((size_t)header[3]) << 8) + header[4] != inlen) { - error_print(); - return -1; - } - - rem = (inlen + 32) % 16; - memcpy(last_blocks, in + inlen - rem, rem); - mac = last_blocks + rem; - - memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, seq_num, 8); - sm3_hmac_update(&hmac_ctx, header, 5); - sm3_hmac_update(&hmac_ctx, in, inlen); - sm3_hmac_finish(&hmac_ctx, mac); - - padding = mac + 32; - padding_len = 16 - rem - 1; - for (i = 0; i <= padding_len; i++) { - padding[i] = padding_len; - } - - iv = out; - if (rand_bytes(iv, 16) != 1) { - error_print(); - return -1; - } - out += 16; - - if (inlen >= 16) { - sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out); - out += inlen - rem; - iv = out - 16; - } - sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out); - *outlen = 16 + inlen - rem + sizeof(last_blocks); - return 1; -} - -int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key, - const uint8_t seq_num[8], const uint8_t enced_header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM3_HMAC_CTX hmac_ctx; - const uint8_t *iv; - const uint8_t *padding; - const uint8_t *mac; - uint8_t header[5]; - int padding_len; - uint8_t hmac[32]; - int i; - - if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) { - error_print(); - return -1; - } - if (inlen % 16 - || inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding - || inlen > (16 + (1<<14) + 32 + 256)) { - error_print_msg("invalid tls cbc ciphertext length %zu\n", inlen); - return -1; - } - - iv = in; - in += 16; - inlen -= 16; - - sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out); - - padding_len = out[inlen - 1]; - padding = out + inlen - padding_len - 1; - if (padding < out + 32) { - error_print(); - return -1; - } - for (i = 0; i < padding_len; i++) { - if (padding[i] != padding_len) { - error_puts("tls ciphertext cbc-padding check failure"); - return -1; - } - } - - *outlen = inlen - 32 - padding_len - 1; - - header[0] = enced_header[0]; - header[1] = enced_header[1]; - header[2] = enced_header[2]; - header[3] = (*outlen) >> 8; - header[4] = (*outlen); - mac = padding - 32; - - memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, seq_num, 8); - sm3_hmac_update(&hmac_ctx, header, 5); - sm3_hmac_update(&hmac_ctx, out, *outlen); - sm3_hmac_finish(&hmac_ctx, hmac); - if (gmssl_secure_memcmp(mac, hmac, sizeof(hmac)) != 0) { - error_puts("tls ciphertext mac check failure\n"); - return -1; - } - return 1; -} - -int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - if (tls_cbc_encrypt(hmac_ctx, cbc_key, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (*outlen) >> 8; - out[4] = (*outlen); - (*outlen) += 5; - return 1; -} - -int tls_record_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) -{ - if (tls_cbc_decrypt(hmac_ctx, cbc_key, seq_num, in, - in + 5, inlen - 5, - out + 5, outlen) != 1) { - error_print(); - return -1; - } - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (*outlen) >> 8; - out[4] = (*outlen); - (*outlen) += 5; - - return 1; -} - -int tls_random_generate(uint8_t random[32]) -{ - uint32_t gmt_unix_time = (uint32_t)time(NULL); - uint8_t *p = random; - size_t len = 0; - tls_uint32_to_bytes(gmt_unix_time, &p, &len); - if (rand_bytes(random + 4, 28) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, - const uint8_t *seed, size_t seedlen, - const uint8_t *more, size_t morelen, - size_t outlen, uint8_t *out) -{ - SM3_HMAC_CTX inited_hmac_ctx; - SM3_HMAC_CTX hmac_ctx; - uint8_t A[32]; - uint8_t hmac[32]; - size_t len; - - if (!secret || !secretlen || !label || !seed || !seedlen - || (!more && morelen) || !outlen || !out) { - error_print(); - return -1; - } - - sm3_hmac_init(&inited_hmac_ctx, secret, secretlen); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, A); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, hmac); - - len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); - memcpy(out, hmac, len); - out += len; - outlen -= len; - - while (outlen) { - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_finish(&hmac_ctx, A); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, hmac); - - len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); - memcpy(out, hmac, len); - out += len; - outlen -= len; - } - return 1; -} - -int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol) -{ - if (!tls_protocol_name(protocol)) { - error_print(); - return -1; - } - pre_master_secret[0] = protocol >> 8; - pre_master_secret[1] = protocol; - if (rand_bytes(pre_master_secret + 2, 46) != 1) { - error_print(); - return -1; - } - return 1; -} - -// 用于设置CertificateRequest -int tls_cert_type_from_oid(int oid) -{ - switch (oid) { - case OID_sm2sign_with_sm3: - case OID_ecdsa_with_sha1: - case OID_ecdsa_with_sha224: - case OID_ecdsa_with_sha256: - case OID_ecdsa_with_sha512: - return TLS_cert_type_ecdsa_sign; - case OID_rsasign_with_sm3: - case OID_rsasign_with_md5: - case OID_rsasign_with_sha1: - case OID_rsasign_with_sha224: - case OID_rsasign_with_sha256: - case OID_rsasign_with_sha384: - case OID_rsasign_with_sha512: - return TLS_cert_type_rsa_sign; - } - // TLS_cert_type_xxx 中没有为0的值 - return 0; -} - -// 这两个函数没有对应的TLCP版本 -int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen) -{ - uint8_t server_ecdh_params[69]; - SM2_SIGN_CTX sign_ctx; - - if (!server_sign_key || !client_random || !server_random - || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) { - error_print(); - return -1; - } - server_ecdh_params[0] = TLS_curve_type_named_curve; - server_ecdh_params[1] = curve >> 8; - server_ecdh_params[2] = curve; - server_ecdh_params[3] = 65; - sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); - - sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_sign_update(&sign_ctx, client_random, 32); - sm2_sign_update(&sign_ctx, server_random, 32); - sm2_sign_update(&sign_ctx, server_ecdh_params, 69); - sm2_sign_finish(&sign_ctx, sig, siglen); - - return 1; -} - -int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) -{ - int ret; - uint8_t server_ecdh_params[69]; - SM2_SIGN_CTX verify_ctx; - - if (!server_sign_key || !client_random || !server_random - || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen - || siglen > SM2_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - server_ecdh_params[0] = TLS_curve_type_named_curve; - server_ecdh_params[1] = curve >> 8; - server_ecdh_params[2] = curve; - server_ecdh_params[3] = 65; - sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); - - sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_verify_update(&verify_ctx, client_random, 32); - sm2_verify_update(&verify_ctx, server_random, 32); - sm2_verify_update(&verify_ctx, server_ecdh_params, 69); - ret = sm2_verify_finish(&verify_ctx, sig, siglen); - if (ret != 1) error_print(); - return ret; -} - -int tls_record_set_handshake(uint8_t *record, size_t *recordlen, - int type, const uint8_t *data, size_t datalen) -{ - size_t handshakelen; - - if (!record || !recordlen) { - error_print(); - return -1; - } - // 由于ServerHelloDone没有负载数据,因此允许 data,datalen = NULL,0 - if (datalen > TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE) { - error_print(); - return -1; - } - if (!tls_protocol_name(tls_record_protocol(record))) { - error_print(); - return -1; - } - if (!tls_handshake_type_name(type)) { - error_print(); - return -1; - } - handshakelen = TLS_HANDSHAKE_HEADER_SIZE + datalen; - record[0] = TLS_record_handshake; - record[3] = handshakelen >> 8; - record[4] = handshakelen; - record[5] = type; - record[6] = datalen >> 16; - record[7] = datalen >> 8; - record[8] = datalen; - if (data) { - memcpy(tls_handshake_data(tls_record_data(record)), data, datalen); - } - *recordlen = TLS_RECORD_HEADER_SIZE + handshakelen; - return 1; -} - -int tls_record_get_handshake(const uint8_t *record, - int *type, const uint8_t **data, size_t *datalen) -{ - const uint8_t *handshake; - size_t handshake_len; - uint24_t handshake_datalen; - - if (!record || !type || !data || !datalen) { - error_print(); - return -1; - } - if (!tls_protocol_name(tls_record_protocol(record))) { - error_print(); - return -1; - } - if (tls_record_type(record) != TLS_record_handshake) { - error_print(); - return -1; - } - handshake = tls_record_data(record); - handshake_len = tls_record_data_length(record); - - if (handshake_len < TLS_HANDSHAKE_HEADER_SIZE) { - error_print(); - return -1; - } - if (handshake_len > TLS_MAX_PLAINTEXT_SIZE) { - // 不支持证书长度超过记录长度的特殊情况 - error_print(); - return -1; - } - - if (!tls_handshake_type_name(handshake[0])) { - error_print(); - return -1; - } - *type = handshake[0]; - - handshake++; - handshake_len--; - if (tls_uint24_from_bytes(&handshake_datalen, &handshake, &handshake_len) != 1) { - error_print(); - return -1; - } - if (handshake_len != handshake_datalen) { - error_print(); - return -1; - } - *data = handshake; - *datalen = handshake_datalen; - - if (*datalen == 0) { - *data = NULL; - } - return 1; -} - -int tls_record_set_handshake_client_hello(uint8_t *record, size_t *recordlen, - int protocol, const uint8_t random[32], - const uint8_t *session_id, size_t session_id_len, - const int *cipher_suites, size_t cipher_suites_count, - const uint8_t *exts, size_t exts_len) -{ - uint8_t type = TLS_handshake_client_hello; - uint8_t *p; - size_t len; - - if (!record || !recordlen || !random || !cipher_suites || !cipher_suites_count) { - error_print(); - return -1; - } - if (session_id) { - if (!session_id_len - || session_id_len < TLS_MAX_SESSION_ID_SIZE - || session_id_len > TLS_MAX_SESSION_ID_SIZE) { - error_print(); - return -1; - } - } - if (cipher_suites_count > TLS_MAX_CIPHER_SUITES_COUNT) { - error_print(); - return -1; - } - if (exts && !exts_len) { - error_print(); - return -1; - } - - - p = tls_handshake_data(tls_record_data(record)); - len = 0; - - if (!tls_protocol_name(protocol)) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)protocol, &p, &len); - tls_array_to_bytes(random, 32, &p, &len); - tls_uint8array_to_bytes(session_id, session_id_len, &p, &len); - tls_uint16_to_bytes(cipher_suites_count * 2, &p, &len); - while (cipher_suites_count--) { - if (!tls_cipher_suite_name(*cipher_suites)) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)*cipher_suites, &p, &len); - cipher_suites++; - } - tls_uint8_to_bytes(1, &p, &len); - tls_uint8_to_bytes((uint8_t)TLS_compression_null, &p, &len); - if (exts) { - size_t tmp_len = len; - if (protocol < TLS_protocol_tls12) { - error_print(); - return -1; - } - tls_uint16array_to_bytes(exts, exts_len, NULL, &tmp_len); - if (tmp_len > TLS_MAX_HANDSHAKE_DATA_SIZE) { - error_print(); - return -1; - } - tls_uint16array_to_bytes(exts, exts_len, &p, &len); - } - if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_get_handshake_client_hello(const uint8_t *record, - int *protocol, const uint8_t **random, - const uint8_t **session_id, size_t *session_id_len, - const uint8_t **cipher_suites, size_t *cipher_suites_len, - const uint8_t **exts, size_t *exts_len) -{ - int type; - const uint8_t *p; - size_t len; - uint16_t ver; - const uint8_t *comp_meths; - size_t comp_meths_len; - - if (!record || !protocol || !random - || !session_id || !session_id_len - || !cipher_suites || !cipher_suites_len - || !exts || !exts_len) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_client_hello) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&ver, &p, &len) != 1 - || tls_array_from_bytes(random, 32, &p, &len) != 1 - || tls_uint8array_from_bytes(session_id, session_id_len, &p, &len) != 1 - || tls_uint16array_from_bytes(cipher_suites, cipher_suites_len, &p, &len) != 1 - || tls_uint8array_from_bytes(&comp_meths, &comp_meths_len, &p, &len) != 1) { - error_print(); - return -1; - } - - if (!tls_protocol_name(ver)) { - error_print(); - return -1; - } - *protocol = ver; - - if (*session_id) { - if (*session_id_len == 0 - || *session_id_len < TLS_MIN_SESSION_ID_SIZE - || *session_id_len > TLS_MAX_SESSION_ID_SIZE) { - error_print(); - return -1; - } - } - - if (!cipher_suites) { - error_print(); - return -1; - } - if (*cipher_suites_len % 2) { - error_print(); - return -1; - } - - if (len) { - if (tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1) { - error_print(); - return -1; - } - if (*exts == NULL) { - error_print(); - return -1; - } - } else { - *exts = NULL; - *exts_len = 0; - } - if (len) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, - int protocol, const uint8_t random[32], - const uint8_t *session_id, size_t session_id_len, int cipher_suite, - const uint8_t *exts, size_t exts_len) -{ - uint8_t type = TLS_handshake_server_hello; - uint8_t *p; - size_t len; - - if (!record || !recordlen || !random) { - error_print(); - return -1; - } - if (session_id) { - if (session_id_len == 0 - || session_id_len < TLS_MIN_SESSION_ID_SIZE - || session_id_len > TLS_MAX_SESSION_ID_SIZE) { - error_print(); - return -1; - } - } - if (!tls_protocol_name(protocol)) { - error_print(); - return -1; - } - if (!tls_cipher_suite_name(cipher_suite)) { - error_print(); - return -1; - } - - p = tls_handshake_data(tls_record_data(record)); - len = 0; - - tls_uint16_to_bytes((uint16_t)protocol, &p, &len); - tls_array_to_bytes(random, 32, &p, &len); - tls_uint8array_to_bytes(session_id, session_id_len, &p, &len); - tls_uint16_to_bytes((uint16_t)cipher_suite, &p, &len); - tls_uint8_to_bytes((uint8_t)TLS_compression_null, &p, &len); - if (exts) { - if (protocol < TLS_protocol_tls12) { - error_print(); - return -1; - } - tls_uint16array_to_bytes(exts, exts_len, &p, &len); - } - if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_get_handshake_server_hello(const uint8_t *record, - int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len, - int *cipher_suite, const uint8_t **exts, size_t *exts_len) -{ - int type; - const uint8_t *p; - size_t len; - uint16_t ver; - uint16_t cipher; - uint8_t comp_meth; - - if (!record || !protocol || !random || !session_id || !session_id_len - || !cipher_suite || !exts || !exts_len) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_server_hello) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&ver, &p, &len) != 1 - || tls_array_from_bytes(random, 32, &p, &len) != 1 - || tls_uint8array_from_bytes(session_id, session_id_len, &p, &len) != 1 - || tls_uint16_from_bytes(&cipher, &p, &len) != 1 - || tls_uint8_from_bytes(&comp_meth, &p, &len) != 1) { - error_print(); - return -1; - } - - if (!tls_protocol_name(ver)) { - error_print(); - return -1; - } - if (ver < tls_record_protocol(record)) { - error_print(); - return -1; - } - *protocol = ver; - - if (*session_id) { - if (*session_id == 0 - || *session_id_len < TLS_MIN_SESSION_ID_SIZE - || *session_id_len > TLS_MAX_SESSION_ID_SIZE) { - error_print(); - return -1; - } - } - - if (!tls_cipher_suite_name(cipher)) { - error_print(); - return -1; - } - *cipher_suite = cipher; - - if (comp_meth != TLS_compression_null) { - error_print(); - return -1; - } - - if (len) { - if (tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1) { - error_print(); - return -1; - } - if (*exts == NULL) { - error_print(); - return -1; - } - } else { - *exts = NULL; - *exts_len = 0; - } - if (len) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, - const uint8_t *certs, size_t certslen) -{ - int type = TLS_handshake_certificate; - uint8_t *data; - size_t datalen; - uint8_t *p; - size_t len; - - if (!record || !recordlen || !certs || !certslen) { - error_print(); - return -1; - } - data = tls_handshake_data(tls_record_data(record)); - p = data + tls_uint24_size(); - datalen = tls_uint24_size(); - len = 0; - - while (certslen) { - const uint8_t *cert; - size_t certlen; - - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - tls_uint24array_to_bytes(cert, certlen, NULL, &datalen); - if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { - error_print(); - return -1; - } - tls_uint24array_to_bytes(cert, certlen, &p, &len); - } - tls_uint24_to_bytes(len, &data, &len); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); - return 1; -} - -int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen) -{ - int type; - const uint8_t *data; - size_t datalen; - const uint8_t *cp; - size_t len; - - if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate) { - error_print(); - return -1; - } - if (tls_uint24array_from_bytes(&cp, &len, &data, &datalen) != 1) { - error_print(); - return -1; - } - - *certslen = 0; - while (len) { - const uint8_t *a; - size_t alen; - const uint8_t *cert; - size_t certlen; - - if (tls_uint24array_from_bytes(&a, &alen, &cp, &len) != 1) { - error_print(); - return -1; - } - if (x509_cert_from_der(&cert, &certlen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1 - || x509_cert_to_der(cert, certlen, &certs, certslen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, - const uint8_t *cert_types, size_t cert_types_len, - const uint8_t *ca_names, size_t ca_names_len) -{ - int type = TLS_handshake_certificate_request; - uint8_t *p; - size_t len =0; - size_t datalen = 0; - - if (!record || !recordlen) { - error_print(); - return -1; - } - if (cert_types) { - if (cert_types_len == 0 || cert_types_len > TLS_MAX_CERTIFICATE_TYPES) { - error_print(); - return -1; - } - } - if (ca_names) { - if (ca_names_len == 0 || ca_names_len > TLS_MAX_CA_NAMES_SIZE) { - error_print(); - return -1; - } - } - tls_uint8array_to_bytes(cert_types, cert_types_len, NULL, &datalen); - tls_uint16array_to_bytes(ca_names, ca_names_len, NULL, &datalen); - if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { - error_print(); - return -1; - } - p = tls_handshake_data(tls_record_data(record)); - tls_uint8array_to_bytes(cert_types, cert_types_len, &p, &len); - tls_uint16array_to_bytes(ca_names, ca_names_len, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); - return 1; -} - -int tls_record_get_handshake_certificate_request(const uint8_t *record, - const uint8_t **cert_types, size_t *cert_types_len, - const uint8_t **ca_names, size_t *ca_names_len) -{ - int type; - const uint8_t *cp; - size_t len; - size_t i; - - if (!record || !cert_types || !cert_types_len || !ca_names || !ca_names_len) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate_request) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(cert_types, cert_types_len, &cp, &len) != 1 - || tls_uint16array_from_bytes(ca_names, ca_names_len, &cp, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - if (*cert_types == NULL) { - error_print(); - return -1; - } - for (i = 0; i < *cert_types_len; i++) { - if (!tls_cert_type_name((*cert_types)[i])) { - error_print(); - return -1; - } - } - if (*ca_names) { - const uint8_t *names = *ca_names; - size_t nameslen = *ca_names_len; - while (nameslen) { - if (tls_uint16array_from_bytes(&cp, &len, &names, &nameslen) != 1) { - error_print(); - return -1; - } - } - } - return 1; -} - -int tls_record_set_handshake_server_hello_done(uint8_t *record, size_t *recordlen) -{ - int type = TLS_handshake_server_hello_done; - if (!record || !recordlen) { - error_print(); - return -1; - } - tls_record_set_handshake(record, recordlen, type, NULL, 0); - return 1; -} - -int tls_record_get_handshake_server_hello_done(const uint8_t *record) -{ - int type; - const uint8_t *p; - size_t len; - - if (!record) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_server_hello_done) { - error_print(); - return -1; - } - if (p != NULL || len != 0) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_client_key_exchange_pke(uint8_t *record, size_t *recordlen, - const uint8_t *enced_pms, size_t enced_pms_len) -{ - int type = TLS_handshake_client_key_exchange; - uint8_t *p; - size_t len = 0; - - if (!record || !recordlen || !enced_pms || !enced_pms_len) { - error_print(); - return -1; - } - if (enced_pms_len > TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint16_size()) { - error_print(); - return -1; - } - p = tls_handshake_data(tls_record_data(record)); - tls_uint16array_to_bytes(enced_pms, enced_pms_len, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - return 1; -} - -int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record, - const uint8_t **enced_pms, size_t *enced_pms_len) -{ - int type; - const uint8_t *cp; - size_t len; - - if (!record || !enced_pms || !enced_pms_len) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_client_key_exchange) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(enced_pms, enced_pms_len, &cp, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, - const uint8_t *sig, size_t siglen) -{ - int type = TLS_handshake_certificate_verify; - - if (!record || !recordlen || !sig || !siglen) { - error_print(); - return -1; - } - if (siglen > TLS_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - tls_record_set_handshake(record, recordlen, type, sig, siglen); - return 1; -} - -int tls_record_get_handshake_certificate_verify(const uint8_t *record, - const uint8_t **sig, size_t *siglen) -{ - int type; - - if (!record || !sig || !siglen) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, sig, siglen) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate_verify) { - error_print(); - return -1; - } - if (*sig == NULL || *siglen == 0) { - error_print(); - return -1; - } - if (*siglen > TLS_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen, - const uint8_t *verify_data, size_t verify_data_len) -{ - int type = TLS_handshake_finished; - - if (!record || !recordlen || !verify_data || !verify_data_len) { - error_print(); - return -1; - } - if (verify_data_len != 12 && verify_data_len != 32) { - error_print(); - return -1; - } - tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); - return 1; -} - -int tls_record_get_handshake_finished(const uint8_t *record, const uint8_t **verify_data, size_t *verify_data_len) -{ - int type; - - if (!record || !verify_data || !verify_data_len) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, verify_data, verify_data_len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_finished) { - error_print(); - return -1; - } - if (*verify_data == NULL || *verify_data_len == 0) { - error_print(); - return -1; - } - if (*verify_data_len != 12 && *verify_data_len != 32) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_alert(uint8_t *record, size_t *recordlen, - int alert_level, - int alert_description) -{ - if (!record || !recordlen) { - error_print(); - return -1; - } - if (!tls_alert_level_name(alert_level)) { - error_print(); - return -1; - } - if (!tls_alert_description_text(alert_description)) { - error_print(); - return -1; - } - record[0] = TLS_record_alert; - record[3] = 0; // length - record[4] = 2; // length - record[5] = (uint8_t)alert_level; - record[6] = (uint8_t)alert_description; - *recordlen = TLS_RECORD_HEADER_SIZE + 2; - return 1; -} - -int tls_record_get_alert(const uint8_t *record, - int *alert_level, - int *alert_description) -{ - if (!record || !alert_level || !alert_description) { - error_print(); - return -1; - } - if (tls_record_type(record) != TLS_record_alert) { - error_print(); - return -1; - } - if (record[3] != 0 || record[4] != 2) { - error_print(); - return -1; - } - *alert_level = record[5]; - *alert_description = record[6]; - if (!tls_alert_level_name(*alert_level)) { - error_print(); - return -1; - } - if (!tls_alert_description_text(*alert_description)) { - error_puts("warning"); - return -1; - } - return 1; -} - -int tls_record_set_change_cipher_spec(uint8_t *record, size_t *recordlen) -{ - if (!record || !recordlen) { - error_print(); - return -1; - } - record[0] = TLS_record_change_cipher_spec; - record[3] = 0; - record[4] = 1; - record[5] = TLS_change_cipher_spec; - *recordlen = TLS_RECORD_HEADER_SIZE + 1; - return 1; -} - -int tls_record_get_change_cipher_spec(const uint8_t *record) -{ - if (!record) { - error_print(); - return -1; - } - if (tls_record_type(record) != TLS_record_change_cipher_spec) { - error_print(); - return -1; - } - if (record[3] != 0 || record[4] != 1) { - error_print(); - return -1; - } - if (record[5] != TLS_change_cipher_spec) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_application_data(uint8_t *record, size_t *recordlen, - const uint8_t *data, size_t datalen) -{ - if (!record || !recordlen || !data || !datalen) { - error_print(); - return -1; - } - record[0] = TLS_record_application_data; - record[3] = (datalen >> 8) & 0xff; - record[4] = datalen & 0xff; - memcpy(tls_record_data(record), data, datalen); - *recordlen = TLS_RECORD_HEADER_SIZE + datalen; - return 1; -} - -int tls_record_get_application_data(uint8_t *record, - const uint8_t **data, size_t *datalen) -{ - if (!record || !data || !datalen) { - error_print(); - return -1; - } - if (tls_record_type(record) != TLS_record_application_data) { - error_print(); - return -1; - } - *datalen = ((size_t)record[3] << 8) | record[4]; - *data = *datalen ? record + TLS_RECORD_HEADER_SIZE : 0; - return 1; -} - -int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count) -{ - size_t i; - if (!list || !list_count) { - error_print(); - return -1; - } - for (i = 0; i < list_count; i++) { - if (cipher == list[i]) { - return 1; - } - } - return 0; -} - -int tls_record_send(const uint8_t *record, size_t recordlen, int sock) -{ - ssize_t r; - if (!record) { - error_print(); - return -1; - } - if (recordlen < TLS_RECORD_HEADER_SIZE) { - error_print(); - return -1; - } - if (tls_record_length(record) != recordlen) { - error_print(); - return -1; - } - if ((r = send(sock, record, recordlen, 0)) < 0) { - perror("tls_record_send"); - error_print(); - return -1; - } else if (r != recordlen) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_do_recv(uint8_t *record, size_t *recordlen, int sock) -{ - ssize_t r; - int type; - size_t len; - - len = 5; - while (len) { - if ((r = recv(sock, record + 5 - len, len, 0)) < 0) { - perror("tls_record_do_recv"); - error_print(); - return -1; - } - if (r == 0) { - perror("tls_record_do_recv"); - error_print(); - return 0; - } - - len -= r; - } - if (!tls_record_type_name(tls_record_type(record))) { - error_print(); - return -1; - } - if (!tls_protocol_name(tls_record_protocol(record))) { - error_print(); - return -1; - } - len = (size_t)record[3] << 8 | record[4]; - *recordlen = 5 + len; - if (*recordlen > TLS_MAX_RECORD_SIZE) { - // 这里只检查是否超过最大长度,握手协议的长度检查由上层协议完成 - error_print(); - return -1; - } - while (len) { - if ((r = recv(sock, record + *recordlen - len, len, 0)) < 0) { - perror("tls_record_do_recv"); - error_print(); - return -1; - } - len -= r; - } - return 1; -} - -int tls_record_recv(uint8_t *record, size_t *recordlen, int sock) -{ -retry: - if (tls_record_do_recv(record, recordlen, sock) != 1) { - error_print(); - return -1; - } - - if (tls_record_type(record) == TLS_record_alert) { - int level; - int alert; - if (tls_record_get_alert(record, &level, &alert) != 1) { - error_print(); - return -1; - } - tls_record_trace(stderr, record, *recordlen, 0, 0); - if (level == TLS_alert_level_warning) { - // 忽略Warning,读取下一个记录 - error_puts("Warning record received!\n"); - goto retry; - } - if (alert == TLS_alert_close_notify) { - // close_notify是唯一需要提供反馈的Fatal Alert,其他直接中止连接 - uint8_t alert_record[TLS_ALERT_RECORD_SIZE]; - size_t alert_record_len; - tls_record_set_type(alert_record, TLS_record_alert); - tls_record_set_protocol(alert_record, tls_record_protocol(record)); - tls_record_set_alert(alert_record, &alert_record_len, TLS_alert_level_fatal, TLS_alert_close_notify); - - tls_trace("send Alert close_notifiy\n"); - tls_record_trace(stderr, alert_record, alert_record_len, 0, 0); - tls_record_send(alert_record, alert_record_len, sock); - } - // 返回错误0通知调用方不再做任何处理(无需再发送Alert) - return 0; - } - return 1; -} - -int tls_seq_num_incr(uint8_t seq_num[8]) -{ - int i; - for (i = 7; i > 0; i--) { - seq_num[i]++; - if (seq_num[i]) break; - } - // FIXME: 检查溢出 - return 1; -} - -int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t methslen) -{ - if (!meths || !methslen) { - error_print(); - return -1; - } - while (methslen--) { - if (*meths++ == TLS_compression_null) { - return 1; - } - } - error_print(); - return -1; -} - -int tls_send_alert(TLS_CONNECT *conn, int alert) -{ - uint8_t record[5 + 2]; - size_t recordlen; - - if (!conn) { - error_print(); - return -1; - } - tls_record_set_protocol(record, conn->protocol == TLS_protocol_tls13 ? TLS_protocol_tls12 : conn->protocol); - tls_record_set_alert(record, &recordlen, TLS_alert_level_fatal, alert); - - if (tls_record_send(record, sizeof(record), conn->sock) != 1) { - error_print(); - return -1; - } - tls_record_trace(stderr, record, sizeof(record), 0, 0); - return 1; -} - -int tls_alert_level(int alert) -{ - switch (alert) { - case TLS_alert_bad_certificate: - case TLS_alert_unsupported_certificate: - case TLS_alert_certificate_revoked: - case TLS_alert_certificate_expired: - case TLS_alert_certificate_unknown: - return 0; - case TLS_alert_user_canceled: - case TLS_alert_no_renegotiation: - return TLS_alert_level_warning; - default: - return TLS_alert_level_fatal; - } - return -1; -} - -int tls_send_warning(TLS_CONNECT *conn, int alert) -{ - uint8_t record[5 + 2]; - size_t recordlen; - - if (!conn) { - error_print(); - return -1; - } - if (tls_alert_level(alert) == TLS_alert_level_fatal) { - error_print(); - return -1; - } - tls_record_set_protocol(record, conn->protocol == TLS_protocol_tls13 ? TLS_protocol_tls12 : conn->protocol); - tls_record_set_alert(record, &recordlen, TLS_alert_level_warning, alert); - - if (tls_record_send(record, sizeof(record), conn->sock) != 1) { - error_print(); - return -1; - } - tls_record_trace(stderr, record, sizeof(record), 0, 0); - return 1; -} - -int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) -{ - const SM3_HMAC_CTX *hmac_ctx; - const SM4_KEY *enc_key; - uint8_t *seq_num; - uint8_t *record; - size_t recordlen; - uint8_t *data; - size_t datalen; - - if (!conn) { - error_print(); - return -1; - } - if (!in || !inlen || !sentlen) { - error_print(); - return -1; - } - - if (inlen > TLS_MAX_PLAINTEXT_SIZE) { - inlen = TLS_MAX_PLAINTEXT_SIZE; - } - - if (conn->is_client) { - hmac_ctx = &conn->client_write_mac_ctx; - enc_key = &conn->client_write_enc_key; - seq_num = conn->client_seq_num; - } else { - hmac_ctx = &conn->server_write_mac_ctx; - enc_key = &conn->server_write_enc_key; - seq_num = conn->server_seq_num; - } - record = conn->record; - - tls_trace("send ApplicationData\n"); - - if (tls_record_set_type(record, TLS_record_application_data) != 1 - || tls_record_set_protocol(record, conn->protocol) != 1 - || tls_record_set_length(record, inlen) != 1) { - error_print(); - return -1; - } - - if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, tls_record_header(record), - in, inlen, tls_record_data(record), &datalen) != 1) { - error_print(); - return -1; - } - if (tls_record_set_length(record, datalen) != 1) { - error_print(); - return -1; - } - tls_seq_num_incr(seq_num); - if (tls_record_send(record, tls_record_length(record), conn->sock) != 1) { - error_print(); - return -1; - } - *sentlen = inlen; - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - return 1; -} - -int tls_do_recv(TLS_CONNECT *conn) -{ - int ret; - const SM3_HMAC_CTX *hmac_ctx; - const SM4_KEY *dec_key; - uint8_t *seq_num; - - uint8_t *record = conn->record; - size_t recordlen; - - if (conn->is_client) { - hmac_ctx = &conn->server_write_mac_ctx; - dec_key = &conn->server_write_enc_key; - seq_num = conn->server_seq_num; - } else { - hmac_ctx = &conn->client_write_mac_ctx; - dec_key = &conn->client_write_enc_key; - seq_num = conn->client_seq_num; - } - - tls_trace("recv ApplicationData\n"); - if ((ret = tls_record_recv(record, &recordlen, conn->sock)) != 1) { - if (ret < 0) error_print(); - return ret; - } - - tls_record_trace(stderr, record, recordlen, 0, 0); - if (tls_cbc_decrypt(hmac_ctx, dec_key, seq_num, record, - tls_record_data(record), tls_record_data_length(record), - conn->databuf, &conn->datalen) != 1) { - error_print(); - return -1; - } - conn->data = conn->databuf; - tls_seq_num_incr(seq_num); - - tls_record_set_data(record, conn->data, conn->datalen); - tls_trace("decrypt ApplicationData\n"); - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - return 1; -} - -int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen) -{ - if (!conn || !out || !outlen || !recvlen) { - error_print(); - return -1; - } - if (conn->datalen == 0) { - int ret; - if ((ret = tls_do_recv(conn)) != 1) { - if (ret) error_print(); - return ret; - } - } - *recvlen = outlen <= conn->datalen ? outlen : conn->datalen; - memcpy(out, conn->data, *recvlen); - conn->data += *recvlen; - conn->datalen -= *recvlen; - return 1; -} - -int tls_shutdown(TLS_CONNECT *conn) -{ - size_t recordlen; - if (!conn) { - error_print(); - return -1; - } - tls_trace("send Alert close_notify\n"); - if (tls_send_alert(conn, TLS_alert_close_notify) != 1) { - error_print(); - return -1; - } - tls_trace("recv Alert close_notify\n"); - - if (tls_record_do_recv(conn->record, &recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - tls_record_trace(stderr, conn->record, recordlen, 0, 0); - - return 1; -} - -int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, const uint8_t *certs, size_t certslen) -{ - const uint8_t *cert; - size_t certlen; - const uint8_t *name; - size_t namelen; - - *nameslen = 0; - while (certslen) { - size_t alen = 0; - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1 - || x509_cert_get_subject(cert, certlen, &name, &namelen) != 1 - || asn1_sequence_to_der(name, namelen, NULL, &alen) != 1) { - error_print(); - return -1; - } - if (tls_uint16_size() + alen > maxlen) { - error_print(); - return -1; - } - tls_uint16_to_bytes(alen, &names, nameslen); - if (asn1_sequence_to_der(name, namelen, &names, nameslen) != 1) { - error_print(); - return -1; - } - maxlen -= alen; - } - return 1; -} - -int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_names_len, const uint8_t *certs, size_t certslen) -{ - const uint8_t *cert; - size_t certlen; - const uint8_t *issuer; - size_t issuer_len; - - if (x509_certs_get_last(certs, certslen, &cert, &certlen) != 1 - || x509_cert_get_issuer(cert, certlen, &issuer, &issuer_len) != 1) { - error_print(); - return -1; - } - while (ca_names_len) { - const uint8_t *p; - size_t len; - const uint8_t *name; - size_t namelen; - - if (tls_uint16array_from_bytes(&p, &len, &ca_names, &ca_names_len) != 1) { - error_print(); - return -1; - } - if (asn1_sequence_from_der(&name, &namelen, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (x509_name_equ(name, namelen, issuer, issuer_len) == 1) { - return 1; - } - } - error_print(); - return 0; -} - -int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len) -{ - const uint8_t *cert; - size_t certlen; - int sig_alg; - size_t i; - - if (x509_certs_get_cert_by_index(client_certs, client_certs_len, 0, &cert, &certlen) != 1) { - error_print(); - return -1; - } - if ((sig_alg = tls_cert_type_from_oid(OID_sm2sign_with_sm3)) < 0) { - error_print(); - return -1; - } - for (i = 0; i < types_len; i++) { - if (sig_alg == types[i]) { - return 1; - } - } - return 0; -} - -int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx) -{ - if (!ctx) { - error_print(); - return -1; - } - memset(ctx, 0, sizeof(TLS_CLIENT_VERIFY_CTX)); - return 1; -} - -int tls_client_verify_update(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *handshake, size_t handshake_len) -{ - uint8_t *buf; - if (!ctx || !handshake || !handshake_len) { - error_print(); - return -1; - } - if (ctx->index < 0 || ctx->index > 7) { - error_print(); - return -1; - } - if (!(buf = malloc(handshake_len))) { - error_print(); - return -1; - } - memcpy(buf, handshake, handshake_len); - ctx->handshake[ctx->index] = buf; - ctx->handshake_len[ctx->index] = handshake_len; - ctx->index++; - return 1; -} - -int tls_client_verify_finish(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen, const SM2_KEY *public_key) -{ - int ret; - SM2_SIGN_CTX sm2_ctx; - int i; - - if (!ctx || !sig || !siglen || !public_key) { - error_print(); - return -1; - } - - if (ctx->index != 8) { - error_print(); - return -1; - } - if (sm2_verify_init(&sm2_ctx, public_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - for (i = 0; i < 8; i++) { - if (sm2_verify_update(&sm2_ctx, ctx->handshake[i], ctx->handshake_len[i]) != 1) { - error_print(); - return -1; - } - } - if ((ret = sm2_verify_finish(&sm2_ctx, sig, siglen)) < 0) { - error_print(); - return -1; - } - return ret; -} - -void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx) -{ - if (ctx) { - int i; - for (i = 0; i< ctx->index; i++) { - if (ctx->handshake[i]) { - free(ctx->handshake[i]); - ctx->handshake[i] = NULL; - ctx->handshake_len[i] = 0; - } - } - } -} - -int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len, - const int *server_ciphers, size_t server_ciphers_cnt, - int *selected_cipher) -{ - if (!client_ciphers || !client_ciphers_len - || !server_ciphers || !server_ciphers_cnt || !selected_cipher) { - error_print(); - return -1; - } - while (server_ciphers_cnt--) { - const uint8_t *p = client_ciphers; - size_t len = client_ciphers_len; - while (len) { - uint16_t cipher; - if (tls_uint16_from_bytes(&cipher, &p, &len) != 1) { - error_print(); - return -1; - } - if (cipher == *server_ciphers) { - *selected_cipher = *server_ciphers; - return 1; - } - } - server_ciphers++; - } - return 0; -} - -void tls_ctx_cleanup(TLS_CTX *ctx) -{ - if (ctx) { - gmssl_secure_clear(&ctx->signkey, sizeof(SM2_KEY)); - gmssl_secure_clear(&ctx->kenckey, sizeof(SM2_KEY)); - if (ctx->certs) free(ctx->certs); - if (ctx->cacerts) free(ctx->cacerts); - memset(ctx, 0, sizeof(TLS_CTX)); - } -} - -int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) -{ - if (!ctx) { - error_print(); - return -1; - } - memset(ctx, 0, sizeof(*ctx)); - - switch (protocol) { - case TLS_protocol_tlcp: - case TLS_protocol_tls12: - case TLS_protocol_tls13: - ctx->protocol = protocol; - break; - default: - error_print(); - return -1; - } - ctx->is_client = is_client ? 1 : 0; - return 1; -} - -int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt) -{ - size_t i; - - if (!ctx || !cipher_suites || !cipher_suites_cnt) { - error_print(); - return -1; - } - if (cipher_suites_cnt < 1 || cipher_suites_cnt > TLS_MAX_CIPHER_SUITES_COUNT) { - error_print(); - return -1; - } - for (i = 0; i < cipher_suites_cnt; i++) { - if (!tls_cipher_suite_name(cipher_suites[i])) { - error_print(); - return -1; - } - } - for (i = 0; i < cipher_suites_cnt; i++) { - ctx->cipher_suites[i] = cipher_suites[i]; - } - ctx->cipher_suites_cnt = cipher_suites_cnt; - return 1; -} - -int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth) -{ - if (!ctx || !cacertsfile) { - error_print(); - return -1; - } - if (depth < 0 || depth > TLS_MAX_VERIFY_DEPTH) { - error_print(); - return -1; - } - if (!tls_protocol_name(ctx->protocol)) { - error_print(); - return -1; - } - if (ctx->cacerts) { - error_print(); - return -1; - } - if (x509_certs_new_from_file(&ctx->cacerts, &ctx->cacertslen, cacertsfile) != 1) { - error_print(); - return -1; - } - if (ctx->cacertslen == 0) { - error_print(); - return -1; - } - - ctx->verify_depth = depth; - return 1; -} - -int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile, - const char *keyfile, const char *keypass) -{ - int ret = -1; - uint8_t *certs = NULL; - size_t certslen; - FILE *keyfp = NULL; - SM2_KEY key; - const uint8_t *cert; - size_t certlen; - SM2_KEY public_key; - - if (!ctx || !chainfile || !keyfile || !keypass) { - error_print(); - return -1; - } - if (!tls_protocol_name(ctx->protocol)) { - error_print(); - return -1; - } - if (ctx->certs) { - error_print(); - return -1; - } - - if (x509_certs_new_from_file(&certs, &certslen, chainfile) != 1) { - error_print(); - goto end; - } - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - goto end; - } - if (sm2_private_key_info_decrypt_from_pem(&key, keypass, keyfp) != 1) { - error_print(); - goto end; - } - if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { - error_print(); - return -1; - } - if (sm2_public_key_equ(&key, &public_key) != 1) { - error_print(); - return -1; - } - ctx->certs = certs; - ctx->certslen = certslen; - ctx->signkey = key; - certs = NULL; - ret = 1; - -end: - gmssl_secure_clear(&key, sizeof(key)); - if (certs) free(certs); - if (keyfp) fclose(keyfp); - return ret; -} - -int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile, - const char *signkeyfile, const char *signkeypass, - const char *kenckeyfile, const char *kenckeypass) -{ - int ret = -1; - uint8_t *certs = NULL; - size_t certslen; - FILE *signkeyfp = NULL; - FILE *kenckeyfp = NULL; - SM2_KEY signkey; - SM2_KEY kenckey; - - const uint8_t *cert; - size_t certlen; - SM2_KEY public_key; - - if (!ctx || !chainfile || !signkeyfile || !signkeypass || !kenckeyfile || !kenckeypass) { - error_print(); - return -1; - } - if (!tls_protocol_name(ctx->protocol)) { - error_print(); - return -1; - } - if (ctx->certs) { - error_print(); - return -1; - } - - if (x509_certs_new_from_file(&certs, &certslen, chainfile) != 1) { - error_print(); - return -1; - } - - if (!(signkeyfp = fopen(signkeyfile, "r"))) { - error_print(); - goto end; - } - if (sm2_private_key_info_decrypt_from_pem(&signkey, signkeypass, signkeyfp) != 1) { - error_print(); - goto end; - } - if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 - || sm2_public_key_equ(&signkey, &public_key) != 1) { - error_print(); - goto end; - } - - if (!(kenckeyfp = fopen(kenckeyfile, "r"))) { - error_print(); - goto end; - } - if (sm2_private_key_info_decrypt_from_pem(&kenckey, kenckeypass, kenckeyfp) != 1) { - error_print(); - goto end; - } - if (x509_certs_get_cert_by_index(certs, certslen, 1, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 - || sm2_public_key_equ(&kenckey, &public_key) != 1) { - error_print(); - goto end; - } - - ctx->certs = certs; - ctx->certslen = certslen; - ctx->signkey = signkey; - ctx->kenckey = kenckey; - certs = NULL; - ret = 1; - -end: - gmssl_secure_clear(&signkey, sizeof(signkey)); - gmssl_secure_clear(&kenckey, sizeof(kenckey)); - if (certs) free(certs); - if (signkeyfp) fclose(signkeyfp); - if (kenckeyfp) fclose(kenckeyfp); - return ret; -} - -int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx) -{ - size_t i; - memset(conn, 0, sizeof(*conn)); - - conn->protocol = ctx->protocol; - conn->is_client = ctx->is_client; - for (i = 0; i < ctx->cipher_suites_cnt; i++) { - conn->cipher_suites[i] = ctx->cipher_suites[i]; - } - conn->cipher_suites_cnt = ctx->cipher_suites_cnt; - - - if (ctx->certslen > TLS_MAX_CERTIFICATES_SIZE) { - error_print(); - return -1; - } - if (conn->is_client) { - memcpy(conn->client_certs, ctx->certs, ctx->certslen); - conn->client_certs_len = ctx->certslen; - } else { - memcpy(conn->server_certs, ctx->certs, ctx->certslen); - conn->server_certs_len = ctx->certslen; - } - - if (ctx->cacertslen > TLS_MAX_CERTIFICATES_SIZE) { - error_print(); - return -1; - } - memcpy(conn->ca_certs, ctx->cacerts, ctx->cacertslen); - conn->ca_certs_len = ctx->cacertslen; - - conn->sign_key = ctx->signkey; - conn->kenc_key = ctx->kenckey; - - return 1; -} - -void tls_cleanup(TLS_CONNECT *conn) -{ - gmssl_secure_clear(conn, sizeof(TLS_CONNECT)); -} - - -int tls_set_socket(TLS_CONNECT *conn, int sock) -{ - int opts; - - if ((opts = fcntl(sock, F_GETFL)) < 0) { - error_print(); - perror("tls_set_socket"); - return -1; - } - opts &= ~O_NONBLOCK; - if (fcntl(sock, F_SETFL, opts) < 0) { - error_print(); - return -1; - } - conn->sock = sock; - return 1; -} - -int tls_do_handshake(TLS_CONNECT *conn) -{ - switch (conn->protocol) { - case TLS_protocol_tlcp: - if (conn->is_client) return tlcp_do_connect(conn); - else return tlcp_do_accept(conn); - case TLS_protocol_tls12: - if (conn->is_client) return tls12_do_connect(conn); - else return tls12_do_accept(conn); - case TLS_protocol_tls13: - if (conn->is_client) return tls13_do_connect(conn); - else return tls13_do_accept(conn); - } - error_print(); - return -1; -} - -int tls_get_verify_result(TLS_CONNECT *conn, int *result) -{ - *result = conn->verify_result; - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +void tls_uint8_to_bytes(uint8_t a, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + *(*out)++ = a; + } + (*outlen)++; +} + +void tls_uint16_to_bytes(uint16_t a, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + *(*out)++ = (uint8_t)(a >> 8); + *(*out)++ = (uint8_t)a; + } + *outlen += 2; +} + +void tls_uint24_to_bytes(uint24_t a, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + *(*out)++ = (uint8_t)(a >> 16); + *(*out)++ = (uint8_t)(a >> 8); + *(*out)++ = (uint8_t)(a); + } + (*outlen) += 3; +} + +void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + *(*out)++ = (uint8_t)(a >> 24); + *(*out)++ = (uint8_t)(a >> 16); + *(*out)++ = (uint8_t)(a >> 8); + *(*out)++ = (uint8_t)(a ); + } + (*outlen) += 4; +} + +void tls_array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) +{ + if (out && *out) { + if (data) { + memcpy(*out, data, datalen); + } + *out += datalen; + } + *outlen += datalen; +} + +/* +这几个函数要区分data = NULL, datalen = 0 和 data = NULL, datalen != 0的情况 +前者意味着数据为空,因此输出的就是一个长度 +后者意味着数据不为空,只是我们不想输出数据,只输出头部的长度,并且更新整个的输出长度。 这种情况应该避免! + +*/ + +void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) +{ + tls_uint8_to_bytes((uint8_t)datalen, out, outlen); + tls_array_to_bytes(data, datalen, out, outlen); +} + +void tls_uint16array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) +{ + tls_uint16_to_bytes((uint16_t)datalen, out, outlen); + tls_array_to_bytes(data, datalen, out, outlen); +} + +void tls_uint24array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) +{ + tls_uint24_to_bytes((uint24_t)datalen, out, outlen); + tls_array_to_bytes(data, datalen, out, outlen); +} + +int tls_uint8_from_bytes(uint8_t *a, const uint8_t **in, size_t *inlen) +{ + if (*inlen < 1) { + error_print(); + return -1; + } + *a = *(*in)++; + (*inlen)--; + return 1; +} + +int tls_uint16_from_bytes(uint16_t *a, const uint8_t **in, size_t *inlen) +{ + if (*inlen < 2) { + error_print(); + return -1; + } + *a = *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *inlen -= 2; + return 1; +} + +int tls_uint24_from_bytes(uint24_t *a, const uint8_t **in, size_t *inlen) +{ + if (*inlen < 3) { + error_print(); + return -1; + } + *a = *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *inlen -= 3; + return 1; +} + +int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen) +{ + if (*inlen < 4) { + error_print(); + return -1; + } + *a = *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *a <<= 8; + *a |= *(*in)++; + *inlen -= 4; + return 1; +} + +int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen) +{ + if (*inlen < datalen) { + error_print(); + return -1; + } + *data = *in; + *in += datalen; + *inlen -= datalen; + return 1; +} + +int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) +{ + uint8_t len; + if (tls_uint8_from_bytes(&len, in, inlen) != 1 + || tls_array_from_bytes(data, len, in, inlen) != 1) { + error_print(); + return -1; + } + if (!len) { + *data = NULL; + } + *datalen = len; + return 1; +} + +int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) +{ + uint16_t len; + if (tls_uint16_from_bytes(&len, in, inlen) != 1 + || tls_array_from_bytes(data, len, in, inlen) != 1) { + error_print(); + return -1; + } + if (!len) { + *data = NULL; + } + *datalen = len; + return 1; +} + +int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) +{ + uint24_t len; + if (tls_uint24_from_bytes(&len, in, inlen) != 1 + || tls_array_from_bytes(data, len, in, inlen) != 1) { + error_print(); + return -1; + } + if (!len) { + *data = NULL; + } + *datalen = len; + return 1; +} + +int tls_length_is_zero(size_t len) +{ + if (len) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_type(uint8_t *record, int type) +{ + if (!tls_record_type_name(type)) { + error_print(); + return -1; + } + record[0] = type; + return 1; +} + +int tls_record_set_protocol(uint8_t *record, int protocol) +{ + if (!tls_protocol_name(protocol)) { + error_print(); + return -1; + } + record[1] = protocol >> 8; + record[2] = protocol; + return 1; +} + +int tls_record_set_length(uint8_t *record, size_t length) +{ + uint8_t *p = record + 3; + size_t len; + if (length > TLS_MAX_CIPHERTEXT_SIZE) { + error_print(); + return -1; + } + tls_uint16_to_bytes(length, &p, &len); + return 1; +} + +int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen) +{ + if (tls_record_set_length(record, datalen) != 1) { + error_print(); + return -1; + } + memcpy(tls_record_data(record), data, datalen); + return 1; +} + +int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, + const uint8_t seq_num[8], const uint8_t header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM3_HMAC_CTX hmac_ctx; + uint8_t last_blocks[32 + 16] = {0}; + uint8_t *mac, *padding, *iv; + int rem, padding_len; + int i; + + if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) { + error_print(); + return -1; + } + if (inlen > (1 << 14)) { + error_print_msg("invalid tls record data length %zu\n", inlen); + return -1; + } + if ((((size_t)header[3]) << 8) + header[4] != inlen) { + error_print(); + return -1; + } + + rem = (inlen + 32) % 16; + memcpy(last_blocks, in + inlen - rem, rem); + mac = last_blocks + rem; + + memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, seq_num, 8); + sm3_hmac_update(&hmac_ctx, header, 5); + sm3_hmac_update(&hmac_ctx, in, inlen); + sm3_hmac_finish(&hmac_ctx, mac); + + padding = mac + 32; + padding_len = 16 - rem - 1; + for (i = 0; i <= padding_len; i++) { + padding[i] = padding_len; + } + + iv = out; + if (rand_bytes(iv, 16) != 1) { + error_print(); + return -1; + } + out += 16; + + if (inlen >= 16) { + sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out); + out += inlen - rem; + iv = out - 16; + } + sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out); + *outlen = 16 + inlen - rem + sizeof(last_blocks); + return 1; +} + +int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key, + const uint8_t seq_num[8], const uint8_t enced_header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM3_HMAC_CTX hmac_ctx; + const uint8_t *iv; + const uint8_t *padding; + const uint8_t *mac; + uint8_t header[5]; + int padding_len; + uint8_t hmac[32]; + int i; + + if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) { + error_print(); + return -1; + } + if (inlen % 16 + || inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding + || inlen > (16 + (1<<14) + 32 + 256)) { + error_print_msg("invalid tls cbc ciphertext length %zu\n", inlen); + return -1; + } + + iv = in; + in += 16; + inlen -= 16; + + sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out); + + padding_len = out[inlen - 1]; + padding = out + inlen - padding_len - 1; + if (padding < out + 32) { + error_print(); + return -1; + } + for (i = 0; i < padding_len; i++) { + if (padding[i] != padding_len) { + error_puts("tls ciphertext cbc-padding check failure"); + return -1; + } + } + + *outlen = inlen - 32 - padding_len - 1; + + header[0] = enced_header[0]; + header[1] = enced_header[1]; + header[2] = enced_header[2]; + header[3] = (*outlen) >> 8; + header[4] = (*outlen); + mac = padding - 32; + + memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, seq_num, 8); + sm3_hmac_update(&hmac_ctx, header, 5); + sm3_hmac_update(&hmac_ctx, out, *outlen); + sm3_hmac_finish(&hmac_ctx, hmac); + if (gmssl_secure_memcmp(mac, hmac, sizeof(hmac)) != 0) { + error_puts("tls ciphertext mac check failure\n"); + return -1; + } + return 1; +} + +int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + if (tls_cbc_encrypt(hmac_ctx, cbc_key, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = (*outlen) >> 8; + out[4] = (*outlen); + (*outlen) += 5; + return 1; +} + +int tls_record_decrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + uint8_t *out, size_t *outlen) +{ + if (tls_cbc_decrypt(hmac_ctx, cbc_key, seq_num, in, + in + 5, inlen - 5, + out + 5, outlen) != 1) { + error_print(); + return -1; + } + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = (*outlen) >> 8; + out[4] = (*outlen); + (*outlen) += 5; + + return 1; +} + +int tls_random_generate(uint8_t random[32]) +{ + uint32_t gmt_unix_time = (uint32_t)time(NULL); + uint8_t *p = random; + size_t len = 0; + tls_uint32_to_bytes(gmt_unix_time, &p, &len); + if (rand_bytes(random + 4, 28) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, + const uint8_t *seed, size_t seedlen, + const uint8_t *more, size_t morelen, + size_t outlen, uint8_t *out) +{ + SM3_HMAC_CTX inited_hmac_ctx; + SM3_HMAC_CTX hmac_ctx; + uint8_t A[32]; + uint8_t hmac[32]; + size_t len; + + if (!secret || !secretlen || !label || !seed || !seedlen + || (!more && morelen) || !outlen || !out) { + error_print(); + return -1; + } + + sm3_hmac_init(&inited_hmac_ctx, secret, secretlen); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, A); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, hmac); + + len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); + memcpy(out, hmac, len); + out += len; + outlen -= len; + + while (outlen) { + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_finish(&hmac_ctx, A); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, hmac); + + len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); + memcpy(out, hmac, len); + out += len; + outlen -= len; + } + return 1; +} + +int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol) +{ + if (!tls_protocol_name(protocol)) { + error_print(); + return -1; + } + pre_master_secret[0] = protocol >> 8; + pre_master_secret[1] = protocol; + if (rand_bytes(pre_master_secret + 2, 46) != 1) { + error_print(); + return -1; + } + return 1; +} + +// 用于设置CertificateRequest +int tls_cert_type_from_oid(int oid) +{ + switch (oid) { + case OID_sm2sign_with_sm3: + case OID_ecdsa_with_sha1: + case OID_ecdsa_with_sha224: + case OID_ecdsa_with_sha256: + case OID_ecdsa_with_sha512: + return TLS_cert_type_ecdsa_sign; + case OID_rsasign_with_sm3: + case OID_rsasign_with_md5: + case OID_rsasign_with_sha1: + case OID_rsasign_with_sha224: + case OID_rsasign_with_sha256: + case OID_rsasign_with_sha384: + case OID_rsasign_with_sha512: + return TLS_cert_type_rsa_sign; + } + // TLS_cert_type_xxx 中没有为0的值 + return 0; +} + +// 这两个函数没有对应的TLCP版本 +int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen) +{ + uint8_t server_ecdh_params[69]; + SM2_SIGN_CTX sign_ctx; + + if (!server_sign_key || !client_random || !server_random + || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) { + error_print(); + return -1; + } + server_ecdh_params[0] = TLS_curve_type_named_curve; + server_ecdh_params[1] = curve >> 8; + server_ecdh_params[2] = curve; + server_ecdh_params[3] = 65; + sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); + + sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_sign_update(&sign_ctx, client_random, 32); + sm2_sign_update(&sign_ctx, server_random, 32); + sm2_sign_update(&sign_ctx, server_ecdh_params, 69); + sm2_sign_finish(&sign_ctx, sig, siglen); + + return 1; +} + +int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) +{ + int ret; + uint8_t server_ecdh_params[69]; + SM2_SIGN_CTX verify_ctx; + + if (!server_sign_key || !client_random || !server_random + || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen + || siglen > SM2_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + server_ecdh_params[0] = TLS_curve_type_named_curve; + server_ecdh_params[1] = curve >> 8; + server_ecdh_params[2] = curve; + server_ecdh_params[3] = 65; + sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); + + sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_verify_update(&verify_ctx, client_random, 32); + sm2_verify_update(&verify_ctx, server_random, 32); + sm2_verify_update(&verify_ctx, server_ecdh_params, 69); + ret = sm2_verify_finish(&verify_ctx, sig, siglen); + if (ret != 1) error_print(); + return ret; +} + +int tls_record_set_handshake(uint8_t *record, size_t *recordlen, + int type, const uint8_t *data, size_t datalen) +{ + size_t handshakelen; + + if (!record || !recordlen) { + error_print(); + return -1; + } + // 由于ServerHelloDone没有负载数据,因此允许 data,datalen = NULL,0 + if (datalen > TLS_MAX_PLAINTEXT_SIZE - TLS_HANDSHAKE_HEADER_SIZE) { + error_print(); + return -1; + } + if (!tls_protocol_name(tls_record_protocol(record))) { + error_print(); + return -1; + } + if (!tls_handshake_type_name(type)) { + error_print(); + return -1; + } + handshakelen = TLS_HANDSHAKE_HEADER_SIZE + datalen; + record[0] = TLS_record_handshake; + record[3] = handshakelen >> 8; + record[4] = handshakelen; + record[5] = type; + record[6] = datalen >> 16; + record[7] = datalen >> 8; + record[8] = datalen; + if (data) { + memcpy(tls_handshake_data(tls_record_data(record)), data, datalen); + } + *recordlen = TLS_RECORD_HEADER_SIZE + handshakelen; + return 1; +} + +int tls_record_get_handshake(const uint8_t *record, + int *type, const uint8_t **data, size_t *datalen) +{ + const uint8_t *handshake; + size_t handshake_len; + uint24_t handshake_datalen; + + if (!record || !type || !data || !datalen) { + error_print(); + return -1; + } + if (!tls_protocol_name(tls_record_protocol(record))) { + error_print(); + return -1; + } + if (tls_record_type(record) != TLS_record_handshake) { + error_print(); + return -1; + } + handshake = tls_record_data(record); + handshake_len = tls_record_data_length(record); + + if (handshake_len < TLS_HANDSHAKE_HEADER_SIZE) { + error_print(); + return -1; + } + if (handshake_len > TLS_MAX_PLAINTEXT_SIZE) { + // 不支持证书长度超过记录长度的特殊情况 + error_print(); + return -1; + } + + if (!tls_handshake_type_name(handshake[0])) { + error_print(); + return -1; + } + *type = handshake[0]; + + handshake++; + handshake_len--; + if (tls_uint24_from_bytes(&handshake_datalen, &handshake, &handshake_len) != 1) { + error_print(); + return -1; + } + if (handshake_len != handshake_datalen) { + error_print(); + return -1; + } + *data = handshake; + *datalen = handshake_datalen; + + if (*datalen == 0) { + *data = NULL; + } + return 1; +} + +int tls_record_set_handshake_client_hello(uint8_t *record, size_t *recordlen, + int protocol, const uint8_t random[32], + const uint8_t *session_id, size_t session_id_len, + const int *cipher_suites, size_t cipher_suites_count, + const uint8_t *exts, size_t exts_len) +{ + uint8_t type = TLS_handshake_client_hello; + uint8_t *p; + size_t len; + + if (!record || !recordlen || !random || !cipher_suites || !cipher_suites_count) { + error_print(); + return -1; + } + if (session_id) { + if (!session_id_len + || session_id_len < TLS_MAX_SESSION_ID_SIZE + || session_id_len > TLS_MAX_SESSION_ID_SIZE) { + error_print(); + return -1; + } + } + if (cipher_suites_count > TLS_MAX_CIPHER_SUITES_COUNT) { + error_print(); + return -1; + } + if (exts && !exts_len) { + error_print(); + return -1; + } + + + p = tls_handshake_data(tls_record_data(record)); + len = 0; + + if (!tls_protocol_name(protocol)) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)protocol, &p, &len); + tls_array_to_bytes(random, 32, &p, &len); + tls_uint8array_to_bytes(session_id, session_id_len, &p, &len); + tls_uint16_to_bytes(cipher_suites_count * 2, &p, &len); + while (cipher_suites_count--) { + if (!tls_cipher_suite_name(*cipher_suites)) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)*cipher_suites, &p, &len); + cipher_suites++; + } + tls_uint8_to_bytes(1, &p, &len); + tls_uint8_to_bytes((uint8_t)TLS_compression_null, &p, &len); + if (exts) { + size_t tmp_len = len; + if (protocol < TLS_protocol_tls12) { + error_print(); + return -1; + } + tls_uint16array_to_bytes(exts, exts_len, NULL, &tmp_len); + if (tmp_len > TLS_MAX_HANDSHAKE_DATA_SIZE) { + error_print(); + return -1; + } + tls_uint16array_to_bytes(exts, exts_len, &p, &len); + } + if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_get_handshake_client_hello(const uint8_t *record, + int *protocol, const uint8_t **random, + const uint8_t **session_id, size_t *session_id_len, + const uint8_t **cipher_suites, size_t *cipher_suites_len, + const uint8_t **exts, size_t *exts_len) +{ + int type; + const uint8_t *p; + size_t len; + uint16_t ver; + const uint8_t *comp_meths; + size_t comp_meths_len; + + if (!record || !protocol || !random + || !session_id || !session_id_len + || !cipher_suites || !cipher_suites_len + || !exts || !exts_len) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_client_hello) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&ver, &p, &len) != 1 + || tls_array_from_bytes(random, 32, &p, &len) != 1 + || tls_uint8array_from_bytes(session_id, session_id_len, &p, &len) != 1 + || tls_uint16array_from_bytes(cipher_suites, cipher_suites_len, &p, &len) != 1 + || tls_uint8array_from_bytes(&comp_meths, &comp_meths_len, &p, &len) != 1) { + error_print(); + return -1; + } + + if (!tls_protocol_name(ver)) { + error_print(); + return -1; + } + *protocol = ver; + + if (*session_id) { + if (*session_id_len == 0 + || *session_id_len < TLS_MIN_SESSION_ID_SIZE + || *session_id_len > TLS_MAX_SESSION_ID_SIZE) { + error_print(); + return -1; + } + } + + if (!cipher_suites) { + error_print(); + return -1; + } + if (*cipher_suites_len % 2) { + error_print(); + return -1; + } + + if (len) { + if (tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1) { + error_print(); + return -1; + } + if (*exts == NULL) { + error_print(); + return -1; + } + } else { + *exts = NULL; + *exts_len = 0; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, + int protocol, const uint8_t random[32], + const uint8_t *session_id, size_t session_id_len, int cipher_suite, + const uint8_t *exts, size_t exts_len) +{ + uint8_t type = TLS_handshake_server_hello; + uint8_t *p; + size_t len; + + if (!record || !recordlen || !random) { + error_print(); + return -1; + } + if (session_id) { + if (session_id_len == 0 + || session_id_len < TLS_MIN_SESSION_ID_SIZE + || session_id_len > TLS_MAX_SESSION_ID_SIZE) { + error_print(); + return -1; + } + } + if (!tls_protocol_name(protocol)) { + error_print(); + return -1; + } + if (!tls_cipher_suite_name(cipher_suite)) { + error_print(); + return -1; + } + + p = tls_handshake_data(tls_record_data(record)); + len = 0; + + tls_uint16_to_bytes((uint16_t)protocol, &p, &len); + tls_array_to_bytes(random, 32, &p, &len); + tls_uint8array_to_bytes(session_id, session_id_len, &p, &len); + tls_uint16_to_bytes((uint16_t)cipher_suite, &p, &len); + tls_uint8_to_bytes((uint8_t)TLS_compression_null, &p, &len); + if (exts) { + if (protocol < TLS_protocol_tls12) { + error_print(); + return -1; + } + tls_uint16array_to_bytes(exts, exts_len, &p, &len); + } + if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_get_handshake_server_hello(const uint8_t *record, + int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len, + int *cipher_suite, const uint8_t **exts, size_t *exts_len) +{ + int type; + const uint8_t *p; + size_t len; + uint16_t ver; + uint16_t cipher; + uint8_t comp_meth; + + if (!record || !protocol || !random || !session_id || !session_id_len + || !cipher_suite || !exts || !exts_len) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_server_hello) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&ver, &p, &len) != 1 + || tls_array_from_bytes(random, 32, &p, &len) != 1 + || tls_uint8array_from_bytes(session_id, session_id_len, &p, &len) != 1 + || tls_uint16_from_bytes(&cipher, &p, &len) != 1 + || tls_uint8_from_bytes(&comp_meth, &p, &len) != 1) { + error_print(); + return -1; + } + + if (!tls_protocol_name(ver)) { + error_print(); + return -1; + } + if (ver < tls_record_protocol(record)) { + error_print(); + return -1; + } + *protocol = ver; + + if (*session_id) { + if (*session_id == 0 + || *session_id_len < TLS_MIN_SESSION_ID_SIZE + || *session_id_len > TLS_MAX_SESSION_ID_SIZE) { + error_print(); + return -1; + } + } + + if (!tls_cipher_suite_name(cipher)) { + error_print(); + return -1; + } + *cipher_suite = cipher; + + if (comp_meth != TLS_compression_null) { + error_print(); + return -1; + } + + if (len) { + if (tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1) { + error_print(); + return -1; + } + if (*exts == NULL) { + error_print(); + return -1; + } + } else { + *exts = NULL; + *exts_len = 0; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, + const uint8_t *certs, size_t certslen) +{ + int type = TLS_handshake_certificate; + uint8_t *data; + size_t datalen; + uint8_t *p; + size_t len; + + if (!record || !recordlen || !certs || !certslen) { + error_print(); + return -1; + } + data = tls_handshake_data(tls_record_data(record)); + p = data + tls_uint24_size(); + datalen = tls_uint24_size(); + len = 0; + + while (certslen) { + const uint8_t *cert; + size_t certlen; + + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + tls_uint24array_to_bytes(cert, certlen, NULL, &datalen); + if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { + error_print(); + return -1; + } + tls_uint24array_to_bytes(cert, certlen, &p, &len); + } + tls_uint24_to_bytes(len, &data, &len); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen) +{ + int type; + const uint8_t *data; + size_t datalen; + const uint8_t *cp; + size_t len; + + if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate) { + error_print(); + return -1; + } + if (tls_uint24array_from_bytes(&cp, &len, &data, &datalen) != 1) { + error_print(); + return -1; + } + + *certslen = 0; + while (len) { + const uint8_t *a; + size_t alen; + const uint8_t *cert; + size_t certlen; + + if (tls_uint24array_from_bytes(&a, &alen, &cp, &len) != 1) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cert, &certlen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1 + || x509_cert_to_der(cert, certlen, &certs, certslen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, + const uint8_t *cert_types, size_t cert_types_len, + const uint8_t *ca_names, size_t ca_names_len) +{ + int type = TLS_handshake_certificate_request; + uint8_t *p; + size_t len =0; + size_t datalen = 0; + + if (!record || !recordlen) { + error_print(); + return -1; + } + if (cert_types) { + if (cert_types_len == 0 || cert_types_len > TLS_MAX_CERTIFICATE_TYPES) { + error_print(); + return -1; + } + } + if (ca_names) { + if (ca_names_len == 0 || ca_names_len > TLS_MAX_CA_NAMES_SIZE) { + error_print(); + return -1; + } + } + tls_uint8array_to_bytes(cert_types, cert_types_len, NULL, &datalen); + tls_uint16array_to_bytes(ca_names, ca_names_len, NULL, &datalen); + if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { + error_print(); + return -1; + } + p = tls_handshake_data(tls_record_data(record)); + tls_uint8array_to_bytes(cert_types, cert_types_len, &p, &len); + tls_uint16array_to_bytes(ca_names, ca_names_len, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **cert_types, size_t *cert_types_len, + const uint8_t **ca_names, size_t *ca_names_len) +{ + int type; + const uint8_t *cp; + size_t len; + size_t i; + + if (!record || !cert_types || !cert_types_len || !ca_names || !ca_names_len) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_request) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(cert_types, cert_types_len, &cp, &len) != 1 + || tls_uint16array_from_bytes(ca_names, ca_names_len, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + if (*cert_types == NULL) { + error_print(); + return -1; + } + for (i = 0; i < *cert_types_len; i++) { + if (!tls_cert_type_name((*cert_types)[i])) { + error_print(); + return -1; + } + } + if (*ca_names) { + const uint8_t *names = *ca_names; + size_t nameslen = *ca_names_len; + while (nameslen) { + if (tls_uint16array_from_bytes(&cp, &len, &names, &nameslen) != 1) { + error_print(); + return -1; + } + } + } + return 1; +} + +int tls_record_set_handshake_server_hello_done(uint8_t *record, size_t *recordlen) +{ + int type = TLS_handshake_server_hello_done; + if (!record || !recordlen) { + error_print(); + return -1; + } + tls_record_set_handshake(record, recordlen, type, NULL, 0); + return 1; +} + +int tls_record_get_handshake_server_hello_done(const uint8_t *record) +{ + int type; + const uint8_t *p; + size_t len; + + if (!record) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_server_hello_done) { + error_print(); + return -1; + } + if (p != NULL || len != 0) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_client_key_exchange_pke(uint8_t *record, size_t *recordlen, + const uint8_t *enced_pms, size_t enced_pms_len) +{ + int type = TLS_handshake_client_key_exchange; + uint8_t *p; + size_t len = 0; + + if (!record || !recordlen || !enced_pms || !enced_pms_len) { + error_print(); + return -1; + } + if (enced_pms_len > TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint16_size()) { + error_print(); + return -1; + } + p = tls_handshake_data(tls_record_data(record)); + tls_uint16array_to_bytes(enced_pms, enced_pms_len, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record, + const uint8_t **enced_pms, size_t *enced_pms_len) +{ + int type; + const uint8_t *cp; + size_t len; + + if (!record || !enced_pms || !enced_pms_len) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_client_key_exchange) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(enced_pms, enced_pms_len, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, + const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_certificate_verify; + + if (!record || !recordlen || !sig || !siglen) { + error_print(); + return -1; + } + if (siglen > TLS_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + tls_record_set_handshake(record, recordlen, type, sig, siglen); + return 1; +} + +int tls_record_get_handshake_certificate_verify(const uint8_t *record, + const uint8_t **sig, size_t *siglen) +{ + int type; + + if (!record || !sig || !siglen) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, sig, siglen) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_verify) { + error_print(); + return -1; + } + if (*sig == NULL || *siglen == 0) { + error_print(); + return -1; + } + if (*siglen > TLS_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen, + const uint8_t *verify_data, size_t verify_data_len) +{ + int type = TLS_handshake_finished; + + if (!record || !recordlen || !verify_data || !verify_data_len) { + error_print(); + return -1; + } + if (verify_data_len != 12 && verify_data_len != 32) { + error_print(); + return -1; + } + tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); + return 1; +} + +int tls_record_get_handshake_finished(const uint8_t *record, const uint8_t **verify_data, size_t *verify_data_len) +{ + int type; + + if (!record || !verify_data || !verify_data_len) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, verify_data, verify_data_len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_finished) { + error_print(); + return -1; + } + if (*verify_data == NULL || *verify_data_len == 0) { + error_print(); + return -1; + } + if (*verify_data_len != 12 && *verify_data_len != 32) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_alert(uint8_t *record, size_t *recordlen, + int alert_level, + int alert_description) +{ + if (!record || !recordlen) { + error_print(); + return -1; + } + if (!tls_alert_level_name(alert_level)) { + error_print(); + return -1; + } + if (!tls_alert_description_text(alert_description)) { + error_print(); + return -1; + } + record[0] = TLS_record_alert; + record[3] = 0; // length + record[4] = 2; // length + record[5] = (uint8_t)alert_level; + record[6] = (uint8_t)alert_description; + *recordlen = TLS_RECORD_HEADER_SIZE + 2; + return 1; +} + +int tls_record_get_alert(const uint8_t *record, + int *alert_level, + int *alert_description) +{ + if (!record || !alert_level || !alert_description) { + error_print(); + return -1; + } + if (tls_record_type(record) != TLS_record_alert) { + error_print(); + return -1; + } + if (record[3] != 0 || record[4] != 2) { + error_print(); + return -1; + } + *alert_level = record[5]; + *alert_description = record[6]; + if (!tls_alert_level_name(*alert_level)) { + error_print(); + return -1; + } + if (!tls_alert_description_text(*alert_description)) { + error_puts("warning"); + return -1; + } + return 1; +} + +int tls_record_set_change_cipher_spec(uint8_t *record, size_t *recordlen) +{ + if (!record || !recordlen) { + error_print(); + return -1; + } + record[0] = TLS_record_change_cipher_spec; + record[3] = 0; + record[4] = 1; + record[5] = TLS_change_cipher_spec; + *recordlen = TLS_RECORD_HEADER_SIZE + 1; + return 1; +} + +int tls_record_get_change_cipher_spec(const uint8_t *record) +{ + if (!record) { + error_print(); + return -1; + } + if (tls_record_type(record) != TLS_record_change_cipher_spec) { + error_print(); + return -1; + } + if (record[3] != 0 || record[4] != 1) { + error_print(); + return -1; + } + if (record[5] != TLS_change_cipher_spec) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_application_data(uint8_t *record, size_t *recordlen, + const uint8_t *data, size_t datalen) +{ + if (!record || !recordlen || !data || !datalen) { + error_print(); + return -1; + } + record[0] = TLS_record_application_data; + record[3] = (datalen >> 8) & 0xff; + record[4] = datalen & 0xff; + memcpy(tls_record_data(record), data, datalen); + *recordlen = TLS_RECORD_HEADER_SIZE + datalen; + return 1; +} + +int tls_record_get_application_data(uint8_t *record, + const uint8_t **data, size_t *datalen) +{ + if (!record || !data || !datalen) { + error_print(); + return -1; + } + if (tls_record_type(record) != TLS_record_application_data) { + error_print(); + return -1; + } + *datalen = ((size_t)record[3] << 8) | record[4]; + *data = *datalen ? record + TLS_RECORD_HEADER_SIZE : 0; + return 1; +} + +int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count) +{ + size_t i; + if (!list || !list_count) { + error_print(); + return -1; + } + for (i = 0; i < list_count; i++) { + if (cipher == list[i]) { + return 1; + } + } + return 0; +} + +int tls_record_send(const uint8_t *record, size_t recordlen, int sock) +{ + ssize_t r; + if (!record) { + error_print(); + return -1; + } + if (recordlen < TLS_RECORD_HEADER_SIZE) { + error_print(); + return -1; + } + if (tls_record_length(record) != recordlen) { + error_print(); + return -1; + } + if ((r = send(sock, record, recordlen, 0)) < 0) { + perror("tls_record_send"); + error_print(); + return -1; + } else if (r != recordlen) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_do_recv(uint8_t *record, size_t *recordlen, int sock) +{ + ssize_t r; + int type; + size_t len; + + len = 5; + while (len) { + if ((r = recv(sock, record + 5 - len, len, 0)) < 0) { + perror("tls_record_do_recv"); + error_print(); + return -1; + } + if (r == 0) { + perror("tls_record_do_recv"); + error_print(); + return 0; + } + + len -= r; + } + if (!tls_record_type_name(tls_record_type(record))) { + error_print(); + return -1; + } + if (!tls_protocol_name(tls_record_protocol(record))) { + error_print(); + return -1; + } + len = (size_t)record[3] << 8 | record[4]; + *recordlen = 5 + len; + if (*recordlen > TLS_MAX_RECORD_SIZE) { + // 这里只检查是否超过最大长度,握手协议的长度检查由上层协议完成 + error_print(); + return -1; + } + while (len) { + if ((r = recv(sock, record + *recordlen - len, len, 0)) < 0) { + perror("tls_record_do_recv"); + error_print(); + return -1; + } + len -= r; + } + return 1; +} + +int tls_record_recv(uint8_t *record, size_t *recordlen, int sock) +{ +retry: + if (tls_record_do_recv(record, recordlen, sock) != 1) { + error_print(); + return -1; + } + + if (tls_record_type(record) == TLS_record_alert) { + int level; + int alert; + if (tls_record_get_alert(record, &level, &alert) != 1) { + error_print(); + return -1; + } + tls_record_trace(stderr, record, *recordlen, 0, 0); + if (level == TLS_alert_level_warning) { + // 忽略Warning,读取下一个记录 + error_puts("Warning record received!\n"); + goto retry; + } + if (alert == TLS_alert_close_notify) { + // close_notify是唯一需要提供反馈的Fatal Alert,其他直接中止连接 + uint8_t alert_record[TLS_ALERT_RECORD_SIZE]; + size_t alert_record_len; + tls_record_set_type(alert_record, TLS_record_alert); + tls_record_set_protocol(alert_record, tls_record_protocol(record)); + tls_record_set_alert(alert_record, &alert_record_len, TLS_alert_level_fatal, TLS_alert_close_notify); + + tls_trace("send Alert close_notifiy\n"); + tls_record_trace(stderr, alert_record, alert_record_len, 0, 0); + tls_record_send(alert_record, alert_record_len, sock); + } + // 返回错误0通知调用方不再做任何处理(无需再发送Alert) + return 0; + } + return 1; +} + +int tls_seq_num_incr(uint8_t seq_num[8]) +{ + int i; + for (i = 7; i > 0; i--) { + seq_num[i]++; + if (seq_num[i]) break; + } + // FIXME: 检查溢出 + return 1; +} + +int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t methslen) +{ + if (!meths || !methslen) { + error_print(); + return -1; + } + while (methslen--) { + if (*meths++ == TLS_compression_null) { + return 1; + } + } + error_print(); + return -1; +} + +int tls_send_alert(TLS_CONNECT *conn, int alert) +{ + uint8_t record[5 + 2]; + size_t recordlen; + + if (!conn) { + error_print(); + return -1; + } + tls_record_set_protocol(record, conn->protocol == TLS_protocol_tls13 ? TLS_protocol_tls12 : conn->protocol); + tls_record_set_alert(record, &recordlen, TLS_alert_level_fatal, alert); + + if (tls_record_send(record, sizeof(record), conn->sock) != 1) { + error_print(); + return -1; + } + tls_record_trace(stderr, record, sizeof(record), 0, 0); + return 1; +} + +int tls_alert_level(int alert) +{ + switch (alert) { + case TLS_alert_bad_certificate: + case TLS_alert_unsupported_certificate: + case TLS_alert_certificate_revoked: + case TLS_alert_certificate_expired: + case TLS_alert_certificate_unknown: + return 0; + case TLS_alert_user_canceled: + case TLS_alert_no_renegotiation: + return TLS_alert_level_warning; + default: + return TLS_alert_level_fatal; + } + return -1; +} + +int tls_send_warning(TLS_CONNECT *conn, int alert) +{ + uint8_t record[5 + 2]; + size_t recordlen; + + if (!conn) { + error_print(); + return -1; + } + if (tls_alert_level(alert) == TLS_alert_level_fatal) { + error_print(); + return -1; + } + tls_record_set_protocol(record, conn->protocol == TLS_protocol_tls13 ? TLS_protocol_tls12 : conn->protocol); + tls_record_set_alert(record, &recordlen, TLS_alert_level_warning, alert); + + if (tls_record_send(record, sizeof(record), conn->sock) != 1) { + error_print(); + return -1; + } + tls_record_trace(stderr, record, sizeof(record), 0, 0); + return 1; +} + +int tls_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentlen) +{ + const SM3_HMAC_CTX *hmac_ctx; + const SM4_KEY *enc_key; + uint8_t *seq_num; + uint8_t *record; + size_t recordlen; + uint8_t *data; + size_t datalen; + + if (!conn) { + error_print(); + return -1; + } + if (!in || !inlen || !sentlen) { + error_print(); + return -1; + } + + if (inlen > TLS_MAX_PLAINTEXT_SIZE) { + inlen = TLS_MAX_PLAINTEXT_SIZE; + } + + if (conn->is_client) { + hmac_ctx = &conn->client_write_mac_ctx; + enc_key = &conn->client_write_enc_key; + seq_num = conn->client_seq_num; + } else { + hmac_ctx = &conn->server_write_mac_ctx; + enc_key = &conn->server_write_enc_key; + seq_num = conn->server_seq_num; + } + record = conn->record; + + tls_trace("send ApplicationData\n"); + + if (tls_record_set_type(record, TLS_record_application_data) != 1 + || tls_record_set_protocol(record, conn->protocol) != 1 + || tls_record_set_length(record, inlen) != 1) { + error_print(); + return -1; + } + + if (tls_cbc_encrypt(hmac_ctx, enc_key, seq_num, tls_record_header(record), + in, inlen, tls_record_data(record), &datalen) != 1) { + error_print(); + return -1; + } + if (tls_record_set_length(record, datalen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + if (tls_record_send(record, tls_record_length(record), conn->sock) != 1) { + error_print(); + return -1; + } + *sentlen = inlen; + tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + return 1; +} + +int tls_do_recv(TLS_CONNECT *conn) +{ + int ret; + const SM3_HMAC_CTX *hmac_ctx; + const SM4_KEY *dec_key; + uint8_t *seq_num; + + uint8_t *record = conn->record; + size_t recordlen; + + if (conn->is_client) { + hmac_ctx = &conn->server_write_mac_ctx; + dec_key = &conn->server_write_enc_key; + seq_num = conn->server_seq_num; + } else { + hmac_ctx = &conn->client_write_mac_ctx; + dec_key = &conn->client_write_enc_key; + seq_num = conn->client_seq_num; + } + + tls_trace("recv ApplicationData\n"); + if ((ret = tls_record_recv(record, &recordlen, conn->sock)) != 1) { + if (ret < 0) error_print(); + return ret; + } + + tls_record_trace(stderr, record, recordlen, 0, 0); + if (tls_cbc_decrypt(hmac_ctx, dec_key, seq_num, record, + tls_record_data(record), tls_record_data_length(record), + conn->databuf, &conn->datalen) != 1) { + error_print(); + return -1; + } + conn->data = conn->databuf; + tls_seq_num_incr(seq_num); + + tls_record_set_data(record, conn->data, conn->datalen); + tls_trace("decrypt ApplicationData\n"); + tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + return 1; +} + +int tls_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen) +{ + if (!conn || !out || !outlen || !recvlen) { + error_print(); + return -1; + } + if (conn->datalen == 0) { + int ret; + if ((ret = tls_do_recv(conn)) != 1) { + if (ret) error_print(); + return ret; + } + } + *recvlen = outlen <= conn->datalen ? outlen : conn->datalen; + memcpy(out, conn->data, *recvlen); + conn->data += *recvlen; + conn->datalen -= *recvlen; + return 1; +} + +int tls_shutdown(TLS_CONNECT *conn) +{ + size_t recordlen; + if (!conn) { + error_print(); + return -1; + } + tls_trace("send Alert close_notify\n"); + if (tls_send_alert(conn, TLS_alert_close_notify) != 1) { + error_print(); + return -1; + } + tls_trace("recv Alert close_notify\n"); + + if (tls_record_do_recv(conn->record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_record_trace(stderr, conn->record, recordlen, 0, 0); + + return 1; +} + +int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, const uint8_t *certs, size_t certslen) +{ + const uint8_t *cert; + size_t certlen; + const uint8_t *name; + size_t namelen; + + *nameslen = 0; + while (certslen) { + size_t alen = 0; + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1 + || x509_cert_get_subject(cert, certlen, &name, &namelen) != 1 + || asn1_sequence_to_der(name, namelen, NULL, &alen) != 1) { + error_print(); + return -1; + } + if (tls_uint16_size() + alen > maxlen) { + error_print(); + return -1; + } + tls_uint16_to_bytes(alen, &names, nameslen); + if (asn1_sequence_to_der(name, namelen, &names, nameslen) != 1) { + error_print(); + return -1; + } + maxlen -= alen; + } + return 1; +} + +int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_names_len, const uint8_t *certs, size_t certslen) +{ + const uint8_t *cert; + size_t certlen; + const uint8_t *issuer; + size_t issuer_len; + + if (x509_certs_get_last(certs, certslen, &cert, &certlen) != 1 + || x509_cert_get_issuer(cert, certlen, &issuer, &issuer_len) != 1) { + error_print(); + return -1; + } + while (ca_names_len) { + const uint8_t *p; + size_t len; + const uint8_t *name; + size_t namelen; + + if (tls_uint16array_from_bytes(&p, &len, &ca_names, &ca_names_len) != 1) { + error_print(); + return -1; + } + if (asn1_sequence_from_der(&name, &namelen, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (x509_name_equ(name, namelen, issuer, issuer_len) == 1) { + return 1; + } + } + error_print(); + return 0; +} + +int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len) +{ + const uint8_t *cert; + size_t certlen; + int sig_alg; + size_t i; + + if (x509_certs_get_cert_by_index(client_certs, client_certs_len, 0, &cert, &certlen) != 1) { + error_print(); + return -1; + } + if ((sig_alg = tls_cert_type_from_oid(OID_sm2sign_with_sm3)) < 0) { + error_print(); + return -1; + } + for (i = 0; i < types_len; i++) { + if (sig_alg == types[i]) { + return 1; + } + } + return 0; +} + +int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + memset(ctx, 0, sizeof(TLS_CLIENT_VERIFY_CTX)); + return 1; +} + +int tls_client_verify_update(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *handshake, size_t handshake_len) +{ + uint8_t *buf; + if (!ctx || !handshake || !handshake_len) { + error_print(); + return -1; + } + if (ctx->index < 0 || ctx->index > 7) { + error_print(); + return -1; + } + if (!(buf = malloc(handshake_len))) { + error_print(); + return -1; + } + memcpy(buf, handshake, handshake_len); + ctx->handshake[ctx->index] = buf; + ctx->handshake_len[ctx->index] = handshake_len; + ctx->index++; + return 1; +} + +int tls_client_verify_finish(TLS_CLIENT_VERIFY_CTX *ctx, const uint8_t *sig, size_t siglen, const SM2_KEY *public_key) +{ + int ret; + SM2_SIGN_CTX sm2_ctx; + int i; + + if (!ctx || !sig || !siglen || !public_key) { + error_print(); + return -1; + } + + if (ctx->index != 8) { + error_print(); + return -1; + } + if (sm2_verify_init(&sm2_ctx, public_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + for (i = 0; i < 8; i++) { + if (sm2_verify_update(&sm2_ctx, ctx->handshake[i], ctx->handshake_len[i]) != 1) { + error_print(); + return -1; + } + } + if ((ret = sm2_verify_finish(&sm2_ctx, sig, siglen)) < 0) { + error_print(); + return -1; + } + return ret; +} + +void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx) +{ + if (ctx) { + int i; + for (i = 0; i< ctx->index; i++) { + if (ctx->handshake[i]) { + free(ctx->handshake[i]); + ctx->handshake[i] = NULL; + ctx->handshake_len[i] = 0; + } + } + } +} + +int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len, + const int *server_ciphers, size_t server_ciphers_cnt, + int *selected_cipher) +{ + if (!client_ciphers || !client_ciphers_len + || !server_ciphers || !server_ciphers_cnt || !selected_cipher) { + error_print(); + return -1; + } + while (server_ciphers_cnt--) { + const uint8_t *p = client_ciphers; + size_t len = client_ciphers_len; + while (len) { + uint16_t cipher; + if (tls_uint16_from_bytes(&cipher, &p, &len) != 1) { + error_print(); + return -1; + } + if (cipher == *server_ciphers) { + *selected_cipher = *server_ciphers; + return 1; + } + } + server_ciphers++; + } + return 0; +} + +void tls_ctx_cleanup(TLS_CTX *ctx) +{ + if (ctx) { + gmssl_secure_clear(&ctx->signkey, sizeof(SM2_KEY)); + gmssl_secure_clear(&ctx->kenckey, sizeof(SM2_KEY)); + if (ctx->certs) free(ctx->certs); + if (ctx->cacerts) free(ctx->cacerts); + memset(ctx, 0, sizeof(TLS_CTX)); + } +} + +int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) +{ + if (!ctx) { + error_print(); + return -1; + } + memset(ctx, 0, sizeof(*ctx)); + + switch (protocol) { + case TLS_protocol_tlcp: + case TLS_protocol_tls12: + case TLS_protocol_tls13: + ctx->protocol = protocol; + break; + default: + error_print(); + return -1; + } + ctx->is_client = is_client ? 1 : 0; + return 1; +} + +int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt) +{ + size_t i; + + if (!ctx || !cipher_suites || !cipher_suites_cnt) { + error_print(); + return -1; + } + if (cipher_suites_cnt < 1 || cipher_suites_cnt > TLS_MAX_CIPHER_SUITES_COUNT) { + error_print(); + return -1; + } + for (i = 0; i < cipher_suites_cnt; i++) { + if (!tls_cipher_suite_name(cipher_suites[i])) { + error_print(); + return -1; + } + } + for (i = 0; i < cipher_suites_cnt; i++) { + ctx->cipher_suites[i] = cipher_suites[i]; + } + ctx->cipher_suites_cnt = cipher_suites_cnt; + return 1; +} + +int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth) +{ + if (!ctx || !cacertsfile) { + error_print(); + return -1; + } + if (depth < 0 || depth > TLS_MAX_VERIFY_DEPTH) { + error_print(); + return -1; + } + if (!tls_protocol_name(ctx->protocol)) { + error_print(); + return -1; + } + if (ctx->cacerts) { + error_print(); + return -1; + } + if (x509_certs_new_from_file(&ctx->cacerts, &ctx->cacertslen, cacertsfile) != 1) { + error_print(); + return -1; + } + if (ctx->cacertslen == 0) { + error_print(); + return -1; + } + + ctx->verify_depth = depth; + return 1; +} + +int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile, + const char *keyfile, const char *keypass) +{ + int ret = -1; + uint8_t *certs = NULL; + size_t certslen; + FILE *keyfp = NULL; + SM2_KEY key; + const uint8_t *cert; + size_t certlen; + SM2_KEY public_key; + + if (!ctx || !chainfile || !keyfile || !keypass) { + error_print(); + return -1; + } + if (!tls_protocol_name(ctx->protocol)) { + error_print(); + return -1; + } + if (ctx->certs) { + error_print(); + return -1; + } + + if (x509_certs_new_from_file(&certs, &certslen, chainfile) != 1) { + error_print(); + goto end; + } + if (!(keyfp = fopen(keyfile, "r"))) { + error_print(); + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&key, keypass, keyfp) != 1) { + error_print(); + goto end; + } + if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + return -1; + } + if (sm2_public_key_equ(&key, &public_key) != 1) { + error_print(); + return -1; + } + ctx->certs = certs; + ctx->certslen = certslen; + ctx->signkey = key; + certs = NULL; + ret = 1; + +end: + gmssl_secure_clear(&key, sizeof(key)); + if (certs) free(certs); + if (keyfp) fclose(keyfp); + return ret; +} + +int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile, + const char *signkeyfile, const char *signkeypass, + const char *kenckeyfile, const char *kenckeypass) +{ + int ret = -1; + uint8_t *certs = NULL; + size_t certslen; + FILE *signkeyfp = NULL; + FILE *kenckeyfp = NULL; + SM2_KEY signkey; + SM2_KEY kenckey; + + const uint8_t *cert; + size_t certlen; + SM2_KEY public_key; + + if (!ctx || !chainfile || !signkeyfile || !signkeypass || !kenckeyfile || !kenckeypass) { + error_print(); + return -1; + } + if (!tls_protocol_name(ctx->protocol)) { + error_print(); + return -1; + } + if (ctx->certs) { + error_print(); + return -1; + } + + if (x509_certs_new_from_file(&certs, &certslen, chainfile) != 1) { + error_print(); + return -1; + } + + if (!(signkeyfp = fopen(signkeyfile, "r"))) { + error_print(); + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&signkey, signkeypass, signkeyfp) != 1) { + error_print(); + goto end; + } + if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 + || sm2_public_key_equ(&signkey, &public_key) != 1) { + error_print(); + goto end; + } + + if (!(kenckeyfp = fopen(kenckeyfile, "r"))) { + error_print(); + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&kenckey, kenckeypass, kenckeyfp) != 1) { + error_print(); + goto end; + } + if (x509_certs_get_cert_by_index(certs, certslen, 1, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1 + || sm2_public_key_equ(&kenckey, &public_key) != 1) { + error_print(); + goto end; + } + + ctx->certs = certs; + ctx->certslen = certslen; + ctx->signkey = signkey; + ctx->kenckey = kenckey; + certs = NULL; + ret = 1; + +end: + gmssl_secure_clear(&signkey, sizeof(signkey)); + gmssl_secure_clear(&kenckey, sizeof(kenckey)); + if (certs) free(certs); + if (signkeyfp) fclose(signkeyfp); + if (kenckeyfp) fclose(kenckeyfp); + return ret; +} + +int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx) +{ + size_t i; + memset(conn, 0, sizeof(*conn)); + + conn->protocol = ctx->protocol; + conn->is_client = ctx->is_client; + for (i = 0; i < ctx->cipher_suites_cnt; i++) { + conn->cipher_suites[i] = ctx->cipher_suites[i]; + } + conn->cipher_suites_cnt = ctx->cipher_suites_cnt; + + + if (ctx->certslen > TLS_MAX_CERTIFICATES_SIZE) { + error_print(); + return -1; + } + if (conn->is_client) { + memcpy(conn->client_certs, ctx->certs, ctx->certslen); + conn->client_certs_len = ctx->certslen; + } else { + memcpy(conn->server_certs, ctx->certs, ctx->certslen); + conn->server_certs_len = ctx->certslen; + } + + if (ctx->cacertslen > TLS_MAX_CERTIFICATES_SIZE) { + error_print(); + return -1; + } + memcpy(conn->ca_certs, ctx->cacerts, ctx->cacertslen); + conn->ca_certs_len = ctx->cacertslen; + + conn->sign_key = ctx->signkey; + conn->kenc_key = ctx->kenckey; + + return 1; +} + +void tls_cleanup(TLS_CONNECT *conn) +{ + gmssl_secure_clear(conn, sizeof(TLS_CONNECT)); +} + + +int tls_set_socket(TLS_CONNECT *conn, int sock) +{ + int opts; + + if ((opts = fcntl(sock, F_GETFL)) < 0) { + error_print(); + perror("tls_set_socket"); + return -1; + } + opts &= ~O_NONBLOCK; + if (fcntl(sock, F_SETFL, opts) < 0) { + error_print(); + return -1; + } + conn->sock = sock; + return 1; +} + +int tls_do_handshake(TLS_CONNECT *conn) +{ + switch (conn->protocol) { + case TLS_protocol_tlcp: + if (conn->is_client) return tlcp_do_connect(conn); + else return tlcp_do_accept(conn); + case TLS_protocol_tls12: + if (conn->is_client) return tls12_do_connect(conn); + else return tls12_do_accept(conn); + case TLS_protocol_tls13: + if (conn->is_client) return tls13_do_connect(conn); + else return tls13_do_accept(conn); + } + error_print(); + return -1; +} + +int tls_get_verify_result(TLS_CONNECT *conn, int *result) +{ + *result = conn->verify_result; + return 1; +} diff --git a/src/tls12.c b/src/tls12.c index 5d30dffc..fe056a7a 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1084 +7,1085 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -static const int tls12_ciphers[] = { - TLS_cipher_ecdhe_sm4_cbc_sm3, -}; - -static const size_t tls12_ciphers_count = sizeof(tls12_ciphers)/sizeof(tls12_ciphers[0]); - -static const uint8_t tls12_exts[] = { - /* supported_groups */ 0x00,0x0A, 0x00,0x04, 0x00,0x02, 0x00,30,//0x29, // curveSM2 - /* ec_point_formats */ 0x00,0x0B, 0x00,0x02, 0x01, 0x00, // uncompressed - /* signature_algors */ 0x00,0x0D, 0x00,0x04, 0x00,0x02, 0x07,0x07,//0x08, // sm2sig_sm3 -}; - - -int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) -{ - // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 - // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) - format |= tls12_ciphers[0] << 8; - return tls_record_print(fp, record, recordlen, format, indent); -} - - -int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, - int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) -{ - int type = TLS_handshake_server_key_exchange; - uint8_t *server_ecdh_params = record + 9; - uint8_t *p = server_ecdh_params + 69; - size_t len = 69; - - if (!record || !recordlen || !tls_named_curve_name(curve) || !point - || !sig || !siglen || siglen > TLS_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - server_ecdh_params[0] = TLS_curve_type_named_curve; - server_ecdh_params[1] = curve >> 8; - server_ecdh_params[2] = curve; - server_ecdh_params[3] = 65; - sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); - tls_uint16_to_bytes(TLS_sig_sm2sig_sm3, &p, &len); - tls_uint16array_to_bytes(sig, siglen, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - return 1; -} - -// 这里返回的应该是一个SM2_POINT吗? -int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record, - int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen) -{ - int type; - const uint8_t *p; - size_t len; - uint8_t curve_type; - uint16_t named_curve; - const uint8_t *octets; - size_t octetslen; - uint16_t sig_alg; - - if (!record || !curve || !point || !sig || !siglen) { - error_print(); - return -1; - } - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_server_key_exchange) { - error_print(); - return -1; - } - if (tls_uint8_from_bytes(&curve_type, &p, &len) != 1 - || tls_uint16_from_bytes(&named_curve, &p, &len) != 1 - || tls_uint8array_from_bytes(&octets, &octetslen, &p, &len) != 1 - || tls_uint16_from_bytes(&sig_alg, &p, &len) != 1 - || tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (curve_type != TLS_curve_type_named_curve) { - error_print(); - return -1; - } - if (named_curve != TLS_curve_sm2p256v1) { - error_print(); - return -1; - } - *curve = named_curve; - if (octetslen != 65 - || sm2_point_from_octets(point, octets, octetslen) != 1) { - error_print(); - return -1; - } - if (sig_alg != TLS_sig_sm2sig_sm3) { - error_print(); - return -1; - } - return 1; -} - -int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, - const SM2_POINT *point) -{ - int type = TLS_handshake_client_key_exchange; - record[9] = 65; - sm2_point_to_uncompressed_octets(point, record + 9 + 1); - tls_record_set_handshake(record, recordlen, type, NULL, 1 + 65); - return 1; -} - -int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point) -{ - int type; - const uint8_t *p; - size_t len; - const uint8_t *octets; - size_t octetslen; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_client_key_exchange) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(&octets, &octetslen, &p, &len) != 1 - || len > 0) { - error_print(); - return -1; - } - if (octetslen != 65 - || sm2_point_from_octets(point, octets, octetslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -/* - Client Server - - ClientHello --------> - ServerHello - Certificate - ServerKeyExchange - CertificateRequest* - <-------- ServerHelloDone - Certificate* - ClientKeyExchange - CertificateVerify* - [ChangeCipherSpec] - Finished --------> - [ChangeCipherSpec] - <-------- Finished - Application Data <-------> Application Data - - -*/ - -int tls12_do_connect(TLS_CONNECT *conn) -{ - int ret = -1; - uint8_t *record = conn->record; - uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; - size_t recordlen, finished_record_len; - - uint8_t client_random[32]; - uint8_t server_random[32]; - int protocol; - int cipher_suite; - const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - - uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t client_exts_len = 0; - const uint8_t *server_exts; - size_t server_exts_len; - - // 扩展的协商结果,-1 表示服务器不支持该扩展(未给出响应) - int ec_point_format = -1; - int supported_group = -1; - int signature_algor = -1; - - - SM2_KEY server_sign_key; - SM2_SIGN_CTX verify_ctx; - SM2_SIGN_CTX sign_ctx; - const uint8_t *sig; - size_t siglen; - uint8_t pre_master_secret[48]; - SM3_CTX sm3_ctx; - SM3_CTX tmp_sm3_ctx; - uint8_t sm3_hash[32]; - const uint8_t *verify_data; - size_t verify_data_len; - uint8_t local_verify_data[12]; - - int handshake_type; - const uint8_t *server_enc_cert; // 这几个值也是不需要的 - size_t server_enc_cert_len; - uint8_t server_enc_cert_lenbuf[3]; - const uint8_t *cp; - uint8_t *p; - size_t len; - - int depth = 5; - int alert = 0; - int verify_result; - - - // 初始化记录缓冲 - tls_record_set_protocol(record, TLS_protocol_tls1); // ClientHello的记录层协议版本是TLSv1.0 - tls_record_set_protocol(finished_record, conn->protocol); - - // 准备Finished Context(和ClientVerify) - sm3_init(&sm3_ctx); - if (conn->client_certs_len) - sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - - - // send ClientHello - tls_random_generate(client_random); - int ec_point_formats[] = { TLS_point_uncompressed }; - size_t ec_point_formats_cnt = 1; - int supported_groups[] = { TLS_curve_sm2p256v1 }; - size_t supported_groups_cnt = 1; - int signature_algors[] = { TLS_sig_sm2sig_sm3 }; - size_t signature_algors_cnt = 1; - - - p = client_exts; - client_exts_len = 0; - - tls_ec_point_formats_ext_to_bytes(ec_point_formats, ec_point_formats_cnt, &p, &client_exts_len); - tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &p, &client_exts_len); - tls_signature_algorithms_ext_to_bytes(signature_algors, signature_algors_cnt, &p, &client_exts_len); - - if (tls_record_set_handshake_client_hello(record, &recordlen, - conn->protocol, client_random, NULL, 0, - tls12_ciphers, tls12_ciphers_count, - client_exts, client_exts_len) != 1) { - error_print(); - goto end; - } - tls_trace("send ClientHello\n"); - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerHello - tls_trace("recv ServerHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - if (tls_record_get_handshake_server_hello(record, - &protocol, &random, &session_id, &session_id_len, &cipher_suite, - &server_exts, &server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (protocol != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - // tls12_ciphers 应该改为conn的内部变量 - if (tls_cipher_suite_in_list(cipher_suite, tls12_ciphers, tls12_ciphers_count) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; - } - if (!server_exts) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (tls_process_server_hello_exts(server_exts, server_exts_len, &ec_point_format, &supported_group, &signature_algor) != 1 - || ec_point_format < 0 - || supported_group < 0 - || signature_algor < 0) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - memcpy(server_random, random, 32); - memcpy(conn->session_id, session_id, session_id_len); - conn->cipher_suite = cipher_suite; - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerCertificate - tls_trace("recv ServerCertificate\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - - if (tls_record_get_handshake_certificate(record, - conn->server_certs, &conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // verify ServerCertificate - if (x509_certs_verify(conn->server_certs, conn->server_certs_len, - conn->ca_certs, conn->ca_certs_len, depth, &verify_result) != 1) { - error_print(); - tls_send_alert(conn, alert); - goto end; - } - - // recv ServerKeyExchange - tls_trace("recv ServerKeyExchange\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - - int curve; - SM2_POINT server_ecdhe_public; - if (tls_record_get_handshake_server_key_exchange_ecdhe(record, &curve, &server_ecdhe_public, &sig, &siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (curve != TLS_curve_sm2p256v1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // verify ServerKeyExchange - if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 - || x509_cert_get_subject_public_key(cp, len, &server_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - if (tls_verify_server_ecdh_params(&server_sign_key, // 这应该是签名公钥 - client_random, server_random, curve, &server_ecdhe_public, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - - // recv CertificateRequest or ServerHelloDone - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol - || tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (handshake_type == TLS_handshake_certificate_request) { - const uint8_t *cert_types; - size_t cert_types_len; - const uint8_t *ca_names; - size_t ca_names_len; - - // recv CertificateRequest - tls_trace("recv CertificateRequest\n"); - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate_request(record, - &cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if(!conn->client_certs_len) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1 - || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unsupported_certificate); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // recv ServerHelloDone - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - } else { - // 这个得处理一下 - conn->client_certs_len = 0; - gmssl_secure_clear(&conn->sign_key, sizeof(SM2_KEY)); - } - tls_trace("recv ServerHelloDone\n"); - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_server_hello_done(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // send ClientCertificate - if (conn->client_certs_len) { - tls_trace("send ClientCertificate\n"); - if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - } - - // generate MASTER_SECRET - tls_trace("generate secrets\n"); - SM2_KEY client_ecdh; - sm2_key_generate(&client_ecdh); - sm2_ecdh(&client_ecdh, &server_ecdhe_public, &server_ecdhe_public); - memcpy(pre_master_secret, &server_ecdhe_public, 32); // 这个做法很不优雅 - // ECDHE和ECC的PMS结构是不一样的吗? - - if (tls_prf(pre_master_secret, 32, "master secret", - client_random, 32, server_random, 32, - 48, conn->master_secret) != 1 - || tls_prf(conn->master_secret, 48, "key expansion", - server_random, 32, client_random, 32, - 96, conn->key_block) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); - sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); - sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); - sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - /* - tls_secrets_print(stderr, - pre_master_secret, 48, - client_random, server_random, - conn->master_secret, - conn->key_block, 96, - 0, 4); - */ - - // send ClientKeyExchange - tls_trace("send ClientKeyExchange\n"); - if (tls_record_set_handshake_client_key_exchange_ecdhe(record, &recordlen, &client_ecdh.public_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (conn->client_certs_len) - sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); - - // send CertificateVerify - if (conn->client_certs_len) { - tls_trace("send CertificateVerify\n"); - uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; - if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 - || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - } - - // send [ChangeCipherSpec] - tls_trace("send [ChangeCipherSpec]\n"); - if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // send Client Finished - tls_trace("send Finished\n"); - memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); - sm3_finish(&tmp_sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "client finished", - sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1 - || tls_record_set_handshake_finished(finished_record, &finished_record_len, - local_verify_data, sizeof(local_verify_data)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); - sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); - - // encrypt Client Finished - tls_trace("encrypt Finished\n"); - if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, - conn->client_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_seq_num_incr(conn->client_seq_num); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // [ChangeCipherSpec] - tls_trace("recv [ChangeCipherSpec]\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_change_cipher_spec(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - - // Finished - tls_trace("recv Finished\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (recordlen > sizeof(finished_record)) { - error_print(); // 解密可能导致 finished_record 溢出 - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_trace("decrypt Finished\n"); - if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, - conn->server_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); - tls_seq_num_incr(conn->server_seq_num); - if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (verify_data_len != sizeof(local_verify_data)) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - sm3_finish(&sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "server finished", - sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - fprintf(stderr, "Connection established!\n"); - - - conn->protocol = conn->protocol; - conn->cipher_suite = cipher_suite; - - ret = 1; - -end: - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - return 1; -} - -int tls12_do_accept(TLS_CONNECT *conn) -{ - int ret = -1; - - int client_verify = 0; - - uint8_t *record = conn->record; - uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; // 解密可能导致前面的record被覆盖 - size_t recordlen, finished_record_len; - - // 这个ciphers不是应该在CTX中设置的吗 - const int server_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3 }; // 未来应该支持GCM/CBC两个套件 - - // ClientHello, ServerHello - uint8_t client_random[32]; - uint8_t server_random[32]; - int protocol; - const uint8_t *random; - const uint8_t *session_id; // TLCP服务器忽略客户端SessionID,也不主动设置SessionID - size_t session_id_len; - const uint8_t *client_ciphers; - size_t client_ciphers_len; - const uint8_t *client_exts; - size_t client_exts_len; - uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t server_exts_len; - int curve = TLS_curve_sm2p256v1; // 这个是否应该在conn中设置? - - // ServerKeyExchange - SM2_KEY server_ecdhe_key; - SM2_SIGN_CTX sign_ctx; - uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - // ClientCertificate, CertificateVerify - TLS_CLIENT_VERIFY_CTX client_verify_ctx; - SM2_KEY client_sign_key; - const uint8_t *sig; - const int verify_depth = 5; - int verify_result; - - // ClientKeyExchange - SM2_POINT client_ecdhe_point; - uint8_t pre_master_secret[SM2_MAX_PLAINTEXT_SIZE]; // sm2_decrypt 保证输出不会溢出 - size_t pre_master_secret_len; - - // Finished - SM3_CTX sm3_ctx; - SM3_CTX tmp_sm3_ctx; - uint8_t sm3_hash[32]; - uint8_t local_verify_data[12]; - const uint8_t *verify_data; - size_t verify_data_len; - - uint8_t *p; - const uint8_t *cp; - size_t len; - - - // 服务器端如果设置了CA - if (conn->ca_certs_len) - client_verify = 1; - - // 初始化Finished和客户端验证环境 - sm3_init(&sm3_ctx); - if (client_verify) - tls_client_verify_init(&client_verify_ctx); - - - // recv ClientHello - tls_trace("recv ClientHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_protocol(record) != conn->protocol - && tls_record_protocol(record) != TLS_protocol_tls1) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - if (tls_record_get_handshake_client_hello(record, - &protocol, &random, &session_id, &session_id_len, - &client_ciphers, &client_ciphers_len, - &client_exts, &client_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (protocol != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - memcpy(client_random, random, 32); - if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, - server_ciphers, sizeof(server_ciphers)/sizeof(server_ciphers[0]), - &conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_insufficient_security); - goto end; - } - if (client_exts) { - server_exts_len = 0; - curve = TLS_curve_sm2p256v1; - - tls_process_client_hello_exts(client_exts, client_exts_len, server_exts, &server_exts_len, sizeof(server_exts)); - - - - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - - // send ServerHello - tls_trace("send ServerHello\n"); - tls_random_generate(server_random); - tls_record_set_protocol(record, conn->protocol); - if (tls_record_set_handshake_server_hello(record, &recordlen, - conn->protocol, server_random, NULL, 0, - conn->cipher_suite, server_exts, server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send ServerCertificate - tls_trace("send ServerCertificate\n"); - if (tls_record_set_handshake_certificate(record, &recordlen, - conn->server_certs, conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send ServerKeyExchange - tls_trace("send ServerKeyExchange\n"); - sm2_key_generate(&server_ecdhe_key); - if (tls_sign_server_ecdh_params(&conn->sign_key, - client_random, server_random, TLS_curve_sm2p256v1, &server_ecdhe_key.public_key, - sigbuf, &siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (tls_record_set_handshake_server_key_exchange_ecdhe(record, &recordlen, - curve, &server_ecdhe_key.public_key, sigbuf, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // send CertificateRequest - if (client_verify) { - const uint8_t cert_types[] = { TLS_cert_type_ecdsa_sign }; - uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; // TODO: 根据客户端验证CA证书列计算缓冲大小,或直接输出到record缓冲 - size_t ca_names_len = 0; - - tls_trace("send CertificateRequest\n"); - if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), - conn->ca_certs, conn->ca_certs_len) != 1) { - error_print(); - goto end; - } - if (tls_record_set_handshake_certificate_request(record, &recordlen, - cert_types, sizeof(cert_types), - ca_names, ca_names_len) != 1) { - error_print(); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - } - - // send ServerHelloDone - tls_trace("send ServerHelloDone\n"); - tls_record_set_handshake_server_hello_done(record, &recordlen); - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // recv ClientCertificate - if (conn->ca_certs_len) { - tls_trace("recv ClientCertificate\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { // protocol检查应该在trace之后 - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate(record, conn->client_certs, &conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (x509_certs_verify(conn->client_certs, conn->client_certs_len, - conn->ca_certs, conn->ca_certs_len, verify_depth, &verify_result) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - } - - // recv ClientKeyExchange - tls_trace("recv ClientKeyExchange\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); // 应该给tls12一个独立的trace - if (tls_record_get_handshake_client_key_exchange_ecdhe(record, &client_ecdhe_point) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - if (client_verify) - tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); - - // recv CertificateVerify - if (client_verify) { - tls_trace("recv CertificateVerify\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - tls_send_alert(conn, TLS_alert_unexpected_message); - error_print(); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_certificate_verify(record, &sig, &siglen) != 1) { - tls_send_alert(conn, TLS_alert_unexpected_message); - error_print(); - goto end; - } - if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cp, &len) != 1 - || x509_cert_get_subject_public_key(cp, len, &client_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; - } - if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - sm3_update(&sm3_ctx, record + 5, recordlen - 5); - } - - // generate secrets - tls_trace("generate secrets\n"); - sm2_ecdh(&server_ecdhe_key, &client_ecdhe_point, &client_ecdhe_point); - memcpy(pre_master_secret, (uint8_t *)&client_ecdhe_point, 32); // 这里应该修改一下表示方式,比如get_xy() - tls_prf(pre_master_secret, 32, "master secret", - client_random, 32, server_random, 32, - 48, conn->master_secret); - tls_prf(conn->master_secret, 48, "key expansion", - server_random, 32, client_random, 32, - 96, conn->key_block); - sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); - sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); - sm4_set_decrypt_key(&conn->client_write_enc_key, conn->key_block + 64); - sm4_set_encrypt_key(&conn->server_write_enc_key, conn->key_block + 80); - /* - tls_secrets_print(stderr, pre_master_secret, 32, client_random, server_random, - conn->master_secret, conn->key_block, 96, 0, 4); - */ - - // recv [ChangeCipherSpec] - tls_trace("recv [ChangeCipherSpec]\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_change_cipher_spec(record) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - - // recv ClientFinished - tls_trace("recv Finished\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1 - || tls_record_protocol(record) != conn->protocol) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (recordlen > sizeof(finished_record)) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - - // decrypt ClientFinished - tls_trace("decrypt Finished\n"); - if (tls_record_decrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, - conn->client_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); - tls_seq_num_incr(conn->client_seq_num); - if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - if (verify_data_len != sizeof(local_verify_data)) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - - // verify ClientFinished - memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(SM3_CTX)); - sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); - sm3_finish(&tmp_sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "client finished", sm3_hash, 32, NULL, 0, - sizeof(local_verify_data), local_verify_data) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { - error_puts("client_finished.verify_data verification failure"); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - - // send [ChangeCipherSpec] - tls_trace("send [ChangeCipherSpec]\n"); - if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - // send ServerFinished - tls_trace("send Finished\n"); - sm3_finish(&sm3_ctx, sm3_hash); - if (tls_prf(conn->master_secret, 48, "server finished", sm3_hash, 32, NULL, 0, - sizeof(local_verify_data), local_verify_data) != 1 - || tls_record_set_handshake_finished(finished_record, &finished_record_len, - local_verify_data, sizeof(local_verify_data)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); - if (tls_record_encrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, - conn->server_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls_trace("encrypt Finished\n"); - tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 - tls_seq_num_incr(conn->server_seq_num); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - - conn->protocol = conn->protocol; - - fprintf(stderr, "Connection Established!\n\n"); - ret = 1; - -end: - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); - if (client_verify) tls_client_verify_cleanup(&client_verify_ctx); - return ret; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static const int tls12_ciphers[] = { + TLS_cipher_ecdhe_sm4_cbc_sm3, +}; + +static const size_t tls12_ciphers_count = sizeof(tls12_ciphers)/sizeof(tls12_ciphers[0]); + +static const uint8_t tls12_exts[] = { + /* supported_groups */ 0x00,0x0A, 0x00,0x04, 0x00,0x02, 0x00,30,//0x29, // curveSM2 + /* ec_point_formats */ 0x00,0x0B, 0x00,0x02, 0x01, 0x00, // uncompressed + /* signature_algors */ 0x00,0x0D, 0x00,0x04, 0x00,0x02, 0x07,0x07,//0x08, // sm2sig_sm3 +}; + + +int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 + // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) + format |= tls12_ciphers[0] << 8; + return tls_record_print(fp, record, recordlen, format, indent); +} + + +int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, + int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_server_key_exchange; + uint8_t *server_ecdh_params = record + 9; + uint8_t *p = server_ecdh_params + 69; + size_t len = 69; + + if (!record || !recordlen || !tls_named_curve_name(curve) || !point + || !sig || !siglen || siglen > TLS_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + server_ecdh_params[0] = TLS_curve_type_named_curve; + server_ecdh_params[1] = curve >> 8; + server_ecdh_params[2] = curve; + server_ecdh_params[3] = 65; + sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); + tls_uint16_to_bytes(TLS_sig_sm2sig_sm3, &p, &len); + tls_uint16array_to_bytes(sig, siglen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +// 这里返回的应该是一个SM2_POINT吗? +int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record, + int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen) +{ + int type; + const uint8_t *p; + size_t len; + uint8_t curve_type; + uint16_t named_curve; + const uint8_t *octets; + size_t octetslen; + uint16_t sig_alg; + + if (!record || !curve || !point || !sig || !siglen) { + error_print(); + return -1; + } + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_server_key_exchange) { + error_print(); + return -1; + } + if (tls_uint8_from_bytes(&curve_type, &p, &len) != 1 + || tls_uint16_from_bytes(&named_curve, &p, &len) != 1 + || tls_uint8array_from_bytes(&octets, &octetslen, &p, &len) != 1 + || tls_uint16_from_bytes(&sig_alg, &p, &len) != 1 + || tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (curve_type != TLS_curve_type_named_curve) { + error_print(); + return -1; + } + if (named_curve != TLS_curve_sm2p256v1) { + error_print(); + return -1; + } + *curve = named_curve; + if (octetslen != 65 + || sm2_point_from_octets(point, octets, octetslen) != 1) { + error_print(); + return -1; + } + if (sig_alg != TLS_sig_sm2sig_sm3) { + error_print(); + return -1; + } + return 1; +} + +int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen, + const SM2_POINT *point) +{ + int type = TLS_handshake_client_key_exchange; + record[9] = 65; + sm2_point_to_uncompressed_octets(point, record + 9 + 1); + tls_record_set_handshake(record, recordlen, type, NULL, 1 + 65); + return 1; +} + +int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point) +{ + int type; + const uint8_t *p; + size_t len; + const uint8_t *octets; + size_t octetslen; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_client_key_exchange) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(&octets, &octetslen, &p, &len) != 1 + || len > 0) { + error_print(); + return -1; + } + if (octetslen != 65 + || sm2_point_from_octets(point, octets, octetslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +/* + Client Server + + ClientHello --------> + ServerHello + Certificate + ServerKeyExchange + CertificateRequest* + <-------- ServerHelloDone + Certificate* + ClientKeyExchange + CertificateVerify* + [ChangeCipherSpec] + Finished --------> + [ChangeCipherSpec] + <-------- Finished + Application Data <-------> Application Data + + +*/ + +int tls12_do_connect(TLS_CONNECT *conn) +{ + int ret = -1; + uint8_t *record = conn->record; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; + size_t recordlen, finished_record_len; + + uint8_t client_random[32]; + uint8_t server_random[32]; + int protocol; + int cipher_suite; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + + uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t client_exts_len = 0; + const uint8_t *server_exts; + size_t server_exts_len; + + // 扩展的协商结果,-1 表示服务器不支持该扩展(未给出响应) + int ec_point_format = -1; + int supported_group = -1; + int signature_algor = -1; + + + SM2_KEY server_sign_key; + SM2_SIGN_CTX verify_ctx; + SM2_SIGN_CTX sign_ctx; + const uint8_t *sig; + size_t siglen; + uint8_t pre_master_secret[48]; + SM3_CTX sm3_ctx; + SM3_CTX tmp_sm3_ctx; + uint8_t sm3_hash[32]; + const uint8_t *verify_data; + size_t verify_data_len; + uint8_t local_verify_data[12]; + + int handshake_type; + const uint8_t *server_enc_cert; // 这几个值也是不需要的 + size_t server_enc_cert_len; + uint8_t server_enc_cert_lenbuf[3]; + const uint8_t *cp; + uint8_t *p; + size_t len; + + int depth = 5; + int alert = 0; + int verify_result; + + + // 初始化记录缓冲 + tls_record_set_protocol(record, TLS_protocol_tls1); // ClientHello的记录层协议版本是TLSv1.0 + tls_record_set_protocol(finished_record, conn->protocol); + + // 准备Finished Context(和ClientVerify) + sm3_init(&sm3_ctx); + if (conn->client_certs_len) + sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + + + // send ClientHello + tls_random_generate(client_random); + int ec_point_formats[] = { TLS_point_uncompressed }; + size_t ec_point_formats_cnt = 1; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + size_t supported_groups_cnt = 1; + int signature_algors[] = { TLS_sig_sm2sig_sm3 }; + size_t signature_algors_cnt = 1; + + + p = client_exts; + client_exts_len = 0; + + tls_ec_point_formats_ext_to_bytes(ec_point_formats, ec_point_formats_cnt, &p, &client_exts_len); + tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &p, &client_exts_len); + tls_signature_algorithms_ext_to_bytes(signature_algors, signature_algors_cnt, &p, &client_exts_len); + + if (tls_record_set_handshake_client_hello(record, &recordlen, + conn->protocol, client_random, NULL, 0, + tls12_ciphers, tls12_ciphers_count, + client_exts, client_exts_len) != 1) { + error_print(); + goto end; + } + tls_trace("send ClientHello\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHello + tls_trace("recv ServerHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + if (tls_record_get_handshake_server_hello(record, + &protocol, &random, &session_id, &session_id_len, &cipher_suite, + &server_exts, &server_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (protocol != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + // tls12_ciphers 应该改为conn的内部变量 + if (tls_cipher_suite_in_list(cipher_suite, tls12_ciphers, tls12_ciphers_count) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + goto end; + } + if (!server_exts) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (tls_process_server_hello_exts(server_exts, server_exts_len, &ec_point_format, &supported_group, &signature_algor) != 1 + || ec_point_format < 0 + || supported_group < 0 + || signature_algor < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->cipher_suite = cipher_suite; + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerCertificate + tls_trace("recv ServerCertificate\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + + if (tls_record_get_handshake_certificate(record, + conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerCertificate + if (x509_certs_verify(conn->server_certs, conn->server_certs_len, + conn->ca_certs, conn->ca_certs_len, depth, &verify_result) != 1) { + error_print(); + tls_send_alert(conn, alert); + goto end; + } + + // recv ServerKeyExchange + tls_trace("recv ServerKeyExchange\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + + int curve; + SM2_POINT server_ecdhe_public; + if (tls_record_get_handshake_server_key_exchange_ecdhe(record, &curve, &server_ecdhe_public, &sig, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (curve != TLS_curve_sm2p256v1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerKeyExchange + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 + || x509_cert_get_subject_public_key(cp, len, &server_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + if (tls_verify_server_ecdh_params(&server_sign_key, // 这应该是签名公钥 + client_random, server_random, curve, &server_ecdhe_public, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + + // recv CertificateRequest or ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol + || tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (handshake_type == TLS_handshake_certificate_request) { + const uint8_t *cert_types; + size_t cert_types_len; + const uint8_t *ca_names; + size_t ca_names_len; + + // recv CertificateRequest + tls_trace("recv CertificateRequest\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate_request(record, + &cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if(!conn->client_certs_len) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1 + || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unsupported_certificate); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + } else { + // 这个得处理一下 + conn->client_certs_len = 0; + gmssl_secure_clear(&conn->sign_key, sizeof(SM2_KEY)); + } + tls_trace("recv ServerHelloDone\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_server_hello_done(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send ClientCertificate + if (conn->client_certs_len) { + tls_trace("send ClientCertificate\n"); + if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + } + + // generate MASTER_SECRET + tls_trace("generate secrets\n"); + SM2_KEY client_ecdh; + sm2_key_generate(&client_ecdh); + sm2_ecdh(&client_ecdh, &server_ecdhe_public, &server_ecdhe_public); + memcpy(pre_master_secret, &server_ecdhe_public, 32); // 这个做法很不优雅 + // ECDHE和ECC的PMS结构是不一样的吗? + + if (tls_prf(pre_master_secret, 32, "master secret", + client_random, 32, server_random, 32, + 48, conn->master_secret) != 1 + || tls_prf(conn->master_secret, 48, "key expansion", + server_random, 32, client_random, 32, + 96, conn->key_block) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); + sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); + sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); + sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); + /* + tls_secrets_print(stderr, + pre_master_secret, 48, + client_random, server_random, + conn->master_secret, + conn->key_block, 96, + 0, 4); + */ + + // send ClientKeyExchange + tls_trace("send ClientKeyExchange\n"); + if (tls_record_set_handshake_client_key_exchange_ecdhe(record, &recordlen, &client_ecdh.public_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send CertificateVerify + if (conn->client_certs_len) { + tls_trace("send CertificateVerify\n"); + uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; + if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 + || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + } + + // send [ChangeCipherSpec] + tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // send Client Finished + tls_trace("send Finished\n"); + memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); + sm3_finish(&tmp_sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "client finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1 + || tls_record_set_handshake_finished(finished_record, &finished_record_len, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); + + // encrypt Client Finished + tls_trace("encrypt Finished\n"); + if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, + conn->client_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // [ChangeCipherSpec] + tls_trace("recv [ChangeCipherSpec]\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + // Finished + tls_trace("recv Finished\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (recordlen > sizeof(finished_record)) { + error_print(); // 解密可能导致 finished_record 溢出 + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_trace("decrypt Finished\n"); + if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, + conn->server_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_finish(&sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "server finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + fprintf(stderr, "Connection established!\n"); + + + conn->protocol = conn->protocol; + conn->cipher_suite = cipher_suite; + + ret = 1; + +end: + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); + return 1; +} + +int tls12_do_accept(TLS_CONNECT *conn) +{ + int ret = -1; + + int client_verify = 0; + + uint8_t *record = conn->record; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; // 解密可能导致前面的record被覆盖 + size_t recordlen, finished_record_len; + + // 这个ciphers不是应该在CTX中设置的吗 + const int server_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3 }; // 未来应该支持GCM/CBC两个套件 + + // ClientHello, ServerHello + uint8_t client_random[32]; + uint8_t server_random[32]; + int protocol; + const uint8_t *random; + const uint8_t *session_id; // TLCP服务器忽略客户端SessionID,也不主动设置SessionID + size_t session_id_len; + const uint8_t *client_ciphers; + size_t client_ciphers_len; + const uint8_t *client_exts; + size_t client_exts_len; + uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t server_exts_len; + int curve = TLS_curve_sm2p256v1; // 这个是否应该在conn中设置? + + // ServerKeyExchange + SM2_KEY server_ecdhe_key; + SM2_SIGN_CTX sign_ctx; + uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + // ClientCertificate, CertificateVerify + TLS_CLIENT_VERIFY_CTX client_verify_ctx; + SM2_KEY client_sign_key; + const uint8_t *sig; + const int verify_depth = 5; + int verify_result; + + // ClientKeyExchange + SM2_POINT client_ecdhe_point; + uint8_t pre_master_secret[SM2_MAX_PLAINTEXT_SIZE]; // sm2_decrypt 保证输出不会溢出 + size_t pre_master_secret_len; + + // Finished + SM3_CTX sm3_ctx; + SM3_CTX tmp_sm3_ctx; + uint8_t sm3_hash[32]; + uint8_t local_verify_data[12]; + const uint8_t *verify_data; + size_t verify_data_len; + + uint8_t *p; + const uint8_t *cp; + size_t len; + + + // 服务器端如果设置了CA + if (conn->ca_certs_len) + client_verify = 1; + + // 初始化Finished和客户端验证环境 + sm3_init(&sm3_ctx); + if (client_verify) + tls_client_verify_init(&client_verify_ctx); + + + // recv ClientHello + tls_trace("recv ClientHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_protocol(record) != conn->protocol + && tls_record_protocol(record) != TLS_protocol_tls1) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + if (tls_record_get_handshake_client_hello(record, + &protocol, &random, &session_id, &session_id_len, + &client_ciphers, &client_ciphers_len, + &client_exts, &client_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (protocol != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + memcpy(client_random, random, 32); + if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, + server_ciphers, sizeof(server_ciphers)/sizeof(server_ciphers[0]), + &conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + goto end; + } + if (client_exts) { + server_exts_len = 0; + curve = TLS_curve_sm2p256v1; + + tls_process_client_hello_exts(client_exts, client_exts_len, server_exts, &server_exts_len, sizeof(server_exts)); + + + + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + + // send ServerHello + tls_trace("send ServerHello\n"); + tls_random_generate(server_random); + tls_record_set_protocol(record, conn->protocol); + if (tls_record_set_handshake_server_hello(record, &recordlen, + conn->protocol, server_random, NULL, 0, + conn->cipher_suite, server_exts, server_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send ServerCertificate + tls_trace("send ServerCertificate\n"); + if (tls_record_set_handshake_certificate(record, &recordlen, + conn->server_certs, conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send ServerKeyExchange + tls_trace("send ServerKeyExchange\n"); + sm2_key_generate(&server_ecdhe_key); + if (tls_sign_server_ecdh_params(&conn->sign_key, + client_random, server_random, TLS_curve_sm2p256v1, &server_ecdhe_key.public_key, + sigbuf, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (tls_record_set_handshake_server_key_exchange_ecdhe(record, &recordlen, + curve, &server_ecdhe_key.public_key, sigbuf, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // send CertificateRequest + if (client_verify) { + const uint8_t cert_types[] = { TLS_cert_type_ecdsa_sign }; + uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; // TODO: 根据客户端验证CA证书列计算缓冲大小,或直接输出到record缓冲 + size_t ca_names_len = 0; + + tls_trace("send CertificateRequest\n"); + if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), + conn->ca_certs, conn->ca_certs_len) != 1) { + error_print(); + goto end; + } + if (tls_record_set_handshake_certificate_request(record, &recordlen, + cert_types, sizeof(cert_types), + ca_names, ca_names_len) != 1) { + error_print(); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + } + + // send ServerHelloDone + tls_trace("send ServerHelloDone\n"); + tls_record_set_handshake_server_hello_done(record, &recordlen); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // recv ClientCertificate + if (conn->ca_certs_len) { + tls_trace("recv ClientCertificate\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { // protocol检查应该在trace之后 + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate(record, conn->client_certs, &conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (x509_certs_verify(conn->client_certs, conn->client_certs_len, + conn->ca_certs, conn->ca_certs_len, verify_depth, &verify_result) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + } + + // recv ClientKeyExchange + tls_trace("recv ClientKeyExchange\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); // 应该给tls12一个独立的trace + if (tls_record_get_handshake_client_key_exchange_ecdhe(record, &client_ecdhe_point) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (client_verify) + tls_client_verify_update(&client_verify_ctx, record + 5, recordlen - 5); + + // recv CertificateVerify + if (client_verify) { + tls_trace("recv CertificateVerify\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + tls_send_alert(conn, TLS_alert_unexpected_message); + error_print(); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate_verify(record, &sig, &siglen) != 1) { + tls_send_alert(conn, TLS_alert_unexpected_message); + error_print(); + goto end; + } + if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cp, &len) != 1 + || x509_cert_get_subject_public_key(cp, len, &client_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + if (tls_client_verify_finish(&client_verify_ctx, sig, siglen, &client_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + } + + // generate secrets + tls_trace("generate secrets\n"); + sm2_ecdh(&server_ecdhe_key, &client_ecdhe_point, &client_ecdhe_point); + memcpy(pre_master_secret, (uint8_t *)&client_ecdhe_point, 32); // 这里应该修改一下表示方式,比如get_xy() + tls_prf(pre_master_secret, 32, "master secret", + client_random, 32, server_random, 32, + 48, conn->master_secret); + tls_prf(conn->master_secret, 48, "key expansion", + server_random, 32, client_random, 32, + 96, conn->key_block); + sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); + sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); + sm4_set_decrypt_key(&conn->client_write_enc_key, conn->key_block + 64); + sm4_set_encrypt_key(&conn->server_write_enc_key, conn->key_block + 80); + /* + tls_secrets_print(stderr, pre_master_secret, 32, client_random, server_random, + conn->master_secret, conn->key_block, 96, 0, 4); + */ + + // recv [ChangeCipherSpec] + tls_trace("recv [ChangeCipherSpec]\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + // recv ClientFinished + tls_trace("recv Finished\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (recordlen > sizeof(finished_record)) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + + // decrypt ClientFinished + tls_trace("decrypt Finished\n"); + if (tls_record_decrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, + conn->client_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + + // verify ClientFinished + memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(SM3_CTX)); + sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); + sm3_finish(&tmp_sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "client finished", sm3_hash, 32, NULL, 0, + sizeof(local_verify_data), local_verify_data) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_puts("client_finished.verify_data verification failure"); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + + // send [ChangeCipherSpec] + tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // send ServerFinished + tls_trace("send Finished\n"); + sm3_finish(&sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "server finished", sm3_hash, 32, NULL, 0, + sizeof(local_verify_data), local_verify_data) != 1 + || tls_record_set_handshake_finished(finished_record, &finished_record_len, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + if (tls_record_encrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, + conn->server_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls_trace("encrypt Finished\n"); + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_seq_num_incr(conn->server_seq_num); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + conn->protocol = conn->protocol; + + fprintf(stderr, "Connection Established!\n\n"); + ret = 1; + +end: + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); + if (client_verify) tls_client_verify_cleanup(&client_verify_ctx); + return ret; +} diff --git a/src/tls13.c b/src/tls13.c index 8daabf07..5969ba7a 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,2332 +7,2333 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; -static size_t tls13_ciphers_count = sizeof(tls13_ciphers)/sizeof(int); - -/* -int tls13_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) -{ - // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 - // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) - format |= tls13_ciphers[0] << 8; - return tls_record_print(fp, record, recordlen, format, indent); -} -*/ - -static int tls13_client_hello_exts[] = { - TLS_extension_supported_versions, - TLS_extension_padding, -}; - - -/* -struct { - opaque content[TLSPlaintext.length]; - ContentType type; - uint8 zeros[length_of_padding]; -} TLSInnerPlaintext; - -struct { - ContentType opaque_type = application_data; // 23 - ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2 - uint16 length; - opaque encrypted_record[TLSCiphertext.length]; -} TLSCiphertext; -*/ -int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], int record_type, - const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content - uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record -{ - uint8_t nonce[12]; - uint8_t aad[5]; - uint8_t *gmac; - uint8_t *mbuf = NULL; // FIXME: update gcm_encrypt API - size_t mlen, clen; - - if (!(mbuf = malloc(inlen + 256))) { - error_print(); - return -1; - } - - // nonce = (zeros|seq_num) xor (iv) - nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; - memcpy(nonce + 4, seq_num, 8); - gmssl_memxor(nonce, nonce, iv, 12); - - // TLSInnerPlaintext - memcpy(mbuf, in, inlen); - mbuf[inlen] = record_type; - memset(mbuf + inlen + 1, 0, padding_len); - mlen = inlen + 1 + padding_len; - clen = mlen + GHASH_SIZE; - - // aad = TLSCiphertext header - aad[0] = TLS_record_application_data; - aad[1] = 0x03; //TLS_protocol_tls12_major; - aad[2] = 0x03; //TLS_protocol_tls12_minor; - aad[3] = clen >> 8; - aad[4] = clen; - - gmac = out + mlen; - if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) { - error_print(); - free(mbuf); - return -1; - } - *outlen = clen; - free(mbuf); - - return 1; -} - -int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - int *record_type, uint8_t *out, size_t *outlen) -{ - uint8_t nonce[12]; - uint8_t aad[5]; - size_t mlen; - const uint8_t *gmac; - size_t i; - - // nonce = (zeros|seq_num) xor (iv) - nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; - memcpy(nonce + 4, seq_num, 8); - gmssl_memxor(nonce, nonce, iv, 12); - - // aad = TLSCiphertext header - aad[0] = TLS_record_application_data; - aad[1] = 0x03; //TLS_protocol_tls12_major; - aad[2] = 0x03; //TLS_protocol_tls12_minor; - aad[3] = inlen >> 8; - aad[4] = inlen; - - if (inlen < GHASH_SIZE) { - error_print(); - return -1; - } - mlen = inlen - GHASH_SIZE; - gmac = in + mlen; - - if (gcm_decrypt(key, nonce, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { - error_print(); - return -1; - } - // remove padding, get record_type - *record_type = 0; - while (mlen--) { - if (out[mlen] != 0) { - *record_type = out[mlen]; - break; - } - } - *outlen = mlen; - if (!tls_record_type_name(*record_type)) { - error_print(); - return -1; - } - return 1; -} - -// 这个函数是不对的,在我们的一些情况下,加密的时候并不会组成完整的数据 -int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, - uint8_t *enced_record, size_t *enced_recordlen) -{ - // 被加密的是握手消息或者是应用层数据 - - if (tls13_gcm_encrypt(key, iv, - seq_num, record[0], record + 5, recordlen - 5, padding_len, - enced_record + 5, enced_recordlen) != 1) { - error_print(); - return -1; - } - - enced_record[0] = TLS_record_application_data; // 显然这个不太对啊 - enced_record[1] = 0x03; //TLS_protocol_tls12_major; - enced_record[2] = 0x03; //TLS_protocol_tls12_minor; - enced_record[3] = (*enced_recordlen) >> 8; - enced_record[4] = (*enced_recordlen); - - (*enced_recordlen) += 5; - return 1; -} - -int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen, - uint8_t *record, size_t *recordlen) -{ - int record_type; - - if (tls13_gcm_decrypt(key, iv, - seq_num, enced_record + 5, enced_recordlen - 5, - &record_type, record + 5, recordlen) != 1) { - error_print(); - return -1; - } - record[0] = record_type; - record[1] = 0x03; //TLS_protocol_tls12_major; - record[2] = 0x03; //TLS_protocol_tls12_minor; - record[3] = (*recordlen) >> 8; - record[4] = (*recordlen); - - (*recordlen) += 5; - return 1; -} - -int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen) -{ - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - uint8_t *record = conn->record; - size_t recordlen; - size_t padding_len = 0; //FIXME: 在conn中设置是否加随机填充,及设置该值 - - tls_trace("send {ApplicationData}\n"); - - if (conn->is_client) { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } else { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } - - if (tls13_gcm_encrypt(key, iv, - seq_num, TLS_record_application_data, data, datalen, padding_len, - record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - - record[0] = TLS_record_application_data; - record[1] = TLS_protocol_tls12 >> 8; - record[2] = TLS_protocol_tls12 & 0xff; - record[3] = recordlen >> 8; - record[4] = recordlen; - recordlen += 5; - - tls_record_send(record, recordlen, conn->sock); - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - - tls_seq_num_incr(seq_num); - - *sentlen = datalen; - - return 1; -} - -/* -int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) -{ - int record_type; - uint8_t *record = conn->record; - size_t recordlen; - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - - - tls_trace("recv {ApplicationData}\n"); - - if (conn->is_client) { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } else { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } - - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - if (record[0] != TLS_record_application_data) { - error_print(); - return -1; - } - - if (tls13_gcm_decrypt(key, iv, - seq_num, record + 5, recordlen - 5, - &record_type, data, datalen) != 1) { - error_print(); - return -1; - } - - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - tls_seq_num_incr(seq_num); - - if (record_type != TLS_record_application_data) { - error_print(); - return -1; - } - return 1; -} -*/ - -int tls13_do_recv(TLS_CONNECT *conn) -{ - int ret; - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - uint8_t *record = conn->record; - size_t recordlen; - int record_type; - - if (conn->is_client) { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } else { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } - - tls_trace("recv ApplicationData\n"); - if ((ret = tls_record_recv(record, &recordlen, conn->sock)) != 1) { - if (ret < 0) error_print(); - return ret; - } - tls_record_trace(stderr, record, recordlen, 0, 0); - // TODO: 是否需要检查record_type? record[0] != TLS_record_application_data - - if (tls13_gcm_decrypt(key, iv, - seq_num, record + 5, recordlen - 5, - &record_type, conn->databuf, &conn->datalen) != 1) { - error_print(); - return -1; - } - conn->data = conn->databuf; - tls_seq_num_incr(seq_num); - - tls_record_set_data(record, conn->data, conn->datalen); - tls_trace("decrypt ApplicationData\n"); - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - - - if (record_type != TLS_record_application_data) { - error_print(); - return -1; - } - return 1; -} - -int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen) -{ - if (!conn || !out || !outlen || !recvlen) { - error_print(); - return -1; - } - if (conn->datalen == 0) { - int ret; - if ((ret = tls13_do_recv(conn)) != 1) { - if (ret) error_print(); - return ret; - } - } - *recvlen = outlen <= conn->datalen ? outlen : conn->datalen; - memcpy(out, conn->data, *recvlen); - conn->data += *recvlen; - conn->datalen -= *recvlen; - return 1; -} - - - -/* -HKDF-Expand-Label(Secret, Label, Context, Length) = - HKDF-Expand(Secret, HkdfLabel, Length); - - HkdfLabel = struct { - uint16 length = Length; - opaque label<7..255> = "tls13 " + Label; - opaque context<0..255> = Context; } - -Derive-Secret(Secret, Label, Messages) = - HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length) - -*/ - -int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]) -{ - size_t dgstlen; - - if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1 - || dgstlen != 32) { - error_print(); - return -1; - } - return 1; -} - -int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], - const char *label, const uint8_t *context, size_t context_len, - size_t outlen, uint8_t *out) -{ - uint8_t label_len; - uint8_t hkdf_label[2 + 256 + 256]; - uint8_t *p = hkdf_label; - size_t hkdf_label_len = 0; - - label_len = strlen("tls13 ") + strlen(label); - tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len); - tls_uint8_to_bytes(label_len, &p, &hkdf_label_len); - tls_array_to_bytes((uint8_t *)"tls13 ", strlen("tls13 "), &p, &hkdf_label_len); - tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len); - tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len); - - hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out); - - return 1; -} - -int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]) -{ - DIGEST_CTX ctx = *dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - - if (digest_finish(&ctx, dgst, &dgstlen) != 1 - || tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) { - error_print(); - return -1; - } - return 1; -} - -static const uint8_t TLS13_client_context_str_and_zero[] = "TLS 1.3, client CertificateVerify"; -static const uint8_t TLS13_server_context_str_and_zero[] = "TLS 1.3, server CertificateVerify"; -static size_t TLS13_client_context_str_and_zero_size = sizeof(TLS13_client_context_str_and_zero); -static size_t TLS13_server_context_str_and_zero_size = sizeof(TLS13_server_context_str_and_zero); - -int tls13_sign_certificate_verify(int tls_mode, - const SM2_KEY *key, const char *signer_id, size_t signer_id_len, - const DIGEST_CTX *tbs_dgst_ctx, - uint8_t *sig, size_t *siglen) -{ - SM2_SIGN_CTX sign_ctx; - uint8_t prefix[64]; - const uint8_t *context_str_and_zero; - size_t context_str_and_zero_len; - DIGEST_CTX dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - - memset(prefix, 0x20, 64); - - switch (tls_mode) { - case TLS_client_mode: - context_str_and_zero = TLS13_client_context_str_and_zero; - context_str_and_zero_len = TLS13_client_context_str_and_zero_size; - break; - case TLS_server_mode: - context_str_and_zero = TLS13_server_context_str_and_zero; - context_str_and_zero_len = TLS13_server_context_str_and_zero_size; - break; - default: - error_print(); - return -1; - } - - dgst_ctx = *tbs_dgst_ctx; - digest_finish(&dgst_ctx, dgst, &dgstlen); - - sm2_sign_init(&sign_ctx, key, signer_id, signer_id_len); - sm2_sign_update(&sign_ctx, prefix, 64); - sm2_sign_update(&sign_ctx, context_str_and_zero, context_str_and_zero_len); - sm2_sign_update(&sign_ctx, dgst, dgstlen); - sm2_sign_finish(&sign_ctx, sig, siglen); - - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - return 1; -} - -int tls13_verify_certificate_verify(int tls_mode, - const SM2_KEY *public_key, const char *signer_id, size_t signer_id_len, - const DIGEST_CTX *tbs_dgst_ctx, const uint8_t *sig, size_t siglen) -{ - int ret; - SM2_SIGN_CTX verify_ctx; - uint8_t prefix[64]; - const uint8_t *context_str_and_zero; - size_t context_str_and_zero_len; - DIGEST_CTX dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - - memset(prefix, 0x20, 64); - - switch (tls_mode) { - case TLS_client_mode: - context_str_and_zero = TLS13_client_context_str_and_zero; - context_str_and_zero_len = TLS13_client_context_str_and_zero_size; - break; - case TLS_server_mode: - context_str_and_zero = TLS13_server_context_str_and_zero; - context_str_and_zero_len = TLS13_server_context_str_and_zero_size; - break; - default: - error_print(); - return -1; - } - - dgst_ctx = *tbs_dgst_ctx; - digest_finish(&dgst_ctx, dgst, &dgstlen); - - sm2_verify_init(&verify_ctx, public_key, signer_id, signer_id_len); - sm2_verify_update(&verify_ctx, prefix, 64); - sm2_verify_update(&verify_ctx, context_str_and_zero, context_str_and_zero_len); - sm2_verify_update(&verify_ctx, dgst, dgstlen); - - if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { - error_print(); - return -1; - } - if (ret != 1) { - error_print(); - } - return ret; -} - -/* - verify_data in Finished - - finished_key = - HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) - Structure of this message: - struct { - opaque verify_data[Hash.length]; - } Finished; - The verify_data value is computed as follows: - verify_data = - HMAC(finished_key, - Transcript-Hash(Handshake Context, - Certificate*, CertificateVerify*)) -*/ - -int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, - const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len) -{ - DIGEST_CTX temp_dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - uint8_t finished_key[64]; - size_t finished_key_len; - - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - finished_key_len = dgstlen; - - tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret, - "finished", NULL, 0, finished_key_len, finished_key); - - hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len); - return 1; -} - -/* -Handshakes - -*/ - -int tls13_client_hello_exts_set(uint8_t *exts, size_t *extslen, size_t maxlen, - const SM2_POINT *client_ecdhe_public) -{ - int protocols[] = { TLS_protocol_tls13 }; - int supported_groups[] = { TLS_curve_sm2p256v1 }; - int sig_algs[] = { TLS_sig_sm2sig_sm3 }; - size_t protocols_cnt = sizeof(protocols)/sizeof(int); - size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(int); - size_t sig_algs_cnt = sizeof(sig_algs)/sizeof(int); - - - if (!exts || !extslen || !client_ecdhe_public) { - error_print(); - return -1; - } - - *extslen = 0; - if (tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, NULL, extslen) != 1 - || tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, NULL, extslen) != 1 - || tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, NULL, extslen) != 1 - || tls13_client_key_share_ext_to_bytes(client_ecdhe_public, NULL, extslen) != 1) { - error_print(); - return -1; - } - if (*extslen > maxlen) { - error_print(); - return -1; - } - *extslen = 0; - tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, &exts, extslen); - tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &exts, extslen); - tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, &exts, extslen); - tls13_client_key_share_ext_to_bytes(client_ecdhe_public, &exts, extslen); - return 1; -} - -int tls13_process_client_hello_exts(const uint8_t *exts, size_t extslen, - const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, - uint8_t *server_exts, size_t *server_exts_len, size_t server_exts_maxlen) -{ - size_t len = 0; - *server_exts_len = 0; - - while (extslen) { - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 - || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - - switch (ext_type) { - /* - // tls13_process_client_hello_exts 的接口需要处理,部分输出要输出到server_exts中 - case TLS_extension_supported_groups: // 这个应该放在EE里面 - if (tls_process_client_supported_groups(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls_process_client_supported_groups(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - case TLS_extension_signature_algorithms: // client单方面通知就可以了,服务器不需要响应 - if (tls_process_client_signature_algorithms(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls_process_client_signature_algorithms(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - */ - case TLS_extension_supported_versions: - if (tls13_process_client_supported_versions(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls13_process_client_supported_versions(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - case TLS_extension_key_share: - if (tls13_process_client_key_share(ext_data, ext_datalen, server_ecdhe_key, client_ecdhe_public, &server_exts, server_exts_len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - break; - - default: - ; // server ignore unkonwn extensions - } - } - - return 1; -} - -int tls_client_key_shares_from_bytes(SM2_POINT *sm2_point, const uint8_t **in, size_t *inlen) -{ - const uint8_t *key_shares; - size_t key_shares_len; - - tls_uint16array_from_bytes(&key_shares, &key_shares_len, in, inlen); - - while (key_shares_len) { - uint16_t group; - const uint8_t *key_exch; - size_t key_exch_len; - - tls_uint16_from_bytes(&group, &key_shares, &key_shares_len); - tls_uint16array_from_bytes(&key_exch, &key_exch_len, &key_shares, &key_shares_len); - - if (key_exch_len != 65) { - error_print(); - return -1; - } - - switch (group) { - case TLS_curve_sm2p256v1: - sm2_point_from_octets(sm2_point, key_exch, key_exch_len); - break; - default: - error_print(); - return -1; - } - } - - return 1; -} - -// 这个函数不是太正确,应该也是一个process -int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *sm2_point) -{ - uint16_t version; - while (extslen) { - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - const uint8_t *p; - size_t len; - - tls_uint16_from_bytes(&ext_type, &exts, &extslen); - tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen); - - switch (ext_type) { - case TLS_extension_supported_versions: - if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - if (version != TLS_protocol_tls13) { - error_print(); - return -1; - } - break; - case TLS_extension_key_share: - if (tls13_process_server_key_share(ext_data, ext_datalen, sm2_point) != 1) { - error_print(); - return -1; - } - break; - //default: - // FIXME: 还有几个扩展没有处理! - //error_print(); - //return -1; - } - } - return 1; -} - - -/* -struct { - Extension extensions<0..2^16-1>; -} EncryptedExtensions; -*/ -static int tls13_encrypted_exts[] = { - TLS_extension_server_name, - TLS_extension_max_fragment_length, - TLS_extension_supported_groups, - TLS_extension_use_srtp, - TLS_extension_heartbeat, - TLS_extension_application_layer_protocol_negotiation, - TLS_extension_client_certificate_type, - TLS_extension_server_certificate_type, - TLS_extension_early_data, -}; - -int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen) -{ - const uint8_t *exts; - size_t extslen; - - format_print(fp, fmt, ind, "EncryptedExtensions\n"); - ind += 4; - - if (tls_uint16array_from_bytes(&exts, &extslen, &data, &datalen) != 1) { - error_print(); - return -1; - } - if (exts) { - tls13_extensions_print(fp, fmt, ind, TLS_handshake_encrypted_extensions, exts, extslen); - } - if (tls_length_is_zero(datalen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen) -{ - int type = TLS_handshake_encrypted_extensions; - uint8_t *p = record + 5 + 4; - size_t len = 0; - uint8_t exts[128]; - size_t extslen = 0; - uint8_t *pexts = exts; - const int supported_groups[] = { TLS_curve_sm2p256v1 }; - - tls_supported_groups_ext_to_bytes(supported_groups, sizeof(supported_groups)/sizeof(int), &pexts, &extslen); - - tls_uint16array_to_bytes(exts, extslen, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - - return 1; -} - -int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) -{ - int type; - const uint8_t *p; - size_t len; - const uint8_t *exts_data; - size_t exts_datalen; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(&exts_data, &exts_datalen, &p, &len) != 1) { - error_print(); - return -1; - } - // 当前实现不需要在EncryptedExtensions提供扩展 - if (exts_datalen) { - // FIXME: 实际上supported_groups是放在这里的,应该加以处理 - //error_print(); - //return -1; - } - return 1; -} - - -/* - ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 - ServerHello.Extensions.supported_groups 决定了服务器的公钥类型, - 因此也决定了服务器的签名算法 - ServerHello.cipher_suite决定了哈希函数 -*/ - -/* -struct { - SignatureScheme algorithm; - opaque signature<0..2^16-1>; -} CertificateVerify; - -注意:TLS 1.2中只有RAW signature, 也就是没有经过uint16array封装的,这其实不太符合TLS的设计逻辑 -*/ -int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, - int sign_algor, const uint8_t *sig, size_t siglen) -{ - int type = TLS_handshake_certificate_verify; - uint8_t *p = record + 5 + 4; - size_t len = 0; - - tls_uint16_to_bytes((uint16_t)sign_algor, &p, &len); - tls_uint16array_to_bytes(sig, siglen, &p, &len); - - if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_record_get_handshake_certificate_verify(const uint8_t *record, - int *sign_algor, const uint8_t **sig, size_t *siglen) -{ - int type; - const uint8_t *p; - size_t len ; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_certificate_verify) { - error_print(); - return -1; - } - - *sign_algor = 0; - tls_uint16_from_bytes((uint16_t *)sign_algor, &p, &len); - tls_uint16array_from_bytes(sig, siglen, &p, &len); - - return 1; -} - - -/* -struct { - opaque certificate_request_context<0..2^8-1>; - Extension extensions<2..2^16-1>; -} CertificateRequest; - -certificate_request_context 用于 Post-handshake Authentication,否则应该长度为0 - -*/ -static int tls13_certificate_request_exts[] = { - TLS_extension_signature_algorithms, // 必须包含 - TLS_extension_status_request, - TLS_extension_signed_certificate_timestamp, - TLS_extension_certificate_authorities, - TLS_extension_oid_filters, - TLS_extension_signature_algorithms_cert, -}; - - - - -/* -struct { - opaque certificate_request_context<0..2^8-1>; - Extension extensions<2..2^16-1>; -} CertificateRequest; - -extensiosns: - Extension signature_algorithms MUST be specified -*/ -int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, - const uint8_t *request_context, size_t request_context_len, - const uint8_t *exts, size_t extslen) -{ - int type = TLS_handshake_certificate_request; - uint8_t *data; - size_t datalen = 0; - - if (!record || !recordlen) { - error_print(); - return -1; - } - data = tls_handshake_data(tls_record_data(record)); - tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); - tls_uint16array_to_bytes(exts, extslen, &data, &datalen); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); - return 1; -} - -int tls13_record_set_handshake_certificate_request_default(uint8_t *record, size_t *recordlen) -{ - int sig_algs[] = { TLS_sig_sm2sig_sm3 }; - uint8_t exts[256]; - uint8_t *p = exts; - size_t extslen = 0; - - tls_signature_algorithms_ext_to_bytes(sig_algs, sizeof(sig_algs)/sizeof(int), &p, &extslen); - tls13_record_set_handshake_certificate_request(record, recordlen, NULL, 0, exts, extslen); - return 1; -} - -int tls13_record_get_handshake_certificate_request(const uint8_t *record, - const uint8_t **requst_context, size_t *request_context_len, - const uint8_t **exts, size_t *exts_len) -{ - int type; - const uint8_t *p; - size_t len; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate_request) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(requst_context, request_context_len, &p, &len) != 1 - || tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -static const int tls13_handshake_certificate_exts[] = { - TLS_extension_status_request, - TLS_extension_signed_certificate_timestamp, -}; -/* -enum { X509(0), RawPublicKey(2), (255) } CertificateType; - -struct { - select (certificate_type) { - case RawPublicKey: opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; -- TLS 1.3可以只传公钥不传证书 - case X509: opaque cert_data<1..2^24-1>; - }; - Extension extensions<0..2^16-1>; -} CertificateEntry; - -struct { - opaque certificate_request_context<0..2^8-1>; -- 用于客户端证书,服务器证书该域长度为0 - CertificateEntry certificate_list<0..2^24-1>; -} Certificate; - -TLS 1.3 Certificate: - - * TLS 1.3 支持发送公钥,可以去掉嵌入式环境的证书传输开销 - * TLS 1.3 的证书链中增加了 certificate_request_context - 用于客户端发送证书时标识context,服务器端的证书中该域的长度为0 - * 证书链中每个证书都有一个独立的扩展域,TLS 1.2 中的证书相关扩展移至此处 - -Extensions in client Certificate MUST from ClientHello -Extensions in server Certificate MUST from CertificateRequest -Entensions apply to entire chain SHOULD be in the first CertificateEntry - -目前CertificateEntry中的扩展主要用于服务器证书的验证 -客户端在ClientHello中可以包含status_request 和 signed_certificate_timestamp -让服务器提供 OCSP 的状态证明和时间戳信息 -服务器则在证书消息的每个证书否面附带这两个扩展,提供相关信息 - -在 RFC 8446 (TLS 1.3) 中还没有涉及客户端证书的具体扩展 -但是客户端在提供客户端证书时,应该响应服务器CertificateRequest消息中的扩展 - -目前GmSSLv3还不支持这两个证书扩展的生成,但是提供解析和显示 - -Valid extensions for server certificates: - TLS_extension_status_request (5) - TLS_extension_signed_certificate_timestamp (18) -*/ - -int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "Certificate\n"); - ind += 4; - - if (tls_uint8array_from_bytes(&p, &len, &cert, &certlen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "certificate_request_context", p, len); - - format_print(fp, fmt, ind, "certificate_list\n"); - ind += 4; - if (tls_uint24array_from_bytes(&p, &len, &cert, &certlen) != 1) { - error_print(); - return -1; - } - while (len) { - const uint8_t *cert_data; - size_t cert_data_len; - const uint8_t *exts; - size_t extslen; - - if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &p, &len) != 1 - || tls_uint16array_from_bytes(&exts, &extslen, &p, &len) != 1) { - error_print(); - return -1; - } - if (!cert_data) { - error_print(); - return -1; - } - - format_print(fp, fmt, ind, "CertificateEntry\n"); - x509_cert_print(fp, fmt, ind + 4, "Certificate", cert_data, cert_data_len); - x509_cert_to_pem(cert_data, cert_data_len, fp); - tls13_extensions_print(fp, fmt, ind + 4, TLS_handshake_certificate, exts, extslen); - } - return 1; -} - -int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *certreq, size_t certreqlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "CertificateRequest\n"); - ind += 4; - - if (tls_uint8array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "certificate_request_context", p, len); - - if (tls_uint16array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "extensions", p, len); - - if (tls_length_is_zero(certreqlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) -{ - uint16_t sig_alg; - const uint8_t *sig; - size_t siglen; - - format_print(fp, fmt, ind, "CertificateVerify\n"); - ind += 4; - - if (tls_uint16_from_bytes(&sig_alg, &d, &dlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "algorithm: %s (0x%04x)\n", tls_signature_scheme_name(sig_alg), sig_alg); - if (tls_uint16array_from_bytes(&sig, &siglen, &d, &dlen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, fmt, ind, "signature", sig, siglen); - if (tls_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_certificate_list_to_bytes(const uint8_t *certs, size_t certslen, - uint8_t **out, size_t *outlen) -{ - uint8_t *p = NULL; - size_t cert_list_len = 0; - - if (out && *out) { - p = (*out) + tls_uint24_size(); - } - while (certslen) { - const uint8_t *cert; - size_t certlen; - const uint8_t *entry_exts = NULL; - size_t entry_exts_len = 0; - - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - tls_uint24array_to_bytes(cert, certlen, &p, &cert_list_len); - tls_uint16array_to_bytes(entry_exts, entry_exts_len, &p, &cert_list_len); - - } - tls_uint24array_to_bytes(NULL, cert_list_len, out, outlen); - return 1; -} - -int tls13_process_certificate_list(const uint8_t *cert_list, size_t cert_list_len, - uint8_t *certs, size_t *certs_len) -{ - *certs_len = 0; - - while (cert_list_len) { - const uint8_t *cert_data; - size_t cert_data_len; - const uint8_t *exts; - size_t exts_len; - const uint8_t *cert; - size_t cert_len; - - if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &cert_list, &cert_list_len) != 1 - || tls_uint16array_from_bytes(&exts, &exts_len, &cert_list, &cert_list_len) != 1) { - error_print(); - return -1; - } - if (x509_cert_from_der(&cert, &cert_len, &cert_data, &cert_data_len) != 1 - || asn1_length_is_zero(cert_data_len) != 1 - || x509_cert_to_der(cert, cert_len, &certs, certs_len) != 1) { - error_print(); - return -1; - } - - while (exts_len) { - int ext_type; - const uint8_t *ext_data; - size_t ext_data_len; - - if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_data_len, &exts, &exts_len) != 1) { - error_print(); - return -1; - } - switch (ext_type) { - case TLS_extension_status_request: - case TLS_extension_signed_certificate_timestamp: - error_print(); - return -1; - default: - error_print(); - return -1; - } - } - } - return 1; -} - -int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, - const uint8_t *request_context, size_t request_context_len, - const uint8_t *certs, size_t certslen) -{ - int type = TLS_handshake_certificate; - uint8_t *data; - size_t datalen; - - if (!record || !recordlen || !certs || !certslen) { - error_print(); - return -1; - } - - datalen = 0; - tls_uint8array_to_bytes(request_context, request_context_len, NULL, &datalen); - tls13_certificate_list_to_bytes(certs, certslen, NULL, &datalen); - if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { - error_print(); - return -1; - } - - data = tls_handshake_data(tls_record_data(record)); - datalen = 0; - tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); - tls13_certificate_list_to_bytes(certs, certslen, &data, &datalen); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); - - return 1; -} - -int tls13_record_get_handshake_certificate(const uint8_t *record, - const uint8_t **cert_request_context, size_t *cert_request_context_len, - const uint8_t **cert_list, size_t *cert_list_len) -{ - int type; - const uint8_t *p; - size_t len; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(cert_request_context, cert_request_context_len, &p, &len) != 1 - || tls_uint24array_from_bytes(cert_list, cert_list_len, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (*cert_list == NULL) { - error_print(); - return -1; - } - return 1; -} - - - -/* -finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) - -struct { - opaque verify_data[Hash.length]; -} Finished; - -verify_data = HMAC(finished_key, Hash(Handshake Context, Certificate*, CertificateVerify*)) -Hash = SM3, SHA256 or SHA384 -*/ - - -int tls13_record_set_handshake_finished(uint8_t *record, size_t *recordlen, - const uint8_t *verify_data, size_t verify_data_len) -{ - int type = TLS_handshake_finished; - if (!record || !recordlen || !verify_data) { - error_print(); - return -1; - } - tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); - return 1; -} - -int tls13_record_get_handshake_finished(const uint8_t *record, - const uint8_t **verify_data, size_t *verify_data_len) -{ - int type; - - if (tls_record_get_handshake(record, &type, verify_data, verify_data_len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_finished) { - error_print(); - return -1; - } - if (*verify_data_len != SM3_DIGEST_SIZE - && *verify_data_len != SHA384_DIGEST_SIZE) { - error_print(); - return -1; - } - return 1; -} - - -int tls13_padding_len_rand(size_t *padding_len) -{ - uint8_t val; - rand_bytes(&val, 1); - *padding_len = val % 128; - return 1; -} - - - -int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_CIPHER **cipher) -{ - switch (cipher_suite) { - case TLS_cipher_sm4_gcm_sm3: - *digest = DIGEST_sm3(); - *cipher = BLOCK_CIPHER_sm4(); - break; - case TLS_cipher_aes_128_gcm_sha256: - *digest = DIGEST_sha256(); - *cipher = BLOCK_CIPHER_aes128(); - break; - default: - error_print(); - return -1; - } - return 1; -} - - - -/* - Client Server - -Key ^ ClientHello -Exch | + key_share* - | + signature_algorithms* - | + psk_key_exchange_modes* - v + pre_shared_key* --------> - ServerHello ^ Key - + key_share* | Exch - + pre_shared_key* v - - - | ecdhe => handshake_secret | - | handshake_secret => master_secret | - | handshake_secret, client_hello, server_hello | - | => client_handshake_traffic_secret | - | => server_handshake_traffic_secret | - - - {EncryptedExtensions} ^ Server - {CertificateRequest*} v Params - {Certificate} ^ - {CertificateVerify} | Auth - {Finished} v - - + master_secret, ClientHello .. server Finished - => server_application_traffic_secret_0 - - <-------- [Application Data*] - - ^ {Certificate*} -Auth | {CertificateVerify*} - v {Finished} --------> - - - + master_secret, ClientHello .. server Finished - => client_application_traffic_secret_0 - - [Application Data] <-------> [Application Data] - - -TLS 1.3的区别: - - * 首先在最开始的握手阶段就协商好了密钥,因此握手之后传输的就是加密消息了 - * 因此在第二阶段,双方不再发送ServerKeyExchange和ClientKeyExchange - * 服务器先发送CertificateRequest,再发送Certificate - * 没有ChangeCipherSpec了 - * 在握手阶段就需要加密,并且Certificate也在其中,因此需要格外的大的密文数据缓冲 - - 0 - | - v -[1] PSK -> HKDF-Extract = Early Secret - | -[2] +-----> Derive-Secret(., "ext binder" | "res binder", "") - | = binder_key - | -[3] +-----> Derive-Secret(., "c e traffic", ClientHello) - | = client_early_traffic_secret - | -[4] +-----> Derive-Secret(., "e exp master", ClientHello) - | = early_exporter_master_secret - v -[5] Derive-Secret(., "derived", "") - | - v -[6] (EC)DHE -> HKDF-Extract = Handshake Secret - | -[7] +-----> Derive-Secret(., "c hs traffic", - | ClientHello...ServerHello) - | = client_handshake_traffic_secret - | -[8] +-----> Derive-Secret(., "s hs traffic", - | ClientHello...ServerHello) - | = server_handshake_traffic_secret - v -[9] Derive-Secret(., "derived", "") - | - v -[10] 0 -> HKDF-Extract = Master Secret - | -[11] +-----> Derive-Secret(., "c ap traffic", - | ClientHello...server Finished) - | = client_application_traffic_secret_0 - | -[12] +-----> Derive-Secret(., "s ap traffic", - | ClientHello...server Finished) - | = server_application_traffic_secret_0 - | -[13] +-----> Derive-Secret(., "exp master", - | ClientHello...server Finished) - | = exporter_master_secret - | -[14] +-----> Derive-Secret(., "res master", - ClientHello...client Finished) - = resumption_master_secret - -*/ - - - -int tls13_do_connect(TLS_CONNECT *conn) -{ - uint8_t *record = conn->record; - uint8_t *enced_record = conn->enced_record; - size_t recordlen; - - size_t enced_recordlen; - - - int type; - const uint8_t *data; - size_t datalen; - - int protocol; - uint8_t client_random[32]; - uint8_t server_random[32]; - int cipher_suite; - const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - - int protocols[] = { TLS_protocol_tls13 }; - int supported_groups[] = { TLS_curve_sm2p256v1 }; - int sign_algors[] = { TLS_sig_sm2sig_sm3 }; - - uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t client_exts_len; - const uint8_t *server_exts; - size_t server_exts_len; - - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen = sizeof(sig); - uint8_t verify_data[32]; - size_t verify_data_len; - - int server_sign_algor; - const uint8_t *server_sig; - size_t server_siglen; - const uint8_t *server_verify_data; - size_t server_verify_data_len; - - SM2_KEY client_ecdhe; - SM2_POINT server_ecdhe_public; - SM2_KEY server_sign_key; - - const DIGEST *digest = DIGEST_sm3(); - DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的 - DIGEST_CTX null_dgst_ctx; // secret generation过程中不需要握手数据的 - const BLOCK_CIPHER *cipher = NULL; - size_t padding_len; - - uint8_t zeros[32] = {0}; - uint8_t psk[32] = {0}; - uint8_t early_secret[32]; - uint8_t handshake_secret[32]; - uint8_t master_secret[32]; - uint8_t client_handshake_traffic_secret[32]; - uint8_t server_handshake_traffic_secret[32]; - uint8_t client_application_traffic_secret[32]; - uint8_t server_application_traffic_secret[32]; - uint8_t client_write_key[16]; - uint8_t server_write_key[16]; - - - const uint8_t *request_context; - size_t request_context_len; - const uint8_t *cert_request_exts; - size_t cert_request_extslen; - const uint8_t *cert_list; - size_t cert_list_len; - const uint8_t *cert; - size_t certlen; - - uint8_t *p; - - - conn->is_client = 1; - tls_record_set_protocol(enced_record, TLS_protocol_tls12); - - digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; - - - // send ClientHello - tls_trace("send ClientHello\n"); - tls_record_set_protocol(record, TLS_protocol_tls1); - rand_bytes(client_random, 32); // TLS 1.3 Random 不再包含 UNIX Time - sm2_key_generate(&client_ecdhe); - tls13_client_hello_exts_set(client_exts, &client_exts_len, sizeof(client_exts), &(client_ecdhe.public_key)); - tls_record_set_handshake_client_hello(record, &recordlen, - TLS_protocol_tls12, client_random, NULL, 0, - tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]), - client_exts, client_exts_len); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - // 此时尚未确定digest算法,因此无法digest_update - - - // recv ServerHello - tls_trace("recv ServerHello\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - tls13_record_trace(stderr, enced_record, enced_recordlen, 0, 0); - if (tls_record_get_handshake_server_hello(enced_record, - &protocol, &random, &session_id, &session_id_len, - &cipher_suite, &server_exts, &server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (protocol != TLS_protocol_tls12) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - return -1; - } - memcpy(server_random, random, 32); - memcpy(conn->session_id, session_id, session_id_len); - conn->session_id_len = session_id_len; - if (tls_cipher_suite_in_list(cipher_suite, - tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0])) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - conn->cipher_suite = cipher_suite; - if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - conn->protocol = TLS_protocol_tls13; - - tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); - digest_update(&dgst_ctx, record + 5, recordlen - 5); - digest_update(&dgst_ctx, enced_record + 5, enced_recordlen - 5); - - - printf("generate handshake secrets\n"); - /* - generate handshake keys - uint8_t client_write_key[32] - uint8_t server_write_key[32] - uint8_t client_write_iv[12] - uint8_t server_write_iv[12] - */ - sm2_ecdh(&client_ecdhe, &server_ecdhe_public, &server_ecdhe_public); - /* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret); - /* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); - /* [6] */ tls13_hkdf_extract(digest, handshake_secret, (uint8_t *)&server_ecdhe_public, handshake_secret); - /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); - /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); - /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); - /* [10] */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); - //[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) - //[sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length) - //[sender] in {server, client} - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - memset(conn->server_seq_num, 0, 8); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); - memset(conn->client_seq_num, 0, 8); - /* - format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); - format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); - format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - - // recv {EncryptedExtensions} - printf("recv {EncryptedExtensions}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_encrypted_extensions(record) != 1) { - tls_send_alert(conn, TLS_alert_handshake_failure); - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // recv {CertififcateRequest*} or {Certificate} - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - if (type == TLS_handshake_certificate_request) { - tls_trace("recv {CertificateRequest*}\n"); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate_request(record, - &request_context, &request_context_len, - &cert_request_exts, &cert_request_extslen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - // 当前忽略 request_context 和 cert_request_exts - // request_context 应该为空,当前实现中不支持Post-Handshake Auth - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // recv {Certificate} - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - } else { - conn->client_certs_len = 0; - // 清空客户端签名密钥 - } - - // recv {Certificate} - tls_trace("recv {Certificate}\n"); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate(record, - &request_context, &request_context_len, - &cert_list, &cert_list_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_process_certificate_list(cert_list, cert_list_len, conn->server_certs, &conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // recv {CertificateVerify} - tls_trace("recv {CertificateVerify}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate_verify(record, - &server_sign_algor, &server_sig, &server_siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (server_sign_algor != TLS_sig_sm2sig_sm3) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_verify_certificate_verify(TLS_server_mode, &server_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, server_sig, server_siglen) != 1) { - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // use Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*) - tls13_compute_verify_data(server_handshake_traffic_secret, - &dgst_ctx, verify_data, &verify_data_len); - - - // recv {Finished} - tls_trace("recv {Finished}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_finished(record, - &server_verify_data, &server_verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (server_verify_data_len != verify_data_len - || memcmp(server_verify_data, verify_data, verify_data_len) != 0) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // generate server_application_traffic_secret - /* [12] */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); - // generate client_application_traffic_secret - /* [11] */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); - - - if (conn->client_certs_len) { - int client_sign_algor; - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen; - - // send client {Certificate*} - tls_trace("send {Certificate*}\n"); - if (tls13_record_set_handshake_certificate(record, &recordlen, - NULL, 0, // certificate_request_context - conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - - - // send {CertificateVerify*} - tls_trace("send {CertificateVerify*}\n"); - client_sign_algor = TLS_sig_sm2sig_sm3; // FIXME: 应该放在conn里面 - tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); - if (tls13_record_set_handshake_certificate_verify(record, &recordlen, - client_sign_algor, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - } - - // send Client {Finished} - tls_trace("send {Finished}\n"); - tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len); - if (tls_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - - - - // update server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - memset(conn->server_seq_num, 0, 8); - /* - format_print(stderr, 0, 0, "update server secrets\n"); - format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); - format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - - //update client_write_key, client_write_iv, reset client_seq_num - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); - memset(conn->client_seq_num, 0, 8); - - /* - format_print(stderr, 0, 0, "update client secrets\n"); - format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - fprintf(stderr, "Connection established\n"); - -end: - return 1; -} - -int tls13_do_accept(TLS_CONNECT *conn) -{ - uint8_t *record = conn->record; - size_t recordlen; - uint8_t enced_record[25600]; - size_t enced_recordlen = sizeof(enced_record); - - int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; - - - int protocol; - const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - const uint8_t *client_exts; - size_t client_exts_len; - - uint8_t client_random[32]; - uint8_t server_random[32]; - const uint8_t *client_ciphers; - size_t client_ciphers_len; - uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t server_exts_len; - - SM2_KEY server_ecdhe; - SM2_POINT client_ecdhe_public; - SM2_KEY client_sign_key; - const BLOCK_CIPHER *cipher; - const DIGEST *digest; - DIGEST_CTX dgst_ctx; - DIGEST_CTX null_dgst_ctx; - size_t padding_len; - - - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen = sizeof(sig); - - uint8_t verify_data[32]; - size_t verify_data_len; - - const uint8_t *client_verify_data; - size_t client_verify_data_len; - size_t i; - - uint8_t client_write_key[16]; - uint8_t server_write_key[16]; - - uint8_t zeros[32] = {0}; - uint8_t psk[32] = {0}; - uint8_t early_secret[32]; - uint8_t binder_key[32]; - uint8_t handshake_secret[32]; - uint8_t client_handshake_traffic_secret[32]; - uint8_t server_handshake_traffic_secret[32]; - uint8_t client_application_traffic_secret[32]; - uint8_t server_application_traffic_secret[32]; - uint8_t master_secret[32]; - - const uint8_t *request_context; - size_t request_context_len; - const uint8_t *cert_list; - size_t cert_list_len; - const uint8_t *cert; - size_t certlen; - - - int client_verify = 0; - if (conn->ca_certs_len) - client_verify = 1; - - - // 1. Recv ClientHello - tls_trace("recv ClientHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_client_hello(record, - &protocol, &random, - &session_id, &session_id_len, // 不支持SessionID,不做任何处理 - &client_ciphers, &client_ciphers_len, - &client_exts, &client_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (protocol != TLS_protocol_tls12) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - memcpy(client_random, random, 32); - if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, - server_ciphers, sizeof(server_ciphers)/sizeof(int), - &conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_insufficient_security); - goto end; - } - if (!client_exts) { - error_print(); - return -1; - } - tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); // 这个函数是否应该放到tls_里面? - digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; // 在密钥导出函数中可能输入的消息为空,因此需要一个空的dgst_ctx,这里不对了,应该在tls13_derive_secret里面直接支持NULL! - digest_update(&dgst_ctx, record + 5, recordlen - 5); - - - // 2. Send ServerHello - tls_trace("send ServerHello\n"); - rand_bytes(server_random, 32); - sm2_key_generate(&server_ecdhe); - if (tls13_process_client_hello_exts(client_exts, client_exts_len, - &server_ecdhe, &client_ecdhe_public, - server_exts, &server_exts_len, sizeof(server_exts)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - tls_record_set_protocol(record, TLS_protocol_tls12); - if (tls_record_set_handshake_server_hello(record, &recordlen, - TLS_protocol_tls12, server_random, - NULL, 0, // openssl的兼容模式在ClientHello中发送SessionID并检查在ServerHello是否返回,用`-no_middlebox`可关闭兼容模式 - conn->cipher_suite, server_exts, server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - - - sm2_ecdh(&server_ecdhe, &client_ecdhe_public, &client_ecdhe_public); - /* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret); - /* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); - /* 6 */ tls13_hkdf_extract(digest, handshake_secret, (uint8_t *)&client_ecdhe_public, handshake_secret); - /* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); - /* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); - /* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); - /* 10 */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); - // generate server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - memset(conn->server_seq_num, 0, 8); - // generate client_write_key, client_write_iv, reset client_seq_num - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - memset(conn->client_seq_num, 0, 8); - /* - format_print(stderr, 0, 0, "generate handshake secrets\n"); - format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); - format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); - format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - - // 3. Send {EncryptedExtensions} - tls_trace("send {EncryptedExtensions}\n"); - tls_record_set_protocol(record, TLS_protocol_tls12); - tls13_record_set_handshake_encrypted_extensions(record, &recordlen); - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - // FIXME: tls13_record_encrypt需要支持握手消息 - // tls_record_data(enced_record)[0] = TLS_handshake_encrypted_extensions; - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // send {CertificateRequest*} - if (client_verify) { - tls_trace("send {CertificateRequest*}\n"); - - // TODO: 设置certificate_request中的extensions! - if (tls13_record_set_handshake_certificate_request_default(record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - } - - // send Server {Certificate} - tls_trace("send {Certificate}\n"); - if (tls13_record_set_handshake_certificate(record, &recordlen, NULL, 0, conn->server_certs, conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // send Server {CertificateVerify} - tls_trace("send {CertificateVerify}\n"); - tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); - if (tls13_record_set_handshake_certificate_verify(record, &recordlen, - TLS_sig_sm2sig_sm3, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // Send Server {Finished} - tls_trace("send {Finished}\n"); - - // compute server verify_data before digest_update() - tls13_compute_verify_data(server_handshake_traffic_secret, - &dgst_ctx, verify_data, &verify_data_len); - if (tls13_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - // generate server_application_traffic_secret - /* 12 */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); - // Generate client_application_traffic_secret - /* 11 */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); - // 因为后面还要解密握手消息,因此client application key, iv 等到握手结束之后再更新 - - // Recv Client {Certificate*} - if (client_verify) { - tls_trace("recv {Certificate*}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - - if (tls13_record_get_handshake_certificate(record, - &request_context, &request_context_len, - &cert_list, &cert_list_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_process_certificate_list(cert_list, cert_list_len, conn->client_certs, &conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cert, &certlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - } - - // Recv client {CertificateVerify*} - if (client_verify) { - int client_sign_algor; - const uint8_t *client_sig; - size_t client_siglen; - - tls_trace("recv Client {CertificateVerify*}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - - if (tls13_record_get_handshake_certificate_verify(record, &client_sign_algor, &client_sig, &client_siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_verify_certificate_verify(TLS_client_mode, &client_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, client_sig, client_siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - } - - // 12. Recv Client {Finished} - - tls_trace("recv {Finished}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_finished(record, &client_verify_data, &client_verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - return -1; - } - if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - return -1; - } - if (client_verify_data_len != verify_data_len - || memcmp(client_verify_data, verify_data, verify_data_len) != 0) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - return -1; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); - - - // 注意:OpenSSL兼容模式在此处会收发ChangeCipherSpec报文 - - - // update server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - memset(conn->server_seq_num, 0, 8); - /* - format_print(stderr, 0, 0, "update server secrets\n"); - format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); - format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - - // update client_write_key, client_write_iv - // reset client_seq_num - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); - memset(conn->client_seq_num, 0, 8); - /* - format_print(stderr, 0, 0, "update client secrets\n"); - format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - - fprintf(stderr, "Connection Established!\n\n"); - -end: - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; +static size_t tls13_ciphers_count = sizeof(tls13_ciphers)/sizeof(int); + +/* +int tls13_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 + // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) + format |= tls13_ciphers[0] << 8; + return tls_record_print(fp, record, recordlen, format, indent); +} +*/ + +static int tls13_client_hello_exts[] = { + TLS_extension_supported_versions, + TLS_extension_padding, +}; + + +/* +struct { + opaque content[TLSPlaintext.length]; + ContentType type; + uint8 zeros[length_of_padding]; +} TLSInnerPlaintext; + +struct { + ContentType opaque_type = application_data; // 23 + ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2 + uint16 length; + opaque encrypted_record[TLSCiphertext.length]; +} TLSCiphertext; +*/ +int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], int record_type, + const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content + uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record +{ + uint8_t nonce[12]; + uint8_t aad[5]; + uint8_t *gmac; + uint8_t *mbuf = NULL; // FIXME: update gcm_encrypt API + size_t mlen, clen; + + if (!(mbuf = malloc(inlen + 256))) { + error_print(); + return -1; + } + + // nonce = (zeros|seq_num) xor (iv) + nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; + memcpy(nonce + 4, seq_num, 8); + gmssl_memxor(nonce, nonce, iv, 12); + + // TLSInnerPlaintext + memcpy(mbuf, in, inlen); + mbuf[inlen] = record_type; + memset(mbuf + inlen + 1, 0, padding_len); + mlen = inlen + 1 + padding_len; + clen = mlen + GHASH_SIZE; + + // aad = TLSCiphertext header + aad[0] = TLS_record_application_data; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; + aad[3] = clen >> 8; + aad[4] = clen; + + gmac = out + mlen; + if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) { + error_print(); + free(mbuf); + return -1; + } + *outlen = clen; + free(mbuf); + + return 1; +} + +int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + int *record_type, uint8_t *out, size_t *outlen) +{ + uint8_t nonce[12]; + uint8_t aad[5]; + size_t mlen; + const uint8_t *gmac; + size_t i; + + // nonce = (zeros|seq_num) xor (iv) + nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; + memcpy(nonce + 4, seq_num, 8); + gmssl_memxor(nonce, nonce, iv, 12); + + // aad = TLSCiphertext header + aad[0] = TLS_record_application_data; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; + aad[3] = inlen >> 8; + aad[4] = inlen; + + if (inlen < GHASH_SIZE) { + error_print(); + return -1; + } + mlen = inlen - GHASH_SIZE; + gmac = in + mlen; + + if (gcm_decrypt(key, nonce, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { + error_print(); + return -1; + } + // remove padding, get record_type + *record_type = 0; + while (mlen--) { + if (out[mlen] != 0) { + *record_type = out[mlen]; + break; + } + } + *outlen = mlen; + if (!tls_record_type_name(*record_type)) { + error_print(); + return -1; + } + return 1; +} + +// 这个函数是不对的,在我们的一些情况下,加密的时候并不会组成完整的数据 +int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, + uint8_t *enced_record, size_t *enced_recordlen) +{ + // 被加密的是握手消息或者是应用层数据 + + if (tls13_gcm_encrypt(key, iv, + seq_num, record[0], record + 5, recordlen - 5, padding_len, + enced_record + 5, enced_recordlen) != 1) { + error_print(); + return -1; + } + + enced_record[0] = TLS_record_application_data; // 显然这个不太对啊 + enced_record[1] = 0x03; //TLS_protocol_tls12_major; + enced_record[2] = 0x03; //TLS_protocol_tls12_minor; + enced_record[3] = (*enced_recordlen) >> 8; + enced_record[4] = (*enced_recordlen); + + (*enced_recordlen) += 5; + return 1; +} + +int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen, + uint8_t *record, size_t *recordlen) +{ + int record_type; + + if (tls13_gcm_decrypt(key, iv, + seq_num, enced_record + 5, enced_recordlen - 5, + &record_type, record + 5, recordlen) != 1) { + error_print(); + return -1; + } + record[0] = record_type; + record[1] = 0x03; //TLS_protocol_tls12_major; + record[2] = 0x03; //TLS_protocol_tls12_minor; + record[3] = (*recordlen) >> 8; + record[4] = (*recordlen); + + (*recordlen) += 5; + return 1; +} + +int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *sentlen) +{ + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + uint8_t *record = conn->record; + size_t recordlen; + size_t padding_len = 0; //FIXME: 在conn中设置是否加随机填充,及设置该值 + + tls_trace("send {ApplicationData}\n"); + + if (conn->is_client) { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls13_gcm_encrypt(key, iv, + seq_num, TLS_record_application_data, data, datalen, padding_len, + record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + + record[0] = TLS_record_application_data; + record[1] = TLS_protocol_tls12 >> 8; + record[2] = TLS_protocol_tls12 & 0xff; + record[3] = recordlen >> 8; + record[4] = recordlen; + recordlen += 5; + + tls_record_send(record, recordlen, conn->sock); + tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + + tls_seq_num_incr(seq_num); + + *sentlen = datalen; + + return 1; +} + +/* +int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) +{ + int record_type; + uint8_t *record = conn->record; + size_t recordlen; + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + + + tls_trace("recv {ApplicationData}\n"); + + if (conn->is_client) { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } else { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } + + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (record[0] != TLS_record_application_data) { + error_print(); + return -1; + } + + if (tls13_gcm_decrypt(key, iv, + seq_num, record + 5, recordlen - 5, + &record_type, data, datalen) != 1) { + error_print(); + return -1; + } + + tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + tls_seq_num_incr(seq_num); + + if (record_type != TLS_record_application_data) { + error_print(); + return -1; + } + return 1; +} +*/ + +int tls13_do_recv(TLS_CONNECT *conn) +{ + int ret; + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + uint8_t *record = conn->record; + size_t recordlen; + int record_type; + + if (conn->is_client) { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } else { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } + + tls_trace("recv ApplicationData\n"); + if ((ret = tls_record_recv(record, &recordlen, conn->sock)) != 1) { + if (ret < 0) error_print(); + return ret; + } + tls_record_trace(stderr, record, recordlen, 0, 0); + // TODO: 是否需要检查record_type? record[0] != TLS_record_application_data + + if (tls13_gcm_decrypt(key, iv, + seq_num, record + 5, recordlen - 5, + &record_type, conn->databuf, &conn->datalen) != 1) { + error_print(); + return -1; + } + conn->data = conn->databuf; + tls_seq_num_incr(seq_num); + + tls_record_set_data(record, conn->data, conn->datalen); + tls_trace("decrypt ApplicationData\n"); + tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + + + if (record_type != TLS_record_application_data) { + error_print(); + return -1; + } + return 1; +} + +int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen) +{ + if (!conn || !out || !outlen || !recvlen) { + error_print(); + return -1; + } + if (conn->datalen == 0) { + int ret; + if ((ret = tls13_do_recv(conn)) != 1) { + if (ret) error_print(); + return ret; + } + } + *recvlen = outlen <= conn->datalen ? outlen : conn->datalen; + memcpy(out, conn->data, *recvlen); + conn->data += *recvlen; + conn->datalen -= *recvlen; + return 1; +} + + + +/* +HKDF-Expand-Label(Secret, Label, Context, Length) = + HKDF-Expand(Secret, HkdfLabel, Length); + + HkdfLabel = struct { + uint16 length = Length; + opaque label<7..255> = "tls13 " + Label; + opaque context<0..255> = Context; } + +Derive-Secret(Secret, Label, Messages) = + HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length) + +*/ + +int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]) +{ + size_t dgstlen; + + if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1 + || dgstlen != 32) { + error_print(); + return -1; + } + return 1; +} + +int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], + const char *label, const uint8_t *context, size_t context_len, + size_t outlen, uint8_t *out) +{ + uint8_t label_len; + uint8_t hkdf_label[2 + 256 + 256]; + uint8_t *p = hkdf_label; + size_t hkdf_label_len = 0; + + label_len = strlen("tls13 ") + strlen(label); + tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len); + tls_uint8_to_bytes(label_len, &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)"tls13 ", strlen("tls13 "), &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len); + tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len); + + hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out); + + return 1; +} + +int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]) +{ + DIGEST_CTX ctx = *dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + + if (digest_finish(&ctx, dgst, &dgstlen) != 1 + || tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) { + error_print(); + return -1; + } + return 1; +} + +static const uint8_t TLS13_client_context_str_and_zero[] = "TLS 1.3, client CertificateVerify"; +static const uint8_t TLS13_server_context_str_and_zero[] = "TLS 1.3, server CertificateVerify"; +static size_t TLS13_client_context_str_and_zero_size = sizeof(TLS13_client_context_str_and_zero); +static size_t TLS13_server_context_str_and_zero_size = sizeof(TLS13_server_context_str_and_zero); + +int tls13_sign_certificate_verify(int tls_mode, + const SM2_KEY *key, const char *signer_id, size_t signer_id_len, + const DIGEST_CTX *tbs_dgst_ctx, + uint8_t *sig, size_t *siglen) +{ + SM2_SIGN_CTX sign_ctx; + uint8_t prefix[64]; + const uint8_t *context_str_and_zero; + size_t context_str_and_zero_len; + DIGEST_CTX dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + + switch (tls_mode) { + case TLS_client_mode: + context_str_and_zero = TLS13_client_context_str_and_zero; + context_str_and_zero_len = TLS13_client_context_str_and_zero_size; + break; + case TLS_server_mode: + context_str_and_zero = TLS13_server_context_str_and_zero; + context_str_and_zero_len = TLS13_server_context_str_and_zero_size; + break; + default: + error_print(); + return -1; + } + + dgst_ctx = *tbs_dgst_ctx; + digest_finish(&dgst_ctx, dgst, &dgstlen); + + sm2_sign_init(&sign_ctx, key, signer_id, signer_id_len); + sm2_sign_update(&sign_ctx, prefix, 64); + sm2_sign_update(&sign_ctx, context_str_and_zero, context_str_and_zero_len); + sm2_sign_update(&sign_ctx, dgst, dgstlen); + sm2_sign_finish(&sign_ctx, sig, siglen); + + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + return 1; +} + +int tls13_verify_certificate_verify(int tls_mode, + const SM2_KEY *public_key, const char *signer_id, size_t signer_id_len, + const DIGEST_CTX *tbs_dgst_ctx, const uint8_t *sig, size_t siglen) +{ + int ret; + SM2_SIGN_CTX verify_ctx; + uint8_t prefix[64]; + const uint8_t *context_str_and_zero; + size_t context_str_and_zero_len; + DIGEST_CTX dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + + switch (tls_mode) { + case TLS_client_mode: + context_str_and_zero = TLS13_client_context_str_and_zero; + context_str_and_zero_len = TLS13_client_context_str_and_zero_size; + break; + case TLS_server_mode: + context_str_and_zero = TLS13_server_context_str_and_zero; + context_str_and_zero_len = TLS13_server_context_str_and_zero_size; + break; + default: + error_print(); + return -1; + } + + dgst_ctx = *tbs_dgst_ctx; + digest_finish(&dgst_ctx, dgst, &dgstlen); + + sm2_verify_init(&verify_ctx, public_key, signer_id, signer_id_len); + sm2_verify_update(&verify_ctx, prefix, 64); + sm2_verify_update(&verify_ctx, context_str_and_zero, context_str_and_zero_len); + sm2_verify_update(&verify_ctx, dgst, dgstlen); + + if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + error_print(); + return -1; + } + if (ret != 1) { + error_print(); + } + return ret; +} + +/* + verify_data in Finished + + finished_key = + HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) + Structure of this message: + struct { + opaque verify_data[Hash.length]; + } Finished; + The verify_data value is computed as follows: + verify_data = + HMAC(finished_key, + Transcript-Hash(Handshake Context, + Certificate*, CertificateVerify*)) +*/ + +int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, + const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len) +{ + DIGEST_CTX temp_dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + uint8_t finished_key[64]; + size_t finished_key_len; + + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + finished_key_len = dgstlen; + + tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret, + "finished", NULL, 0, finished_key_len, finished_key); + + hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len); + return 1; +} + +/* +Handshakes + +*/ + +int tls13_client_hello_exts_set(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_POINT *client_ecdhe_public) +{ + int protocols[] = { TLS_protocol_tls13 }; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + int sig_algs[] = { TLS_sig_sm2sig_sm3 }; + size_t protocols_cnt = sizeof(protocols)/sizeof(int); + size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(int); + size_t sig_algs_cnt = sizeof(sig_algs)/sizeof(int); + + + if (!exts || !extslen || !client_ecdhe_public) { + error_print(); + return -1; + } + + *extslen = 0; + if (tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, NULL, extslen) != 1 + || tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, NULL, extslen) != 1 + || tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, NULL, extslen) != 1 + || tls13_client_key_share_ext_to_bytes(client_ecdhe_public, NULL, extslen) != 1) { + error_print(); + return -1; + } + if (*extslen > maxlen) { + error_print(); + return -1; + } + *extslen = 0; + tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, &exts, extslen); + tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &exts, extslen); + tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, &exts, extslen); + tls13_client_key_share_ext_to_bytes(client_ecdhe_public, &exts, extslen); + return 1; +} + +int tls13_process_client_hello_exts(const uint8_t *exts, size_t extslen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t *server_exts, size_t *server_exts_len, size_t server_exts_maxlen) +{ + size_t len = 0; + *server_exts_len = 0; + + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + + switch (ext_type) { + /* + // tls13_process_client_hello_exts 的接口需要处理,部分输出要输出到server_exts中 + case TLS_extension_supported_groups: // 这个应该放在EE里面 + if (tls_process_client_supported_groups(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { + error_print(); + return -1; + } + tls_process_client_supported_groups(ext_data, ext_datalen, &server_exts, server_exts_len); + break; + case TLS_extension_signature_algorithms: // client单方面通知就可以了,服务器不需要响应 + if (tls_process_client_signature_algorithms(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { + error_print(); + return -1; + } + tls_process_client_signature_algorithms(ext_data, ext_datalen, &server_exts, server_exts_len); + break; + */ + case TLS_extension_supported_versions: + if (tls13_process_client_supported_versions(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { + error_print(); + return -1; + } + tls13_process_client_supported_versions(ext_data, ext_datalen, &server_exts, server_exts_len); + break; + case TLS_extension_key_share: + if (tls13_process_client_key_share(ext_data, ext_datalen, server_ecdhe_key, client_ecdhe_public, &server_exts, server_exts_len) != 1 + || len > server_exts_maxlen) { + error_print(); + return -1; + } + break; + + default: + ; // server ignore unkonwn extensions + } + } + + return 1; +} + +int tls_client_key_shares_from_bytes(SM2_POINT *sm2_point, const uint8_t **in, size_t *inlen) +{ + const uint8_t *key_shares; + size_t key_shares_len; + + tls_uint16array_from_bytes(&key_shares, &key_shares_len, in, inlen); + + while (key_shares_len) { + uint16_t group; + const uint8_t *key_exch; + size_t key_exch_len; + + tls_uint16_from_bytes(&group, &key_shares, &key_shares_len); + tls_uint16array_from_bytes(&key_exch, &key_exch_len, &key_shares, &key_shares_len); + + if (key_exch_len != 65) { + error_print(); + return -1; + } + + switch (group) { + case TLS_curve_sm2p256v1: + sm2_point_from_octets(sm2_point, key_exch, key_exch_len); + break; + default: + error_print(); + return -1; + } + } + + return 1; +} + +// 这个函数不是太正确,应该也是一个process +int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *sm2_point) +{ + uint16_t version; + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + const uint8_t *p; + size_t len; + + tls_uint16_from_bytes(&ext_type, &exts, &extslen); + tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen); + + switch (ext_type) { + case TLS_extension_supported_versions: + if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + if (version != TLS_protocol_tls13) { + error_print(); + return -1; + } + break; + case TLS_extension_key_share: + if (tls13_process_server_key_share(ext_data, ext_datalen, sm2_point) != 1) { + error_print(); + return -1; + } + break; + //default: + // FIXME: 还有几个扩展没有处理! + //error_print(); + //return -1; + } + } + return 1; +} + + +/* +struct { + Extension extensions<0..2^16-1>; +} EncryptedExtensions; +*/ +static int tls13_encrypted_exts[] = { + TLS_extension_server_name, + TLS_extension_max_fragment_length, + TLS_extension_supported_groups, + TLS_extension_use_srtp, + TLS_extension_heartbeat, + TLS_extension_application_layer_protocol_negotiation, + TLS_extension_client_certificate_type, + TLS_extension_server_certificate_type, + TLS_extension_early_data, +}; + +int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen) +{ + const uint8_t *exts; + size_t extslen; + + format_print(fp, fmt, ind, "EncryptedExtensions\n"); + ind += 4; + + if (tls_uint16array_from_bytes(&exts, &extslen, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (exts) { + tls13_extensions_print(fp, fmt, ind, TLS_handshake_encrypted_extensions, exts, extslen); + } + if (tls_length_is_zero(datalen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen) +{ + int type = TLS_handshake_encrypted_extensions; + uint8_t *p = record + 5 + 4; + size_t len = 0; + uint8_t exts[128]; + size_t extslen = 0; + uint8_t *pexts = exts; + const int supported_groups[] = { TLS_curve_sm2p256v1 }; + + tls_supported_groups_ext_to_bytes(supported_groups, sizeof(supported_groups)/sizeof(int), &pexts, &extslen); + + tls_uint16array_to_bytes(exts, extslen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + + return 1; +} + +int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) +{ + int type; + const uint8_t *p; + size_t len; + const uint8_t *exts_data; + size_t exts_datalen; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(&exts_data, &exts_datalen, &p, &len) != 1) { + error_print(); + return -1; + } + // 当前实现不需要在EncryptedExtensions提供扩展 + if (exts_datalen) { + // FIXME: 实际上supported_groups是放在这里的,应该加以处理 + //error_print(); + //return -1; + } + return 1; +} + + +/* + ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 + ServerHello.Extensions.supported_groups 决定了服务器的公钥类型, + 因此也决定了服务器的签名算法 + ServerHello.cipher_suite决定了哈希函数 +*/ + +/* +struct { + SignatureScheme algorithm; + opaque signature<0..2^16-1>; +} CertificateVerify; + +注意:TLS 1.2中只有RAW signature, 也就是没有经过uint16array封装的,这其实不太符合TLS的设计逻辑 +*/ +int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, + int sign_algor, const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_certificate_verify; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + tls_uint16_to_bytes((uint16_t)sign_algor, &p, &len); + tls_uint16array_to_bytes(sig, siglen, &p, &len); + + if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_get_handshake_certificate_verify(const uint8_t *record, + int *sign_algor, const uint8_t **sig, size_t *siglen) +{ + int type; + const uint8_t *p; + size_t len ; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_certificate_verify) { + error_print(); + return -1; + } + + *sign_algor = 0; + tls_uint16_from_bytes((uint16_t *)sign_algor, &p, &len); + tls_uint16array_from_bytes(sig, siglen, &p, &len); + + return 1; +} + + +/* +struct { + opaque certificate_request_context<0..2^8-1>; + Extension extensions<2..2^16-1>; +} CertificateRequest; + +certificate_request_context 用于 Post-handshake Authentication,否则应该长度为0 + +*/ +static int tls13_certificate_request_exts[] = { + TLS_extension_signature_algorithms, // 必须包含 + TLS_extension_status_request, + TLS_extension_signed_certificate_timestamp, + TLS_extension_certificate_authorities, + TLS_extension_oid_filters, + TLS_extension_signature_algorithms_cert, +}; + + + + +/* +struct { + opaque certificate_request_context<0..2^8-1>; + Extension extensions<2..2^16-1>; +} CertificateRequest; + +extensiosns: + Extension signature_algorithms MUST be specified +*/ +int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, + const uint8_t *request_context, size_t request_context_len, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_certificate_request; + uint8_t *data; + size_t datalen = 0; + + if (!record || !recordlen) { + error_print(); + return -1; + } + data = tls_handshake_data(tls_record_data(record)); + tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); + tls_uint16array_to_bytes(exts, extslen, &data, &datalen); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls13_record_set_handshake_certificate_request_default(uint8_t *record, size_t *recordlen) +{ + int sig_algs[] = { TLS_sig_sm2sig_sm3 }; + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + + tls_signature_algorithms_ext_to_bytes(sig_algs, sizeof(sig_algs)/sizeof(int), &p, &extslen); + tls13_record_set_handshake_certificate_request(record, recordlen, NULL, 0, exts, extslen); + return 1; +} + +int tls13_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **requst_context, size_t *request_context_len, + const uint8_t **exts, size_t *exts_len) +{ + int type; + const uint8_t *p; + size_t len; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_request) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(requst_context, request_context_len, &p, &len) != 1 + || tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +static const int tls13_handshake_certificate_exts[] = { + TLS_extension_status_request, + TLS_extension_signed_certificate_timestamp, +}; +/* +enum { X509(0), RawPublicKey(2), (255) } CertificateType; + +struct { + select (certificate_type) { + case RawPublicKey: opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; -- TLS 1.3可以只传公钥不传证书 + case X509: opaque cert_data<1..2^24-1>; + }; + Extension extensions<0..2^16-1>; +} CertificateEntry; + +struct { + opaque certificate_request_context<0..2^8-1>; -- 用于客户端证书,服务器证书该域长度为0 + CertificateEntry certificate_list<0..2^24-1>; +} Certificate; + +TLS 1.3 Certificate: + + * TLS 1.3 支持发送公钥,可以去掉嵌入式环境的证书传输开销 + * TLS 1.3 的证书链中增加了 certificate_request_context + 用于客户端发送证书时标识context,服务器端的证书中该域的长度为0 + * 证书链中每个证书都有一个独立的扩展域,TLS 1.2 中的证书相关扩展移至此处 + +Extensions in client Certificate MUST from ClientHello +Extensions in server Certificate MUST from CertificateRequest +Entensions apply to entire chain SHOULD be in the first CertificateEntry + +目前CertificateEntry中的扩展主要用于服务器证书的验证 +客户端在ClientHello中可以包含status_request 和 signed_certificate_timestamp +让服务器提供 OCSP 的状态证明和时间戳信息 +服务器则在证书消息的每个证书否面附带这两个扩展,提供相关信息 + +在 RFC 8446 (TLS 1.3) 中还没有涉及客户端证书的具体扩展 +但是客户端在提供客户端证书时,应该响应服务器CertificateRequest消息中的扩展 + +目前GmSSLv3还不支持这两个证书扩展的生成,但是提供解析和显示 + +Valid extensions for server certificates: + TLS_extension_status_request (5) + TLS_extension_signed_certificate_timestamp (18) +*/ + +int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "Certificate\n"); + ind += 4; + + if (tls_uint8array_from_bytes(&p, &len, &cert, &certlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "certificate_request_context", p, len); + + format_print(fp, fmt, ind, "certificate_list\n"); + ind += 4; + if (tls_uint24array_from_bytes(&p, &len, &cert, &certlen) != 1) { + error_print(); + return -1; + } + while (len) { + const uint8_t *cert_data; + size_t cert_data_len; + const uint8_t *exts; + size_t extslen; + + if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &p, &len) != 1 + || tls_uint16array_from_bytes(&exts, &extslen, &p, &len) != 1) { + error_print(); + return -1; + } + if (!cert_data) { + error_print(); + return -1; + } + + format_print(fp, fmt, ind, "CertificateEntry\n"); + x509_cert_print(fp, fmt, ind + 4, "Certificate", cert_data, cert_data_len); + x509_cert_to_pem(cert_data, cert_data_len, fp); + tls13_extensions_print(fp, fmt, ind + 4, TLS_handshake_certificate, exts, extslen); + } + return 1; +} + +int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *certreq, size_t certreqlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "CertificateRequest\n"); + ind += 4; + + if (tls_uint8array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "certificate_request_context", p, len); + + if (tls_uint16array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "extensions", p, len); + + if (tls_length_is_zero(certreqlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + uint16_t sig_alg; + const uint8_t *sig; + size_t siglen; + + format_print(fp, fmt, ind, "CertificateVerify\n"); + ind += 4; + + if (tls_uint16_from_bytes(&sig_alg, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "algorithm: %s (0x%04x)\n", tls_signature_scheme_name(sig_alg), sig_alg); + if (tls_uint16array_from_bytes(&sig, &siglen, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "signature", sig, siglen); + if (tls_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_certificate_list_to_bytes(const uint8_t *certs, size_t certslen, + uint8_t **out, size_t *outlen) +{ + uint8_t *p = NULL; + size_t cert_list_len = 0; + + if (out && *out) { + p = (*out) + tls_uint24_size(); + } + while (certslen) { + const uint8_t *cert; + size_t certlen; + const uint8_t *entry_exts = NULL; + size_t entry_exts_len = 0; + + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + tls_uint24array_to_bytes(cert, certlen, &p, &cert_list_len); + tls_uint16array_to_bytes(entry_exts, entry_exts_len, &p, &cert_list_len); + + } + tls_uint24array_to_bytes(NULL, cert_list_len, out, outlen); + return 1; +} + +int tls13_process_certificate_list(const uint8_t *cert_list, size_t cert_list_len, + uint8_t *certs, size_t *certs_len) +{ + *certs_len = 0; + + while (cert_list_len) { + const uint8_t *cert_data; + size_t cert_data_len; + const uint8_t *exts; + size_t exts_len; + const uint8_t *cert; + size_t cert_len; + + if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &cert_list, &cert_list_len) != 1 + || tls_uint16array_from_bytes(&exts, &exts_len, &cert_list, &cert_list_len) != 1) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cert, &cert_len, &cert_data, &cert_data_len) != 1 + || asn1_length_is_zero(cert_data_len) != 1 + || x509_cert_to_der(cert, cert_len, &certs, certs_len) != 1) { + error_print(); + return -1; + } + + while (exts_len) { + int ext_type; + const uint8_t *ext_data; + size_t ext_data_len; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_data_len, &exts, &exts_len) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_status_request: + case TLS_extension_signed_certificate_timestamp: + error_print(); + return -1; + default: + error_print(); + return -1; + } + } + } + return 1; +} + +int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, + const uint8_t *request_context, size_t request_context_len, + const uint8_t *certs, size_t certslen) +{ + int type = TLS_handshake_certificate; + uint8_t *data; + size_t datalen; + + if (!record || !recordlen || !certs || !certslen) { + error_print(); + return -1; + } + + datalen = 0; + tls_uint8array_to_bytes(request_context, request_context_len, NULL, &datalen); + tls13_certificate_list_to_bytes(certs, certslen, NULL, &datalen); + if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { + error_print(); + return -1; + } + + data = tls_handshake_data(tls_record_data(record)); + datalen = 0; + tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); + tls13_certificate_list_to_bytes(certs, certslen, &data, &datalen); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + + return 1; +} + +int tls13_record_get_handshake_certificate(const uint8_t *record, + const uint8_t **cert_request_context, size_t *cert_request_context_len, + const uint8_t **cert_list, size_t *cert_list_len) +{ + int type; + const uint8_t *p; + size_t len; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(cert_request_context, cert_request_context_len, &p, &len) != 1 + || tls_uint24array_from_bytes(cert_list, cert_list_len, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (*cert_list == NULL) { + error_print(); + return -1; + } + return 1; +} + + + +/* +finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) + +struct { + opaque verify_data[Hash.length]; +} Finished; + +verify_data = HMAC(finished_key, Hash(Handshake Context, Certificate*, CertificateVerify*)) +Hash = SM3, SHA256 or SHA384 +*/ + + +int tls13_record_set_handshake_finished(uint8_t *record, size_t *recordlen, + const uint8_t *verify_data, size_t verify_data_len) +{ + int type = TLS_handshake_finished; + if (!record || !recordlen || !verify_data) { + error_print(); + return -1; + } + tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); + return 1; +} + +int tls13_record_get_handshake_finished(const uint8_t *record, + const uint8_t **verify_data, size_t *verify_data_len) +{ + int type; + + if (tls_record_get_handshake(record, &type, verify_data, verify_data_len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_finished) { + error_print(); + return -1; + } + if (*verify_data_len != SM3_DIGEST_SIZE + && *verify_data_len != SHA384_DIGEST_SIZE) { + error_print(); + return -1; + } + return 1; +} + + +int tls13_padding_len_rand(size_t *padding_len) +{ + uint8_t val; + rand_bytes(&val, 1); + *padding_len = val % 128; + return 1; +} + + + +int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_CIPHER **cipher) +{ + switch (cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + *digest = DIGEST_sm3(); + *cipher = BLOCK_CIPHER_sm4(); + break; + case TLS_cipher_aes_128_gcm_sha256: + *digest = DIGEST_sha256(); + *cipher = BLOCK_CIPHER_aes128(); + break; + default: + error_print(); + return -1; + } + return 1; +} + + + +/* + Client Server + +Key ^ ClientHello +Exch | + key_share* + | + signature_algorithms* + | + psk_key_exchange_modes* + v + pre_shared_key* --------> + ServerHello ^ Key + + key_share* | Exch + + pre_shared_key* v + + + | ecdhe => handshake_secret | + | handshake_secret => master_secret | + | handshake_secret, client_hello, server_hello | + | => client_handshake_traffic_secret | + | => server_handshake_traffic_secret | + + + {EncryptedExtensions} ^ Server + {CertificateRequest*} v Params + {Certificate} ^ + {CertificateVerify} | Auth + {Finished} v + + + master_secret, ClientHello .. server Finished + => server_application_traffic_secret_0 + + <-------- [Application Data*] + + ^ {Certificate*} +Auth | {CertificateVerify*} + v {Finished} --------> + + + + master_secret, ClientHello .. server Finished + => client_application_traffic_secret_0 + + [Application Data] <-------> [Application Data] + + +TLS 1.3的区别: + + * 首先在最开始的握手阶段就协商好了密钥,因此握手之后传输的就是加密消息了 + * 因此在第二阶段,双方不再发送ServerKeyExchange和ClientKeyExchange + * 服务器先发送CertificateRequest,再发送Certificate + * 没有ChangeCipherSpec了 + * 在握手阶段就需要加密,并且Certificate也在其中,因此需要格外的大的密文数据缓冲 + + 0 + | + v +[1] PSK -> HKDF-Extract = Early Secret + | +[2] +-----> Derive-Secret(., "ext binder" | "res binder", "") + | = binder_key + | +[3] +-----> Derive-Secret(., "c e traffic", ClientHello) + | = client_early_traffic_secret + | +[4] +-----> Derive-Secret(., "e exp master", ClientHello) + | = early_exporter_master_secret + v +[5] Derive-Secret(., "derived", "") + | + v +[6] (EC)DHE -> HKDF-Extract = Handshake Secret + | +[7] +-----> Derive-Secret(., "c hs traffic", + | ClientHello...ServerHello) + | = client_handshake_traffic_secret + | +[8] +-----> Derive-Secret(., "s hs traffic", + | ClientHello...ServerHello) + | = server_handshake_traffic_secret + v +[9] Derive-Secret(., "derived", "") + | + v +[10] 0 -> HKDF-Extract = Master Secret + | +[11] +-----> Derive-Secret(., "c ap traffic", + | ClientHello...server Finished) + | = client_application_traffic_secret_0 + | +[12] +-----> Derive-Secret(., "s ap traffic", + | ClientHello...server Finished) + | = server_application_traffic_secret_0 + | +[13] +-----> Derive-Secret(., "exp master", + | ClientHello...server Finished) + | = exporter_master_secret + | +[14] +-----> Derive-Secret(., "res master", + ClientHello...client Finished) + = resumption_master_secret + +*/ + + + +int tls13_do_connect(TLS_CONNECT *conn) +{ + uint8_t *record = conn->record; + uint8_t *enced_record = conn->enced_record; + size_t recordlen; + + size_t enced_recordlen; + + + int type; + const uint8_t *data; + size_t datalen; + + int protocol; + uint8_t client_random[32]; + uint8_t server_random[32]; + int cipher_suite; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + + int protocols[] = { TLS_protocol_tls13 }; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + int sign_algors[] = { TLS_sig_sm2sig_sm3 }; + + uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t client_exts_len; + const uint8_t *server_exts; + size_t server_exts_len; + + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen = sizeof(sig); + uint8_t verify_data[32]; + size_t verify_data_len; + + int server_sign_algor; + const uint8_t *server_sig; + size_t server_siglen; + const uint8_t *server_verify_data; + size_t server_verify_data_len; + + SM2_KEY client_ecdhe; + SM2_POINT server_ecdhe_public; + SM2_KEY server_sign_key; + + const DIGEST *digest = DIGEST_sm3(); + DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的 + DIGEST_CTX null_dgst_ctx; // secret generation过程中不需要握手数据的 + const BLOCK_CIPHER *cipher = NULL; + size_t padding_len; + + uint8_t zeros[32] = {0}; + uint8_t psk[32] = {0}; + uint8_t early_secret[32]; + uint8_t handshake_secret[32]; + uint8_t master_secret[32]; + uint8_t client_handshake_traffic_secret[32]; + uint8_t server_handshake_traffic_secret[32]; + uint8_t client_application_traffic_secret[32]; + uint8_t server_application_traffic_secret[32]; + uint8_t client_write_key[16]; + uint8_t server_write_key[16]; + + + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *cert_request_exts; + size_t cert_request_extslen; + const uint8_t *cert_list; + size_t cert_list_len; + const uint8_t *cert; + size_t certlen; + + uint8_t *p; + + + conn->is_client = 1; + tls_record_set_protocol(enced_record, TLS_protocol_tls12); + + digest_init(&dgst_ctx, digest); + null_dgst_ctx = dgst_ctx; + + + // send ClientHello + tls_trace("send ClientHello\n"); + tls_record_set_protocol(record, TLS_protocol_tls1); + rand_bytes(client_random, 32); // TLS 1.3 Random 不再包含 UNIX Time + sm2_key_generate(&client_ecdhe); + tls13_client_hello_exts_set(client_exts, &client_exts_len, sizeof(client_exts), &(client_ecdhe.public_key)); + tls_record_set_handshake_client_hello(record, &recordlen, + TLS_protocol_tls12, client_random, NULL, 0, + tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]), + client_exts, client_exts_len); + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + // 此时尚未确定digest算法,因此无法digest_update + + + // recv ServerHello + tls_trace("recv ServerHello\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + tls13_record_trace(stderr, enced_record, enced_recordlen, 0, 0); + if (tls_record_get_handshake_server_hello(enced_record, + &protocol, &random, &session_id, &session_id_len, + &cipher_suite, &server_exts, &server_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (protocol != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + if (tls_cipher_suite_in_list(cipher_suite, + tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0])) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + conn->cipher_suite = cipher_suite; + if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + conn->protocol = TLS_protocol_tls13; + + tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + digest_update(&dgst_ctx, enced_record + 5, enced_recordlen - 5); + + + printf("generate handshake secrets\n"); + /* + generate handshake keys + uint8_t client_write_key[32] + uint8_t server_write_key[32] + uint8_t client_write_iv[12] + uint8_t server_write_iv[12] + */ + sm2_ecdh(&client_ecdhe, &server_ecdhe_public, &server_ecdhe_public); + /* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + /* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); + /* [6] */ tls13_hkdf_extract(digest, handshake_secret, (uint8_t *)&server_ecdhe_public, handshake_secret); + /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); + /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); + /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); + /* [10] */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + //[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) + //[sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length) + //[sender] in {server, client} + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + memset(conn->server_seq_num, 0, 8); + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + memset(conn->client_seq_num, 0, 8); + /* + format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); + format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + + // recv {EncryptedExtensions} + printf("recv {EncryptedExtensions}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_encrypted_extensions(record) != 1) { + tls_send_alert(conn, TLS_alert_handshake_failure); + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // recv {CertififcateRequest*} or {Certificate} + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (type == TLS_handshake_certificate_request) { + tls_trace("recv {CertificateRequest*}\n"); + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_certificate_request(record, + &request_context, &request_context_len, + &cert_request_exts, &cert_request_extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + // 当前忽略 request_context 和 cert_request_exts + // request_context 应该为空,当前实现中不支持Post-Handshake Auth + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // recv {Certificate} + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + } else { + conn->client_certs_len = 0; + // 清空客户端签名密钥 + } + + // recv {Certificate} + tls_trace("recv {Certificate}\n"); + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_certificate(record, + &request_context, &request_context_len, + &cert_list, &cert_list_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_process_certificate_list(cert_list, cert_list_len, conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // recv {CertificateVerify} + tls_trace("recv {CertificateVerify}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_certificate_verify(record, + &server_sign_algor, &server_sig, &server_siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (server_sign_algor != TLS_sig_sm2sig_sm3) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_verify_certificate_verify(TLS_server_mode, &server_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, server_sig, server_siglen) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // use Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*) + tls13_compute_verify_data(server_handshake_traffic_secret, + &dgst_ctx, verify_data, &verify_data_len); + + + // recv {Finished} + tls_trace("recv {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_finished(record, + &server_verify_data, &server_verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (server_verify_data_len != verify_data_len + || memcmp(server_verify_data, verify_data, verify_data_len) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // generate server_application_traffic_secret + /* [12] */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + // generate client_application_traffic_secret + /* [11] */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); + + + if (conn->client_certs_len) { + int client_sign_algor; + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen; + + // send client {Certificate*} + tls_trace("send {Certificate*}\n"); + if (tls13_record_set_handshake_certificate(record, &recordlen, + NULL, 0, // certificate_request_context + conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + + + // send {CertificateVerify*} + tls_trace("send {CertificateVerify*}\n"); + client_sign_algor = TLS_sig_sm2sig_sm3; // FIXME: 应该放在conn里面 + tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); + if (tls13_record_set_handshake_certificate_verify(record, &recordlen, + client_sign_algor, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + } + + // send Client {Finished} + tls_trace("send {Finished}\n"); + tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len); + if (tls_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + + + + // update server_write_key, server_write_iv, reset server_seq_num + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + memset(conn->server_seq_num, 0, 8); + /* + format_print(stderr, 0, 0, "update server secrets\n"); + format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + + //update client_write_key, client_write_iv, reset client_seq_num + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + memset(conn->client_seq_num, 0, 8); + + /* + format_print(stderr, 0, 0, "update client secrets\n"); + format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + fprintf(stderr, "Connection established\n"); + +end: + return 1; +} + +int tls13_do_accept(TLS_CONNECT *conn) +{ + uint8_t *record = conn->record; + size_t recordlen; + uint8_t enced_record[25600]; + size_t enced_recordlen = sizeof(enced_record); + + int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + + + int protocol; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *client_exts; + size_t client_exts_len; + + uint8_t client_random[32]; + uint8_t server_random[32]; + const uint8_t *client_ciphers; + size_t client_ciphers_len; + uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t server_exts_len; + + SM2_KEY server_ecdhe; + SM2_POINT client_ecdhe_public; + SM2_KEY client_sign_key; + const BLOCK_CIPHER *cipher; + const DIGEST *digest; + DIGEST_CTX dgst_ctx; + DIGEST_CTX null_dgst_ctx; + size_t padding_len; + + + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen = sizeof(sig); + + uint8_t verify_data[32]; + size_t verify_data_len; + + const uint8_t *client_verify_data; + size_t client_verify_data_len; + size_t i; + + uint8_t client_write_key[16]; + uint8_t server_write_key[16]; + + uint8_t zeros[32] = {0}; + uint8_t psk[32] = {0}; + uint8_t early_secret[32]; + uint8_t binder_key[32]; + uint8_t handshake_secret[32]; + uint8_t client_handshake_traffic_secret[32]; + uint8_t server_handshake_traffic_secret[32]; + uint8_t client_application_traffic_secret[32]; + uint8_t server_application_traffic_secret[32]; + uint8_t master_secret[32]; + + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *cert_list; + size_t cert_list_len; + const uint8_t *cert; + size_t certlen; + + + int client_verify = 0; + if (conn->ca_certs_len) + client_verify = 1; + + + // 1. Recv ClientHello + tls_trace("recv ClientHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_client_hello(record, + &protocol, &random, + &session_id, &session_id_len, // 不支持SessionID,不做任何处理 + &client_ciphers, &client_ciphers_len, + &client_exts, &client_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (protocol != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + memcpy(client_random, random, 32); + if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, + server_ciphers, sizeof(server_ciphers)/sizeof(int), + &conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + goto end; + } + if (!client_exts) { + error_print(); + return -1; + } + tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); // 这个函数是否应该放到tls_里面? + digest_init(&dgst_ctx, digest); + null_dgst_ctx = dgst_ctx; // 在密钥导出函数中可能输入的消息为空,因此需要一个空的dgst_ctx,这里不对了,应该在tls13_derive_secret里面直接支持NULL! + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + + // 2. Send ServerHello + tls_trace("send ServerHello\n"); + rand_bytes(server_random, 32); + sm2_key_generate(&server_ecdhe); + if (tls13_process_client_hello_exts(client_exts, client_exts_len, + &server_ecdhe, &client_ecdhe_public, + server_exts, &server_exts_len, sizeof(server_exts)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + tls_record_set_protocol(record, TLS_protocol_tls12); + if (tls_record_set_handshake_server_hello(record, &recordlen, + TLS_protocol_tls12, server_random, + NULL, 0, // openssl的兼容模式在ClientHello中发送SessionID并检查在ServerHello是否返回,用`-no_middlebox`可关闭兼容模式 + conn->cipher_suite, server_exts, server_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + + sm2_ecdh(&server_ecdhe, &client_ecdhe_public, &client_ecdhe_public); + /* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + /* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); + /* 6 */ tls13_hkdf_extract(digest, handshake_secret, (uint8_t *)&client_ecdhe_public, handshake_secret); + /* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); + /* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); + /* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); + /* 10 */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + // generate server_write_key, server_write_iv, reset server_seq_num + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + memset(conn->server_seq_num, 0, 8); + // generate client_write_key, client_write_iv, reset client_seq_num + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + memset(conn->client_seq_num, 0, 8); + /* + format_print(stderr, 0, 0, "generate handshake secrets\n"); + format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); + format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + + // 3. Send {EncryptedExtensions} + tls_trace("send {EncryptedExtensions}\n"); + tls_record_set_protocol(record, TLS_protocol_tls12); + tls13_record_set_handshake_encrypted_extensions(record, &recordlen); + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + // FIXME: tls13_record_encrypt需要支持握手消息 + // tls_record_data(enced_record)[0] = TLS_handshake_encrypted_extensions; + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // send {CertificateRequest*} + if (client_verify) { + tls_trace("send {CertificateRequest*}\n"); + + // TODO: 设置certificate_request中的extensions! + if (tls13_record_set_handshake_certificate_request_default(record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + } + + // send Server {Certificate} + tls_trace("send {Certificate}\n"); + if (tls13_record_set_handshake_certificate(record, &recordlen, NULL, 0, conn->server_certs, conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // send Server {CertificateVerify} + tls_trace("send {CertificateVerify}\n"); + tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); + if (tls13_record_set_handshake_certificate_verify(record, &recordlen, + TLS_sig_sm2sig_sm3, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + // Send Server {Finished} + tls_trace("send {Finished}\n"); + + // compute server verify_data before digest_update() + tls13_compute_verify_data(server_handshake_traffic_secret, + &dgst_ctx, verify_data, &verify_data_len); + if (tls13_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + // generate server_application_traffic_secret + /* 12 */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + // Generate client_application_traffic_secret + /* 11 */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); + // 因为后面还要解密握手消息,因此client application key, iv 等到握手结束之后再更新 + + // Recv Client {Certificate*} + if (client_verify) { + tls_trace("recv {Certificate*}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + + if (tls13_record_get_handshake_certificate(record, + &request_context, &request_context_len, + &cert_list, &cert_list_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_process_certificate_list(cert_list, cert_list_len, conn->client_certs, &conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cert, &certlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + } + + // Recv client {CertificateVerify*} + if (client_verify) { + int client_sign_algor; + const uint8_t *client_sig; + size_t client_siglen; + + tls_trace("recv Client {CertificateVerify*}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + + if (tls13_record_get_handshake_certificate_verify(record, &client_sign_algor, &client_sig, &client_siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_verify_certificate_verify(TLS_client_mode, &client_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, client_sig, client_siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + } + + // 12. Recv Client {Finished} + + tls_trace("recv {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_finished(record, &client_verify_data, &client_verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if (client_verify_data_len != verify_data_len + || memcmp(client_verify_data, verify_data, verify_data_len) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + + + // 注意:OpenSSL兼容模式在此处会收发ChangeCipherSpec报文 + + + // update server_write_key, server_write_iv, reset server_seq_num + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + memset(conn->server_seq_num, 0, 8); + /* + format_print(stderr, 0, 0, "update server secrets\n"); + format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + + // update client_write_key, client_write_iv + // reset client_seq_num + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + memset(conn->client_seq_num, 0, 8); + /* + format_print(stderr, 0, 0, "update client secrets\n"); + format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); + format_print(stderr, 0, 0, "\n"); + */ + + fprintf(stderr, "Connection Established!\n\n"); + +end: + return 1; +} diff --git a/src/tls_ext.c b/src/tls_ext.c index 24402842..64b7cca3 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,966 +7,967 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* -ec_point_formats - - struct { - ECPointFormat ec_point_format_list<1..2^8-1> - } ECPointFormatList; -*/ -int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_ec_point_formats; - size_t ext_datalen; - size_t ec_point_format_list_len; - size_t i; - - if (!formats || !formats_cnt || !outlen) { - error_print(); - return -1; - } - ec_point_format_list_len = tls_uint8_size() * formats_cnt; - if (ec_point_format_list_len < 1 || ec_point_format_list_len > 255) { - error_print(); - return -1; - } - ext_datalen = tls_uint8_size() + ec_point_format_list_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint8_to_bytes((uint8_t)ec_point_format_list_len, out, outlen); - for (i = 0; i < formats_cnt; i++) { - if (!tls_ec_point_format_name(formats[i])) { - error_print(); - return -1; - } - tls_uint8_to_bytes((uint8_t)formats[i], out, outlen); - } - return 1; -} - -int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) -{ - int shared_formats[] = { TLS_point_uncompressed }; - size_t shared_formats_cnt = 0; - const uint8_t *p; - size_t len; - - if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - while (len) { - uint8_t format; - if (tls_uint8_from_bytes(&format, &p, &len) != 1) { - error_print(); - return -1; - } - if (!tls_ec_point_format_name(format)) { - error_print(); - return -1; - } - if (format == shared_formats[0]) { - shared_formats_cnt = 1; - } - } - if (!shared_formats_cnt) { - error_print(); - return -1; - } - if (tls_ec_point_formats_ext_to_bytes(shared_formats, shared_formats_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *p; - size_t len; - uint8_t format; - - if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (tls_uint8_from_bytes(&format, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (format != TLS_point_uncompressed) { - error_print(); - return -1; - } - return 1; -} - -#define TLS_MAX_SUPPORTED_GROUPS_COUNT 64 - - -/* -supported_groups - - struct { - NamedGroup named_group_list<2..2^16-1>; - } NamedGroupList; -*/ -int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_supported_groups; - size_t ext_datalen; - size_t named_group_list_len; - size_t i; - - if (!groups || !groups_cnt) { - error_print(); - return -1; - } - if (!outlen) { - error_print(); - return -1; - } - - if (groups_cnt > ((1<<16) - 1)/2) { - error_print(); - return -1; - } - named_group_list_len = tls_uint16_size() * groups_cnt; - ext_datalen = tls_uint16_size() + named_group_list_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint16_to_bytes((uint16_t)named_group_list_len, out, outlen); - for (i = 0; i < groups_cnt; i++) { - if (!tls_named_curve_name(groups[i])) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)groups[i], out, outlen); - } - return 1; -} - -int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) -{ - int shared_groups[] = { TLS_curve_sm2p256v1 }; - size_t shared_groups_cnt = 0; - const uint8_t *p; - size_t len; - - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - while (len) { - uint16_t group; - if (tls_uint16_from_bytes(&group, &p, &len) != 1) { - error_print(); - return -1; - } - if (!tls_named_curve_name(group)) { - error_print(); - return -1; - } - if (group == shared_groups[0]) { - shared_groups_cnt = 1; - } - } - if (!shared_groups_cnt) { - error_print(); - return -1; - } - if (tls_supported_groups_ext_to_bytes(shared_groups, shared_groups_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *p; - size_t len; - uint16_t group; - - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&group, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (group != TLS_curve_sm2p256v1) { - error_print(); - return -1; - } - return 1; -} - - - -#define TLS_MAX_SIGNATURE_ALGORS_COUNT 64 - -/* -signature_algorithms -signature_algorithms_cert - - struct { - SignatureScheme supported_signature_algorithms<2..2^16-2>; - } SignatureSchemeList; -*/ -int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen) -{ - size_t ext_datalen; - size_t supported_signature_algorithms_len; - size_t i; - - if (!algs || !algs_cnt || !outlen) { - error_print(); - return -1; - } - if (algs_cnt > ((1<<16) - 2)/2) { - error_print(); - return -1; - } - supported_signature_algorithms_len = tls_uint16_size() * algs_cnt; - ext_datalen = tls_uint16_size() + supported_signature_algorithms_len; - - tls_uint16_to_bytes((uint16_t)ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint16_to_bytes((uint16_t)supported_signature_algorithms_len, out, outlen); - for (i = 0; i < algs_cnt; i++) { - if (!tls_signature_scheme_name(algs[i])) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)algs[i], out, outlen); - } - return 1; -} - -int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen) -{ - int ext_type = TLS_extension_signature_algorithms; - if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, - uint8_t **out, size_t *outlen) -{ - int ext_type = TLS_extension_signature_algorithms_cert; - if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) -{ - int shared_algs[1] = { TLS_sig_sm2sig_sm3 }; - size_t shared_algs_cnt = 0; - const uint8_t *p; - size_t len; - - if (!ext_data || !ext_datalen || !outlen) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - while (len) { - uint16_t alg; - if (tls_uint16_from_bytes(&alg, &p, &len) != 1) { - error_print(); - return -1; - } - /* - // GmSSL不识别所有的算法! - if (!tls_signature_scheme_name(alg)) { - error_print(); - return -1; - } - */ - if (alg == shared_algs[0]) { - shared_algs_cnt = 1; - break; - } - } - if (!shared_algs_cnt) { - error_print(); - return -1; - } - if (tls_signature_algorithms_ext_to_bytes(shared_algs, shared_algs_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *p; - size_t len; - uint16_t alg; - - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&alg, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (alg != TLS_sig_sm2sig_sm3) { - error_print(); - return -1; - } - return 1; -} - -/* -supported_versions - - struct { - select (Handshake.msg_type) { - case client_hello: - ProtocolVersion versions<2..254>; - case server_hello: -- and HelloRetryRequest - ProtocolVersion selected_version; - }; - } SupportedVersions; -*/ - -int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, - int handshake_type, const uint8_t *data, size_t datalen) -{ - const uint8_t *versions; - size_t versions_len; - uint16_t version; - - switch (handshake_type) { - case TLS_handshake_client_hello: - format_print(fp, fmt, ind, "versions\n"); - ind += 4; - - if (tls_uint8array_from_bytes(&versions, &versions_len, &data, &datalen) != 1) { - error_print(); - return -1; - } - if (versions_len < 2 || versions_len > 254) { - error_print(); - return -1; - } - while (versions_len) { - if (tls_uint16_from_bytes(&version, &versions, &versions_len) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s (0x%04x)\n", tls_protocol_name(version), version); - } - break; - - case TLS_handshake_server_hello: - case TLS_handshake_hello_retry_request: - if (tls_uint16_from_bytes(&version, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "selected_version: %s (0x%04x)\n", tls_protocol_name(version), version); - break; - - default: - error_print(); - return -1; - } - - if (datalen) { - error_print(); - return -1; - } - return 1; -} - -int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_supported_versions; - size_t ext_datalen; - size_t i; - - if (!protos || !protos_cnt || !outlen) { - error_print(); - return -1; - } - switch (handshake_type) { - case TLS_handshake_client_hello: - { - size_t versions_len; - if (protos_cnt > 254/2) { - error_print(); - return -1; - } - versions_len = tls_uint16_size() * protos_cnt; - ext_datalen = tls_uint8_size() + versions_len; - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint8_to_bytes((uint8_t)versions_len, out, outlen); - for (i = 0; i < protos_cnt; i++) { - if (!tls_protocol_name(protos[i])) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)protos[i], out, outlen); - } - break; - } - case TLS_handshake_server_hello: - case TLS_handshake_hello_retry_request: - { - uint16_t selected_version; - if (protos_cnt > 1) { - error_print(); - return -1; - } - selected_version = protos[0]; - ext_datalen = tls_uint16_size(); - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint16_to_bytes(selected_version, out, outlen); - break; - } - default: - error_print(); - return -1; - } - return 1; -} - -int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) -{ - const uint8_t *versions; - size_t versions_len; - int selected_version = -1; - size_t len; - - if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (versions_len < 2 || versions_len > 254) { - error_print(); - return -1; - } - while (versions_len) { - uint16_t proto; - if (tls_uint16_from_bytes(&proto, &versions, &versions_len) != 1) { - error_print(); - return -1; - } - if (!tls_protocol_name(proto)) { - error_print(); - return -1; - } - if (proto == TLS_protocol_tls13) { - selected_version = proto; - } - } - if (selected_version < 0) { - error_print(); - return -1; - } - if (tls13_supported_versions_ext_to_bytes(TLS_handshake_server_hello, &selected_version, 1, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen) -{ - uint16_t selected_version; - - if (tls_uint16_from_bytes(&selected_version, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (selected_version != TLS_protocol_tls13) { - error_print(); - return -1; - } - return 1; -} - -/* -key_share - -实际上这个 key_share 也存在相同的问题 - - - struct { - NamedGroup group; - opaque key_exchange<1..2^16-1>; - } KeyShareEntry; - - struct { - KeyShareEntry client_shares<0..2^16-1>; - } KeyShareClientHello; - - struct { - KeyShareEntry server_share; - } KeyShareServerHello; -*/ - -int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen) -{ - const uint8_t *client_shares; - size_t client_shares_len; - uint16_t group; - const uint8_t *key_exchange; - size_t key_exchange_len; - - switch (handshake_type) { - case TLS_handshake_client_hello: - format_print(fp, fmt, ind, "client_shares\n"); - ind += 4; - if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "KeyShareEntry\n"); - ind += 4; - while (client_shares_len) { - if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1) goto err; - format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); - if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) goto err; - format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); - } - break; - case TLS_handshake_server_hello: - format_print(fp, fmt, ind, "server_share\n"); - ind += 4; - if (tls_uint16_from_bytes(&group, &data, &datalen) != 1) goto err; - format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); - if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &data, &datalen) != 1) goto err; - format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); - break; - default: - error_print(); - return -1; - } - if (tls_length_is_zero(datalen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t group = TLS_curve_sm2p256v1; - uint8_t key_exchange[65]; - - if (!point || !outlen) { - error_print(); - return -1; - } - sm2_point_to_uncompressed_octets(point, key_exchange); - tls_uint16_to_bytes(group, out, outlen); - tls_uint16array_to_bytes(key_exchange, 65, out, outlen); - return 1; -} - -int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - size_t ext_datalen = 0; - - if (!point || !outlen) { - error_print(); - return -1; - } - tls13_key_share_entry_to_bytes(point, NULL, &ext_datalen); - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(ext_datalen, out, outlen); - tls13_key_share_entry_to_bytes(point, out, outlen); - return 1; -} - -int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point) -{ - uint16_t group; - const uint8_t *key_exchange; - size_t key_exchange_len; - - if (!point) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&group, &ext_data, &ext_datalen) != 1 - || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (group != TLS_curve_sm2p256v1) { - error_print(); - return -1; - } - if (key_exchange_len != 65) { - error_print(); - return -1; - } - if (sm2_point_from_octets(point, key_exchange, key_exchange_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - size_t ext_datalen; - size_t client_shares_len = 0; - - if (!point || !outlen) { - error_print(); - return -1; - } - tls13_key_share_entry_to_bytes(point, NULL, &client_shares_len); - ext_datalen = tls_uint16_size() + client_shares_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(ext_datalen, out, outlen); - tls_uint16_to_bytes(client_shares_len, out, outlen); - tls13_key_share_entry_to_bytes(point, out, outlen); - return 1; -} - -int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, - const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, - uint8_t **out, size_t *outlen) -{ - const uint8_t *client_shares; - size_t client_shares_len; - uint16_t group; - const uint8_t *key_exchange; - size_t key_exchange_len; - - if (!server_ecdhe_key || !client_ecdhe_public || !outlen) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - while (client_shares_len) { - if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 - || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { - error_print(); - return -1; - } - if (!tls_named_curve_name(group)) { - error_print(); - return -1; - } - if (!key_exchange) { - error_print(); - return -1; - } - if (group == TLS_curve_sm2p256v1) { - if (key_exchange_len != 65) { - error_print(); - return -1; - } - if (sm2_point_from_octets(client_ecdhe_public, key_exchange, key_exchange_len) != 1) { - error_print(); - return -1; - } - if (tls13_server_key_share_ext_to_bytes(&server_ecdhe_key->public_key, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; - } - } - error_print(); - return -1; -} - -/* -certificate_authorities - - opaque DistinguishedName<1..2^16-1>; - - struct { - DistinguishedName authorities<3..2^16-1>; - } CertificateAuthoritiesExtension; -*/ - -int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, - uint8_t **out, size_t *outlen) -{ - int ext_type = TLS_extension_certificate_authorities; - size_t ext_datalen; - size_t authorities_len; - const uint8_t *name; - size_t namelen; - const uint8_t *p; - size_t len; - - p = ca_names; - len = ca_names_len; - authorities_len = 0; - while (len) { - if (x509_name_from_der(&name, &namelen, &p, &len) != 1) { - error_print(); - return -1; - } - tls_uint16array_to_bytes(name, namelen, NULL, &authorities_len); - } - if (authorities_len < 3 || authorities_len > (1 << 16) - 1) { - error_print(); - return -1; - } - ext_datalen = tls_uint16_size() + authorities_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(ext_datalen, out, outlen); - tls_uint16_to_bytes(authorities_len, out, outlen); - while (ca_names_len) { - x509_name_from_der(&name, &namelen, &ca_names, &ca_names_len); - tls_uint16array_to_bytes(name, namelen, out, outlen); - } - return 1; -} - - -int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) -{ - uint16_t ext_type; - if (tls_uint16_from_bytes(&ext_type, in, inlen) != 1 - || tls_uint16array_from_bytes(data, datalen, in, inlen) != 1) { - error_print(); - return -1; - } - *type = ext_type; - if (!tls_extension_name(ext_type)) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen) -{ - int type; - const uint8_t *data; - size_t datalen; - - while (extslen) { - if (tls_ext_from_bytes(&type, &data, &datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - - switch (type) { - case TLS_extension_ec_point_formats: - if (tls_process_client_ec_point_formats(data, datalen, &out, outlen) != 1) { - error_print(); - return -1; - } - break; - case TLS_extension_signature_algorithms: - if (tls_process_client_signature_algorithms(data, datalen, &out, outlen) != 1) { - error_print(); - return -1; - } - break; - case TLS_extension_supported_groups: - if (tls_process_client_supported_groups(data, datalen, &out, outlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - } - return 1; -} - -int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, - int *ec_point_format, int *supported_group, int *signature_algor) -{ - int type; - const uint8_t *data; - size_t datalen; - - *ec_point_format = -1; - *supported_group = -1; - *signature_algor = -1; - - while (extslen) { - if (tls_ext_from_bytes(&type, &data, &datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - - switch (type) { - case TLS_extension_ec_point_formats: - if (tls_process_server_ec_point_formats(data, datalen) != 1) { - error_print(); - return -1; - } - *ec_point_format = TLS_point_uncompressed; - break; - case TLS_extension_signature_algorithms: - if (tls_process_server_signature_algors(data, datalen) != 1) { - error_print(); - return -1; - } - *supported_group = TLS_curve_sm2p256v1; - break; - case TLS_extension_supported_groups: - if (tls_process_server_supported_groups(data, datalen) != 1) { - error_print(); - return -1; - } - *signature_algor = TLS_sig_sm2sig_sm3; - break; - default: - error_print(); - return -1; - } - } - return 1; -} - - - -static int tls13_server_hello_exts[] = { - TLS_extension_key_share, - TLS_extension_pre_shared_key, - TLS_extension_supported_versions, -}; - -/* -struct { - Extension extensions<0..2^16-1>; -} EncryptedExtensions; -*/ -static int tls13_encrypted_extensions_exts[] = { - TLS_extension_server_name, - TLS_extension_max_fragment_length, - TLS_extension_supported_groups, // 必须放在EE中,不能放在SH中 - TLS_extension_use_srtp, - TLS_extension_heartbeat, - TLS_extension_application_layer_protocol_negotiation, - TLS_extension_client_certificate_type, - TLS_extension_server_certificate_type, - TLS_extension_early_data, -}; - -static int tls13_certificate_exts[] = { - TLS_extension_status_request, - TLS_extension_signed_certificate_timestamp, -}; - -static int tls13_certificate_request_exts[] = { - TLS_extension_status_request, - TLS_extension_signature_algorithms, - TLS_extension_signed_certificate_timestamp, - TLS_extension_certificate_authorities, - TLS_extension_oid_filters, - TLS_extension_signature_algorithms_cert, -}; - -static int tls13_hello_retry_request_exts[] = { - TLS_extension_key_share, - TLS_extension_cookie, - TLS_extension_supported_versions, -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* +ec_point_formats + + struct { + ECPointFormat ec_point_format_list<1..2^8-1> + } ECPointFormatList; +*/ +int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_ec_point_formats; + size_t ext_datalen; + size_t ec_point_format_list_len; + size_t i; + + if (!formats || !formats_cnt || !outlen) { + error_print(); + return -1; + } + ec_point_format_list_len = tls_uint8_size() * formats_cnt; + if (ec_point_format_list_len < 1 || ec_point_format_list_len > 255) { + error_print(); + return -1; + } + ext_datalen = tls_uint8_size() + ec_point_format_list_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint8_to_bytes((uint8_t)ec_point_format_list_len, out, outlen); + for (i = 0; i < formats_cnt; i++) { + if (!tls_ec_point_format_name(formats[i])) { + error_print(); + return -1; + } + tls_uint8_to_bytes((uint8_t)formats[i], out, outlen); + } + return 1; +} + +int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + int shared_formats[] = { TLS_point_uncompressed }; + size_t shared_formats_cnt = 0; + const uint8_t *p; + size_t len; + + if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (len) { + uint8_t format; + if (tls_uint8_from_bytes(&format, &p, &len) != 1) { + error_print(); + return -1; + } + if (!tls_ec_point_format_name(format)) { + error_print(); + return -1; + } + if (format == shared_formats[0]) { + shared_formats_cnt = 1; + } + } + if (!shared_formats_cnt) { + error_print(); + return -1; + } + if (tls_ec_point_formats_ext_to_bytes(shared_formats, shared_formats_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *p; + size_t len; + uint8_t format; + + if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (tls_uint8_from_bytes(&format, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (format != TLS_point_uncompressed) { + error_print(); + return -1; + } + return 1; +} + +#define TLS_MAX_SUPPORTED_GROUPS_COUNT 64 + + +/* +supported_groups + + struct { + NamedGroup named_group_list<2..2^16-1>; + } NamedGroupList; +*/ +int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_groups; + size_t ext_datalen; + size_t named_group_list_len; + size_t i; + + if (!groups || !groups_cnt) { + error_print(); + return -1; + } + if (!outlen) { + error_print(); + return -1; + } + + if (groups_cnt > ((1<<16) - 1)/2) { + error_print(); + return -1; + } + named_group_list_len = tls_uint16_size() * groups_cnt; + ext_datalen = tls_uint16_size() + named_group_list_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)named_group_list_len, out, outlen); + for (i = 0; i < groups_cnt; i++) { + if (!tls_named_curve_name(groups[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)groups[i], out, outlen); + } + return 1; +} + +int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + int shared_groups[] = { TLS_curve_sm2p256v1 }; + size_t shared_groups_cnt = 0; + const uint8_t *p; + size_t len; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (len) { + uint16_t group; + if (tls_uint16_from_bytes(&group, &p, &len) != 1) { + error_print(); + return -1; + } + if (!tls_named_curve_name(group)) { + error_print(); + return -1; + } + if (group == shared_groups[0]) { + shared_groups_cnt = 1; + } + } + if (!shared_groups_cnt) { + error_print(); + return -1; + } + if (tls_supported_groups_ext_to_bytes(shared_groups, shared_groups_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *p; + size_t len; + uint16_t group; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&group, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (group != TLS_curve_sm2p256v1) { + error_print(); + return -1; + } + return 1; +} + + + +#define TLS_MAX_SIGNATURE_ALGORS_COUNT 64 + +/* +signature_algorithms +signature_algorithms_cert + + struct { + SignatureScheme supported_signature_algorithms<2..2^16-2>; + } SignatureSchemeList; +*/ +int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + size_t ext_datalen; + size_t supported_signature_algorithms_len; + size_t i; + + if (!algs || !algs_cnt || !outlen) { + error_print(); + return -1; + } + if (algs_cnt > ((1<<16) - 2)/2) { + error_print(); + return -1; + } + supported_signature_algorithms_len = tls_uint16_size() * algs_cnt; + ext_datalen = tls_uint16_size() + supported_signature_algorithms_len; + + tls_uint16_to_bytes((uint16_t)ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)supported_signature_algorithms_len, out, outlen); + for (i = 0; i < algs_cnt; i++) { + if (!tls_signature_scheme_name(algs[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)algs[i], out, outlen); + } + return 1; +} + +int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_signature_algorithms; + if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_signature_algorithms_cert; + if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + int shared_algs[1] = { TLS_sig_sm2sig_sm3 }; + size_t shared_algs_cnt = 0; + const uint8_t *p; + size_t len; + + if (!ext_data || !ext_datalen || !outlen) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (len) { + uint16_t alg; + if (tls_uint16_from_bytes(&alg, &p, &len) != 1) { + error_print(); + return -1; + } + /* + // GmSSL不识别所有的算法! + if (!tls_signature_scheme_name(alg)) { + error_print(); + return -1; + } + */ + if (alg == shared_algs[0]) { + shared_algs_cnt = 1; + break; + } + } + if (!shared_algs_cnt) { + error_print(); + return -1; + } + if (tls_signature_algorithms_ext_to_bytes(shared_algs, shared_algs_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *p; + size_t len; + uint16_t alg; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&alg, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (alg != TLS_sig_sm2sig_sm3) { + error_print(); + return -1; + } + return 1; +} + +/* +supported_versions + + struct { + select (Handshake.msg_type) { + case client_hello: + ProtocolVersion versions<2..254>; + case server_hello: -- and HelloRetryRequest + ProtocolVersion selected_version; + }; + } SupportedVersions; +*/ + +int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *data, size_t datalen) +{ + const uint8_t *versions; + size_t versions_len; + uint16_t version; + + switch (handshake_type) { + case TLS_handshake_client_hello: + format_print(fp, fmt, ind, "versions\n"); + ind += 4; + + if (tls_uint8array_from_bytes(&versions, &versions_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; + } + while (versions_len) { + if (tls_uint16_from_bytes(&version, &versions, &versions_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (0x%04x)\n", tls_protocol_name(version), version); + } + break; + + case TLS_handshake_server_hello: + case TLS_handshake_hello_retry_request: + if (tls_uint16_from_bytes(&version, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "selected_version: %s (0x%04x)\n", tls_protocol_name(version), version); + break; + + default: + error_print(); + return -1; + } + + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_versions; + size_t ext_datalen; + size_t i; + + if (!protos || !protos_cnt || !outlen) { + error_print(); + return -1; + } + switch (handshake_type) { + case TLS_handshake_client_hello: + { + size_t versions_len; + if (protos_cnt > 254/2) { + error_print(); + return -1; + } + versions_len = tls_uint16_size() * protos_cnt; + ext_datalen = tls_uint8_size() + versions_len; + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint8_to_bytes((uint8_t)versions_len, out, outlen); + for (i = 0; i < protos_cnt; i++) { + if (!tls_protocol_name(protos[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)protos[i], out, outlen); + } + break; + } + case TLS_handshake_server_hello: + case TLS_handshake_hello_retry_request: + { + uint16_t selected_version; + if (protos_cnt > 1) { + error_print(); + return -1; + } + selected_version = protos[0]; + ext_datalen = tls_uint16_size(); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes(selected_version, out, outlen); + break; + } + default: + error_print(); + return -1; + } + return 1; +} + +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + const uint8_t *versions; + size_t versions_len; + int selected_version = -1; + size_t len; + + if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; + } + while (versions_len) { + uint16_t proto; + if (tls_uint16_from_bytes(&proto, &versions, &versions_len) != 1) { + error_print(); + return -1; + } + if (!tls_protocol_name(proto)) { + error_print(); + return -1; + } + if (proto == TLS_protocol_tls13) { + selected_version = proto; + } + } + if (selected_version < 0) { + error_print(); + return -1; + } + if (tls13_supported_versions_ext_to_bytes(TLS_handshake_server_hello, &selected_version, 1, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen) +{ + uint16_t selected_version; + + if (tls_uint16_from_bytes(&selected_version, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (selected_version != TLS_protocol_tls13) { + error_print(); + return -1; + } + return 1; +} + +/* +key_share + +实际上这个 key_share 也存在相同的问题 + + + struct { + NamedGroup group; + opaque key_exchange<1..2^16-1>; + } KeyShareEntry; + + struct { + KeyShareEntry client_shares<0..2^16-1>; + } KeyShareClientHello; + + struct { + KeyShareEntry server_share; + } KeyShareServerHello; +*/ + +int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen) +{ + const uint8_t *client_shares; + size_t client_shares_len; + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + switch (handshake_type) { + case TLS_handshake_client_hello: + format_print(fp, fmt, ind, "client_shares\n"); + ind += 4; + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "KeyShareEntry\n"); + ind += 4; + while (client_shares_len) { + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1) goto err; + format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) goto err; + format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); + } + break; + case TLS_handshake_server_hello: + format_print(fp, fmt, ind, "server_share\n"); + ind += 4; + if (tls_uint16_from_bytes(&group, &data, &datalen) != 1) goto err; + format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &data, &datalen) != 1) goto err; + format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); + break; + default: + error_print(); + return -1; + } + if (tls_length_is_zero(datalen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t group = TLS_curve_sm2p256v1; + uint8_t key_exchange[65]; + + if (!point || !outlen) { + error_print(); + return -1; + } + sm2_point_to_uncompressed_octets(point, key_exchange); + tls_uint16_to_bytes(group, out, outlen); + tls_uint16array_to_bytes(key_exchange, 65, out, outlen); + return 1; +} + +int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen = 0; + + if (!point || !outlen) { + error_print(); + return -1; + } + tls13_key_share_entry_to_bytes(point, NULL, &ext_datalen); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls13_key_share_entry_to_bytes(point, out, outlen); + return 1; +} + +int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point) +{ + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (!point) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&group, &ext_data, &ext_datalen) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (group != TLS_curve_sm2p256v1) { + error_print(); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(point, key_exchange, key_exchange_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen; + size_t client_shares_len = 0; + + if (!point || !outlen) { + error_print(); + return -1; + } + tls13_key_share_entry_to_bytes(point, NULL, &client_shares_len); + ext_datalen = tls_uint16_size() + client_shares_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls_uint16_to_bytes(client_shares_len, out, outlen); + tls13_key_share_entry_to_bytes(point, out, outlen); + return 1; +} + +int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t **out, size_t *outlen) +{ + const uint8_t *client_shares; + size_t client_shares_len; + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (!server_ecdhe_key || !client_ecdhe_public || !outlen) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (client_shares_len) { + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { + error_print(); + return -1; + } + if (!tls_named_curve_name(group)) { + error_print(); + return -1; + } + if (!key_exchange) { + error_print(); + return -1; + } + if (group == TLS_curve_sm2p256v1) { + if (key_exchange_len != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(client_ecdhe_public, key_exchange, key_exchange_len) != 1) { + error_print(); + return -1; + } + if (tls13_server_key_share_ext_to_bytes(&server_ecdhe_key->public_key, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; + } + } + error_print(); + return -1; +} + +/* +certificate_authorities + + opaque DistinguishedName<1..2^16-1>; + + struct { + DistinguishedName authorities<3..2^16-1>; + } CertificateAuthoritiesExtension; +*/ + +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_certificate_authorities; + size_t ext_datalen; + size_t authorities_len; + const uint8_t *name; + size_t namelen; + const uint8_t *p; + size_t len; + + p = ca_names; + len = ca_names_len; + authorities_len = 0; + while (len) { + if (x509_name_from_der(&name, &namelen, &p, &len) != 1) { + error_print(); + return -1; + } + tls_uint16array_to_bytes(name, namelen, NULL, &authorities_len); + } + if (authorities_len < 3 || authorities_len > (1 << 16) - 1) { + error_print(); + return -1; + } + ext_datalen = tls_uint16_size() + authorities_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls_uint16_to_bytes(authorities_len, out, outlen); + while (ca_names_len) { + x509_name_from_der(&name, &namelen, &ca_names, &ca_names_len); + tls_uint16array_to_bytes(name, namelen, out, outlen); + } + return 1; +} + + +int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) +{ + uint16_t ext_type; + if (tls_uint16_from_bytes(&ext_type, in, inlen) != 1 + || tls_uint16array_from_bytes(data, datalen, in, inlen) != 1) { + error_print(); + return -1; + } + *type = ext_type; + if (!tls_extension_name(ext_type)) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen) +{ + int type; + const uint8_t *data; + size_t datalen; + + while (extslen) { + if (tls_ext_from_bytes(&type, &data, &datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + + switch (type) { + case TLS_extension_ec_point_formats: + if (tls_process_client_ec_point_formats(data, datalen, &out, outlen) != 1) { + error_print(); + return -1; + } + break; + case TLS_extension_signature_algorithms: + if (tls_process_client_signature_algorithms(data, datalen, &out, outlen) != 1) { + error_print(); + return -1; + } + break; + case TLS_extension_supported_groups: + if (tls_process_client_supported_groups(data, datalen, &out, outlen) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + } + return 1; +} + +int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, + int *ec_point_format, int *supported_group, int *signature_algor) +{ + int type; + const uint8_t *data; + size_t datalen; + + *ec_point_format = -1; + *supported_group = -1; + *signature_algor = -1; + + while (extslen) { + if (tls_ext_from_bytes(&type, &data, &datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + + switch (type) { + case TLS_extension_ec_point_formats: + if (tls_process_server_ec_point_formats(data, datalen) != 1) { + error_print(); + return -1; + } + *ec_point_format = TLS_point_uncompressed; + break; + case TLS_extension_signature_algorithms: + if (tls_process_server_signature_algors(data, datalen) != 1) { + error_print(); + return -1; + } + *supported_group = TLS_curve_sm2p256v1; + break; + case TLS_extension_supported_groups: + if (tls_process_server_supported_groups(data, datalen) != 1) { + error_print(); + return -1; + } + *signature_algor = TLS_sig_sm2sig_sm3; + break; + default: + error_print(); + return -1; + } + } + return 1; +} + + + +static int tls13_server_hello_exts[] = { + TLS_extension_key_share, + TLS_extension_pre_shared_key, + TLS_extension_supported_versions, +}; + +/* +struct { + Extension extensions<0..2^16-1>; +} EncryptedExtensions; +*/ +static int tls13_encrypted_extensions_exts[] = { + TLS_extension_server_name, + TLS_extension_max_fragment_length, + TLS_extension_supported_groups, // 必须放在EE中,不能放在SH中 + TLS_extension_use_srtp, + TLS_extension_heartbeat, + TLS_extension_application_layer_protocol_negotiation, + TLS_extension_client_certificate_type, + TLS_extension_server_certificate_type, + TLS_extension_early_data, +}; + +static int tls13_certificate_exts[] = { + TLS_extension_status_request, + TLS_extension_signed_certificate_timestamp, +}; + +static int tls13_certificate_request_exts[] = { + TLS_extension_status_request, + TLS_extension_signature_algorithms, + TLS_extension_signed_certificate_timestamp, + TLS_extension_certificate_authorities, + TLS_extension_oid_filters, + TLS_extension_signature_algorithms_cert, +}; + +static int tls13_hello_retry_request_exts[] = { + TLS_extension_key_share, + TLS_extension_cookie, + TLS_extension_supported_versions, +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tls_trace.c b/src/tls_trace.c index ac81bf0a..3ef00323 100644 --- a/src/tls_trace.c +++ b/src/tls_trace.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1181 +7,1182 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -const char *tls_record_type_name(int type) -{ - switch (type) { - case TLS_record_change_cipher_spec: return "ChangeCipherSpec"; - case TLS_record_alert: return "Alert"; - case TLS_record_handshake: return "Handshake"; - case TLS_record_application_data: return "ApplicationData"; - } - return NULL; -} - -const char *tls_protocol_name(int protocol) -{ - switch(protocol) { - case TLS_protocol_tlcp: return "TLCP"; - case TLS_protocol_ssl2: return "SSL2.0"; - case TLS_protocol_ssl3: return "SSL3.0"; - case TLS_protocol_tls1: return "TLS1.0"; - case TLS_protocol_tls11: return "TLS1.1"; - case TLS_protocol_tls12: return "TLS1.2"; - case TLS_protocol_tls13: return "TLS1.3"; - case TLS_protocol_dtls1: return "DTLS1.0"; - case TLS_protocol_dtls12: return "DTLS1.2"; - } - return NULL; -} - -const char *tls_cipher_suite_name(int cipher) -{ - switch (cipher) { - case TLS_cipher_null_with_null_null: return "TLS_NULL_WITH_NULL_NULL"; - case TLS_cipher_sm4_gcm_sm3: return "TLS_SM4_GCM_SM3"; - case TLS_cipher_sm4_ccm_sm3: return "TLS_SM4_CCM_SM3"; - case TLS_cipher_ecdhe_sm4_cbc_sm3: return "TLS_ECDHE_SM4_CBC_SM3"; - case TLS_cipher_ecdhe_sm4_gcm_sm3: return "TLS_ECDHE_SM4_GCM_SM3"; - case TLS_cipher_ecc_sm4_cbc_sm3: return "TLS_ECC_SM4_CBC_SM3"; - case TLS_cipher_ecc_sm4_gcm_sm3: return "TLS_ECC_SM4_GCM_SM3"; - case TLS_cipher_ibsdh_sm4_cbc_sm3: return "TLS_IBSDH_SM4_CBC_SM3"; - case TLS_cipher_ibsdh_sm4_gcm_sm3: return "TLS_IBSDH_SM4_GCM_SM3"; - case TLS_cipher_ibc_sm4_cbc_sm3: return "TLS_IBC_SM4_CBC_SM3"; - case TLS_cipher_ibc_sm4_gcm_sm3: return "TLS_IBC_SM4_GCM_SM3"; - case TLS_cipher_rsa_sm4_cbc_sm3: return "TLS_RSA_SM4_CBC_SM3"; - case TLS_cipher_rsa_sm4_gcm_sm3: return "TLS_RSA_SM4_GCM_SM3"; - case TLS_cipher_rsa_sm4_cbc_sha256: return "TLS_RSA_SM4_CBC_SHA256"; - case TLS_cipher_rsa_sm4_gcm_sha256: return "TLS_RSA_SM4_GCM_SHA256"; - case TLS_cipher_aes_128_gcm_sha256: return "TLS_AES_128_GCM_SHA256"; - case TLS_cipher_aes_256_gcm_sha384: return "TLS_AES_256_GCM_SHA384"; - case TLS_cipher_chacha20_poly1305_sha256: return "TLS_CHACHA20_POLY1305_SHA256"; - case TLS_cipher_aes_128_ccm_sha256: return "TLS_AES_128_CCM_SHA256"; - case TLS_cipher_aes_128_ccm_8_sha256: return "TLS_AES_128_CCM_8_SHA256"; - case TLS_cipher_empty_renegotiation_info_scsv: return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - } - return NULL; -} - -const char *tls_compression_method_name(int meth) -{ - switch (meth) { - case 0: return "no_compression"; - } - return NULL; -} - -const char *tls_extension_name(int ext) -{ - switch (ext) { - case TLS_extension_server_name: return "server_name"; - case TLS_extension_max_fragment_length: return "max_fragment_length"; - case TLS_extension_client_certificate_url: return "client_certificate_url"; - case TLS_extension_trusted_ca_keys: return "trusted_ca_keys"; - case TLS_extension_truncated_hmac: return "truncated_hmac"; - case TLS_extension_status_request: return "status_request"; - case TLS_extension_user_mapping: return "user_mapping"; - case TLS_extension_client_authz: return "client_authz"; - case TLS_extension_server_authz: return "server_authz"; - case TLS_extension_cert_type: return "cert_type"; - case TLS_extension_supported_groups: return "supported_groups"; - case TLS_extension_ec_point_formats: return "ec_point_formats"; - case TLS_extension_srp: return "srp"; - case TLS_extension_signature_algorithms: return "signature_algorithms"; - case TLS_extension_use_srtp: return "use_srtp"; - case TLS_extension_heartbeat: return "heartbeat"; - case TLS_extension_application_layer_protocol_negotiation: return "application_layer_protocol_negotiation"; - case TLS_extension_status_request_v2: return "status_request_v2"; - case TLS_extension_signed_certificate_timestamp: return "signed_certificate_timestamp"; - case TLS_extension_client_certificate_type: return "client_certificate_type"; - case TLS_extension_server_certificate_type: return "server_certificate_type"; - case TLS_extension_padding: return "padding"; - case TLS_extension_encrypt_then_mac: return "encrypt_then_mac"; - case TLS_extension_extended_master_secret: return "extended_master_secret"; - case TLS_extension_token_binding: return "token_binding"; - case TLS_extension_cached_info: return "cached_info"; - case TLS_extension_tls_lts: return "tls_lts"; - case TLS_extension_compress_certificate: return "compress_certificate"; - case TLS_extension_record_size_limit: return "record_size_limit"; - case TLS_extension_pwd_protect: return "pwd_protect"; - case TLS_extension_pwd_clear: return "pwd_clear"; - case TLS_extension_password_salt: return "password_salt"; - case TLS_extension_ticket_pinning: return "ticket_pinning"; - case TLS_extension_tls_cert_with_extern_psk: return "tls_cert_with_extern_psk"; - case TLS_extension_delegated_credentials: return "delegated_credentials"; - case TLS_extension_session_ticket: return "session_ticket"; - case TLS_extension_TLMSP: return "TLMSP"; - case TLS_extension_TLMSP_proxying: return "TLMSP_proxying"; - case TLS_extension_TLMSP_delegate: return "TLMSP_delegate"; - case TLS_extension_supported_ekt_ciphers: return "supported_ekt_ciphers"; - case TLS_extension_pre_shared_key: return "pre_shared_key"; - case TLS_extension_early_data: return "early_data"; - case TLS_extension_supported_versions: return "supported_versions"; - case TLS_extension_cookie: return "cookie"; - case TLS_extension_psk_key_exchange_modes: return "psk_key_exchange_modes"; - case TLS_extension_certificate_authorities: return "certificate_authorities"; - case TLS_extension_oid_filters: return "oid_filters"; - case TLS_extension_post_handshake_auth: return "post_handshake_auth"; - case TLS_extension_signature_algorithms_cert: return "signature_algorithms_cert"; - case TLS_extension_key_share: return "key_share"; - case TLS_extension_transparency_info: return "transparency_info"; - case TLS_extension_connection_id: return "connection_id"; - case TLS_extension_external_id_hash: return "external_id_hash"; - case TLS_extension_external_session_id: return "external_session_id"; - case TLS_extension_quic_transport_parameters: return "quic_transport_parameters"; - case TLS_extension_ticket_request: return "ticket_request"; - case TLS_extension_renegotiation_info: return "renegotiation_info"; - }; - return NULL; -} - -const char *tls_cert_type_name(int type) -{ - switch (type) { - case TLS_cert_type_rsa_sign: return "rsa_sign"; - case TLS_cert_type_dss_sign: return "dss_sign"; - case TLS_cert_type_rsa_fixed_dh: return "rsa_fixed_dh"; - case TLS_cert_type_dss_fixed_dh: return "dss_fixed_dh"; - case TLS_cert_type_rsa_ephemeral_dh_RESERVED: return "rsa_ephemeral_dh_RESERVED"; - case TLS_cert_type_dss_ephemeral_dh_RESERVED: return "dss_ephemeral_dh_RESERVED"; - case TLS_cert_type_fortezza_dms_RESERVED: return "fortezza_dms_RESERVED"; - case TLS_cert_type_ecdsa_sign: return "ecdsa_sign"; - case TLS_cert_type_rsa_fixed_ecdh: return "rsa_fixed_ecdh_DEPRECATED"; - case TLS_cert_type_ecdsa_fixed_ecdh: return "ecdsa_fixed_ecdh_DEPRECATED"; - case TLS_cert_type_gost_sign256: return "gost_sign256"; - case TLS_cert_type_gost_sign512: return "gost_sign512"; - case TLS_cert_type_ibc_params: return "ibc_params"; - } - return NULL; -} - -const char *tls_handshake_type_name(int type) -{ - switch (type) { - case TLS_handshake_hello_request: return "HelloRequest"; - case TLS_handshake_client_hello: return "ClientHello"; - case TLS_handshake_server_hello: return "ServerHello"; - case TLS_handshake_hello_verify_request: return "HelloVerifyRequest"; - case TLS_handshake_new_session_ticket: return "NewSessionTicket"; - case TLS_handshake_end_of_early_data: return "EndOfEarlyData"; - case TLS_handshake_hello_retry_request: return "HelloRetryRequest"; - case TLS_handshake_encrypted_extensions: return "EncryptedExtensions"; - case TLS_handshake_certificate: return "Certificate"; - case TLS_handshake_server_key_exchange: return "ServerKeyExchange"; - case TLS_handshake_certificate_request: return "CertificateRequest"; - case TLS_handshake_server_hello_done: return "ServerHelloDone"; - case TLS_handshake_certificate_verify: return "CertificateVerify"; - case TLS_handshake_client_key_exchange: return "ClientKeyExchange"; - case TLS_handshake_finished: return "Finished"; - case TLS_handshake_certificate_url: return "CertificateUrl"; - case TLS_handshake_certificate_status: return "CertificateStatus"; - case TLS_handshake_supplemental_data: return "SupplementalData"; - case TLS_handshake_key_update: return "KeyUpdate"; - case TLS_handshake_compressed_certificate: return "CompressedCertificate"; - case TLS_handshake_ekt_key: return "EktKey"; - case TLS_handshake_message_hash: return "MessageHash"; - } - return NULL; -} - -const char *tls_alert_level_name(int level) -{ - switch (level) { - case TLS_alert_level_warning: return "warning"; - case TLS_alert_level_fatal: return "fatal"; - } - error_print_msg("unknown alert level %d\n", level); - return NULL; -} - -const char *tls_alert_description_text(int description) -{ - switch (description) { - case TLS_alert_close_notify: return "close_notify"; - case TLS_alert_unexpected_message: return "unexpected_message"; - case TLS_alert_bad_record_mac: return "bad_record_mac"; - case TLS_alert_decryption_failed: return "decryption_failed"; - case TLS_alert_record_overflow: return "record_overflow"; - case TLS_alert_decompression_failure: return "decompression_failure"; - case TLS_alert_handshake_failure: return "handshake_failure"; - case TLS_alert_no_certificate: return "no_certificate_RESERVED"; - case TLS_alert_bad_certificate: return "bad_certificate"; - case TLS_alert_unsupported_certificate: return "unsupported_certificate"; - case TLS_alert_certificate_revoked: return "certificate_revoked"; - case TLS_alert_certificate_expired: return "certificate_expired"; - case TLS_alert_certificate_unknown: return "certificate_unknown"; - case TLS_alert_illegal_parameter: return "illegal_parameter"; - case TLS_alert_unknown_ca: return "unknown_ca"; - case TLS_alert_access_denied: return "access_denied"; - case TLS_alert_decode_error: return "decode_error"; - case TLS_alert_decrypt_error: return "decrypt_error"; - case TLS_alert_export_restriction: return "export_restriction_RESERVED"; - case TLS_alert_protocol_version: return "protocol_version"; - case TLS_alert_insufficient_security: return "insufficient_security"; - case TLS_alert_internal_error: return "internal_error"; - case TLS_alert_user_canceled: return "user_canceled"; - case TLS_alert_no_renegotiation: return "no_renegotiation"; - case TLS_alert_unsupported_extension: return "unsupported_extension"; - case TLS_alert_unsupported_site2site: return "unsupported_site2site"; - case TLS_alert_no_area: return "no_area"; - case TLS_alert_unsupported_areatype: return "unsupported_areatype"; - case TLS_alert_bad_ibcparam: return "bad_ibcparam"; - case TLS_alert_unsupported_ibcparam: return "unsupported_ibcparam"; - case TLS_alert_identity_need: return "identity_need"; - } - error_print_msg("unknown alert description %d", description); - return NULL; -} - -const char *tls_change_cipher_spec_text(int change_cipher_spec) -{ - switch (change_cipher_spec) { - case TLS_change_cipher_spec: return "change_cipher_spec"; - } - return NULL; -} - -const char *tls_ec_point_format_name(int format) -{ - switch (format) { - case TLS_point_uncompressed: return "uncompressed"; - case TLS_point_ansix962_compressed_prime: return "compressed_prime"; - case TLS_point_ansix962_compressed_char2: return "compressed_char2"; - } - return NULL; -} - -const char *tls_curve_type_name(int type) -{ - switch (type) { - case TLS_curve_type_explicit_prime: return "explicit_prime"; - case TLS_curve_type_explicit_char2: return "explicit_char2"; - case TLS_curve_type_named_curve: return "named_curve"; - } - return NULL; -} - - -// FIXME: 是否应该将函数名改为 tls_curve_name() 这样和 TLS_curve_xxx 保持一致 -const char *tls_named_curve_name(int curve) -{ - switch (curve) { - case TLS_curve_secp256k1: return "secp256k1"; - case TLS_curve_secp256r1: return "secp256r1"; - case TLS_curve_secp384r1: return "secp384r1"; - case TLS_curve_secp521r1: return "secp521r1"; - case TLS_curve_brainpoolp256r1: return "brainpoolp256r1"; - case TLS_curve_brainpoolp384r1: return "brainpoolp384r1"; - case TLS_curve_brainpoolp512r1: return "brainpoolp512r1"; - case TLS_curve_x25519: return "x25519"; - case TLS_curve_x448: return "x448"; - case TLS_curve_brainpoolp256r1tls13: return "brainpoolp256r1tls13"; - case TLS_curve_brainpoolp384r1tls13: return "brainpoolp384r1tls13"; - case TLS_curve_brainpoolp512r1tls13: return "brainpoolp512r1tls13"; - case TLS_curve_sm2p256v1: return "sm2p256v1"; - } - return NULL; -} - -const char *tls_signature_scheme_name(int scheme) -{ - switch (scheme) { - case TLS_sig_rsa_pkcs1_sha1: return "rsa_pkcs1_sha1"; - case TLS_sig_ecdsa_sha1: return "ecdsa_sha1"; - case TLS_sig_rsa_pkcs1_sha256: return "rsa_pkcs1_sha256"; - case TLS_sig_ecdsa_secp256r1_sha256: return "ecdsa_secp256r1_sha256"; - case TLS_sig_rsa_pkcs1_sha256_legacy: return "rsa_pkcs1_sha256_legacy"; - case TLS_sig_rsa_pkcs1_sha384: return "rsa_pkcs1_sha384"; - case TLS_sig_ecdsa_secp384r1_sha384: return "ecdsa_secp384r1_sha384"; - case TLS_sig_rsa_pkcs1_sha384_legacy: return "rsa_pkcs1_sha384_legacy"; - case TLS_sig_rsa_pkcs1_sha512: return "rsa_pkcs1_sha512"; - case TLS_sig_ecdsa_secp521r1_sha512: return "ecdsa_secp521r1_sha512"; - case TLS_sig_rsa_pkcs1_sha512_legacy: return "rsa_pkcs1_sha512_legacy"; - case TLS_sig_sm2sig_sm3: return "sm2sig_sm3"; - case TLS_sig_rsa_pss_rsae_sha256: return "rsa_pss_rsae_sha256"; - case TLS_sig_rsa_pss_rsae_sha384: return "rsa_pss_rsae_sha384"; - case TLS_sig_rsa_pss_rsae_sha512: return "rsa_pss_rsae_sha512"; - case TLS_sig_ed25519: return "ed25519"; - case TLS_sig_ed448: return "ed448"; - case TLS_sig_rsa_pss_pss_sha256: return "rsa_pss_pss_sha256"; - case TLS_sig_rsa_pss_pss_sha384: return "rsa_pss_pss_sha384"; - case TLS_sig_rsa_pss_pss_sha512: return "rsa_pss_pss_sha512"; - case TLS_sig_ecdsa_brainpoolP256r1tls13_sha256: return "ecdsa_brainpoolP256r1tls13_sha256"; - case TLS_sig_ecdsa_brainpoolP384r1tls13_sha384: return "ecdsa_brainpoolP384r1tls13_sha384"; - case TLS_sig_ecdsa_brainpoolP512r1tls13_sha512: return "ecdsa_brainpoolP512r1tls13_sha512"; - } - return NULL; -} - -int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent) -{ - int i; - time_t gmt_unix_time = 0; - const uint8_t *cp = random; - size_t len = 4; - - tls_uint32_from_bytes((uint32_t *)&gmt_unix_time, &cp, &len); - format_print(fp, format, indent, "Random\n"); - indent += 4; - format_print(fp, format, indent, "gmt_unix_time : %s", ctime(&gmt_unix_time)); - format_bytes(fp, format, indent, "random", random + 4, 28); - return 1; -} - -int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], int format, int indent) -{ - int protocol = ((int)pre_master_secret[0] << 8) | pre_master_secret[1]; - format_print(fp, format, indent, "PreMasterSecret\n"); - indent += 4; - format_print(fp, format, indent, "protocol : %s\n", tls_protocol_name(protocol)); - format_bytes(fp, format, indent, "pre_master_secret", pre_master_secret, 48); - return 1; -} - -// supported_versions 的格式还受到 handshake_type 影响 -int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, int format, int indent) -{ - const uint8_t *p; - size_t len; - - format_print(fp, format, indent, "%s (%d)\n", tls_extension_name(type), type); - indent += 4; - - switch (type) { - case TLS_extension_supported_versions: - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1 - || len % 2) { - error_print(); - return -1; - } - while (len) { - uint16_t proto; - tls_uint16_from_bytes(&proto, &p, &len); - format_print(fp, format, indent, "%s (0x%04x)\n", - tls_protocol_name(proto), proto); - } - break; - case TLS_extension_supported_groups: - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || datalen - || len % 2) { - error_print(); - return -1; - } - while (len) { - uint16_t curve; - tls_uint16_from_bytes(&curve, &p, &len); - format_print(fp, format, indent, "%s (%d)\n", - tls_named_curve_name(curve), curve); - } - break; - case TLS_extension_ec_point_formats: - if (tls_uint8array_from_bytes(&p, &len, &data, &datalen) != 1 - || datalen) { - error_print(); - return -1; - } - while (len) { - uint8_t point_form; - tls_uint8_from_bytes(&point_form, &p, &len); - format_print(fp, format, indent, "%s (%d)\n", - tls_ec_point_format_name(point_form), point_form); - } - break; - case TLS_extension_signature_algorithms: - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || datalen - || len % 2) { - error_print(); - return -1; - } - while (len) { - uint16_t sig_alg; - tls_uint16_from_bytes(&sig_alg, &p, &len); - format_print(fp, format, indent, "%s (0x%04x)\n", - tls_signature_scheme_name(sig_alg), sig_alg); - } - break; - case TLS_extension_key_share: - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || datalen) { - error_print(); - return -1; - } - while (len) { - uint16_t group; - const uint8_t *key_exch; - size_t key_exch_len; - - if (tls_uint16_from_bytes(&group, &p, &len) != 1 - || tls_uint16array_from_bytes(&key_exch, &key_exch_len, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent, "group: %s (%d)\n", tls_named_curve_name(group), group); - format_bytes(fp, format, indent, "key_exchange", key_exch, key_exch_len); - } - break; - - default: - format_bytes(fp, format, indent, "raw_data", data, datalen); - } - return 1; -} - -int tls13_extension_print(FILE *fp, int fmt, int ind, - int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen) -{ - switch (ext_type) { - case TLS_extension_supported_groups: - case TLS_extension_ec_point_formats: - case TLS_extension_signature_algorithms: - return tls_extension_print(fp, ext_type, ext_data, ext_datalen, fmt, ind); - } - - format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); - ind += 4; - - switch (ext_type) { - case TLS_extension_supported_versions: - tls13_supported_versions_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); - break; - case TLS_extension_key_share: - tls13_key_share_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); - break; - default: - format_bytes(fp, fmt, ind, "raw_data", ext_data, ext_datalen); - } - return 1; -} - -int tls13_extensions_print(FILE *fp, int fmt, int ind, - int handshake_type, const uint8_t *exts, size_t extslen) -{ - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - if (!exts) { - format_print(fp, fmt, ind, "Extensions: (null)\n"); - return 1; - } - - format_print(fp, fmt, ind, "Extensions\n"); - ind += 4; - - while (extslen > 0) { - if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 - || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - if (tls13_extension_print(fp, fmt, ind, handshake_type, ext_type, ext_data, ext_datalen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int tls_extensions_print(FILE *fp, const uint8_t *exts, size_t extslen, int format, int indent) -{ - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - format_print(fp, format, indent, "Extensions\n"); - indent += 4; - while (extslen > 0) { - if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 - || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - if (tls_extension_print(fp, ext_type, ext_data, ext_datalen, format, indent) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - format_print(fp, format, indent, "HelloRequest\n"); - indent += 4; - if (data || datalen > 0) { - error_print(); - return -1; - } - return 1; -} - -int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - int ret = -1; - uint16_t protocol; - const uint8_t *random; - const uint8_t *session_id; - const uint8_t *cipher_suites; - const uint8_t *comp_meths; - const uint8_t *exts; - size_t session_id_len, cipher_suites_len, comp_meths_len, exts_len; - size_t i; - - format_print(fp, format, indent, "ClientHello\n"); indent += 4; - if (tls_uint16_from_bytes((uint16_t *)&protocol, &data, &datalen) != 1) goto end; - format_print(fp, format, indent, "Version: %s (%d.%d)\n", - tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); - if (tls_array_from_bytes(&random, 32, &data, &datalen) != 1) goto end; - tls_random_print(fp, random, format, indent); - if (tls_uint8array_from_bytes(&session_id, &session_id_len, &data, &datalen) != 1) goto end; - format_bytes(fp, format, indent, "SessionID", session_id, session_id_len); - if (tls_uint16array_from_bytes(&cipher_suites, &cipher_suites_len, &data, &datalen) != 1) goto end; - format_print(fp, format, indent, "CipherSuites\n"); - while (cipher_suites_len >= 2) { - uint16_t cipher; - if (tls_uint16_from_bytes(&cipher, &cipher_suites, &cipher_suites_len) != 1) goto end; - format_print(fp, format, indent + 4, "%s (0x%04x)\n", - tls_cipher_suite_name(cipher), cipher); - } - if (cipher_suites_len) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(&comp_meths, &comp_meths_len, &data, &datalen) != 1) goto end; - format_print(fp, format, indent, "CompressionMethods\n"); - for (i = 0; i < comp_meths_len; i++) { - format_print(fp, format, indent + 4, "%s (%d)\n", - tls_compression_method_name(comp_meths[i]), comp_meths[i]); - } - if (datalen > 0) { - if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto end; - //tls_extensions_print(fp, exts, exts_len, format, indent); - tls13_extensions_print(fp, format, indent, TLS_handshake_client_hello, exts, exts_len); - } - if (datalen > 0) { - error_print(); - return -1; - } - ret = 1; -end: - return ret; -} - -int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - int ret = -1; - uint16_t protocol; - const uint8_t *random; - const uint8_t *session_id; - uint16_t cipher_suite; - uint8_t comp_meth; - const uint8_t *exts; - size_t session_id_len, cipher_suites_len, comp_meths_len, exts_len; - size_t i; - - format_print(fp, format, indent, "ServerHello\n"); indent += 4; - if (tls_uint16_from_bytes(&protocol, &data, &datalen) != 1) goto bad; - format_print(fp, format, indent, "Version: %s (%d.%d)\n", - tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); - if (tls_array_from_bytes(&random, 32, &data, &datalen) != 1) goto bad; - tls_random_print(fp, random, format, indent); - if (tls_uint8array_from_bytes(&session_id, &session_id_len, &data, &datalen) != 1) goto bad; - format_bytes(fp, format, indent, "SessionID", session_id, session_id_len); - if (tls_uint16_from_bytes(&cipher_suite, &data, &datalen) != 1) goto bad; - format_print(fp, format, indent, "CipherSuite: %s (0x%04x)\n", - tls_cipher_suite_name(cipher_suite), cipher_suite); - if (tls_uint8_from_bytes(&comp_meth, &data, &datalen) != 1) goto bad; - format_print(fp, format, indent, "CompressionMethod: %s (%d)\n", - tls_compression_method_name(comp_meth), comp_meth); - if (datalen > 0) { - if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad; - //format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print - //tls_extensions_print(fp, exts, exts_len, format, indent); - tls13_extensions_print(fp, format, indent, TLS_handshake_server_hello, exts, exts_len); - } - return 1; -bad: - error_print(); - return -1; -} - -int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - int ret; - const uint8_t *certs; - size_t certslen; - const uint8_t *der; - size_t derlen; - - if (tls_uint24array_from_bytes(&certs, &certslen, &data, &datalen) != 1) { - error_print(); - return -1; - } - while (certslen > 0) { - if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - (void)x509_cert_print(fp, format, indent, "Certificate", der, derlen); - (void)x509_cert_to_pem(der, derlen, fp); - } - - if (datalen) { - error_print(); - return -1; - } - return 1; -} - -int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, - int format, int indent) -{ - uint8_t curve_type; - uint16_t curve; - const uint8_t *octets; - size_t octetslen; - uint16_t sig_alg; - const uint8_t *sig; - size_t siglen; - - format_print(fp, format, indent, "ServerKeyExchange\n"); - indent += 4; - format_print(fp, format, indent, "ServerECDHParams\n"); - format_print(fp, format, indent + 4, "curve_params\n"); - if (tls_uint8_from_bytes(&curve_type, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent + 8, "curve_type: %s (%d)\n", - tls_curve_type_name(curve_type), curve_type); - if (tls_uint16_from_bytes(&curve, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent + 8, "named_curve: %s (%d)\n", - tls_named_curve_name(curve), curve); - if (tls_uint8array_from_bytes(&octets, &octetslen, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, format, indent + 4, "point", octets, octetslen); - if (tls_uint16_from_bytes(&sig_alg, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent, "SignatureScheme: %s (0x%04x)\n", - tls_signature_scheme_name(sig_alg), sig_alg); - if (tls_uint16array_from_bytes(&sig, &siglen, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, format, indent, "Siganture", sig, siglen); - if (datalen > 0) { - error_print(); - return -1; - } - return 1; -} - -int tls_server_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - int cipher_suite = (format >> 8) & 0xffff; - - switch (cipher_suite) { - case TLS_cipher_ecc_sm4_cbc_sm3: - case TLS_cipher_ecc_sm4_gcm_sm3: - if (tlcp_server_key_exchange_pke_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - if (tls_server_key_exchange_ecdhe_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int tls_certificate_subjects_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *a; - size_t alen; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - const uint8_t *name; - size_t namelen; - - if (tls_uint16array_from_bytes(&a, &alen, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (asn1_sequence_from_der(&name, &namelen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - x509_name_print(fp, fmt, ind, "DistinguishedName", name, namelen); - } - return 1; -} - -int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - const uint8_t *cert_types; - const uint8_t *ca_names; - size_t cert_types_len, ca_names_len, i; - - format_print(fp, format, indent, "CertificateRequest\n"); indent += 4; - if (tls_uint8array_from_bytes(&cert_types, &cert_types_len, &data, &datalen) != 1) goto bad; - format_print(fp, format, indent, "cert_types\n"); - while (cert_types_len--) { - int cert_type = *cert_types++; - format_print(fp, format, indent + 4, "%s (%d)\n", tls_cert_type_name(cert_type), cert_type); - } - if (tls_uint16array_from_bytes(&ca_names, &ca_names_len, &data, &datalen) != 1) goto bad; - tls_certificate_subjects_print(fp, format, indent, "CAnames", ca_names, ca_names_len); - - return 1; -bad: - error_print(); - return -1; -} - -int tls_server_hello_done_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - if (datalen > 0) { - error_print(); - return -1; - } - return 1; -} - -int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - const uint8_t *enced_pms; - size_t enced_pms_len; - - if (tls_uint16array_from_bytes(&enced_pms, &enced_pms_len, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, format, indent, "EncryptedPreMasterSecret", enced_pms, enced_pms_len); - return 1; -} - -int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, - int format, int indent) -{ - const uint8_t *octets; - size_t octetslen; - - format_print(fp, format, indent, "ClientKeyExchange\n"); - indent += 4; - if (tls_uint8array_from_bytes(&octets, &octetslen, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_bytes(fp, format, indent, "ecdh_Yc", octets, octetslen); - if (datalen > 0) { - error_print(); - return -1; - } - return 1; -} - -int tls_client_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - int cipher_suite = (format >> 8) & 0xffff; - switch (cipher_suite) { - case TLS_cipher_ecc_sm4_cbc_sm3: - case TLS_cipher_ecc_sm4_gcm_sm3: - if (tls_client_key_exchange_pke_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_cipher_ecdhe_sm4_cbc_sm3: - case TLS_cipher_ecdhe_sm4_gcm_sm3: - if (tls_client_key_exchange_ecdhe_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int tls_certificate_verify_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - format_print(fp, format, indent, "CertificateVerify\n"); - format_bytes(fp, format, indent + 4, "Signature", data, datalen); - return 1; -} - -int tls_finished_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - format_print(fp, format, indent, "Finished\n"); - indent += 4; - format_bytes(fp, format, indent, "verify_data", data, datalen); - return 1; -} - -int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) -{ - const uint8_t *p = handshake; - size_t len = handshake_len; - uint8_t type; - const uint8_t *data; - size_t datalen; - - if (tls_uint8_from_bytes(&type, &handshake, &handshake_len) != 1 - || tls_uint24array_from_bytes(&data, &datalen, &handshake, &handshake_len) != 1 - || tls_length_is_zero(handshake_len) != 1) { - error_print(); - return -1; - } - - switch (type) { - case TLS_handshake_certificate: - case TLS_handshake_certificate_request: - case TLS_handshake_certificate_verify: - format_print(fp, fmt, ind, "Handshake\n"); - ind += 4; - format_print(fp, fmt, ind, "Type: %s (%d)\n", tls_handshake_type_name(type), type); - format_print(fp, fmt, ind, "Length: %zu\n", datalen); - break; - } - switch (type) { - case TLS_handshake_certificate: - return tls13_certificate_print(fp, fmt, ind, data, datalen); - case TLS_handshake_certificate_request: - return tls13_certificate_request_print(fp, fmt, ind, data, datalen); - case TLS_handshake_certificate_verify: - return tls13_certificate_verify_print(fp, fmt, ind, data, datalen); - } - - return tls_handshake_print(fp, p, len, fmt, ind); -} - -// 这个是有问题的,因为TLS 1.3的证书和TLS 1.2是不一样的 -int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent) -{ - const uint8_t *cp = handshake; - uint8_t type; - const uint8_t *data; - size_t datalen = 0; - - format_print(fp, format, indent, "Handshake\n"); - indent += 4; - - if (tls_uint8_from_bytes(&type, &cp, &handshakelen) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent, "Type: %s (%d)\n", tls_handshake_type_name(type), type); - if (tls_uint24_from_bytes((uint24_t *)&datalen, &cp, &handshakelen) != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent, "Length: %zu\n", datalen); - - if (tls_array_from_bytes(&data, datalen, &cp, &handshakelen) != 1) { - error_print(); - return -1; - } - switch (type) { - case TLS_handshake_hello_request: - if (tls_hello_request_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_client_hello: - if (tls_client_hello_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_server_hello: - if (tls_server_hello_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_encrypted_extensions: - tls13_encrypted_extensions_print(fp, format, indent, data, datalen); - break; - - case TLS_handshake_certificate: - if (tls_certificate_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_server_key_exchange: - if (tls_server_key_exchange_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_certificate_request: - if (tls_certificate_request_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_server_hello_done: - if (tls_server_hello_done_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_client_key_exchange: - if (tls_client_key_exchange_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_certificate_verify: - if (tls_certificate_verify_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - case TLS_handshake_finished: - if (tls_finished_print(fp, data, datalen, format, indent) != 1) - { error_print(); return -1; } break; - default: - error_print(); - return -1; - } - return 1; -} - -int tls_alert_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - if (datalen != 2) { - error_print(); - return -1; - } - format_print(fp, format, indent, "Alert:\n"); - indent += 4; - format_print(fp, format, indent, "Level: %s (%d)\n", tls_alert_level_name(data[0]), data[0]); - format_print(fp, format, indent, "Reason: %s (%d)\n", tls_alert_description_text(data[1]), data[1]); - return 1; -} - -int tls_change_cipher_spec_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - if (datalen != 1) { - error_print(); - return -1; - } - format_print(fp, format, indent, "ChangeCipherSpec\n"); - indent += 4; - format_print(fp, format, indent, "type : %s (%d)\n", tls_change_cipher_spec_text(data[0]), data[0]); - return 1; -} - -int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) -{ - format_bytes(fp, format, indent, "ApplicationData", data, datalen); - return 1; -} - -int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen) -{ - const uint8_t *data; - size_t datalen; - int protocol; - - format |= TLS_cipher_sm4_gcm_sm3 << 8; - - if (!fp || !record || recordlen < 5) { - error_print(); - return -1; - } - protocol = tls_record_protocol(record); - format_print(fp, format, indent, "Record\n"); indent += 4; - format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); - format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); - format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); - - data = tls_record_data(record); - datalen = tls_record_data_length(record); - - if (recordlen < tls_record_length(record)) { - error_print(); - return -1; - } - - // 最高字节设置后强制打印记录原始数据 - if (format >> 24) { - format_bytes(fp, format, indent, "Data", data, datalen); - fprintf(fp, "\n"); - return 1; - } - - switch (record[0]) { - case TLS_record_handshake: - tls13_handshake_print(fp, format, indent, data, datalen); - break; - case TLS_record_alert: - if (tls_alert_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_change_cipher_spec: - if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_application_data: - if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - - recordlen -= tls_record_length(record); - if (recordlen) { - format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); - } - - fprintf(fp, "\n"); - return 1; - -} - - -// 仅从record数据是不能判断这个record是TLS 1.2还是TLS 1.3 -// 不同协议上,同名的握手消息,其格式也是不一样的。这真是太恶心了!!!! - -// 当消息为ClientKeyExchange,ServerKeyExchange,需要密码套件中的密钥交换算法信息 -// 当消息为加密的Finished,记录类型为Handshake,但是记录负载数据中没有Handshake头 -// 注意:这里的recordlen 是冗余的,要容忍recordlen的错误 -// -// supported_versions 的格式由handshake_type 是否为ClientHello, ServerHello 决定 -// record中是包含这个信息的,但是在exts中没有这个信息 -int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) -{ - const uint8_t *data; - size_t datalen; - int protocol; - - if (!fp || !record || recordlen < 5) { - error_print(); - return -1; - } - protocol = tls_record_protocol(record); - format_print(fp, format, indent, "Record\n"); indent += 4; - format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); - format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); - format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); - - data = tls_record_data(record); - datalen = tls_record_data_length(record); - - if (recordlen < tls_record_length(record)) { - error_print(); - return -1; - } - - // 最高字节设置后强制打印记录原始数据 - if (format >> 24) { - format_bytes(fp, format, indent, "Data", data, datalen); - fprintf(fp, "\n"); - return 1; - } - - switch (record[0]) { - case TLS_record_handshake: - if (tls_handshake_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_alert: - if (tls_alert_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_change_cipher_spec: - if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_application_data: - if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - - recordlen -= tls_record_length(record); - if (recordlen) { - format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); - } - - fprintf(fp, "\n"); - return 1; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -} - -int tls_secrets_print(FILE *fp, - const uint8_t *pre_master_secret, size_t pre_master_secret_len, - const uint8_t client_random[32], const uint8_t server_random[32], - const uint8_t master_secret[48], - const uint8_t *key_block, size_t key_block_len, - int format, int indent) -{ - // 应该检查一下key_block_len的值,判断是否支持,或者算法选择, 或者要求输入一个cipher_suite参数 - format_bytes(stderr, format, indent, "pre_master_secret", pre_master_secret, pre_master_secret_len); - format_bytes(stderr, format, indent, "client_random", client_random, 32); - format_bytes(stderr, format, indent, "server_random", server_random, 32); - format_bytes(stderr, format, indent, "master_secret", master_secret, 48); - format_bytes(stderr, format, indent, "client_write_mac_key", key_block, 32); - format_bytes(stderr, format, indent, "server_write_mac_key", key_block + 32, 32); - format_bytes(stderr, format, indent, "client_write_enc_key", key_block + 64, 16); - format_bytes(stderr, format, indent, "server_write_enc_key", key_block + 80, 16); - format_print(stderr, format, indent, "\n"); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +const char *tls_record_type_name(int type) +{ + switch (type) { + case TLS_record_change_cipher_spec: return "ChangeCipherSpec"; + case TLS_record_alert: return "Alert"; + case TLS_record_handshake: return "Handshake"; + case TLS_record_application_data: return "ApplicationData"; + } + return NULL; +} + +const char *tls_protocol_name(int protocol) +{ + switch(protocol) { + case TLS_protocol_tlcp: return "TLCP"; + case TLS_protocol_ssl2: return "SSL2.0"; + case TLS_protocol_ssl3: return "SSL3.0"; + case TLS_protocol_tls1: return "TLS1.0"; + case TLS_protocol_tls11: return "TLS1.1"; + case TLS_protocol_tls12: return "TLS1.2"; + case TLS_protocol_tls13: return "TLS1.3"; + case TLS_protocol_dtls1: return "DTLS1.0"; + case TLS_protocol_dtls12: return "DTLS1.2"; + } + return NULL; +} + +const char *tls_cipher_suite_name(int cipher) +{ + switch (cipher) { + case TLS_cipher_null_with_null_null: return "TLS_NULL_WITH_NULL_NULL"; + case TLS_cipher_sm4_gcm_sm3: return "TLS_SM4_GCM_SM3"; + case TLS_cipher_sm4_ccm_sm3: return "TLS_SM4_CCM_SM3"; + case TLS_cipher_ecdhe_sm4_cbc_sm3: return "TLS_ECDHE_SM4_CBC_SM3"; + case TLS_cipher_ecdhe_sm4_gcm_sm3: return "TLS_ECDHE_SM4_GCM_SM3"; + case TLS_cipher_ecc_sm4_cbc_sm3: return "TLS_ECC_SM4_CBC_SM3"; + case TLS_cipher_ecc_sm4_gcm_sm3: return "TLS_ECC_SM4_GCM_SM3"; + case TLS_cipher_ibsdh_sm4_cbc_sm3: return "TLS_IBSDH_SM4_CBC_SM3"; + case TLS_cipher_ibsdh_sm4_gcm_sm3: return "TLS_IBSDH_SM4_GCM_SM3"; + case TLS_cipher_ibc_sm4_cbc_sm3: return "TLS_IBC_SM4_CBC_SM3"; + case TLS_cipher_ibc_sm4_gcm_sm3: return "TLS_IBC_SM4_GCM_SM3"; + case TLS_cipher_rsa_sm4_cbc_sm3: return "TLS_RSA_SM4_CBC_SM3"; + case TLS_cipher_rsa_sm4_gcm_sm3: return "TLS_RSA_SM4_GCM_SM3"; + case TLS_cipher_rsa_sm4_cbc_sha256: return "TLS_RSA_SM4_CBC_SHA256"; + case TLS_cipher_rsa_sm4_gcm_sha256: return "TLS_RSA_SM4_GCM_SHA256"; + case TLS_cipher_aes_128_gcm_sha256: return "TLS_AES_128_GCM_SHA256"; + case TLS_cipher_aes_256_gcm_sha384: return "TLS_AES_256_GCM_SHA384"; + case TLS_cipher_chacha20_poly1305_sha256: return "TLS_CHACHA20_POLY1305_SHA256"; + case TLS_cipher_aes_128_ccm_sha256: return "TLS_AES_128_CCM_SHA256"; + case TLS_cipher_aes_128_ccm_8_sha256: return "TLS_AES_128_CCM_8_SHA256"; + case TLS_cipher_empty_renegotiation_info_scsv: return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + } + return NULL; +} + +const char *tls_compression_method_name(int meth) +{ + switch (meth) { + case 0: return "no_compression"; + } + return NULL; +} + +const char *tls_extension_name(int ext) +{ + switch (ext) { + case TLS_extension_server_name: return "server_name"; + case TLS_extension_max_fragment_length: return "max_fragment_length"; + case TLS_extension_client_certificate_url: return "client_certificate_url"; + case TLS_extension_trusted_ca_keys: return "trusted_ca_keys"; + case TLS_extension_truncated_hmac: return "truncated_hmac"; + case TLS_extension_status_request: return "status_request"; + case TLS_extension_user_mapping: return "user_mapping"; + case TLS_extension_client_authz: return "client_authz"; + case TLS_extension_server_authz: return "server_authz"; + case TLS_extension_cert_type: return "cert_type"; + case TLS_extension_supported_groups: return "supported_groups"; + case TLS_extension_ec_point_formats: return "ec_point_formats"; + case TLS_extension_srp: return "srp"; + case TLS_extension_signature_algorithms: return "signature_algorithms"; + case TLS_extension_use_srtp: return "use_srtp"; + case TLS_extension_heartbeat: return "heartbeat"; + case TLS_extension_application_layer_protocol_negotiation: return "application_layer_protocol_negotiation"; + case TLS_extension_status_request_v2: return "status_request_v2"; + case TLS_extension_signed_certificate_timestamp: return "signed_certificate_timestamp"; + case TLS_extension_client_certificate_type: return "client_certificate_type"; + case TLS_extension_server_certificate_type: return "server_certificate_type"; + case TLS_extension_padding: return "padding"; + case TLS_extension_encrypt_then_mac: return "encrypt_then_mac"; + case TLS_extension_extended_master_secret: return "extended_master_secret"; + case TLS_extension_token_binding: return "token_binding"; + case TLS_extension_cached_info: return "cached_info"; + case TLS_extension_tls_lts: return "tls_lts"; + case TLS_extension_compress_certificate: return "compress_certificate"; + case TLS_extension_record_size_limit: return "record_size_limit"; + case TLS_extension_pwd_protect: return "pwd_protect"; + case TLS_extension_pwd_clear: return "pwd_clear"; + case TLS_extension_password_salt: return "password_salt"; + case TLS_extension_ticket_pinning: return "ticket_pinning"; + case TLS_extension_tls_cert_with_extern_psk: return "tls_cert_with_extern_psk"; + case TLS_extension_delegated_credentials: return "delegated_credentials"; + case TLS_extension_session_ticket: return "session_ticket"; + case TLS_extension_TLMSP: return "TLMSP"; + case TLS_extension_TLMSP_proxying: return "TLMSP_proxying"; + case TLS_extension_TLMSP_delegate: return "TLMSP_delegate"; + case TLS_extension_supported_ekt_ciphers: return "supported_ekt_ciphers"; + case TLS_extension_pre_shared_key: return "pre_shared_key"; + case TLS_extension_early_data: return "early_data"; + case TLS_extension_supported_versions: return "supported_versions"; + case TLS_extension_cookie: return "cookie"; + case TLS_extension_psk_key_exchange_modes: return "psk_key_exchange_modes"; + case TLS_extension_certificate_authorities: return "certificate_authorities"; + case TLS_extension_oid_filters: return "oid_filters"; + case TLS_extension_post_handshake_auth: return "post_handshake_auth"; + case TLS_extension_signature_algorithms_cert: return "signature_algorithms_cert"; + case TLS_extension_key_share: return "key_share"; + case TLS_extension_transparency_info: return "transparency_info"; + case TLS_extension_connection_id: return "connection_id"; + case TLS_extension_external_id_hash: return "external_id_hash"; + case TLS_extension_external_session_id: return "external_session_id"; + case TLS_extension_quic_transport_parameters: return "quic_transport_parameters"; + case TLS_extension_ticket_request: return "ticket_request"; + case TLS_extension_renegotiation_info: return "renegotiation_info"; + }; + return NULL; +} + +const char *tls_cert_type_name(int type) +{ + switch (type) { + case TLS_cert_type_rsa_sign: return "rsa_sign"; + case TLS_cert_type_dss_sign: return "dss_sign"; + case TLS_cert_type_rsa_fixed_dh: return "rsa_fixed_dh"; + case TLS_cert_type_dss_fixed_dh: return "dss_fixed_dh"; + case TLS_cert_type_rsa_ephemeral_dh_RESERVED: return "rsa_ephemeral_dh_RESERVED"; + case TLS_cert_type_dss_ephemeral_dh_RESERVED: return "dss_ephemeral_dh_RESERVED"; + case TLS_cert_type_fortezza_dms_RESERVED: return "fortezza_dms_RESERVED"; + case TLS_cert_type_ecdsa_sign: return "ecdsa_sign"; + case TLS_cert_type_rsa_fixed_ecdh: return "rsa_fixed_ecdh_DEPRECATED"; + case TLS_cert_type_ecdsa_fixed_ecdh: return "ecdsa_fixed_ecdh_DEPRECATED"; + case TLS_cert_type_gost_sign256: return "gost_sign256"; + case TLS_cert_type_gost_sign512: return "gost_sign512"; + case TLS_cert_type_ibc_params: return "ibc_params"; + } + return NULL; +} + +const char *tls_handshake_type_name(int type) +{ + switch (type) { + case TLS_handshake_hello_request: return "HelloRequest"; + case TLS_handshake_client_hello: return "ClientHello"; + case TLS_handshake_server_hello: return "ServerHello"; + case TLS_handshake_hello_verify_request: return "HelloVerifyRequest"; + case TLS_handshake_new_session_ticket: return "NewSessionTicket"; + case TLS_handshake_end_of_early_data: return "EndOfEarlyData"; + case TLS_handshake_hello_retry_request: return "HelloRetryRequest"; + case TLS_handshake_encrypted_extensions: return "EncryptedExtensions"; + case TLS_handshake_certificate: return "Certificate"; + case TLS_handshake_server_key_exchange: return "ServerKeyExchange"; + case TLS_handshake_certificate_request: return "CertificateRequest"; + case TLS_handshake_server_hello_done: return "ServerHelloDone"; + case TLS_handshake_certificate_verify: return "CertificateVerify"; + case TLS_handshake_client_key_exchange: return "ClientKeyExchange"; + case TLS_handshake_finished: return "Finished"; + case TLS_handshake_certificate_url: return "CertificateUrl"; + case TLS_handshake_certificate_status: return "CertificateStatus"; + case TLS_handshake_supplemental_data: return "SupplementalData"; + case TLS_handshake_key_update: return "KeyUpdate"; + case TLS_handshake_compressed_certificate: return "CompressedCertificate"; + case TLS_handshake_ekt_key: return "EktKey"; + case TLS_handshake_message_hash: return "MessageHash"; + } + return NULL; +} + +const char *tls_alert_level_name(int level) +{ + switch (level) { + case TLS_alert_level_warning: return "warning"; + case TLS_alert_level_fatal: return "fatal"; + } + error_print_msg("unknown alert level %d\n", level); + return NULL; +} + +const char *tls_alert_description_text(int description) +{ + switch (description) { + case TLS_alert_close_notify: return "close_notify"; + case TLS_alert_unexpected_message: return "unexpected_message"; + case TLS_alert_bad_record_mac: return "bad_record_mac"; + case TLS_alert_decryption_failed: return "decryption_failed"; + case TLS_alert_record_overflow: return "record_overflow"; + case TLS_alert_decompression_failure: return "decompression_failure"; + case TLS_alert_handshake_failure: return "handshake_failure"; + case TLS_alert_no_certificate: return "no_certificate_RESERVED"; + case TLS_alert_bad_certificate: return "bad_certificate"; + case TLS_alert_unsupported_certificate: return "unsupported_certificate"; + case TLS_alert_certificate_revoked: return "certificate_revoked"; + case TLS_alert_certificate_expired: return "certificate_expired"; + case TLS_alert_certificate_unknown: return "certificate_unknown"; + case TLS_alert_illegal_parameter: return "illegal_parameter"; + case TLS_alert_unknown_ca: return "unknown_ca"; + case TLS_alert_access_denied: return "access_denied"; + case TLS_alert_decode_error: return "decode_error"; + case TLS_alert_decrypt_error: return "decrypt_error"; + case TLS_alert_export_restriction: return "export_restriction_RESERVED"; + case TLS_alert_protocol_version: return "protocol_version"; + case TLS_alert_insufficient_security: return "insufficient_security"; + case TLS_alert_internal_error: return "internal_error"; + case TLS_alert_user_canceled: return "user_canceled"; + case TLS_alert_no_renegotiation: return "no_renegotiation"; + case TLS_alert_unsupported_extension: return "unsupported_extension"; + case TLS_alert_unsupported_site2site: return "unsupported_site2site"; + case TLS_alert_no_area: return "no_area"; + case TLS_alert_unsupported_areatype: return "unsupported_areatype"; + case TLS_alert_bad_ibcparam: return "bad_ibcparam"; + case TLS_alert_unsupported_ibcparam: return "unsupported_ibcparam"; + case TLS_alert_identity_need: return "identity_need"; + } + error_print_msg("unknown alert description %d", description); + return NULL; +} + +const char *tls_change_cipher_spec_text(int change_cipher_spec) +{ + switch (change_cipher_spec) { + case TLS_change_cipher_spec: return "change_cipher_spec"; + } + return NULL; +} + +const char *tls_ec_point_format_name(int format) +{ + switch (format) { + case TLS_point_uncompressed: return "uncompressed"; + case TLS_point_ansix962_compressed_prime: return "compressed_prime"; + case TLS_point_ansix962_compressed_char2: return "compressed_char2"; + } + return NULL; +} + +const char *tls_curve_type_name(int type) +{ + switch (type) { + case TLS_curve_type_explicit_prime: return "explicit_prime"; + case TLS_curve_type_explicit_char2: return "explicit_char2"; + case TLS_curve_type_named_curve: return "named_curve"; + } + return NULL; +} + + +// FIXME: 是否应该将函数名改为 tls_curve_name() 这样和 TLS_curve_xxx 保持一致 +const char *tls_named_curve_name(int curve) +{ + switch (curve) { + case TLS_curve_secp256k1: return "secp256k1"; + case TLS_curve_secp256r1: return "secp256r1"; + case TLS_curve_secp384r1: return "secp384r1"; + case TLS_curve_secp521r1: return "secp521r1"; + case TLS_curve_brainpoolp256r1: return "brainpoolp256r1"; + case TLS_curve_brainpoolp384r1: return "brainpoolp384r1"; + case TLS_curve_brainpoolp512r1: return "brainpoolp512r1"; + case TLS_curve_x25519: return "x25519"; + case TLS_curve_x448: return "x448"; + case TLS_curve_brainpoolp256r1tls13: return "brainpoolp256r1tls13"; + case TLS_curve_brainpoolp384r1tls13: return "brainpoolp384r1tls13"; + case TLS_curve_brainpoolp512r1tls13: return "brainpoolp512r1tls13"; + case TLS_curve_sm2p256v1: return "sm2p256v1"; + } + return NULL; +} + +const char *tls_signature_scheme_name(int scheme) +{ + switch (scheme) { + case TLS_sig_rsa_pkcs1_sha1: return "rsa_pkcs1_sha1"; + case TLS_sig_ecdsa_sha1: return "ecdsa_sha1"; + case TLS_sig_rsa_pkcs1_sha256: return "rsa_pkcs1_sha256"; + case TLS_sig_ecdsa_secp256r1_sha256: return "ecdsa_secp256r1_sha256"; + case TLS_sig_rsa_pkcs1_sha256_legacy: return "rsa_pkcs1_sha256_legacy"; + case TLS_sig_rsa_pkcs1_sha384: return "rsa_pkcs1_sha384"; + case TLS_sig_ecdsa_secp384r1_sha384: return "ecdsa_secp384r1_sha384"; + case TLS_sig_rsa_pkcs1_sha384_legacy: return "rsa_pkcs1_sha384_legacy"; + case TLS_sig_rsa_pkcs1_sha512: return "rsa_pkcs1_sha512"; + case TLS_sig_ecdsa_secp521r1_sha512: return "ecdsa_secp521r1_sha512"; + case TLS_sig_rsa_pkcs1_sha512_legacy: return "rsa_pkcs1_sha512_legacy"; + case TLS_sig_sm2sig_sm3: return "sm2sig_sm3"; + case TLS_sig_rsa_pss_rsae_sha256: return "rsa_pss_rsae_sha256"; + case TLS_sig_rsa_pss_rsae_sha384: return "rsa_pss_rsae_sha384"; + case TLS_sig_rsa_pss_rsae_sha512: return "rsa_pss_rsae_sha512"; + case TLS_sig_ed25519: return "ed25519"; + case TLS_sig_ed448: return "ed448"; + case TLS_sig_rsa_pss_pss_sha256: return "rsa_pss_pss_sha256"; + case TLS_sig_rsa_pss_pss_sha384: return "rsa_pss_pss_sha384"; + case TLS_sig_rsa_pss_pss_sha512: return "rsa_pss_pss_sha512"; + case TLS_sig_ecdsa_brainpoolP256r1tls13_sha256: return "ecdsa_brainpoolP256r1tls13_sha256"; + case TLS_sig_ecdsa_brainpoolP384r1tls13_sha384: return "ecdsa_brainpoolP384r1tls13_sha384"; + case TLS_sig_ecdsa_brainpoolP512r1tls13_sha512: return "ecdsa_brainpoolP512r1tls13_sha512"; + } + return NULL; +} + +int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent) +{ + int i; + time_t gmt_unix_time = 0; + const uint8_t *cp = random; + size_t len = 4; + + tls_uint32_from_bytes((uint32_t *)&gmt_unix_time, &cp, &len); + format_print(fp, format, indent, "Random\n"); + indent += 4; + format_print(fp, format, indent, "gmt_unix_time : %s", ctime(&gmt_unix_time)); + format_bytes(fp, format, indent, "random", random + 4, 28); + return 1; +} + +int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], int format, int indent) +{ + int protocol = ((int)pre_master_secret[0] << 8) | pre_master_secret[1]; + format_print(fp, format, indent, "PreMasterSecret\n"); + indent += 4; + format_print(fp, format, indent, "protocol : %s\n", tls_protocol_name(protocol)); + format_bytes(fp, format, indent, "pre_master_secret", pre_master_secret, 48); + return 1; +} + +// supported_versions 的格式还受到 handshake_type 影响 +int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, int format, int indent) +{ + const uint8_t *p; + size_t len; + + format_print(fp, format, indent, "%s (%d)\n", tls_extension_name(type), type); + indent += 4; + + switch (type) { + case TLS_extension_supported_versions: + if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 + || tls_length_is_zero(datalen) != 1 + || len % 2) { + error_print(); + return -1; + } + while (len) { + uint16_t proto; + tls_uint16_from_bytes(&proto, &p, &len); + format_print(fp, format, indent, "%s (0x%04x)\n", + tls_protocol_name(proto), proto); + } + break; + case TLS_extension_supported_groups: + if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 + || datalen + || len % 2) { + error_print(); + return -1; + } + while (len) { + uint16_t curve; + tls_uint16_from_bytes(&curve, &p, &len); + format_print(fp, format, indent, "%s (%d)\n", + tls_named_curve_name(curve), curve); + } + break; + case TLS_extension_ec_point_formats: + if (tls_uint8array_from_bytes(&p, &len, &data, &datalen) != 1 + || datalen) { + error_print(); + return -1; + } + while (len) { + uint8_t point_form; + tls_uint8_from_bytes(&point_form, &p, &len); + format_print(fp, format, indent, "%s (%d)\n", + tls_ec_point_format_name(point_form), point_form); + } + break; + case TLS_extension_signature_algorithms: + if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 + || datalen + || len % 2) { + error_print(); + return -1; + } + while (len) { + uint16_t sig_alg; + tls_uint16_from_bytes(&sig_alg, &p, &len); + format_print(fp, format, indent, "%s (0x%04x)\n", + tls_signature_scheme_name(sig_alg), sig_alg); + } + break; + case TLS_extension_key_share: + if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 + || datalen) { + error_print(); + return -1; + } + while (len) { + uint16_t group; + const uint8_t *key_exch; + size_t key_exch_len; + + if (tls_uint16_from_bytes(&group, &p, &len) != 1 + || tls_uint16array_from_bytes(&key_exch, &key_exch_len, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent, "group: %s (%d)\n", tls_named_curve_name(group), group); + format_bytes(fp, format, indent, "key_exchange", key_exch, key_exch_len); + } + break; + + default: + format_bytes(fp, format, indent, "raw_data", data, datalen); + } + return 1; +} + +int tls13_extension_print(FILE *fp, int fmt, int ind, + int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen) +{ + switch (ext_type) { + case TLS_extension_supported_groups: + case TLS_extension_ec_point_formats: + case TLS_extension_signature_algorithms: + return tls_extension_print(fp, ext_type, ext_data, ext_datalen, fmt, ind); + } + + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + ind += 4; + + switch (ext_type) { + case TLS_extension_supported_versions: + tls13_supported_versions_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); + break; + case TLS_extension_key_share: + tls13_key_share_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); + break; + default: + format_bytes(fp, fmt, ind, "raw_data", ext_data, ext_datalen); + } + return 1; +} + +int tls13_extensions_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *exts, size_t extslen) +{ + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (!exts) { + format_print(fp, fmt, ind, "Extensions: (null)\n"); + return 1; + } + + format_print(fp, fmt, ind, "Extensions\n"); + ind += 4; + + while (extslen > 0) { + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + if (tls13_extension_print(fp, fmt, ind, handshake_type, ext_type, ext_data, ext_datalen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int tls_extensions_print(FILE *fp, const uint8_t *exts, size_t extslen, int format, int indent) +{ + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + format_print(fp, format, indent, "Extensions\n"); + indent += 4; + while (extslen > 0) { + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + if (tls_extension_print(fp, ext_type, ext_data, ext_datalen, format, indent) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + format_print(fp, format, indent, "HelloRequest\n"); + indent += 4; + if (data || datalen > 0) { + error_print(); + return -1; + } + return 1; +} + +int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + int ret = -1; + uint16_t protocol; + const uint8_t *random; + const uint8_t *session_id; + const uint8_t *cipher_suites; + const uint8_t *comp_meths; + const uint8_t *exts; + size_t session_id_len, cipher_suites_len, comp_meths_len, exts_len; + size_t i; + + format_print(fp, format, indent, "ClientHello\n"); indent += 4; + if (tls_uint16_from_bytes((uint16_t *)&protocol, &data, &datalen) != 1) goto end; + format_print(fp, format, indent, "Version: %s (%d.%d)\n", + tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + if (tls_array_from_bytes(&random, 32, &data, &datalen) != 1) goto end; + tls_random_print(fp, random, format, indent); + if (tls_uint8array_from_bytes(&session_id, &session_id_len, &data, &datalen) != 1) goto end; + format_bytes(fp, format, indent, "SessionID", session_id, session_id_len); + if (tls_uint16array_from_bytes(&cipher_suites, &cipher_suites_len, &data, &datalen) != 1) goto end; + format_print(fp, format, indent, "CipherSuites\n"); + while (cipher_suites_len >= 2) { + uint16_t cipher; + if (tls_uint16_from_bytes(&cipher, &cipher_suites, &cipher_suites_len) != 1) goto end; + format_print(fp, format, indent + 4, "%s (0x%04x)\n", + tls_cipher_suite_name(cipher), cipher); + } + if (cipher_suites_len) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(&comp_meths, &comp_meths_len, &data, &datalen) != 1) goto end; + format_print(fp, format, indent, "CompressionMethods\n"); + for (i = 0; i < comp_meths_len; i++) { + format_print(fp, format, indent + 4, "%s (%d)\n", + tls_compression_method_name(comp_meths[i]), comp_meths[i]); + } + if (datalen > 0) { + if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto end; + //tls_extensions_print(fp, exts, exts_len, format, indent); + tls13_extensions_print(fp, format, indent, TLS_handshake_client_hello, exts, exts_len); + } + if (datalen > 0) { + error_print(); + return -1; + } + ret = 1; +end: + return ret; +} + +int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + int ret = -1; + uint16_t protocol; + const uint8_t *random; + const uint8_t *session_id; + uint16_t cipher_suite; + uint8_t comp_meth; + const uint8_t *exts; + size_t session_id_len, cipher_suites_len, comp_meths_len, exts_len; + size_t i; + + format_print(fp, format, indent, "ServerHello\n"); indent += 4; + if (tls_uint16_from_bytes(&protocol, &data, &datalen) != 1) goto bad; + format_print(fp, format, indent, "Version: %s (%d.%d)\n", + tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + if (tls_array_from_bytes(&random, 32, &data, &datalen) != 1) goto bad; + tls_random_print(fp, random, format, indent); + if (tls_uint8array_from_bytes(&session_id, &session_id_len, &data, &datalen) != 1) goto bad; + format_bytes(fp, format, indent, "SessionID", session_id, session_id_len); + if (tls_uint16_from_bytes(&cipher_suite, &data, &datalen) != 1) goto bad; + format_print(fp, format, indent, "CipherSuite: %s (0x%04x)\n", + tls_cipher_suite_name(cipher_suite), cipher_suite); + if (tls_uint8_from_bytes(&comp_meth, &data, &datalen) != 1) goto bad; + format_print(fp, format, indent, "CompressionMethod: %s (%d)\n", + tls_compression_method_name(comp_meth), comp_meth); + if (datalen > 0) { + if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad; + //format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print + //tls_extensions_print(fp, exts, exts_len, format, indent); + tls13_extensions_print(fp, format, indent, TLS_handshake_server_hello, exts, exts_len); + } + return 1; +bad: + error_print(); + return -1; +} + +int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + int ret; + const uint8_t *certs; + size_t certslen; + const uint8_t *der; + size_t derlen; + + if (tls_uint24array_from_bytes(&certs, &certslen, &data, &datalen) != 1) { + error_print(); + return -1; + } + while (certslen > 0) { + if (tls_uint24array_from_bytes(&der, &derlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + (void)x509_cert_print(fp, format, indent, "Certificate", der, derlen); + (void)x509_cert_to_pem(der, derlen, fp); + } + + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, + int format, int indent) +{ + uint8_t curve_type; + uint16_t curve; + const uint8_t *octets; + size_t octetslen; + uint16_t sig_alg; + const uint8_t *sig; + size_t siglen; + + format_print(fp, format, indent, "ServerKeyExchange\n"); + indent += 4; + format_print(fp, format, indent, "ServerECDHParams\n"); + format_print(fp, format, indent + 4, "curve_params\n"); + if (tls_uint8_from_bytes(&curve_type, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent + 8, "curve_type: %s (%d)\n", + tls_curve_type_name(curve_type), curve_type); + if (tls_uint16_from_bytes(&curve, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent + 8, "named_curve: %s (%d)\n", + tls_named_curve_name(curve), curve); + if (tls_uint8array_from_bytes(&octets, &octetslen, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, format, indent + 4, "point", octets, octetslen); + if (tls_uint16_from_bytes(&sig_alg, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent, "SignatureScheme: %s (0x%04x)\n", + tls_signature_scheme_name(sig_alg), sig_alg); + if (tls_uint16array_from_bytes(&sig, &siglen, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, format, indent, "Siganture", sig, siglen); + if (datalen > 0) { + error_print(); + return -1; + } + return 1; +} + +int tls_server_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + int cipher_suite = (format >> 8) & 0xffff; + + switch (cipher_suite) { + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecc_sm4_gcm_sm3: + if (tlcp_server_key_exchange_pke_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + if (tls_server_key_exchange_ecdhe_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls_certificate_subjects_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *a; + size_t alen; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + const uint8_t *name; + size_t namelen; + + if (tls_uint16array_from_bytes(&a, &alen, &d, &dlen) != 1) { + error_print(); + return -1; + } + if (asn1_sequence_from_der(&name, &namelen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + x509_name_print(fp, fmt, ind, "DistinguishedName", name, namelen); + } + return 1; +} + +int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + const uint8_t *cert_types; + const uint8_t *ca_names; + size_t cert_types_len, ca_names_len, i; + + format_print(fp, format, indent, "CertificateRequest\n"); indent += 4; + if (tls_uint8array_from_bytes(&cert_types, &cert_types_len, &data, &datalen) != 1) goto bad; + format_print(fp, format, indent, "cert_types\n"); + while (cert_types_len--) { + int cert_type = *cert_types++; + format_print(fp, format, indent + 4, "%s (%d)\n", tls_cert_type_name(cert_type), cert_type); + } + if (tls_uint16array_from_bytes(&ca_names, &ca_names_len, &data, &datalen) != 1) goto bad; + tls_certificate_subjects_print(fp, format, indent, "CAnames", ca_names, ca_names_len); + + return 1; +bad: + error_print(); + return -1; +} + +int tls_server_hello_done_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + if (datalen > 0) { + error_print(); + return -1; + } + return 1; +} + +int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + const uint8_t *enced_pms; + size_t enced_pms_len; + + if (tls_uint16array_from_bytes(&enced_pms, &enced_pms_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, format, indent, "EncryptedPreMasterSecret", enced_pms, enced_pms_len); + return 1; +} + +int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen, + int format, int indent) +{ + const uint8_t *octets; + size_t octetslen; + + format_print(fp, format, indent, "ClientKeyExchange\n"); + indent += 4; + if (tls_uint8array_from_bytes(&octets, &octetslen, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, format, indent, "ecdh_Yc", octets, octetslen); + if (datalen > 0) { + error_print(); + return -1; + } + return 1; +} + +int tls_client_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + int cipher_suite = (format >> 8) & 0xffff; + switch (cipher_suite) { + case TLS_cipher_ecc_sm4_cbc_sm3: + case TLS_cipher_ecc_sm4_gcm_sm3: + if (tls_client_key_exchange_pke_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_cipher_ecdhe_sm4_cbc_sm3: + case TLS_cipher_ecdhe_sm4_gcm_sm3: + if (tls_client_key_exchange_ecdhe_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls_certificate_verify_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + format_print(fp, format, indent, "CertificateVerify\n"); + format_bytes(fp, format, indent + 4, "Signature", data, datalen); + return 1; +} + +int tls_finished_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + format_print(fp, format, indent, "Finished\n"); + indent += 4; + format_bytes(fp, format, indent, "verify_data", data, datalen); + return 1; +} + +int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) +{ + const uint8_t *p = handshake; + size_t len = handshake_len; + uint8_t type; + const uint8_t *data; + size_t datalen; + + if (tls_uint8_from_bytes(&type, &handshake, &handshake_len) != 1 + || tls_uint24array_from_bytes(&data, &datalen, &handshake, &handshake_len) != 1 + || tls_length_is_zero(handshake_len) != 1) { + error_print(); + return -1; + } + + switch (type) { + case TLS_handshake_certificate: + case TLS_handshake_certificate_request: + case TLS_handshake_certificate_verify: + format_print(fp, fmt, ind, "Handshake\n"); + ind += 4; + format_print(fp, fmt, ind, "Type: %s (%d)\n", tls_handshake_type_name(type), type); + format_print(fp, fmt, ind, "Length: %zu\n", datalen); + break; + } + switch (type) { + case TLS_handshake_certificate: + return tls13_certificate_print(fp, fmt, ind, data, datalen); + case TLS_handshake_certificate_request: + return tls13_certificate_request_print(fp, fmt, ind, data, datalen); + case TLS_handshake_certificate_verify: + return tls13_certificate_verify_print(fp, fmt, ind, data, datalen); + } + + return tls_handshake_print(fp, p, len, fmt, ind); +} + +// 这个是有问题的,因为TLS 1.3的证书和TLS 1.2是不一样的 +int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent) +{ + const uint8_t *cp = handshake; + uint8_t type; + const uint8_t *data; + size_t datalen = 0; + + format_print(fp, format, indent, "Handshake\n"); + indent += 4; + + if (tls_uint8_from_bytes(&type, &cp, &handshakelen) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent, "Type: %s (%d)\n", tls_handshake_type_name(type), type); + if (tls_uint24_from_bytes((uint24_t *)&datalen, &cp, &handshakelen) != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent, "Length: %zu\n", datalen); + + if (tls_array_from_bytes(&data, datalen, &cp, &handshakelen) != 1) { + error_print(); + return -1; + } + switch (type) { + case TLS_handshake_hello_request: + if (tls_hello_request_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_client_hello: + if (tls_client_hello_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_server_hello: + if (tls_server_hello_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_encrypted_extensions: + tls13_encrypted_extensions_print(fp, format, indent, data, datalen); + break; + + case TLS_handshake_certificate: + if (tls_certificate_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_server_key_exchange: + if (tls_server_key_exchange_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_certificate_request: + if (tls_certificate_request_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_server_hello_done: + if (tls_server_hello_done_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_client_key_exchange: + if (tls_client_key_exchange_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_certificate_verify: + if (tls_certificate_verify_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + case TLS_handshake_finished: + if (tls_finished_print(fp, data, datalen, format, indent) != 1) + { error_print(); return -1; } break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls_alert_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + if (datalen != 2) { + error_print(); + return -1; + } + format_print(fp, format, indent, "Alert:\n"); + indent += 4; + format_print(fp, format, indent, "Level: %s (%d)\n", tls_alert_level_name(data[0]), data[0]); + format_print(fp, format, indent, "Reason: %s (%d)\n", tls_alert_description_text(data[1]), data[1]); + return 1; +} + +int tls_change_cipher_spec_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + if (datalen != 1) { + error_print(); + return -1; + } + format_print(fp, format, indent, "ChangeCipherSpec\n"); + indent += 4; + format_print(fp, format, indent, "type : %s (%d)\n", tls_change_cipher_spec_text(data[0]), data[0]); + return 1; +} + +int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) +{ + format_bytes(fp, format, indent, "ApplicationData", data, datalen); + return 1; +} + +int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen) +{ + const uint8_t *data; + size_t datalen; + int protocol; + + format |= TLS_cipher_sm4_gcm_sm3 << 8; + + if (!fp || !record || recordlen < 5) { + error_print(); + return -1; + } + protocol = tls_record_protocol(record); + format_print(fp, format, indent, "Record\n"); indent += 4; + format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); + format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); + + data = tls_record_data(record); + datalen = tls_record_data_length(record); + + if (recordlen < tls_record_length(record)) { + error_print(); + return -1; + } + + // 最高字节设置后强制打印记录原始数据 + if (format >> 24) { + format_bytes(fp, format, indent, "Data", data, datalen); + fprintf(fp, "\n"); + return 1; + } + + switch (record[0]) { + case TLS_record_handshake: + tls13_handshake_print(fp, format, indent, data, datalen); + break; + case TLS_record_alert: + if (tls_alert_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_change_cipher_spec: + if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_application_data: + if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + + recordlen -= tls_record_length(record); + if (recordlen) { + format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); + } + + fprintf(fp, "\n"); + return 1; + +} + + +// 仅从record数据是不能判断这个record是TLS 1.2还是TLS 1.3 +// 不同协议上,同名的握手消息,其格式也是不一样的。这真是太恶心了!!!! + +// 当消息为ClientKeyExchange,ServerKeyExchange,需要密码套件中的密钥交换算法信息 +// 当消息为加密的Finished,记录类型为Handshake,但是记录负载数据中没有Handshake头 +// 注意:这里的recordlen 是冗余的,要容忍recordlen的错误 +// +// supported_versions 的格式由handshake_type 是否为ClientHello, ServerHello 决定 +// record中是包含这个信息的,但是在exts中没有这个信息 +int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + const uint8_t *data; + size_t datalen; + int protocol; + + if (!fp || !record || recordlen < 5) { + error_print(); + return -1; + } + protocol = tls_record_protocol(record); + format_print(fp, format, indent, "Record\n"); indent += 4; + format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); + format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); + + data = tls_record_data(record); + datalen = tls_record_data_length(record); + + if (recordlen < tls_record_length(record)) { + error_print(); + return -1; + } + + // 最高字节设置后强制打印记录原始数据 + if (format >> 24) { + format_bytes(fp, format, indent, "Data", data, datalen); + fprintf(fp, "\n"); + return 1; + } + + switch (record[0]) { + case TLS_record_handshake: + if (tls_handshake_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_alert: + if (tls_alert_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_change_cipher_spec: + if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_application_data: + if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + + recordlen -= tls_record_length(record); + if (recordlen) { + format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); + } + + fprintf(fp, "\n"); + return 1; + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +int tls_secrets_print(FILE *fp, + const uint8_t *pre_master_secret, size_t pre_master_secret_len, + const uint8_t client_random[32], const uint8_t server_random[32], + const uint8_t master_secret[48], + const uint8_t *key_block, size_t key_block_len, + int format, int indent) +{ + // 应该检查一下key_block_len的值,判断是否支持,或者算法选择, 或者要求输入一个cipher_suite参数 + format_bytes(stderr, format, indent, "pre_master_secret", pre_master_secret, pre_master_secret_len); + format_bytes(stderr, format, indent, "client_random", client_random, 32); + format_bytes(stderr, format, indent, "server_random", server_random, 32); + format_bytes(stderr, format, indent, "master_secret", master_secret, 48); + format_bytes(stderr, format, indent, "client_write_mac_key", key_block, 32); + format_bytes(stderr, format, indent, "server_write_mac_key", key_block + 32, 32); + format_bytes(stderr, format, indent, "client_write_enc_key", key_block + 64, 16); + format_bytes(stderr, format, indent, "server_write_enc_key", key_block + 80, 16); + format_print(stderr, format, indent, "\n"); + return 1; +} diff --git a/src/version.c b/src/version.c index 3dc91110..69f2933c 100644 --- a/src/version.c +++ b/src/version.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,16 +7,17 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include - -int gmssl_version_num(void) -{ - return GMSSL_VERSION_NUM; -} - -const char *gmssl_version_str(void) -{ - return GMSSL_VERSION_STR; -} + + + +#include + +int gmssl_version_num(void) +{ + return GMSSL_VERSION_NUM; +} + +const char *gmssl_version_str(void) +{ + return GMSSL_VERSION_STR; +} diff --git a/src/x509_alg.c b/src/x509_alg.c index 18d1cc98..736745a7 100644 --- a/src/x509_alg.c +++ b/src/x509_alg.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,583 +7,584 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static uint32_t oid_sm3[] = { 1,2,156,10197,1,401 }; -static uint32_t oid_md5[] = { 1,2,840,113549,2,5 }; -static uint32_t oid_sha1[] = { 1,3,14,3,2,26 }; -static uint32_t oid_sha256[] = { 2,16,840,1,101,3,4,2,1 }; -static uint32_t oid_sha384[] = { 2,16,840,1,101,3,4,2,2 }; -static uint32_t oid_sha512[] = { 2,16,840,1,101,3,4,2,3 }; -static uint32_t oid_sha224[] = { 2,16,840,1,101,3,4,2,4 }; - -static const ASN1_OID_INFO x509_digest_algors[] = { - { OID_sm3, "sm3", oid_sm3, sizeof(oid_sm3)/sizeof(int) }, - { OID_md5, "md5", oid_md5, sizeof(oid_md5)/sizeof(int) }, - { OID_sha1, "sha1", oid_sha1, sizeof(oid_sha1)/sizeof(int) }, - { OID_sha224, "sha224", oid_sha224, sizeof(oid_sha224)/sizeof(int) }, - { OID_sha256, "sha256", oid_sha256, sizeof(oid_sha256)/sizeof(int) }, - { OID_sha384, "sha384", oid_sha384, sizeof(oid_sha384)/sizeof(int) }, - { OID_sha512, "sha512", oid_sha512, sizeof(oid_sha512)/sizeof(int) }, -}; - -static const int x509_digest_algors_count = - sizeof(x509_digest_algors)/sizeof(x509_digest_algors[0]); - -const char *x509_digest_algor_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_digest_algors, x509_digest_algors_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_digest_algor_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_digest_algors, x509_digest_algors_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - size_t len = 0; - if (!(info = asn1_oid_info_from_oid(x509_digest_algors, x509_digest_algors_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - const ASN1_OID_INFO *info; - - *oid = 0; - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if ((ret = asn1_oid_info_from_der(&info, x509_digest_algors, x509_digest_algors_count, &p, &len)) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return ret; - } - *oid = info->oid; - return 1; -} - -int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const ASN1_OID_INFO *info; - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_oid_info_from_der(&info, x509_digest_algors, x509_digest_algors_count, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", info->name); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - - -static uint32_t oid_sm4_cbc[] = { 1,2,156,10197,1,104,2 }; -static uint32_t oid_aes128_cbc[] = { 2,16,840,1,101,3,4,1,2 }; -static uint32_t oid_aes192_cbc[] = { 2,16,840,1,101,3,4,1,22 }; -static uint32_t oid_aes256_cbc[] = { 2,16,840,1,101,3,4,1,42 }; - -static const ASN1_OID_INFO x509_enc_algors[] = { - { OID_sm4_cbc, "sm4-cbc", oid_sm4_cbc, sizeof(oid_sm4_cbc)/sizeof(int) }, - { OID_aes128_cbc, "aes128-cbc", oid_aes128_cbc, sizeof(oid_aes128_cbc)/sizeof(int) }, - { OID_aes192_cbc, "aes192-cbc", oid_aes192_cbc, sizeof(oid_aes192_cbc)/sizeof(int) }, - { OID_aes256_cbc, "aes256-cbc", oid_aes256_cbc, sizeof(oid_aes256_cbc)/sizeof(int) }, -}; - -static const int x509_enc_algors_count = - sizeof(x509_enc_algors)/sizeof(x509_enc_algors[0]); - -const char *x509_encryption_algor_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_enc_algors, x509_enc_algors_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_encryption_algor_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_enc_algors, x509_enc_algors_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, - uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - size_t len = 0; - - if (!(info = asn1_oid_info_from_oid(x509_enc_algors, x509_enc_algors_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_octet_string_to_der(iv, ivlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1 - || asn1_octet_string_to_der(iv, ivlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - const ASN1_OID_INFO *info; - - *oid = OID_undef; - *iv = NULL; - *ivlen = 0; - - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_oid_info_from_der(&info, x509_enc_algors, x509_enc_algors_count, &p, &len) != 1 - || asn1_octet_string_from_der(iv, ivlen, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (!(*iv) || *ivlen != 16) { - error_print(); - return -1; - } - *oid = info->oid; - return 1; -} - -int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const ASN1_OID_INFO *info; - const uint8_t *iv; - size_t ivlen; - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_oid_info_from_der(&info, x509_enc_algors, x509_enc_algors_count, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", info->name); - if (asn1_octet_string_from_der(&iv, &ivlen, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "iv: ", iv, ivlen); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - - -static uint32_t oid_sm2sign_with_sm3[] = { 1,2,156,10197,1,501 }; -static uint32_t oid_rsasign_with_sm3[] = { 1,2,156,10197,1,504 }; -static uint32_t oid_ecdsa_with_sha1[] = { 1,2,840,10045,4,1 }; -static uint32_t oid_ecdsa_with_sha224[] = { 1,2,840,10045,4,3,1 }; -static uint32_t oid_ecdsa_with_sha256[] = { 1,2,840,10045,4,3,2 }; -static uint32_t oid_ecdsa_with_sha384[] = { 1,2,840,10045,4,3,3 }; -static uint32_t oid_ecdsa_with_sha512[] = { 1,2,840,10045,4,3,4 }; -static uint32_t oid_rsasign_with_md5[] = { 1,2,840,113549,1,1,4 }; -static uint32_t oid_rsasign_with_sha1[] = { 1,2,840,113549,1,1,5 }; -static uint32_t oid_rsasign_with_sha224[] = { 1,2,840,113549,1,1,14 }; -static uint32_t oid_rsasign_with_sha256[] = { 1,2,840,113549,1,1,11 }; -static uint32_t oid_rsasign_with_sha384[] = { 1,2,840,113549,1,1,12 }; -static uint32_t oid_rsasign_with_sha512[] = { 1,2,840,113549,1,1,13 }; - - -static const ASN1_OID_INFO x509_sign_algors[] = { - { OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), 1 }, - { OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM } , - { OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_md5, "md5WithRSAEncryption", oid_rsasign_with_md5, sizeof(oid_rsasign_with_md5)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, - { OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), 1 }, - { OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 }, - { OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), 1 }, - { OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), 1 }, -}; - -static const int x509_sign_algors_count = - sizeof(x509_sign_algors)/sizeof(x509_sign_algors[0]); - -const char *x509_signature_algor_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_sign_algors, x509_sign_algors_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_signature_algor_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_sign_algors, x509_sign_algors_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - size_t len = 0; - if (!(info = asn1_oid_info_from_oid(x509_sign_algors, x509_sign_algors_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || (info->flags && asn1_null_to_der(NULL, &len) != 1) - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1 - || (info->flags && asn1_null_to_der(out, outlen) != 1)) { - error_print(); - return -1; - } - return 1; -} - -int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - const ASN1_OID_INFO *info; - int has_null_obj; - int i; - - *oid = OID_undef; - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_oid_info_from_der(&info, x509_sign_algors, x509_sign_algors_count, &p, &len) != 1 - || (info->flags && asn1_null_from_der(&p, &len) < 0) - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - *oid = info->oid; - return 1; -} - -int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const ASN1_OID_INFO *info; - int null_param; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_oid_info_from_der(&info, x509_sign_algors, x509_sign_algors_count, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", info->name); - if ((null_param = asn1_null_from_der(&d, &dlen)) < 0) goto err; - if (null_param) format_print(fp, fmt, ind, "parameters: %s\n", asn1_tag_name(ASN1_TAG_NULL)); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -/* -sm2encrypt: no parameters - -rsaes_oaep: from rfc 3560 -RSAES-OAEP-params ::= SEQUENCE { - hashFunc [0] AlgorithmIdentifier DEFAULT sha1Identifier, - maskGenFunc [1] AlgorithmIdentifier DEFAULT mgf1SHA1Identifier, - pSourceFunc [2] AlgorithmIdentifier DEFAULT -*/ - -static uint32_t oid_sm2encrypt[] = { 1,2,156,10197,1,301,2 }; -static uint32_t oid_rsa_encryption[] = { 1,2,840,113549,1,1,1 }; -static uint32_t oid_rsaes_oaep[] = { 1,2,840,113549,1,1,7 }; - -static const ASN1_OID_INFO x509_pke_algors[] = { - { OID_sm2encrypt, "sm2encrypt", oid_sm2encrypt, sizeof(oid_sm2encrypt)/sizeof(int) }, - { OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int) }, - { OID_rsaes_oaep, "rsaesOAEP", oid_rsaes_oaep, sizeof(oid_rsaes_oaep)/sizeof(int) }, -}; - -static const int x509_pke_algors_count = - sizeof(x509_pke_algors)/sizeof(x509_pke_algors[0]); - -const char *x509_public_key_encryption_algor_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_pke_algors, x509_pke_algors_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_public_key_encryption_algor_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_pke_algors, x509_pke_algors_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - size_t len = 0; - - if (oid != OID_sm2encrypt) { - error_print(); - return -1; - } - if (!(info = asn1_oid_info_from_oid(x509_pke_algors, x509_pke_algors_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - const ASN1_OID_INFO *info; - - *oid = OID_undef; - *params = NULL; - *params_len = 0; - - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_oid_info_from_der(&info, x509_pke_algors, x509_pke_algors_count, &p, &len) != 1) { - error_print(); - return -1; - } - *oid = info->oid; - if (asn1_length_is_zero(len) != 1) { - if (info->oid == OID_sm2encrypt) { - error_print(); - return -1; - } - *params = p; - *params_len = len; - } - return 1; -} - -int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const ASN1_OID_INFO *info; - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_oid_info_from_der(&info, x509_pke_algors, x509_pke_algors_count, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", info->name); - if (asn1_length_is_zero(dlen) != 1) { - if (info->oid == OID_sm2encrypt) goto err; - format_bytes(fp, fmt, ind, "parameters: ", d, dlen); - } - return 1; -err: - error_print(); - return -1; -} - - - - - -static uint32_t oid_ec_public_key[] = { oid_x9_62,2,1 }; -//static uint32_t oid_rsa_encryption[] = { 1,2,840,113549,1,1,1 }; - -static const ASN1_OID_INFO x509_public_key_algors[] = { - { OID_ec_public_key, "ecPublicKey", oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), 0, "X9.62 ecPublicKey" }, - { OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), 0, "RSAEncryption" }, -}; - -static const int x509_public_key_algors_count = - sizeof(x509_public_key_algors)/sizeof(x509_public_key_algors[0]); - -const char *x509_public_key_algor_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_public_key_algors, x509_public_key_algors_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_public_key_algor_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_public_key_algors, x509_public_key_algors_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_public_key_algor_to_der(int oid, int curve_or_null, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - - switch (oid) { - case OID_ec_public_key: - if (asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), NULL, &len) != 1 - || ec_named_curve_to_der(curve_or_null, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), out, outlen) != 1 - || ec_named_curve_to_der(curve_or_null, out, outlen) != 1) { - error_print(); - return -1; - } - break; - case OID_rsa_encryption: - if (asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), NULL, &len) != 1 - || asn1_null_to_der(NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), out, outlen) != 1 - || asn1_null_to_der(out, outlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int x509_public_key_algor_from_der(int *oid , int *curve_or_null, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const ASN1_OID_INFO *info; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - - if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) { - error_print(); - return -1; - } - *oid = info->oid; - - switch (*oid) { - case OID_ec_public_key: - if (ec_named_curve_from_der(curve_or_null, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - break; - case OID_rsa_encryption: - if ((*curve_or_null = asn1_null_from_der(&d, &dlen)) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const ASN1_OID_INFO *info; - int val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "algorithm: %s\n", info->name); - - switch (info->oid) { - case OID_ec_public_key: - if (ec_named_curve_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "namedCurve: %s\n", ec_named_curve_name(val)); - break; - case OID_rsa_encryption: - if ((val = asn1_null_from_der(&d, &dlen)) < 0) goto err; - else if (val) format_print(fp, fmt, ind, "parameters: %s\n", asn1_null_name()); - break; - default: - error_print(); - return -1; - } - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static uint32_t oid_sm3[] = { 1,2,156,10197,1,401 }; +static uint32_t oid_md5[] = { 1,2,840,113549,2,5 }; +static uint32_t oid_sha1[] = { 1,3,14,3,2,26 }; +static uint32_t oid_sha256[] = { 2,16,840,1,101,3,4,2,1 }; +static uint32_t oid_sha384[] = { 2,16,840,1,101,3,4,2,2 }; +static uint32_t oid_sha512[] = { 2,16,840,1,101,3,4,2,3 }; +static uint32_t oid_sha224[] = { 2,16,840,1,101,3,4,2,4 }; + +static const ASN1_OID_INFO x509_digest_algors[] = { + { OID_sm3, "sm3", oid_sm3, sizeof(oid_sm3)/sizeof(int) }, + { OID_md5, "md5", oid_md5, sizeof(oid_md5)/sizeof(int) }, + { OID_sha1, "sha1", oid_sha1, sizeof(oid_sha1)/sizeof(int) }, + { OID_sha224, "sha224", oid_sha224, sizeof(oid_sha224)/sizeof(int) }, + { OID_sha256, "sha256", oid_sha256, sizeof(oid_sha256)/sizeof(int) }, + { OID_sha384, "sha384", oid_sha384, sizeof(oid_sha384)/sizeof(int) }, + { OID_sha512, "sha512", oid_sha512, sizeof(oid_sha512)/sizeof(int) }, +}; + +static const int x509_digest_algors_count = + sizeof(x509_digest_algors)/sizeof(x509_digest_algors[0]); + +const char *x509_digest_algor_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_digest_algors, x509_digest_algors_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_digest_algor_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_digest_algors, x509_digest_algors_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + size_t len = 0; + if (!(info = asn1_oid_info_from_oid(x509_digest_algors, x509_digest_algors_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_digest_algor_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + const ASN1_OID_INFO *info; + + *oid = 0; + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if ((ret = asn1_oid_info_from_der(&info, x509_digest_algors, x509_digest_algors_count, &p, &len)) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return ret; + } + *oid = info->oid; + return 1; +} + +int x509_digest_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const ASN1_OID_INFO *info; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_oid_info_from_der(&info, x509_digest_algors, x509_digest_algors_count, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", info->name); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + +static uint32_t oid_sm4_cbc[] = { 1,2,156,10197,1,104,2 }; +static uint32_t oid_aes128_cbc[] = { 2,16,840,1,101,3,4,1,2 }; +static uint32_t oid_aes192_cbc[] = { 2,16,840,1,101,3,4,1,22 }; +static uint32_t oid_aes256_cbc[] = { 2,16,840,1,101,3,4,1,42 }; + +static const ASN1_OID_INFO x509_enc_algors[] = { + { OID_sm4_cbc, "sm4-cbc", oid_sm4_cbc, sizeof(oid_sm4_cbc)/sizeof(int) }, + { OID_aes128_cbc, "aes128-cbc", oid_aes128_cbc, sizeof(oid_aes128_cbc)/sizeof(int) }, + { OID_aes192_cbc, "aes192-cbc", oid_aes192_cbc, sizeof(oid_aes192_cbc)/sizeof(int) }, + { OID_aes256_cbc, "aes256-cbc", oid_aes256_cbc, sizeof(oid_aes256_cbc)/sizeof(int) }, +}; + +static const int x509_enc_algors_count = + sizeof(x509_enc_algors)/sizeof(x509_enc_algors[0]); + +const char *x509_encryption_algor_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_enc_algors, x509_enc_algors_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_encryption_algor_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_enc_algors, x509_enc_algors_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_encryption_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, + uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + size_t len = 0; + + if (!(info = asn1_oid_info_from_oid(x509_enc_algors, x509_enc_algors_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 + || asn1_octet_string_to_der(iv, ivlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1 + || asn1_octet_string_to_der(iv, ivlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_encryption_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + const ASN1_OID_INFO *info; + + *oid = OID_undef; + *iv = NULL; + *ivlen = 0; + + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_oid_info_from_der(&info, x509_enc_algors, x509_enc_algors_count, &p, &len) != 1 + || asn1_octet_string_from_der(iv, ivlen, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (!(*iv) || *ivlen != 16) { + error_print(); + return -1; + } + *oid = info->oid; + return 1; +} + +int x509_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const ASN1_OID_INFO *info; + const uint8_t *iv; + size_t ivlen; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_oid_info_from_der(&info, x509_enc_algors, x509_enc_algors_count, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", info->name); + if (asn1_octet_string_from_der(&iv, &ivlen, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "iv: ", iv, ivlen); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + +static uint32_t oid_sm2sign_with_sm3[] = { 1,2,156,10197,1,501 }; +static uint32_t oid_rsasign_with_sm3[] = { 1,2,156,10197,1,504 }; +static uint32_t oid_ecdsa_with_sha1[] = { 1,2,840,10045,4,1 }; +static uint32_t oid_ecdsa_with_sha224[] = { 1,2,840,10045,4,3,1 }; +static uint32_t oid_ecdsa_with_sha256[] = { 1,2,840,10045,4,3,2 }; +static uint32_t oid_ecdsa_with_sha384[] = { 1,2,840,10045,4,3,3 }; +static uint32_t oid_ecdsa_with_sha512[] = { 1,2,840,10045,4,3,4 }; +static uint32_t oid_rsasign_with_md5[] = { 1,2,840,113549,1,1,4 }; +static uint32_t oid_rsasign_with_sha1[] = { 1,2,840,113549,1,1,5 }; +static uint32_t oid_rsasign_with_sha224[] = { 1,2,840,113549,1,1,14 }; +static uint32_t oid_rsasign_with_sha256[] = { 1,2,840,113549,1,1,11 }; +static uint32_t oid_rsasign_with_sha384[] = { 1,2,840,113549,1,1,12 }; +static uint32_t oid_rsasign_with_sha512[] = { 1,2,840,113549,1,1,13 }; + + +static const ASN1_OID_INFO x509_sign_algors[] = { + { OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), 1 }, + { OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM } , + { OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_rsasign_with_md5, "md5WithRSAEncryption", oid_rsasign_with_md5, sizeof(oid_rsasign_with_md5)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM }, + { OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), 1 }, + { OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 }, + { OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), 1 }, + { OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), 1 }, +}; + +static const int x509_sign_algors_count = + sizeof(x509_sign_algors)/sizeof(x509_sign_algors[0]); + +const char *x509_signature_algor_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_sign_algors, x509_sign_algors_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_signature_algor_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_sign_algors, x509_sign_algors_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + size_t len = 0; + if (!(info = asn1_oid_info_from_oid(x509_sign_algors, x509_sign_algors_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 + || (info->flags && asn1_null_to_der(NULL, &len) != 1) + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1 + || (info->flags && asn1_null_to_der(out, outlen) != 1)) { + error_print(); + return -1; + } + return 1; +} + +int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + const ASN1_OID_INFO *info; + int has_null_obj; + int i; + + *oid = OID_undef; + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_oid_info_from_der(&info, x509_sign_algors, x509_sign_algors_count, &p, &len) != 1 + || (info->flags && asn1_null_from_der(&p, &len) < 0) + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + *oid = info->oid; + return 1; +} + +int x509_signature_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const ASN1_OID_INFO *info; + int null_param; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_oid_info_from_der(&info, x509_sign_algors, x509_sign_algors_count, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", info->name); + if ((null_param = asn1_null_from_der(&d, &dlen)) < 0) goto err; + if (null_param) format_print(fp, fmt, ind, "parameters: %s\n", asn1_tag_name(ASN1_TAG_NULL)); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +/* +sm2encrypt: no parameters + +rsaes_oaep: from rfc 3560 +RSAES-OAEP-params ::= SEQUENCE { + hashFunc [0] AlgorithmIdentifier DEFAULT sha1Identifier, + maskGenFunc [1] AlgorithmIdentifier DEFAULT mgf1SHA1Identifier, + pSourceFunc [2] AlgorithmIdentifier DEFAULT +*/ + +static uint32_t oid_sm2encrypt[] = { 1,2,156,10197,1,301,2 }; +static uint32_t oid_rsa_encryption[] = { 1,2,840,113549,1,1,1 }; +static uint32_t oid_rsaes_oaep[] = { 1,2,840,113549,1,1,7 }; + +static const ASN1_OID_INFO x509_pke_algors[] = { + { OID_sm2encrypt, "sm2encrypt", oid_sm2encrypt, sizeof(oid_sm2encrypt)/sizeof(int) }, + { OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int) }, + { OID_rsaes_oaep, "rsaesOAEP", oid_rsaes_oaep, sizeof(oid_rsaes_oaep)/sizeof(int) }, +}; + +static const int x509_pke_algors_count = + sizeof(x509_pke_algors)/sizeof(x509_pke_algors[0]); + +const char *x509_public_key_encryption_algor_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_pke_algors, x509_pke_algors_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_public_key_encryption_algor_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_pke_algors, x509_pke_algors_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_public_key_encryption_algor_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + size_t len = 0; + + if (oid != OID_sm2encrypt) { + error_print(); + return -1; + } + if (!(info = asn1_oid_info_from_oid(x509_pke_algors, x509_pke_algors_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_public_key_encryption_algor_from_der(int *oid, const uint8_t **params, size_t *params_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + const ASN1_OID_INFO *info; + + *oid = OID_undef; + *params = NULL; + *params_len = 0; + + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_oid_info_from_der(&info, x509_pke_algors, x509_pke_algors_count, &p, &len) != 1) { + error_print(); + return -1; + } + *oid = info->oid; + if (asn1_length_is_zero(len) != 1) { + if (info->oid == OID_sm2encrypt) { + error_print(); + return -1; + } + *params = p; + *params_len = len; + } + return 1; +} + +int x509_public_key_encryption_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const ASN1_OID_INFO *info; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_oid_info_from_der(&info, x509_pke_algors, x509_pke_algors_count, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", info->name); + if (asn1_length_is_zero(dlen) != 1) { + if (info->oid == OID_sm2encrypt) goto err; + format_bytes(fp, fmt, ind, "parameters: ", d, dlen); + } + return 1; +err: + error_print(); + return -1; +} + + + + + +static uint32_t oid_ec_public_key[] = { oid_x9_62,2,1 }; +//static uint32_t oid_rsa_encryption[] = { 1,2,840,113549,1,1,1 }; + +static const ASN1_OID_INFO x509_public_key_algors[] = { + { OID_ec_public_key, "ecPublicKey", oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), 0, "X9.62 ecPublicKey" }, + { OID_rsa_encryption, "rsaEncryption", oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), 0, "RSAEncryption" }, +}; + +static const int x509_public_key_algors_count = + sizeof(x509_public_key_algors)/sizeof(x509_public_key_algors[0]); + +const char *x509_public_key_algor_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_public_key_algors, x509_public_key_algors_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_public_key_algor_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_public_key_algors, x509_public_key_algors_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_public_key_algor_to_der(int oid, int curve_or_null, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + + switch (oid) { + case OID_ec_public_key: + if (asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), NULL, &len) != 1 + || ec_named_curve_to_der(curve_or_null, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_ec_public_key, sizeof(oid_ec_public_key)/sizeof(int), out, outlen) != 1 + || ec_named_curve_to_der(curve_or_null, out, outlen) != 1) { + error_print(); + return -1; + } + break; + case OID_rsa_encryption: + if (asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), NULL, &len) != 1 + || asn1_null_to_der(NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(oid_rsa_encryption, sizeof(oid_rsa_encryption)/sizeof(int), out, outlen) != 1 + || asn1_null_to_der(out, outlen) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int x509_public_key_algor_from_der(int *oid , int *curve_or_null, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const ASN1_OID_INFO *info; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + + if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) { + error_print(); + return -1; + } + *oid = info->oid; + + switch (*oid) { + case OID_ec_public_key: + if (ec_named_curve_from_der(curve_or_null, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + break; + case OID_rsa_encryption: + if ((*curve_or_null = asn1_null_from_der(&d, &dlen)) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int x509_public_key_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const ASN1_OID_INFO *info; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_oid_info_from_der(&info, x509_public_key_algors, x509_public_key_algors_count, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "algorithm: %s\n", info->name); + + switch (info->oid) { + case OID_ec_public_key: + if (ec_named_curve_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "namedCurve: %s\n", ec_named_curve_name(val)); + break; + case OID_rsa_encryption: + if ((val = asn1_null_from_der(&d, &dlen)) < 0) goto err; + else if (val) format_print(fp, fmt, ind, "parameters: %s\n", asn1_null_name()); + break; + default: + error_print(); + return -1; + } + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} diff --git a/src/x509_cer.c b/src/x509_cer.c index 137ca54c..caa5ddfb 100644 --- a/src/x509_cer.c +++ b/src/x509_cer.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1704 +7,1705 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -const char *x509_version_name(int version) -{ - switch (version) { - case X509_version_v1: return "v1"; - case X509_version_v2: return "v2"; - case X509_version_v3: return "v3"; - } - return NULL; -} - -int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - - if (version < 0) { - return 0; - } - if (!x509_version_name(version)) { - error_print(); - return -1; - } - if (asn1_int_to_der(version, NULL, &len) != 1 - || asn1_explicit_header_to_der(index, len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_explicit_from_der(index, &d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *version = -1; - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (!x509_version_name(*version)) { - error_print(); - return -1; - } - return 1; -} - -/* - from RFC 5280 section 4.1.2.5 - - CAs conforming to this profile MUST always encode certificate - validity dates through the year 2049 as UTCTime; certificate validity - dates in 2050 or later MUST be encoded as GeneralizedTime. - Conforming applications MUST be able to process validity dates that - are encoded in either UTCTime or GeneralizedTime. - - To indicate that a certificate has no well-defined expiration date, - the notAfter SHOULD be assigned the GeneralizedTime value of - 99991231235959Z. -*/ -int x509_time_to_der(time_t tv, uint8_t **out, size_t *outlen) -{ - int ret; - struct tm tm_val; - - gmtime_r(&tv, &tm_val); - if (tm_val.tm_year < 2050 - 1900) { - if ((ret = asn1_utc_time_to_der(tv, out, outlen)) != 1) { - if (ret < 0) error_print(); - } - } else { - if ((ret = asn1_generalized_time_to_der(tv, out, outlen)) !=1) { - if (ret < 0) error_print(); - } - } - return ret; -} - -int x509_time_from_der(time_t *tv, const uint8_t **in, size_t *inlen) -{ - int ret; - - if ((ret = asn1_utc_time_from_der(tv, in, inlen)) < 0) { - error_print(); - return -1; - } else if (ret) { - return 1; - } - - if ((ret = asn1_generalized_time_from_der(tv, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_validity_add_days(time_t *not_after, time_t not_before, int days) -{ - struct tm tm_val; - if (days < X509_VALIDITY_MIN_DAYS - || days > X509_VALIDITY_MAX_DAYS) { - error_print(); - return -1; - } - gmtime_r(¬_before, &tm_val); - tm_val.tm_mday += days; - *not_after = mktime(&tm_val); - return 1; -} - -int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_time_to_der(not_before, NULL, &len) != 1 - || x509_time_to_der(not_after, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_time_to_der(not_before, out, outlen) != 1 - || x509_time_to_der(not_after, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_time_from_der(not_before, &d, &dlen) != 1 - || x509_time_from_der(not_after, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*not_before >= *not_after) { - error_print(); - return -1; - } - return 1; -} - -int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - time_t tv; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "notBefore: %s", ctime(&tv)); - if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "notAfter: %s", ctime(&tv)); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - - -static const struct { - int oid; - int is_printable_string_only; - int minlen; - int maxlen; -} x509_name_types[] = { - { OID_at_country_name, 1, 2, 2 }, - { OID_at_state_or_province_name, 0, 1, X509_ub_state_name }, - { OID_at_locality_name, 0, 1, X509_ub_locality_name }, - { OID_at_organization_name, 0, 1, X509_ub_organization_name }, - { OID_at_organizational_unit_name, 0, 1, X509_ub_organizational_unit_name }, - { OID_at_common_name, 0, 1, X509_ub_common_name }, - { OID_at_serial_number, 1, 1, X509_ub_serial_number }, - { OID_at_dn_qualifier, 1, 1, 64 }, // max length unspecified in RFC 5280 - { OID_at_title, 0, 1, X509_ub_title }, - { OID_at_surname, 0, 1, X509_ub_name }, - { OID_at_given_name, 0, 1, X509_ub_name }, - { OID_at_initials, 0, 1, X509_ub_name }, - { OID_at_generation_qualifier, 0, 1, X509_ub_name }, - { OID_at_pseudonym, 0, 1, X509_ub_pseudonym }, -}; - -static const int x509_name_types_count - = sizeof(x509_name_types)/sizeof(x509_name_types[0]); - -int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen) -{ - int i; - for (i = 0; i < x509_name_types_count; i++) { - if (oid == x509_name_types[i].oid) { - if (x509_name_types[i].is_printable_string_only - && tag != ASN1_TAG_PrintableString) { - error_print(); - return -1; - } - if (x509_directory_name_check_ex(tag, val, vlen, - x509_name_types[i].minlen, x509_name_types[i].maxlen) != 1) { - error_print(); - return -1; - } - return 1; - } - } - error_print(); - return -1; -} - -int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_attr_type_and_value_check(oid, tag, val, vlen) != 1 - || x509_name_type_to_der(oid, NULL, &len) != 1 - || x509_directory_name_to_der(tag, val, vlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_name_type_to_der(oid, out, outlen) != 1 - || x509_directory_name_to_der(tag, val, vlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_name_type_from_der(oid, &d, &dlen) != 1 - || x509_directory_name_from_der(tag, val, vlen, &d, &dlen) != 1 - || x509_attr_type_and_value_check(*oid, *tag, *val, *vlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int oid, tag; - const uint8_t *val; - size_t vlen; - - if (fmt & ASN1_FMT_FULL) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0); - if (oid == OID_email_address) { - if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err; - format_string(fp, fmt, ind, "value", val, vlen); - } else { - if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err; - x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen); - } - } else { - if (x509_name_type_from_der(&oid, &d, &dlen) != 1) { error_print(); goto err; } - if (oid == OID_email_address) { - if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err; - format_string(fp, fmt, ind, "emailAddress", val, vlen); - } else { - if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err; - x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen); - } - } - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, - const uint8_t *more, size_t morelen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_attr_type_and_value_to_der(oid, tag, val, vlen, NULL, &len) != 1 - || asn1_data_to_der(more, morelen, NULL, &len) < 0 - || asn1_set_header_to_der(len, out, outlen) != 1 - || x509_attr_type_and_value_to_der(oid, tag, val, vlen, out, outlen) != 1 - || asn1_data_to_der(more, morelen, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, - const uint8_t **more, size_t *morelen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_set_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_attr_type_and_value_from_der(oid, tag, val, vlen, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (dlen) { - *more = d; - *morelen = dlen; - // TODO: check more,morelen - } else { - *more = NULL; - *morelen = 0; - } - return 1; -} - -int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (fmt & ASN1_FMT_FULL) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len); - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_attr_type_and_value_print(fp, fmt, ind + 4, "AttributeTypeAndValue", p, len); - } - return 1; -} - -int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, - int oid, int tag, const uint8_t *val, size_t vlen, - const uint8_t *more, size_t morelen) -{ - size_t len = 0; - uint8_t *p = d + *dlen; - if (!val && !more) { - return 0; - } - if (x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, NULL, &len) != 1 - || asn1_length_le(*dlen + len, maxlen) != 1 - || x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, &p, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2]) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, - OID_at_country_name, ASN1_TAG_PrintableString, (uint8_t *)val, 2, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen, - int tag, const uint8_t *val, size_t vlen) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_state_or_province_name, tag, val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, - int tag, const uint8_t *val, size_t vlen) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_locality_name, tag, val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, - int tag, const uint8_t *val, size_t vlen) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organization_name, tag, val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, - int tag, const uint8_t *val, size_t vlen) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organizational_unit_name, tag, val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, - int tag, const uint8_t *val, size_t vlen) -{ - int ret; - ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_common_name, tag, val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, - const char *val, size_t vlen) -{ - int ret; - return x509_name_add_rdn(d, dlen, maxlen, OID_domain_component, ASN1_TAG_IA5String, (uint8_t *)val, vlen, NULL, 0); - if (ret < 0) error_print(); - return ret; -} - -static size_t _strlen(const char *s) { return s ? strlen(s) : 0; } - -int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, - const char *country, const char *state, const char *locality, - const char *org, const char *org_unit, const char *common_name) -{ - int tag = ASN1_TAG_PrintableString; - if (country && strlen(country) != 2) { - error_print(); - return -1; - } - *dlen = 0; - if (x509_name_add_country_name(d, dlen, maxlen, country) < 0 - || x509_name_add_state_or_province_name(d, dlen, maxlen, tag, (uint8_t *)state, _strlen(state)) < 0 - || x509_name_add_locality_name(d, dlen, maxlen, tag, (uint8_t *)locality, _strlen(locality)) < 0 - || x509_name_add_organization_name(d, dlen, maxlen, tag, (uint8_t *)org, _strlen(org)) < 0 - || x509_name_add_organizational_unit_name(d, dlen, maxlen, tag, (uint8_t *)org_unit, _strlen(org_unit)) < 0 - || x509_name_add_common_name(d, dlen, maxlen, tag, (uint8_t *)common_name, _strlen(common_name)) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_rdn_print(fp, fmt, ind, "RelativeDistinguishedName", p, len); - } - return 1; -} - -int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_name_print(fp, fmt, ind, "Name", p, len); - } - return 1; -} - -int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen) -{ - const uint8_t *rdn_d; - size_t rdn_dlen; - - while (dlen) { - int attr_oid; - int attr_tag; - const uint8_t *attr_val; - size_t attr_vlen; - - if (asn1_set_from_der(&rdn_d, &rdn_dlen, &d, &dlen) != 1) { - error_print(); - return -1; - } - while (rdn_dlen) { - if (x509_attr_type_and_value_from_der(&attr_oid, &attr_tag, &attr_val, &attr_vlen, - &rdn_d, &rdn_dlen) != 1) { - error_print(); - return -1; - } - } - if (attr_oid == oid) { - *tag = attr_tag; - *val = attr_val; - *vlen = attr_vlen; - return 1; - } - } - return 0; -} - -int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen) -{ - int ret; - ret = x509_name_get_value_by_type(d, dlen, OID_at_common_name, tag, val, vlen); - if (ret < 0) error_print(); - return -1; -} - -int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen) -{ - if (alen != blen || memcmp(a, b, blen) != 0) { - return 0; - } - return 1; -} - - -int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p = d; - size_t len = dlen; - int alg; - int params; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_public_key_algor_from_der(&alg, ¶ms, &p, &len) != 1) goto err; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_public_key_algor_print(fp, fmt, ind, "algorithm", p, len); - format_print(fp, fmt, ind, "subjectPublicKey\n"); - ind += 4; - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - switch (alg) { - case OID_ec_public_key: - format_bytes(fp, fmt, ind, "ECPoint", p, len); - break; - case OID_rsa_encryption: - rsa_public_key_print(fp, fmt, ind, "RSAPublicKey", p, len); - break; - default: - format_bytes(fp, fmt, ind, "raw_data", p, len); - } - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_ext_id_to_der(oid, NULL, &len) != 1 - || asn1_boolean_to_der(critical, NULL, &len) < 0 - || asn1_octet_string_to_der(val, vlen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_ext_id_to_der(oid, out, outlen) != 1 - || asn1_boolean_to_der(critical, out, outlen) < 0 - || asn1_octet_string_to_der(val, vlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, - int *critical, const uint8_t **val, size_t *vlen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - *critical = 0; - if (x509_ext_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1 - || asn1_boolean_from_der(critical, &d, &dlen) < 0 - || asn1_octet_string_from_der(val, vlen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, oid, critical; - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *val; - size_t vlen; - - const uint8_t *p; - size_t len; - int ival; - const char *name; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_ext_id_name(oid), nodes, nodes_cnt); - if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); - if (asn1_octet_string_from_der(&val, &vlen, &d, &dlen) != 1) goto err; - - switch (oid) { - case OID_ce_subject_key_identifier: - if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1) { - error_print(); - return -1; - } - break; - case OID_ce_key_usage: - case OID_netscape_cert_type: - if (asn1_bits_from_der(&ival, &val, &vlen) != 1) { - error_print(); - return -1; - } - break; - case OID_ce_inhibit_any_policy: - if (asn1_int_from_der(&ival, &val, &vlen) != 1) { - error_print(); - return -1; - } - break; - case OID_netscape_cert_comment: - if (asn1_ia5_string_from_der((const char **)&p, &len, &val, &vlen) != 1) { - error_print(); - return -1; - } - break; - case OID_ct_precertificate_scts: - case OID_undef: - p = val; - len = vlen; - vlen = 0; - break; - default: - if (asn1_sequence_from_der(&p, &len, &val, &vlen) != 1) { - error_print(); - return -1; - } - } - if (asn1_length_is_zero(vlen) != 1) { - error_print(); - return -1; - } - - name = x509_ext_id_name(oid); - - switch (oid) { - case OID_ce_authority_key_identifier: return x509_authority_key_identifier_print(fp, fmt, ind, name, p, len); - case OID_ce_subject_key_identifier: return format_bytes(fp, fmt, ind, name, p, len); - case OID_ce_key_usage: return x509_key_usage_print(fp, fmt, ind, name, ival); - case OID_ce_certificate_policies: return x509_certificate_policies_print(fp, fmt, ind, name, p, len); - case OID_ce_policy_mappings: return x509_policy_mappings_print(fp, fmt, ind, name, p, len); - case OID_ce_subject_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len); - case OID_ce_issuer_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len); - case OID_ce_subject_directory_attributes: return x509_attributes_print(fp, fmt, ind, name, p, len); - case OID_ce_basic_constraints: return x509_basic_constraints_print(fp, fmt, ind, name, p, len); - case OID_ce_name_constraints: return x509_name_constraints_print(fp, fmt, ind, name, p, len); - case OID_ce_policy_constraints: return x509_policy_constraints_print(fp, fmt, ind, name, p, len); - case OID_ce_ext_key_usage: return x509_ext_key_usage_print(fp, fmt, ind, name, p, len); - case OID_ce_crl_distribution_points: return x509_crl_distribution_points_print(fp, fmt, ind, name, p, len); - case OID_ce_inhibit_any_policy: format_print(fp, fmt, ind, "%s: %d\n", name, ival); - case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len); - case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival); - case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len); - default: format_bytes(fp, fmt, ind, "extnValue", p, len); - } - return 1; -err: - error_print(); - return -1; -} - -int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (!d) { - return 0; - } - if (asn1_sequence_to_der(d, dlen, NULL, &len) != 1 - || asn1_explicit_header_to_der(index, len, out, outlen) != 1 - || asn1_sequence_to_der(d, dlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_sequence_from_der(d, dlen, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_get_count(const uint8_t *d, size_t dlen, size_t *cnt) -{ - return asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt); -} - -int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index, - int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, - const uint8_t **val, size_t *vlen) -{ - error_print(); - return -1; -} - -int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid, - int *critical, const uint8_t **val, size_t *vlen) -{ - return -1; -} - -int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_ext_print(fp, fmt, ind, "Extension", p, len); - } - return 1; -} - -int x509_tbs_cert_to_der( - int version, - const uint8_t *serial, size_t serial_len, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t not_before, time_t not_after, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, - const uint8_t *subject_unique_id, size_t subject_unique_id_len, - const uint8_t *exts, size_t exts_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_explicit_version_to_der(0, version, NULL, &len) < 0 - || asn1_integer_to_der(serial, serial_len, NULL, &len) != 1 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1 - || x509_validity_to_der(not_before, not_after, NULL, &len) != 1 - || asn1_sequence_to_der(subject, subject_len, NULL, &len) != 1 - || x509_public_key_info_to_der(subject_public_key, NULL, &len) != 1 - || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, NULL, &len) < 0 - || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, NULL, &len) < 0 - || x509_explicit_exts_to_der(3, exts, exts_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_explicit_version_to_der(0, version, out, outlen) < 0 - || asn1_integer_to_der(serial, serial_len, out, outlen) != 1 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1 - || x509_validity_to_der(not_before, not_after, out, outlen) != 1 - || asn1_sequence_to_der(subject, subject_len, out, outlen) != 1 - || x509_public_key_info_to_der(subject_public_key, out, outlen) != 1 - || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, out, outlen) < 0 - || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, out, outlen) < 0 - || x509_explicit_exts_to_der(3, exts, exts_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_tbs_cert_from_der( - int *version, - const uint8_t **serial, size_t *serial_len, - int *signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *not_before, time_t *not_after, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, - const uint8_t **subject_unique_id, size_t *subject_unique_id_len, - const uint8_t **exts, size_t *exts_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_explicit_version_from_der(0, version, &d, &dlen) < 0 - || asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || asn1_sequence_from_der(issuer, issuer_len, &d, &dlen) != 1 - || x509_validity_from_der(not_before, not_after, &d, &dlen) != 1 - || asn1_sequence_from_der(subject, subject_len, &d, &dlen) != 1 - || x509_public_key_info_from_der(subject_public_key, &d, &dlen) != 1 - || asn1_implicit_bit_octets_from_der(1, issuer_unique_id, issuer_unique_id_len, &d, &dlen) < 0 - || asn1_implicit_bit_octets_from_der(2, subject_unique_id, subject_unique_id_len, &d, &dlen) < 0 - || x509_explicit_exts_from_der(3, exts, exts_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = x509_explicit_version_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val); - if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "serialNumber", p, len); - if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "siganture: %s\n", x509_signature_algor_name(val)); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "issuer", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_validity_print(fp, fmt, ind, "validity", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "subject", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_public_key_info_print(fp, fmt, ind, "subjectPulbicKeyInfo", p, len); - if ((ret = asn1_implicit_bit_octets_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "issuerUniqueID", p, len); - if ((ret = asn1_implicit_bit_octets_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "subjectUniqueID", p, len); - if ((ret = x509_explicit_exts_from_der(3, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_exts_print(fp, fmt, ind, "extensions", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_certificate_to_der( - const uint8_t *tbs, size_t tbslen, // full TLV - int signature_algor, - const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_data_to_der(tbs, tbslen, out, outlen) != 1 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_certificate_from_der( - const uint8_t **tbs, size_t *tbslen, // full TLV - int *signature_algor, - const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_any_from_der(tbs, tbslen, &d, &dlen) != 1 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - int val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_tbs_cert_print(fp, fmt, ind, "tbsCertificate", p, len); - if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val)); - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "signatureValue", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_cert_sign( - uint8_t *cert, size_t *certlen, size_t maxlen, - int version, - const uint8_t *serial, size_t serial_len, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t not_before, time_t not_after, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, - const uint8_t *subject_unique_id, size_t subject_unique_id_len, - const uint8_t *exts, size_t exts_len, - const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len) -{ - uint8_t tbs[1024]; - size_t tbslen = 0; - uint8_t *p = tbs; - size_t len = 0; - SM2_SIGN_CTX sign_ctx; - int sig_alg = OID_sm2sign_with_sm3; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - if (x509_tbs_cert_to_der(version, serial, serial_len, signature_algor, - issuer, issuer_len, not_before, not_after, - subject, subject_len, subject_public_key, - issuer_unique_id, issuer_unique_id_len, - subject_unique_id, subject_unique_id_len, - exts, exts_len, NULL, &len) != 1 - || asn1_length_le(len, sizeof(tbs)) != 1 - || x509_tbs_cert_to_der(version, serial, serial_len, signature_algor, - issuer, issuer_len, not_before, not_after, - subject, subject_len, subject_public_key, - issuer_unique_id, issuer_unique_id_len, - subject_unique_id, subject_unique_id_len, - exts, exts_len, &p, &tbslen) != 1) { - error_print(); - return -1; - } - - if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 - || sm2_sign_update(&sign_ctx, tbs, tbslen) != 1 - || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { - memset(&sign_ctx, 0, sizeof(sign_ctx)); - error_print(); - return -1; - } - memset(&sign_ctx, 0, sizeof(sign_ctx)); - - *certlen = len = 0; - if (x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, NULL, &len) != 1 - || asn1_length_le(len, maxlen) != 1 - || x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, &cert, certlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_cert_verify(const uint8_t *a, size_t alen, - const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len) -{ - int ret; - const uint8_t *tbs; - size_t tbslen; - int sig_alg; - const uint8_t *sig; - size_t siglen; - SM2_SIGN_CTX verify_ctx; - - if (x509_certificate_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - if (sig_alg != OID_sm2sign_with_sm3) { - error_print(); - return -1; - } - if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1 - || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1 - || (ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { - error_print(); - return -1; - } - if (!ret) error_print(); - return ret; -} - -int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, - const uint8_t *cacert, size_t cacertlen, - const char *signer_id, size_t signer_id_len) -{ - int ret; - SM2_KEY public_key; - - if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 - || (ret = x509_cert_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { - error_print(); - return -1; - } - if (!ret) error_print(); - return ret; -} - -int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) -{ - return asn1_any_to_der(a, alen, out, outlen); -} - -int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen) -{ - return asn1_any_from_der(a, alen, in, inlen); -} - -int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp) -{ - if (pem_write(fp, "CERTIFICATE", a, alen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) -{ - int ret; - if ((ret = pem_read(fp, "CERTIFICATE", a, alen, maxlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp) -{ - int i; - for (i = 0; i <= index; i++) { - if (x509_cert_from_pem(a, alen, maxlen, fp) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp) -{ - int ret; - const uint8_t *d; - size_t dlen; - - for (;;) { - if ((ret = x509_cert_from_pem(a, alen, maxlen, fp)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_cert_get_subject(a, *alen, &d, &dlen) != 1) { - error_print(); - return -1; - } - - if (dlen == namelen && memcmp(name, d, dlen) == 0) { - return 1; - } - } - return 0; -} - -int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - const uint8_t *d; - size_t dlen; - - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) { - error_print(); - return -1; - } - x509_certificate_print(fp, fmt, ind, label, d, dlen); - if (asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_cert_get_details(const uint8_t *a, size_t alen, - int *version, - const uint8_t **serial_number, size_t *serial_number_len, - int *inner_signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *not_before, time_t *not_after, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, - const uint8_t **subject_unique_id, size_t *subject_unique_id_len, - const uint8_t **extensions, size_t *extensions_len, - int *signature_algor, - const uint8_t **signature, size_t *signature_len) -{ - const uint8_t *tbs; - size_t tbs_len; - int sig_alg; - const uint8_t *sig; size_t sig_len; - - const uint8_t *d; - size_t dlen; - - int ver; - const uint8_t *serial; size_t serial_len; - int inner_sig_alg; - const uint8_t *isur; size_t isur_len; - time_t before, after; - const uint8_t *subj; size_t subj_len; - SM2_KEY sm2_key; - const uint8_t *isur_uniq_id; size_t isur_uniq_id_len; - const uint8_t *subj_uniq_id; size_t subj_uniq_id_len; - const uint8_t *exts; size_t exts_len; - - if (x509_certificate_from_der(&tbs, &tbs_len, &sig_alg, &sig, &sig_len, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - if (asn1_sequence_from_der(&d, &dlen, &tbs, &tbs_len) != 1 - || asn1_length_is_zero(tbs_len) != 1) { - error_print(); - return -1; - } - - if (x509_explicit_version_from_der(0, &ver, &d, &dlen) < 0 - || asn1_integer_from_der(&serial, &serial_len, &d, &dlen) != 1 - || x509_signature_algor_from_der(&inner_sig_alg, &d, &dlen) != 1 - || asn1_sequence_from_der(&isur, &isur_len, &d, &dlen) != 1 - || x509_validity_from_der(&before, &after, &d, &dlen) != 1 - || asn1_sequence_from_der(&subj, &subj_len, &d, &dlen) != 1 - || x509_public_key_info_from_der(&sm2_key, &d, &dlen) != 1 - || asn1_implicit_bit_octets_from_der(1, &isur_uniq_id, &isur_uniq_id_len, &d, &dlen) < 0 - || asn1_implicit_bit_octets_from_der(2, &subj_uniq_id, &subj_uniq_id_len, &d, &dlen) < 0 - || x509_explicit_exts_from_der(3, &exts, &exts_len, &d, &dlen) < 0) { - error_print(); - return -1; - } - - if (version) *version = ver; - if (serial_number) *serial_number = serial; - if (serial_number_len) *serial_number_len = serial_len; - if (inner_signature_algor) *inner_signature_algor = inner_sig_alg; - if (issuer) *issuer = isur; - if (issuer_len) *issuer_len = isur_len; - if (not_before) *not_before = before; - if (not_after) *not_after = after; - if (subject) *subject = subj; - if (subject_len) *subject_len = subj_len; - if (subject_public_key) *subject_public_key = sm2_key; - if (issuer_unique_id) *issuer_unique_id = isur_uniq_id; - if (issuer_unique_id_len) *issuer_unique_id_len = isur_uniq_id_len; - if (subject_unique_id) *subject_unique_id = subj_uniq_id; - if (subject_unique_id_len) *subject_unique_id_len = subj_uniq_id_len; - if (extensions) *extensions = exts; - if (extensions_len) *extensions_len = exts_len; - if (signature_algor) *signature_algor = sig_alg; - if (signature) *signature = sig; - if (signature_len) *signature_len = sig_len; - return 1; -} - -int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial_number, size_t *serial_number_len) -{ - return x509_cert_get_details(a, alen, - NULL, // version - serial_number, serial_number_len, // serial - NULL, // signature_algor - issuer, issuer_len, // issuer - NULL, NULL, // validity - NULL, NULL, // subject - NULL, // subject_public_key - NULL, NULL, // issuer_unique_id - NULL, NULL, // subject_unique_id - NULL, NULL, // extensions - NULL, // signature_algor - NULL, NULL); // signature -} - -int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key) -{ - return x509_cert_get_details(a, alen, - NULL, // version - NULL, NULL, // serial - NULL, // signature_algor - NULL, NULL, // issuer - NULL, NULL, // validity - NULL, NULL, // subject - public_key, // subject_public_key - NULL, NULL, // issuer_unique_id - NULL, NULL, // subject_unique_id - NULL, NULL, // extensions - NULL, // signature_algor - NULL, NULL); // signature -} - -int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen) -{ - return x509_cert_get_details(a, alen, - NULL, // version - NULL, NULL, // serial - NULL, // signature_algor - NULL, NULL, // issuer - NULL, NULL, // validity - d, dlen, // subject - NULL, // subject_public_key - NULL, NULL, // issuer_unique_id - NULL, NULL, // subject_unique_id - NULL, NULL, // extensions - NULL, // signature_algor - NULL, NULL); // signature -} - -int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen) -{ - return x509_cert_get_details(a, alen, - NULL, // version - NULL, NULL, // serial - NULL, // signature_algor - d, dlen, // issuer - NULL, NULL, // validity - NULL, NULL, // subject - NULL, // subject_public_key - NULL, NULL, // issuer_unique_id - NULL, NULL, // subject_unique_id - NULL, NULL, // extensions - NULL, // signature_algor - NULL, NULL); // signature -} - -int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp) -{ - const uint8_t *a; - size_t alen; - - while (dlen) { - if (asn1_any_from_der(&a, &alen, &d, &dlen) != 1 - || x509_cert_to_pem(a, alen, fp) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp) -{ - int ret; - size_t len, total_len = 0; - - for (;;) { - if ((ret = x509_cert_from_pem(d, &len, maxlen, fp)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - break; - } - d += len; - total_len += len; - maxlen -= len; - } - *dlen = total_len; - if (!total_len) { - return 0; - } - return 1; -} - -int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt) -{ - if (asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen) -{ - const uint8_t *a; - size_t alen; - int ret, i; - - for (i = 0; i <= index; i++) { - if ((ret = x509_cert_from_der(&a, &alen, &d, &dlen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return -1; - } - } - *cert = a; - *certlen = alen; - return 1; -} - -int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen) -{ - if (!dlen) { - error_print(); - return -1; - } - while (dlen) { - if (x509_cert_from_der(cert, certlen, &d, &dlen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, - const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen) -{ - const uint8_t *a; - size_t alen; - const uint8_t *subj; - size_t subj_len; - - while (dlen) { - if (x509_cert_from_der(&a, &alen, &d, &dlen) != 1) { - error_print(); - return -1; - } - if (x509_cert_get_subject(a, alen, &subj, &subj_len) != 1) { - error_print(); - return -1; - } - if (x509_name_equ(subj, subj_len, subject, subject_len) == 1) { - *cert = a; - *certlen = alen; - return 1; - } - } - error_print(); // 可能来自于没有找到对应的CA证书 - return 0; -} - -int x509_certs_get_cert_by_issuer_and_serial_number( - const uint8_t *certs, size_t certs_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - const uint8_t **cert, size_t *cert_len) -{ - const uint8_t *cur_issuer; - size_t cur_issuer_len; - const uint8_t *cur_serial; - size_t cur_serial_len; - - while (certs_len) { - if (asn1_any_from_der(cert, cert_len, &certs, &certs_len) != 1 - || x509_cert_get_issuer_and_serial_number(*cert, *cert_len, - &cur_issuer, &cur_issuer_len, - &cur_serial, &cur_serial_len) != 1) { - error_print(); - return -1; - } - if (cur_issuer_len == issuer_len - && memcmp(cur_issuer, issuer, issuer_len) == 0 - && cur_serial_len == serial_len - && memcmp(cur_serial, serial, serial_len) == 0) { - return 1; - } - } - return 0; -} - -int x509_cert_check(const uint8_t *cert, size_t certlen) -{ - time_t not_before; - time_t not_after; - time_t now; - - x509_cert_get_details(cert, certlen, - NULL, // version - NULL, NULL, // serial - NULL, // signature_algor - NULL, NULL, // issuer - ¬_before, ¬_after, // validity - NULL, NULL, // subject - NULL, // subject_public_key - NULL, NULL, // issuer_unique_id - NULL, NULL, // subject_unique_id - NULL, NULL, // extensions - NULL, // signature_algor - NULL, NULL); // signature - - // not_before < now < not_after - time(&now); - if (not_before >= not_after) { - error_print(); - return -1; - } - if (now < not_before) { - error_print(); - return X509_verify_err_cert_not_yet_valid; - } - if (not_after < now) { - error_print(); - return X509_verify_err_cert_has_expired; - } - - return 1; -} - -int x509_certs_verify(const uint8_t *certs, size_t certslen, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) -{ - const uint8_t *cert; - size_t certlen; - const uint8_t *cacert; - size_t cacertlen; - const uint8_t *name; - size_t namelen; - *verify_result = -1; - - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - while (certslen) { - - if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { - error_print(); - return -1; - } - if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - // 这里应该检查证书是否有效啊, 这个函数应该返回进一步的错误信息 - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - cert = cacert; - certlen = cacertlen; - } - if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) { - error_print(); - return -1; - } - if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, - &cacert, &cacertlen) != 1) { - error_print(); - return -1; - } - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - - return 1; -} - -int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) -{ - const uint8_t *signcert; - size_t signcertlen; - int signcert_verified = 0; - const uint8_t *cert; - size_t certlen; - const uint8_t *cacert; - size_t cacertlen; - const uint8_t *name; - size_t namelen; - - *verify_result = -1; - - if (x509_cert_from_der(&signcert, &signcertlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - // 要检查这两个证书的类型是否分别为签名和加密证书 - // FIXME: 检查depth - while (certslen) { - if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { - error_print(); - return -1; - } - if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - if (!signcert_verified) { - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - signcert_verified = 1; - } - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - cert = cacert; - certlen = cacertlen; - } - if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) { - error_print(); - return -1; - } - if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, &cacert, &cacertlen) != 1) { - // 当前证书链和提供的CA证书不匹配 - error_print(); - return -1; - } - if (!signcert_verified) { - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - } - if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, - SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - return 1; -} - - -int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_certificate_print(fp, fmt, ind, "Certficate", p, len); - } - return 1; -} - -#include -#include - -int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file) -{ - int ret = -1; - FILE *fp = NULL; - struct stat st; - uint8_t *buf = NULL; - size_t buflen; - - if (!(fp = fopen(file, "r")) - || fstat(fileno(fp), &st) < 0 - || (buflen = (st.st_size * 3)/4 + 1) < 0 - || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) { - error_print(); - goto end; - } - if (x509_cert_from_pem(buf, outlen, buflen, fp) != 1) { - error_print(); - goto end; - } - *out = buf; - buf = NULL; - ret = 1; -end: - if (fp) fclose(fp); - if (buf) free(buf); - return ret; -} - -int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file) -{ - int ret = -1; - FILE *fp = NULL; - struct stat st; - uint8_t *buf = NULL; - size_t buflen; - - if (!(fp = fopen(file, "r")) - || fstat(fileno(fp), &st) < 0 - || (buflen = (st.st_size * 3)/4 + 1) < 0 - || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) { - error_print(); - goto end; - } - if (x509_certs_from_pem(buf, outlen, buflen, fp) != 1) { - error_print(); - goto end; - } - *out = buf; - buf = NULL; - ret = 1; -end: - if (fp) fclose(fp); - if (buf) free(buf); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const char *x509_version_name(int version) +{ + switch (version) { + case X509_version_v1: return "v1"; + case X509_version_v2: return "v2"; + case X509_version_v3: return "v3"; + } + return NULL; +} + +int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + + if (version < 0) { + return 0; + } + if (!x509_version_name(version)) { + error_print(); + return -1; + } + if (asn1_int_to_der(version, NULL, &len) != 1 + || asn1_explicit_header_to_der(index, len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_explicit_from_der(index, &d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *version = -1; + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (!x509_version_name(*version)) { + error_print(); + return -1; + } + return 1; +} + +/* + from RFC 5280 section 4.1.2.5 + + CAs conforming to this profile MUST always encode certificate + validity dates through the year 2049 as UTCTime; certificate validity + dates in 2050 or later MUST be encoded as GeneralizedTime. + Conforming applications MUST be able to process validity dates that + are encoded in either UTCTime or GeneralizedTime. + + To indicate that a certificate has no well-defined expiration date, + the notAfter SHOULD be assigned the GeneralizedTime value of + 99991231235959Z. +*/ +int x509_time_to_der(time_t tv, uint8_t **out, size_t *outlen) +{ + int ret; + struct tm tm_val; + + gmtime_r(&tv, &tm_val); + if (tm_val.tm_year < 2050 - 1900) { + if ((ret = asn1_utc_time_to_der(tv, out, outlen)) != 1) { + if (ret < 0) error_print(); + } + } else { + if ((ret = asn1_generalized_time_to_der(tv, out, outlen)) !=1) { + if (ret < 0) error_print(); + } + } + return ret; +} + +int x509_time_from_der(time_t *tv, const uint8_t **in, size_t *inlen) +{ + int ret; + + if ((ret = asn1_utc_time_from_der(tv, in, inlen)) < 0) { + error_print(); + return -1; + } else if (ret) { + return 1; + } + + if ((ret = asn1_generalized_time_from_der(tv, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_validity_add_days(time_t *not_after, time_t not_before, int days) +{ + struct tm tm_val; + if (days < X509_VALIDITY_MIN_DAYS + || days > X509_VALIDITY_MAX_DAYS) { + error_print(); + return -1; + } + gmtime_r(¬_before, &tm_val); + tm_val.tm_mday += days; + *not_after = mktime(&tm_val); + return 1; +} + +int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_time_to_der(not_before, NULL, &len) != 1 + || x509_time_to_der(not_after, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_time_to_der(not_before, out, outlen) != 1 + || x509_time_to_der(not_after, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_time_from_der(not_before, &d, &dlen) != 1 + || x509_time_from_der(not_after, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*not_before >= *not_after) { + error_print(); + return -1; + } + return 1; +} + +int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + time_t tv; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "notBefore: %s", ctime(&tv)); + if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "notAfter: %s", ctime(&tv)); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + + +static const struct { + int oid; + int is_printable_string_only; + int minlen; + int maxlen; +} x509_name_types[] = { + { OID_at_country_name, 1, 2, 2 }, + { OID_at_state_or_province_name, 0, 1, X509_ub_state_name }, + { OID_at_locality_name, 0, 1, X509_ub_locality_name }, + { OID_at_organization_name, 0, 1, X509_ub_organization_name }, + { OID_at_organizational_unit_name, 0, 1, X509_ub_organizational_unit_name }, + { OID_at_common_name, 0, 1, X509_ub_common_name }, + { OID_at_serial_number, 1, 1, X509_ub_serial_number }, + { OID_at_dn_qualifier, 1, 1, 64 }, // max length unspecified in RFC 5280 + { OID_at_title, 0, 1, X509_ub_title }, + { OID_at_surname, 0, 1, X509_ub_name }, + { OID_at_given_name, 0, 1, X509_ub_name }, + { OID_at_initials, 0, 1, X509_ub_name }, + { OID_at_generation_qualifier, 0, 1, X509_ub_name }, + { OID_at_pseudonym, 0, 1, X509_ub_pseudonym }, +}; + +static const int x509_name_types_count + = sizeof(x509_name_types)/sizeof(x509_name_types[0]); + +int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen) +{ + int i; + for (i = 0; i < x509_name_types_count; i++) { + if (oid == x509_name_types[i].oid) { + if (x509_name_types[i].is_printable_string_only + && tag != ASN1_TAG_PrintableString) { + error_print(); + return -1; + } + if (x509_directory_name_check_ex(tag, val, vlen, + x509_name_types[i].minlen, x509_name_types[i].maxlen) != 1) { + error_print(); + return -1; + } + return 1; + } + } + error_print(); + return -1; +} + +int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_attr_type_and_value_check(oid, tag, val, vlen) != 1 + || x509_name_type_to_der(oid, NULL, &len) != 1 + || x509_directory_name_to_der(tag, val, vlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_name_type_to_der(oid, out, outlen) != 1 + || x509_directory_name_to_der(tag, val, vlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_name_type_from_der(oid, &d, &dlen) != 1 + || x509_directory_name_from_der(tag, val, vlen, &d, &dlen) != 1 + || x509_attr_type_and_value_check(*oid, *tag, *val, *vlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int oid, tag; + const uint8_t *val; + size_t vlen; + + if (fmt & ASN1_FMT_FULL) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0); + if (oid == OID_email_address) { + if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err; + format_string(fp, fmt, ind, "value", val, vlen); + } else { + if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err; + x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen); + } + } else { + if (x509_name_type_from_der(&oid, &d, &dlen) != 1) { error_print(); goto err; } + if (oid == OID_email_address) { + if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err; + format_string(fp, fmt, ind, "emailAddress", val, vlen); + } else { + if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err; + x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen); + } + } + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen, + const uint8_t *more, size_t morelen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_attr_type_and_value_to_der(oid, tag, val, vlen, NULL, &len) != 1 + || asn1_data_to_der(more, morelen, NULL, &len) < 0 + || asn1_set_header_to_der(len, out, outlen) != 1 + || x509_attr_type_and_value_to_der(oid, tag, val, vlen, out, outlen) != 1 + || asn1_data_to_der(more, morelen, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen, + const uint8_t **more, size_t *morelen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_set_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_attr_type_and_value_from_der(oid, tag, val, vlen, &d, &dlen) != 1) { + error_print(); + return -1; + } + if (dlen) { + *more = d; + *morelen = dlen; + // TODO: check more,morelen + } else { + *more = NULL; + *morelen = 0; + } + return 1; +} + +int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (fmt & ASN1_FMT_FULL) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len); + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_attr_type_and_value_print(fp, fmt, ind + 4, "AttributeTypeAndValue", p, len); + } + return 1; +} + +int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen, + int oid, int tag, const uint8_t *val, size_t vlen, + const uint8_t *more, size_t morelen) +{ + size_t len = 0; + uint8_t *p = d + *dlen; + if (!val && !more) { + return 0; + } + if (x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, NULL, &len) != 1 + || asn1_length_le(*dlen + len, maxlen) != 1 + || x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, &p, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2]) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, + OID_at_country_name, ASN1_TAG_PrintableString, (uint8_t *)val, 2, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen, + int tag, const uint8_t *val, size_t vlen) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_state_or_province_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen, + int tag, const uint8_t *val, size_t vlen) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_locality_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen, + int tag, const uint8_t *val, size_t vlen) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organization_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen, + int tag, const uint8_t *val, size_t vlen) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organizational_unit_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen, + int tag, const uint8_t *val, size_t vlen) +{ + int ret; + ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_common_name, tag, val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen, + const char *val, size_t vlen) +{ + int ret; + return x509_name_add_rdn(d, dlen, maxlen, OID_domain_component, ASN1_TAG_IA5String, (uint8_t *)val, vlen, NULL, 0); + if (ret < 0) error_print(); + return ret; +} + +static size_t _strlen(const char *s) { return s ? strlen(s) : 0; } + +int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen, + const char *country, const char *state, const char *locality, + const char *org, const char *org_unit, const char *common_name) +{ + int tag = ASN1_TAG_PrintableString; + if (country && strlen(country) != 2) { + error_print(); + return -1; + } + *dlen = 0; + if (x509_name_add_country_name(d, dlen, maxlen, country) < 0 + || x509_name_add_state_or_province_name(d, dlen, maxlen, tag, (uint8_t *)state, _strlen(state)) < 0 + || x509_name_add_locality_name(d, dlen, maxlen, tag, (uint8_t *)locality, _strlen(locality)) < 0 + || x509_name_add_organization_name(d, dlen, maxlen, tag, (uint8_t *)org, _strlen(org)) < 0 + || x509_name_add_organizational_unit_name(d, dlen, maxlen, tag, (uint8_t *)org_unit, _strlen(org_unit)) < 0 + || x509_name_add_common_name(d, dlen, maxlen, tag, (uint8_t *)common_name, _strlen(common_name)) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (label) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + while (dlen) { + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_rdn_print(fp, fmt, ind, "RelativeDistinguishedName", p, len); + } + return 1; +} + +int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_name_print(fp, fmt, ind, "Name", p, len); + } + return 1; +} + +int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen) +{ + const uint8_t *rdn_d; + size_t rdn_dlen; + + while (dlen) { + int attr_oid; + int attr_tag; + const uint8_t *attr_val; + size_t attr_vlen; + + if (asn1_set_from_der(&rdn_d, &rdn_dlen, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (rdn_dlen) { + if (x509_attr_type_and_value_from_der(&attr_oid, &attr_tag, &attr_val, &attr_vlen, + &rdn_d, &rdn_dlen) != 1) { + error_print(); + return -1; + } + } + if (attr_oid == oid) { + *tag = attr_tag; + *val = attr_val; + *vlen = attr_vlen; + return 1; + } + } + return 0; +} + +int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen) +{ + int ret; + ret = x509_name_get_value_by_type(d, dlen, OID_at_common_name, tag, val, vlen); + if (ret < 0) error_print(); + return -1; +} + +int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen) +{ + if (alen != blen || memcmp(a, b, blen) != 0) { + return 0; + } + return 1; +} + + +int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p = d; + size_t len = dlen; + int alg; + int params; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_public_key_algor_from_der(&alg, ¶ms, &p, &len) != 1) goto err; + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_public_key_algor_print(fp, fmt, ind, "algorithm", p, len); + format_print(fp, fmt, ind, "subjectPublicKey\n"); + ind += 4; + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + switch (alg) { + case OID_ec_public_key: + format_bytes(fp, fmt, ind, "ECPoint", p, len); + break; + case OID_rsa_encryption: + rsa_public_key_print(fp, fmt, ind, "RSAPublicKey", p, len); + break; + default: + format_bytes(fp, fmt, ind, "raw_data", p, len); + } + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_ext_id_to_der(oid, NULL, &len) != 1 + || asn1_boolean_to_der(critical, NULL, &len) < 0 + || asn1_octet_string_to_der(val, vlen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_ext_id_to_der(oid, out, outlen) != 1 + || asn1_boolean_to_der(critical, out, outlen) < 0 + || asn1_octet_string_to_der(val, vlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, + int *critical, const uint8_t **val, size_t *vlen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + *critical = 0; + if (x509_ext_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1 + || asn1_boolean_from_der(critical, &d, &dlen) < 0 + || asn1_octet_string_from_der(val, vlen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, oid, critical; + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *val; + size_t vlen; + + const uint8_t *p; + size_t len; + int ival; + const char *name; + + if (label) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_ext_id_name(oid), nodes, nodes_cnt); + if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); + if (asn1_octet_string_from_der(&val, &vlen, &d, &dlen) != 1) goto err; + + switch (oid) { + case OID_ce_subject_key_identifier: + if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1) { + error_print(); + return -1; + } + break; + case OID_ce_key_usage: + case OID_netscape_cert_type: + if (asn1_bits_from_der(&ival, &val, &vlen) != 1) { + error_print(); + return -1; + } + break; + case OID_ce_inhibit_any_policy: + if (asn1_int_from_der(&ival, &val, &vlen) != 1) { + error_print(); + return -1; + } + break; + case OID_netscape_cert_comment: + if (asn1_ia5_string_from_der((const char **)&p, &len, &val, &vlen) != 1) { + error_print(); + return -1; + } + break; + case OID_ct_precertificate_scts: + case OID_undef: + p = val; + len = vlen; + vlen = 0; + break; + default: + if (asn1_sequence_from_der(&p, &len, &val, &vlen) != 1) { + error_print(); + return -1; + } + } + if (asn1_length_is_zero(vlen) != 1) { + error_print(); + return -1; + } + + name = x509_ext_id_name(oid); + + switch (oid) { + case OID_ce_authority_key_identifier: return x509_authority_key_identifier_print(fp, fmt, ind, name, p, len); + case OID_ce_subject_key_identifier: return format_bytes(fp, fmt, ind, name, p, len); + case OID_ce_key_usage: return x509_key_usage_print(fp, fmt, ind, name, ival); + case OID_ce_certificate_policies: return x509_certificate_policies_print(fp, fmt, ind, name, p, len); + case OID_ce_policy_mappings: return x509_policy_mappings_print(fp, fmt, ind, name, p, len); + case OID_ce_subject_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len); + case OID_ce_issuer_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len); + case OID_ce_subject_directory_attributes: return x509_attributes_print(fp, fmt, ind, name, p, len); + case OID_ce_basic_constraints: return x509_basic_constraints_print(fp, fmt, ind, name, p, len); + case OID_ce_name_constraints: return x509_name_constraints_print(fp, fmt, ind, name, p, len); + case OID_ce_policy_constraints: return x509_policy_constraints_print(fp, fmt, ind, name, p, len); + case OID_ce_ext_key_usage: return x509_ext_key_usage_print(fp, fmt, ind, name, p, len); + case OID_ce_crl_distribution_points: return x509_crl_distribution_points_print(fp, fmt, ind, name, p, len); + case OID_ce_inhibit_any_policy: format_print(fp, fmt, ind, "%s: %d\n", name, ival); + case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len); + case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival); + case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len); + default: format_bytes(fp, fmt, ind, "extnValue", p, len); + } + return 1; +err: + error_print(); + return -1; +} + +int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (!d) { + return 0; + } + if (asn1_sequence_to_der(d, dlen, NULL, &len) != 1 + || asn1_explicit_header_to_der(index, len, out, outlen) != 1 + || asn1_sequence_to_der(d, dlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_sequence_from_der(d, dlen, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_get_count(const uint8_t *d, size_t dlen, size_t *cnt) +{ + return asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt); +} + +int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index, + int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical, + const uint8_t **val, size_t *vlen) +{ + error_print(); + return -1; +} + +int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid, + int *critical, const uint8_t **val, size_t *vlen) +{ + return -1; +} + +int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (label) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_ext_print(fp, fmt, ind, "Extension", p, len); + } + return 1; +} + +int x509_tbs_cert_to_der( + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, + const uint8_t *subject_unique_id, size_t subject_unique_id_len, + const uint8_t *exts, size_t exts_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_explicit_version_to_der(0, version, NULL, &len) < 0 + || asn1_integer_to_der(serial, serial_len, NULL, &len) != 1 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1 + || x509_validity_to_der(not_before, not_after, NULL, &len) != 1 + || asn1_sequence_to_der(subject, subject_len, NULL, &len) != 1 + || x509_public_key_info_to_der(subject_public_key, NULL, &len) != 1 + || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, NULL, &len) < 0 + || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, NULL, &len) < 0 + || x509_explicit_exts_to_der(3, exts, exts_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_explicit_version_to_der(0, version, out, outlen) < 0 + || asn1_integer_to_der(serial, serial_len, out, outlen) != 1 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1 + || x509_validity_to_der(not_before, not_after, out, outlen) != 1 + || asn1_sequence_to_der(subject, subject_len, out, outlen) != 1 + || x509_public_key_info_to_der(subject_public_key, out, outlen) != 1 + || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, out, outlen) < 0 + || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, out, outlen) < 0 + || x509_explicit_exts_to_der(3, exts, exts_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_tbs_cert_from_der( + int *version, + const uint8_t **serial, size_t *serial_len, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, + const uint8_t **subject_unique_id, size_t *subject_unique_id_len, + const uint8_t **exts, size_t *exts_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_explicit_version_from_der(0, version, &d, &dlen) < 0 + || asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || asn1_sequence_from_der(issuer, issuer_len, &d, &dlen) != 1 + || x509_validity_from_der(not_before, not_after, &d, &dlen) != 1 + || asn1_sequence_from_der(subject, subject_len, &d, &dlen) != 1 + || x509_public_key_info_from_der(subject_public_key, &d, &dlen) != 1 + || asn1_implicit_bit_octets_from_der(1, issuer_unique_id, issuer_unique_id_len, &d, &dlen) < 0 + || asn1_implicit_bit_octets_from_der(2, subject_unique_id, subject_unique_id_len, &d, &dlen) < 0 + || x509_explicit_exts_from_der(3, exts, exts_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = x509_explicit_version_from_der(0, &val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val); + if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "serialNumber", p, len); + if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "siganture: %s\n", x509_signature_algor_name(val)); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_name_print(fp, fmt, ind, "issuer", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_validity_print(fp, fmt, ind, "validity", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_name_print(fp, fmt, ind, "subject", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_public_key_info_print(fp, fmt, ind, "subjectPulbicKeyInfo", p, len); + if ((ret = asn1_implicit_bit_octets_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "issuerUniqueID", p, len); + if ((ret = asn1_implicit_bit_octets_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "subjectUniqueID", p, len); + if ((ret = x509_explicit_exts_from_der(3, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_exts_print(fp, fmt, ind, "extensions", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_certificate_to_der( + const uint8_t *tbs, size_t tbslen, // full TLV + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_data_to_der(tbs, tbslen, out, outlen) != 1 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_certificate_from_der( + const uint8_t **tbs, size_t *tbslen, // full TLV + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_any_from_der(tbs, tbslen, &d, &dlen) != 1 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + int val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_tbs_cert_print(fp, fmt, ind, "tbsCertificate", p, len); + if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val)); + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "signatureValue", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_cert_sign( + uint8_t *cert, size_t *certlen, size_t maxlen, + int version, + const uint8_t *serial, size_t serial_len, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t not_before, time_t not_after, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *issuer_unique_id, size_t issuer_unique_id_len, + const uint8_t *subject_unique_id, size_t subject_unique_id_len, + const uint8_t *exts, size_t exts_len, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len) +{ + uint8_t tbs[1024]; + size_t tbslen = 0; + uint8_t *p = tbs; + size_t len = 0; + SM2_SIGN_CTX sign_ctx; + int sig_alg = OID_sm2sign_with_sm3; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + if (x509_tbs_cert_to_der(version, serial, serial_len, signature_algor, + issuer, issuer_len, not_before, not_after, + subject, subject_len, subject_public_key, + issuer_unique_id, issuer_unique_id_len, + subject_unique_id, subject_unique_id_len, + exts, exts_len, NULL, &len) != 1 + || asn1_length_le(len, sizeof(tbs)) != 1 + || x509_tbs_cert_to_der(version, serial, serial_len, signature_algor, + issuer, issuer_len, not_before, not_after, + subject, subject_len, subject_public_key, + issuer_unique_id, issuer_unique_id_len, + subject_unique_id, subject_unique_id_len, + exts, exts_len, &p, &tbslen) != 1) { + error_print(); + return -1; + } + + if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 + || sm2_sign_update(&sign_ctx, tbs, tbslen) != 1 + || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + memset(&sign_ctx, 0, sizeof(sign_ctx)); + error_print(); + return -1; + } + memset(&sign_ctx, 0, sizeof(sign_ctx)); + + *certlen = len = 0; + if (x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, NULL, &len) != 1 + || asn1_length_le(len, maxlen) != 1 + || x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, &cert, certlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_cert_verify(const uint8_t *a, size_t alen, + const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len) +{ + int ret; + const uint8_t *tbs; + size_t tbslen; + int sig_alg; + const uint8_t *sig; + size_t siglen; + SM2_SIGN_CTX verify_ctx; + + if (x509_certificate_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + if (sig_alg != OID_sm2sign_with_sm3) { + error_print(); + return -1; + } + if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1 + || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1 + || (ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + error_print(); + return -1; + } + if (!ret) error_print(); + return ret; +} + +int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen, + const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len) +{ + int ret; + SM2_KEY public_key; + + if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 + || (ret = x509_cert_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { + error_print(); + return -1; + } + if (!ret) error_print(); + return ret; +} + +int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) +{ + return asn1_any_to_der(a, alen, out, outlen); +} + +int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen) +{ + return asn1_any_from_der(a, alen, in, inlen); +} + +int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp) +{ + if (pem_write(fp, "CERTIFICATE", a, alen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) +{ + int ret; + if ((ret = pem_read(fp, "CERTIFICATE", a, alen, maxlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp) +{ + int i; + for (i = 0; i <= index; i++) { + if (x509_cert_from_pem(a, alen, maxlen, fp) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp) +{ + int ret; + const uint8_t *d; + size_t dlen; + + for (;;) { + if ((ret = x509_cert_from_pem(a, alen, maxlen, fp)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_cert_get_subject(a, *alen, &d, &dlen) != 1) { + error_print(); + return -1; + } + + if (dlen == namelen && memcmp(name, d, dlen) == 0) { + return 1; + } + } + return 0; +} + +int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + const uint8_t *d; + size_t dlen; + + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) { + error_print(); + return -1; + } + x509_certificate_print(fp, fmt, ind, label, d, dlen); + if (asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_cert_get_details(const uint8_t *a, size_t alen, + int *version, + const uint8_t **serial_number, size_t *serial_number_len, + int *inner_signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *not_before, time_t *not_after, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len, + const uint8_t **subject_unique_id, size_t *subject_unique_id_len, + const uint8_t **extensions, size_t *extensions_len, + int *signature_algor, + const uint8_t **signature, size_t *signature_len) +{ + const uint8_t *tbs; + size_t tbs_len; + int sig_alg; + const uint8_t *sig; size_t sig_len; + + const uint8_t *d; + size_t dlen; + + int ver; + const uint8_t *serial; size_t serial_len; + int inner_sig_alg; + const uint8_t *isur; size_t isur_len; + time_t before, after; + const uint8_t *subj; size_t subj_len; + SM2_KEY sm2_key; + const uint8_t *isur_uniq_id; size_t isur_uniq_id_len; + const uint8_t *subj_uniq_id; size_t subj_uniq_id_len; + const uint8_t *exts; size_t exts_len; + + if (x509_certificate_from_der(&tbs, &tbs_len, &sig_alg, &sig, &sig_len, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + if (asn1_sequence_from_der(&d, &dlen, &tbs, &tbs_len) != 1 + || asn1_length_is_zero(tbs_len) != 1) { + error_print(); + return -1; + } + + if (x509_explicit_version_from_der(0, &ver, &d, &dlen) < 0 + || asn1_integer_from_der(&serial, &serial_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(&inner_sig_alg, &d, &dlen) != 1 + || asn1_sequence_from_der(&isur, &isur_len, &d, &dlen) != 1 + || x509_validity_from_der(&before, &after, &d, &dlen) != 1 + || asn1_sequence_from_der(&subj, &subj_len, &d, &dlen) != 1 + || x509_public_key_info_from_der(&sm2_key, &d, &dlen) != 1 + || asn1_implicit_bit_octets_from_der(1, &isur_uniq_id, &isur_uniq_id_len, &d, &dlen) < 0 + || asn1_implicit_bit_octets_from_der(2, &subj_uniq_id, &subj_uniq_id_len, &d, &dlen) < 0 + || x509_explicit_exts_from_der(3, &exts, &exts_len, &d, &dlen) < 0) { + error_print(); + return -1; + } + + if (version) *version = ver; + if (serial_number) *serial_number = serial; + if (serial_number_len) *serial_number_len = serial_len; + if (inner_signature_algor) *inner_signature_algor = inner_sig_alg; + if (issuer) *issuer = isur; + if (issuer_len) *issuer_len = isur_len; + if (not_before) *not_before = before; + if (not_after) *not_after = after; + if (subject) *subject = subj; + if (subject_len) *subject_len = subj_len; + if (subject_public_key) *subject_public_key = sm2_key; + if (issuer_unique_id) *issuer_unique_id = isur_uniq_id; + if (issuer_unique_id_len) *issuer_unique_id_len = isur_uniq_id_len; + if (subject_unique_id) *subject_unique_id = subj_uniq_id; + if (subject_unique_id_len) *subject_unique_id_len = subj_uniq_id_len; + if (extensions) *extensions = exts; + if (extensions_len) *extensions_len = exts_len; + if (signature_algor) *signature_algor = sig_alg; + if (signature) *signature = sig; + if (signature_len) *signature_len = sig_len; + return 1; +} + +int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial_number, size_t *serial_number_len) +{ + return x509_cert_get_details(a, alen, + NULL, // version + serial_number, serial_number_len, // serial + NULL, // signature_algor + issuer, issuer_len, // issuer + NULL, NULL, // validity + NULL, NULL, // subject + NULL, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature +} + +int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key) +{ + return x509_cert_get_details(a, alen, + NULL, // version + NULL, NULL, // serial + NULL, // signature_algor + NULL, NULL, // issuer + NULL, NULL, // validity + NULL, NULL, // subject + public_key, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature +} + +int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen) +{ + return x509_cert_get_details(a, alen, + NULL, // version + NULL, NULL, // serial + NULL, // signature_algor + NULL, NULL, // issuer + NULL, NULL, // validity + d, dlen, // subject + NULL, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature +} + +int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen) +{ + return x509_cert_get_details(a, alen, + NULL, // version + NULL, NULL, // serial + NULL, // signature_algor + d, dlen, // issuer + NULL, NULL, // validity + NULL, NULL, // subject + NULL, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature +} + +int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp) +{ + const uint8_t *a; + size_t alen; + + while (dlen) { + if (asn1_any_from_der(&a, &alen, &d, &dlen) != 1 + || x509_cert_to_pem(a, alen, fp) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp) +{ + int ret; + size_t len, total_len = 0; + + for (;;) { + if ((ret = x509_cert_from_pem(d, &len, maxlen, fp)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + break; + } + d += len; + total_len += len; + maxlen -= len; + } + *dlen = total_len; + if (!total_len) { + return 0; + } + return 1; +} + +int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt) +{ + if (asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen) +{ + const uint8_t *a; + size_t alen; + int ret, i; + + for (i = 0; i <= index; i++) { + if ((ret = x509_cert_from_der(&a, &alen, &d, &dlen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + } + *cert = a; + *certlen = alen; + return 1; +} + +int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen) +{ + if (!dlen) { + error_print(); + return -1; + } + while (dlen) { + if (x509_cert_from_der(cert, certlen, &d, &dlen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen, + const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen) +{ + const uint8_t *a; + size_t alen; + const uint8_t *subj; + size_t subj_len; + + while (dlen) { + if (x509_cert_from_der(&a, &alen, &d, &dlen) != 1) { + error_print(); + return -1; + } + if (x509_cert_get_subject(a, alen, &subj, &subj_len) != 1) { + error_print(); + return -1; + } + if (x509_name_equ(subj, subj_len, subject, subject_len) == 1) { + *cert = a; + *certlen = alen; + return 1; + } + } + error_print(); // 可能来自于没有找到对应的CA证书 + return 0; +} + +int x509_certs_get_cert_by_issuer_and_serial_number( + const uint8_t *certs, size_t certs_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + const uint8_t **cert, size_t *cert_len) +{ + const uint8_t *cur_issuer; + size_t cur_issuer_len; + const uint8_t *cur_serial; + size_t cur_serial_len; + + while (certs_len) { + if (asn1_any_from_der(cert, cert_len, &certs, &certs_len) != 1 + || x509_cert_get_issuer_and_serial_number(*cert, *cert_len, + &cur_issuer, &cur_issuer_len, + &cur_serial, &cur_serial_len) != 1) { + error_print(); + return -1; + } + if (cur_issuer_len == issuer_len + && memcmp(cur_issuer, issuer, issuer_len) == 0 + && cur_serial_len == serial_len + && memcmp(cur_serial, serial, serial_len) == 0) { + return 1; + } + } + return 0; +} + +int x509_cert_check(const uint8_t *cert, size_t certlen) +{ + time_t not_before; + time_t not_after; + time_t now; + + x509_cert_get_details(cert, certlen, + NULL, // version + NULL, NULL, // serial + NULL, // signature_algor + NULL, NULL, // issuer + ¬_before, ¬_after, // validity + NULL, NULL, // subject + NULL, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature + + // not_before < now < not_after + time(&now); + if (not_before >= not_after) { + error_print(); + return -1; + } + if (now < not_before) { + error_print(); + return X509_verify_err_cert_not_yet_valid; + } + if (not_after < now) { + error_print(); + return X509_verify_err_cert_has_expired; + } + + return 1; +} + +int x509_certs_verify(const uint8_t *certs, size_t certslen, + const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) +{ + const uint8_t *cert; + size_t certlen; + const uint8_t *cacert; + size_t cacertlen; + const uint8_t *name; + size_t namelen; + *verify_result = -1; + + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + while (certslen) { + + if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + // 这里应该检查证书是否有效啊, 这个函数应该返回进一步的错误信息 + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + cert = cacert; + certlen = cacertlen; + } + if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) { + error_print(); + return -1; + } + if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, + &cacert, &cacertlen) != 1) { + error_print(); + return -1; + } + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + + return 1; +} + +int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, + const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) +{ + const uint8_t *signcert; + size_t signcertlen; + int signcert_verified = 0; + const uint8_t *cert; + size_t certlen; + const uint8_t *cacert; + size_t cacertlen; + const uint8_t *name; + size_t namelen; + + *verify_result = -1; + + if (x509_cert_from_der(&signcert, &signcertlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + // 要检查这两个证书的类型是否分别为签名和加密证书 + // FIXME: 检查depth + while (certslen) { + if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + if (!signcert_verified) { + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + signcert_verified = 1; + } + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + cert = cacert; + certlen = cacertlen; + } + if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) { + error_print(); + return -1; + } + if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, &cacert, &cacertlen) != 1) { + // 当前证书链和提供的CA证书不匹配 + error_print(); + return -1; + } + if (!signcert_verified) { + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + } + if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, + SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + return 1; +} + + +int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_certificate_print(fp, fmt, ind, "Certficate", p, len); + } + return 1; +} + +#include +#include + +int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file) +{ + int ret = -1; + FILE *fp = NULL; + struct stat st; + uint8_t *buf = NULL; + size_t buflen; + + if (!(fp = fopen(file, "r")) + || fstat(fileno(fp), &st) < 0 + || (buflen = (st.st_size * 3)/4 + 1) < 0 + || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) { + error_print(); + goto end; + } + if (x509_cert_from_pem(buf, outlen, buflen, fp) != 1) { + error_print(); + goto end; + } + *out = buf; + buf = NULL; + ret = 1; +end: + if (fp) fclose(fp); + if (buf) free(buf); + return ret; +} + +int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file) +{ + int ret = -1; + FILE *fp = NULL; + struct stat st; + uint8_t *buf = NULL; + size_t buflen; + + if (!(fp = fopen(file, "r")) + || fstat(fileno(fp), &st) < 0 + || (buflen = (st.st_size * 3)/4 + 1) < 0 + || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) { + error_print(); + goto end; + } + if (x509_certs_from_pem(buf, outlen, buflen, fp) != 1) { + error_print(); + goto end; + } + *out = buf; + buf = NULL; + ret = 1; +end: + if (fp) fclose(fp); + if (buf) free(buf); + return ret; +} diff --git a/src/x509_crl.c b/src/x509_crl.c index 90bb8333..e9d1b7e4 100644 --- a/src/x509_crl.c +++ b/src/x509_crl.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1198 +7,1199 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char *x509_crl_reason_names[] = { - "unspecified", - "keyCompromise", - "cACompromise", - "affiliationChanged", - "superseded", - "cessationOfOperation", - "certificateHold", - "notAssigned", - "removeFromCRL", - "privilegeWithdrawn", - "aACompromise", -}; - -static const size_t x509_crl_reason_names_count = - sizeof(x509_crl_reason_names)/sizeof(x509_crl_reason_names[0]); - -const char *x509_crl_reason_name(int reason) -{ - if (reason < 0 || reason >= x509_crl_reason_names_count) { - error_print(); - return NULL; - } - return x509_crl_reason_names[reason]; -} - -int x509_crl_reason_from_name(int *reason, const char *name) -{ - int i; - for (i = 0; i < x509_crl_reason_names_count; i++) { - if (strcmp(name, x509_crl_reason_names[i]) == 0) { - *reason = i; - return 1; - } - } - return 0; -} - -int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen) -{ - if (reason >= 0 && !x509_crl_reason_name(reason)) { - error_print(); - return -1; - } - return asn1_enumerated_to_der(reason, out, outlen); -} - -int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen) -{ - return asn1_enumerated_from_der(reason, in, inlen); -} - -int x509_implicit_crl_reason_from_der(int index, int *reason, const uint8_t **in, size_t *inlen) -{ - return asn1_implicit_enumerated_from_der(index, reason, in, inlen); -} - - -static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; -static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; -static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; - -static const ASN1_OID_INFO x509_crl_entry_exts[] = { - { OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, sizeof(oid_ce_crl_reasons)/sizeof(int) }, - { OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, sizeof(oid_ce_invalidity_date)/sizeof(int) }, - { OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, sizeof(oid_ce_certificate_issuer)/sizeof(int) }, -}; - -static const int x509_crl_entry_exts_count = - sizeof(x509_crl_entry_exts)/sizeof(x509_crl_entry_exts[0]); - -const char *x509_crl_entry_ext_id_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_crl_entry_exts, x509_crl_entry_exts_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_crl_entry_ext_id_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_crl_entry_exts, x509_crl_entry_exts_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_crl_entry_exts, x509_crl_entry_exts_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - - if ((ret = asn1_oid_info_from_der(&info, x509_crl_entry_exts, x509_crl_entry_exts_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - -int x509_crl_entry_exts_add_reason(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, int reason) -{ - int oid = OID_ce_crl_reasons; - size_t curlen = *extslen; - uint8_t val[16]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (x509_crl_reason_to_der(reason, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_entry_exts_add_invalidity_date(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, time_t tv) -{ - int oid = OID_ce_invalidity_date; - size_t curlen = *extslen; - uint8_t val[16]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (asn1_generalized_time_to_der(tv, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_entry_exts_add_certificate_issuer(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_certificate_issuer; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_crl_entry_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, oid, critical; - const uint8_t *v; - size_t vlen; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_crl_entry_ext_id_from_der(&oid, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "extnID: %s\n", x509_crl_entry_ext_id_name(oid)); - if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); - if (asn1_octet_string_from_der(&v, &vlen, &d, &dlen) != 1) goto err; - - if (oid == OID_ce_crl_reasons) { - int reason; - if (x509_crl_reason_from_der(&reason, &v, &vlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "reasonCode: %s\n", x509_crl_reason_name(reason)); - - } else if (oid == OID_ce_invalidity_date) { - time_t invalidity_date; - if (asn1_generalized_time_from_der(&invalidity_date, &v, &vlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "invalidityDate: %s", ctime(&invalidity_date)); - - } else if (oid == OID_ce_certificate_issuer) { - const uint8_t *gns; - size_t gnslen; - if (asn1_sequence_from_der(&gns, &gnslen, &v, &vlen) != 1) { - error_print(); - return -1; - } - x509_general_names_print(fp, fmt, ind, "certificateIssuer", gns, gnslen); - - } else { -err: - error_print(); - return -1; - } - - return 1; -} - -int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_crl_entry_ext_print(fp, fmt, ind, "Extension", p, len); - } - return 1; -} - -int x509_revoked_cert_to_der( - const uint8_t *serial, size_t serial_len, - time_t revoke_date, - const uint8_t *entry_exts, size_t entry_exts_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_integer_to_der(serial, serial_len, NULL, &len) != 1 - || x509_time_to_der(revoke_date, NULL, &len) != 1 - || asn1_sequence_to_der(entry_exts, entry_exts_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_integer_to_der(serial, serial_len, out, outlen) != 1 - || x509_time_to_der(revoke_date, out, outlen) != 1 - || asn1_sequence_to_der(entry_exts, entry_exts_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_revoked_cert_from_der( - const uint8_t **serial, size_t *serial_len, - time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1 - || x509_time_from_der(revoke_date, &d, &dlen) != 1 - || asn1_sequence_from_der(entry_exts, entry_exts_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - time_t tv; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "userCertificate", p, len); - if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "revocationDate: %s", ctime(&tv)); - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen, - const uint8_t *serial, size_t serial_len, - time_t revoke_date, - const uint8_t *entry_exts, size_t entry_exts_len) -{ - error_print(); - return -1; -} - -int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen, - const uint8_t *serial, size_t serial_len, - time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len) -{ - error_print(); - return -1; -} - -int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_revoked_cert_print(fp, fmt, ind, "RevokedCertificate", p, len); - } - return 1; -} - - -static uint32_t oid_ce_authority_key_identifier[] = { oid_ce,35 }; -static uint32_t oid_ce_issuer_alt_name[] = { oid_ce,18 }; -static uint32_t oid_ce_crl_number[] = { oid_ce,20 }; -static uint32_t oid_ce_delta_crl_indicator[] = { oid_ce,27 }; -static uint32_t oid_ce_issuing_distribution_point[] = { oid_ce,28 }; -static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 }; -static uint32_t oid_pe_authority_info_access[] = { oid_pe,1 }; - - -static const ASN1_OID_INFO x509_crl_exts[] = { - { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, sizeof(oid_ce_authority_key_identifier)/sizeof(int) }, - { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, sizeof(oid_ce_issuer_alt_name)/sizeof(int) }, - { OID_ce_crl_number, "CRLNumber", oid_ce_crl_number, sizeof(oid_ce_crl_number)/sizeof(int) }, - { OID_ce_delta_crl_indicator, "DeltaCRLIndicator", oid_ce_delta_crl_indicator, sizeof(oid_ce_delta_crl_indicator)/sizeof(int) }, - { OID_ce_issuing_distribution_point, "IssuingDistributionPoint", oid_ce_issuing_distribution_point, sizeof(oid_ce_issuing_distribution_point)/sizeof(int) }, - { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, sizeof(oid_ce_freshest_crl)/sizeof(int) }, - { OID_pe_authority_info_access, "AuthorityInfoAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) }, -}; - -static const int x509_crl_exts_count = - sizeof(x509_crl_exts)/sizeof(x509_crl_exts[0]); - -const char *x509_crl_ext_id_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_crl_exts, x509_crl_exts_count, oid))) { - return NULL; - } - return info->name; -} - -int x509_crl_ext_id_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_crl_exts, x509_crl_exts_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - size_t len = 0; - if (!(info = asn1_oid_info_from_oid(x509_crl_exts, x509_crl_exts_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_ext_id_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - const ASN1_OID_INFO *info; - - *oid = 0; - if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_crl_exts, x509_crl_exts_count, in, inlen)) != 1) { - error_print(); - return -1; - } - if (info) { - *oid = info->oid; - } - return ret; -} - -int x509_crl_exts_add_authority_key_identifier( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len) -{ - if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical, - keyid, keyid_len, issuer, issuer_len, serial, serial_len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_exts_add_issuer_alt_name( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *d, size_t dlen) -{ - if (x509_exts_add_issuer_alt_name(exts, extslen, maxlen, critical, d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_exts_add_crl_number( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - int num) -{ - int oid = OID_ce_crl_number; - size_t curlen = *extslen; - uint8_t val[32]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (asn1_int_to_der(num, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_exts_add_delta_crl_indicator( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - int num) -{ - int oid = OID_ce_delta_crl_indicator; - size_t curlen = *extslen; - uint8_t val[32]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (asn1_int_to_der(num, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_exts_add_issuing_distribution_point( - uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *dist_point, size_t dist_point_len, - int only_contains_user_certs, - int only_contains_ca_certs, - int only_some_reasons, - int indirect_crl, - int only_contains_attr_certs) -{ - error_print(); - return -1; -} - -int x509_issuing_distribution_point_to_der( - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int only_contains_user_certs, - int only_contains_ca_certs, - int only_some_reasons, - int indirect_crl, - int only_contains_attr_certs, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0 - || asn1_implicit_boolean_to_der(1, only_contains_user_certs, NULL, &len) < 0 - || asn1_implicit_boolean_to_der(2, only_contains_ca_certs, NULL, &len) < 0 - || asn1_implicit_bits_to_der(3, only_some_reasons, NULL, &len) < 0 // 是否有特化的类型 - || asn1_implicit_boolean_to_der(4, indirect_crl, NULL, &len) < 0 - || asn1_implicit_boolean_to_der(5, only_contains_attr_certs, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0 - || asn1_implicit_boolean_to_der(1, only_contains_user_certs, out, outlen) < 0 - || asn1_implicit_boolean_to_der(2, only_contains_ca_certs, out, outlen) < 0 - || asn1_implicit_bits_to_der(3, only_some_reasons, out, outlen) < 0 // 是否有特化的类型 - || asn1_implicit_boolean_to_der(4, indirect_crl, out, outlen) < 0 - || asn1_implicit_boolean_to_der(5, only_contains_attr_certs, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_issuing_distribution_point_from_der( - int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, - int *only_contains_user_certs, - int *only_contains_ca_certs, - int *only_some_reasons, - int *indirect_crl, - int *only_contains_attr_certs, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0 - || asn1_implicit_boolean_from_der(1, only_contains_user_certs, &d, &dlen) < 0 - || asn1_implicit_boolean_from_der(2, only_contains_ca_certs, &d, &dlen) < 0 - || asn1_implicit_bits_from_der(3, only_some_reasons, &d, &dlen) < 0 - || asn1_implicit_boolean_from_der(4, indirect_crl, &d, &dlen) < 0 - || asn1_implicit_boolean_from_der(5, only_contains_attr_certs, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto end; - if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); - if ((ret = asn1_implicit_boolean_from_der(1, &val, &d, &dlen)) < 0) goto end; - if (!ret) val = 0; - format_print(fp, fmt, ind, "onlyContainsUserCerts: %s\n", asn1_boolean_name(val)); - if ((ret = asn1_implicit_boolean_from_der(2, &val, &d, &dlen)) < 0) goto end; - if (!ret) val = 0; - format_print(fp, fmt, ind, "onlyContainsCACerts: %s\n", asn1_boolean_name(val)); - if ((ret = x509_implicit_crl_reason_from_der(3, &val, &d, &dlen)) < 0) goto end; - if (ret) format_print(fp, fmt, ind, "onlySomeReasons: %s\n", x509_crl_reason_name(val)); - if ((ret = asn1_implicit_boolean_from_der(4, &val, &d, &dlen)) < 0) goto end; - if (!ret) val = 0; - format_print(fp, fmt, ind, "indirectCRL: %s\n", asn1_boolean_name(val)); - if ((ret = asn1_implicit_boolean_from_der(5, &val, &d, &dlen)) < 0) goto end; - if (!ret) val = 0; - format_print(fp, fmt, ind, "onlyContainsAttributeCerts: %s\n", asn1_boolean_name(val)); - if (asn1_length_is_zero(dlen) != 1) goto end; - return 1; -end: - error_print(); - return -1; -} - -int x509_access_descriptions_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - error_print(); - return -1; -} - -int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, oid, critical; - const char *name; - const uint8_t *v; - size_t vlen; - const uint8_t *p; - size_t len; - uint32_t nodes[32]; - size_t nodes_cnt; - int num; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_crl_ext_id_from_der_ex(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_crl_ext_id_name(oid), nodes, nodes_cnt); - if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); - if (asn1_octet_string_from_der(&v, &vlen, &d, &dlen) != 1) goto err; - - switch (oid) { - case OID_ce_authority_key_identifier: - case OID_ce_issuer_alt_name: - case OID_ce_issuing_distribution_point: - case OID_ce_freshest_crl: - case OID_pe_authority_info_access: - if (asn1_sequence_from_der(&p, &len, &v, &vlen) != 1) { - error_print(); - return -1; - } - break; - case OID_ce_crl_number: - case OID_ce_delta_crl_indicator: - if (asn1_int_from_der(&num, &v, &vlen) != 1) { - error_print(); - return -1; - } - break; - default: - if (asn1_any_from_der(&p, &len, &v, &vlen) != 1) { - error_print(); - return -1; - } - } - - name = x509_crl_ext_id_name(oid); - - switch (oid) { - case OID_ce_authority_key_identifier: x509_authority_key_identifier_print(fp, fmt, ind, name, p, len); break; - case OID_ce_issuer_alt_name: x509_general_names_print(fp, fmt, ind, name, p, len); break; - case OID_ce_crl_number: format_print(fp, fmt, ind, "%s: %d\n", name, num); break; - case OID_ce_delta_crl_indicator: format_print(fp, fmt, ind, "%s: %d\n", name, num); break; - case OID_ce_issuing_distribution_point: x509_issuing_distribution_point_print(fp, fmt, ind, name, p, len); break; - case OID_ce_freshest_crl: x509_crl_distribution_points_print(fp, fmt, ind, name, p, len); break; - case OID_pe_authority_info_access: x509_access_descriptions_print(fp, fmt, ind, name, p, len); break; - default: format_bytes(fp, fmt, ind, "value", p, len); - } - if (asn1_length_is_zero(vlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_crl_ext_print(fp, fmt, ind, "Extension", p, len); - } - return 1; -} - -int x509_tbs_crl_to_der( - int version, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t this_update, time_t next_update, - const uint8_t *revoked_certs, size_t revoked_certs_len, - const uint8_t *exts, size_t exts_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_int_to_der(version, NULL, &len) < 0 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || x509_name_to_der(issuer, issuer_len, NULL, &len) != 1 - || x509_time_to_der(this_update, NULL, &len) != 1 - || x509_time_to_der(next_update, NULL, &len) < 0 - || asn1_sequence_to_der(revoked_certs, revoked_certs_len, NULL, &len) < 0 - || asn1_sequence_to_der(exts, exts_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) < 0 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || x509_name_to_der(issuer, issuer_len, out, outlen) != 1 - || x509_time_to_der(this_update, out, outlen) != 1 - || x509_time_to_der(next_update, out, outlen) < 0 - || asn1_sequence_to_der(revoked_certs, revoked_certs_len, out, outlen) < 0 - || asn1_sequence_to_der(exts, exts_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_tbs_crl_from_der( - int *version, - int *signature_algor, - const uint8_t **issuer, size_t *issuer_len, - time_t *this_update, - time_t *next_update, - const uint8_t **revoked_certs, size_t *revoked_certs_len, - const uint8_t **exts, size_t *exts_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) < 0 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || x509_name_from_der(issuer, issuer_len, &d, &dlen) != 1 - || x509_time_from_der(this_update, &d, &dlen) != 1 - || x509_time_from_der(next_update, &d, &dlen) < 0 - || asn1_sequence_from_der(revoked_certs, revoked_certs_len, &d, &dlen) < 0 - || x509_explicit_exts_from_der(0, exts, exts_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*version >= 0 && *version != X509_version_v2) { - error_print(); - return -1; - } - if (*revoked_certs && *version != X509_version_v2) { - error_print(); - return -1; - } - if (*exts && *version != X509_version_v2) { - error_print(); - return -1; - } - - return 1; -} - -int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - const uint8_t *p; - size_t len; - time_t tv; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val); - if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "signature: %s\n", x509_signature_algor_name(val)); - if (x509_name_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "issuer", p, len); - if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "thisUpdate: %s", ctime(&tv)); - if ((ret = x509_time_from_der(&tv, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "nextUpdate: %s", ctime(&tv)); - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_revoked_certs_print(fp, fmt, ind, "revokedCertificates", p, len); - if ((ret = x509_explicit_exts_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) { - x509_crl_exts_print(fp, fmt, ind, "crlExtensions", p, len); - } - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len, - int signature_algor, const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_sequence_to_der(tbs_crl, tbs_crl_len, NULL, &len) != 1 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_sequence_to_der(tbs_crl, tbs_crl_len, out, outlen) != 1 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len, - int *signature_algor, const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_sequence_from_der(tbs_crl, tbs_crl_len, &d, &dlen) != 1 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int val; - const uint8_t *p; - size_t len; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_tbs_crl_print(fp, fmt, ind, "tbsCertList", p, len); - if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val)); - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "signatureValue", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -// FIXME: 这两个函数应该检查CRL格式是否正确 -int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) -{ - int ret; - if ((ret = asn1_any_to_der(a, alen, out, outlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen) -{ - int ret; - if ((ret = asn1_any_from_der(a, alen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp) -{ - if (pem_write(fp, "X509 CRL", a, alen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) -{ - int ret; - if ((ret = pem_read(fp, "X509 CRL", a, alen, maxlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp) -{ - if (fwrite(a, 1, alen, fp) != alen) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) -{ - size_t len; - const uint8_t *d = a; - size_t dlen; - const uint8_t *crl; - size_t crl_len; - - if (!(len = fread(a, 1, maxlen, fp))) { - if (feof(fp)) { - return 0; - } else { - error_print(); - return -1; - } - } - - dlen = len; - if (x509_crl_from_der(&crl, &crl_len, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - - *alen = len; - return 1; -} - - -int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - const uint8_t *d; - size_t dlen; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - x509_cert_list_print(fp, fmt, ind, label, d, dlen); - return 1; -} - -int x509_tbs_crl_sign( - int version, - int signature_algor, - const uint8_t *issuer, size_t issuer_len, - time_t this_update, time_t next_update, - const uint8_t *revoked_certs, size_t revoked_certs_len, - const uint8_t *exts, size_t exts_len, - const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len, - uint8_t *crl, size_t *crl_len) -{ - uint8_t tbs[512]; - size_t tbslen; - SM2_SIGN_CTX sign_ctx; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - uint8_t *p = tbs; - size_t len = 0; - uint8_t *out = crl; - size_t outlen = 0; - - if (x509_tbs_crl_to_der(version, signature_algor, issuer, issuer_len, - this_update, next_update, revoked_certs, revoked_certs_len, - exts, exts_len, &p, &tbslen) != 1) { - error_print(); - return -1; - } - if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 - || sm2_sign_update(&sign_ctx, tbs, tbslen) != 1 - || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { - error_print(); - return -1; - } - if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, &out, &outlen) != 1 - || asn1_data_to_der(tbs, tbslen, &out, &outlen) != 1 - || x509_signature_algor_to_der(signature_algor, &out, &outlen) != 1 - || asn1_bit_octets_to_der(sig, siglen, &out, &outlen) != 1) { - error_print(); - return -1; - } - *crl_len = outlen; - return 1; -} - -int x509_crl_verify(const uint8_t *a, size_t alen, - const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *tbs; - size_t tbslen; - int sig_alg; - const uint8_t *sig; - size_t siglen; - SM2_SIGN_CTX verify_ctx; - - if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return -1; - } - if (asn1_any_from_der(&tbs, &tbslen, &d, &dlen) != 1 - || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (sig_alg != OID_sm2sign_with_sm3) { - error_print(); - return -1; - } - if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1 - || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1) { - error_print(); - return -1; - } - if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return -1; - } - return 1; -} - -int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, - const char *signer_id, size_t signer_id_len) -{ - int ret; - SM2_KEY public_key; - - if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 - || (ret = x509_crl_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { - error_print(); - return -1; - } - if (!ret) error_print(); - return ret; -} - -int x509_crl_get_details(const uint8_t *a, size_t alen, - int *opt_version, - const uint8_t **opt_issuer, size_t *opt_issuer_len, - time_t *opt_this_update, - time_t *opt_next_update, - const uint8_t **opt_revoked_certs, size_t *opt_revoked_certs_len, - const uint8_t **opt_exts, size_t *opt_exts_len, - int *opt_signature_algor, - const uint8_t **opt_sig, size_t *opt_siglen) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *tbs; - size_t tbs_len; - int signature_algor; - const uint8_t *sig; - size_t siglen; - - int version; - int sig_alg; - const uint8_t *issuer; - size_t issuer_len; - time_t this_update; - time_t next_update; - const uint8_t *revoked_certs; - size_t revoked_certs_len; - const uint8_t *exts; - size_t exts_len; - - if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return -1; - } - if (asn1_any_from_der(&tbs, &tbs_len, &d, &dlen) != 1 - || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (opt_signature_algor) *opt_signature_algor = signature_algor; - if (opt_sig) *opt_sig = sig; - if (opt_siglen) *opt_siglen = siglen; - - if (x509_tbs_crl_from_der(&version, &sig_alg, &issuer, &issuer_len, - &this_update, &next_update, &revoked_certs, &revoked_certs_len, - &exts, &exts_len, &tbs, &tbs_len) != 1 - || asn1_length_is_zero(tbs_len) != 1) { - error_print(); - return -1; - } - - if (opt_version) *opt_version = version; - if (opt_issuer) *opt_issuer = issuer; - if (opt_issuer_len) *opt_issuer_len = issuer_len; - if (opt_this_update) *opt_this_update = this_update; - if (opt_next_update) *opt_next_update = next_update; - if (opt_revoked_certs) *opt_revoked_certs = revoked_certs; - if (opt_revoked_certs_len) *opt_revoked_certs_len = revoked_certs_len; - if (opt_exts) *opt_exts = exts; - if (opt_exts_len) *opt_exts_len = exts_len; - return 1; -} - -int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, - const uint8_t **issuer, size_t *issuer_len) -{ - if (x509_crl_get_details(crl, crl_len, - NULL, // version - issuer, issuer_len, - NULL, NULL, // this_udpate, next_update - NULL, NULL, // revoked_certs, revoked_certs_len - NULL, NULL, // exts, exts_len, - NULL, // signature_algor - NULL, NULL // sig, siglen - ) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, - const uint8_t *serial, size_t serial_len, - time_t *revoke_date, - const uint8_t **entry_exts, size_t *entry_exts_len) -{ - const uint8_t *certs; - size_t certslen; - - if (x509_crl_get_details(a, alen, - NULL, NULL, NULL, NULL, NULL, - &certs, &certslen, - NULL, NULL, NULL, NULL, NULL) != 1) { - error_print(); - return -1; - } - while (certslen) { - const uint8_t *serial_number; - size_t serial_number_len; - - if (x509_revoked_cert_from_der( - &serial_number, &serial_number_len, - revoke_date, - entry_exts, entry_exts_len, - &certs, &certslen) != 1) { - error_print(); - return -1; - } - if (serial_number_len == serial_len - && memcmp(serial_number, serial, serial_len) == 0) { - return 1; - } - } - - return 0; -} - -int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_cert_list_print(fp, fmt, ind, "CertificateRevocationList", p, len); - } - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *x509_crl_reason_names[] = { + "unspecified", + "keyCompromise", + "cACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "notAssigned", + "removeFromCRL", + "privilegeWithdrawn", + "aACompromise", +}; + +static const size_t x509_crl_reason_names_count = + sizeof(x509_crl_reason_names)/sizeof(x509_crl_reason_names[0]); + +const char *x509_crl_reason_name(int reason) +{ + if (reason < 0 || reason >= x509_crl_reason_names_count) { + error_print(); + return NULL; + } + return x509_crl_reason_names[reason]; +} + +int x509_crl_reason_from_name(int *reason, const char *name) +{ + int i; + for (i = 0; i < x509_crl_reason_names_count; i++) { + if (strcmp(name, x509_crl_reason_names[i]) == 0) { + *reason = i; + return 1; + } + } + return 0; +} + +int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen) +{ + if (reason >= 0 && !x509_crl_reason_name(reason)) { + error_print(); + return -1; + } + return asn1_enumerated_to_der(reason, out, outlen); +} + +int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen) +{ + return asn1_enumerated_from_der(reason, in, inlen); +} + +int x509_implicit_crl_reason_from_der(int index, int *reason, const uint8_t **in, size_t *inlen) +{ + return asn1_implicit_enumerated_from_der(index, reason, in, inlen); +} + + +static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; +static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; +static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; + +static const ASN1_OID_INFO x509_crl_entry_exts[] = { + { OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, sizeof(oid_ce_crl_reasons)/sizeof(int) }, + { OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, sizeof(oid_ce_invalidity_date)/sizeof(int) }, + { OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, sizeof(oid_ce_certificate_issuer)/sizeof(int) }, +}; + +static const int x509_crl_entry_exts_count = + sizeof(x509_crl_entry_exts)/sizeof(x509_crl_entry_exts[0]); + +const char *x509_crl_entry_ext_id_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_crl_entry_exts, x509_crl_entry_exts_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_crl_entry_ext_id_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_crl_entry_exts, x509_crl_entry_exts_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_crl_entry_exts, x509_crl_entry_exts_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + + if ((ret = asn1_oid_info_from_der(&info, x509_crl_entry_exts, x509_crl_entry_exts_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + +int x509_crl_entry_exts_add_reason(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, int reason) +{ + int oid = OID_ce_crl_reasons; + size_t curlen = *extslen; + uint8_t val[16]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (x509_crl_reason_to_der(reason, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_entry_exts_add_invalidity_date(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, time_t tv) +{ + int oid = OID_ce_invalidity_date; + size_t curlen = *extslen; + uint8_t val[16]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (asn1_generalized_time_to_der(tv, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_entry_exts_add_certificate_issuer(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_certificate_issuer; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_crl_entry_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, oid, critical; + const uint8_t *v; + size_t vlen; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_crl_entry_ext_id_from_der(&oid, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "extnID: %s\n", x509_crl_entry_ext_id_name(oid)); + if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); + if (asn1_octet_string_from_der(&v, &vlen, &d, &dlen) != 1) goto err; + + if (oid == OID_ce_crl_reasons) { + int reason; + if (x509_crl_reason_from_der(&reason, &v, &vlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "reasonCode: %s\n", x509_crl_reason_name(reason)); + + } else if (oid == OID_ce_invalidity_date) { + time_t invalidity_date; + if (asn1_generalized_time_from_der(&invalidity_date, &v, &vlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "invalidityDate: %s", ctime(&invalidity_date)); + + } else if (oid == OID_ce_certificate_issuer) { + const uint8_t *gns; + size_t gnslen; + if (asn1_sequence_from_der(&gns, &gnslen, &v, &vlen) != 1) { + error_print(); + return -1; + } + x509_general_names_print(fp, fmt, ind, "certificateIssuer", gns, gnslen); + + } else { +err: + error_print(); + return -1; + } + + return 1; +} + +int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_crl_entry_ext_print(fp, fmt, ind, "Extension", p, len); + } + return 1; +} + +int x509_revoked_cert_to_der( + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_integer_to_der(serial, serial_len, NULL, &len) != 1 + || x509_time_to_der(revoke_date, NULL, &len) != 1 + || asn1_sequence_to_der(entry_exts, entry_exts_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_integer_to_der(serial, serial_len, out, outlen) != 1 + || x509_time_to_der(revoke_date, out, outlen) != 1 + || asn1_sequence_to_der(entry_exts, entry_exts_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_revoked_cert_from_der( + const uint8_t **serial, size_t *serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1 + || x509_time_from_der(revoke_date, &d, &dlen) != 1 + || asn1_sequence_from_der(entry_exts, entry_exts_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + time_t tv; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "userCertificate", p, len); + if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "revocationDate: %s", ctime(&tv)); + if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen, + const uint8_t *serial, size_t serial_len, + time_t revoke_date, + const uint8_t *entry_exts, size_t entry_exts_len) +{ + error_print(); + return -1; +} + +int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen, + const uint8_t *serial, size_t serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len) +{ + error_print(); + return -1; +} + +int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_revoked_cert_print(fp, fmt, ind, "RevokedCertificate", p, len); + } + return 1; +} + + +static uint32_t oid_ce_authority_key_identifier[] = { oid_ce,35 }; +static uint32_t oid_ce_issuer_alt_name[] = { oid_ce,18 }; +static uint32_t oid_ce_crl_number[] = { oid_ce,20 }; +static uint32_t oid_ce_delta_crl_indicator[] = { oid_ce,27 }; +static uint32_t oid_ce_issuing_distribution_point[] = { oid_ce,28 }; +static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 }; +static uint32_t oid_pe_authority_info_access[] = { oid_pe,1 }; + + +static const ASN1_OID_INFO x509_crl_exts[] = { + { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, sizeof(oid_ce_authority_key_identifier)/sizeof(int) }, + { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, sizeof(oid_ce_issuer_alt_name)/sizeof(int) }, + { OID_ce_crl_number, "CRLNumber", oid_ce_crl_number, sizeof(oid_ce_crl_number)/sizeof(int) }, + { OID_ce_delta_crl_indicator, "DeltaCRLIndicator", oid_ce_delta_crl_indicator, sizeof(oid_ce_delta_crl_indicator)/sizeof(int) }, + { OID_ce_issuing_distribution_point, "IssuingDistributionPoint", oid_ce_issuing_distribution_point, sizeof(oid_ce_issuing_distribution_point)/sizeof(int) }, + { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, sizeof(oid_ce_freshest_crl)/sizeof(int) }, + { OID_pe_authority_info_access, "AuthorityInfoAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) }, +}; + +static const int x509_crl_exts_count = + sizeof(x509_crl_exts)/sizeof(x509_crl_exts[0]); + +const char *x509_crl_ext_id_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_crl_exts, x509_crl_exts_count, oid))) { + return NULL; + } + return info->name; +} + +int x509_crl_ext_id_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_crl_exts, x509_crl_exts_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + size_t len = 0; + if (!(info = asn1_oid_info_from_oid(x509_crl_exts, x509_crl_exts_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_ext_id_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + const ASN1_OID_INFO *info; + + *oid = 0; + if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_crl_exts, x509_crl_exts_count, in, inlen)) != 1) { + error_print(); + return -1; + } + if (info) { + *oid = info->oid; + } + return ret; +} + +int x509_crl_exts_add_authority_key_identifier( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len) +{ + if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical, + keyid, keyid_len, issuer, issuer_len, serial, serial_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_exts_add_issuer_alt_name( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *d, size_t dlen) +{ + if (x509_exts_add_issuer_alt_name(exts, extslen, maxlen, critical, d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_exts_add_crl_number( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num) +{ + int oid = OID_ce_crl_number; + size_t curlen = *extslen; + uint8_t val[32]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (asn1_int_to_der(num, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_exts_add_delta_crl_indicator( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + int num) +{ + int oid = OID_ce_delta_crl_indicator; + size_t curlen = *extslen; + uint8_t val[32]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (asn1_int_to_der(num, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_exts_add_issuing_distribution_point( + uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *dist_point, size_t dist_point_len, + int only_contains_user_certs, + int only_contains_ca_certs, + int only_some_reasons, + int indirect_crl, + int only_contains_attr_certs) +{ + error_print(); + return -1; +} + +int x509_issuing_distribution_point_to_der( + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int only_contains_user_certs, + int only_contains_ca_certs, + int only_some_reasons, + int indirect_crl, + int only_contains_attr_certs, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0 + || asn1_implicit_boolean_to_der(1, only_contains_user_certs, NULL, &len) < 0 + || asn1_implicit_boolean_to_der(2, only_contains_ca_certs, NULL, &len) < 0 + || asn1_implicit_bits_to_der(3, only_some_reasons, NULL, &len) < 0 // 是否有特化的类型 + || asn1_implicit_boolean_to_der(4, indirect_crl, NULL, &len) < 0 + || asn1_implicit_boolean_to_der(5, only_contains_attr_certs, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0 + || asn1_implicit_boolean_to_der(1, only_contains_user_certs, out, outlen) < 0 + || asn1_implicit_boolean_to_der(2, only_contains_ca_certs, out, outlen) < 0 + || asn1_implicit_bits_to_der(3, only_some_reasons, out, outlen) < 0 // 是否有特化的类型 + || asn1_implicit_boolean_to_der(4, indirect_crl, out, outlen) < 0 + || asn1_implicit_boolean_to_der(5, only_contains_attr_certs, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_issuing_distribution_point_from_der( + int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, + int *only_contains_user_certs, + int *only_contains_ca_certs, + int *only_some_reasons, + int *indirect_crl, + int *only_contains_attr_certs, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0 + || asn1_implicit_boolean_from_der(1, only_contains_user_certs, &d, &dlen) < 0 + || asn1_implicit_boolean_from_der(2, only_contains_ca_certs, &d, &dlen) < 0 + || asn1_implicit_bits_from_der(3, only_some_reasons, &d, &dlen) < 0 + || asn1_implicit_boolean_from_der(4, indirect_crl, &d, &dlen) < 0 + || asn1_implicit_boolean_from_der(5, only_contains_attr_certs, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto end; + if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); + if ((ret = asn1_implicit_boolean_from_der(1, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsUserCerts: %s\n", asn1_boolean_name(val)); + if ((ret = asn1_implicit_boolean_from_der(2, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsCACerts: %s\n", asn1_boolean_name(val)); + if ((ret = x509_implicit_crl_reason_from_der(3, &val, &d, &dlen)) < 0) goto end; + if (ret) format_print(fp, fmt, ind, "onlySomeReasons: %s\n", x509_crl_reason_name(val)); + if ((ret = asn1_implicit_boolean_from_der(4, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "indirectCRL: %s\n", asn1_boolean_name(val)); + if ((ret = asn1_implicit_boolean_from_der(5, &val, &d, &dlen)) < 0) goto end; + if (!ret) val = 0; + format_print(fp, fmt, ind, "onlyContainsAttributeCerts: %s\n", asn1_boolean_name(val)); + if (asn1_length_is_zero(dlen) != 1) goto end; + return 1; +end: + error_print(); + return -1; +} + +int x509_access_descriptions_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + error_print(); + return -1; +} + +int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, oid, critical; + const char *name; + const uint8_t *v; + size_t vlen; + const uint8_t *p; + size_t len; + uint32_t nodes[32]; + size_t nodes_cnt; + int num; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_crl_ext_id_from_der_ex(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_crl_ext_id_name(oid), nodes, nodes_cnt); + if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical)); + if (asn1_octet_string_from_der(&v, &vlen, &d, &dlen) != 1) goto err; + + switch (oid) { + case OID_ce_authority_key_identifier: + case OID_ce_issuer_alt_name: + case OID_ce_issuing_distribution_point: + case OID_ce_freshest_crl: + case OID_pe_authority_info_access: + if (asn1_sequence_from_der(&p, &len, &v, &vlen) != 1) { + error_print(); + return -1; + } + break; + case OID_ce_crl_number: + case OID_ce_delta_crl_indicator: + if (asn1_int_from_der(&num, &v, &vlen) != 1) { + error_print(); + return -1; + } + break; + default: + if (asn1_any_from_der(&p, &len, &v, &vlen) != 1) { + error_print(); + return -1; + } + } + + name = x509_crl_ext_id_name(oid); + + switch (oid) { + case OID_ce_authority_key_identifier: x509_authority_key_identifier_print(fp, fmt, ind, name, p, len); break; + case OID_ce_issuer_alt_name: x509_general_names_print(fp, fmt, ind, name, p, len); break; + case OID_ce_crl_number: format_print(fp, fmt, ind, "%s: %d\n", name, num); break; + case OID_ce_delta_crl_indicator: format_print(fp, fmt, ind, "%s: %d\n", name, num); break; + case OID_ce_issuing_distribution_point: x509_issuing_distribution_point_print(fp, fmt, ind, name, p, len); break; + case OID_ce_freshest_crl: x509_crl_distribution_points_print(fp, fmt, ind, name, p, len); break; + case OID_pe_authority_info_access: x509_access_descriptions_print(fp, fmt, ind, name, p, len); break; + default: format_bytes(fp, fmt, ind, "value", p, len); + } + if (asn1_length_is_zero(vlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_crl_ext_print(fp, fmt, ind, "Extension", p, len); + } + return 1; +} + +int x509_tbs_crl_to_der( + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_int_to_der(version, NULL, &len) < 0 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || x509_name_to_der(issuer, issuer_len, NULL, &len) != 1 + || x509_time_to_der(this_update, NULL, &len) != 1 + || x509_time_to_der(next_update, NULL, &len) < 0 + || asn1_sequence_to_der(revoked_certs, revoked_certs_len, NULL, &len) < 0 + || asn1_sequence_to_der(exts, exts_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) < 0 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || x509_name_to_der(issuer, issuer_len, out, outlen) != 1 + || x509_time_to_der(this_update, out, outlen) != 1 + || x509_time_to_der(next_update, out, outlen) < 0 + || asn1_sequence_to_der(revoked_certs, revoked_certs_len, out, outlen) < 0 + || asn1_sequence_to_der(exts, exts_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_tbs_crl_from_der( + int *version, + int *signature_algor, + const uint8_t **issuer, size_t *issuer_len, + time_t *this_update, + time_t *next_update, + const uint8_t **revoked_certs, size_t *revoked_certs_len, + const uint8_t **exts, size_t *exts_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) < 0 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || x509_name_from_der(issuer, issuer_len, &d, &dlen) != 1 + || x509_time_from_der(this_update, &d, &dlen) != 1 + || x509_time_from_der(next_update, &d, &dlen) < 0 + || asn1_sequence_from_der(revoked_certs, revoked_certs_len, &d, &dlen) < 0 + || x509_explicit_exts_from_der(0, exts, exts_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*version >= 0 && *version != X509_version_v2) { + error_print(); + return -1; + } + if (*revoked_certs && *version != X509_version_v2) { + error_print(); + return -1; + } + if (*exts && *version != X509_version_v2) { + error_print(); + return -1; + } + + return 1; +} + +int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + const uint8_t *p; + size_t len; + time_t tv; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val); + if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "signature: %s\n", x509_signature_algor_name(val)); + if (x509_name_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_name_print(fp, fmt, ind, "issuer", p, len); + if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "thisUpdate: %s", ctime(&tv)); + if ((ret = x509_time_from_der(&tv, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "nextUpdate: %s", ctime(&tv)); + if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_revoked_certs_print(fp, fmt, ind, "revokedCertificates", p, len); + if ((ret = x509_explicit_exts_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) { + x509_crl_exts_print(fp, fmt, ind, "crlExtensions", p, len); + } + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len, + int signature_algor, const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_sequence_to_der(tbs_crl, tbs_crl_len, NULL, &len) != 1 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_sequence_to_der(tbs_crl, tbs_crl_len, out, outlen) != 1 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len, + int *signature_algor, const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_sequence_from_der(tbs_crl, tbs_crl_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int val; + const uint8_t *p; + size_t len; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_tbs_crl_print(fp, fmt, ind, "tbsCertList", p, len); + if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val)); + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "signatureValue", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +// FIXME: 这两个函数应该检查CRL格式是否正确 +int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen) +{ + int ret; + if ((ret = asn1_any_to_der(a, alen, out, outlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen) +{ + int ret; + if ((ret = asn1_any_from_der(a, alen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp) +{ + if (pem_write(fp, "X509 CRL", a, alen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) +{ + int ret; + if ((ret = pem_read(fp, "X509 CRL", a, alen, maxlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp) +{ + if (fwrite(a, 1, alen, fp) != alen) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp) +{ + size_t len; + const uint8_t *d = a; + size_t dlen; + const uint8_t *crl; + size_t crl_len; + + if (!(len = fread(a, 1, maxlen, fp))) { + if (feof(fp)) { + return 0; + } else { + error_print(); + return -1; + } + } + + dlen = len; + if (x509_crl_from_der(&crl, &crl_len, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + + *alen = len; + return 1; +} + + +int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + const uint8_t *d; + size_t dlen; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + x509_cert_list_print(fp, fmt, ind, label, d, dlen); + return 1; +} + +int x509_tbs_crl_sign( + int version, + int signature_algor, + const uint8_t *issuer, size_t issuer_len, + time_t this_update, time_t next_update, + const uint8_t *revoked_certs, size_t revoked_certs_len, + const uint8_t *exts, size_t exts_len, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len, + uint8_t *crl, size_t *crl_len) +{ + uint8_t tbs[512]; + size_t tbslen; + SM2_SIGN_CTX sign_ctx; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + uint8_t *p = tbs; + size_t len = 0; + uint8_t *out = crl; + size_t outlen = 0; + + if (x509_tbs_crl_to_der(version, signature_algor, issuer, issuer_len, + this_update, next_update, revoked_certs, revoked_certs_len, + exts, exts_len, &p, &tbslen) != 1) { + error_print(); + return -1; + } + if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 + || sm2_sign_update(&sign_ctx, tbs, tbslen) != 1 + || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + error_print(); + return -1; + } + if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, &out, &outlen) != 1 + || asn1_data_to_der(tbs, tbslen, &out, &outlen) != 1 + || x509_signature_algor_to_der(signature_algor, &out, &outlen) != 1 + || asn1_bit_octets_to_der(sig, siglen, &out, &outlen) != 1) { + error_print(); + return -1; + } + *crl_len = outlen; + return 1; +} + +int x509_crl_verify(const uint8_t *a, size_t alen, + const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *tbs; + size_t tbslen; + int sig_alg; + const uint8_t *sig; + size_t siglen; + SM2_SIGN_CTX verify_ctx; + + if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + if (asn1_any_from_der(&tbs, &tbslen, &d, &dlen) != 1 + || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (sig_alg != OID_sm2sign_with_sm3) { + error_print(); + return -1; + } + if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1 + || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1) { + error_print(); + return -1; + } + if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + return 1; +} + +int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen, + const char *signer_id, size_t signer_id_len) +{ + int ret; + SM2_KEY public_key; + + if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1 + || (ret = x509_crl_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) { + error_print(); + return -1; + } + if (!ret) error_print(); + return ret; +} + +int x509_crl_get_details(const uint8_t *a, size_t alen, + int *opt_version, + const uint8_t **opt_issuer, size_t *opt_issuer_len, + time_t *opt_this_update, + time_t *opt_next_update, + const uint8_t **opt_revoked_certs, size_t *opt_revoked_certs_len, + const uint8_t **opt_exts, size_t *opt_exts_len, + int *opt_signature_algor, + const uint8_t **opt_sig, size_t *opt_siglen) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *tbs; + size_t tbs_len; + int signature_algor; + const uint8_t *sig; + size_t siglen; + + int version; + int sig_alg; + const uint8_t *issuer; + size_t issuer_len; + time_t this_update; + time_t next_update; + const uint8_t *revoked_certs; + size_t revoked_certs_len; + const uint8_t *exts; + size_t exts_len; + + if ((ret = asn1_sequence_from_der(&d, &dlen, &a, &alen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + if (asn1_any_from_der(&tbs, &tbs_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(&sig_alg, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (opt_signature_algor) *opt_signature_algor = signature_algor; + if (opt_sig) *opt_sig = sig; + if (opt_siglen) *opt_siglen = siglen; + + if (x509_tbs_crl_from_der(&version, &sig_alg, &issuer, &issuer_len, + &this_update, &next_update, &revoked_certs, &revoked_certs_len, + &exts, &exts_len, &tbs, &tbs_len) != 1 + || asn1_length_is_zero(tbs_len) != 1) { + error_print(); + return -1; + } + + if (opt_version) *opt_version = version; + if (opt_issuer) *opt_issuer = issuer; + if (opt_issuer_len) *opt_issuer_len = issuer_len; + if (opt_this_update) *opt_this_update = this_update; + if (opt_next_update) *opt_next_update = next_update; + if (opt_revoked_certs) *opt_revoked_certs = revoked_certs; + if (opt_revoked_certs_len) *opt_revoked_certs_len = revoked_certs_len; + if (opt_exts) *opt_exts = exts; + if (opt_exts_len) *opt_exts_len = exts_len; + return 1; +} + +int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len, + const uint8_t **issuer, size_t *issuer_len) +{ + if (x509_crl_get_details(crl, crl_len, + NULL, // version + issuer, issuer_len, + NULL, NULL, // this_udpate, next_update + NULL, NULL, // revoked_certs, revoked_certs_len + NULL, NULL, // exts, exts_len, + NULL, // signature_algor + NULL, NULL // sig, siglen + ) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen, + const uint8_t *serial, size_t serial_len, + time_t *revoke_date, + const uint8_t **entry_exts, size_t *entry_exts_len) +{ + const uint8_t *certs; + size_t certslen; + + if (x509_crl_get_details(a, alen, + NULL, NULL, NULL, NULL, NULL, + &certs, &certslen, + NULL, NULL, NULL, NULL, NULL) != 1) { + error_print(); + return -1; + } + while (certslen) { + const uint8_t *serial_number; + size_t serial_number_len; + + if (x509_revoked_cert_from_der( + &serial_number, &serial_number_len, + revoke_date, + entry_exts, entry_exts_len, + &certs, &certslen) != 1) { + error_print(); + return -1; + } + if (serial_number_len == serial_len + && memcmp(serial_number, serial, serial_len) == 0) { + return 1; + } + } + + return 0; +} + +int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_cert_list_print(fp, fmt, ind, "CertificateRevocationList", p, len); + } + return 1; +} diff --git a/src/x509_ext.c b/src/x509_ext.c index f1e26492..cec6f7dc 100644 --- a/src/x509_ext.c +++ b/src/x509_ext.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1782 +7,1783 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen, - int oid, int critical, const uint8_t *d, size_t dlen) -{ - uint8_t val[32 + dlen]; - uint8_t *p = val; - size_t curlen = *extslen; - size_t vlen = 0; - - exts += *extslen; - if (asn1_sequence_to_der(d, dlen, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len) -{ - int oid = OID_ce_authority_key_identifier; - size_t curlen = *extslen; - uint8_t val[512]; - uint8_t *p = val; - size_t vlen = 0; - size_t len = 0; - - exts += *extslen; - if (x509_authority_key_identifier_to_der( - keyid, keyid_len, - issuer, issuer_len, - serial, serial_len, - NULL, &len) != 1 - || asn1_length_le(len, sizeof(val)) != 1 - || x509_authority_key_identifier_to_der( - keyid, keyid_len, - issuer, issuer_len, - serial, serial_len, - &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, - const SM2_KEY *public_key) -{ - uint8_t buf[65]; - uint8_t id[32]; - int critical = -1; - - sm2_point_to_uncompressed_octets(&public_key->public_key, buf); - sm3_digest(buf, sizeof(buf), id); - - if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical, - id, sizeof(id), NULL, 0, NULL, 0) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_subject_key_identifier; - size_t curlen = *extslen; - uint8_t val[32 + X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN]; - uint8_t *p = val; - size_t vlen = 0; - - if (dlen < X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN - || dlen > X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN) { - error_print(); - return -1; - } - - exts += *extslen; - if (asn1_octet_string_to_der(d, dlen, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits) -{ - int oid = OID_ce_key_usage; - size_t curlen = *extslen; - uint8_t val[16]; - uint8_t *p = val; - size_t vlen = 0; - - if (!bits) { - // TODO: 检查是否在合法范围内 - error_print(); - return -1; - } - - exts += *extslen; - if (asn1_bits_to_der(bits, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_certificate_policies; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_policy_mappings; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_subject_alt_name; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_issuer_alt_name; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_subject_directory_attributes; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, - const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, - const uint8_t *excluded_subtrees, size_t excluded_subtrees_len) -{ - int oid = OID_ce_name_constraints; - size_t curlen = *extslen; - uint8_t val[512]; - uint8_t *p = val; - size_t vlen = 0; - size_t len = 0; - - exts += *extslen; - if (x509_name_constraints_to_der( - permitted_subtrees, permitted_subtrees_len, - excluded_subtrees, excluded_subtrees_len, - NULL, &len) != 1 - || asn1_length_le(len, sizeof(val)) != 1 - || x509_name_constraints_to_der( - permitted_subtrees, permitted_subtrees_len, - excluded_subtrees, excluded_subtrees_len, - &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, int require_explicit_policy, int inhibit_policy_mapping) -{ - int oid = OID_ce_policy_constraints; - size_t curlen = *extslen; - uint8_t val[32]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (x509_policy_constraints_to_der( - require_explicit_policy, - inhibit_policy_mapping, - &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, int ca, int path_len_constraint) -{ - int oid = OID_ce_basic_constraints; - size_t curlen = *extslen; - uint8_t val[32]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (x509_basic_constraints_to_der(ca, path_len_constraint, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const int *key_purposes, size_t key_purposes_cnt) -{ - int oid = OID_ce_ext_key_usage; - size_t curlen = *extslen; - uint8_t val[256]; - uint8_t *p = val; - size_t vlen = 0; - size_t len = 0; - - exts += *extslen; - if (x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, NULL, &len) != 1 - || asn1_length_le(len, sizeof(val)) != 1 - || x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_crl_distribution_points; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, int skip_certs) -{ - int oid = OID_ce_inhibit_any_policy; - size_t curlen = *extslen; - uint8_t val[16]; - uint8_t *p = val; - size_t vlen = 0; - - exts += *extslen; - if (x509_inhibit_any_policy_to_der(skip_certs, &p, &vlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 - || asn1_length_le(curlen, maxlen) != 1 - || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, - int critical, const uint8_t *d, size_t dlen) -{ - int oid = OID_ce_freshest_crl; - return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); -} - -int x509_other_name_to_der( - const uint32_t *type_nodes, size_t type_nodes_cnt, - const uint8_t *value, size_t value_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, NULL, &len) != 1 - || asn1_explicit_to_der(0, value, value_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, out, outlen) != 1 - || asn1_explicit_to_der(0, value, value_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_other_name_from_der( - uint32_t *type_nodes, size_t *type_nodes_cnt, - const uint8_t **value, size_t *value_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_object_identifier_from_der(type_nodes, type_nodes_cnt, &p, &len) != 1 - || asn1_explicit_from_der(0, value, value_len, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "type-id", NULL, nodes, nodes_cnt); - if (asn1_explicit_from_der(0, &p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "value", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_edi_party_name_to_der( - int assigner_choice, const uint8_t *assigner, size_t assigner_len, - int party_name_choice, const uint8_t *party_name, size_t party_name_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, NULL, &len) < 0 - || x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, out, outlen) < 0 - || x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_edi_party_name_from_der( - int *assigner_choice, const uint8_t **assigner, size_t *assigner_len, - int *party_name_choice, const uint8_t **party_name, size_t *party_name_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_explicit_directory_name_from_der(0, assigner_choice, assigner, assigner_len, &p, &len) < 0 - || x509_explicit_directory_name_from_der(1, party_name_choice, party_name, party_name_len, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - int tag; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = x509_explicit_directory_name_from_der(0, &tag, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_directory_name_print(fp, fmt, ind, "nameAssigner", tag, p, len); - if (x509_explicit_directory_name_from_der(1, &tag, &p, &len, &d, &dlen) != 1) goto err; - x509_directory_name_print(fp, fmt, ind, "partyName", tag, p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -// GeneralName CHOICE 中有的是基本类型,有的是SEQUENCE,在设置标签时是否有区别? -// 这里是否支持OPTIONAL?? -int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - return asn1_implicit_to_der(choice, d, dlen, out, outlen); -} - -int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - int tag; - if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - switch (tag) { - case ASN1_TAG_EXPLICIT(0): *choice = 0; break; - case ASN1_TAG_IMPLICIT(1): *choice = 1; break; - case ASN1_TAG_IMPLICIT(2): *choice = 2; break; - case ASN1_TAG_EXPLICIT(3): *choice = 3; break; - case ASN1_TAG_EXPLICIT(4): *choice = 4; break; - case ASN1_TAG_EXPLICIT(5): *choice = 5; break; - case ASN1_TAG_IMPLICIT(6): *choice = 6; break; - case ASN1_TAG_IMPLICIT(7): *choice = 7; break; - case ASN1_TAG_IMPLICIT(8): *choice = 8; break; - default: - fprintf(stderr, "%s %d: tag = %x\n", __FILE__, __LINE__, tag); - error_print(); - return -1; - } - return 1; -} - -int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - switch (choice) { - case 0: - case 3: - case 4: - case 5: - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - d = p; - dlen = len; - } - switch (choice) { - case 0: return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen); - case 1: return asn1_string_print(fp, fmt, ind, "rfc822Name", ASN1_TAG_IA5String, d, dlen); - case 2: return asn1_string_print(fp, fmt, ind, "DNSName", ASN1_TAG_IA5String, d, dlen); - case 3: return format_bytes(fp, fmt, ind, "x400Address", d, dlen); - case 4: return x509_name_print(fp, fmt, ind, "directoryName", d, dlen); - case 5: return x509_edi_party_name_print(fp, fmt, ind, "ediPartyName", d, dlen); - case 6: return asn1_string_print(fp, fmt, ind, "URI", ASN1_TAG_IA5String, d, dlen); - case 7: return format_bytes(fp, fmt, ind, "IPAddress", d, dlen); - case 8: - { - uint32_t nodes[32]; - size_t nodes_cnt; - if (asn1_object_identifier_from_octets(nodes, &nodes_cnt, d, dlen) != 1) { - error_print(); - return -1; - } - return asn1_object_identifier_print(fp, fmt, ind, "registeredID", NULL, nodes, nodes_cnt); - } - default: - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - int choice, const uint8_t *d, size_t dlen) -{ - size_t len = 0; - uint8_t *p = gns + *gnslen; - - switch (choice) { - case X509_gn_rfc822_name: - case X509_gn_dns_name: - case X509_gn_uniform_resource_identifier: - if (asn1_ia5_string_check((char *)d, dlen) != 1) { - error_print(); - return -1; - } - break; - } - if (x509_general_name_to_der(choice, d, dlen, NULL, &len) != 1 - || asn1_length_le(*gnslen + len, maxlen) != 1 - || x509_general_name_to_der(choice, d, dlen, &p, gnslen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - const uint32_t *nodes, size_t nodes_cnt, - const uint8_t *value, size_t value_len) -{ - int choice = X509_gn_other_name; - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - if (x509_other_name_to_der(nodes, nodes_cnt, value, value_len, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen, - int assigner_tag, const uint8_t *assigner, size_t assigner_len, - int party_name_tag, const uint8_t *party_name, size_t party_name_len) -{ - int choice = X509_gn_edi_party_name; - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - if (x509_edi_party_name_to_der( - assigner_tag, assigner, assigner_len, - party_name_tag, party_name, party_name_len, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen, - const uint32_t *nodes, size_t nodes_cnt) -{ - int choice = X509_gn_registered_id; - uint8_t d[128]; - size_t dlen; - - if (asn1_object_identifier_to_octets(nodes, nodes_cnt, d, &dlen) != 1 - || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int choice; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_general_name_print(fp, fmt, ind, "GeneralName", choice, p, len); - } - return 1; -} - -int x509_authority_key_identifier_to_der( - const uint8_t *keyid, size_t keyid_len, - const uint8_t *issuer, size_t issuer_len, - const uint8_t *serial, size_t serial_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_implicit_octet_string_to_der(0, keyid, keyid_len, NULL, &len) < 0 - || asn1_implicit_sequence_to_der(1, issuer, issuer_len, NULL, &len) < 0 - || asn1_implicit_integer_to_der(2, serial, serial_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_implicit_octet_string_to_der(0, keyid, keyid_len, out, outlen) < 0 - || asn1_implicit_sequence_to_der(1, issuer, issuer_len, out, outlen) < 0 - || asn1_implicit_integer_to_der(2, serial, serial_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_authority_key_identifier_from_der( - const uint8_t **keyid, size_t *keyid_len, - const uint8_t **issuer, size_t *issuer_len, - const uint8_t **serial, size_t *serial_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_implicit_octet_string_from_der(0, keyid, keyid_len, &d, &dlen) < 0 - || asn1_implicit_sequence_from_der(1, issuer, issuer_len, &d, &dlen) < 0 - || asn1_implicit_integer_from_der(2, serial, serial_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "keyIdentifier", p, len); - if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_general_names_print(fp, fmt, ind, "authorityCertIssuer", p, len); - if ((ret = asn1_implicit_integer_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) format_bytes(fp, fmt, ind, "authorityCertSerialNumber", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -static const char *x509_key_usages[] = { - "digitalSignature", - "nonRepudiation", - "keyEncipherment", - "dataEncipherment", - "keyAgreement", - "keyCertSign", - "cRLSign", - "encipherOnly", - "decipherOnly", -}; - -static size_t x509_key_usages_count = - sizeof(x509_key_usages)/sizeof(x509_key_usages[0]); - -const char *x509_key_usage_name(int flag) -{ - int i; - for (i = 0; i < x509_key_usages_count; i++) { - if (flag & 1) { - if (flag >> 1) { - error_print(); - return NULL; - } - return x509_key_usages[i]; - } - flag >>= 1; - } - error_print(); - return NULL; -} - -int x509_key_usage_from_name(int *flag, const char *name) -{ - int i; - for (i = 0; i < x509_key_usages_count; i++) { - if (strcmp(name, x509_key_usages[i]) == 0) { - *flag = 1 << i; - return 1; - } - } - *flag = 0; - error_print(); - return -1; -} - -int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits) -{ - return asn1_bits_print(fp, fmt, ind, label, x509_key_usages, x509_key_usages_count, bits); -} - -int x509_notice_reference_to_der( - int org_tag, const uint8_t *org, size_t org_len, - const int *notice_numbers, size_t notice_numbers_cnt, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_display_text_to_der(org_tag, org, org_len, NULL, &len) != 1 - || asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_display_text_to_der(org_tag, org, org_len, out, outlen) != 1 - || asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_notice_reference_from_der( - int *org_tag, const uint8_t **org, size_t *org_len, - int notice_numbers[X509_MAX_NOTICE_NUMBERS], size_t *notice_numbers_cnt, size_t max_notice_numbers, //FIXME: max_notice_numbers 还没检查 - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - else error_print(); - return ret; - } - if (x509_display_text_from_der(org_tag, org, org_len, &d, &dlen) != 1 - || asn1_sequence_of_int_from_der(notice_numbers, notice_numbers_cnt, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int tag; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_display_text_from_der(&tag, &p, &len, &d, &dlen) != 1) goto err; - x509_display_text_print(fp, fmt, ind, "organization", tag, p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - asn1_sequence_of_int_print(fp, fmt, ind, "noticeNumbers", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_user_notice_to_der( - int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len, - const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt, - int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_notice_reference_to_der( - notice_ref_org_tag, notice_ref_org, notice_ref_org_len, - notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, - NULL, &len) < 0 - || x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_notice_reference_to_der( - notice_ref_org_tag, notice_ref_org, notice_ref_org_len, - notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, - out, outlen) < 0 - || x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_user_notice_from_der( - int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len, - int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, // FIXME: max_notice_ref_notice_numbers - int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_notice_reference_from_der(notice_ref_org_tag, notice_ref_org, notice_ref_org_len, - notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, max_notice_ref_notice_numbers, &d, &dlen) < 0 - || x509_display_text_from_der(explicit_text_tag, explicit_text, explicit_text_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - int tag; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_notice_reference_print(fp, fmt, ind, "noticeRef", p, len); - if ((ret = x509_display_text_from_der(&tag, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_display_text_print(fp, fmt, ind, "explicitText", tag, p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -// 是否要针对oid = cps的IA5String做一个方便的接口呢?毕竟oid 只有两个可选项 -int x509_policy_qualifier_info_to_der( - int oid, - const uint8_t *qualifier, size_t qualifier_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_qualifier_id_to_der(oid, NULL, &len) != 1 - || asn1_any_to_der(qualifier, qualifier_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_qualifier_id_to_der(oid, out, outlen) != 1 - || asn1_any_to_der(qualifier, qualifier_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_qualifier_info_from_der(int *oid, const uint8_t **qualifier, size_t *qualifier_len, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_qualifier_id_from_der(oid, &p, &len) != 1 - || asn1_any_from_der(qualifier, qualifier_len, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int oid; - const uint8_t *p; - size_t len; - - if (x509_qualifier_id_from_der(&oid, &d, &dlen) != 1) goto err; - switch (oid) { - case OID_qt_cps: - if (asn1_ia5_string_from_der((const char **)&p, &len, &d, &dlen) != 1) goto err; - format_string(fp, fmt, ind, "cPSuri", p, len); - break; - case OID_qt_unotice: - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_user_notice_print(fp, fmt, ind, "userNotice", p, len); - break; - } - return 1; -err: - error_print(); - return -1; -} - -int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_policy_qualifier_info_print(fp, fmt, ind, "PolicyQualifierInfo", p, len); - } - return 1; -} - -int x509_policy_information_to_der( - int oid, const uint32_t *nodes, size_t nodes_cnt, - const uint8_t *qualifiers, size_t qualifiers_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, NULL, &len) != 1 - || asn1_sequence_to_der(qualifiers, qualifiers_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, out, outlen) != 1 - || asn1_sequence_to_der(qualifiers, qualifiers_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_information_from_der( - int *oid, uint32_t *nodes, size_t *nodes_cnt, - const uint8_t **qualifiers, size_t *qualifiers_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_cert_policy_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1 - || asn1_sequence_from_der(qualifiers, qualifiers_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, oid; - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "policyIdentifier", x509_cert_policy_id_name(oid), nodes, nodes_cnt); - if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_policy_qualifier_infos_print(fp, fmt, ind, "policyQualifiers", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen, - int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, - const uint8_t *qualifiers, size_t qualifiers_len) -{ - error_print(); - return -1; -} - -int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_policy_information_print(fp, fmt, ind, label, p, len); - } - return 1; -} - -int x509_policy_mapping_to_der( - int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, - int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_cert_policy_id_to_der(issuer_policy_oid, - issuer_policy_nodes, issuer_policy_nodes_cnt, NULL, &len) != 1 - || x509_cert_policy_id_to_der(subject_policy_oid, - subject_policy_nodes, subject_policy_nodes_cnt, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_cert_policy_id_to_der(issuer_policy_oid, - issuer_policy_nodes, issuer_policy_nodes_cnt, out, outlen) != 1 - || x509_cert_policy_id_to_der(subject_policy_oid, - subject_policy_nodes, subject_policy_nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_mapping_from_der( - int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt, - int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_cert_policy_id_from_der(issuer_policy_oid, - issuer_policy_nodes, issuer_policy_nodes_cnt, &d, &dlen) != 1 - || x509_cert_policy_id_from_der(subject_policy_oid, - subject_policy_nodes, subject_policy_nodes_cnt, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int oid; - uint32_t nodes[32]; - size_t nodes_cnt; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "issuerDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt); - if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "subjectDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_policy_mapping_print(fp, fmt, ind, label, p, len); - } - return 1; -} - - -int x509_attribute_to_der( - const uint32_t *nodes, size_t nodes_cnt, - const uint8_t *values, size_t values_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_object_identifier_to_der(nodes, nodes_cnt, NULL, &len) != 1 - || asn1_set_to_der(values, values_len, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_object_identifier_to_der(nodes, nodes_cnt, out, outlen) != 1 - || asn1_set_to_der(values, values_len, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_attribute_from_der( - int *oid, uint32_t *nodes, size_t *nodes_cnt, - const uint8_t **values, size_t *values_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - *oid = OID_undef; - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_object_identifier_from_der(nodes, nodes_cnt, &p, &len) != 1 - || asn1_set_from_der(values, values_len, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err; - asn1_object_identifier_print(fp, fmt, ind, "type", NULL, nodes, nodes_cnt); - if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "values", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_attribute_print(fp, fmt, ind, "Attribute", p, len); - } - return 1; -} - -int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_boolean_to_der(ca, NULL, &len) < 0 - || asn1_int_to_der(path_len_cons, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_boolean_to_der(ca, out, outlen) < 0 - || asn1_int_to_der(path_len_cons, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_boolean_from_der(ca, &d, &dlen) < 0 - || asn1_int_from_der(path_len_cons, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*ca < 0 && *path_len_cons < 0) { - error_print(); - return -1; - } - if (*ca < 0) *ca = 0; - return 1; -} - -int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val)); - else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果 - if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_general_subtree_to_der( - int base_choice, const uint8_t *base, size_t base_len, - int minimum, - int maximum, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_general_name_to_der(base_choice, base, base_len, NULL, &len) != 1 - || asn1_implicit_int_to_der(0, minimum, NULL, &len) < 0 - || asn1_implicit_int_to_der(1, maximum, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_general_name_to_der(base_choice, base, base_len, out, outlen) != 1 - || asn1_implicit_int_to_der(0, minimum, out, outlen) < 0 - || asn1_implicit_int_to_der(1, maximum, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_general_subtree_from_der( - int *base_choice, const uint8_t **base, size_t *base_len, - int *minimum, - int *maximum, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_general_name_from_der(base_choice, base, base_len, &d, &dlen) != 1 - || asn1_implicit_int_from_der(0, minimum, &d, &dlen) < 0 - || asn1_implicit_int_from_der(1, maximum, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*minimum < 0) *minimum = 0; - return 1; -} - -int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, choice, val; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) goto err; - x509_general_name_print(fp, fmt, ind, "base", choice, p, len); - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "minimum: %d\n", val); - if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "maximum: %d\n", val); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen, - int base_choice, const uint8_t *base, size_t base_len, - int minimum, int maximum) -{ - error_print(); - return -1; -} - -int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_general_subtree_print(fp, fmt, ind, "GeneralSubtree", p, len); - } - return 1; -} - -int x509_name_constraints_to_der( - const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, - const uint8_t *excluded_subtrees, size_t excluded_subtrees_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, NULL, &len) < 0 - || asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, out, outlen) < 0 - || asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_name_constraints_from_der( - const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len, - const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - *permitted_subtrees = NULL; - *permitted_subtrees_len = 0; - *excluded_subtrees = NULL; - *excluded_subtrees_len = 0; - if (asn1_implicit_sequence_from_der(0, permitted_subtrees, permitted_subtrees_len, &d, &dlen) < 0 - || asn1_implicit_sequence_from_der(1, excluded_subtrees, excluded_subtrees_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_implicit_sequence_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_general_subtrees_print(fp, fmt, ind, "permittedSubtrees", p, len); - if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_general_subtrees_print(fp, fmt, ind, "excludedSubtrees", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_policy_constraints_to_der( - int require_explicit_policy, - int inhibit_policy_mapping, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (asn1_implicit_int_to_der(0, require_explicit_policy, NULL, &len) < 0 - || asn1_implicit_int_to_der(1, inhibit_policy_mapping, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_implicit_int_to_der(0, require_explicit_policy, out, outlen) < 0 - || asn1_implicit_int_to_der(1, inhibit_policy_mapping, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_constraints_from_der( - int *require_explicit_policy, - int *inhibit_policy_mapping, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - *require_explicit_policy = -1; - *inhibit_policy_mapping = -1; - if (asn1_implicit_int_from_der(0, require_explicit_policy, &d, &dlen) < 0 - || asn1_implicit_int_from_der(1, inhibit_policy_mapping, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, val; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "requireExplicitPolicy: %d\n", val); - if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err; - if (ret) format_print(fp, fmt, ind, "inhibitPolicyMapping: %d\n", val); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen) -{ - size_t len = 0; - size_t i; - - if (oids_cnt > X509_MAX_KEY_PURPOSES) { - error_print(); - return -1; - } - for (i = 0; i < oids_cnt; i++) { - if (x509_key_purpose_to_der(oids[i], NULL, &len) != 1) { - error_print(); - return -1; - } - } - if (asn1_sequence_header_to_der(len, out, outlen) != 1) { - error_print(); - return -1; - } - for (i = 0; i < oids_cnt; i++) { - if (x509_key_purpose_to_der(oids[i], out, outlen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - -int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - *oids_cnt = 0; - if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - while (len && (*oids_cnt < max_cnt)) { - if (x509_key_purpose_from_der(oids, &p, &len) != 1) { - error_print(); - return -1; - } - oids++; - (*oids_cnt)++; - } - if (len) { - error_print(); - return -1; - } - return 1; -} - -int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int oid; - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - while (dlen) { - if (x509_key_purpose_from_der(&oid, &d, &dlen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "%s\n", x509_key_purpose_name(oid)); - } - return 1; -} - -static const char *x509_revoke_reasons[] = { - "unused", - "keyCompromise", - "cACompromise", - "affiliationChanged", - "superseded", - "cessationOfOperation", - "certificateHold", - "privilegeWithdrawn", - "aACompromise", -}; - -static size_t x509_revoke_reasons_count = - sizeof(x509_revoke_reasons)/sizeof(x509_revoke_reasons[0]); - -const char *x509_revoke_reason_name(int flag) -{ - int i; - for (i = 0; i < x509_revoke_reasons_count; i++) { - if (flag & 1) { - if (flag >> 1) { - error_print(); - return NULL; - } - return x509_revoke_reasons[i]; - } - flag >>= 1; - } - return NULL; -} - -int x509_revoke_reason_from_name(int *flag, const char *name) -{ - int i; - for (i = 0; i < x509_revoke_reasons_count; i++) { - if (strcmp(name, x509_revoke_reasons[i]) == 0) { - *flag = 1 << i; - return 1; - } - } - *flag = 0; - error_print(); - return -1; -} - -int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits) -{ - return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reasons, x509_revoke_reasons_count, bits); -} - -int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - switch (choice) { - case 0: - case 1: - if (asn1_implicit_to_der(choice, d, dlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; - default: - error_print(); - return -1; - } -} - -int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - - if ((ret = asn1_implicit_from_der(*choice, d, dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return -1; - } - switch (*choice) { - case 0: - case 1: - break; - default: - error_print(); - return -1; - } - return 1; -} - -int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - // 注意:要能够解决d == NULL的情况 - error_print(); - return -1; -} - -int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - // 注意:要能够解决d == NULL的情况 - error_print(); - return -1; -} - -int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) -{ - int tag; - const uint8_t *d; - size_t dlen; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_any_type_from_der(&tag, &d, &dlen, &a, &alen) != 1) { - error_print(); - return -1; - } - switch (tag) { - case ASN1_TAG_EXPLICIT(0): return x509_general_names_print(fp, fmt, ind, "fullName", d, dlen); - case ASN1_TAG_IMPLICIT(1): return x509_rdn_print(fp, fmt, ind, "nameRelativeToCRLIssuer", d, dlen); - default: - error_print(); - return -1; - } - return 1; -} - -int x509_distribution_point_to_der( - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0 - || asn1_implicit_bits_to_der(1, reasons, NULL, &len) < 0 - || asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0 - || asn1_implicit_bits_to_der(1, reasons, out, outlen) < 0 - || asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_distribution_point_from_der( - int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, - int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0 - || asn1_implicit_bits_from_der(1, reasons, &d, &dlen) < 0 - || asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret; - const uint8_t *p; - size_t len; - int bits; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); - - if ((ret = asn1_implicit_bits_from_der(1, &bits, &d, &dlen)) < 0) goto err; - if (ret) x509_revoke_reasons_print(fp, fmt, ind, "reasons", bits); - - if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -/* - extnID: CRLDistributionPoints (2.5.29.31) - DistributionPoint - distributionPoint - fullName - GeneralName - URI: http://www.rootca.gov.cn/Civil_Servant_arl/Civil_Servant_ARL.crl - DistributionPoint - distributionPoint - fullName - GeneralName - URI: ldap://ldap.rootca.gov.cn:390/CN=Civil_Servant_ARL,OU=ARL,O=NRCAC,C=CN - -*/ - -int x509_distribution_points_add_url(uint8_t *d, size_t *dlen, size_t maxlen, const char *url) -{ - return 0; -} - -int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, - int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, - int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len) -{ - error_print(); - return -1; -} - -int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - if (label) { - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - } - while (dlen) { - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - x509_distribution_point_print(fp, fmt, ind, "DistributionPoint", p, len); - } - return 1; -} - -static const char *netscape_cert_types[] = { - "SSL Client certificate", - "SSL Server certificate", - "S/MIME certificate", - "Object-signing certificate", - "Reserved for future use", - "SSL CA certificate", - "S/MIME CA certificate", - "Object-signing CA certificate", -}; - -int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits) -{ - return asn1_bits_print(fp, fmt, ind, label, netscape_cert_types, - sizeof(netscape_cert_types)/sizeof(netscape_cert_types[0]), bits); -} - + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen, + int oid, int critical, const uint8_t *d, size_t dlen) +{ + uint8_t val[32 + dlen]; + uint8_t *p = val; + size_t curlen = *extslen; + size_t vlen = 0; + + exts += *extslen; + if (asn1_sequence_to_der(d, dlen, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len) +{ + int oid = OID_ce_authority_key_identifier; + size_t curlen = *extslen; + uint8_t val[512]; + uint8_t *p = val; + size_t vlen = 0; + size_t len = 0; + + exts += *extslen; + if (x509_authority_key_identifier_to_der( + keyid, keyid_len, + issuer, issuer_len, + serial, serial_len, + NULL, &len) != 1 + || asn1_length_le(len, sizeof(val)) != 1 + || x509_authority_key_identifier_to_der( + keyid, keyid_len, + issuer, issuer_len, + serial, serial_len, + &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_KEY *public_key) +{ + uint8_t buf[65]; + uint8_t id[32]; + int critical = -1; + + sm2_point_to_uncompressed_octets(&public_key->public_key, buf); + sm3_digest(buf, sizeof(buf), id); + + if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical, + id, sizeof(id), NULL, 0, NULL, 0) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_subject_key_identifier; + size_t curlen = *extslen; + uint8_t val[32 + X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN]; + uint8_t *p = val; + size_t vlen = 0; + + if (dlen < X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN + || dlen > X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN) { + error_print(); + return -1; + } + + exts += *extslen; + if (asn1_octet_string_to_der(d, dlen, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits) +{ + int oid = OID_ce_key_usage; + size_t curlen = *extslen; + uint8_t val[16]; + uint8_t *p = val; + size_t vlen = 0; + + if (!bits) { + // TODO: 检查是否在合法范围内 + error_print(); + return -1; + } + + exts += *extslen; + if (asn1_bits_to_der(bits, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_certificate_policies; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_policy_mappings; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_subject_alt_name; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_issuer_alt_name; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_subject_directory_attributes; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len) +{ + int oid = OID_ce_name_constraints; + size_t curlen = *extslen; + uint8_t val[512]; + uint8_t *p = val; + size_t vlen = 0; + size_t len = 0; + + exts += *extslen; + if (x509_name_constraints_to_der( + permitted_subtrees, permitted_subtrees_len, + excluded_subtrees, excluded_subtrees_len, + NULL, &len) != 1 + || asn1_length_le(len, sizeof(val)) != 1 + || x509_name_constraints_to_der( + permitted_subtrees, permitted_subtrees_len, + excluded_subtrees, excluded_subtrees_len, + &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, int require_explicit_policy, int inhibit_policy_mapping) +{ + int oid = OID_ce_policy_constraints; + size_t curlen = *extslen; + uint8_t val[32]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (x509_policy_constraints_to_der( + require_explicit_policy, + inhibit_policy_mapping, + &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, int ca, int path_len_constraint) +{ + int oid = OID_ce_basic_constraints; + size_t curlen = *extslen; + uint8_t val[32]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (x509_basic_constraints_to_der(ca, path_len_constraint, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const int *key_purposes, size_t key_purposes_cnt) +{ + int oid = OID_ce_ext_key_usage; + size_t curlen = *extslen; + uint8_t val[256]; + uint8_t *p = val; + size_t vlen = 0; + size_t len = 0; + + exts += *extslen; + if (x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, NULL, &len) != 1 + || asn1_length_le(len, sizeof(val)) != 1 + || x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_crl_distribution_points; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, int skip_certs) +{ + int oid = OID_ce_inhibit_any_policy; + size_t curlen = *extslen; + uint8_t val[16]; + uint8_t *p = val; + size_t vlen = 0; + + exts += *extslen; + if (x509_inhibit_any_policy_to_der(skip_certs, &p, &vlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1 + || asn1_length_le(curlen, maxlen) != 1 + || x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, + int critical, const uint8_t *d, size_t dlen) +{ + int oid = OID_ce_freshest_crl; + return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen); +} + +int x509_other_name_to_der( + const uint32_t *type_nodes, size_t type_nodes_cnt, + const uint8_t *value, size_t value_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, NULL, &len) != 1 + || asn1_explicit_to_der(0, value, value_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, out, outlen) != 1 + || asn1_explicit_to_der(0, value, value_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_other_name_from_der( + uint32_t *type_nodes, size_t *type_nodes_cnt, + const uint8_t **value, size_t *value_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_object_identifier_from_der(type_nodes, type_nodes_cnt, &p, &len) != 1 + || asn1_explicit_from_der(0, value, value_len, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "type-id", NULL, nodes, nodes_cnt); + if (asn1_explicit_from_der(0, &p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "value", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_edi_party_name_to_der( + int assigner_choice, const uint8_t *assigner, size_t assigner_len, + int party_name_choice, const uint8_t *party_name, size_t party_name_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, NULL, &len) < 0 + || x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, out, outlen) < 0 + || x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_edi_party_name_from_der( + int *assigner_choice, const uint8_t **assigner, size_t *assigner_len, + int *party_name_choice, const uint8_t **party_name, size_t *party_name_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_explicit_directory_name_from_der(0, assigner_choice, assigner, assigner_len, &p, &len) < 0 + || x509_explicit_directory_name_from_der(1, party_name_choice, party_name, party_name_len, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int tag; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = x509_explicit_directory_name_from_der(0, &tag, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_directory_name_print(fp, fmt, ind, "nameAssigner", tag, p, len); + if (x509_explicit_directory_name_from_der(1, &tag, &p, &len, &d, &dlen) != 1) goto err; + x509_directory_name_print(fp, fmt, ind, "partyName", tag, p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +// GeneralName CHOICE 中有的是基本类型,有的是SEQUENCE,在设置标签时是否有区别? +// 这里是否支持OPTIONAL?? +int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + return asn1_implicit_to_der(choice, d, dlen, out, outlen); +} + +int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + int tag; + if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + switch (tag) { + case ASN1_TAG_EXPLICIT(0): *choice = 0; break; + case ASN1_TAG_IMPLICIT(1): *choice = 1; break; + case ASN1_TAG_IMPLICIT(2): *choice = 2; break; + case ASN1_TAG_EXPLICIT(3): *choice = 3; break; + case ASN1_TAG_EXPLICIT(4): *choice = 4; break; + case ASN1_TAG_EXPLICIT(5): *choice = 5; break; + case ASN1_TAG_IMPLICIT(6): *choice = 6; break; + case ASN1_TAG_IMPLICIT(7): *choice = 7; break; + case ASN1_TAG_IMPLICIT(8): *choice = 8; break; + default: + fprintf(stderr, "%s %d: tag = %x\n", __FILE__, __LINE__, tag); + error_print(); + return -1; + } + return 1; +} + +int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + switch (choice) { + case 0: + case 3: + case 4: + case 5: + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + d = p; + dlen = len; + } + switch (choice) { + case 0: return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen); + case 1: return asn1_string_print(fp, fmt, ind, "rfc822Name", ASN1_TAG_IA5String, d, dlen); + case 2: return asn1_string_print(fp, fmt, ind, "DNSName", ASN1_TAG_IA5String, d, dlen); + case 3: return format_bytes(fp, fmt, ind, "x400Address", d, dlen); + case 4: return x509_name_print(fp, fmt, ind, "directoryName", d, dlen); + case 5: return x509_edi_party_name_print(fp, fmt, ind, "ediPartyName", d, dlen); + case 6: return asn1_string_print(fp, fmt, ind, "URI", ASN1_TAG_IA5String, d, dlen); + case 7: return format_bytes(fp, fmt, ind, "IPAddress", d, dlen); + case 8: + { + uint32_t nodes[32]; + size_t nodes_cnt; + if (asn1_object_identifier_from_octets(nodes, &nodes_cnt, d, dlen) != 1) { + error_print(); + return -1; + } + return asn1_object_identifier_print(fp, fmt, ind, "registeredID", NULL, nodes, nodes_cnt); + } + default: + error_print(); + return -1; + } + return 1; +} + +int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + int choice, const uint8_t *d, size_t dlen) +{ + size_t len = 0; + uint8_t *p = gns + *gnslen; + + switch (choice) { + case X509_gn_rfc822_name: + case X509_gn_dns_name: + case X509_gn_uniform_resource_identifier: + if (asn1_ia5_string_check((char *)d, dlen) != 1) { + error_print(); + return -1; + } + break; + } + if (x509_general_name_to_der(choice, d, dlen, NULL, &len) != 1 + || asn1_length_le(*gnslen + len, maxlen) != 1 + || x509_general_name_to_der(choice, d, dlen, &p, gnslen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *value, size_t value_len) +{ + int choice = X509_gn_other_name; + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + if (x509_other_name_to_der(nodes, nodes_cnt, value, value_len, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen, + int assigner_tag, const uint8_t *assigner, size_t assigner_len, + int party_name_tag, const uint8_t *party_name, size_t party_name_len) +{ + int choice = X509_gn_edi_party_name; + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + if (x509_edi_party_name_to_der( + assigner_tag, assigner, assigner_len, + party_name_tag, party_name, party_name_len, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen, + const uint32_t *nodes, size_t nodes_cnt) +{ + int choice = X509_gn_registered_id; + uint8_t d[128]; + size_t dlen; + + if (asn1_object_identifier_to_octets(nodes, nodes_cnt, d, &dlen) != 1 + || x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int choice; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_general_name_print(fp, fmt, ind, "GeneralName", choice, p, len); + } + return 1; +} + +int x509_authority_key_identifier_to_der( + const uint8_t *keyid, size_t keyid_len, + const uint8_t *issuer, size_t issuer_len, + const uint8_t *serial, size_t serial_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_implicit_octet_string_to_der(0, keyid, keyid_len, NULL, &len) < 0 + || asn1_implicit_sequence_to_der(1, issuer, issuer_len, NULL, &len) < 0 + || asn1_implicit_integer_to_der(2, serial, serial_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_implicit_octet_string_to_der(0, keyid, keyid_len, out, outlen) < 0 + || asn1_implicit_sequence_to_der(1, issuer, issuer_len, out, outlen) < 0 + || asn1_implicit_integer_to_der(2, serial, serial_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_authority_key_identifier_from_der( + const uint8_t **keyid, size_t *keyid_len, + const uint8_t **issuer, size_t *issuer_len, + const uint8_t **serial, size_t *serial_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_implicit_octet_string_from_der(0, keyid, keyid_len, &d, &dlen) < 0 + || asn1_implicit_sequence_from_der(1, issuer, issuer_len, &d, &dlen) < 0 + || asn1_implicit_integer_from_der(2, serial, serial_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "keyIdentifier", p, len); + if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_general_names_print(fp, fmt, ind, "authorityCertIssuer", p, len); + if ((ret = asn1_implicit_integer_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) format_bytes(fp, fmt, ind, "authorityCertSerialNumber", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +static const char *x509_key_usages[] = { + "digitalSignature", + "nonRepudiation", + "keyEncipherment", + "dataEncipherment", + "keyAgreement", + "keyCertSign", + "cRLSign", + "encipherOnly", + "decipherOnly", +}; + +static size_t x509_key_usages_count = + sizeof(x509_key_usages)/sizeof(x509_key_usages[0]); + +const char *x509_key_usage_name(int flag) +{ + int i; + for (i = 0; i < x509_key_usages_count; i++) { + if (flag & 1) { + if (flag >> 1) { + error_print(); + return NULL; + } + return x509_key_usages[i]; + } + flag >>= 1; + } + error_print(); + return NULL; +} + +int x509_key_usage_from_name(int *flag, const char *name) +{ + int i; + for (i = 0; i < x509_key_usages_count; i++) { + if (strcmp(name, x509_key_usages[i]) == 0) { + *flag = 1 << i; + return 1; + } + } + *flag = 0; + error_print(); + return -1; +} + +int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits) +{ + return asn1_bits_print(fp, fmt, ind, label, x509_key_usages, x509_key_usages_count, bits); +} + +int x509_notice_reference_to_der( + int org_tag, const uint8_t *org, size_t org_len, + const int *notice_numbers, size_t notice_numbers_cnt, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_display_text_to_der(org_tag, org, org_len, NULL, &len) != 1 + || asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_display_text_to_der(org_tag, org, org_len, out, outlen) != 1 + || asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_notice_reference_from_der( + int *org_tag, const uint8_t **org, size_t *org_len, + int notice_numbers[X509_MAX_NOTICE_NUMBERS], size_t *notice_numbers_cnt, size_t max_notice_numbers, //FIXME: max_notice_numbers 还没检查 + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return ret; + } + if (x509_display_text_from_der(org_tag, org, org_len, &d, &dlen) != 1 + || asn1_sequence_of_int_from_der(notice_numbers, notice_numbers_cnt, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int tag; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_display_text_from_der(&tag, &p, &len, &d, &dlen) != 1) goto err; + x509_display_text_print(fp, fmt, ind, "organization", tag, p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + asn1_sequence_of_int_print(fp, fmt, ind, "noticeNumbers", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_user_notice_to_der( + int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len, + const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt, + int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_notice_reference_to_der( + notice_ref_org_tag, notice_ref_org, notice_ref_org_len, + notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, + NULL, &len) < 0 + || x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_notice_reference_to_der( + notice_ref_org_tag, notice_ref_org, notice_ref_org_len, + notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, + out, outlen) < 0 + || x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_user_notice_from_der( + int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len, + int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, // FIXME: max_notice_ref_notice_numbers + int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_notice_reference_from_der(notice_ref_org_tag, notice_ref_org, notice_ref_org_len, + notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, max_notice_ref_notice_numbers, &d, &dlen) < 0 + || x509_display_text_from_der(explicit_text_tag, explicit_text, explicit_text_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int tag; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_notice_reference_print(fp, fmt, ind, "noticeRef", p, len); + if ((ret = x509_display_text_from_der(&tag, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_display_text_print(fp, fmt, ind, "explicitText", tag, p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +// 是否要针对oid = cps的IA5String做一个方便的接口呢?毕竟oid 只有两个可选项 +int x509_policy_qualifier_info_to_der( + int oid, + const uint8_t *qualifier, size_t qualifier_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_qualifier_id_to_der(oid, NULL, &len) != 1 + || asn1_any_to_der(qualifier, qualifier_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_qualifier_id_to_der(oid, out, outlen) != 1 + || asn1_any_to_der(qualifier, qualifier_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_qualifier_info_from_der(int *oid, const uint8_t **qualifier, size_t *qualifier_len, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_qualifier_id_from_der(oid, &p, &len) != 1 + || asn1_any_from_der(qualifier, qualifier_len, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int oid; + const uint8_t *p; + size_t len; + + if (x509_qualifier_id_from_der(&oid, &d, &dlen) != 1) goto err; + switch (oid) { + case OID_qt_cps: + if (asn1_ia5_string_from_der((const char **)&p, &len, &d, &dlen) != 1) goto err; + format_string(fp, fmt, ind, "cPSuri", p, len); + break; + case OID_qt_unotice: + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_user_notice_print(fp, fmt, ind, "userNotice", p, len); + break; + } + return 1; +err: + error_print(); + return -1; +} + +int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_policy_qualifier_info_print(fp, fmt, ind, "PolicyQualifierInfo", p, len); + } + return 1; +} + +int x509_policy_information_to_der( + int oid, const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, NULL, &len) != 1 + || asn1_sequence_to_der(qualifiers, qualifiers_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, out, outlen) != 1 + || asn1_sequence_to_der(qualifiers, qualifiers_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_information_from_der( + int *oid, uint32_t *nodes, size_t *nodes_cnt, + const uint8_t **qualifiers, size_t *qualifiers_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_cert_policy_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1 + || asn1_sequence_from_der(qualifiers, qualifiers_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, oid; + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "policyIdentifier", x509_cert_policy_id_name(oid), nodes, nodes_cnt); + if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_policy_qualifier_infos_print(fp, fmt, ind, "policyQualifiers", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen, + int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt, + const uint8_t *qualifiers, size_t qualifiers_len) +{ + error_print(); + return -1; +} + +int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_policy_information_print(fp, fmt, ind, label, p, len); + } + return 1; +} + +int x509_policy_mapping_to_der( + int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt, + int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_cert_policy_id_to_der(issuer_policy_oid, + issuer_policy_nodes, issuer_policy_nodes_cnt, NULL, &len) != 1 + || x509_cert_policy_id_to_der(subject_policy_oid, + subject_policy_nodes, subject_policy_nodes_cnt, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_cert_policy_id_to_der(issuer_policy_oid, + issuer_policy_nodes, issuer_policy_nodes_cnt, out, outlen) != 1 + || x509_cert_policy_id_to_der(subject_policy_oid, + subject_policy_nodes, subject_policy_nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_mapping_from_der( + int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt, + int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_cert_policy_id_from_der(issuer_policy_oid, + issuer_policy_nodes, issuer_policy_nodes_cnt, &d, &dlen) != 1 + || x509_cert_policy_id_from_der(subject_policy_oid, + subject_policy_nodes, subject_policy_nodes_cnt, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "issuerDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt); + if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "subjectDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_policy_mapping_print(fp, fmt, ind, label, p, len); + } + return 1; +} + + +int x509_attribute_to_der( + const uint32_t *nodes, size_t nodes_cnt, + const uint8_t *values, size_t values_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_object_identifier_to_der(nodes, nodes_cnt, NULL, &len) != 1 + || asn1_set_to_der(values, values_len, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_object_identifier_to_der(nodes, nodes_cnt, out, outlen) != 1 + || asn1_set_to_der(values, values_len, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_attribute_from_der( + int *oid, uint32_t *nodes, size_t *nodes_cnt, + const uint8_t **values, size_t *values_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + *oid = OID_undef; + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_object_identifier_from_der(nodes, nodes_cnt, &p, &len) != 1 + || asn1_set_from_der(values, values_len, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err; + asn1_object_identifier_print(fp, fmt, ind, "type", NULL, nodes, nodes_cnt); + if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "values", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (label) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_attribute_print(fp, fmt, ind, "Attribute", p, len); + } + return 1; +} + +int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_boolean_to_der(ca, NULL, &len) < 0 + || asn1_int_to_der(path_len_cons, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_boolean_to_der(ca, out, outlen) < 0 + || asn1_int_to_der(path_len_cons, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_boolean_from_der(ca, &d, &dlen) < 0 + || asn1_int_from_der(path_len_cons, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*ca < 0 && *path_len_cons < 0) { + error_print(); + return -1; + } + if (*ca < 0) *ca = 0; + return 1; +} + +int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val)); + else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果 + if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_general_subtree_to_der( + int base_choice, const uint8_t *base, size_t base_len, + int minimum, + int maximum, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_general_name_to_der(base_choice, base, base_len, NULL, &len) != 1 + || asn1_implicit_int_to_der(0, minimum, NULL, &len) < 0 + || asn1_implicit_int_to_der(1, maximum, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_general_name_to_der(base_choice, base, base_len, out, outlen) != 1 + || asn1_implicit_int_to_der(0, minimum, out, outlen) < 0 + || asn1_implicit_int_to_der(1, maximum, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_general_subtree_from_der( + int *base_choice, const uint8_t **base, size_t *base_len, + int *minimum, + int *maximum, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_general_name_from_der(base_choice, base, base_len, &d, &dlen) != 1 + || asn1_implicit_int_from_der(0, minimum, &d, &dlen) < 0 + || asn1_implicit_int_from_der(1, maximum, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*minimum < 0) *minimum = 0; + return 1; +} + +int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, choice, val; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) goto err; + x509_general_name_print(fp, fmt, ind, "base", choice, p, len); + if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "minimum: %d\n", val); + if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "maximum: %d\n", val); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen, + int base_choice, const uint8_t *base, size_t base_len, + int minimum, int maximum) +{ + error_print(); + return -1; +} + +int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_general_subtree_print(fp, fmt, ind, "GeneralSubtree", p, len); + } + return 1; +} + +int x509_name_constraints_to_der( + const uint8_t *permitted_subtrees, size_t permitted_subtrees_len, + const uint8_t *excluded_subtrees, size_t excluded_subtrees_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, NULL, &len) < 0 + || asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, out, outlen) < 0 + || asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_name_constraints_from_der( + const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len, + const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + *permitted_subtrees = NULL; + *permitted_subtrees_len = 0; + *excluded_subtrees = NULL; + *excluded_subtrees_len = 0; + if (asn1_implicit_sequence_from_der(0, permitted_subtrees, permitted_subtrees_len, &d, &dlen) < 0 + || asn1_implicit_sequence_from_der(1, excluded_subtrees, excluded_subtrees_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_implicit_sequence_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_general_subtrees_print(fp, fmt, ind, "permittedSubtrees", p, len); + if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_general_subtrees_print(fp, fmt, ind, "excludedSubtrees", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_policy_constraints_to_der( + int require_explicit_policy, + int inhibit_policy_mapping, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (asn1_implicit_int_to_der(0, require_explicit_policy, NULL, &len) < 0 + || asn1_implicit_int_to_der(1, inhibit_policy_mapping, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_implicit_int_to_der(0, require_explicit_policy, out, outlen) < 0 + || asn1_implicit_int_to_der(1, inhibit_policy_mapping, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_constraints_from_der( + int *require_explicit_policy, + int *inhibit_policy_mapping, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + *require_explicit_policy = -1; + *inhibit_policy_mapping = -1; + if (asn1_implicit_int_from_der(0, require_explicit_policy, &d, &dlen) < 0 + || asn1_implicit_int_from_der(1, inhibit_policy_mapping, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, val; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "requireExplicitPolicy: %d\n", val); + if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err; + if (ret) format_print(fp, fmt, ind, "inhibitPolicyMapping: %d\n", val); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen) +{ + size_t len = 0; + size_t i; + + if (oids_cnt > X509_MAX_KEY_PURPOSES) { + error_print(); + return -1; + } + for (i = 0; i < oids_cnt; i++) { + if (x509_key_purpose_to_der(oids[i], NULL, &len) != 1) { + error_print(); + return -1; + } + } + if (asn1_sequence_header_to_der(len, out, outlen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < oids_cnt; i++) { + if (x509_key_purpose_to_der(oids[i], out, outlen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + +int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + *oids_cnt = 0; + if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + while (len && (*oids_cnt < max_cnt)) { + if (x509_key_purpose_from_der(oids, &p, &len) != 1) { + error_print(); + return -1; + } + oids++; + (*oids_cnt)++; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + +int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int oid; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + while (dlen) { + if (x509_key_purpose_from_der(&oid, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s\n", x509_key_purpose_name(oid)); + } + return 1; +} + +static const char *x509_revoke_reasons[] = { + "unused", + "keyCompromise", + "cACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "privilegeWithdrawn", + "aACompromise", +}; + +static size_t x509_revoke_reasons_count = + sizeof(x509_revoke_reasons)/sizeof(x509_revoke_reasons[0]); + +const char *x509_revoke_reason_name(int flag) +{ + int i; + for (i = 0; i < x509_revoke_reasons_count; i++) { + if (flag & 1) { + if (flag >> 1) { + error_print(); + return NULL; + } + return x509_revoke_reasons[i]; + } + flag >>= 1; + } + return NULL; +} + +int x509_revoke_reason_from_name(int *flag, const char *name) +{ + int i; + for (i = 0; i < x509_revoke_reasons_count; i++) { + if (strcmp(name, x509_revoke_reasons[i]) == 0) { + *flag = 1 << i; + return 1; + } + } + *flag = 0; + error_print(); + return -1; +} + +int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits) +{ + return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reasons, x509_revoke_reasons_count, bits); +} + +int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + switch (choice) { + case 0: + case 1: + if (asn1_implicit_to_der(choice, d, dlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; + default: + error_print(); + return -1; + } +} + +int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + + if ((ret = asn1_implicit_from_der(*choice, d, dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return -1; + } + switch (*choice) { + case 0: + case 1: + break; + default: + error_print(); + return -1; + } + return 1; +} + +int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + // 注意:要能够解决d == NULL的情况 + error_print(); + return -1; +} + +int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + // 注意:要能够解决d == NULL的情况 + error_print(); + return -1; +} + +int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen) +{ + int tag; + const uint8_t *d; + size_t dlen; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_any_type_from_der(&tag, &d, &dlen, &a, &alen) != 1) { + error_print(); + return -1; + } + switch (tag) { + case ASN1_TAG_EXPLICIT(0): return x509_general_names_print(fp, fmt, ind, "fullName", d, dlen); + case ASN1_TAG_IMPLICIT(1): return x509_rdn_print(fp, fmt, ind, "nameRelativeToCRLIssuer", d, dlen); + default: + error_print(); + return -1; + } + return 1; +} + +int x509_distribution_point_to_der( + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0 + || asn1_implicit_bits_to_der(1, reasons, NULL, &len) < 0 + || asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0 + || asn1_implicit_bits_to_der(1, reasons, out, outlen) < 0 + || asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_distribution_point_from_der( + int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len, + int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0 + || asn1_implicit_bits_from_der(1, reasons, &d, &dlen) < 0 + || asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret; + const uint8_t *p; + size_t len; + int bits; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len); + + if ((ret = asn1_implicit_bits_from_der(1, &bits, &d, &dlen)) < 0) goto err; + if (ret) x509_revoke_reasons_print(fp, fmt, ind, "reasons", bits); + + if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +/* + extnID: CRLDistributionPoints (2.5.29.31) + DistributionPoint + distributionPoint + fullName + GeneralName + URI: http://www.rootca.gov.cn/Civil_Servant_arl/Civil_Servant_ARL.crl + DistributionPoint + distributionPoint + fullName + GeneralName + URI: ldap://ldap.rootca.gov.cn:390/CN=Civil_Servant_ARL,OU=ARL,O=NRCAC,C=CN + +*/ + +int x509_distribution_points_add_url(uint8_t *d, size_t *dlen, size_t maxlen, const char *url) +{ + return 0; +} + +int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen, + int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len, + int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len) +{ + error_print(); + return -1; +} + +int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + if (label) { + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + } + while (dlen) { + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + x509_distribution_point_print(fp, fmt, ind, "DistributionPoint", p, len); + } + return 1; +} + +static const char *netscape_cert_types[] = { + "SSL Client certificate", + "SSL Server certificate", + "S/MIME certificate", + "Object-signing certificate", + "Reserved for future use", + "SSL CA certificate", + "S/MIME CA certificate", + "Object-signing CA certificate", +}; + +int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits) +{ + return asn1_bits_print(fp, fmt, ind, label, netscape_cert_types, + sizeof(netscape_cert_types)/sizeof(netscape_cert_types[0]), bits); +} + diff --git a/src/x509_oid.c b/src/x509_oid.c index e81031d2..ed4f9459 100644 --- a/src/x509_oid.c +++ b/src/x509_oid.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,406 +7,407 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static uint32_t oid_at_name[] = { oid_at,41 }; -static uint32_t oid_at_surname[] = { oid_at,4 }; -static uint32_t oid_at_given_name[] = { oid_at,42 }; -static uint32_t oid_at_initials[] = { oid_at,43 }; -static uint32_t oid_at_generation_qualifier[] = { oid_at,44 }; -static uint32_t oid_at_common_name[] = { oid_at,3 }; -static uint32_t oid_at_locality_name[] = { oid_at,7 }; -static uint32_t oid_at_state_or_province_name[] = { oid_at,8 }; -static uint32_t oid_at_organization_name[] = { oid_at,10 }; -static uint32_t oid_at_organizational_unit_name[] = { oid_at,11 }; -static uint32_t oid_at_title[] = { oid_at,12 }; -static uint32_t oid_at_dn_qualifier[] = { oid_at,46 }; -static uint32_t oid_at_country_name[] = { oid_at,6 }; -static uint32_t oid_at_serial_number[] = { oid_at,5 }; -static uint32_t oid_at_pseudonym[] = { oid_at,65 }; -static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 }; -static uint32_t oid_email_address[] = { 1,2,840,113549,1,9,1 }; - -#define OID_AT_CNT (sizeof(oid_at_name)/sizeof(int)) - -static const ASN1_OID_INFO x509_name_types[] = { - { OID_at_name, "name", oid_at_name, OID_AT_CNT }, - { OID_at_surname, "surname", oid_at_surname, OID_AT_CNT }, - { OID_at_given_name, "givenName", oid_at_given_name, OID_AT_CNT }, - { OID_at_initials, "initials", oid_at_initials, OID_AT_CNT }, - { OID_at_generation_qualifier, "generationQualifier", oid_at_generation_qualifier, OID_AT_CNT }, - { OID_at_common_name, "commonName", oid_at_common_name, OID_AT_CNT }, - { OID_at_locality_name, "localityName", oid_at_locality_name, OID_AT_CNT }, - { OID_at_state_or_province_name, "stateOrProvinceName", oid_at_state_or_province_name, OID_AT_CNT }, - { OID_at_organization_name, "organizationName", oid_at_organization_name, OID_AT_CNT }, - { OID_at_organizational_unit_name, "organizationalUnitName", oid_at_organizational_unit_name, OID_AT_CNT }, - { OID_at_title, "title", oid_at_title, OID_AT_CNT }, - { OID_at_dn_qualifier, "dnQualifier", oid_at_dn_qualifier, OID_AT_CNT }, - { OID_at_country_name, "countryName", oid_at_country_name, OID_AT_CNT }, - { OID_at_serial_number, "serialNumber", oid_at_serial_number, OID_AT_CNT }, - { OID_at_pseudonym, "pseudonym", oid_at_pseudonym, OID_AT_CNT }, - { OID_domain_component, "domainComponent", oid_domain_component, sizeof(oid_domain_component)/sizeof(int) }, - { OID_email_address, "emailAddress", oid_email_address, sizeof(oid_email_address)/sizeof(int) }, -}; - -static const int x509_name_types_count - = sizeof(x509_name_types)/sizeof(x509_name_types[0]); - -const char *x509_name_type_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_name_types, x509_name_types_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_name_type_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_name_types, x509_name_types_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_name_types, x509_name_types_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - - if ((ret = asn1_oid_info_from_der(&info, x509_name_types, x509_name_types_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - - -static uint32_t oid_ce_subject_directory_attributes[] = { oid_ce,9 }; -static uint32_t oid_ce_subject_key_identifier[] = { oid_ce,14 }; -static uint32_t oid_ce_key_usage[] = { oid_ce,15 }; -static uint32_t oid_ce_subject_alt_name[] = { oid_ce,17 }; -static uint32_t oid_ce_issuer_alt_name[] = { oid_ce,18 }; -static uint32_t oid_ce_basic_constraints[] = { oid_ce,19 }; -static uint32_t oid_ce_name_constraints[] = { oid_ce,30 }; -static uint32_t oid_ce_crl_distribution_points[] = { oid_ce,31 }; -static uint32_t oid_ce_certificate_policies[] = { oid_ce,32 }; -static uint32_t oid_ce_policy_mappings[] = { oid_ce,33 }; -static uint32_t oid_ce_authority_key_identifier[] = { oid_ce,35 }; -static uint32_t oid_ce_policy_constraints[] = { oid_ce,36 }; -static uint32_t oid_ce_ext_key_usage[] = { oid_ce,37 }; -static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 }; -static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 }; -static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; // crl_entry_ext -static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; // crl_entry_ext -static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext -#define OID_CE_CNT sizeof(oid_ce_subject_directory_attributes)/sizeof(int) -static uint32_t oid_netscape_cert_type[] = { 2,16,840,1,113730,1,1 }; -static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 }; -static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 }; -static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 }; - -static const ASN1_OID_INFO x509_ext_ids[] = { - { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, OID_CE_CNT }, - { OID_ce_subject_key_identifier, "SubjectKeyIdentifier", oid_ce_subject_key_identifier, OID_CE_CNT }, - { OID_ce_key_usage, "KeyUsage", oid_ce_key_usage, OID_CE_CNT }, - { OID_ce_certificate_policies, "CertificatePolicies", oid_ce_certificate_policies, OID_CE_CNT }, - { OID_ce_policy_mappings, "PolicyMappings", oid_ce_policy_mappings, OID_CE_CNT }, - { OID_ce_subject_alt_name, "SubjectAltName", oid_ce_subject_alt_name, OID_CE_CNT }, - { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, OID_CE_CNT }, - { OID_ce_subject_directory_attributes, "SubjectDirectoryAttributes", oid_ce_subject_directory_attributes, OID_CE_CNT }, - { OID_ce_basic_constraints, "BasicConstraints", oid_ce_basic_constraints, OID_CE_CNT }, - { OID_ce_name_constraints, "NameConstraints", oid_ce_name_constraints, OID_CE_CNT }, - { OID_ce_policy_constraints, "PolicyConstraints", oid_ce_policy_constraints, OID_CE_CNT }, - { OID_ce_ext_key_usage, "ExtKeyUsage", oid_ce_ext_key_usage, OID_CE_CNT }, - { OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, OID_CE_CNT }, - { OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, OID_CE_CNT }, - { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, OID_CE_CNT }, - { OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, OID_CE_CNT }, - { OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, OID_CE_CNT }, - { OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, OID_CE_CNT }, - { OID_netscape_cert_type, "NetscapeCertType", oid_netscape_cert_type, sizeof(oid_netscape_cert_type)/sizeof(int) }, - { OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) }, - { OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) }, - { OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) }, -}; - -static const int x509_ext_ids_count = - sizeof(x509_ext_ids)/sizeof(x509_ext_ids[0]); - -const char *x509_ext_id_name(int oid) -{ - const ASN1_OID_INFO *info; - if (oid == 0) { - return NULL; - } - if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_ext_id_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_ext_ids, x509_ext_ids_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -// 如果要支持未知的ext_id,应该提供一个callback -int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - - if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_ext_ids, x509_ext_ids_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info ? info->oid : 0; - return 1; -} - - -static uint32_t oid_qt_cps[] = { oid_qt,1 }; -static uint32_t oid_qt_unotice[] = {oid_qt,2 }; - -static const ASN1_OID_INFO x509_qt_ids[] = { - { OID_qt_cps, "CPS", oid_qt_cps, sizeof(oid_qt_cps)/sizeof(int) }, - { OID_qt_unotice, "userNotice", oid_qt_unotice, sizeof(oid_qt_unotice)/sizeof(int) } -}; - -static const int x509_qt_ids_count = - sizeof(x509_qt_ids)/sizeof(x509_qt_ids[0]); - -int x509_qualifier_id_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_qt_ids, x509_qt_ids_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -const char *x509_qualifier_id_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_qt_ids, x509_qt_ids_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_qt_ids, x509_qt_ids_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - if ((ret = asn1_oid_info_from_der(&info, x509_qt_ids, x509_qt_ids_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} - - -int x509_cert_policy_id_from_name(const char *name) -{ - if (strcmp(name, "anyPolicy") == 0) { - return OID_any_policy; - } - return OID_undef; -} - -char *x509_cert_policy_id_name(int oid) -{ - switch (oid) { - case OID_any_policy: return "anyPolicy"; - } - return NULL; -} - -static uint32_t oid_any_policy[] = { oid_ce,32,0 }; - -int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen) -{ - switch (oid) { - case OID_any_policy: - if (asn1_object_identifier_to_der(oid_any_policy, sizeof(oid_any_policy)/sizeof(int), out, outlen) != 1) { - error_print(); - return -1; - } - break; - case OID_undef: - if (asn1_object_identifier_to_der(nodes, nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) -{ - int ret; - if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - if (asn1_object_identifier_equ(nodes, *nodes_cnt, oid_any_policy, oid_cnt(oid_any_policy))) - *oid = OID_any_policy; - else *oid = 0; - return 1; -} - - -#define oid_kp oid_pkix,3 - -static uint32_t oid_kp_server_auth[] = { oid_kp,1 }; -static uint32_t oid_kp_client_auth[] = { oid_kp,2 }; -static uint32_t oid_kp_code_signing[] = { oid_kp,3 }; -static uint32_t oid_kp_email_protection[] = { oid_kp,4 }; -static uint32_t oid_kp_time_stamping[] = { oid_kp,8 }; -static uint32_t oid_kp_ocsp_signing[] = { oid_kp,9 }; -#define OID_KP_CNT sizeof(oid_kp_server_auth)/sizeof(int) - -static const ASN1_OID_INFO x509_key_purposes[] = { - { OID_kp_server_auth, "serverAuth", oid_kp_server_auth, OID_KP_CNT, 0, "TLS WWW server authentication" }, - { OID_kp_client_auth, "clientAuth", oid_kp_client_auth, OID_KP_CNT, 0, "TLS WWW client authentication" }, - { OID_kp_code_signing, "codeSigning", oid_kp_code_signing, OID_KP_CNT, 0, "Signing of downloadable executable code" }, - { OID_kp_email_protection, "emailProtection", oid_kp_email_protection, OID_KP_CNT, 0, "Email protection" }, - { OID_kp_time_stamping, "timeStamping", oid_kp_time_stamping, OID_KP_CNT, 0, "Binding the hash of an object to a time" }, - { OID_kp_ocsp_signing, "OCSPSigning", oid_kp_ocsp_signing, OID_KP_CNT, 0, "Signing OCSP responses" }, -}; - -static const int x509_key_purposes_count = - sizeof(x509_key_purposes)/sizeof(x509_key_purposes[0]); - -int x509_key_purpose_from_name(const char *name) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_name(x509_key_purposes, x509_key_purposes_count, name))) { - error_print(); - return OID_undef; - } - return info->oid; -} - -const char *x509_key_purpose_name(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { - error_print(); - return NULL; - } - return info->name; -} - -const char *x509_key_purpose_text(int oid) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { - error_print(); - return NULL; - } - return info->description; -} - -int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen) -{ - const ASN1_OID_INFO *info; - if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { - error_print(); - return -1; - } - if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen) -{ - int ret; - const ASN1_OID_INFO *info; - if ((ret = asn1_oid_info_from_der(&info, x509_key_purposes, x509_key_purposes_count, in, inlen)) != 1) { - if (ret < 0) error_print(); - else *oid = -1; - return ret; - } - *oid = info->oid; - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static uint32_t oid_at_name[] = { oid_at,41 }; +static uint32_t oid_at_surname[] = { oid_at,4 }; +static uint32_t oid_at_given_name[] = { oid_at,42 }; +static uint32_t oid_at_initials[] = { oid_at,43 }; +static uint32_t oid_at_generation_qualifier[] = { oid_at,44 }; +static uint32_t oid_at_common_name[] = { oid_at,3 }; +static uint32_t oid_at_locality_name[] = { oid_at,7 }; +static uint32_t oid_at_state_or_province_name[] = { oid_at,8 }; +static uint32_t oid_at_organization_name[] = { oid_at,10 }; +static uint32_t oid_at_organizational_unit_name[] = { oid_at,11 }; +static uint32_t oid_at_title[] = { oid_at,12 }; +static uint32_t oid_at_dn_qualifier[] = { oid_at,46 }; +static uint32_t oid_at_country_name[] = { oid_at,6 }; +static uint32_t oid_at_serial_number[] = { oid_at,5 }; +static uint32_t oid_at_pseudonym[] = { oid_at,65 }; +static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 }; +static uint32_t oid_email_address[] = { 1,2,840,113549,1,9,1 }; + +#define OID_AT_CNT (sizeof(oid_at_name)/sizeof(int)) + +static const ASN1_OID_INFO x509_name_types[] = { + { OID_at_name, "name", oid_at_name, OID_AT_CNT }, + { OID_at_surname, "surname", oid_at_surname, OID_AT_CNT }, + { OID_at_given_name, "givenName", oid_at_given_name, OID_AT_CNT }, + { OID_at_initials, "initials", oid_at_initials, OID_AT_CNT }, + { OID_at_generation_qualifier, "generationQualifier", oid_at_generation_qualifier, OID_AT_CNT }, + { OID_at_common_name, "commonName", oid_at_common_name, OID_AT_CNT }, + { OID_at_locality_name, "localityName", oid_at_locality_name, OID_AT_CNT }, + { OID_at_state_or_province_name, "stateOrProvinceName", oid_at_state_or_province_name, OID_AT_CNT }, + { OID_at_organization_name, "organizationName", oid_at_organization_name, OID_AT_CNT }, + { OID_at_organizational_unit_name, "organizationalUnitName", oid_at_organizational_unit_name, OID_AT_CNT }, + { OID_at_title, "title", oid_at_title, OID_AT_CNT }, + { OID_at_dn_qualifier, "dnQualifier", oid_at_dn_qualifier, OID_AT_CNT }, + { OID_at_country_name, "countryName", oid_at_country_name, OID_AT_CNT }, + { OID_at_serial_number, "serialNumber", oid_at_serial_number, OID_AT_CNT }, + { OID_at_pseudonym, "pseudonym", oid_at_pseudonym, OID_AT_CNT }, + { OID_domain_component, "domainComponent", oid_domain_component, sizeof(oid_domain_component)/sizeof(int) }, + { OID_email_address, "emailAddress", oid_email_address, sizeof(oid_email_address)/sizeof(int) }, +}; + +static const int x509_name_types_count + = sizeof(x509_name_types)/sizeof(x509_name_types[0]); + +const char *x509_name_type_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_name_types, x509_name_types_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_name_type_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_name_types, x509_name_types_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_name_type_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_name_types, x509_name_types_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_name_type_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + + if ((ret = asn1_oid_info_from_der(&info, x509_name_types, x509_name_types_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + + +static uint32_t oid_ce_subject_directory_attributes[] = { oid_ce,9 }; +static uint32_t oid_ce_subject_key_identifier[] = { oid_ce,14 }; +static uint32_t oid_ce_key_usage[] = { oid_ce,15 }; +static uint32_t oid_ce_subject_alt_name[] = { oid_ce,17 }; +static uint32_t oid_ce_issuer_alt_name[] = { oid_ce,18 }; +static uint32_t oid_ce_basic_constraints[] = { oid_ce,19 }; +static uint32_t oid_ce_name_constraints[] = { oid_ce,30 }; +static uint32_t oid_ce_crl_distribution_points[] = { oid_ce,31 }; +static uint32_t oid_ce_certificate_policies[] = { oid_ce,32 }; +static uint32_t oid_ce_policy_mappings[] = { oid_ce,33 }; +static uint32_t oid_ce_authority_key_identifier[] = { oid_ce,35 }; +static uint32_t oid_ce_policy_constraints[] = { oid_ce,36 }; +static uint32_t oid_ce_ext_key_usage[] = { oid_ce,37 }; +static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 }; +static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 }; +static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; // crl_entry_ext +static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; // crl_entry_ext +static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext +#define OID_CE_CNT sizeof(oid_ce_subject_directory_attributes)/sizeof(int) +static uint32_t oid_netscape_cert_type[] = { 2,16,840,1,113730,1,1 }; +static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 }; +static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 }; +static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 }; + +static const ASN1_OID_INFO x509_ext_ids[] = { + { OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, OID_CE_CNT }, + { OID_ce_subject_key_identifier, "SubjectKeyIdentifier", oid_ce_subject_key_identifier, OID_CE_CNT }, + { OID_ce_key_usage, "KeyUsage", oid_ce_key_usage, OID_CE_CNT }, + { OID_ce_certificate_policies, "CertificatePolicies", oid_ce_certificate_policies, OID_CE_CNT }, + { OID_ce_policy_mappings, "PolicyMappings", oid_ce_policy_mappings, OID_CE_CNT }, + { OID_ce_subject_alt_name, "SubjectAltName", oid_ce_subject_alt_name, OID_CE_CNT }, + { OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, OID_CE_CNT }, + { OID_ce_subject_directory_attributes, "SubjectDirectoryAttributes", oid_ce_subject_directory_attributes, OID_CE_CNT }, + { OID_ce_basic_constraints, "BasicConstraints", oid_ce_basic_constraints, OID_CE_CNT }, + { OID_ce_name_constraints, "NameConstraints", oid_ce_name_constraints, OID_CE_CNT }, + { OID_ce_policy_constraints, "PolicyConstraints", oid_ce_policy_constraints, OID_CE_CNT }, + { OID_ce_ext_key_usage, "ExtKeyUsage", oid_ce_ext_key_usage, OID_CE_CNT }, + { OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, OID_CE_CNT }, + { OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, OID_CE_CNT }, + { OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, OID_CE_CNT }, + { OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, OID_CE_CNT }, + { OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, OID_CE_CNT }, + { OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, OID_CE_CNT }, + { OID_netscape_cert_type, "NetscapeCertType", oid_netscape_cert_type, sizeof(oid_netscape_cert_type)/sizeof(int) }, + { OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) }, + { OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) }, + { OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) }, +}; + +static const int x509_ext_ids_count = + sizeof(x509_ext_ids)/sizeof(x509_ext_ids[0]); + +const char *x509_ext_id_name(int oid) +{ + const ASN1_OID_INFO *info; + if (oid == 0) { + return NULL; + } + if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_ext_id_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_ext_ids, x509_ext_ids_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +int x509_ext_id_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_ext_ids, x509_ext_ids_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +// 如果要支持未知的ext_id,应该提供一个callback +int x509_ext_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + + if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_ext_ids, x509_ext_ids_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info ? info->oid : 0; + return 1; +} + + +static uint32_t oid_qt_cps[] = { oid_qt,1 }; +static uint32_t oid_qt_unotice[] = {oid_qt,2 }; + +static const ASN1_OID_INFO x509_qt_ids[] = { + { OID_qt_cps, "CPS", oid_qt_cps, sizeof(oid_qt_cps)/sizeof(int) }, + { OID_qt_unotice, "userNotice", oid_qt_unotice, sizeof(oid_qt_unotice)/sizeof(int) } +}; + +static const int x509_qt_ids_count = + sizeof(x509_qt_ids)/sizeof(x509_qt_ids[0]); + +int x509_qualifier_id_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_qt_ids, x509_qt_ids_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +const char *x509_qualifier_id_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_qt_ids, x509_qt_ids_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +int x509_qualifier_id_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_qt_ids, x509_qt_ids_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_qualifier_id_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + if ((ret = asn1_oid_info_from_der(&info, x509_qt_ids, x509_qt_ids_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} + + +int x509_cert_policy_id_from_name(const char *name) +{ + if (strcmp(name, "anyPolicy") == 0) { + return OID_any_policy; + } + return OID_undef; +} + +char *x509_cert_policy_id_name(int oid) +{ + switch (oid) { + case OID_any_policy: return "anyPolicy"; + } + return NULL; +} + +static uint32_t oid_any_policy[] = { oid_ce,32,0 }; + +int x509_cert_policy_id_to_der(int oid, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen) +{ + switch (oid) { + case OID_any_policy: + if (asn1_object_identifier_to_der(oid_any_policy, sizeof(oid_any_policy)/sizeof(int), out, outlen) != 1) { + error_print(); + return -1; + } + break; + case OID_undef: + if (asn1_object_identifier_to_der(nodes, nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int x509_cert_policy_id_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen) +{ + int ret; + if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + if (asn1_object_identifier_equ(nodes, *nodes_cnt, oid_any_policy, oid_cnt(oid_any_policy))) + *oid = OID_any_policy; + else *oid = 0; + return 1; +} + + +#define oid_kp oid_pkix,3 + +static uint32_t oid_kp_server_auth[] = { oid_kp,1 }; +static uint32_t oid_kp_client_auth[] = { oid_kp,2 }; +static uint32_t oid_kp_code_signing[] = { oid_kp,3 }; +static uint32_t oid_kp_email_protection[] = { oid_kp,4 }; +static uint32_t oid_kp_time_stamping[] = { oid_kp,8 }; +static uint32_t oid_kp_ocsp_signing[] = { oid_kp,9 }; +#define OID_KP_CNT sizeof(oid_kp_server_auth)/sizeof(int) + +static const ASN1_OID_INFO x509_key_purposes[] = { + { OID_kp_server_auth, "serverAuth", oid_kp_server_auth, OID_KP_CNT, 0, "TLS WWW server authentication" }, + { OID_kp_client_auth, "clientAuth", oid_kp_client_auth, OID_KP_CNT, 0, "TLS WWW client authentication" }, + { OID_kp_code_signing, "codeSigning", oid_kp_code_signing, OID_KP_CNT, 0, "Signing of downloadable executable code" }, + { OID_kp_email_protection, "emailProtection", oid_kp_email_protection, OID_KP_CNT, 0, "Email protection" }, + { OID_kp_time_stamping, "timeStamping", oid_kp_time_stamping, OID_KP_CNT, 0, "Binding the hash of an object to a time" }, + { OID_kp_ocsp_signing, "OCSPSigning", oid_kp_ocsp_signing, OID_KP_CNT, 0, "Signing OCSP responses" }, +}; + +static const int x509_key_purposes_count = + sizeof(x509_key_purposes)/sizeof(x509_key_purposes[0]); + +int x509_key_purpose_from_name(const char *name) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_name(x509_key_purposes, x509_key_purposes_count, name))) { + error_print(); + return OID_undef; + } + return info->oid; +} + +const char *x509_key_purpose_name(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { + error_print(); + return NULL; + } + return info->name; +} + +const char *x509_key_purpose_text(int oid) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { + error_print(); + return NULL; + } + return info->description; +} + +int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen) +{ + const ASN1_OID_INFO *info; + if (!(info = asn1_oid_info_from_oid(x509_key_purposes, x509_key_purposes_count, oid))) { + error_print(); + return -1; + } + if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen) +{ + int ret; + const ASN1_OID_INFO *info; + if ((ret = asn1_oid_info_from_der(&info, x509_key_purposes, x509_key_purposes_count, in, inlen)) != 1) { + if (ret < 0) error_print(); + else *oid = -1; + return ret; + } + *oid = info->oid; + return 1; +} diff --git a/src/x509_req.c b/src/x509_req.c index 6313d47b..0be52ed9 100644 --- a/src/x509_req.c +++ b/src/x509_req.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,339 +7,340 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int x509_request_info_to_der( - int version, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *attrs, size_t attrs_len, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (version != X509_version_v1) { - error_print(); - return -1; - } - if (asn1_int_to_der(version, NULL, &len) != 1 - || asn1_sequence_to_der(subject, subject_len, NULL, &len) != 1 - || x509_public_key_info_to_der(subject_public_key, NULL, &len) != 1 - || asn1_implicit_set_to_der(0, attrs, attrs_len, NULL, &len) < 0 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || asn1_int_to_der(version, out, outlen) != 1 - || asn1_sequence_to_der(subject, subject_len, out, outlen) != 1 - || x509_public_key_info_to_der(subject_public_key, out, outlen) != 1 - || asn1_implicit_set_to_der(0, attrs, attrs_len, out, outlen) < 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_request_info_from_der( - int *version, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **attrs, size_t *attrs_len, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_int_from_der(version, &d, &dlen) != 1 - || asn1_sequence_from_der(subject, subject_len, &d, &dlen) != 1 - || x509_public_key_info_from_der(subject_public_key, &d, &dlen) != 1 - || asn1_implicit_set_from_der(0, attrs, attrs_len, &d, &dlen) < 0 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (*version != X509_version_v1) { - error_print(); - return -1; - } - return 1; -} - -int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - int ret, ival; - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_int_from_der(&ival, &d, &dlen) != 1) goto err; - format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(ival), ival); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_name_print(fp, fmt, ind, "subject", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_public_key_info_print(fp, fmt, ind, "subjectPublicKeyInfo", p, len); - if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; - if (ret) x509_attributes_print(fp, fmt, ind, "attributes", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_request_to_der( - int version, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *attrs, size_t attrs_len, - int signature_algor, - const uint8_t *sig, size_t siglen, - uint8_t **out, size_t *outlen) -{ - size_t len = 0; - if (x509_request_info_to_der(version, subject, subject_len, subject_public_key, attrs, attrs_len, NULL, &len) != 1 - || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 - || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 - || asn1_sequence_header_to_der(len, out, outlen) != 1 - || x509_request_info_to_der(version, subject, subject_len, subject_public_key, attrs, attrs_len, out, outlen) != 1 - || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 - || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_request_from_der( - int *version, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **attrs, size_t *attrs_len, - int *signature_algor, - const uint8_t **sig, size_t *siglen, - const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *d; - size_t dlen; - - if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_request_info_from_der(version, subject, subject_len, subject_public_key, - attrs, attrs_len, &d, &dlen) != 1 - || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 - || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) -{ - const uint8_t *p; - size_t len; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_request_info_print(fp, fmt, ind, "certificationRequestInfo", p, len); - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; - x509_signature_algor_print(fp, fmt, ind, "signatureAlgorithm", p, len); - if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; - format_bytes(fp, fmt, ind, "signature: ", p, len); - if (asn1_length_is_zero(dlen) != 1) goto err; - return 1; -err: - error_print(); - return -1; -} - -int x509_req_sign( - uint8_t *req, size_t *reqlen, size_t maxlen, - int version, - const uint8_t *subject, size_t subject_len, - const SM2_KEY *subject_public_key, - const uint8_t *attrs, size_t attrs_len, - int signature_algor, - const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len) -{ - uint8_t req_info[2048]; - size_t req_info_len = 0; - uint8_t *p = req_info; - size_t len = 0; - SM2_SIGN_CTX sign_ctx; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - if (x509_request_info_to_der(version, subject, subject_len, subject_public_key, - attrs, attrs_len, NULL, &len) != 1 - || asn1_length_le(len, sizeof(req_info)) != 1 - || x509_request_info_to_der(version, subject, subject_len, subject_public_key, - attrs, attrs_len, &p, &req_info_len) != 1) { - error_print(); - return -1; - } - - if (signature_algor != OID_sm2sign_with_sm3) { - error_print(); - return -1; - } - if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 - || sm2_sign_update(&sign_ctx, req_info, req_info_len) != 1 - || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { - memset(&sign_ctx, 0, sizeof(sign_ctx)); - error_print(); - return -1; - } - memset(&sign_ctx, 0, sizeof(sign_ctx)); - - len = *reqlen = 0; - if (x509_request_to_der(version, subject, subject_len, subject_public_key, - attrs, attrs_len, signature_algor, sig, siglen, NULL, &len) != 1 - || asn1_length_le(len, maxlen) != 1 - || x509_request_to_der(version, subject, subject_len, subject_public_key, - attrs, attrs_len, signature_algor, sig, siglen, &req, reqlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_req_verify(const uint8_t *req, size_t reqlen, const SM2_KEY *sign_pubkey, const char *signer_id, size_t signer_id_len) -{ - int ret; - const uint8_t *d; - size_t dlen; - const uint8_t *p; - size_t len; - const uint8_t *req_info; - size_t req_info_len; - int signature_algor; - const uint8_t *sig; - size_t siglen; - SM2_SIGN_CTX sign_ctx; - - if (asn1_sequence_from_der(&d, &dlen, &req, &reqlen) != 1 - || asn1_length_is_zero(reqlen) != 1) { - error_print(); - return -1; - } - - req_info = d; - req_info_len = dlen; - if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { - error_print(); - return -1; - } - req_info_len -= dlen; - - if (x509_signature_algor_from_der(&signature_algor, &d, &dlen) != 1 - || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 - || asn1_length_is_zero(dlen) != 1) { - error_print(); - return -1; - } - if (signature_algor != OID_sm2sign_with_sm3) { - error_print(); - return -1; - } - if (sm2_verify_init(&sign_ctx, sign_pubkey, signer_id, signer_id_len) != 1 - || sm2_verify_update(&sign_ctx, req_info, req_info_len) != 1 - || (ret = sm2_verify_finish(&sign_ctx, sig, siglen)) != 1) { - error_print(); - return -1; - } - return ret; -} - -int x509_req_get_details(const uint8_t *req, size_t reqlen, - int *version, - const uint8_t **subject, size_t *subject_len, - SM2_KEY *subject_public_key, - const uint8_t **attributes, size_t *attributes_len, - int *signature_algor, - const uint8_t **signature, size_t *signature_len) -{ - int ver; - const uint8_t *subj; - size_t subj_len; - SM2_KEY pub_key; - const uint8_t *attrs; - size_t attrs_len; - int sig_alg; - const uint8_t *sig; - size_t siglen; - - if (x509_request_from_der(&ver, &subj, &subj_len, &pub_key, &attrs, &attrs_len, - &sig_alg, &sig, &siglen, &req, &reqlen) != 1 - || asn1_length_is_zero(reqlen) != 1) { - error_print(); - return -1; - } - if (version) *version = ver; - if (subject) *subject = subj; - if (subject_len) *subject_len = subj_len; - if (subject_public_key) *subject_public_key = pub_key; - if (attributes) *attributes = attrs; - if (attributes_len) *attributes_len = attrs_len; - if (signature_algor) *signature_algor = sig_alg; - if (signature) *signature = sig; - if (signature_len) *signature_len = siglen; - return 1; -} - -int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen) -{ - const uint8_t *d; - size_t dlen; - - if (asn1_sequence_from_der(&d, &dlen, &req, &reqlen) != 1 - || asn1_length_is_zero(reqlen) != 1) { - error_print(); - return -1; - } - x509_request_print(fp, fmt, ind, label, d, dlen); - return 1; -} - -int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp) -{ - if (pem_write(fp, "CERTIFICATE REQUEST", req, reqlen) <= 0) { - error_print(); - return -1; - } - return 1; -} - -int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp) -{ - if (pem_read(fp, "CERTIFICATE REQUEST", req, reqlen, maxlen) != 1) { - error_print(); - return -1; - } - return 1; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int x509_request_info_to_der( + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (version != X509_version_v1) { + error_print(); + return -1; + } + if (asn1_int_to_der(version, NULL, &len) != 1 + || asn1_sequence_to_der(subject, subject_len, NULL, &len) != 1 + || x509_public_key_info_to_der(subject_public_key, NULL, &len) != 1 + || asn1_implicit_set_to_der(0, attrs, attrs_len, NULL, &len) < 0 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || asn1_int_to_der(version, out, outlen) != 1 + || asn1_sequence_to_der(subject, subject_len, out, outlen) != 1 + || x509_public_key_info_to_der(subject_public_key, out, outlen) != 1 + || asn1_implicit_set_to_der(0, attrs, attrs_len, out, outlen) < 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_request_info_from_der( + int *version, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attrs, size_t *attrs_len, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_int_from_der(version, &d, &dlen) != 1 + || asn1_sequence_from_der(subject, subject_len, &d, &dlen) != 1 + || x509_public_key_info_from_der(subject_public_key, &d, &dlen) != 1 + || asn1_implicit_set_from_der(0, attrs, attrs_len, &d, &dlen) < 0 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (*version != X509_version_v1) { + error_print(); + return -1; + } + return 1; +} + +int x509_request_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + int ret, ival; + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_int_from_der(&ival, &d, &dlen) != 1) goto err; + format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(ival), ival); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_name_print(fp, fmt, ind, "subject", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_public_key_info_print(fp, fmt, ind, "subjectPublicKeyInfo", p, len); + if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err; + if (ret) x509_attributes_print(fp, fmt, ind, "attributes", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_request_to_der( + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const uint8_t *sig, size_t siglen, + uint8_t **out, size_t *outlen) +{ + size_t len = 0; + if (x509_request_info_to_der(version, subject, subject_len, subject_public_key, attrs, attrs_len, NULL, &len) != 1 + || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1 + || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1 + || asn1_sequence_header_to_der(len, out, outlen) != 1 + || x509_request_info_to_der(version, subject, subject_len, subject_public_key, attrs, attrs_len, out, outlen) != 1 + || x509_signature_algor_to_der(signature_algor, out, outlen) != 1 + || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_request_from_der( + int *version, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attrs, size_t *attrs_len, + int *signature_algor, + const uint8_t **sig, size_t *siglen, + const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *d; + size_t dlen; + + if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_request_info_from_der(version, subject, subject_len, subject_public_key, + attrs, attrs_len, &d, &dlen) != 1 + || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1 + || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *p; + size_t len; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_request_info_print(fp, fmt, ind, "certificationRequestInfo", p, len); + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err; + x509_signature_algor_print(fp, fmt, ind, "signatureAlgorithm", p, len); + if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err; + format_bytes(fp, fmt, ind, "signature: ", p, len); + if (asn1_length_is_zero(dlen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int x509_req_sign( + uint8_t *req, size_t *reqlen, size_t maxlen, + int version, + const uint8_t *subject, size_t subject_len, + const SM2_KEY *subject_public_key, + const uint8_t *attrs, size_t attrs_len, + int signature_algor, + const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len) +{ + uint8_t req_info[2048]; + size_t req_info_len = 0; + uint8_t *p = req_info; + size_t len = 0; + SM2_SIGN_CTX sign_ctx; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + if (x509_request_info_to_der(version, subject, subject_len, subject_public_key, + attrs, attrs_len, NULL, &len) != 1 + || asn1_length_le(len, sizeof(req_info)) != 1 + || x509_request_info_to_der(version, subject, subject_len, subject_public_key, + attrs, attrs_len, &p, &req_info_len) != 1) { + error_print(); + return -1; + } + + if (signature_algor != OID_sm2sign_with_sm3) { + error_print(); + return -1; + } + if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1 + || sm2_sign_update(&sign_ctx, req_info, req_info_len) != 1 + || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + memset(&sign_ctx, 0, sizeof(sign_ctx)); + error_print(); + return -1; + } + memset(&sign_ctx, 0, sizeof(sign_ctx)); + + len = *reqlen = 0; + if (x509_request_to_der(version, subject, subject_len, subject_public_key, + attrs, attrs_len, signature_algor, sig, siglen, NULL, &len) != 1 + || asn1_length_le(len, maxlen) != 1 + || x509_request_to_der(version, subject, subject_len, subject_public_key, + attrs, attrs_len, signature_algor, sig, siglen, &req, reqlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_req_verify(const uint8_t *req, size_t reqlen, const SM2_KEY *sign_pubkey, const char *signer_id, size_t signer_id_len) +{ + int ret; + const uint8_t *d; + size_t dlen; + const uint8_t *p; + size_t len; + const uint8_t *req_info; + size_t req_info_len; + int signature_algor; + const uint8_t *sig; + size_t siglen; + SM2_SIGN_CTX sign_ctx; + + if (asn1_sequence_from_der(&d, &dlen, &req, &reqlen) != 1 + || asn1_length_is_zero(reqlen) != 1) { + error_print(); + return -1; + } + + req_info = d; + req_info_len = dlen; + if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) { + error_print(); + return -1; + } + req_info_len -= dlen; + + if (x509_signature_algor_from_der(&signature_algor, &d, &dlen) != 1 + || asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1 + || asn1_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + if (signature_algor != OID_sm2sign_with_sm3) { + error_print(); + return -1; + } + if (sm2_verify_init(&sign_ctx, sign_pubkey, signer_id, signer_id_len) != 1 + || sm2_verify_update(&sign_ctx, req_info, req_info_len) != 1 + || (ret = sm2_verify_finish(&sign_ctx, sig, siglen)) != 1) { + error_print(); + return -1; + } + return ret; +} + +int x509_req_get_details(const uint8_t *req, size_t reqlen, + int *version, + const uint8_t **subject, size_t *subject_len, + SM2_KEY *subject_public_key, + const uint8_t **attributes, size_t *attributes_len, + int *signature_algor, + const uint8_t **signature, size_t *signature_len) +{ + int ver; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + int sig_alg; + const uint8_t *sig; + size_t siglen; + + if (x509_request_from_der(&ver, &subj, &subj_len, &pub_key, &attrs, &attrs_len, + &sig_alg, &sig, &siglen, &req, &reqlen) != 1 + || asn1_length_is_zero(reqlen) != 1) { + error_print(); + return -1; + } + if (version) *version = ver; + if (subject) *subject = subj; + if (subject_len) *subject_len = subj_len; + if (subject_public_key) *subject_public_key = pub_key; + if (attributes) *attributes = attrs; + if (attributes_len) *attributes_len = attrs_len; + if (signature_algor) *signature_algor = sig_alg; + if (signature) *signature = sig; + if (signature_len) *signature_len = siglen; + return 1; +} + +int x509_req_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *req, size_t reqlen) +{ + const uint8_t *d; + size_t dlen; + + if (asn1_sequence_from_der(&d, &dlen, &req, &reqlen) != 1 + || asn1_length_is_zero(reqlen) != 1) { + error_print(); + return -1; + } + x509_request_print(fp, fmt, ind, label, d, dlen); + return 1; +} + +int x509_req_to_pem(const uint8_t *req, size_t reqlen, FILE *fp) +{ + if (pem_write(fp, "CERTIFICATE REQUEST", req, reqlen) <= 0) { + error_print(); + return -1; + } + return 1; +} + +int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp) +{ + if (pem_read(fp, "CERTIFICATE REQUEST", req, reqlen, maxlen) != 1) { + error_print(); + return -1; + } + return 1; +} diff --git a/src/x509_str.c b/src/x509_str.c index d6614822..6d379ca4 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,229 +7,230 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* -DirectoryString ::= CHOICE { - teletexString TeletexString (SIZE (1..MAX)), - printableString PrintableString (SIZE (1..MAX)), - universalString UniversalString (SIZE (1..MAX)), - utf8String UTF8String (SIZE (1..MAX)), - bmpString BMPString (SIZE (1..MAX)) } - -BMPString has zeros! - "Cert" in BMPStirng is 00 43 00 65 00 72 00 74 - -RDN 中很多值都是这个类型,但是有特定的长度限制,因此这个函数应该增加一个长度限制选项。 -*/ - - -int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen) -{ - switch (tag) { - case ASN1_TAG_TeletexString: - case ASN1_TAG_PrintableString: - case ASN1_TAG_UniversalString: - case ASN1_TAG_UTF8String: - if (d && strnlen((char *)d, dlen) != dlen) { - error_print(); - return -1; - } - break; - case ASN1_TAG_BMPString: - if (d && dlen % 2) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - return 1; -} - -int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen) -{ - if (x509_directory_name_check(tag, d, dlen) != 1) { - error_print(); - return -1; - } - if (dlen < minlen || dlen > maxlen) { - printf("%s %d: dlen = %zu, minlen = %zu, maxlne = %zu\n", __FILE__, __LINE__, dlen, minlen, maxlen); - error_print(); - return -1; - } - return 1; -} - -int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - int ret; - if (x509_directory_name_check(tag, d, dlen) != 1) { - error_print(); - return -1; - } - if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - - if ((ret = asn1_tag_get(tag, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - switch (*tag) { - case ASN1_TAG_TeletexString: - case ASN1_TAG_PrintableString: - case ASN1_TAG_UniversalString: - case ASN1_TAG_UTF8String: - case ASN1_TAG_BMPString: - break; - default: - return 0; - } - - if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_directory_name_check(*tag, *d, *dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - int ret; - size_t len = 0; - - if ((ret = x509_directory_name_to_der(tag, d, dlen, NULL, &len)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (asn1_explicit_header_to_der(index, len, out, outlen) != 1 - || x509_directory_name_to_der(tag, d, dlen, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - const uint8_t *p; - size_t len; - - if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_directory_name_from_der(tag, d, dlen, &p, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) -{ - return asn1_string_print(fp, fmt, ind, label, tag, d, dlen); -} - -int x509_display_text_check(int tag, const uint8_t *d, size_t dlen) -{ - switch (tag) { - case ASN1_TAG_IA5String: - case ASN1_TAG_VisibleString: - case ASN1_TAG_UTF8String: - if (d && strnlen((char *)d, dlen) != dlen) { - error_print(); - return -1; - } - break; - case ASN1_TAG_BMPString: - if (d && dlen % 2) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - if (dlen < X509_DISPLAY_TEXT_MIN_LEN || dlen > X509_DISPLAY_TEXT_MAX_LEN) { - error_print(); - return -1; - } - return 1; -} - -int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) -{ - int ret; - if (x509_display_text_check(tag, d, dlen) != 1) { - error_print(); - return -1; - } - if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - return 1; -} - -int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) -{ - int ret; - - if ((ret = asn1_tag_get(tag, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - switch (*tag) { - case ASN1_TAG_IA5String: - case ASN1_TAG_VisibleString: - case ASN1_TAG_UTF8String: - case ASN1_TAG_BMPString: - break; - default: - return 0; - } - - if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) { - if (ret < 0) error_print(); - return ret; - } - if (x509_display_text_check(*tag, *d, *dlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) -{ - return asn1_string_print(fp, fmt, ind, label, tag, d, dlen); -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +DirectoryString ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1..MAX)), + bmpString BMPString (SIZE (1..MAX)) } + +BMPString has zeros! + "Cert" in BMPStirng is 00 43 00 65 00 72 00 74 + +RDN 中很多值都是这个类型,但是有特定的长度限制,因此这个函数应该增加一个长度限制选项。 +*/ + + +int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen) +{ + switch (tag) { + case ASN1_TAG_TeletexString: + case ASN1_TAG_PrintableString: + case ASN1_TAG_UniversalString: + case ASN1_TAG_UTF8String: + if (d && strnlen((char *)d, dlen) != dlen) { + error_print(); + return -1; + } + break; + case ASN1_TAG_BMPString: + if (d && dlen % 2) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + return 1; +} + +int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen) +{ + if (x509_directory_name_check(tag, d, dlen) != 1) { + error_print(); + return -1; + } + if (dlen < minlen || dlen > maxlen) { + printf("%s %d: dlen = %zu, minlen = %zu, maxlne = %zu\n", __FILE__, __LINE__, dlen, minlen, maxlen); + error_print(); + return -1; + } + return 1; +} + +int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + int ret; + if (x509_directory_name_check(tag, d, dlen) != 1) { + error_print(); + return -1; + } + if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + + if ((ret = asn1_tag_get(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + switch (*tag) { + case ASN1_TAG_TeletexString: + case ASN1_TAG_PrintableString: + case ASN1_TAG_UniversalString: + case ASN1_TAG_UTF8String: + case ASN1_TAG_BMPString: + break; + default: + return 0; + } + + if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_directory_name_check(*tag, *d, *dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + int ret; + size_t len = 0; + + if ((ret = x509_directory_name_to_der(tag, d, dlen, NULL, &len)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (asn1_explicit_header_to_der(index, len, out, outlen) != 1 + || x509_directory_name_to_der(tag, d, dlen, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + const uint8_t *p; + size_t len; + + if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_directory_name_from_der(tag, d, dlen, &p, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) +{ + return asn1_string_print(fp, fmt, ind, label, tag, d, dlen); +} + +int x509_display_text_check(int tag, const uint8_t *d, size_t dlen) +{ + switch (tag) { + case ASN1_TAG_IA5String: + case ASN1_TAG_VisibleString: + case ASN1_TAG_UTF8String: + if (d && strnlen((char *)d, dlen) != dlen) { + error_print(); + return -1; + } + break; + case ASN1_TAG_BMPString: + if (d && dlen % 2) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + if (dlen < X509_DISPLAY_TEXT_MIN_LEN || dlen > X509_DISPLAY_TEXT_MAX_LEN) { + error_print(); + return -1; + } + return 1; +} + +int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen) +{ + int ret; + if (x509_display_text_check(tag, d, dlen) != 1) { + error_print(); + return -1; + } + if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + return 1; +} + +int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen) +{ + int ret; + + if ((ret = asn1_tag_get(tag, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + switch (*tag) { + case ASN1_TAG_IA5String: + case ASN1_TAG_VisibleString: + case ASN1_TAG_UTF8String: + case ASN1_TAG_BMPString: + break; + default: + return 0; + } + + if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) { + if (ret < 0) error_print(); + return ret; + } + if (x509_display_text_check(*tag, *d, *dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen) +{ + return asn1_string_print(fp, fmt, ind, label, tag, d, dlen); +} diff --git a/src/zuc.c b/src/zuc.c index 6a6923a9..e33f36ed 100644 --- a/src/zuc.c +++ b/src/zuc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,598 +7,599 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -static const ZUC_UINT15 KD[16] = { - 0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF, - 0x4D78,0x2F13,0x6BC4,0x1AF1,0x5E26,0x3C4D,0x789A,0x47AC, -}; - -static const uint8_t S0[256] = { - 0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb, - 0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90, - 0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac, - 0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38, - 0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b, - 0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c, - 0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad, - 0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8, - 0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56, - 0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe, - 0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d, - 0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23, - 0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1, - 0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f, - 0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65, - 0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60, -}; - -static const uint8_t S1[256] = { - 0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77, - 0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42, - 0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1, - 0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48, - 0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87, - 0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb, - 0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09, - 0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9, - 0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9, - 0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89, - 0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4, - 0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde, - 0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21, - 0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34, - 0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28, - 0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2, -}; - - -#define ADD31(a,b) a += (b); a = (a & 0x7fffffff) + (a >> 31) -#define ROT31(a,k) ((((a) << (k)) | ((a) >> (31 - (k)))) & 0x7FFFFFFF) -#define ROT32(a,k) (((a) << (k)) | ((a) >> (32 - (k)))) - -#define L1(X) \ - ((X) ^ \ - ROT32((X), 2) ^ \ - ROT32((X), 10) ^ \ - ROT32((X), 18) ^ \ - ROT32((X), 24)) - -#define L2(X) \ - ((X) ^ \ - ROT32((X), 8) ^ \ - ROT32((X), 14) ^ \ - ROT32((X), 22) ^ \ - ROT32((X), 30)) - -#define LFSRWithInitialisationMode(u) \ - V = LFSR[0]; \ - ADD31(V, ROT31(LFSR[0], 8)); \ - ADD31(V, ROT31(LFSR[4], 20)); \ - ADD31(V, ROT31(LFSR[10], 21)); \ - ADD31(V, ROT31(LFSR[13], 17)); \ - ADD31(V, ROT31(LFSR[15], 15)); \ - ADD31(V, (u)); \ - {int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \ - LFSR[15] = V - -#define LFSRWithWorkMode() \ - { \ - int j; \ - uint64_t a = LFSR[0]; \ - a += ((uint64_t)LFSR[0]) << 8; \ - a += ((uint64_t)LFSR[4]) << 20; \ - a += ((uint64_t)LFSR[10]) << 21; \ - a += ((uint64_t)LFSR[13]) << 17; \ - a += ((uint64_t)LFSR[15]) << 15; \ - a = (a & 0x7fffffff) + (a >> 31); \ - V = (a & 0x7fffffff) + (a >> 31); \ - for (j = 0; j < 15; j++) \ - LFSR[j] = LFSR[j+1]; \ - LFSR[15] = V; \ - } - -#define BitReconstruction2(X1,X2) \ - X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \ - X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15) - -#define BitReconstruction3(X0,X1,X2) \ - X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \ - BitReconstruction2(X1,X2) - -#define BitReconstruction4(X0,X1,X2,X3) \ - BitReconstruction3(X0,X1,X2); \ - X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15) - - -#define MAKEU31(k,d,iv) \ - (((uint32_t)(k) << 23) | \ - ((uint32_t)(d) << 8) | \ - (uint32_t)(iv)) - -#define MAKEU32(a, b, c, d) \ - (((uint32_t)(a) << 24) | \ - ((uint32_t)(b) << 16) | \ - ((uint32_t)(c) << 8) | \ - ((uint32_t)(d))) - -#define F_(X1,X2) \ - W1 = R1 + X1; \ - W2 = R2 ^ X2; \ - U = L1((W1 << 16) | (W2 >> 16)); \ - V = L2((W2 << 16) | (W1 >> 16)); \ - R1 = MAKEU32( S0[U >> 24], \ - S1[(U >> 16) & 0xFF], \ - S0[(U >> 8) & 0xFF], \ - S1[U & 0xFF]); \ - R2 = MAKEU32( S0[V >> 24], \ - S1[(V >> 16) & 0xFF], \ - S0[(V >> 8) & 0xFF], \ - S1[V & 0xFF]) - -#define F(X0,X1,X2) \ - (X0 ^ R1) + R2; \ - F_(X1, X2) - -void zuc_init(ZUC_STATE *state, const uint8_t *user_key, const uint8_t *iv) -{ - ZUC_UINT31 *LFSR = state->LFSR; - uint32_t R1, R2; - uint32_t X0, X1, X2; - uint32_t W, W1, W2, U, V; - int i; - - for (i = 0; i < 16; i++) { - LFSR[i] = MAKEU31(user_key[i], KD[i], iv[i]); - } - - R1 = 0; - R2 = 0; - - for (i = 0; i < 32; i++) { - BitReconstruction3(X0, X1, X2); - W = F(X0, X1, X2); - LFSRWithInitialisationMode(W >> 1); - } - - BitReconstruction2(X1, X2); - F_(X1, X2); - LFSRWithWorkMode(); - - state->R1 = R1; - state->R2 = R2; -} - -uint32_t zuc_generate_keyword(ZUC_STATE *state) -{ - ZUC_UINT31 *LFSR = state->LFSR; - uint32_t R1 = state->R1; - uint32_t R2 = state->R2; - uint32_t X0, X1, X2, X3; - uint32_t W1, W2, U, V; - uint32_t Z; - - BitReconstruction4(X0, X1, X2, X3); - Z = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - - state->R1 = R1; - state->R2 = R2; - - return Z; -} - -void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, uint32_t *keystream) -{ - ZUC_UINT31 *LFSR = state->LFSR; - uint32_t R1 = state->R1; - uint32_t R2 = state->R2; - uint32_t X0, X1, X2, X3; - uint32_t W1, W2, U, V; - size_t i; - - for (i = 0; i < nwords; i ++) { - BitReconstruction4(X0, X1, X2, X3); - keystream[i] = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - } - - state->R1 = R1; - state->R2 = R2; -} - -void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out) -{ - ZUC_UINT31 *LFSR = state->LFSR; - uint32_t R1 = state->R1; - uint32_t R2 = state->R2; - uint32_t X0, X1, X2, X3; - uint32_t W1, W2, U, V; - uint32_t Z; - uint8_t block[4]; - size_t nwords = inlen / sizeof(uint32_t); - size_t i; - - for (i = 0; i < nwords; i ++) { - BitReconstruction4(X0, X1, X2, X3); - Z = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - PUTU32(block, Z); - gmssl_memxor(out, in, block, sizeof(block)); - in += sizeof(block); - out += sizeof(block); - } - if (inlen % 4) { - // TODO: use assert to make sure this branch should not be arrived - BitReconstruction4(X0, X1, X2, X3); - Z = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - PUTU32(block, Z); - gmssl_memxor(out, in, block, inlen % 4); - } - - state->R1 = R1; - state->R2 = R2; -} - -void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[16], const uint8_t iv[16]) -{ - memset(ctx, 0, sizeof(*ctx)); - zuc_init((ZUC_STATE *)ctx, key, iv); - ctx->K0 = zuc_generate_keyword((ZUC_STATE *)ctx); -} - -void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len) -{ - ZUC_UINT32 T = ctx->T; - ZUC_UINT32 K0 = ctx->K0; - ZUC_UINT32 K1, M; - ZUC_UINT31 *LFSR = ctx->LFSR; - ZUC_UINT32 R1 = ctx->R1; - ZUC_UINT32 R2 = ctx->R2; - ZUC_UINT32 X0, X1, X2, X3; - ZUC_UINT32 W1, W2, U, V; - size_t i; - - if (!data || !len) { - return; - } - - if (ctx->buflen) { - size_t num = sizeof(ctx->buf) - ctx->buflen; - if (len < num) { - memcpy(ctx->buf + ctx->buflen, data, len); - ctx->buflen += len; - return; - } - - memcpy(ctx->buf + ctx->buflen, data, num); - M = GETU32(ctx->buf); - ctx->buflen = 0; - - BitReconstruction4(X0, X1, X2, X3); - K1 = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - - for (i = 0; i < 32; i++) { - if (M & 0x80000000) { - T ^= K0; - } - M <<= 1; - K0 = (K0 << 1) | (K1 >> 31); - K1 <<= 1; - } - - data += num; - len -= num; - } - - while (len >= 4) { - M = GETU32(data); - - BitReconstruction4(X0, X1, X2, X3); - K1 = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - - for (i = 0; i < 32; i++) { - if (M & 0x80000000) { - T ^= K0; - } - M <<= 1; - K0 = (K0 << 1) | (K1 >> 31); - K1 <<= 1; - } - - data += 4; - len -= 4; - } - - if (len) { - memcpy(ctx->buf, data, len); - ctx->buflen = len; - } - ctx->R1 = R1; - ctx->R2 = R2; - ctx->K0 = K0; - ctx->T = T; -} - -void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[4]) -{ - ZUC_UINT32 T = ctx->T; - ZUC_UINT32 K0 = ctx->K0; - ZUC_UINT32 K1, M; - ZUC_UINT31 *LFSR = ctx->LFSR; - ZUC_UINT32 R1 = ctx->R1; - ZUC_UINT32 R2 = ctx->R2; - ZUC_UINT32 X0, X1, X2, X3; - ZUC_UINT32 W1, W2, U, V; - size_t i; - - - if (!data) - nbits = 0; - - if (nbits >= 8) { - zuc_mac_update(ctx, data, nbits/8); - data += nbits/8; - nbits %= 8; - } - - T = ctx->T; - K0 = ctx->K0; - LFSR = ctx->LFSR; - R1 = ctx->R1; - R2 = ctx->R2; - - - if (nbits) - ctx->buf[ctx->buflen] = *data; - - if (ctx->buflen || nbits) { - M = GETU32(ctx->buf); - BitReconstruction4(X0, X1, X2, X3); - K1 = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - - for (i = 0; i < ctx->buflen * 8 + nbits; i++) { - if (M & 0x80000000) { - T ^= K0; - } - M <<= 1; - K0 = (K0 << 1) | (K1 >> 31); - K1 <<= 1; - } - } - - T ^= K0; - - BitReconstruction4(X0, X1, X2, X3); - K1 = X3 ^ F(X0, X1, X2); - LFSRWithWorkMode(); - T ^= K1; - - ctx->T = T; - PUTU32(mac, T); - - memset(ctx, 0, sizeof(*ctx)); -} - - -typedef uint8_t ZUC_UINT7; - -static const ZUC_UINT7 ZUC256_D[][16] = { - {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, - {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, - {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, - {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, -}; - -#define ZUC256_MAKEU31(a,b,c,d) \ - (((uint32_t)(a) << 23) | \ - ((uint32_t)(b) << 16) | \ - ((uint32_t)(c) << 8) | \ - (uint32_t)(d)) - - -static void zuc256_set_mac_key(ZUC_STATE *key, const uint8_t K[32], - const uint8_t IV[23], int macbits) -{ - ZUC_UINT31 *LFSR = key->LFSR; - uint32_t R1, R2; - uint32_t X0, X1, X2; - uint32_t W, W1, W2, U, V; - const ZUC_UINT7 *D; - int i; - - ZUC_UINT6 IV17 = IV[17] >> 2; - ZUC_UINT6 IV18 = ((IV[17] & 0x3) << 4) | (IV[18] >> 4); - ZUC_UINT6 IV19 = ((IV[18] & 0xf) << 2) | (IV[19] >> 6); - ZUC_UINT6 IV20 = IV[19] & 0x3f; - ZUC_UINT6 IV21 = IV[20] >> 2; - ZUC_UINT6 IV22 = ((IV[20] & 0x3) << 4) | (IV[21] >> 4); - ZUC_UINT6 IV23 = ((IV[21] & 0xf) << 2) | (IV[22] >> 6); - ZUC_UINT6 IV24 = IV[22] & 0x3f; - - D = macbits/32 < 3 ? ZUC256_D[macbits/32] : ZUC256_D[3]; - LFSR[0] = ZUC256_MAKEU31(K[0], D[0], K[21], K[16]); - LFSR[1] = ZUC256_MAKEU31(K[1], D[1], K[22], K[17]); - LFSR[2] = ZUC256_MAKEU31(K[2], D[2], K[23], K[18]); - LFSR[3] = ZUC256_MAKEU31(K[3], D[3], K[24], K[19]); - LFSR[4] = ZUC256_MAKEU31(K[4], D[4], K[25], K[20]); - LFSR[5] = ZUC256_MAKEU31(IV[0], (D[5] | IV17), K[5], K[26]); - LFSR[6] = ZUC256_MAKEU31(IV[1], (D[6] | IV18), K[6], K[27]); - LFSR[7] = ZUC256_MAKEU31(IV[10], (D[7] | IV19), K[7], IV[2]); - LFSR[8] = ZUC256_MAKEU31(K[8], (D[8] | IV20), IV[3], IV[11]); - LFSR[9] = ZUC256_MAKEU31(K[9], (D[9] | IV21), IV[12], IV[4]); - LFSR[10] = ZUC256_MAKEU31(IV[5], (D[10] | IV22), K[10], K[28]); - LFSR[11] = ZUC256_MAKEU31(K[11], (D[11] | IV23), IV[6], IV[13]); - LFSR[12] = ZUC256_MAKEU31(K[12], (D[12] | IV24), IV[7], IV[14]); - LFSR[13] = ZUC256_MAKEU31(K[13], D[13], IV[15], IV[8]); - LFSR[14] = ZUC256_MAKEU31(K[14], (D[14] | (K[31] >> 4)), IV[16], IV[9]); - LFSR[15] = ZUC256_MAKEU31(K[15], (D[15] | (K[31] & 0x0F)), K[30], K[29]); - - R1 = 0; - R2 = 0; - - for (i = 0; i < 32; i++) { - BitReconstruction3(X0, X1, X2); - W = F(X0, X1, X2); - LFSRWithInitialisationMode(W >> 1); - } - - BitReconstruction2(X1, X2); - F_(X1, X2); - LFSRWithWorkMode(); - - key->R1 = R1; - key->R2 = R2; -} - -void zuc256_init(ZUC_STATE *key, const uint8_t K[32], - const uint8_t IV[23]) -{ - zuc256_set_mac_key(key, K, IV, 0); -} - -void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[32], - const uint8_t iv[23], int macbits) -{ - if (macbits < 32) - macbits = 32; - else if (macbits > 64) - macbits = 128; - memset(ctx, 0, sizeof(*ctx)); - zuc256_set_mac_key((ZUC256_STATE *)ctx, key, iv, macbits); - zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->T); - zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->K0); - ctx->macbits = (macbits/32) * 32; -} - -void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len) -{ - ZUC_UINT32 K1, M; - size_t n = ctx->macbits / 32; - size_t i, j; - - if (!data || !len) { - return; - } - - if (ctx->buflen) { - size_t num = sizeof(ctx->buf) - ctx->buflen; - if (len < num) { - memcpy(ctx->buf + ctx->buflen, data, len); - ctx->buflen += len; - return; - } - - memcpy(ctx->buf + ctx->buflen, data, num); - M = GETU32(ctx->buf); - ctx->buflen = 0; - - K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); - - for (i = 0; i < 32; i++) { - if (M & 0x80000000) { - for (j = 0; j < n; j++) { - ctx->T[j] ^= ctx->K0[j]; - } - } - M <<= 1; - for (j = 0; j < n - 1; j++) { - ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); - } - ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); - K1 <<= 1; - } - - data += num; - len -= num; - } - - while (len >= 4) { - M = GETU32(data); - K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); - - for (i = 0; i < 32; i++) { - if (M & 0x80000000) { - for (j = 0; j < n; j++) { - ctx->T[j] ^= ctx->K0[j]; - } - } - M <<= 1; - for (j = 0; j < n - 1; j++) { - ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); - } - ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); - K1 <<= 1; - } - - data += 4; - len -= 4; - } - - if (len) { - memcpy(ctx->buf, data, len); - ctx->buflen = len; - } -} - -void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t *mac) -{ - ZUC_UINT32 K1, M; - size_t n = ctx->macbits/32; - size_t i, j; - - - if (!data) - nbits = 0; - - if (nbits >= 8) { - zuc256_mac_update(ctx, data, nbits/8); - data += nbits/8; - nbits %= 8; - } - - if (nbits) - ctx->buf[ctx->buflen] = *data; - - if (ctx->buflen || nbits) { - M = GETU32(ctx->buf); - K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); - - - for (i = 0; i < ctx->buflen * 8 + nbits; i++) { - if (M & 0x80000000) { - for (j = 0; j < n; j++) { - ctx->T[j] ^= ctx->K0[j]; - } - } - M <<= 1; - for (j = 0; j < n - 1; j++) { - ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); - } - ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); - K1 <<= 1; - } - } - - for (j = 0; j < n; j++) { - ctx->T[j] ^= ctx->K0[j]; - PUTU32(mac, ctx->T[j]); - mac += 4; - } - - memset(ctx, 0, sizeof(*ctx)); -} + + +#include +#include +#include +#include +#include + + +static const ZUC_UINT15 KD[16] = { + 0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF, + 0x4D78,0x2F13,0x6BC4,0x1AF1,0x5E26,0x3C4D,0x789A,0x47AC, +}; + +static const uint8_t S0[256] = { + 0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb, + 0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90, + 0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac, + 0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38, + 0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b, + 0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c, + 0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad, + 0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8, + 0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56, + 0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe, + 0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d, + 0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23, + 0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1, + 0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f, + 0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65, + 0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60, +}; + +static const uint8_t S1[256] = { + 0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77, + 0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42, + 0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1, + 0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48, + 0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87, + 0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb, + 0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09, + 0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9, + 0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9, + 0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89, + 0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4, + 0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde, + 0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21, + 0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34, + 0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28, + 0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2, +}; + + +#define ADD31(a,b) a += (b); a = (a & 0x7fffffff) + (a >> 31) +#define ROT31(a,k) ((((a) << (k)) | ((a) >> (31 - (k)))) & 0x7FFFFFFF) +#define ROT32(a,k) (((a) << (k)) | ((a) >> (32 - (k)))) + +#define L1(X) \ + ((X) ^ \ + ROT32((X), 2) ^ \ + ROT32((X), 10) ^ \ + ROT32((X), 18) ^ \ + ROT32((X), 24)) + +#define L2(X) \ + ((X) ^ \ + ROT32((X), 8) ^ \ + ROT32((X), 14) ^ \ + ROT32((X), 22) ^ \ + ROT32((X), 30)) + +#define LFSRWithInitialisationMode(u) \ + V = LFSR[0]; \ + ADD31(V, ROT31(LFSR[0], 8)); \ + ADD31(V, ROT31(LFSR[4], 20)); \ + ADD31(V, ROT31(LFSR[10], 21)); \ + ADD31(V, ROT31(LFSR[13], 17)); \ + ADD31(V, ROT31(LFSR[15], 15)); \ + ADD31(V, (u)); \ + {int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \ + LFSR[15] = V + +#define LFSRWithWorkMode() \ + { \ + int j; \ + uint64_t a = LFSR[0]; \ + a += ((uint64_t)LFSR[0]) << 8; \ + a += ((uint64_t)LFSR[4]) << 20; \ + a += ((uint64_t)LFSR[10]) << 21; \ + a += ((uint64_t)LFSR[13]) << 17; \ + a += ((uint64_t)LFSR[15]) << 15; \ + a = (a & 0x7fffffff) + (a >> 31); \ + V = (a & 0x7fffffff) + (a >> 31); \ + for (j = 0; j < 15; j++) \ + LFSR[j] = LFSR[j+1]; \ + LFSR[15] = V; \ + } + +#define BitReconstruction2(X1,X2) \ + X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \ + X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15) + +#define BitReconstruction3(X0,X1,X2) \ + X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \ + BitReconstruction2(X1,X2) + +#define BitReconstruction4(X0,X1,X2,X3) \ + BitReconstruction3(X0,X1,X2); \ + X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15) + + +#define MAKEU31(k,d,iv) \ + (((uint32_t)(k) << 23) | \ + ((uint32_t)(d) << 8) | \ + (uint32_t)(iv)) + +#define MAKEU32(a, b, c, d) \ + (((uint32_t)(a) << 24) | \ + ((uint32_t)(b) << 16) | \ + ((uint32_t)(c) << 8) | \ + ((uint32_t)(d))) + +#define F_(X1,X2) \ + W1 = R1 + X1; \ + W2 = R2 ^ X2; \ + U = L1((W1 << 16) | (W2 >> 16)); \ + V = L2((W2 << 16) | (W1 >> 16)); \ + R1 = MAKEU32( S0[U >> 24], \ + S1[(U >> 16) & 0xFF], \ + S0[(U >> 8) & 0xFF], \ + S1[U & 0xFF]); \ + R2 = MAKEU32( S0[V >> 24], \ + S1[(V >> 16) & 0xFF], \ + S0[(V >> 8) & 0xFF], \ + S1[V & 0xFF]) + +#define F(X0,X1,X2) \ + (X0 ^ R1) + R2; \ + F_(X1, X2) + +void zuc_init(ZUC_STATE *state, const uint8_t *user_key, const uint8_t *iv) +{ + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1, R2; + uint32_t X0, X1, X2; + uint32_t W, W1, W2, U, V; + int i; + + for (i = 0; i < 16; i++) { + LFSR[i] = MAKEU31(user_key[i], KD[i], iv[i]); + } + + R1 = 0; + R2 = 0; + + for (i = 0; i < 32; i++) { + BitReconstruction3(X0, X1, X2); + W = F(X0, X1, X2); + LFSRWithInitialisationMode(W >> 1); + } + + BitReconstruction2(X1, X2); + F_(X1, X2); + LFSRWithWorkMode(); + + state->R1 = R1; + state->R2 = R2; +} + +uint32_t zuc_generate_keyword(ZUC_STATE *state) +{ + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1 = state->R1; + uint32_t R2 = state->R2; + uint32_t X0, X1, X2, X3; + uint32_t W1, W2, U, V; + uint32_t Z; + + BitReconstruction4(X0, X1, X2, X3); + Z = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + + state->R1 = R1; + state->R2 = R2; + + return Z; +} + +void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, uint32_t *keystream) +{ + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1 = state->R1; + uint32_t R2 = state->R2; + uint32_t X0, X1, X2, X3; + uint32_t W1, W2, U, V; + size_t i; + + for (i = 0; i < nwords; i ++) { + BitReconstruction4(X0, X1, X2, X3); + keystream[i] = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + } + + state->R1 = R1; + state->R2 = R2; +} + +void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out) +{ + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1 = state->R1; + uint32_t R2 = state->R2; + uint32_t X0, X1, X2, X3; + uint32_t W1, W2, U, V; + uint32_t Z; + uint8_t block[4]; + size_t nwords = inlen / sizeof(uint32_t); + size_t i; + + for (i = 0; i < nwords; i ++) { + BitReconstruction4(X0, X1, X2, X3); + Z = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + PUTU32(block, Z); + gmssl_memxor(out, in, block, sizeof(block)); + in += sizeof(block); + out += sizeof(block); + } + if (inlen % 4) { + // TODO: use assert to make sure this branch should not be arrived + BitReconstruction4(X0, X1, X2, X3); + Z = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + PUTU32(block, Z); + gmssl_memxor(out, in, block, inlen % 4); + } + + state->R1 = R1; + state->R2 = R2; +} + +void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[16], const uint8_t iv[16]) +{ + memset(ctx, 0, sizeof(*ctx)); + zuc_init((ZUC_STATE *)ctx, key, iv); + ctx->K0 = zuc_generate_keyword((ZUC_STATE *)ctx); +} + +void zuc_mac_update(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t len) +{ + ZUC_UINT32 T = ctx->T; + ZUC_UINT32 K0 = ctx->K0; + ZUC_UINT32 K1, M; + ZUC_UINT31 *LFSR = ctx->LFSR; + ZUC_UINT32 R1 = ctx->R1; + ZUC_UINT32 R2 = ctx->R2; + ZUC_UINT32 X0, X1, X2, X3; + ZUC_UINT32 W1, W2, U, V; + size_t i; + + if (!data || !len) { + return; + } + + if (ctx->buflen) { + size_t num = sizeof(ctx->buf) - ctx->buflen; + if (len < num) { + memcpy(ctx->buf + ctx->buflen, data, len); + ctx->buflen += len; + return; + } + + memcpy(ctx->buf + ctx->buflen, data, num); + M = GETU32(ctx->buf); + ctx->buflen = 0; + + BitReconstruction4(X0, X1, X2, X3); + K1 = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + + for (i = 0; i < 32; i++) { + if (M & 0x80000000) { + T ^= K0; + } + M <<= 1; + K0 = (K0 << 1) | (K1 >> 31); + K1 <<= 1; + } + + data += num; + len -= num; + } + + while (len >= 4) { + M = GETU32(data); + + BitReconstruction4(X0, X1, X2, X3); + K1 = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + + for (i = 0; i < 32; i++) { + if (M & 0x80000000) { + T ^= K0; + } + M <<= 1; + K0 = (K0 << 1) | (K1 >> 31); + K1 <<= 1; + } + + data += 4; + len -= 4; + } + + if (len) { + memcpy(ctx->buf, data, len); + ctx->buflen = len; + } + ctx->R1 = R1; + ctx->R2 = R2; + ctx->K0 = K0; + ctx->T = T; +} + +void zuc_mac_finish(ZUC_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t mac[4]) +{ + ZUC_UINT32 T = ctx->T; + ZUC_UINT32 K0 = ctx->K0; + ZUC_UINT32 K1, M; + ZUC_UINT31 *LFSR = ctx->LFSR; + ZUC_UINT32 R1 = ctx->R1; + ZUC_UINT32 R2 = ctx->R2; + ZUC_UINT32 X0, X1, X2, X3; + ZUC_UINT32 W1, W2, U, V; + size_t i; + + + if (!data) + nbits = 0; + + if (nbits >= 8) { + zuc_mac_update(ctx, data, nbits/8); + data += nbits/8; + nbits %= 8; + } + + T = ctx->T; + K0 = ctx->K0; + LFSR = ctx->LFSR; + R1 = ctx->R1; + R2 = ctx->R2; + + + if (nbits) + ctx->buf[ctx->buflen] = *data; + + if (ctx->buflen || nbits) { + M = GETU32(ctx->buf); + BitReconstruction4(X0, X1, X2, X3); + K1 = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + + for (i = 0; i < ctx->buflen * 8 + nbits; i++) { + if (M & 0x80000000) { + T ^= K0; + } + M <<= 1; + K0 = (K0 << 1) | (K1 >> 31); + K1 <<= 1; + } + } + + T ^= K0; + + BitReconstruction4(X0, X1, X2, X3); + K1 = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + T ^= K1; + + ctx->T = T; + PUTU32(mac, T); + + memset(ctx, 0, sizeof(*ctx)); +} + + +typedef uint8_t ZUC_UINT7; + +static const ZUC_UINT7 ZUC256_D[][16] = { + {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, +}; + +#define ZUC256_MAKEU31(a,b,c,d) \ + (((uint32_t)(a) << 23) | \ + ((uint32_t)(b) << 16) | \ + ((uint32_t)(c) << 8) | \ + (uint32_t)(d)) + + +static void zuc256_set_mac_key(ZUC_STATE *key, const uint8_t K[32], + const uint8_t IV[23], int macbits) +{ + ZUC_UINT31 *LFSR = key->LFSR; + uint32_t R1, R2; + uint32_t X0, X1, X2; + uint32_t W, W1, W2, U, V; + const ZUC_UINT7 *D; + int i; + + ZUC_UINT6 IV17 = IV[17] >> 2; + ZUC_UINT6 IV18 = ((IV[17] & 0x3) << 4) | (IV[18] >> 4); + ZUC_UINT6 IV19 = ((IV[18] & 0xf) << 2) | (IV[19] >> 6); + ZUC_UINT6 IV20 = IV[19] & 0x3f; + ZUC_UINT6 IV21 = IV[20] >> 2; + ZUC_UINT6 IV22 = ((IV[20] & 0x3) << 4) | (IV[21] >> 4); + ZUC_UINT6 IV23 = ((IV[21] & 0xf) << 2) | (IV[22] >> 6); + ZUC_UINT6 IV24 = IV[22] & 0x3f; + + D = macbits/32 < 3 ? ZUC256_D[macbits/32] : ZUC256_D[3]; + LFSR[0] = ZUC256_MAKEU31(K[0], D[0], K[21], K[16]); + LFSR[1] = ZUC256_MAKEU31(K[1], D[1], K[22], K[17]); + LFSR[2] = ZUC256_MAKEU31(K[2], D[2], K[23], K[18]); + LFSR[3] = ZUC256_MAKEU31(K[3], D[3], K[24], K[19]); + LFSR[4] = ZUC256_MAKEU31(K[4], D[4], K[25], K[20]); + LFSR[5] = ZUC256_MAKEU31(IV[0], (D[5] | IV17), K[5], K[26]); + LFSR[6] = ZUC256_MAKEU31(IV[1], (D[6] | IV18), K[6], K[27]); + LFSR[7] = ZUC256_MAKEU31(IV[10], (D[7] | IV19), K[7], IV[2]); + LFSR[8] = ZUC256_MAKEU31(K[8], (D[8] | IV20), IV[3], IV[11]); + LFSR[9] = ZUC256_MAKEU31(K[9], (D[9] | IV21), IV[12], IV[4]); + LFSR[10] = ZUC256_MAKEU31(IV[5], (D[10] | IV22), K[10], K[28]); + LFSR[11] = ZUC256_MAKEU31(K[11], (D[11] | IV23), IV[6], IV[13]); + LFSR[12] = ZUC256_MAKEU31(K[12], (D[12] | IV24), IV[7], IV[14]); + LFSR[13] = ZUC256_MAKEU31(K[13], D[13], IV[15], IV[8]); + LFSR[14] = ZUC256_MAKEU31(K[14], (D[14] | (K[31] >> 4)), IV[16], IV[9]); + LFSR[15] = ZUC256_MAKEU31(K[15], (D[15] | (K[31] & 0x0F)), K[30], K[29]); + + R1 = 0; + R2 = 0; + + for (i = 0; i < 32; i++) { + BitReconstruction3(X0, X1, X2); + W = F(X0, X1, X2); + LFSRWithInitialisationMode(W >> 1); + } + + BitReconstruction2(X1, X2); + F_(X1, X2); + LFSRWithWorkMode(); + + key->R1 = R1; + key->R2 = R2; +} + +void zuc256_init(ZUC_STATE *key, const uint8_t K[32], + const uint8_t IV[23]) +{ + zuc256_set_mac_key(key, K, IV, 0); +} + +void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[32], + const uint8_t iv[23], int macbits) +{ + if (macbits < 32) + macbits = 32; + else if (macbits > 64) + macbits = 128; + memset(ctx, 0, sizeof(*ctx)); + zuc256_set_mac_key((ZUC256_STATE *)ctx, key, iv, macbits); + zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->T); + zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->K0); + ctx->macbits = (macbits/32) * 32; +} + +void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len) +{ + ZUC_UINT32 K1, M; + size_t n = ctx->macbits / 32; + size_t i, j; + + if (!data || !len) { + return; + } + + if (ctx->buflen) { + size_t num = sizeof(ctx->buf) - ctx->buflen; + if (len < num) { + memcpy(ctx->buf + ctx->buflen, data, len); + ctx->buflen += len; + return; + } + + memcpy(ctx->buf + ctx->buflen, data, num); + M = GETU32(ctx->buf); + ctx->buflen = 0; + + K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); + + for (i = 0; i < 32; i++) { + if (M & 0x80000000) { + for (j = 0; j < n; j++) { + ctx->T[j] ^= ctx->K0[j]; + } + } + M <<= 1; + for (j = 0; j < n - 1; j++) { + ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); + } + ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); + K1 <<= 1; + } + + data += num; + len -= num; + } + + while (len >= 4) { + M = GETU32(data); + K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); + + for (i = 0; i < 32; i++) { + if (M & 0x80000000) { + for (j = 0; j < n; j++) { + ctx->T[j] ^= ctx->K0[j]; + } + } + M <<= 1; + for (j = 0; j < n - 1; j++) { + ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); + } + ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); + K1 <<= 1; + } + + data += 4; + len -= 4; + } + + if (len) { + memcpy(ctx->buf, data, len); + ctx->buflen = len; + } +} + +void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t *mac) +{ + ZUC_UINT32 K1, M; + size_t n = ctx->macbits/32; + size_t i, j; + + + if (!data) + nbits = 0; + + if (nbits >= 8) { + zuc256_mac_update(ctx, data, nbits/8); + data += nbits/8; + nbits %= 8; + } + + if (nbits) + ctx->buf[ctx->buflen] = *data; + + if (ctx->buflen || nbits) { + M = GETU32(ctx->buf); + K1 = zuc256_generate_keyword((ZUC256_STATE *)ctx); + + + for (i = 0; i < ctx->buflen * 8 + nbits; i++) { + if (M & 0x80000000) { + for (j = 0; j < n; j++) { + ctx->T[j] ^= ctx->K0[j]; + } + } + M <<= 1; + for (j = 0; j < n - 1; j++) { + ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31); + } + ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31); + K1 <<= 1; + } + } + + for (j = 0; j < n; j++) { + ctx->T[j] ^= ctx->K0[j]; + PUTU32(mac, ctx->T[j]); + mac += 4; + } + + memset(ctx, 0, sizeof(*ctx)); +} diff --git a/src/zuc_modes.c b/src/zuc_modes.c index 6055f5bc..bba7fc74 100644 --- a/src/zuc_modes.c +++ b/src/zuc_modes.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,136 +7,137 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -static void zuc_set_eea_key(ZUC_STATE *key, const uint8_t user_key[16], - ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_BIT direction) -{ - uint8_t iv[16] = {0}; - iv[0] = iv[8] = count >> 24; - iv[1] = iv[9] = count >> 16; - iv[2] = iv[10] = count >> 8; - iv[3] = iv[11] = count; - iv[4] = iv[12] = ((bearer << 1) | (direction & 1)) << 2; - zuc_init(key, user_key, iv); -} - -void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits, - const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, - ZUC_BIT direction) -{ - ZUC_STATE zuc_key; - size_t nwords = (nbits + 31)/32; - size_t i; - - zuc_set_eea_key(&zuc_key, key, count, bearer, direction); - zuc_generate_keystream(&zuc_key, nwords, out); - for (i = 0; i < nwords; i++) { - out[i] ^= in[i]; - } - - if (nbits % 32 != 0) { - out[nwords - 1] |= (0xffffffff << (32 - (nbits%32))); - } -} - -static void zuc_set_eia_iv(uint8_t iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer, - ZUC_BIT direction) -{ - memset(iv, 0, 16); - iv[0] = count >> 24; - iv[1] = iv[9] = count >> 16; - iv[2] = iv[10] = count >> 8; - iv[3] = iv[11] = count; - iv[4] = iv[12] = bearer << 3; - iv[8] = iv[0] ^ (direction << 7); - iv[14] = (direction << 7); -} - -ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits, - const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, - ZUC_BIT direction) -{ - ZUC_MAC_CTX ctx; - uint8_t iv[16]; - uint8_t mac[4]; - zuc_set_eia_iv(iv, count, bearer, direction); - zuc_mac_init(&ctx, key, iv); - zuc_mac_finish(&ctx, (uint8_t *)data, nbits, mac); - return GETU32(mac); -} - -#define ZUC_BLOCK_SIZE 4 - -int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]) -{ - if (!ctx || !key || !iv) { - error_print(); - return -1; - } - zuc_init(&ctx->zuc_state, key, iv); - memset(ctx->block, 0, ZUC_BLOCK_SIZE); - ctx->block_nbytes = 0; - return 1; -} - -int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - size_t left; - size_t nblocks; - size_t len; - - if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) { - error_print(); - return -1; - } - *outlen = 0; - if (ctx->block_nbytes) { - left = ZUC_BLOCK_SIZE - ctx->block_nbytes; - if (inlen < left) { - memcpy(ctx->block + ctx->block_nbytes, in, inlen); - ctx->block_nbytes += inlen; - return 1; - } - memcpy(ctx->block + ctx->block_nbytes, in, left); - zuc_encrypt(&ctx->zuc_state, ctx->block, ZUC_BLOCK_SIZE, out); - in += left; - inlen -= left; - out += ZUC_BLOCK_SIZE; - *outlen += ZUC_BLOCK_SIZE; - } - if (inlen >= ZUC_BLOCK_SIZE) { - nblocks = inlen / ZUC_BLOCK_SIZE; - len = nblocks * ZUC_BLOCK_SIZE; - zuc_encrypt(&ctx->zuc_state, in, len, out); - in += len; - inlen -= len; - out += len; - *outlen += len; - } - if (inlen) { - memcpy(ctx->block, in, inlen); - } - ctx->block_nbytes = inlen; - return 1; -} - -int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen) -{ - size_t left; - if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) { - error_print(); - return -1; - } - zuc_encrypt(&ctx->zuc_state, ctx->block, ctx->block_nbytes, out); - *outlen = ctx->block_nbytes; - return 1; -} + + + +#include +#include +#include +#include +#include +#include + + +static void zuc_set_eea_key(ZUC_STATE *key, const uint8_t user_key[16], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_BIT direction) +{ + uint8_t iv[16] = {0}; + iv[0] = iv[8] = count >> 24; + iv[1] = iv[9] = count >> 16; + iv[2] = iv[10] = count >> 8; + iv[3] = iv[11] = count; + iv[4] = iv[12] = ((bearer << 1) | (direction & 1)) << 2; + zuc_init(key, user_key, iv); +} + +void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits, + const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, + ZUC_BIT direction) +{ + ZUC_STATE zuc_key; + size_t nwords = (nbits + 31)/32; + size_t i; + + zuc_set_eea_key(&zuc_key, key, count, bearer, direction); + zuc_generate_keystream(&zuc_key, nwords, out); + for (i = 0; i < nwords; i++) { + out[i] ^= in[i]; + } + + if (nbits % 32 != 0) { + out[nwords - 1] |= (0xffffffff << (32 - (nbits%32))); + } +} + +static void zuc_set_eia_iv(uint8_t iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer, + ZUC_BIT direction) +{ + memset(iv, 0, 16); + iv[0] = count >> 24; + iv[1] = iv[9] = count >> 16; + iv[2] = iv[10] = count >> 8; + iv[3] = iv[11] = count; + iv[4] = iv[12] = bearer << 3; + iv[8] = iv[0] ^ (direction << 7); + iv[14] = (direction << 7); +} + +ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits, + const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer, + ZUC_BIT direction) +{ + ZUC_MAC_CTX ctx; + uint8_t iv[16]; + uint8_t mac[4]; + zuc_set_eia_iv(iv, count, bearer, direction); + zuc_mac_init(&ctx, key, iv); + zuc_mac_finish(&ctx, (uint8_t *)data, nbits, mac); + return GETU32(mac); +} + +#define ZUC_BLOCK_SIZE 4 + +int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE]) +{ + if (!ctx || !key || !iv) { + error_print(); + return -1; + } + zuc_init(&ctx->zuc_state, key, iv); + memset(ctx->block, 0, ZUC_BLOCK_SIZE); + ctx->block_nbytes = 0; + return 1; +} + +int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + size_t left; + size_t nblocks; + size_t len; + + if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) { + error_print(); + return -1; + } + *outlen = 0; + if (ctx->block_nbytes) { + left = ZUC_BLOCK_SIZE - ctx->block_nbytes; + if (inlen < left) { + memcpy(ctx->block + ctx->block_nbytes, in, inlen); + ctx->block_nbytes += inlen; + return 1; + } + memcpy(ctx->block + ctx->block_nbytes, in, left); + zuc_encrypt(&ctx->zuc_state, ctx->block, ZUC_BLOCK_SIZE, out); + in += left; + inlen -= left; + out += ZUC_BLOCK_SIZE; + *outlen += ZUC_BLOCK_SIZE; + } + if (inlen >= ZUC_BLOCK_SIZE) { + nblocks = inlen / ZUC_BLOCK_SIZE; + len = nblocks * ZUC_BLOCK_SIZE; + zuc_encrypt(&ctx->zuc_state, in, len, out); + in += len; + inlen -= len; + out += len; + *outlen += len; + } + if (inlen) { + memcpy(ctx->block, in, inlen); + } + ctx->block_nbytes = inlen; + return 1; +} + +int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen) +{ + size_t left; + if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) { + error_print(); + return -1; + } + zuc_encrypt(&ctx->zuc_state, ctx->block, ctx->block_nbytes, out); + *outlen = ctx->block_nbytes; + return 1; +} diff --git a/tests/aestest.c b/tests/aestest.c index f91175a9..79a103fb 100644 --- a/tests/aestest.c +++ b/tests/aestest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,370 +7,371 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -int test_aes(void) -{ - AES_KEY aes_key; - int i; - - /* test 1 */ - uint8_t key128[16] = { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }; - uint32_t rk128[4 * 11] = { - 0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c, - 0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605, - 0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f, - 0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b, - 0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00, - 0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc, - 0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd, - 0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f, - 0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f, - 0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e, - 0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6, - }; - - /* test 2 */ - uint8_t key192[24] = { - 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, - 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, - 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, - }; - uint32_t rk192[4 * 13] = { - 0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5, - 0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5, - 0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2, - 0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd, - 0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f, - 0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6, - 0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767, - 0xc0a69407, 0xd19da4e1, 0xec1786eb, 0x6fa64971, - 0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3, - 0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e, - 0xa7e1466c, 0x9411f1df, 0x821f750a, 0xad07d753, - 0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5, - 0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202, - }; - - /* test 3 */ - uint8_t key256[32] = { - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, - }; - uint32_t rk256[4 * 15] = { - 0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781, - 0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4, - 0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde, - 0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a, - 0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96, - 0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3, - 0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464, - 0x98c5bfc9, 0xbebd198e, 0x268c3ba7, 0x09e04214, - 0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80, - 0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239, - 0xde136967, 0x6ccc5a71, 0xfa256395, 0x9674ee15, - 0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3, - 0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a, - 0xcafaaae3, 0xe4d59b34, 0x9adf6ace, 0xbd10190d, - 0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e, - }; - - /* test 4 */ - unsigned char in1[16] = { - 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, - 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, - }; - unsigned char out1[16] = { - 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, - 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32, - }; - - unsigned char buf[16] = {0}; - - printf("aes test 1 "); - aes_set_encrypt_key(&aes_key, key128, sizeof(key128)); - if (memcmp(&aes_key, rk128, sizeof(rk128)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - printf("aes test 2 "); - aes_set_encrypt_key(&aes_key, key192, sizeof(key192)); - if (memcmp(&aes_key, rk192, sizeof(rk192)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - printf("aes test 3 "); - aes_set_encrypt_key(&aes_key, key256, sizeof(key256)); - if (memcmp(&aes_key, rk256, sizeof(rk256)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - printf("aes test 4 "); - aes_set_encrypt_key(&aes_key, key128, sizeof(key128)); - aes_encrypt(&aes_key, in1, buf); - if (memcmp(buf, out1, sizeof(out1)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - printf("aes test 5 "); - aes_set_decrypt_key(&aes_key, key128, sizeof(key128)); - aes_decrypt(&aes_key, buf, buf); - if (memcmp(buf, in1, sizeof(in1)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int test_aes_ctr(void) -{ - // NIST SP 800-38A F.5.1 - char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c"; - char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; - char *hex_msg = "6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"; - char *hex_out = "874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"; - - AES_KEY aes_key; - uint8_t key[32]; - uint8_t ctr[16]; - uint8_t msg[64]; - uint8_t out[64]; - uint8_t buf[64]; - size_t keylen, ctrlen, msglen, outlen, buflen; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - - aes_set_encrypt_key(&aes_key, key, keylen); - aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf); - buflen = msglen; - - printf("aes ctr test 1 "); - if (memcmp(buf, out, outlen) != 0) { - printf("failed\n"); - format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen); - format_bytes(stdout, 0, 0, " != ", out, outlen); - return -1; - } else { - printf("ok\n"); - } - - printf("aes ctr test 2 "); - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - aes_ctr_decrypt(&aes_key, ctr, buf, buflen, buf); - if (memcmp(buf, msg, msglen) != 0) { - printf("failed\n"); - format_bytes(stdout, 0, 0, "msg = ", msg, msglen); - format_bytes(stdout, 0, 0, " = ", buf, buflen); - return -1; - } else { - printf("ok\n"); - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - -struct { - char *K; - char *P; - char *A; - char *IV; - char *C; - char *T; -} aes_gcm_tests[] = { - // test 1 - { - "00000000000000000000000000000000", - "", - "", - "000000000000000000000000", - "", - "58e2fccefa7e3061367f1d57a4e7455a", - }, - // test 2 - { - "00000000000000000000000000000000", - "00000000000000000000000000000000", - "", - "000000000000000000000000", - "0388dace60b6a392f328c2b971b2fe78", - "ab6e47d42cec13bdf53a67b21257bddf", - }, - // test 3 - { - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - "86a7a9531534f7da2e4c303d8a318a72" - "1c3c0c95956809532fcf0e2449a6b525" - "b16aedf5aa0de657ba637b391aafd255", - "", - "cafebabefacedbaddecaf888", - "42831ec2217774244b7221b784d0d49c" - "e3aa212f2c02a4e035c17e2329aca12e" - "21d514b25466931c7d8f6a5aac84aa05" - "1ba30b396a0aac973d58e091473f5985", - "4d5c2af327cd64a62cf35abd2ba6fab4", - }, - // test 4 - { - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - "86a7a9531534f7da2e4c303d8a318a72" - "1c3c0c95956809532fcf0e2449a6b525" - "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "cafebabefacedbaddecaf888", - "42831ec2217774244b7221b784d0d49c" - "e3aa212f2c02a4e035c17e2329aca12e" - "21d514b25466931c7d8f6a5aac84aa05" - "1ba30b396a0aac973d58e091", - "5bc94fbc3221a5db94fae95ae7121a47", - }, - // test 5 - { - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - "86a7a9531534f7da2e4c303d8a318a72" - "1c3c0c95956809532fcf0e2449a6b525" - "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "cafebabefacedbad", - "61353b4c2806934a777ff51fa22a4755" - "699b2a714fcdc6f83766e5f97b6c7423" - "73806900e49f24b22b097544d4896b42" - "4989b5e1ebac0f07c23f4598", - "3612d2e79e3b0785561be14aaca2fccb", - }, - // test 6 - { - "feffe9928665731c6d6a8f9467308308", - "d9313225f88406e5a55909c5aff5269a" - "86a7a9531534f7da2e4c303d8a318a72" - "1c3c0c95956809532fcf0e2449a6b525" - "b16aedf5aa0de657ba637b39", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "9313225df88406e555909c5aff5269aa" - "6a7a9538534f7da1e4c303d2a318a728" - "c3c0c95156809539fcf0e2429a6b5254" - "16aedbf5a0de6a57a637b39b", - "8ce24998625615b603a033aca13fb894" - "be9112a5c3a211a8ba262a3cca7e2ca7" - "01e4a9a4fba43c90ccdcb281d48c7c6f" - "d62875d2aca417034c34aee5", - "619cc5aefffe0bfa462af43c1699d050", - }, - // test 7 - { - "00000000000000000000000000000000" - "0000000000000000", - "", - "", - "000000000000000000000000", - "", - "cd33b28ac773f74ba00ed1f312572435", - }, -}; - -int test_aes_gcm(void) -{ - int err = 0; - uint8_t K[32]; - uint8_t P[64]; - uint8_t A[32]; - uint8_t IV[64]; - uint8_t C[64]; - uint8_t T[16]; - size_t Klen, Plen, Alen, IVlen, Clen, Tlen; - - AES_KEY aes_key; - uint8_t out[64]; - uint8_t tag[16]; - uint8_t buf[64]; - int i; - - for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) { - hex_to_bytes(aes_gcm_tests[i].K, strlen(aes_gcm_tests[i].K), K, &Klen); - hex_to_bytes(aes_gcm_tests[i].P, strlen(aes_gcm_tests[i].P), P, &Plen); - hex_to_bytes(aes_gcm_tests[i].A, strlen(aes_gcm_tests[i].A), A, &Alen); - hex_to_bytes(aes_gcm_tests[i].IV, strlen(aes_gcm_tests[i].IV), IV, &IVlen); - hex_to_bytes(aes_gcm_tests[i].C, strlen(aes_gcm_tests[i].C), C, &Clen); - hex_to_bytes(aes_gcm_tests[i].T, strlen(aes_gcm_tests[i].T), T, &Tlen); - - aes_set_encrypt_key(&aes_key, K, Klen); - aes_gcm_encrypt(&aes_key, IV, IVlen, A, Alen, P, Plen, out, Tlen, tag); - - printf("aes gcm test %d ", i + 1); - if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1 - || memcmp(buf, P, Plen) != 0) { - printf("failed\n"); - format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K); - format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P); - format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A); - format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV); - format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C); - format_bytes(stdout, 0, 2, " = ", out, Plen); - format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T); - format_bytes(stdout, 0, 2, " = ", tag, Tlen); - return -1; - } else { - printf("ok\n"); - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_aes() != 1) goto err; - if (test_aes_ctr() != 1) goto err; - if (test_aes_gcm() != 1) goto err; - printf("%s all tests passed!\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + + +#include +#include +#include +#include +#include +#include + + +int test_aes(void) +{ + AES_KEY aes_key; + int i; + + /* test 1 */ + uint8_t key128[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }; + uint32_t rk128[4 * 11] = { + 0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c, + 0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605, + 0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f, + 0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b, + 0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00, + 0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc, + 0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd, + 0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f, + 0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f, + 0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e, + 0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6, + }; + + /* test 2 */ + uint8_t key192[24] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, + }; + uint32_t rk192[4 * 13] = { + 0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5, + 0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5, + 0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2, + 0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd, + 0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f, + 0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6, + 0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767, + 0xc0a69407, 0xd19da4e1, 0xec1786eb, 0x6fa64971, + 0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3, + 0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e, + 0xa7e1466c, 0x9411f1df, 0x821f750a, 0xad07d753, + 0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5, + 0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202, + }; + + /* test 3 */ + uint8_t key256[32] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, + }; + uint32_t rk256[4 * 15] = { + 0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781, + 0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4, + 0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde, + 0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a, + 0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96, + 0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3, + 0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464, + 0x98c5bfc9, 0xbebd198e, 0x268c3ba7, 0x09e04214, + 0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80, + 0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239, + 0xde136967, 0x6ccc5a71, 0xfa256395, 0x9674ee15, + 0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3, + 0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a, + 0xcafaaae3, 0xe4d59b34, 0x9adf6ace, 0xbd10190d, + 0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e, + }; + + /* test 4 */ + unsigned char in1[16] = { + 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, + }; + unsigned char out1[16] = { + 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32, + }; + + unsigned char buf[16] = {0}; + + printf("aes test 1 "); + aes_set_encrypt_key(&aes_key, key128, sizeof(key128)); + if (memcmp(&aes_key, rk128, sizeof(rk128)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + printf("aes test 2 "); + aes_set_encrypt_key(&aes_key, key192, sizeof(key192)); + if (memcmp(&aes_key, rk192, sizeof(rk192)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + printf("aes test 3 "); + aes_set_encrypt_key(&aes_key, key256, sizeof(key256)); + if (memcmp(&aes_key, rk256, sizeof(rk256)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + printf("aes test 4 "); + aes_set_encrypt_key(&aes_key, key128, sizeof(key128)); + aes_encrypt(&aes_key, in1, buf); + if (memcmp(buf, out1, sizeof(out1)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + printf("aes test 5 "); + aes_set_decrypt_key(&aes_key, key128, sizeof(key128)); + aes_decrypt(&aes_key, buf, buf); + if (memcmp(buf, in1, sizeof(in1)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_aes_ctr(void) +{ + // NIST SP 800-38A F.5.1 + char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c"; + char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + char *hex_msg = "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"; + char *hex_out = "874d6191b620e3261bef6864990db6ce" + "9806f66b7970fdff8617187bb9fffdff" + "5ae4df3edbd5d35e5b4f09020db03eab" + "1e031dda2fbe03d1792170a0f3009cee"; + + AES_KEY aes_key; + uint8_t key[32]; + uint8_t ctr[16]; + uint8_t msg[64]; + uint8_t out[64]; + uint8_t buf[64]; + size_t keylen, ctrlen, msglen, outlen, buflen; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + + aes_set_encrypt_key(&aes_key, key, keylen); + aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf); + buflen = msglen; + + printf("aes ctr test 1 "); + if (memcmp(buf, out, outlen) != 0) { + printf("failed\n"); + format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen); + format_bytes(stdout, 0, 0, " != ", out, outlen); + return -1; + } else { + printf("ok\n"); + } + + printf("aes ctr test 2 "); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + aes_ctr_decrypt(&aes_key, ctr, buf, buflen, buf); + if (memcmp(buf, msg, msglen) != 0) { + printf("failed\n"); + format_bytes(stdout, 0, 0, "msg = ", msg, msglen); + format_bytes(stdout, 0, 0, " = ", buf, buflen); + return -1; + } else { + printf("ok\n"); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + +struct { + char *K; + char *P; + char *A; + char *IV; + char *C; + char *T; +} aes_gcm_tests[] = { + // test 1 + { + "00000000000000000000000000000000", + "", + "", + "000000000000000000000000", + "", + "58e2fccefa7e3061367f1d57a4e7455a", + }, + // test 2 + { + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "", + "000000000000000000000000", + "0388dace60b6a392f328c2b971b2fe78", + "ab6e47d42cec13bdf53a67b21257bddf", + }, + // test 3 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255", + "", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091473f5985", + "4d5c2af327cd64a62cf35abd2ba6fab4", + }, + // test 4 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091", + "5bc94fbc3221a5db94fae95ae7121a47", + }, + // test 5 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "cafebabefacedbad", + "61353b4c2806934a777ff51fa22a4755" + "699b2a714fcdc6f83766e5f97b6c7423" + "73806900e49f24b22b097544d4896b42" + "4989b5e1ebac0f07c23f4598", + "3612d2e79e3b0785561be14aaca2fccb", + }, + // test 6 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "9313225df88406e555909c5aff5269aa" + "6a7a9538534f7da1e4c303d2a318a728" + "c3c0c95156809539fcf0e2429a6b5254" + "16aedbf5a0de6a57a637b39b", + "8ce24998625615b603a033aca13fb894" + "be9112a5c3a211a8ba262a3cca7e2ca7" + "01e4a9a4fba43c90ccdcb281d48c7c6f" + "d62875d2aca417034c34aee5", + "619cc5aefffe0bfa462af43c1699d050", + }, + // test 7 + { + "00000000000000000000000000000000" + "0000000000000000", + "", + "", + "000000000000000000000000", + "", + "cd33b28ac773f74ba00ed1f312572435", + }, +}; + +int test_aes_gcm(void) +{ + int err = 0; + uint8_t K[32]; + uint8_t P[64]; + uint8_t A[32]; + uint8_t IV[64]; + uint8_t C[64]; + uint8_t T[16]; + size_t Klen, Plen, Alen, IVlen, Clen, Tlen; + + AES_KEY aes_key; + uint8_t out[64]; + uint8_t tag[16]; + uint8_t buf[64]; + int i; + + for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) { + hex_to_bytes(aes_gcm_tests[i].K, strlen(aes_gcm_tests[i].K), K, &Klen); + hex_to_bytes(aes_gcm_tests[i].P, strlen(aes_gcm_tests[i].P), P, &Plen); + hex_to_bytes(aes_gcm_tests[i].A, strlen(aes_gcm_tests[i].A), A, &Alen); + hex_to_bytes(aes_gcm_tests[i].IV, strlen(aes_gcm_tests[i].IV), IV, &IVlen); + hex_to_bytes(aes_gcm_tests[i].C, strlen(aes_gcm_tests[i].C), C, &Clen); + hex_to_bytes(aes_gcm_tests[i].T, strlen(aes_gcm_tests[i].T), T, &Tlen); + + aes_set_encrypt_key(&aes_key, K, Klen); + aes_gcm_encrypt(&aes_key, IV, IVlen, A, Alen, P, Plen, out, Tlen, tag); + + printf("aes gcm test %d ", i + 1); + if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1 + || memcmp(buf, P, Plen) != 0) { + printf("failed\n"); + format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K); + format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P); + format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A); + format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV); + format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C); + format_bytes(stdout, 0, 2, " = ", out, Plen); + format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T); + format_bytes(stdout, 0, 2, " = ", tag, Tlen); + return -1; + } else { + printf("ok\n"); + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_aes() != 1) goto err; + if (test_aes_ctr() != 1) goto err; + if (test_aes_gcm() != 1) goto err; + printf("%s all tests passed!\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/asn1test.c b/tests/asn1test.c index 9975878b..7429129b 100644 --- a/tests/asn1test.c +++ b/tests/asn1test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,593 +7,594 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static void print_buf(const uint8_t *a, size_t len) -{ - size_t i; - for (i = 0; i < len; i++) { - printf("%02x ", a[i]); - } - printf("\n"); -} - -static void print_integer(const uint8_t *a, size_t alen) -{ - size_t i; - printf("integer = "); - for (i = 0; i < alen; i++) { - printf("%02x", a[i]); - } - printf("\n"); -} - -static void print_bits(const uint8_t *bits, size_t nbits) -{ - size_t i; - printf("bits (%zu) = ", nbits); - for (i = 0; i < (nbits + 7)/8; i++) { - printf("%02x", bits[i]); - } - printf("\n"); -} - -static void print_octets(const uint8_t *o, size_t olen) -{ - size_t i; - printf("octets (%zu) = ", olen); - for (i = 0; i < olen; i++) { - printf("%02x", o[i]); - } - printf("\n"); -} - -static int test_asn1_tag(void) -{ - int i; - format_print(stderr, 0, 0, "Tags:\n"); - for (i = 1; i <= 13; i++) { - format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); - } - for (i = 18; i <= 30; i++) { - format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_length(void) -{ - size_t tests[] = { - 0, - 5, - 127, - 128, - 256, - 344, - 65537, - 1<<23, - (size_t)1<<31, - }; - size_t length; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "Length:\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_length_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - int ret; - ret = asn1_length_from_der(&length, &cp, &len); - if (ret != 1 && ret != -2) { - error_print(); - return -1; - } - if (length != tests[i]) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%zd\n", length); - } - if (len != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_boolean(void) -{ - int tests[] = {0, 1}; - int val; - uint8_t buf[128] = {0}; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BOOLEAN)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_boolean_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_boolean_from_der(&val, &cp, &len) != 1 - || asn1_check(val == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", val ? "true" : "false"); - } - if (len != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_int(void) -{ - int tests[] = { - 0, - 1, - 127, - 128, - 65535, - 65537, - 1<<23, - 1<<30, - }; - int val; - uint8_t buf[256] = {0}; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - int rv; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_INTEGER)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_int_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - // 测试 -1 表示默认不编码 - if (asn1_int_to_der(-1, &p, &len) != 0) { - error_print(); - return -1; - } - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_int_from_der(&val, &cp, &len) != 1 - || asn1_check(val == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%d\n", val); - } - if (len != 0) { - error_print(); - return -1; - } - - // 测试返回0时是否对val值做初始化 - if (asn1_int_from_der(&val, &cp, &len) != 0) { - error_print(); - return -1; - } - if (val != -1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_bits(void) -{ - int tests[] = { - 0x01, - 0x02, - 0x03, - 0x7f, - 0xfe, - 0xff, - 0xffff, - 0xfffff, - }; - uint8_t der[] = { - 0x03,0x02,0x07,0x80, - 0x03,0x02,0x06,0x40, - 0x03,0x02,0x06,0xC0, - 0x03,0x02,0x01,0xFE, - 0x03,0x02,0x00,0x7F, - 0x03,0x02,0x00,0xFF, - 0x03,0x03,0x00,0xFF,0xFF, - 0x03,0x04,0x04,0xFF,0xFF,0xF0, - }; - int bits; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BIT_STRING)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_bits_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - if (sizeof(der) != len - || memcmp(der, buf, len) != 0) { - error_print(); - return -1; - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_bits_from_der(&bits, &cp, &len) != 1 - || asn1_check(bits == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%x\n", bits); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_null(void) -{ - uint8_t buf[256] = {0}; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "NULL\n"); - for (i = 0; i < 3; i++) { - if (asn1_null_to_der(&p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < 3; i++) { - if (asn1_null_from_der(&cp, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", asn1_tag_name(ASN1_TAG_NULL)); - } - if (asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_object_identifier(void) -{ - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_OBJECT_IDENTIFIER)); - - // test 1 - { - char *name = "sm2"; - uint32_t oid[] = { 1,2,156,10197,1,301 }; - uint8_t der[] = { 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D }; - uint32_t nodes[32]; - size_t nodes_cnt; - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - format_print(stderr, 0 ,4, "%s ", name); - if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 - || asn1_check(len == sizeof(der)) != 1 - || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 - || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { - fprintf(stderr, "failed\n"); - error_print(); - return -1; - } else { - printf("ok\n"); - } - } - - // test 2 - { - char *name = "x9.62-ecPublicKey"; - uint32_t oid[] = { 1,2,840,10045,2,1 }; - uint8_t der[] = { 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 }; - uint8_t buf[128]; - uint32_t nodes[32]; - size_t nodes_cnt; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - format_print(stderr, 0 ,4, "%s ", name); - if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 - || asn1_check(len == sizeof(der)) != 1 - || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 - || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1 - || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { - fprintf(stderr, "failed\n"); - error_print(); - return -1; - } else { - printf("ok\n"); - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_printable_string(void) -{ - char *tests[] = { - "hello", - "world", - "Just do it!", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_PrintableString)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_printable_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - const char *d; - size_t dlen; - if (asn1_printable_string_from_der(&d, &dlen, &cp, &len) != 1 - || strlen(tests[i]) != dlen - || memcmp(tests[i], d, dlen) != 0) { - error_print(); - return -1; - } - format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_utf8_string(void) -{ - char *tests[] = { - "hello", - "world", - "Just do it!", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTF8String)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_utf8_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - const char *d; - size_t dlen; - if (asn1_utf8_string_from_der(&d, &dlen, &cp, &len) != 1 - || strlen(tests[i]) != dlen - || memcmp(tests[i], d, dlen) != 0) { - error_print(); - return -1; - } - format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_ia5_string(void) -{ - char *tests[] = { - "hello", - "world", - "Just do it!", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_IA5String)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_ia5_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - const char *d; - size_t dlen; - if (asn1_ia5_string_from_der(&d, &dlen, &cp, &len) != 1 - || strlen(tests[i]) != dlen - || memcmp(tests[i], d, dlen) != 0) { - error_print(); - return -1; - } - format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_time(void) -{ - time_t tval = 0; - printf("%s", ctime(&tval)); - time(&tval); - printf("%s", ctime(&tval)); - - printf("%08x%08x\n", (uint32_t)(tval >> 32), (uint32_t)tval); - - return 1; -} - -static int test_asn1_utc_time(void) -{ - time_t tests[] = { - 0, - 0, - 1<<30, - }; - time_t tv; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - time(&tests[1]); - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTCTime)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_utc_time_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_utc_time_from_der(&tv, &cp, &len) != 1 - || asn1_check(tv == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s", ctime(&tv)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_asn1_generalized_time(void) -{ - time_t tests[] = { - 0, - 1<<30, - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - time(&tests[0]); - - format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_GeneralizedTime)); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (asn1_generalized_time_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - time_t tv; - if (asn1_generalized_time_from_der(&tv, &cp, &len) != 1 - || asn1_check(tv == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s", ctime(&tv)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_asn1_tag() != 1) goto err; - if (test_asn1_length() != 1) goto err; - if (test_asn1_boolean() != 1) goto err; - if (test_asn1_int() != 1) goto err; - if (test_asn1_bits() != 1) goto err; - if (test_asn1_null() != 1) goto err; - if (test_asn1_object_identifier() != 1) goto err; - if (test_asn1_printable_string() != 1) goto err; - if (test_asn1_utf8_string() != 1) goto err; - if (test_asn1_ia5_string() != 1) goto err; - if (test_asn1_utc_time() != 1) goto err; - if (test_asn1_generalized_time() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include + + +static void print_buf(const uint8_t *a, size_t len) +{ + size_t i; + for (i = 0; i < len; i++) { + printf("%02x ", a[i]); + } + printf("\n"); +} + +static void print_integer(const uint8_t *a, size_t alen) +{ + size_t i; + printf("integer = "); + for (i = 0; i < alen; i++) { + printf("%02x", a[i]); + } + printf("\n"); +} + +static void print_bits(const uint8_t *bits, size_t nbits) +{ + size_t i; + printf("bits (%zu) = ", nbits); + for (i = 0; i < (nbits + 7)/8; i++) { + printf("%02x", bits[i]); + } + printf("\n"); +} + +static void print_octets(const uint8_t *o, size_t olen) +{ + size_t i; + printf("octets (%zu) = ", olen); + for (i = 0; i < olen; i++) { + printf("%02x", o[i]); + } + printf("\n"); +} + +static int test_asn1_tag(void) +{ + int i; + format_print(stderr, 0, 0, "Tags:\n"); + for (i = 1; i <= 13; i++) { + format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); + } + for (i = 18; i <= 30; i++) { + format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i); + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_length(void) +{ + size_t tests[] = { + 0, + 5, + 127, + 128, + 256, + 344, + 65537, + 1<<23, + (size_t)1<<31, + }; + size_t length; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "Length:\n"); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_length_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + int ret; + ret = asn1_length_from_der(&length, &cp, &len); + if (ret != 1 && ret != -2) { + error_print(); + return -1; + } + if (length != tests[i]) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%zd\n", length); + } + if (len != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_boolean(void) +{ + int tests[] = {0, 1}; + int val; + uint8_t buf[128] = {0}; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BOOLEAN)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_boolean_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_boolean_from_der(&val, &cp, &len) != 1 + || asn1_check(val == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", val ? "true" : "false"); + } + if (len != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_int(void) +{ + int tests[] = { + 0, + 1, + 127, + 128, + 65535, + 65537, + 1<<23, + 1<<30, + }; + int val; + uint8_t buf[256] = {0}; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + int rv; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_INTEGER)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_int_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + // 测试 -1 表示默认不编码 + if (asn1_int_to_der(-1, &p, &len) != 0) { + error_print(); + return -1; + } + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_int_from_der(&val, &cp, &len) != 1 + || asn1_check(val == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%d\n", val); + } + if (len != 0) { + error_print(); + return -1; + } + + // 测试返回0时是否对val值做初始化 + if (asn1_int_from_der(&val, &cp, &len) != 0) { + error_print(); + return -1; + } + if (val != -1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_bits(void) +{ + int tests[] = { + 0x01, + 0x02, + 0x03, + 0x7f, + 0xfe, + 0xff, + 0xffff, + 0xfffff, + }; + uint8_t der[] = { + 0x03,0x02,0x07,0x80, + 0x03,0x02,0x06,0x40, + 0x03,0x02,0x06,0xC0, + 0x03,0x02,0x01,0xFE, + 0x03,0x02,0x00,0x7F, + 0x03,0x02,0x00,0xFF, + 0x03,0x03,0x00,0xFF,0xFF, + 0x03,0x04,0x04,0xFF,0xFF,0xF0, + }; + int bits; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BIT_STRING)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_bits_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + if (sizeof(der) != len + || memcmp(der, buf, len) != 0) { + error_print(); + return -1; + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_bits_from_der(&bits, &cp, &len) != 1 + || asn1_check(bits == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%x\n", bits); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_null(void) +{ + uint8_t buf[256] = {0}; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "NULL\n"); + for (i = 0; i < 3; i++) { + if (asn1_null_to_der(&p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < 3; i++) { + if (asn1_null_from_der(&cp, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", asn1_tag_name(ASN1_TAG_NULL)); + } + if (asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_object_identifier(void) +{ + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_OBJECT_IDENTIFIER)); + + // test 1 + { + char *name = "sm2"; + uint32_t oid[] = { 1,2,156,10197,1,301 }; + uint8_t der[] = { 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D }; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0 ,4, "%s ", name); + if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 + || asn1_check(len == sizeof(der)) != 1 + || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 + || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { + fprintf(stderr, "failed\n"); + error_print(); + return -1; + } else { + printf("ok\n"); + } + } + + // test 2 + { + char *name = "x9.62-ecPublicKey"; + uint32_t oid[] = { 1,2,840,10045,2,1 }; + uint8_t der[] = { 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 }; + uint8_t buf[128]; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0 ,4, "%s ", name); + if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1 + || asn1_check(len == sizeof(der)) != 1 + || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1 + || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) { + fprintf(stderr, "failed\n"); + error_print(); + return -1; + } else { + printf("ok\n"); + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_printable_string(void) +{ + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_PrintableString)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_printable_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_printable_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return -1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_utf8_string(void) +{ + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTF8String)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_utf8_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_utf8_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return -1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_ia5_string(void) +{ + char *tests[] = { + "hello", + "world", + "Just do it!", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_IA5String)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_ia5_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + const char *d; + size_t dlen; + if (asn1_ia5_string_from_der(&d, &dlen, &cp, &len) != 1 + || strlen(tests[i]) != dlen + || memcmp(tests[i], d, dlen) != 0) { + error_print(); + return -1; + } + format_string(stderr, 0, 4, "", (uint8_t *)d, dlen); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_time(void) +{ + time_t tval = 0; + printf("%s", ctime(&tval)); + time(&tval); + printf("%s", ctime(&tval)); + + printf("%08x%08x\n", (uint32_t)(tval >> 32), (uint32_t)tval); + + return 1; +} + +static int test_asn1_utc_time(void) +{ + time_t tests[] = { + 0, + 0, + 1<<30, + }; + time_t tv; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + time(&tests[1]); + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTCTime)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_utc_time_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_utc_time_from_der(&tv, &cp, &len) != 1 + || asn1_check(tv == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s", ctime(&tv)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_asn1_generalized_time(void) +{ + time_t tests[] = { + 0, + 1<<30, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + time(&tests[0]); + + format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_GeneralizedTime)); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (asn1_generalized_time_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + time_t tv; + if (asn1_generalized_time_from_der(&tv, &cp, &len) != 1 + || asn1_check(tv == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s", ctime(&tv)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_asn1_tag() != 1) goto err; + if (test_asn1_length() != 1) goto err; + if (test_asn1_boolean() != 1) goto err; + if (test_asn1_int() != 1) goto err; + if (test_asn1_bits() != 1) goto err; + if (test_asn1_null() != 1) goto err; + if (test_asn1_object_identifier() != 1) goto err; + if (test_asn1_printable_string() != 1) goto err; + if (test_asn1_utf8_string() != 1) goto err; + if (test_asn1_ia5_string() != 1) goto err; + if (test_asn1_utc_time() != 1) goto err; + if (test_asn1_generalized_time() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/base64test.c b/tests/base64test.c index 768e390c..b9b66a61 100644 --- a/tests/base64test.c +++ b/tests/base64test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,66 +7,67 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include - - -static int test_base64(void) -{ - uint8_t bin1[50]; - uint8_t bin2[100]; - uint8_t bin3[200]; - uint8_t buf1[8000] = {0}; - uint8_t buf2[8000] = {0}; - - BASE64_CTX ctx; - uint8_t *p; - int len; - - memset(bin1, 0x01, sizeof(bin1)); - memset(bin2, 0xA5, sizeof(bin2)); - memset(bin3, 0xff, sizeof(bin3)); - - - p = buf1; - base64_encode_init(&ctx); - base64_encode_update(&ctx, bin1, sizeof(bin1), p, &len); p += len; - base64_encode_update(&ctx, bin2, sizeof(bin2), p, &len); p += len; - base64_encode_update(&ctx, bin3, sizeof(bin3), p, &len); p += len; - base64_encode_finish(&ctx, p, &len); p += len; - len = (int)(p - buf1); - - p = buf2; - base64_decode_init(&ctx); - base64_decode_update(&ctx, buf1, len, p, &len); p += len; - base64_decode_finish(&ctx, p, &len); p += len; - len = (int)(p - buf2); - - printf("base64 test "); - if (len != sizeof(bin1) + sizeof(bin2) + sizeof(bin3) - || memcmp(buf2, bin1, sizeof(bin1)) != 0 - || memcmp(buf2 + sizeof(bin1), bin2, sizeof(bin2)) != 0 - || memcmp(buf2 + sizeof(bin1) + sizeof(bin2), bin3, sizeof(bin3)) != 0) { - printf("failed\n"); - return -1; - } else { - printf("ok\n"); - } - - return 1; -} - -int main(void) -{ - if (test_base64() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + + +#include +#include +#include +#include +#include + + +static int test_base64(void) +{ + uint8_t bin1[50]; + uint8_t bin2[100]; + uint8_t bin3[200]; + uint8_t buf1[8000] = {0}; + uint8_t buf2[8000] = {0}; + + BASE64_CTX ctx; + uint8_t *p; + int len; + + memset(bin1, 0x01, sizeof(bin1)); + memset(bin2, 0xA5, sizeof(bin2)); + memset(bin3, 0xff, sizeof(bin3)); + + + p = buf1; + base64_encode_init(&ctx); + base64_encode_update(&ctx, bin1, sizeof(bin1), p, &len); p += len; + base64_encode_update(&ctx, bin2, sizeof(bin2), p, &len); p += len; + base64_encode_update(&ctx, bin3, sizeof(bin3), p, &len); p += len; + base64_encode_finish(&ctx, p, &len); p += len; + len = (int)(p - buf1); + + p = buf2; + base64_decode_init(&ctx); + base64_decode_update(&ctx, buf1, len, p, &len); p += len; + base64_decode_finish(&ctx, p, &len); p += len; + len = (int)(p - buf2); + + printf("base64 test "); + if (len != sizeof(bin1) + sizeof(bin2) + sizeof(bin3) + || memcmp(buf2, bin1, sizeof(bin1)) != 0 + || memcmp(buf2 + sizeof(bin1), bin2, sizeof(bin2)) != 0 + || memcmp(buf2 + sizeof(bin1) + sizeof(bin2), bin3, sizeof(bin3)) != 0) { + printf("failed\n"); + return -1; + } else { + printf("ok\n"); + } + + return 1; +} + +int main(void) +{ + if (test_base64() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/block_ciphertest.c b/tests/block_ciphertest.c index 9547eba1..86278da8 100644 --- a/tests/block_ciphertest.c +++ b/tests/block_ciphertest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,13 +7,14 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -int main(void) -{ - return 0; -} + + +#include +#include +#include +#include + +int main(void) +{ + return 0; +} diff --git a/tests/chacha20test.c b/tests/chacha20test.c index 862af062..2eb954b6 100644 --- a/tests/chacha20test.c +++ b/tests/chacha20test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,53 +7,54 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include - - -int main(void) -{ - int err = 0; - int i; - const unsigned char key[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - }; - const unsigned char nonce[] = { - 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, - 0x00, 0x00, 0x00, 0x00, - }; - uint32_t counter = 1; - const unsigned char testdata[] = { - 0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15, - 0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20, 0x71, 0xc4, - 0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03, - 0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e, - 0xd2, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09, - 0x14, 0xc2, 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2, - 0xb5, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9, - 0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e, - }; - unsigned char buf[64]; - - CHACHA20_STATE state; - chacha20_init(&state, key, nonce, counter); - chacha20_generate_keystream(&state, 1, buf); - - printf("chacha20 test "); - if (memcmp(buf, testdata, sizeof(testdata)) != 0) { - printf("failed\n"); - err++; - } else { - printf("ok\n"); - } - - return err; -} - + + + +#include +#include +#include +#include + + +int main(void) +{ + int err = 0; + int i; + const unsigned char key[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }; + const unsigned char nonce[] = { + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x00, + }; + uint32_t counter = 1; + const unsigned char testdata[] = { + 0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15, + 0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20, 0x71, 0xc4, + 0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03, + 0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e, + 0xd2, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09, + 0x14, 0xc2, 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2, + 0xb5, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9, + 0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e, + }; + unsigned char buf[64]; + + CHACHA20_STATE state; + chacha20_init(&state, key, nonce, counter); + chacha20_generate_keystream(&state, 1, buf); + + printf("chacha20 test "); + if (memcmp(buf, testdata, sizeof(testdata)) != 0) { + printf("failed\n"); + err++; + } else { + printf("ok\n"); + } + + return err; +} + diff --git a/tests/cmstest.c b/tests/cmstest.c index 00d5a43e..c21e0833 100644 --- a/tests/cmstest.c +++ b/tests/cmstest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,1037 +7,1038 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_cms_content_type(void) -{ - int tests[] = { - OID_cms_data, - OID_cms_signed_data, - OID_cms_enveloped_data, - OID_cms_signed_and_enveloped_data, - OID_cms_encrypted_data, - OID_cms_key_agreement_info, - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (cms_content_type_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - int oid; - if (cms_content_type_from_der(&oid, &cp, &len) != 1 - || asn1_check(oid == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", cms_content_type_name(oid)); - } - (void)asn1_length_is_zero(len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_content_info(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - uint8_t data[20] = { 0x01,0x02 }; - int oid; - const uint8_t *d; - size_t dlen; - - if (cms_content_info_to_der(OID_cms_data, data, sizeof(data), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_content_info_print(stderr, 0, 0, "ContentInfo", d, dlen); - - p = buf; - cp = buf; - len = 0; - -// 当类型为OID_cms_data, 数据是OCTET STRING,需要再解析一次 - - if (cms_content_info_to_der(OID_cms_data, data, sizeof(data), &p, &len) != 1 - || cms_content_info_from_der(&oid, &d, &dlen, &cp, &len) != 1 - || asn1_check(oid == OID_cms_data) != 1 -// || asn1_check(dlen == sizeof(data)) != 1 -// || asn1_check(memcmp(data, d, dlen) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_enced_content_info(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - uint8_t iv[16] = {0}; - uint8_t enced[32] = { 0x01,0x02 }; - const uint8_t *d; - size_t dlen; - - int oid; - int cipher; - const uint8_t *piv; - size_t ivlen; - const uint8_t *shared_info1; - size_t shared_info1_len; - const uint8_t *shared_info2; - size_t shared_info2_len; - - if (cms_enced_content_info_to_der(OID_cms_data, - OID_sm4_cbc, iv, sizeof(iv), enced, sizeof(enced), - NULL, 0, NULL, 0, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_enced_content_info_print(stderr, 0, 0, "EncryptedContentInfo", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (cms_enced_content_info_to_der(OID_cms_data, - OID_sm4_cbc, iv, sizeof(iv), enced, sizeof(enced), - NULL, 0, NULL, 0, &p, &len) != 1 - || cms_enced_content_info_from_der(&oid, - &cipher, &piv, &ivlen, &d, &dlen, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len, &cp, &len) != 1 - || asn1_check(oid == OID_cms_data) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == sizeof(iv)) != 1 - || asn1_check(dlen == sizeof(enced)) != 1 - || asn1_check(shared_info1 == NULL) != 1 - || asn1_check(shared_info1_len == 0) != 1 - || asn1_check(shared_info2 == NULL) != 1 - || asn1_check(shared_info2_len == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_enced_content_info_encrypt(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - uint8_t key[16] = {0}; - uint8_t iv[16] = {1}; - uint8_t data[20] = {2}; - - const uint8_t *d; - size_t dlen; - - int oid; - int cipher; - const uint8_t *piv; - size_t ivlen; - uint8_t data2[256]; - const uint8_t *shared_info1; - size_t shared_info1_len; - const uint8_t *shared_info2; - size_t shared_info2_len; - - if (cms_enced_content_info_encrypt_to_der( - OID_sm4_cbc, - key, sizeof(key), - iv, sizeof(iv), - OID_cms_data, data, sizeof(data), - NULL, 0, - NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_enced_content_info_print(stderr, 0, 0, "EncryptedContentInfo", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (cms_enced_content_info_encrypt_to_der( - OID_sm4_cbc, - key, sizeof(key), - iv, sizeof(iv), - OID_cms_data, data, sizeof(data), - NULL, 0, - NULL, 0, - &p, &len) != 1 - // 显然这个解密函数是有问题的,在from_der的时候不知道密文的长度,因此无法知道需要的输出缓冲长度 - || cms_enced_content_info_decrypt_from_der( - &cipher, - key, sizeof(key), - &oid, data2, &dlen, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len, - &cp, &len) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(oid = OID_cms_data) != 1 - || asn1_check(dlen == sizeof(data)) != 1 - || asn1_check(memcmp(data, data2, dlen) == 0) != 1 - || asn1_check(shared_info1 == NULL) != 1 - || asn1_check(shared_info2 == NULL) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_issuer_and_serial_number(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - uint8_t issuer[256]; - size_t issuer_len; - uint8_t serial[20] = {1}; - - const uint8_t *d; - size_t dlen; - const uint8_t *pissuer; - const uint8_t *pserial; - size_t serial_len; - - if (x509_name_set(issuer, &issuer_len, sizeof(issuer), - "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 - || cms_issuer_and_serial_number_to_der( - issuer, issuer_len, serial, sizeof(serial), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_issuer_and_serial_number_print(stderr, 0, 0, "IssuerAndSerialNumber", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_name_set(issuer, &issuer_len, sizeof(issuer), - "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 - || cms_issuer_and_serial_number_to_der( - issuer, issuer_len, serial, sizeof(serial), &p, &len) != 1 - || cms_issuer_and_serial_number_from_der( - &pissuer, &issuer_len, &pserial, &serial_len, &cp, &len) != 1 - || asn1_check(memcmp(pissuer, issuer, issuer_len) == 0) != 1 - || asn1_check(serial_len == sizeof(serial)) != 1 - || asn1_check(memcmp(serial, pserial, serial_len) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_signer_info(void) -{ - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t issuer_buf[256]; - size_t issuer_len; - uint8_t serial_buf[20]; - uint8_t sig_buf[256]; - size_t siglen = sizeof(sig_buf); - - int version; - const uint8_t *issuer; - const uint8_t *serial; - size_t serial_len; - int digest_alg; - const uint8_t *auth_attrs; - size_t auth_attrs_len; - int sig_alg; - const uint8_t *sig; - const uint8_t *unauth_attrs; - size_t unauth_attrs_len; - - - if (x509_name_set(issuer_buf, &issuer_len, sizeof(issuer_buf), - "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1) { - error_print(); - return -1; - } - - if (cms_signer_info_to_der( - CMS_version_v1, - issuer_buf, issuer_len, - serial_buf, sizeof(serial_buf), - OID_sm3, - NULL, 0, - OID_sm2sign_with_sm3, - sig_buf, siglen, - NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_signer_info_print(stderr, 0, 0, "SignerInfo", d, dlen); - - cp = p = buf; len = 0; - if (cms_signer_info_to_der( - CMS_version_v1, - issuer_buf, issuer_len, - serial_buf, sizeof(serial_buf), - OID_sm3, - NULL, 0, - OID_sm2sign_with_sm3, - sig_buf, siglen, - NULL, 0, - &p, &len) != 1 - || cms_signer_info_from_der( - &version, - &issuer, &issuer_len, - &serial, &serial_len, - &digest_alg, - &auth_attrs, &auth_attrs_len, - &sig_alg, - &sig, &siglen, - &unauth_attrs, &unauth_attrs_len, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_signer_info_sign(void) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - SM2_KEY sm2_key; - uint8_t serial_buf[20]; - uint8_t name[256]; - size_t namelen; - time_t not_before, not_after; - uint8_t certs[1024]; - size_t certslen; - - SM3_CTX sm3_ctx; - - const uint8_t *cert; - size_t certlen; - const uint8_t *serial; - const uint8_t *issuer; - const uint8_t *auth_attrs; - const uint8_t *unauth_attrs; - size_t serial_len, issuer_len, auth_attrs_len, unauth_attrs_len; - - if (sm2_key_generate(&sm2_key) != 1 - || rand_bytes(serial_buf, sizeof(serial_buf)) != 1 - || x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 - || time(¬_before) == -1 - || x509_validity_add_days(¬_after, not_before, 365) != 1 - || x509_cert_sign(certs, &certslen, sizeof(certs), - X509_version_v3, serial_buf, sizeof(serial_buf), - OID_sm2sign_with_sm3, - name, namelen, - not_before, not_after, - name, namelen, - &sm2_key, NULL, 0, NULL, 0, NULL, 0, - &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, (uint8_t *)"hello", 5); - - cp = p = buf; len = 0; - if (cms_signer_info_sign_to_der( - &sm3_ctx, &sm2_key, - name, namelen, serial_buf, sizeof(serial_buf), - NULL, 0, NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_signer_info_print(stderr, 0, 0, "SignerInfo", d, dlen); - - cp = p = buf; len = 0; - if (cms_signer_info_sign_to_der( - &sm3_ctx, &sm2_key, - name, namelen, serial_buf, sizeof(serial_buf), - NULL, 0, NULL, 0, - &p, &len) != 1 - || cms_signer_info_verify_from_der( - &sm3_ctx, certs, certslen, - &cert, &certlen, - &issuer, &issuer_len, - &serial, &serial_len, - &auth_attrs, &auth_attrs_len, - &unauth_attrs, &unauth_attrs_len, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_signer_infos(void) -{ - uint8_t buf[1280]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t signer_infos[1024]; - size_t signer_infos_len = 0; - - SM3_CTX sm3_ctx; - SM2_KEY sm2_key; - - uint8_t issuer_buf[256]; - size_t issuer_len; - uint8_t serial_buf[20]; - - sm2_key_generate(&sm2_key); - sm3_init(&sm3_ctx); - sm3_update(&sm3_ctx, (uint8_t *)"hello", 5); - x509_name_set(issuer_buf, &issuer_len, sizeof(issuer_buf), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); - - - if (cms_signer_infos_add_signer_info( - signer_infos, &signer_infos_len, sizeof(signer_infos), - &sm3_ctx, &sm2_key, - issuer_buf, issuer_len, - serial_buf, sizeof(serial_buf), - NULL, 0, - NULL, 0) != 1 - || cms_signer_infos_add_signer_info( - signer_infos, &signer_infos_len, sizeof(signer_infos), - &sm3_ctx, &sm2_key, - issuer_buf, issuer_len, - serial_buf, sizeof(serial_buf), - NULL, 0, - NULL, 0) != 1 - || cms_signer_infos_add_signer_info( - signer_infos, &signer_infos_len, sizeof(signer_infos), - &sm3_ctx, &sm2_key, - issuer_buf, issuer_len, - serial_buf, sizeof(serial_buf), - NULL, 0, - NULL, 0) != 1 - || cms_signer_infos_to_der(signer_infos, signer_infos_len, &p, &len) != 1 - || cms_signer_infos_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1){ - error_print(); - return -1; - } - cms_signer_infos_print(stderr, 0, 0, "SET OF SignerInfo", d, dlen); - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_digest_algors(void) -{ - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int oids[] = { - OID_sm3, - OID_md5, - OID_sha1, - OID_sha256, - OID_sha512, - }; - - int algs[16]; - size_t algs_cnt; - - if (cms_digest_algors_to_der(oids, sizeof(oids)/sizeof(oids[0]), &p, &len) != 1 - || asn1_set_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_digest_algors_print(stderr, 0, 0, "digestAlgorithms", d, dlen); - - if (cms_digest_algors_to_der(oids, sizeof(oids)/sizeof(oids[0]), &p, &len) != 1 - || cms_digest_algors_from_der(algs, &algs_cnt, sizeof(algs)/sizeof(algs[0]), &cp, &len) != 1 - || asn1_check(algs_cnt == sizeof(oids)/sizeof(oids[0])) != 1 - || asn1_check(memcmp(algs, oids, sizeof(oids)) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_signed_data(void) -{ - SM2_KEY sm2_key; - uint8_t cert[4096]; - size_t certlen = 0; - CMS_CERTS_AND_KEY signers[1]; - uint8_t data[48] = {0}; - uint8_t buf[4096]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - sm2_key_generate(&sm2_key); - - { - uint8_t serial[20]; - size_t serial_len = sizeof(serial); - uint8_t name[256]; - size_t namelen = 0; - time_t not_before, not_after; - uint8_t subject[256]; - size_t subject_len = 0; - uint8_t *p = cert; - const uint8_t *cp = cert; - - rand_bytes(serial, sizeof(serial)); - x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); - time(¬_before); - x509_validity_add_days(¬_after, not_before, 365); - - if (x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - name, namelen, - not_before, not_after, - name, namelen, - &sm2_key, - NULL, 0, - NULL, 0, - NULL, 0, - &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - } - - signers[0].certs = cert; - signers[0].certs_len = certlen; - signers[0].sign_key = &sm2_key; - - if (cms_signed_data_sign_to_der( - signers, sizeof(signers)/sizeof(signers[0]), - OID_cms_data, data, sizeof(data), - NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_signed_data_print(stderr, 0, 0, "SignedData", d, dlen); - - cp = p = buf; len = 0; - { - int content_type; - const uint8_t *content; - size_t content_len; - const uint8_t *certs; - size_t certslen; - const uint8_t *crls; - size_t crlslen; - const uint8_t *signer_infos; - size_t signer_infos_len; - - if (cms_signed_data_sign_to_der( - signers, sizeof(signers)/sizeof(signers[0]), - OID_cms_data, data, sizeof(data), - NULL, 0, - &p, &len) != 1 - || cms_signed_data_verify_from_der( - NULL, 0, - NULL, 0, - &content_type, &content, &content_len, - &certs, &certslen, - &crls, &crlslen, - &signer_infos, &signer_infos_len, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_recipient_info(void) -{ - SM2_KEY sm2_key; - uint8_t name[256]; - size_t namelen; - uint8_t serial_buf[20]; - uint8_t in[16]; - - uint8_t buf[1024]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int version; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *serial; - size_t serial_len; - int pke_algor; - const uint8_t *params; - size_t params_len; - const uint8_t *enced_key; - size_t enced_key_len; - - uint8_t out[sizeof(in)]; - size_t outlen; - - sm2_key_generate(&sm2_key); - x509_name_set(name, &namelen, sizeof(name), "US", "CA", NULL, "BB", "AA", "CC"); - rand_bytes(serial_buf, sizeof(serial_buf)); - rand_bytes(in, sizeof(in)); - - if (cms_recipient_info_encrypt_to_der(&sm2_key, - name, namelen, - serial_buf, sizeof(serial_buf), - in, sizeof(in), - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_recipient_info_print(stderr, 0, 0, "RecipientInfo", d, dlen); - - - cp = p = buf; len = 0; - if (cms_recipient_info_encrypt_to_der(&sm2_key, - name, namelen, - serial_buf, sizeof(serial_buf), - in, sizeof(in), - &p, &len) != 1 - || cms_recipient_info_from_der( - &version, - &issuer, &issuer_len, - &serial, &serial_len, - &pke_algor, ¶ms, ¶ms_len, - &enced_key, &enced_key_len, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - - cp = p = buf; len = 0; - if (cms_recipient_info_encrypt_to_der( - &sm2_key, - name, namelen, - serial_buf, sizeof(serial_buf), - in, sizeof(in), - &p, &len) != 1 - || cms_recipient_info_decrypt_from_der( - &sm2_key, - name, namelen, - serial_buf, sizeof(serial_buf), - out, &outlen, sizeof(out), - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (sizeof(in) != outlen - || memcmp(in, out, outlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int test_cms_enveloped_data(void) -{ - SM2_KEY sm2_key1; - uint8_t name1[256]; - size_t name1_len; - uint8_t serial1[20]; - size_t serial1_len; - - SM2_KEY sm2_key2; - uint8_t name2[256]; - size_t name2_len; - uint8_t serial2[20]; - size_t serial2_len; - - time_t not_before, not_after; - - uint8_t certs[2048]; - size_t certslen; - - uint8_t key[16]; - uint8_t iv[16]; - - uint8_t in[80]; - uint8_t out[256]; - size_t outlen; - size_t maxlen; - - uint8_t buf[4096]; - uint8_t *p; - const uint8_t *cp; - size_t len; - const uint8_t *d; - size_t dlen; - - // prepare keys and certs - - if (time(¬_before) == -1 - || x509_validity_add_days(¬_after, not_before, 365) != 1) { - error_print(); - return -1; - } - - p = certs; - certslen = 0; - maxlen = sizeof(certs); - - if (sm2_key_generate(&sm2_key1) != 1 - || rand_bytes(serial1, sizeof(serial1)) != 1 - || x509_name_set(name1, &name1_len, sizeof(name1), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 - || x509_cert_sign( - p, &len, maxlen, - X509_version_v3, - serial1, sizeof(serial1), - OID_sm2sign_with_sm3, - name1, name1_len, - not_before, not_after, - name1, name1_len, - &sm2_key1, NULL, 0, NULL, 0, NULL, 0, - &sm2_key1, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - p += len; - certslen += len; - maxlen -= len; - - if (sm2_key_generate(&sm2_key2) != 1 - || rand_bytes(serial2, sizeof(serial2)) != 1 - || x509_name_set(name2, &name2_len, sizeof(name2), "CN", "Beijing", "Haidian", "PKU", "CS", "Bob") != 1 - || x509_cert_sign( - p, &len, maxlen, - X509_version_v3, - serial2, sizeof(serial2), - OID_sm2sign_with_sm3, - name2, name2_len, - not_before, not_after, - name2, name2_len, - &sm2_key2, NULL, 0, NULL, 0, NULL, 0, - &sm2_key2, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - p += len; - certslen += len; - maxlen -= len; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - rand_bytes(in, sizeof(in)); - - // test - - cp = p = buf; len = 0; - if (cms_enveloped_data_encrypt_to_der( - certs, certslen, - OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), - OID_cms_data, in, sizeof(in), - NULL, 0, NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_enveloped_data_print(stderr, 0, 0, "EnvelopedData", d, dlen); - - - int content_type; - - - cp = p = buf; len = 0; - if (cms_enveloped_data_encrypt_to_der( - certs, certslen, - OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), - OID_cms_data, in, sizeof(in), - NULL, 0, NULL, 0, - &p, &len) != 1) { - error_print(); - return -1; - } - - const uint8_t *rcpt_infos; - const uint8_t *shared_info1; - const uint8_t *shared_info2; - size_t rcpt_infos_len, shared_info1_len, shared_info2_len; - - if (cms_enveloped_data_decrypt_from_der( - &sm2_key1, - name1, name1_len, - serial1, sizeof(serial1), - &content_type, out, &outlen, - &rcpt_infos, &rcpt_infos_len, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len, - &cp, &len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_signed_and_enveloped_data(void) -{ -/* -444 int cms_signed_and_enveloped_data_encipher_to_der( -445 const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, -446 const uint8_t *rcpt_certs, size_t rcpt_certs_len, -447 int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, -448 int content_type, const uint8_t *content, size_t content_len, -449 const uint8_t *signers_crls, size_t signers_crls_len, -450 const uint8_t *shared_info1, size_t shared_info1_len, -451 const uint8_t *shared_info2, size_t shared_info2_len, -452 uint8_t **out, size_t *outlen); -453 int cms_signed_and_enveloped_data_decipher_from_der( -454 const SM2_KEY *rcpt_key, -455 const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, -456 const uint8_t *rcpt_serial, size_t rcpt_serial_len, -457 int *content_type, uint8_t *content, size_t *content_len, -458 const uint8_t **prcpt_infos, size_t *prcpt_infos_len, -459 const uint8_t **shared_info1, size_t *shared_info1_len, -460 const uint8_t **shared_info2, size_t *shared_info2_len, -461 const uint8_t **certs, size_t *certs_len, -462 const uint8_t **crls, size_t *crls_len, -463 const uint8_t **psigner_infos, size_t *psigner_infos_len, -464 const uint8_t *extra_certs, size_t extra_certs_len, -465 const uint8_t *extra_crls, size_t extra_crls_len, -466 const uint8_t **in, size_t *inlen); -*/ - SM2_KEY sign_key; - SM2_KEY decr_key; - - - - uint8_t sign_serial[20]; - uint8_t sign_name[256]; - size_t sign_name_len; - - - - - - - - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_cms_key_agreement_info(void) -{ - SM2_KEY sm2_key; - uint8_t name[256]; - size_t namelen; - uint8_t serial[20]; - time_t not_before, not_after; - uint8_t cert[2048]; - size_t certlen; - - uint8_t buf[4096]; - uint8_t *p; - const uint8_t *cp; - size_t len; - const uint8_t *d; - size_t dlen; - - int version; - SM2_KEY public_key; - const uint8_t *pcert; - size_t pcertlen; - const uint8_t *id; - size_t idlen; - - if (sm2_key_generate(&sm2_key) != 1 - || rand_bytes(serial, sizeof(serial)) != 1 - || x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 - || time(¬_before) == - 1 - || x509_validity_add_days(¬_after, not_before, 365) != 1 - || x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - name, namelen, - not_before, not_after, - name, namelen, - &sm2_key, NULL, 0, NULL, 0, NULL, 0, - &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - error_print(); - return -1; - } - - cp = p = buf; len = 0; - if (cms_key_agreement_info_to_der( - CMS_version_v1, - &sm2_key, - cert, certlen, - (uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - cms_key_agreement_info_print(stderr, 0, 0, "KeyAgreementInfo", d, dlen); - - - cp = p = buf; len = 0; - if (cms_key_agreement_info_to_der( - CMS_version_v1, - &sm2_key, - cert, certlen, - (uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, - &p, &len) != 1 - || cms_key_agreement_info_from_der( - &version, - &public_key, - &pcert, &pcertlen, - &id, &idlen, - &cp, &len) != 1 - || asn1_check(version == CMS_version_v1) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (sm2_public_key_equ(&sm2_key, &public_key) != 1) { - error_print(); - return -1; - } - if (pcertlen != certlen - || memcmp(pcert, cert, certlen) != 0 - || idlen != SM2_DEFAULT_ID_LENGTH - || memcmp(SM2_DEFAULT_ID, id, idlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(int argc, char **argv) -{ - if (test_cms_content_type() != 1) goto err; - if (test_cms_content_info() != 1) goto err; - if (test_cms_enced_content_info() != 1) goto err; - if (test_cms_enced_content_info_encrypt() != 1) goto err; - if (test_cms_issuer_and_serial_number() != 1) goto err; - if (test_cms_signer_info() != 1) goto err; - if (test_cms_signer_info_sign() != 1) goto err; - if (test_cms_signer_infos() != 1) goto err; - if (test_cms_digest_algors() != 1) goto err; - if (test_cms_signed_data() != 1) goto err; - if (test_cms_recipient_info() != 1) goto err; - if (test_cms_enveloped_data() != 1) goto err; - if (test_cms_key_agreement_info() != 1) goto err; - - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_cms_content_type(void) +{ + int tests[] = { + OID_cms_data, + OID_cms_signed_data, + OID_cms_enveloped_data, + OID_cms_signed_and_enveloped_data, + OID_cms_encrypted_data, + OID_cms_key_agreement_info, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (cms_content_type_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + int oid; + if (cms_content_type_from_der(&oid, &cp, &len) != 1 + || asn1_check(oid == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", cms_content_type_name(oid)); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_content_info(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + uint8_t data[20] = { 0x01,0x02 }; + int oid; + const uint8_t *d; + size_t dlen; + + if (cms_content_info_to_der(OID_cms_data, data, sizeof(data), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_content_info_print(stderr, 0, 0, "ContentInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + +// 当类型为OID_cms_data, 数据是OCTET STRING,需要再解析一次 + + if (cms_content_info_to_der(OID_cms_data, data, sizeof(data), &p, &len) != 1 + || cms_content_info_from_der(&oid, &d, &dlen, &cp, &len) != 1 + || asn1_check(oid == OID_cms_data) != 1 +// || asn1_check(dlen == sizeof(data)) != 1 +// || asn1_check(memcmp(data, d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_enced_content_info(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + uint8_t iv[16] = {0}; + uint8_t enced[32] = { 0x01,0x02 }; + const uint8_t *d; + size_t dlen; + + int oid; + int cipher; + const uint8_t *piv; + size_t ivlen; + const uint8_t *shared_info1; + size_t shared_info1_len; + const uint8_t *shared_info2; + size_t shared_info2_len; + + if (cms_enced_content_info_to_der(OID_cms_data, + OID_sm4_cbc, iv, sizeof(iv), enced, sizeof(enced), + NULL, 0, NULL, 0, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_enced_content_info_print(stderr, 0, 0, "EncryptedContentInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (cms_enced_content_info_to_der(OID_cms_data, + OID_sm4_cbc, iv, sizeof(iv), enced, sizeof(enced), + NULL, 0, NULL, 0, &p, &len) != 1 + || cms_enced_content_info_from_der(&oid, + &cipher, &piv, &ivlen, &d, &dlen, + &shared_info1, &shared_info1_len, + &shared_info2, &shared_info2_len, &cp, &len) != 1 + || asn1_check(oid == OID_cms_data) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_check(dlen == sizeof(enced)) != 1 + || asn1_check(shared_info1 == NULL) != 1 + || asn1_check(shared_info1_len == 0) != 1 + || asn1_check(shared_info2 == NULL) != 1 + || asn1_check(shared_info2_len == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_enced_content_info_encrypt(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + uint8_t key[16] = {0}; + uint8_t iv[16] = {1}; + uint8_t data[20] = {2}; + + const uint8_t *d; + size_t dlen; + + int oid; + int cipher; + const uint8_t *piv; + size_t ivlen; + uint8_t data2[256]; + const uint8_t *shared_info1; + size_t shared_info1_len; + const uint8_t *shared_info2; + size_t shared_info2_len; + + if (cms_enced_content_info_encrypt_to_der( + OID_sm4_cbc, + key, sizeof(key), + iv, sizeof(iv), + OID_cms_data, data, sizeof(data), + NULL, 0, + NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_enced_content_info_print(stderr, 0, 0, "EncryptedContentInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (cms_enced_content_info_encrypt_to_der( + OID_sm4_cbc, + key, sizeof(key), + iv, sizeof(iv), + OID_cms_data, data, sizeof(data), + NULL, 0, + NULL, 0, + &p, &len) != 1 + // 显然这个解密函数是有问题的,在from_der的时候不知道密文的长度,因此无法知道需要的输出缓冲长度 + || cms_enced_content_info_decrypt_from_der( + &cipher, + key, sizeof(key), + &oid, data2, &dlen, + &shared_info1, &shared_info1_len, + &shared_info2, &shared_info2_len, + &cp, &len) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(oid = OID_cms_data) != 1 + || asn1_check(dlen == sizeof(data)) != 1 + || asn1_check(memcmp(data, data2, dlen) == 0) != 1 + || asn1_check(shared_info1 == NULL) != 1 + || asn1_check(shared_info2 == NULL) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_issuer_and_serial_number(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + uint8_t issuer[256]; + size_t issuer_len; + uint8_t serial[20] = {1}; + + const uint8_t *d; + size_t dlen; + const uint8_t *pissuer; + const uint8_t *pserial; + size_t serial_len; + + if (x509_name_set(issuer, &issuer_len, sizeof(issuer), + "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || cms_issuer_and_serial_number_to_der( + issuer, issuer_len, serial, sizeof(serial), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_issuer_and_serial_number_print(stderr, 0, 0, "IssuerAndSerialNumber", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_name_set(issuer, &issuer_len, sizeof(issuer), + "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || cms_issuer_and_serial_number_to_der( + issuer, issuer_len, serial, sizeof(serial), &p, &len) != 1 + || cms_issuer_and_serial_number_from_der( + &pissuer, &issuer_len, &pserial, &serial_len, &cp, &len) != 1 + || asn1_check(memcmp(pissuer, issuer, issuer_len) == 0) != 1 + || asn1_check(serial_len == sizeof(serial)) != 1 + || asn1_check(memcmp(serial, pserial, serial_len) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_signer_info(void) +{ + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t issuer_buf[256]; + size_t issuer_len; + uint8_t serial_buf[20]; + uint8_t sig_buf[256]; + size_t siglen = sizeof(sig_buf); + + int version; + const uint8_t *issuer; + const uint8_t *serial; + size_t serial_len; + int digest_alg; + const uint8_t *auth_attrs; + size_t auth_attrs_len; + int sig_alg; + const uint8_t *sig; + const uint8_t *unauth_attrs; + size_t unauth_attrs_len; + + + if (x509_name_set(issuer_buf, &issuer_len, sizeof(issuer_buf), + "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1) { + error_print(); + return -1; + } + + if (cms_signer_info_to_der( + CMS_version_v1, + issuer_buf, issuer_len, + serial_buf, sizeof(serial_buf), + OID_sm3, + NULL, 0, + OID_sm2sign_with_sm3, + sig_buf, siglen, + NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_signer_info_print(stderr, 0, 0, "SignerInfo", d, dlen); + + cp = p = buf; len = 0; + if (cms_signer_info_to_der( + CMS_version_v1, + issuer_buf, issuer_len, + serial_buf, sizeof(serial_buf), + OID_sm3, + NULL, 0, + OID_sm2sign_with_sm3, + sig_buf, siglen, + NULL, 0, + &p, &len) != 1 + || cms_signer_info_from_der( + &version, + &issuer, &issuer_len, + &serial, &serial_len, + &digest_alg, + &auth_attrs, &auth_attrs_len, + &sig_alg, + &sig, &siglen, + &unauth_attrs, &unauth_attrs_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_signer_info_sign(void) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + SM2_KEY sm2_key; + uint8_t serial_buf[20]; + uint8_t name[256]; + size_t namelen; + time_t not_before, not_after; + uint8_t certs[1024]; + size_t certslen; + + SM3_CTX sm3_ctx; + + const uint8_t *cert; + size_t certlen; + const uint8_t *serial; + const uint8_t *issuer; + const uint8_t *auth_attrs; + const uint8_t *unauth_attrs; + size_t serial_len, issuer_len, auth_attrs_len, unauth_attrs_len; + + if (sm2_key_generate(&sm2_key) != 1 + || rand_bytes(serial_buf, sizeof(serial_buf)) != 1 + || x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 + || time(¬_before) == -1 + || x509_validity_add_days(¬_after, not_before, 365) != 1 + || x509_cert_sign(certs, &certslen, sizeof(certs), + X509_version_v3, serial_buf, sizeof(serial_buf), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, NULL, 0, NULL, 0, NULL, 0, + &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, (uint8_t *)"hello", 5); + + cp = p = buf; len = 0; + if (cms_signer_info_sign_to_der( + &sm3_ctx, &sm2_key, + name, namelen, serial_buf, sizeof(serial_buf), + NULL, 0, NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_signer_info_print(stderr, 0, 0, "SignerInfo", d, dlen); + + cp = p = buf; len = 0; + if (cms_signer_info_sign_to_der( + &sm3_ctx, &sm2_key, + name, namelen, serial_buf, sizeof(serial_buf), + NULL, 0, NULL, 0, + &p, &len) != 1 + || cms_signer_info_verify_from_der( + &sm3_ctx, certs, certslen, + &cert, &certlen, + &issuer, &issuer_len, + &serial, &serial_len, + &auth_attrs, &auth_attrs_len, + &unauth_attrs, &unauth_attrs_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_signer_infos(void) +{ + uint8_t buf[1280]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t signer_infos[1024]; + size_t signer_infos_len = 0; + + SM3_CTX sm3_ctx; + SM2_KEY sm2_key; + + uint8_t issuer_buf[256]; + size_t issuer_len; + uint8_t serial_buf[20]; + + sm2_key_generate(&sm2_key); + sm3_init(&sm3_ctx); + sm3_update(&sm3_ctx, (uint8_t *)"hello", 5); + x509_name_set(issuer_buf, &issuer_len, sizeof(issuer_buf), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); + + + if (cms_signer_infos_add_signer_info( + signer_infos, &signer_infos_len, sizeof(signer_infos), + &sm3_ctx, &sm2_key, + issuer_buf, issuer_len, + serial_buf, sizeof(serial_buf), + NULL, 0, + NULL, 0) != 1 + || cms_signer_infos_add_signer_info( + signer_infos, &signer_infos_len, sizeof(signer_infos), + &sm3_ctx, &sm2_key, + issuer_buf, issuer_len, + serial_buf, sizeof(serial_buf), + NULL, 0, + NULL, 0) != 1 + || cms_signer_infos_add_signer_info( + signer_infos, &signer_infos_len, sizeof(signer_infos), + &sm3_ctx, &sm2_key, + issuer_buf, issuer_len, + serial_buf, sizeof(serial_buf), + NULL, 0, + NULL, 0) != 1 + || cms_signer_infos_to_der(signer_infos, signer_infos_len, &p, &len) != 1 + || cms_signer_infos_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1){ + error_print(); + return -1; + } + cms_signer_infos_print(stderr, 0, 0, "SET OF SignerInfo", d, dlen); + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_digest_algors(void) +{ + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int oids[] = { + OID_sm3, + OID_md5, + OID_sha1, + OID_sha256, + OID_sha512, + }; + + int algs[16]; + size_t algs_cnt; + + if (cms_digest_algors_to_der(oids, sizeof(oids)/sizeof(oids[0]), &p, &len) != 1 + || asn1_set_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_digest_algors_print(stderr, 0, 0, "digestAlgorithms", d, dlen); + + if (cms_digest_algors_to_der(oids, sizeof(oids)/sizeof(oids[0]), &p, &len) != 1 + || cms_digest_algors_from_der(algs, &algs_cnt, sizeof(algs)/sizeof(algs[0]), &cp, &len) != 1 + || asn1_check(algs_cnt == sizeof(oids)/sizeof(oids[0])) != 1 + || asn1_check(memcmp(algs, oids, sizeof(oids)) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_signed_data(void) +{ + SM2_KEY sm2_key; + uint8_t cert[4096]; + size_t certlen = 0; + CMS_CERTS_AND_KEY signers[1]; + uint8_t data[48] = {0}; + uint8_t buf[4096]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + sm2_key_generate(&sm2_key); + + { + uint8_t serial[20]; + size_t serial_len = sizeof(serial); + uint8_t name[256]; + size_t namelen = 0; + time_t not_before, not_after; + uint8_t subject[256]; + size_t subject_len = 0; + uint8_t *p = cert; + const uint8_t *cp = cert; + + rand_bytes(serial, sizeof(serial)); + x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); + time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + + if (x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + } + + signers[0].certs = cert; + signers[0].certs_len = certlen; + signers[0].sign_key = &sm2_key; + + if (cms_signed_data_sign_to_der( + signers, sizeof(signers)/sizeof(signers[0]), + OID_cms_data, data, sizeof(data), + NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_signed_data_print(stderr, 0, 0, "SignedData", d, dlen); + + cp = p = buf; len = 0; + { + int content_type; + const uint8_t *content; + size_t content_len; + const uint8_t *certs; + size_t certslen; + const uint8_t *crls; + size_t crlslen; + const uint8_t *signer_infos; + size_t signer_infos_len; + + if (cms_signed_data_sign_to_der( + signers, sizeof(signers)/sizeof(signers[0]), + OID_cms_data, data, sizeof(data), + NULL, 0, + &p, &len) != 1 + || cms_signed_data_verify_from_der( + NULL, 0, + NULL, 0, + &content_type, &content, &content_len, + &certs, &certslen, + &crls, &crlslen, + &signer_infos, &signer_infos_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_recipient_info(void) +{ + SM2_KEY sm2_key; + uint8_t name[256]; + size_t namelen; + uint8_t serial_buf[20]; + uint8_t in[16]; + + uint8_t buf[1024]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int version; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + int pke_algor; + const uint8_t *params; + size_t params_len; + const uint8_t *enced_key; + size_t enced_key_len; + + uint8_t out[sizeof(in)]; + size_t outlen; + + sm2_key_generate(&sm2_key); + x509_name_set(name, &namelen, sizeof(name), "US", "CA", NULL, "BB", "AA", "CC"); + rand_bytes(serial_buf, sizeof(serial_buf)); + rand_bytes(in, sizeof(in)); + + if (cms_recipient_info_encrypt_to_der(&sm2_key, + name, namelen, + serial_buf, sizeof(serial_buf), + in, sizeof(in), + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_recipient_info_print(stderr, 0, 0, "RecipientInfo", d, dlen); + + + cp = p = buf; len = 0; + if (cms_recipient_info_encrypt_to_der(&sm2_key, + name, namelen, + serial_buf, sizeof(serial_buf), + in, sizeof(in), + &p, &len) != 1 + || cms_recipient_info_from_der( + &version, + &issuer, &issuer_len, + &serial, &serial_len, + &pke_algor, ¶ms, ¶ms_len, + &enced_key, &enced_key_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + + cp = p = buf; len = 0; + if (cms_recipient_info_encrypt_to_der( + &sm2_key, + name, namelen, + serial_buf, sizeof(serial_buf), + in, sizeof(in), + &p, &len) != 1 + || cms_recipient_info_decrypt_from_der( + &sm2_key, + name, namelen, + serial_buf, sizeof(serial_buf), + out, &outlen, sizeof(out), + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (sizeof(in) != outlen + || memcmp(in, out, outlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_cms_enveloped_data(void) +{ + SM2_KEY sm2_key1; + uint8_t name1[256]; + size_t name1_len; + uint8_t serial1[20]; + size_t serial1_len; + + SM2_KEY sm2_key2; + uint8_t name2[256]; + size_t name2_len; + uint8_t serial2[20]; + size_t serial2_len; + + time_t not_before, not_after; + + uint8_t certs[2048]; + size_t certslen; + + uint8_t key[16]; + uint8_t iv[16]; + + uint8_t in[80]; + uint8_t out[256]; + size_t outlen; + size_t maxlen; + + uint8_t buf[4096]; + uint8_t *p; + const uint8_t *cp; + size_t len; + const uint8_t *d; + size_t dlen; + + // prepare keys and certs + + if (time(¬_before) == -1 + || x509_validity_add_days(¬_after, not_before, 365) != 1) { + error_print(); + return -1; + } + + p = certs; + certslen = 0; + maxlen = sizeof(certs); + + if (sm2_key_generate(&sm2_key1) != 1 + || rand_bytes(serial1, sizeof(serial1)) != 1 + || x509_name_set(name1, &name1_len, sizeof(name1), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 + || x509_cert_sign( + p, &len, maxlen, + X509_version_v3, + serial1, sizeof(serial1), + OID_sm2sign_with_sm3, + name1, name1_len, + not_before, not_after, + name1, name1_len, + &sm2_key1, NULL, 0, NULL, 0, NULL, 0, + &sm2_key1, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + p += len; + certslen += len; + maxlen -= len; + + if (sm2_key_generate(&sm2_key2) != 1 + || rand_bytes(serial2, sizeof(serial2)) != 1 + || x509_name_set(name2, &name2_len, sizeof(name2), "CN", "Beijing", "Haidian", "PKU", "CS", "Bob") != 1 + || x509_cert_sign( + p, &len, maxlen, + X509_version_v3, + serial2, sizeof(serial2), + OID_sm2sign_with_sm3, + name2, name2_len, + not_before, not_after, + name2, name2_len, + &sm2_key2, NULL, 0, NULL, 0, NULL, 0, + &sm2_key2, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + p += len; + certslen += len; + maxlen -= len; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(in, sizeof(in)); + + // test + + cp = p = buf; len = 0; + if (cms_enveloped_data_encrypt_to_der( + certs, certslen, + OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), + OID_cms_data, in, sizeof(in), + NULL, 0, NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_enveloped_data_print(stderr, 0, 0, "EnvelopedData", d, dlen); + + + int content_type; + + + cp = p = buf; len = 0; + if (cms_enveloped_data_encrypt_to_der( + certs, certslen, + OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), + OID_cms_data, in, sizeof(in), + NULL, 0, NULL, 0, + &p, &len) != 1) { + error_print(); + return -1; + } + + const uint8_t *rcpt_infos; + const uint8_t *shared_info1; + const uint8_t *shared_info2; + size_t rcpt_infos_len, shared_info1_len, shared_info2_len; + + if (cms_enveloped_data_decrypt_from_der( + &sm2_key1, + name1, name1_len, + serial1, sizeof(serial1), + &content_type, out, &outlen, + &rcpt_infos, &rcpt_infos_len, + &shared_info1, &shared_info1_len, + &shared_info2, &shared_info2_len, + &cp, &len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_signed_and_enveloped_data(void) +{ +/* +444 int cms_signed_and_enveloped_data_encipher_to_der( +445 const CMS_CERTS_AND_KEY *signers, size_t signers_cnt, +446 const uint8_t *rcpt_certs, size_t rcpt_certs_len, +447 int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, +448 int content_type, const uint8_t *content, size_t content_len, +449 const uint8_t *signers_crls, size_t signers_crls_len, +450 const uint8_t *shared_info1, size_t shared_info1_len, +451 const uint8_t *shared_info2, size_t shared_info2_len, +452 uint8_t **out, size_t *outlen); +453 int cms_signed_and_enveloped_data_decipher_from_der( +454 const SM2_KEY *rcpt_key, +455 const uint8_t *rcpt_issuer, size_t rcpt_issuer_len, +456 const uint8_t *rcpt_serial, size_t rcpt_serial_len, +457 int *content_type, uint8_t *content, size_t *content_len, +458 const uint8_t **prcpt_infos, size_t *prcpt_infos_len, +459 const uint8_t **shared_info1, size_t *shared_info1_len, +460 const uint8_t **shared_info2, size_t *shared_info2_len, +461 const uint8_t **certs, size_t *certs_len, +462 const uint8_t **crls, size_t *crls_len, +463 const uint8_t **psigner_infos, size_t *psigner_infos_len, +464 const uint8_t *extra_certs, size_t extra_certs_len, +465 const uint8_t *extra_crls, size_t extra_crls_len, +466 const uint8_t **in, size_t *inlen); +*/ + SM2_KEY sign_key; + SM2_KEY decr_key; + + + + uint8_t sign_serial[20]; + uint8_t sign_name[256]; + size_t sign_name_len; + + + + + + + + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_cms_key_agreement_info(void) +{ + SM2_KEY sm2_key; + uint8_t name[256]; + size_t namelen; + uint8_t serial[20]; + time_t not_before, not_after; + uint8_t cert[2048]; + size_t certlen; + + uint8_t buf[4096]; + uint8_t *p; + const uint8_t *cp; + size_t len; + const uint8_t *d; + size_t dlen; + + int version; + SM2_KEY public_key; + const uint8_t *pcert; + size_t pcertlen; + const uint8_t *id; + size_t idlen; + + if (sm2_key_generate(&sm2_key) != 1 + || rand_bytes(serial, sizeof(serial)) != 1 + || x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1 + || time(¬_before) == - 1 + || x509_validity_add_days(¬_after, not_before, 365) != 1 + || x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, NULL, 0, NULL, 0, NULL, 0, + &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + error_print(); + return -1; + } + + cp = p = buf; len = 0; + if (cms_key_agreement_info_to_der( + CMS_version_v1, + &sm2_key, + cert, certlen, + (uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + cms_key_agreement_info_print(stderr, 0, 0, "KeyAgreementInfo", d, dlen); + + + cp = p = buf; len = 0; + if (cms_key_agreement_info_to_der( + CMS_version_v1, + &sm2_key, + cert, certlen, + (uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, + &p, &len) != 1 + || cms_key_agreement_info_from_der( + &version, + &public_key, + &pcert, &pcertlen, + &id, &idlen, + &cp, &len) != 1 + || asn1_check(version == CMS_version_v1) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (sm2_public_key_equ(&sm2_key, &public_key) != 1) { + error_print(); + return -1; + } + if (pcertlen != certlen + || memcmp(pcert, cert, certlen) != 0 + || idlen != SM2_DEFAULT_ID_LENGTH + || memcmp(SM2_DEFAULT_ID, id, idlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(int argc, char **argv) +{ + if (test_cms_content_type() != 1) goto err; + if (test_cms_content_info() != 1) goto err; + if (test_cms_enced_content_info() != 1) goto err; + if (test_cms_enced_content_info_encrypt() != 1) goto err; + if (test_cms_issuer_and_serial_number() != 1) goto err; + if (test_cms_signer_info() != 1) goto err; + if (test_cms_signer_info_sign() != 1) goto err; + if (test_cms_signer_infos() != 1) goto err; + if (test_cms_digest_algors() != 1) goto err; + if (test_cms_signed_data() != 1) goto err; + if (test_cms_recipient_info() != 1) goto err; + if (test_cms_enveloped_data() != 1) goto err; + if (test_cms_key_agreement_info() != 1) goto err; + + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/destest.c b/tests/destest.c index 3e4c49db..e3d87faa 100644 --- a/tests/destest.c +++ b/tests/destest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,17 +7,18 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include - - -int main(void) -{ - int err = 0; - return err; -} - + + + +#include +#include +#include +#include + + +int main(void) +{ + int err = 0; + return err; +} + diff --git a/tests/digesttest.c b/tests/digesttest.c index 1464f3db..819f6d9b 100644 --- a/tests/digesttest.c +++ b/tests/digesttest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,41 +7,42 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include - -const char *digests[] = { -// "md5", - "sha1", - "sm3", - "sha224", - "sha256", - "sha384", - "sha512", - "sha512-224", - "sha512-256", -}; - -int main(void) -{ - uint8_t dgst[64]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < sizeof(digests)/sizeof(digests[0]); i++) { - const DIGEST *algor = digest_from_name(digests[i]); - digest(algor, (uint8_t *)"abc", 3, dgst, &dgstlen); - - printf("%s (%zu) ", digests[i], dgstlen); - for (j = 0; j < dgstlen; j++) { - printf("%02x", dgst[j]); - } - printf("\n"); - } - - return 0; -} + + + +#include +#include +#include +#include + +const char *digests[] = { +// "md5", + "sha1", + "sm3", + "sha224", + "sha256", + "sha384", + "sha512", + "sha512-224", + "sha512-256", +}; + +int main(void) +{ + uint8_t dgst[64]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < sizeof(digests)/sizeof(digests[0]); i++) { + const DIGEST *algor = digest_from_name(digests[i]); + digest(algor, (uint8_t *)"abc", 3, dgst, &dgstlen); + + printf("%s (%zu) ", digests[i], dgstlen); + for (j = 0; j < dgstlen; j++) { + printf("%02x", dgst[j]); + } + printf("\n"); + } + + return 0; +} diff --git a/tests/ectest.c b/tests/ectest.c index 3b8e9f14..72786c06 100644 --- a/tests/ectest.c +++ b/tests/ectest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,115 +7,116 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static int test_ec_named_curve(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - char *curves[] = { - "sm2p256v1", - "prime192v1", - "prime256v1", - "secp256k1", - "secp384r1", - "secp521r1", - }; - int oid; - int i; - - for (i = 0; i < sizeof(curves)/sizeof(curves[0]); i++) { - if ((oid = ec_named_curve_from_name(curves[i])) == OID_undef) { - error_print(); - return -1; - } - if (ec_named_curve_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - } - - for (i = 0; i < sizeof(curves)/sizeof(curves[0]); i++) { - if (ec_named_curve_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != ec_named_curve_from_name(curves[i])) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", ec_named_curve_name(oid)); - } - (void)asn1_length_is_zero(len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_ec_point_print(void) -{ - SM2_KEY sm2_key; - uint8_t buf[256]; - uint8_t *p = buf; - size_t len = 0; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - if (sm2_point_to_der(&(sm2_key.public_key), &p, &len) != 1) { - error_print(); - return -1; - } - ec_point_print(stderr, 0, 4, "ECPoint", buf, len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_ec_private_key_print(void) -{ - SM2_KEY sm2_key; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - ec_private_key_print(stderr, 0, 4, "ECPrivateKey", d, dlen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_ec_named_curve() != 1) goto err; - if (test_ec_point_print() != 1) goto err; - if (test_ec_private_key_print() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include + + +static int test_ec_named_curve(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + char *curves[] = { + "sm2p256v1", + "prime192v1", + "prime256v1", + "secp256k1", + "secp384r1", + "secp521r1", + }; + int oid; + int i; + + for (i = 0; i < sizeof(curves)/sizeof(curves[0]); i++) { + if ((oid = ec_named_curve_from_name(curves[i])) == OID_undef) { + error_print(); + return -1; + } + if (ec_named_curve_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + } + + for (i = 0; i < sizeof(curves)/sizeof(curves[0]); i++) { + if (ec_named_curve_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != ec_named_curve_from_name(curves[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", ec_named_curve_name(oid)); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_ec_point_print(void) +{ + SM2_KEY sm2_key; + uint8_t buf[256]; + uint8_t *p = buf; + size_t len = 0; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + if (sm2_point_to_der(&(sm2_key.public_key), &p, &len) != 1) { + error_print(); + return -1; + } + ec_point_print(stderr, 0, 4, "ECPoint", buf, len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_ec_private_key_print(void) +{ + SM2_KEY sm2_key; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + ec_private_key_print(stderr, 0, 4, "ECPrivateKey", d, dlen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_ec_named_curve() != 1) goto err; + if (test_ec_point_print() != 1) goto err; + if (test_ec_private_key_print() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/gcmtest.c b/tests/gcmtest.c index 56eadad9..6bc72121 100644 --- a/tests/gcmtest.c +++ b/tests/gcmtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,187 +7,188 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -struct { - char *H; - char *A; - char *C; - char *T; -} ghash_tests[] = { - // test 1 - { - "66e94bd4ef8a2c3b884cfa59ca342b2e", - "", - "", - "00000000000000000000000000000000", - }, - // test 2 - { - "66e94bd4ef8a2c3b884cfa59ca342b2e", - "", - "0388dace60b6a392f328c2b971b2fe78", - "f38cbb1ad69223dcc3457ae5b6b0f885", - - }, - // test 3 - { - "b83b533708bf535d0aa6e52980d53b78", - "", - "42831ec2217774244b7221b784d0d49c" - "e3aa212f2c02a4e035c17e2329aca12e" - "21d514b25466931c7d8f6a5aac84aa05" - "1ba30b396a0aac973d58e091473f5985", - "7f1b32b81b820d02614f8895ac1d4eac", - }, - // test 4 - { - "b83b533708bf535d0aa6e52980d53b78", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "42831ec2217774244b7221b784d0d49c" - "e3aa212f2c02a4e035c17e2329aca12e" - "21d514b25466931c7d8f6a5aac84aa05" - "1ba30b396a0aac973d58e091", - "698e57f70e6ecc7fd9463b7260a9ae5f", - }, - // test 5 - { - "b83b533708bf535d0aa6e52980d53b78", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "61353b4c2806934a777ff51fa22a4755" - "699b2a714fcdc6f83766e5f97b6c7423" - "73806900e49f24b22b097544d4896b42" - "4989b5e1ebac0f07c23f4598", - "df586bb4c249b92cb6922877e444d37b", - }, - // test 6 - { - "b83b533708bf535d0aa6e52980d53b78", - "feedfacedeadbeeffeedfacedeadbeef" - "abaddad2", - "8ce24998625615b603a033aca13fb894" - "be9112a5c3a211a8ba262a3cca7e2ca7" - "01e4a9a4fba43c90ccdcb281d48c7c6f" - "d62875d2aca417034c34aee5", - "1c5afe9760d3932f3c9a878aac3dc3de", - }, -}; - -int test_ghash(void) -{ - uint8_t H[16]; - uint8_t A[32]; - uint8_t C[64]; - uint8_t T[16]; - uint8_t out[16]; - size_t Hlen, Alen, Clen, Tlen; - int i; - - for (i = 0; i < sizeof(ghash_tests)/sizeof(ghash_tests[0]); i++) { - hex_to_bytes(ghash_tests[i].H, strlen(ghash_tests[i].H), H, &Hlen); - hex_to_bytes(ghash_tests[i].A, strlen(ghash_tests[i].A), A, &Alen); - hex_to_bytes(ghash_tests[i].C, strlen(ghash_tests[i].C), C, &Clen); - hex_to_bytes(ghash_tests[i].T, strlen(ghash_tests[i].T), T, &Tlen); - ghash(H, A, Alen, C, Clen, out); - - if (memcmp(out, T, Tlen) != 0) { - format_print(stderr, 0, 0, "test %d failed\n", i + 1); - format_print(stderr, 0, 2, "H = %s\n", ghash_tests[i].H); - format_print(stderr, 0, 2, "A = %s\n", ghash_tests[i].A); - format_print(stderr, 0, 2, "C = %s\n", ghash_tests[i].C); - format_bytes(stderr, 0, 2, "GHASH(H,A,C) = ", out, 16); - format_print(stderr, 0, 2, " = %s\n\n", ghash_tests[i].T); - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int test_gcm(void) -{ - BLOCK_CIPHER_KEY block_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t aad[64]; - uint8_t in[100]; - uint8_t out[sizeof(in)]; - uint8_t buf[sizeof(in)]; - uint8_t tag[16]; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - rand_bytes(aad, sizeof(aad)); - rand_bytes(in, sizeof(in)); - - memset(out, 0, sizeof(out)); - memset(buf, 0, sizeof(buf)); - memset(tag, 0, sizeof(tag)); - - if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_aes128(), key) != 1) { - error_print(); - return -1; - } - if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { - error_print(); - return -1; - } - if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { - error_print(); - return -1; - } - if (memcmp(buf, in, sizeof(in)) != 0) { - error_print(); - return -1; - } - - memset(out, 0, sizeof(out)); - memset(buf, 0, sizeof(buf)); - memset(tag, 0, sizeof(tag)); - - if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { - error_print(); - return -1; - } - if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { - error_print(); - return -1; - } - if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { - error_print(); - return -1; - } - if (memcmp(buf, in, sizeof(in)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - - - - -int main(int argc, char **argv) -{ - if (test_ghash() != 1) goto err; - if (test_gcm() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +struct { + char *H; + char *A; + char *C; + char *T; +} ghash_tests[] = { + // test 1 + { + "66e94bd4ef8a2c3b884cfa59ca342b2e", + "", + "", + "00000000000000000000000000000000", + }, + // test 2 + { + "66e94bd4ef8a2c3b884cfa59ca342b2e", + "", + "0388dace60b6a392f328c2b971b2fe78", + "f38cbb1ad69223dcc3457ae5b6b0f885", + + }, + // test 3 + { + "b83b533708bf535d0aa6e52980d53b78", + "", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091473f5985", + "7f1b32b81b820d02614f8895ac1d4eac", + }, + // test 4 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091", + "698e57f70e6ecc7fd9463b7260a9ae5f", + }, + // test 5 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "61353b4c2806934a777ff51fa22a4755" + "699b2a714fcdc6f83766e5f97b6c7423" + "73806900e49f24b22b097544d4896b42" + "4989b5e1ebac0f07c23f4598", + "df586bb4c249b92cb6922877e444d37b", + }, + // test 6 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "8ce24998625615b603a033aca13fb894" + "be9112a5c3a211a8ba262a3cca7e2ca7" + "01e4a9a4fba43c90ccdcb281d48c7c6f" + "d62875d2aca417034c34aee5", + "1c5afe9760d3932f3c9a878aac3dc3de", + }, +}; + +int test_ghash(void) +{ + uint8_t H[16]; + uint8_t A[32]; + uint8_t C[64]; + uint8_t T[16]; + uint8_t out[16]; + size_t Hlen, Alen, Clen, Tlen; + int i; + + for (i = 0; i < sizeof(ghash_tests)/sizeof(ghash_tests[0]); i++) { + hex_to_bytes(ghash_tests[i].H, strlen(ghash_tests[i].H), H, &Hlen); + hex_to_bytes(ghash_tests[i].A, strlen(ghash_tests[i].A), A, &Alen); + hex_to_bytes(ghash_tests[i].C, strlen(ghash_tests[i].C), C, &Clen); + hex_to_bytes(ghash_tests[i].T, strlen(ghash_tests[i].T), T, &Tlen); + ghash(H, A, Alen, C, Clen, out); + + if (memcmp(out, T, Tlen) != 0) { + format_print(stderr, 0, 0, "test %d failed\n", i + 1); + format_print(stderr, 0, 2, "H = %s\n", ghash_tests[i].H); + format_print(stderr, 0, 2, "A = %s\n", ghash_tests[i].A); + format_print(stderr, 0, 2, "C = %s\n", ghash_tests[i].C); + format_bytes(stderr, 0, 2, "GHASH(H,A,C) = ", out, 16); + format_print(stderr, 0, 2, " = %s\n\n", ghash_tests[i].T); + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_gcm(void) +{ + BLOCK_CIPHER_KEY block_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[64]; + uint8_t in[100]; + uint8_t out[sizeof(in)]; + uint8_t buf[sizeof(in)]; + uint8_t tag[16]; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(aad, sizeof(aad)); + rand_bytes(in, sizeof(in)); + + memset(out, 0, sizeof(out)); + memset(buf, 0, sizeof(buf)); + memset(tag, 0, sizeof(tag)); + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_aes128(), key) != 1) { + error_print(); + return -1; + } + if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { + error_print(); + return -1; + } + if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, in, sizeof(in)) != 0) { + error_print(); + return -1; + } + + memset(out, 0, sizeof(out)); + memset(buf, 0, sizeof(buf)); + memset(tag, 0, sizeof(tag)); + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { + error_print(); + return -1; + } + if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { + error_print(); + return -1; + } + if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, in, sizeof(in)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + + + +int main(int argc, char **argv) +{ + if (test_ghash() != 1) goto err; + if (test_gcm() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/gf128test.c b/tests/gf128test.c index f434cc9c..9d978f17 100644 --- a/tests/gf128test.c +++ b/tests/gf128test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,102 +7,103 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -int test_gf128_from_hex(void) -{ - char *tests[] = { - "00000000000000000000000000000000", - "00000000000000000000000000000001", - "10000000000000000000000000000000", - "de300f9301a499a965f8bf677e99e80d", - "14b267838ec9ef1bb7b5ce8c19e34bc6", - }; - gf128_t a; - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - a = gf128_from_hex(tests[i]); - if (gf128_equ_hex(a, tests[i]) != 1) { - error_print(); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int test_gf128_mul2(void) -{ - char *tests[] = { - "00000000000000000000000000000001", - "de300f9301a499a965f8bf677e99e80d", - }; - char *results[] = { - "e1000000000000000000000000000000", - "8e1807c980d24cd4b2fc5fb3bf4cf406", - }; - gf128_t a; - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - a = gf128_from_hex(tests[i]); - a = gf128_mul2(a); - if (gf128_equ_hex(a, results[i]) != 1) { - error_print(); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int test_gf128_mul(void) -{ - char *hex_a = "de300f9301a499a965f8bf677e99e80d"; - char *hex_b = "14b267838ec9ef1bb7b5ce8c19e34bc6"; - char *hex_add_a_b = "ca8268108f6d76b2d24d71eb677aa3cb"; - char *hex_mul_a_b = "7d87dda57a20b0c51d9743071ab14010"; - gf128_t a, b, r; - - a = gf128_from_hex(hex_a); - b = gf128_from_hex(hex_b); - - r = gf128_add(a, b); - if (gf128_equ_hex(r, hex_add_a_b) != 1) { - error_print(); - return -1; - } - - r = gf128_mul(a, b); - if (gf128_equ_hex(r, hex_mul_a_b) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_gf128_from_hex() != 1) goto err; - if (test_gf128_mul2() != 1) goto err; - if (test_gf128_mul() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; - -} + + +#include +#include +#include +#include +#include +#include +#include + + +int test_gf128_from_hex(void) +{ + char *tests[] = { + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "10000000000000000000000000000000", + "de300f9301a499a965f8bf677e99e80d", + "14b267838ec9ef1bb7b5ce8c19e34bc6", + }; + gf128_t a; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + a = gf128_from_hex(tests[i]); + if (gf128_equ_hex(a, tests[i]) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_gf128_mul2(void) +{ + char *tests[] = { + "00000000000000000000000000000001", + "de300f9301a499a965f8bf677e99e80d", + }; + char *results[] = { + "e1000000000000000000000000000000", + "8e1807c980d24cd4b2fc5fb3bf4cf406", + }; + gf128_t a; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + a = gf128_from_hex(tests[i]); + a = gf128_mul2(a); + if (gf128_equ_hex(a, results[i]) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_gf128_mul(void) +{ + char *hex_a = "de300f9301a499a965f8bf677e99e80d"; + char *hex_b = "14b267838ec9ef1bb7b5ce8c19e34bc6"; + char *hex_add_a_b = "ca8268108f6d76b2d24d71eb677aa3cb"; + char *hex_mul_a_b = "7d87dda57a20b0c51d9743071ab14010"; + gf128_t a, b, r; + + a = gf128_from_hex(hex_a); + b = gf128_from_hex(hex_b); + + r = gf128_add(a, b); + if (gf128_equ_hex(r, hex_add_a_b) != 1) { + error_print(); + return -1; + } + + r = gf128_mul(a, b); + if (gf128_equ_hex(r, hex_mul_a_b) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_gf128_from_hex() != 1) goto err; + if (test_gf128_mul2() != 1) goto err; + if (test_gf128_mul() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; + +} diff --git a/tests/hash_drbgtest.c b/tests/hash_drbgtest.c index c835ab1e..68af4550 100644 --- a/tests/hash_drbgtest.c +++ b/tests/hash_drbgtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,86 +7,87 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define EntropyInput "212956390783381dbfc6362dd0da9a09" -#define Nonce "5280987fc5e27a49" -#define PersonalizationString "" -#define AdditionalInput "" -#define V0 "02b84eba8121ca090b6b66d3371609eaf76405a5c2807d80035c1a13dfed5aa18e536af599a7b3c68b2c56240ed11997f4048910d84604" -#define C0 "a677e4921587563eebe55d1b25e59c3f3d200bc61aaee665e7a6858c2857c45dba4bce8182252962ae86de491046a5e3450eec44938a0a" - -#define AdditionalInput1 "" -#define EntropyInputPR1 "2edb396eeb8960f77943c2a59075a786" -#define V1 "f9afadfbbf2c3d1004f9baca38be247342e5fbb83281915d5de18beb963712a344e89bb0e6b925a7bbc32eadb8b441efc1fa0c649df42a" -#define C1 "1d41cbbd634909e4761c232fcfd6a6c2edf0a7f4d3d3c164f74a88955f355efce2d86c1e9fa897b7005ef9d4d3a51bf4fc0b805ab896c9" - -#define PR1 "2edb396eeb8960f77943c2a59075a786" -#define PR2 "30b565b63a5012676940d3ef17d9e996" - - -int main(void) -{ - HASH_DRBG drbg; - - uint8_t entropy[sizeof(EntropyInput)/2]; - uint8_t nonce[sizeof(Nonce)/2]; - uint8_t personalstr[sizeof(PersonalizationString)/2]; - uint8_t v[sizeof(V0)/2]; - uint8_t c[sizeof(C0)/2]; - uint8_t entropy_pr1[sizeof(EntropyInputPR1)/2]; - uint8_t pr1[sizeof(PR1)/2]; - uint8_t pr2[sizeof(PR2)/2]; - size_t entropy_len, nonce_len, personalstr_len, vlen, clen; - size_t entropy_pr1len; - size_t pr1_len, pr2_len; - unsigned char out[640/8]; - int i; - - hex_to_bytes(EntropyInput, strlen(EntropyInput), entropy, &entropy_len); - hex_to_bytes(Nonce, strlen(Nonce), nonce, &nonce_len); - hex_to_bytes(PersonalizationString, strlen(PersonalizationString), personalstr, &personalstr_len); - hex_to_bytes(V0, strlen(V0), v, &vlen); - hex_to_bytes(C0, strlen(C0), c, &clen); - hex_to_bytes(EntropyInputPR1, strlen(EntropyInputPR1), entropy_pr1, &entropy_pr1len); - hex_to_bytes(PR1, strlen(PR1), pr1, &pr1_len); - hex_to_bytes(PR2, strlen(PR2), pr2, &pr2_len); - - hash_drbg_init(&drbg, DIGEST_sha1(), - entropy, entropy_len, - nonce, nonce_len, - personalstr, personalstr_len); - - printf("sha1_drbg test 1 "); - if (drbg.seedlen != vlen - || memcmp(drbg.V, v, vlen) != 0 - || memcmp(drbg.C, c, clen) != 0 - || drbg.reseed_counter != 1) { - printf("failed\n"); - return 1; - } else { - printf("ok\n"); - } - - hash_drbg_reseed(&drbg, pr1, pr1_len, NULL, 0); - hash_drbg_generate(&drbg, NULL, 0, 640/8, out); - - hash_drbg_reseed(&drbg, pr2, pr2_len, NULL, 0); - hash_drbg_generate(&drbg, NULL, 0, 640/8, out); - - for (i = 0; i < sizeof(out); i++) { - printf("%02x", out[i]); - } - printf("\n"); - - return 0; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define EntropyInput "212956390783381dbfc6362dd0da9a09" +#define Nonce "5280987fc5e27a49" +#define PersonalizationString "" +#define AdditionalInput "" +#define V0 "02b84eba8121ca090b6b66d3371609eaf76405a5c2807d80035c1a13dfed5aa18e536af599a7b3c68b2c56240ed11997f4048910d84604" +#define C0 "a677e4921587563eebe55d1b25e59c3f3d200bc61aaee665e7a6858c2857c45dba4bce8182252962ae86de491046a5e3450eec44938a0a" + +#define AdditionalInput1 "" +#define EntropyInputPR1 "2edb396eeb8960f77943c2a59075a786" +#define V1 "f9afadfbbf2c3d1004f9baca38be247342e5fbb83281915d5de18beb963712a344e89bb0e6b925a7bbc32eadb8b441efc1fa0c649df42a" +#define C1 "1d41cbbd634909e4761c232fcfd6a6c2edf0a7f4d3d3c164f74a88955f355efce2d86c1e9fa897b7005ef9d4d3a51bf4fc0b805ab896c9" + +#define PR1 "2edb396eeb8960f77943c2a59075a786" +#define PR2 "30b565b63a5012676940d3ef17d9e996" + + +int main(void) +{ + HASH_DRBG drbg; + + uint8_t entropy[sizeof(EntropyInput)/2]; + uint8_t nonce[sizeof(Nonce)/2]; + uint8_t personalstr[sizeof(PersonalizationString)/2]; + uint8_t v[sizeof(V0)/2]; + uint8_t c[sizeof(C0)/2]; + uint8_t entropy_pr1[sizeof(EntropyInputPR1)/2]; + uint8_t pr1[sizeof(PR1)/2]; + uint8_t pr2[sizeof(PR2)/2]; + size_t entropy_len, nonce_len, personalstr_len, vlen, clen; + size_t entropy_pr1len; + size_t pr1_len, pr2_len; + unsigned char out[640/8]; + int i; + + hex_to_bytes(EntropyInput, strlen(EntropyInput), entropy, &entropy_len); + hex_to_bytes(Nonce, strlen(Nonce), nonce, &nonce_len); + hex_to_bytes(PersonalizationString, strlen(PersonalizationString), personalstr, &personalstr_len); + hex_to_bytes(V0, strlen(V0), v, &vlen); + hex_to_bytes(C0, strlen(C0), c, &clen); + hex_to_bytes(EntropyInputPR1, strlen(EntropyInputPR1), entropy_pr1, &entropy_pr1len); + hex_to_bytes(PR1, strlen(PR1), pr1, &pr1_len); + hex_to_bytes(PR2, strlen(PR2), pr2, &pr2_len); + + hash_drbg_init(&drbg, DIGEST_sha1(), + entropy, entropy_len, + nonce, nonce_len, + personalstr, personalstr_len); + + printf("sha1_drbg test 1 "); + if (drbg.seedlen != vlen + || memcmp(drbg.V, v, vlen) != 0 + || memcmp(drbg.C, c, clen) != 0 + || drbg.reseed_counter != 1) { + printf("failed\n"); + return 1; + } else { + printf("ok\n"); + } + + hash_drbg_reseed(&drbg, pr1, pr1_len, NULL, 0); + hash_drbg_generate(&drbg, NULL, 0, 640/8, out); + + hash_drbg_reseed(&drbg, pr2, pr2_len, NULL, 0); + hash_drbg_generate(&drbg, NULL, 0, 640/8, out); + + for (i = 0; i < sizeof(out); i++) { + printf("%02x", out[i]); + } + printf("\n"); + + return 0; +} diff --git a/tests/hextest.c b/tests/hextest.c index f8ed0268..82847e6e 100644 --- a/tests/hextest.c +++ b/tests/hextest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,13 +7,14 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -int main(void) -{ - return 0; -} + + +#include +#include +#include +#include + +int main(void) +{ + return 0; +} diff --git a/tests/hkdftest.c b/tests/hkdftest.c index 4b2d2ef8..9c702ae3 100644 --- a/tests/hkdftest.c +++ b/tests/hkdftest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,210 +7,211 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - -static struct { - char *algor; - char *ikm; - char *salt; - char *info; - int L; - char *prk; - char *okm; -} hkdf_tests[] = { - { - // test 1 - "sha256", - "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", - "000102030405060708090a0b0c", - "f0f1f2f3f4f5f6f7f8f9", - 42, - "077709362c2e32df0ddc3f0dc47bba63" - "90b6c73bb50f9c3122ec844ad7c2b3e5", - "3cb25f25faacd57a90434f64d0362f2a" - "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" - "34007208d5b887185865", - }, - { - // test 2 - "sha256", - "000102030405060708090a0b0c0d0e0f" - "101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f" - "303132333435363738393a3b3c3d3e3f" - "404142434445464748494a4b4c4d4e4f", - "606162636465666768696a6b6c6d6e6f" - "707172737475767778797a7b7c7d7e7f" - "808182838485868788898a8b8c8d8e8f" - "909192939495969798999a9b9c9d9e9f" - "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", - "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" - "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" - "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" - "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" - "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - 82, - "06a6b88c5853361a06104c9ceb35b45c" - "ef760014904671014a193f40c15fc244", - "b11e398dc80327a1c8e7f78c596a4934" - "4f012eda2d4efad8a050cc4c19afa97c" - "59045a99cac7827271cb41c65e590e09" - "da3275600c2f09b8367793a9aca3db71" - "cc30c58179ec3e87c14c01d5c1f3434f" - "1d87", - }, - { - // test 3 - "sha256", - "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", - "", - "", - 42, - "19ef24a32c717b167f33a91d6f648bdf" - "96596776afdb6377ac434c1c293ccb04", - "8da4e775a563c18f715f802a063c5a31" - "b8a11f5c5ee1879ec3454e5f3c738d2d" - "9d201395faa4b61a96c8", - }, - { - // test 4 - "sha1", - "0b0b0b0b0b0b0b0b0b0b0b", - "000102030405060708090a0b0c", - "f0f1f2f3f4f5f6f7f8f9", - 42, - "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243", - "085a01ea1b10f36933068b56efa5ad81" - "a4f14b822f5b091568a9cdd4f155fda2" - "c22e422478d305f3f896", - }, - { - // test 5 - "sha1", - "000102030405060708090a0b0c0d0e0f" - "101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f" - "303132333435363738393a3b3c3d3e3f" - "404142434445464748494a4b4c4d4e4f", - "606162636465666768696a6b6c6d6e6f" - "707172737475767778797a7b7c7d7e7f" - "808182838485868788898a8b8c8d8e8f" - "909192939495969798999a9b9c9d9e9f" - "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", - "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" - "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" - "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" - "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" - "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - 82, - "8adae09a2a307059478d309b26c4115a224cfaf6", - "0bd770a74d1160f7c9f12cd5912a06eb" - "ff6adcae899d92191fe4305673ba2ffe" - "8fa3f1a4e5ad79f3f334b3b202b2173c" - "486ea37ce3d397ed034c7f9dfeb15c5e" - "927336d0441f4c4300e2cff0d0900b52" - "d3b4", - }, - { - // test 6 - "sha1", - "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", - "", - "", - 42, - "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01", - "0ac1af7002b3d761d1e55298da9d0506" - "b9ae52057220a306e07b6b87e8df21d0" - "ea00033de03984d34918" - }, - { - // test 7 - "sha1", - "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", - "", - "", - 42, - "2adccada18779e7c2077ad2eb19d3f3e731385dd", - "2c91117204d745f3500d636a62f64f0a" - "b3bae548aa53d423b0d1f27ebba6f5e5" - "673a081d70cce7acfc48", - }, -}; - -int test_hkdf(void) -{ - int i; - const DIGEST *digest; - uint8_t ikm[512]; - uint8_t salt[512]; - uint8_t info[512]; - uint8_t prk[512]; - uint8_t okm[512]; - size_t ikmlen, saltlen, infolen, prklen, okmlen; - size_t L; - uint8_t buf[512]; - size_t buflen; - size_t len; - - for (i = 0; i < sizeof(hkdf_tests)/sizeof(hkdf_tests[0]); i++) { - - digest = digest_from_name(hkdf_tests[i].algor); - hex_to_bytes(hkdf_tests[i].ikm, strlen(hkdf_tests[i].ikm), ikm, &len); - hex_to_bytes(hkdf_tests[i].salt, strlen(hkdf_tests[i].salt), salt, &len); - hex_to_bytes(hkdf_tests[i].info, strlen(hkdf_tests[i].info), info, &len); - hex_to_bytes(hkdf_tests[i].prk, strlen(hkdf_tests[i].prk), prk, &len); - hex_to_bytes(hkdf_tests[i].okm, strlen(hkdf_tests[i].okm), okm, &len); - ikmlen = strlen(hkdf_tests[i].ikm)/2; - saltlen = strlen(hkdf_tests[i].salt)/2; - infolen = strlen(hkdf_tests[i].info)/2; - prklen = strlen(hkdf_tests[i].prk)/2; - okmlen = strlen(hkdf_tests[i].okm)/2; - L = hkdf_tests[i].L; - - printf("test %d\n", i + 1); - format_print(stdout, 0, 0, "Hash = %s\n", digest_name(digest)); - format_bytes(stdout, 0, 0, "IKM = ", ikm, ikmlen); - format_bytes(stdout, 0, 0, "salt = ", salt, saltlen); - format_bytes(stdout, 0, 0, "info = ", info, infolen); - format_print(stdout, 0, 0, "L = %zu\n", L); - - if (hkdf_extract(digest, salt, saltlen, ikm, ikmlen, buf, &buflen) != 1) { - error_print(); - return -1; - } - format_bytes(stdout, 0, 0, "PRK = ", buf, buflen); - format_bytes(stdout, 0, 0, " = ", prk, prklen); - if (buflen != prklen || memcmp(buf, prk, prklen) != 0) { - error_print(); - return -1; - } - - if (hkdf_expand(digest, prk, prklen, info, infolen, L, buf) != 1) { - error_print(); - return -1; - } - format_bytes(stdout, 0, 0, "OKM = ", buf, L); - format_bytes(stdout, 0, 0, " = ", okm, okmlen); - if (L != okmlen || memcmp(buf, okm, okmlen) != 0) { - error_print(); - return -1; - } - - printf("\n"); - - } - return 0; -} - -int main(void) -{ - int err = 0; - err += test_hkdf(); - return err; -} + + +#include +#include +#include +#include +#include +#include + +static struct { + char *algor; + char *ikm; + char *salt; + char *info; + int L; + char *prk; + char *okm; +} hkdf_tests[] = { + { + // test 1 + "sha256", + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "000102030405060708090a0b0c", + "f0f1f2f3f4f5f6f7f8f9", + 42, + "077709362c2e32df0ddc3f0dc47bba63" + "90b6c73bb50f9c3122ec844ad7c2b3e5", + "3cb25f25faacd57a90434f64d0362f2a" + "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" + "34007208d5b887185865", + }, + { + // test 2 + "sha256", + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f", + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + 82, + "06a6b88c5853361a06104c9ceb35b45c" + "ef760014904671014a193f40c15fc244", + "b11e398dc80327a1c8e7f78c596a4934" + "4f012eda2d4efad8a050cc4c19afa97c" + "59045a99cac7827271cb41c65e590e09" + "da3275600c2f09b8367793a9aca3db71" + "cc30c58179ec3e87c14c01d5c1f3434f" + "1d87", + }, + { + // test 3 + "sha256", + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "", + "", + 42, + "19ef24a32c717b167f33a91d6f648bdf" + "96596776afdb6377ac434c1c293ccb04", + "8da4e775a563c18f715f802a063c5a31" + "b8a11f5c5ee1879ec3454e5f3c738d2d" + "9d201395faa4b61a96c8", + }, + { + // test 4 + "sha1", + "0b0b0b0b0b0b0b0b0b0b0b", + "000102030405060708090a0b0c", + "f0f1f2f3f4f5f6f7f8f9", + 42, + "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243", + "085a01ea1b10f36933068b56efa5ad81" + "a4f14b822f5b091568a9cdd4f155fda2" + "c22e422478d305f3f896", + }, + { + // test 5 + "sha1", + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f", + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + 82, + "8adae09a2a307059478d309b26c4115a224cfaf6", + "0bd770a74d1160f7c9f12cd5912a06eb" + "ff6adcae899d92191fe4305673ba2ffe" + "8fa3f1a4e5ad79f3f334b3b202b2173c" + "486ea37ce3d397ed034c7f9dfeb15c5e" + "927336d0441f4c4300e2cff0d0900b52" + "d3b4", + }, + { + // test 6 + "sha1", + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "", + "", + 42, + "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01", + "0ac1af7002b3d761d1e55298da9d0506" + "b9ae52057220a306e07b6b87e8df21d0" + "ea00033de03984d34918" + }, + { + // test 7 + "sha1", + "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", + "", + "", + 42, + "2adccada18779e7c2077ad2eb19d3f3e731385dd", + "2c91117204d745f3500d636a62f64f0a" + "b3bae548aa53d423b0d1f27ebba6f5e5" + "673a081d70cce7acfc48", + }, +}; + +int test_hkdf(void) +{ + int i; + const DIGEST *digest; + uint8_t ikm[512]; + uint8_t salt[512]; + uint8_t info[512]; + uint8_t prk[512]; + uint8_t okm[512]; + size_t ikmlen, saltlen, infolen, prklen, okmlen; + size_t L; + uint8_t buf[512]; + size_t buflen; + size_t len; + + for (i = 0; i < sizeof(hkdf_tests)/sizeof(hkdf_tests[0]); i++) { + + digest = digest_from_name(hkdf_tests[i].algor); + hex_to_bytes(hkdf_tests[i].ikm, strlen(hkdf_tests[i].ikm), ikm, &len); + hex_to_bytes(hkdf_tests[i].salt, strlen(hkdf_tests[i].salt), salt, &len); + hex_to_bytes(hkdf_tests[i].info, strlen(hkdf_tests[i].info), info, &len); + hex_to_bytes(hkdf_tests[i].prk, strlen(hkdf_tests[i].prk), prk, &len); + hex_to_bytes(hkdf_tests[i].okm, strlen(hkdf_tests[i].okm), okm, &len); + ikmlen = strlen(hkdf_tests[i].ikm)/2; + saltlen = strlen(hkdf_tests[i].salt)/2; + infolen = strlen(hkdf_tests[i].info)/2; + prklen = strlen(hkdf_tests[i].prk)/2; + okmlen = strlen(hkdf_tests[i].okm)/2; + L = hkdf_tests[i].L; + + printf("test %d\n", i + 1); + format_print(stdout, 0, 0, "Hash = %s\n", digest_name(digest)); + format_bytes(stdout, 0, 0, "IKM = ", ikm, ikmlen); + format_bytes(stdout, 0, 0, "salt = ", salt, saltlen); + format_bytes(stdout, 0, 0, "info = ", info, infolen); + format_print(stdout, 0, 0, "L = %zu\n", L); + + if (hkdf_extract(digest, salt, saltlen, ikm, ikmlen, buf, &buflen) != 1) { + error_print(); + return -1; + } + format_bytes(stdout, 0, 0, "PRK = ", buf, buflen); + format_bytes(stdout, 0, 0, " = ", prk, prklen); + if (buflen != prklen || memcmp(buf, prk, prklen) != 0) { + error_print(); + return -1; + } + + if (hkdf_expand(digest, prk, prklen, info, infolen, L, buf) != 1) { + error_print(); + return -1; + } + format_bytes(stdout, 0, 0, "OKM = ", buf, L); + format_bytes(stdout, 0, 0, " = ", okm, okmlen); + if (L != okmlen || memcmp(buf, okm, okmlen) != 0) { + error_print(); + return -1; + } + + printf("\n"); + + } + return 0; +} + +int main(void) +{ + int err = 0; + err += test_hkdf(); + return err; +} diff --git a/tests/hmactest.c b/tests/hmactest.c index 404f81b5..735f4046 100644 --- a/tests/hmactest.c +++ b/tests/hmactest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,114 +7,115 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -// FIXME: md5, sha1, sm3 test vectors - - -struct { - char *key; - char *data; - char *hmac_sha224; - char *hmac_sha256; - char *hmac_sha384; - char *hmac_sha512; -} hmac_tests[] = { - - // rfc 4231 test vectors - { - "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" - "0b0b0b0b", - "4869205468657265", - "896fb1128abbdf196832107cd49df33f" - "47b4b1169912ba4f53684b22", - "b0344c61d8db38535ca8afceaf0bf12b" - "881dc200c9833da726e9376c2e32cff7", - "afd03944d84895626b0825f4ab46907f" - "15f9dadbe4101ec682aa034c7cebc59c" - "faea9ea9076ede7f4af152e8b2fa9cb6", - "87aa7cdea5ef619d4ff0b4241a1d6cb0" - "2379f4e2ce4ec2787ad0b30545e17cde" - "daa833b7d6b8a702038b274eaea3f4e4" - "be9d914eeb61f1702e696c203a126854", - }, - { - "4a656665", - "7768617420646f2079612077616e7420" - "666f72206e6f7468696e673f", - "a30e01098bc6dbbf45690f3a7e9e6d0f" - "8bbea2a39e6148008fd05e44", - "5bdcc146bf60754e6a042426089575c7" - "5a003f089d2739839dec58b964ec3843", - "af45d2e376484031617f78d2b58a6b1b" - "9c7ef464f5a01b47e42ec3736322445e" - "8e2240ca5e69e2c78b3239ecfab21649", - "164b7a7bfcf819e2e395fbe73b56e0a3" - "87bd64222e831fd610270cd7ea250554" - "9758bf75c05a994a6d034f65f8f0e6fd" - "caeab1a34d4a6b4b636e070a38bce737", - }, - { - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaa", - "dddddddddddddddddddddddddddddddd" - "dddddddddddddddddddddddddddddddd" - "dddddddddddddddddddddddddddddddd" - "dddd", - "7fb3cb3588c6c1f6ffa9694d7d6ad264" - "9365b0c1f65d69d1ec8333ea", - "773ea91e36800e46854db8ebd09181a7" - "2959098b3ef8c122d9635514ced565fe", - "88062608d3e6ad8a0aa2ace014c8a86f" - "0aa635d947ac9febe83ef4e55966144b" - "2a5ab39dc13814b94e3ab6e101a34f27", - "fa73b0089d56a284efb0f0756c890be9" - "b1b5dbdd8ee81a3655f83e33b2279d39" - "bf3e848279a722c806b485a47e67c807" - "b946a337bee8942674278859e13292fb", - }, -}; - -int test_hmac(const DIGEST *digest, const char *key_hex, const char *data_hex, const char *hmac_hex) -{ - HMAC_CTX ctx; - uint8_t key[strlen(key_hex)/2]; - uint8_t data[strlen(data_hex)/2]; - uint8_t hmac[strlen(hmac_hex)/2]; - uint8_t buf[64]; - size_t len; - - hex_to_bytes(key_hex, strlen(key_hex), key, &len); - hex_to_bytes(data_hex, strlen(data_hex), data, &len); - hex_to_bytes(hmac_hex, strlen(hmac_hex), hmac, &len); - - hmac_init(&ctx, digest, key, sizeof(key)); - hmac_update(&ctx, data, sizeof(data)); - hmac_finish(&ctx, buf, &len); - - if (len != sizeof(hmac) || memcmp(buf, hmac, sizeof(hmac)) != 0) { - printf("failed\n"); - return 0; - } - printf("ok\n"); - return 1; -} - -int main(void) -{ - int i; - for (i = 0; i < sizeof(hmac_tests)/sizeof(hmac_tests[0]); i++) { - test_hmac(DIGEST_sha224(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha224); - test_hmac(DIGEST_sha256(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha256); - test_hmac(DIGEST_sha384(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha384); - test_hmac(DIGEST_sha512(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha512); - }; - - return 0; -}; + + +#include +#include +#include +#include +#include + + +// FIXME: md5, sha1, sm3 test vectors + + +struct { + char *key; + char *data; + char *hmac_sha224; + char *hmac_sha256; + char *hmac_sha384; + char *hmac_sha512; +} hmac_tests[] = { + + // rfc 4231 test vectors + { + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b", + "4869205468657265", + "896fb1128abbdf196832107cd49df33f" + "47b4b1169912ba4f53684b22", + "b0344c61d8db38535ca8afceaf0bf12b" + "881dc200c9833da726e9376c2e32cff7", + "afd03944d84895626b0825f4ab46907f" + "15f9dadbe4101ec682aa034c7cebc59c" + "faea9ea9076ede7f4af152e8b2fa9cb6", + "87aa7cdea5ef619d4ff0b4241a1d6cb0" + "2379f4e2ce4ec2787ad0b30545e17cde" + "daa833b7d6b8a702038b274eaea3f4e4" + "be9d914eeb61f1702e696c203a126854", + }, + { + "4a656665", + "7768617420646f2079612077616e7420" + "666f72206e6f7468696e673f", + "a30e01098bc6dbbf45690f3a7e9e6d0f" + "8bbea2a39e6148008fd05e44", + "5bdcc146bf60754e6a042426089575c7" + "5a003f089d2739839dec58b964ec3843", + "af45d2e376484031617f78d2b58a6b1b" + "9c7ef464f5a01b47e42ec3736322445e" + "8e2240ca5e69e2c78b3239ecfab21649", + "164b7a7bfcf819e2e395fbe73b56e0a3" + "87bd64222e831fd610270cd7ea250554" + "9758bf75c05a994a6d034f65f8f0e6fd" + "caeab1a34d4a6b4b636e070a38bce737", + }, + { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa", + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd", + "7fb3cb3588c6c1f6ffa9694d7d6ad264" + "9365b0c1f65d69d1ec8333ea", + "773ea91e36800e46854db8ebd09181a7" + "2959098b3ef8c122d9635514ced565fe", + "88062608d3e6ad8a0aa2ace014c8a86f" + "0aa635d947ac9febe83ef4e55966144b" + "2a5ab39dc13814b94e3ab6e101a34f27", + "fa73b0089d56a284efb0f0756c890be9" + "b1b5dbdd8ee81a3655f83e33b2279d39" + "bf3e848279a722c806b485a47e67c807" + "b946a337bee8942674278859e13292fb", + }, +}; + +int test_hmac(const DIGEST *digest, const char *key_hex, const char *data_hex, const char *hmac_hex) +{ + HMAC_CTX ctx; + uint8_t key[strlen(key_hex)/2]; + uint8_t data[strlen(data_hex)/2]; + uint8_t hmac[strlen(hmac_hex)/2]; + uint8_t buf[64]; + size_t len; + + hex_to_bytes(key_hex, strlen(key_hex), key, &len); + hex_to_bytes(data_hex, strlen(data_hex), data, &len); + hex_to_bytes(hmac_hex, strlen(hmac_hex), hmac, &len); + + hmac_init(&ctx, digest, key, sizeof(key)); + hmac_update(&ctx, data, sizeof(data)); + hmac_finish(&ctx, buf, &len); + + if (len != sizeof(hmac) || memcmp(buf, hmac, sizeof(hmac)) != 0) { + printf("failed\n"); + return 0; + } + printf("ok\n"); + return 1; +} + +int main(void) +{ + int i; + for (i = 0; i < sizeof(hmac_tests)/sizeof(hmac_tests[0]); i++) { + test_hmac(DIGEST_sha224(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha224); + test_hmac(DIGEST_sha256(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha256); + test_hmac(DIGEST_sha384(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha384); + test_hmac(DIGEST_sha512(), hmac_tests[i].key, hmac_tests[i].data, hmac_tests[i].hmac_sha512); + }; + + return 0; +}; diff --git a/tests/md5test.c b/tests/md5test.c index 04111692..5dd3f56a 100644 --- a/tests/md5test.c +++ b/tests/md5test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,63 +7,64 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -static char *teststr[] = { - "", - "a", - "abc", - "message digest", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", -}; - -static char *dgsthex[] = { - "d41d8cd98f00b204e9800998ecf8427e", - "0cc175b9c0f1b6a831c399e269772661", - "900150983cd24fb0d6963f7d28e17f72", - "f96b697d7cb7938d525a2f31aaf161d0", - "c3fcd3d76192e4007dfb496cca67e13b", - "d174ab98d277d9f5a5611c2c9f419d9f", - "57edf4a22be3c955ac49da2e2107b67a", -}; - -int main(int argc, char **argv) -{ - int err = 0; - char *p; - uint8_t dgst[16]; - uint8_t dgstbuf[16]; - size_t dgstbuflen; - size_t i; - - for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { - hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); - md5_digest((uint8_t *)teststr[i], strlen(teststr[i]), dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - int n; - printf("error calculating MD5 on %s\n", teststr[i]); - printf(" digest(corret) = "); - for (n = 0; n < sizeof(dgst); n++) { - printf("%02X", dgst[n]); - } - printf("\n"); - printf(" digest(error) = %s\n", dgsthex[i]); - err++; - } else { - printf("md5 test %lu ok\n", i+1); - } - } - - return err; -} + + + +#include +#include +#include +#include +#include +#include + + +static char *teststr[] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", +}; + +static char *dgsthex[] = { + "d41d8cd98f00b204e9800998ecf8427e", + "0cc175b9c0f1b6a831c399e269772661", + "900150983cd24fb0d6963f7d28e17f72", + "f96b697d7cb7938d525a2f31aaf161d0", + "c3fcd3d76192e4007dfb496cca67e13b", + "d174ab98d277d9f5a5611c2c9f419d9f", + "57edf4a22be3c955ac49da2e2107b67a", +}; + +int main(int argc, char **argv) +{ + int err = 0; + char *p; + uint8_t dgst[16]; + uint8_t dgstbuf[16]; + size_t dgstbuflen; + size_t i; + + for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); + md5_digest((uint8_t *)teststr[i], strlen(teststr[i]), dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + int n; + printf("error calculating MD5 on %s\n", teststr[i]); + printf(" digest(corret) = "); + for (n = 0; n < sizeof(dgst); n++) { + printf("%02X", dgst[n]); + } + printf("\n"); + printf(" digest(error) = %s\n", dgsthex[i]); + err++; + } else { + printf("md5 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/pbkdf2test.c b/tests/pbkdf2test.c index 57f8b602..32339896 100644 --- a/tests/pbkdf2test.c +++ b/tests/pbkdf2test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,130 +7,131 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -struct { - char *pass; - char *salt; - int iter; - int dklen; - char *dk; -} pbkdf2_hmac_sha1_tests[] = { - - // rfc 6070 test vectors for pbkdf2-hmac-sha1 - { - "password", - "salt", - 1, - 20, - "0c60c80f961f0e71f3a9b524af6012062fe037a6", - }, - { - "password", - "salt", - 2, - 20, - "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", - }, - { - "password", - "salt", - 4096, - 20, - "4b007901b765489abead49d926f721d065a429c1", - }, - /* - { - "password", - "salt", - 16777216, // very slow - 20, - "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", - }, - */ - { - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 25, - "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", - }, -}; - -/* -void test(void) -{ - HMAC_CTX ctx; - uint8_t iter[4] = {0, 0, 0, 1}; - uint8_t mac[20]; - size_t len; - int i; - - hmac_init(&ctx, DIGEST_sha1(), (uint8_t *)"password", 8); - hmac_update(&ctx, (uint8_t *)"salt", 4); - hmac_update(&ctx, iter, 4); - hmac_finish(&ctx, mac, &len); - - for (i = 1; i < 4096; i++) { - uint8_t buf[20]; - memset(&ctx, 0, sizeof(HMAC_CTX)); - hmac_init(&ctx, DIGEST_sha1(), (uint8_t *)"password", 8); - hmac_update(&ctx, mac, len); - hmac_finish(&ctx, buf, &len); - int j; - for (j = 0; j < len; j++) { - mac[j] ^= buf[j]; - } - } - - - for (i = 0; i < len; i++) { - printf("%02x", mac[i]); - } - printf("\n"); -} -*/ - -static int test_pbkdf2_genkey(void) -{ - int i; - uint8_t key[64]; - uint8_t buf[64]; - size_t len; - - for (i = 0; i < sizeof(pbkdf2_hmac_sha1_tests)/sizeof(pbkdf2_hmac_sha1_tests[0]); i++) { - hex_to_bytes(pbkdf2_hmac_sha1_tests[i].dk, strlen(pbkdf2_hmac_sha1_tests[i].dk), buf, &len); - - if (pbkdf2_genkey(DIGEST_sha1(), - pbkdf2_hmac_sha1_tests[i].pass, strlen(pbkdf2_hmac_sha1_tests[i].pass), - (uint8_t *)pbkdf2_hmac_sha1_tests[i].salt, strlen(pbkdf2_hmac_sha1_tests[i].salt), - pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key) != 1) { - error_print(); - return -1; - } - if (memcmp(key, buf, pbkdf2_hmac_sha1_tests[i].dklen) != 0) { - fprintf(stderr, "test_pbkdf2_genkey test %d failed\n", i); - return -1; - } else { - fprintf(stderr, "test_pbkdf2_genkey test %d ok\n", i); - } - } - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -int main(int argc, char **argv) -{ - int err = 0; - err += test_pbkdf2_genkey(); - return err; -} + + + +#include +#include +#include +#include +#include +#include + + +struct { + char *pass; + char *salt; + int iter; + int dklen; + char *dk; +} pbkdf2_hmac_sha1_tests[] = { + + // rfc 6070 test vectors for pbkdf2-hmac-sha1 + { + "password", + "salt", + 1, + 20, + "0c60c80f961f0e71f3a9b524af6012062fe037a6", + }, + { + "password", + "salt", + 2, + 20, + "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", + }, + { + "password", + "salt", + 4096, + 20, + "4b007901b765489abead49d926f721d065a429c1", + }, + /* + { + "password", + "salt", + 16777216, // very slow + 20, + "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", + }, + */ + { + "passwordPASSWORDpassword", + "saltSALTsaltSALTsaltSALTsaltSALTsalt", + 4096, + 25, + "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", + }, +}; + +/* +void test(void) +{ + HMAC_CTX ctx; + uint8_t iter[4] = {0, 0, 0, 1}; + uint8_t mac[20]; + size_t len; + int i; + + hmac_init(&ctx, DIGEST_sha1(), (uint8_t *)"password", 8); + hmac_update(&ctx, (uint8_t *)"salt", 4); + hmac_update(&ctx, iter, 4); + hmac_finish(&ctx, mac, &len); + + for (i = 1; i < 4096; i++) { + uint8_t buf[20]; + memset(&ctx, 0, sizeof(HMAC_CTX)); + hmac_init(&ctx, DIGEST_sha1(), (uint8_t *)"password", 8); + hmac_update(&ctx, mac, len); + hmac_finish(&ctx, buf, &len); + int j; + for (j = 0; j < len; j++) { + mac[j] ^= buf[j]; + } + } + + + for (i = 0; i < len; i++) { + printf("%02x", mac[i]); + } + printf("\n"); +} +*/ + +static int test_pbkdf2_genkey(void) +{ + int i; + uint8_t key[64]; + uint8_t buf[64]; + size_t len; + + for (i = 0; i < sizeof(pbkdf2_hmac_sha1_tests)/sizeof(pbkdf2_hmac_sha1_tests[0]); i++) { + hex_to_bytes(pbkdf2_hmac_sha1_tests[i].dk, strlen(pbkdf2_hmac_sha1_tests[i].dk), buf, &len); + + if (pbkdf2_genkey(DIGEST_sha1(), + pbkdf2_hmac_sha1_tests[i].pass, strlen(pbkdf2_hmac_sha1_tests[i].pass), + (uint8_t *)pbkdf2_hmac_sha1_tests[i].salt, strlen(pbkdf2_hmac_sha1_tests[i].salt), + pbkdf2_hmac_sha1_tests[i].iter, pbkdf2_hmac_sha1_tests[i].dklen, key) != 1) { + error_print(); + return -1; + } + if (memcmp(key, buf, pbkdf2_hmac_sha1_tests[i].dklen) != 0) { + fprintf(stderr, "test_pbkdf2_genkey test %d failed\n", i); + return -1; + } else { + fprintf(stderr, "test_pbkdf2_genkey test %d ok\n", i); + } + } + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +int main(int argc, char **argv) +{ + int err = 0; + err += test_pbkdf2_genkey(); + return err; +} diff --git a/tests/pemtest.c b/tests/pemtest.c index 88f896ab..7f1ea3be 100644 --- a/tests/pemtest.c +++ b/tests/pemtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,13 +7,14 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -int main(void) -{ - return 0; -} + + +#include +#include +#include +#include + +int main(void) +{ + return 0; +} diff --git a/tests/pkcs8test.c b/tests/pkcs8test.c index 09b7ad1e..ad00edd6 100644 --- a/tests/pkcs8test.c +++ b/tests/pkcs8test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,413 +7,414 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_pbkdf2_params(void) -{ - uint8_t salt[8] = {0}; - size_t saltlen; - int iter = 65536; - int keylen = 16; - int prf = OID_hmac_sm3; - - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *psalt; - - if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); - - p = buf; - cp = buf; - len = 0; - keylen = -1; - prf = -1; - if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); - - p = buf; - cp = buf; - len = 0; - keylen = -1; - prf = -1; - if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 - || pbkdf2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "PBKDF2-params\n"); - format_bytes(stderr, 0, 4, "salt", psalt, saltlen); - format_print(stderr, 0, 4, "iterationCount: %d\n", iter); - format_print(stderr, 0, 4, "keyLength: %d\n", keylen); - format_print(stderr, 0, 4, "prf: %d\n", prf); - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pbkdf2_algor(void) -{ - uint8_t salt[8] = {0}; - size_t saltlen; - int iter = 65536; - int keylen = 16; - int prf = OID_hmac_sm3; - - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *psalt; - - if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbkdf2_algor_print(stderr, 0, 0, "PBKDF2", d, dlen); - - p = buf; - cp = buf; - len = 0; - if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "PBKDF2\n"); - format_bytes(stderr, 0, 4, "salt", psalt, saltlen); - format_print(stderr, 0, 4, "iterationCount: %d\n", iter); - format_print(stderr, 0, 4, "keyLength: %d\n", keylen); - format_print(stderr, 0, 4, "prf: %d\n", prf); - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pbes2_enc_algor(void) -{ - int cipher = OID_sm4_cbc; - uint8_t iv[16] = {1}; - - uint8_t buf[128]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *piv; - size_t ivlen; - - if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbes2_enc_algor_print(stderr, 0, 0, "PBES2-Enc", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 - || pbes2_enc_algor_from_der(&cipher, &piv, &ivlen, &cp, &len) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == sizeof(iv)) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pbes2_params(void) -{ - uint8_t salt[8] = {0}; - size_t saltlen; - int iter = 65536; - int keylen = -1; - int prf = OID_hmac_sm3; - int cipher = OID_sm4_cbc; - uint8_t iv[16]; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *psalt; - const uint8_t *piv; - size_t ivlen; - - if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbes2_params_print(stderr, 0, 0, "PBES2-params", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 - || pbes2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 - || asn1_check(saltlen == sizeof(salt)) != 1 - || asn1_check(iter == 65536) != 1 - || asn1_check(keylen == -1) != 1 - || asn1_check(prf == OID_hmac_sm3) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == sizeof(iv)) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pbes2_algor(void) -{ - uint8_t salt[8] = {0}; - size_t saltlen; - int iter = 65536; - int keylen = -1; - int prf = OID_hmac_sm3; - int cipher = OID_sm4_cbc; - uint8_t iv[16]; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *psalt; - const uint8_t *piv; - size_t ivlen; - - if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pbes2_algor_print(stderr, 0, 0, "PBES2", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 - || pbes2_algor_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 - || asn1_check(saltlen == sizeof(salt)) != 1 - || asn1_check(iter == 65536) != 1 - || asn1_check(keylen == -1) != 1 - || asn1_check(prf == OID_hmac_sm3) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == sizeof(iv)) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pkcs8_enced_private_key_info(void) -{ - uint8_t salt[8] = { 1,0 }; - int iter = 65536; - int keylen = -1; - int prf = OID_hmac_sm3; - int cipher = OID_sm4_cbc; - uint8_t iv[16] = { 2,0 }; - uint8_t enced[128] = { 3,0 }; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - const uint8_t *psalt; - size_t saltlen; - const uint8_t *piv; - size_t ivlen; - const uint8_t *penced; - size_t encedlen; - - if (pkcs8_enced_private_key_info_to_der( - salt, sizeof(salt), iter, keylen, prf, - cipher, iv, sizeof(iv), - enced, sizeof(enced), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pkcs8_enced_private_key_info_print(stderr, 0, 0, "EncryptedPrivateKeyInfo", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (pkcs8_enced_private_key_info_to_der( - salt, sizeof(salt), iter, keylen, prf, - cipher, iv, sizeof(iv), - enced, sizeof(enced), &p, &len) != 1 - || pkcs8_enced_private_key_info_from_der( - &psalt, &saltlen, &iter, &keylen, &prf, - &cipher, &piv, &ivlen, - &penced, &encedlen, &cp, &len) != 1 - || asn1_check(saltlen == sizeof(salt)) != 1 - || asn1_check(keylen == -1) != 1 - || asn1_check(prf == OID_hmac_sm3) != 1 - || asn1_check(cipher == OID_sm4_cbc) != 1 - || asn1_check(ivlen == sizeof(iv)) != 1 - || asn1_check(encedlen == sizeof(enced)) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pkcs8(void) -{ - int err = 0; - SM2_KEY sm2_key; - SM2_KEY sm2_buf; - const uint8_t *attrs; - size_t attrslen; - uint8_t buf[1024]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - sm2_key_generate(&sm2_key); - memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); - sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - - if (sm2_private_key_info_encrypt_to_der(&sm2_key, "password", &p, &len) != 1) { - error_print(); - return -1; - } - { - const uint8_t *a = buf; - size_t alen = len; - const uint8_t *d; - size_t dlen; - if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 - || asn1_length_is_zero(alen) != 1) { - error_print(); - return -1; - } - pkcs8_enced_private_key_info_print(stderr, 0, 0, "test_pkcs8: 392", d, dlen); - fprintf(stderr, "\n"); - } - - memset(&sm2_key, 0, sizeof(sm2_key)); - if (sm2_private_key_info_decrypt_from_der(&sm2_key, &attrs, &attrslen, "password", &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - fprintf(stderr, "\n"); - sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_pkcs8_pem(void) -{ - int err = 0; - char *file = "test_pkcs8_pem.pem"; - char *pass = "password"; - SM2_KEY sm2_key; - SM2_KEY sm2_buf; - const uint8_t *attrs; - size_t attrs_len; - FILE *fp; - - sm2_key_generate(&sm2_key); - memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); - sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - - if (!(fp = fopen(file, "w")) - || sm2_private_key_info_encrypt_to_pem(&sm2_key, pass, fp) != 1) { - error_print(); - return -1; - } - fclose(fp); - - memset(&sm2_key, 0, sizeof(sm2_key)); - if (!(fp = fopen(file, "r")) - || sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, fp) != 1) { - error_print(); - return -1; - } - sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -int main(void) -{ - int err = 0; - /* - err += test_pbkdf2_params(); - err += test_pbkdf2_algor(); - err += test_pbes2_enc_algor(); - err += test_pbes2_params(); - err += test_pbes2_algor(); - err += test_pkcs8_enced_private_key_info(); - */ - err += test_pkcs8(); -// err += test_pkcs8_pem(); - return err; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_pbkdf2_params(void) +{ + uint8_t salt[8] = {0}; + size_t saltlen; + int iter = 65536; + int keylen = 16; + int prf = OID_hmac_sm3; + + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + keylen = -1; + prf = -1; + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbkdf2_params_print(stderr, 0, 0, "PBKDF2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + keylen = -1; + prf = -1; + if (pbkdf2_params_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || pbkdf2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "PBKDF2-params\n"); + format_bytes(stderr, 0, 4, "salt", psalt, saltlen); + format_print(stderr, 0, 4, "iterationCount: %d\n", iter); + format_print(stderr, 0, 4, "keyLength: %d\n", keylen); + format_print(stderr, 0, 4, "prf: %d\n", prf); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pbkdf2_algor(void) +{ + uint8_t salt[8] = {0}; + size_t saltlen; + int iter = 65536; + int keylen = 16; + int prf = OID_hmac_sm3; + + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + + if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbkdf2_algor_print(stderr, 0, 0, "PBKDF2", d, dlen); + + p = buf; + cp = buf; + len = 0; + if (pbkdf2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "PBKDF2\n"); + format_bytes(stderr, 0, 4, "salt", psalt, saltlen); + format_print(stderr, 0, 4, "iterationCount: %d\n", iter); + format_print(stderr, 0, 4, "keyLength: %d\n", keylen); + format_print(stderr, 0, 4, "prf: %d\n", prf); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pbes2_enc_algor(void) +{ + int cipher = OID_sm4_cbc; + uint8_t iv[16] = {1}; + + uint8_t buf[128]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbes2_enc_algor_print(stderr, 0, 0, "PBES2-Enc", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_enc_algor_to_der(cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_enc_algor_from_der(&cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pbes2_params(void) +{ + uint8_t salt[8] = {0}; + size_t saltlen; + int iter = 65536; + int keylen = -1; + int prf = OID_hmac_sm3; + int cipher = OID_sm4_cbc; + uint8_t iv[16]; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbes2_params_print(stderr, 0, 0, "PBES2-params", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_params_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_params_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(iter == 65536) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pbes2_algor(void) +{ + uint8_t salt[8] = {0}; + size_t saltlen; + int iter = 65536; + int keylen = -1; + int prf = OID_hmac_sm3; + int cipher = OID_sm4_cbc; + uint8_t iv[16]; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + const uint8_t *piv; + size_t ivlen; + + if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pbes2_algor_print(stderr, 0, 0, "PBES2", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pbes2_algor_to_der(salt, sizeof(salt), iter, keylen, prf, cipher, iv, sizeof(iv), &p, &len) != 1 + || pbes2_algor_from_der(&psalt, &saltlen, &iter, &keylen, &prf, &cipher, &piv, &ivlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(iter == 65536) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pkcs8_enced_private_key_info(void) +{ + uint8_t salt[8] = { 1,0 }; + int iter = 65536; + int keylen = -1; + int prf = OID_hmac_sm3; + int cipher = OID_sm4_cbc; + uint8_t iv[16] = { 2,0 }; + uint8_t enced[128] = { 3,0 }; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + const uint8_t *psalt; + size_t saltlen; + const uint8_t *piv; + size_t ivlen; + const uint8_t *penced; + size_t encedlen; + + if (pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, keylen, prf, + cipher, iv, sizeof(iv), + enced, sizeof(enced), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pkcs8_enced_private_key_info_print(stderr, 0, 0, "EncryptedPrivateKeyInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (pkcs8_enced_private_key_info_to_der( + salt, sizeof(salt), iter, keylen, prf, + cipher, iv, sizeof(iv), + enced, sizeof(enced), &p, &len) != 1 + || pkcs8_enced_private_key_info_from_der( + &psalt, &saltlen, &iter, &keylen, &prf, + &cipher, &piv, &ivlen, + &penced, &encedlen, &cp, &len) != 1 + || asn1_check(saltlen == sizeof(salt)) != 1 + || asn1_check(keylen == -1) != 1 + || asn1_check(prf == OID_hmac_sm3) != 1 + || asn1_check(cipher == OID_sm4_cbc) != 1 + || asn1_check(ivlen == sizeof(iv)) != 1 + || asn1_check(encedlen == sizeof(enced)) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pkcs8(void) +{ + int err = 0; + SM2_KEY sm2_key; + SM2_KEY sm2_buf; + const uint8_t *attrs; + size_t attrslen; + uint8_t buf[1024]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + sm2_key_generate(&sm2_key); + memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + if (sm2_private_key_info_encrypt_to_der(&sm2_key, "password", &p, &len) != 1) { + error_print(); + return -1; + } + { + const uint8_t *a = buf; + size_t alen = len; + const uint8_t *d; + size_t dlen; + if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1 + || asn1_length_is_zero(alen) != 1) { + error_print(); + return -1; + } + pkcs8_enced_private_key_info_print(stderr, 0, 0, "test_pkcs8: 392", d, dlen); + fprintf(stderr, "\n"); + } + + memset(&sm2_key, 0, sizeof(sm2_key)); + if (sm2_private_key_info_decrypt_from_der(&sm2_key, &attrs, &attrslen, "password", &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + fprintf(stderr, "\n"); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_pkcs8_pem(void) +{ + int err = 0; + char *file = "test_pkcs8_pem.pem"; + char *pass = "password"; + SM2_KEY sm2_key; + SM2_KEY sm2_buf; + const uint8_t *attrs; + size_t attrs_len; + FILE *fp; + + sm2_key_generate(&sm2_key); + memcpy(&sm2_buf, &sm2_key, sizeof(sm2_key)); + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + if (!(fp = fopen(file, "w")) + || sm2_private_key_info_encrypt_to_pem(&sm2_key, pass, fp) != 1) { + error_print(); + return -1; + } + fclose(fp); + + memset(&sm2_key, 0, sizeof(sm2_key)); + if (!(fp = fopen(file, "r")) + || sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, fp) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 0, "SM2_KEY", &sm2_key); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +int main(void) +{ + int err = 0; + /* + err += test_pbkdf2_params(); + err += test_pbkdf2_algor(); + err += test_pbes2_enc_algor(); + err += test_pbes2_params(); + err += test_pbes2_algor(); + err += test_pkcs8_enced_private_key_info(); + */ + err += test_pkcs8(); +// err += test_pkcs8_pem(); + return err; +} diff --git a/tests/rc4test.c b/tests/rc4test.c index 9265fe71..860d7277 100644 --- a/tests/rc4test.c +++ b/tests/rc4test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,383 +7,384 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include - - -/* tests from RFC 6229 Test Vectors for the Stream Cipher RC4 */ - -unsigned char key1[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, -}; - -unsigned char key2[] = { - 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21, - 0xc1, 0x09, 0x16, 0x39, 0x08, 0xeb, 0xe5, 0x1d, - 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, - 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a, -}; - -int keybits[] = { - 40, - 56, - 64, - 80, - 128, - 192, - 256, -}; - -int testindex[] = { - 0, - 16, - 240, - 256, - 496, - 512, - 752, - 768, - 1008, - 1024, - 1520, - 1536, - 2032, - 2048, - 3056, - 3072, - 4080, - 4096, -}; - -unsigned char testdata1[][16 * 18] = { - { - 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27, 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8, - 0x69, 0x82, 0x94, 0x4f, 0x18, 0xfc, 0x82, 0xd5, 0x89, 0xc4, 0x03, 0xa4, 0x7a, 0x0d, 0x09, 0x19, - 0x28, 0xcb, 0x11, 0x32, 0xc9, 0x6c, 0xe2, 0x86, 0x42, 0x1d, 0xca, 0xad, 0xb8, 0xb6, 0x9e, 0xae, - 0x1c, 0xfc, 0xf6, 0x2b, 0x03, 0xed, 0xdb, 0x64, 0x1d, 0x77, 0xdf, 0xcf, 0x7f, 0x8d, 0x8c, 0x93, - 0x42, 0xb7, 0xd0, 0xcd, 0xd9, 0x18, 0xa8, 0xa3, 0x3d, 0xd5, 0x17, 0x81, 0xc8, 0x1f, 0x40, 0x41, - 0x64, 0x59, 0x84, 0x44, 0x32, 0xa7, 0xda, 0x92, 0x3c, 0xfb, 0x3e, 0xb4, 0x98, 0x06, 0x61, 0xf6, - 0xec, 0x10, 0x32, 0x7b, 0xde, 0x2b, 0xee, 0xfd, 0x18, 0xf9, 0x27, 0x76, 0x80, 0x45, 0x7e, 0x22, - 0xeb, 0x62, 0x63, 0x8d, 0x4f, 0x0b, 0xa1, 0xfe, 0x9f, 0xca, 0x20, 0xe0, 0x5b, 0xf8, 0xff, 0x2b, - 0x45, 0x12, 0x90, 0x48, 0xe6, 0xa0, 0xed, 0x0b, 0x56, 0xb4, 0x90, 0x33, 0x8f, 0x07, 0x8d, 0xa5, - 0x30, 0xab, 0xbc, 0xc7, 0xc2, 0x0b, 0x01, 0x60, 0x9f, 0x23, 0xee, 0x2d, 0x5f, 0x6b, 0xb7, 0xdf, - 0x32, 0x94, 0xf7, 0x44, 0xd8, 0xf9, 0x79, 0x05, 0x07, 0xe7, 0x0f, 0x62, 0xe5, 0xbb, 0xce, 0xea, - 0xd8, 0x72, 0x9d, 0xb4, 0x18, 0x82, 0x25, 0x9b, 0xee, 0x4f, 0x82, 0x53, 0x25, 0xf5, 0xa1, 0x30, - 0x1e, 0xb1, 0x4a, 0x0c, 0x13, 0xb3, 0xbf, 0x47, 0xfa, 0x2a, 0x0b, 0xa9, 0x3a, 0xd4, 0x5b, 0x8b, - 0xcc, 0x58, 0x2f, 0x8b, 0xa9, 0xf2, 0x65, 0xe2, 0xb1, 0xbe, 0x91, 0x12, 0xe9, 0x75, 0xd2, 0xd7, - 0xf2, 0xe3, 0x0f, 0x9b, 0xd1, 0x02, 0xec, 0xbf, 0x75, 0xaa, 0xad, 0xe9, 0xbc, 0x35, 0xc4, 0x3c, - 0xec, 0x0e, 0x11, 0xc4, 0x79, 0xdc, 0x32, 0x9d, 0xc8, 0xda, 0x79, 0x68, 0xfe, 0x96, 0x56, 0x81, - 0x06, 0x83, 0x26, 0xa2, 0x11, 0x84, 0x16, 0xd2, 0x1f, 0x9d, 0x04, 0xb2, 0xcd, 0x1c, 0xa0, 0x50, - 0xff, 0x25, 0xb5, 0x89, 0x95, 0x99, 0x67, 0x07, 0xe5, 0x1f, 0xbd, 0xf0, 0x8b, 0x34, 0xd8, 0x75, - }, - { - 0x29, 0x3f, 0x02, 0xd4, 0x7f, 0x37, 0xc9, 0xb6, 0x33, 0xf2, 0xaf, 0x52, 0x85, 0xfe, 0xb4, 0x6b, - 0xe6, 0x20, 0xf1, 0x39, 0x0d, 0x19, 0xbd, 0x84, 0xe2, 0xe0, 0xfd, 0x75, 0x20, 0x31, 0xaf, 0xc1, - 0x91, 0x4f, 0x02, 0x53, 0x1c, 0x92, 0x18, 0x81, 0x0d, 0xf6, 0x0f, 0x67, 0xe3, 0x38, 0x15, 0x4c, - 0xd0, 0xfd, 0xb5, 0x83, 0x07, 0x3c, 0xe8, 0x5a, 0xb8, 0x39, 0x17, 0x74, 0x0e, 0xc0, 0x11, 0xd5, - 0x75, 0xf8, 0x14, 0x11, 0xe8, 0x71, 0xcf, 0xfa, 0x70, 0xb9, 0x0c, 0x74, 0xc5, 0x92, 0xe4, 0x54, - 0x0b, 0xb8, 0x72, 0x02, 0x93, 0x8d, 0xad, 0x60, 0x9e, 0x87, 0xa5, 0xa1, 0xb0, 0x79, 0xe5, 0xe4, - 0xc2, 0x91, 0x12, 0x46, 0xb6, 0x12, 0xe7, 0xe7, 0xb9, 0x03, 0xdf, 0xed, 0xa1, 0xda, 0xd8, 0x66, - 0x32, 0x82, 0x8f, 0x91, 0x50, 0x2b, 0x62, 0x91, 0x36, 0x8d, 0xe8, 0x08, 0x1d, 0xe3, 0x6f, 0xc2, - 0xf3, 0xb9, 0xa7, 0xe3, 0xb2, 0x97, 0xbf, 0x9a, 0xd8, 0x04, 0x51, 0x2f, 0x90, 0x63, 0xef, 0xf1, - 0x8e, 0xcb, 0x67, 0xa9, 0xba, 0x1f, 0x55, 0xa5, 0xa0, 0x67, 0xe2, 0xb0, 0x26, 0xa3, 0x67, 0x6f, - 0xd2, 0xaa, 0x90, 0x2b, 0xd4, 0x2d, 0x0d, 0x7c, 0xfd, 0x34, 0x0c, 0xd4, 0x58, 0x10, 0x52, 0x9f, - 0x78, 0xb2, 0x72, 0xc9, 0x6e, 0x42, 0xea, 0xb4, 0xc6, 0x0b, 0xd9, 0x14, 0xe3, 0x9d, 0x06, 0xe3, - 0xf4, 0x33, 0x2f, 0xd3, 0x1a, 0x07, 0x93, 0x96, 0xee, 0x3c, 0xee, 0x3f, 0x2a, 0x4f, 0xf0, 0x49, - 0x05, 0x45, 0x97, 0x81, 0xd4, 0x1f, 0xda, 0x7f, 0x30, 0xc1, 0xbe, 0x7e, 0x12, 0x46, 0xc6, 0x23, - 0xad, 0xfd, 0x38, 0x68, 0xb8, 0xe5, 0x14, 0x85, 0xd5, 0xe6, 0x10, 0x01, 0x7e, 0x3d, 0xd6, 0x09, - 0xad, 0x26, 0x58, 0x1c, 0x0c, 0x5b, 0xe4, 0x5f, 0x4c, 0xea, 0x01, 0xdb, 0x2f, 0x38, 0x05, 0xd5, - 0xf3, 0x17, 0x2c, 0xef, 0xfc, 0x3b, 0x3d, 0x99, 0x7c, 0x85, 0xcc, 0xd5, 0xaf, 0x1a, 0x95, 0x0c, - 0xe7, 0x4b, 0x0b, 0x97, 0x31, 0x22, 0x7f, 0xd3, 0x7c, 0x0e, 0xc0, 0x8a, 0x47, 0xdd, 0xd8, 0xb8, - }, - { - 0x97, 0xab, 0x8a, 0x1b, 0xf0, 0xaf, 0xb9, 0x61, 0x32, 0xf2, 0xf6, 0x72, 0x58, 0xda, 0x15, 0xa8, - 0x82, 0x63, 0xef, 0xdb, 0x45, 0xc4, 0xa1, 0x86, 0x84, 0xef, 0x87, 0xe6, 0xb1, 0x9e, 0x5b, 0x09, - 0x96, 0x36, 0xeb, 0xc9, 0x84, 0x19, 0x26, 0xf4, 0xf7, 0xd1, 0xf3, 0x62, 0xbd, 0xdf, 0x6e, 0x18, - 0xd0, 0xa9, 0x90, 0xff, 0x2c, 0x05, 0xfe, 0xf5, 0xb9, 0x03, 0x73, 0xc9, 0xff, 0x4b, 0x87, 0x0a, - 0x73, 0x23, 0x9f, 0x1d, 0xb7, 0xf4, 0x1d, 0x80, 0xb6, 0x43, 0xc0, 0xc5, 0x25, 0x18, 0xec, 0x63, - 0x16, 0x3b, 0x31, 0x99, 0x23, 0xa6, 0xbd, 0xb4, 0x52, 0x7c, 0x62, 0x61, 0x26, 0x70, 0x3c, 0x0f, - 0x49, 0xd6, 0xc8, 0xaf, 0x0f, 0x97, 0x14, 0x4a, 0x87, 0xdf, 0x21, 0xd9, 0x14, 0x72, 0xf9, 0x66, - 0x44, 0x17, 0x3a, 0x10, 0x3b, 0x66, 0x16, 0xc5, 0xd5, 0xad, 0x1c, 0xee, 0x40, 0xc8, 0x63, 0xd0, - 0x27, 0x3c, 0x9c, 0x4b, 0x27, 0xf3, 0x22, 0xe4, 0xe7, 0x16, 0xef, 0x53, 0xa4, 0x7d, 0xe7, 0xa4, - 0xc6, 0xd0, 0xe7, 0xb2, 0x26, 0x25, 0x9f, 0xa9, 0x02, 0x34, 0x90, 0xb2, 0x61, 0x67, 0xad, 0x1d, - 0x1f, 0xe8, 0x98, 0x67, 0x13, 0xf0, 0x7c, 0x3d, 0x9a, 0xe1, 0xc1, 0x63, 0xff, 0x8c, 0xf9, 0xd3, - 0x83, 0x69, 0xe1, 0xa9, 0x65, 0x61, 0x0b, 0xe8, 0x87, 0xfb, 0xd0, 0xc7, 0x91, 0x62, 0xaa, 0xfb, - 0x0a, 0x01, 0x27, 0xab, 0xb4, 0x44, 0x84, 0xb9, 0xfb, 0xef, 0x5a, 0xbc, 0xae, 0x1b, 0x57, 0x9f, - 0xc2, 0xcd, 0xad, 0xc6, 0x40, 0x2e, 0x8e, 0xe8, 0x66, 0xe1, 0xf3, 0x7b, 0xdb, 0x47, 0xe4, 0x2c, - 0x26, 0xb5, 0x1e, 0xa3, 0x7d, 0xf8, 0xe1, 0xd6, 0xf7, 0x6f, 0xc3, 0xb6, 0x6a, 0x74, 0x29, 0xb3, - 0xbc, 0x76, 0x83, 0x20, 0x5d, 0x4f, 0x44, 0x3d, 0xc1, 0xf2, 0x9d, 0xda, 0x33, 0x15, 0xc8, 0x7b, - 0xd5, 0xfa, 0x5a, 0x34, 0x69, 0xd2, 0x9a, 0xaa, 0xf8, 0x3d, 0x23, 0x58, 0x9d, 0xb8, 0xc8, 0x5b, - 0x3f, 0xb4, 0x6e, 0x2c, 0x8f, 0x0f, 0x06, 0x8e, 0xdc, 0xe8, 0xcd, 0xcd, 0x7d, 0xfc, 0x58, 0x62, - }, - { - 0xed, 0xe3, 0xb0, 0x46, 0x43, 0xe5, 0x86, 0xcc, 0x90, 0x7d, 0xc2, 0x18, 0x51, 0x70, 0x99, 0x02, - 0x03, 0x51, 0x6b, 0xa7, 0x8f, 0x41, 0x3b, 0xeb, 0x22, 0x3a, 0xa5, 0xd4, 0xd2, 0xdf, 0x67, 0x11, - 0x3c, 0xfd, 0x6c, 0xb5, 0x8e, 0xe0, 0xfd, 0xde, 0x64, 0x01, 0x76, 0xad, 0x00, 0x00, 0x04, 0x4d, - 0x48, 0x53, 0x2b, 0x21, 0xfb, 0x60, 0x79, 0xc9, 0x11, 0x4c, 0x0f, 0xfd, 0x9c, 0x04, 0xa1, 0xad, - 0x3e, 0x8c, 0xea, 0x98, 0x01, 0x71, 0x09, 0x97, 0x90, 0x84, 0xb1, 0xef, 0x92, 0xf9, 0x9d, 0x86, - 0xe2, 0x0f, 0xb4, 0x9b, 0xdb, 0x33, 0x7e, 0xe4, 0x8b, 0x8d, 0x8d, 0xc0, 0xf4, 0xaf, 0xef, 0xfe, - 0x5c, 0x25, 0x21, 0xea, 0xcd, 0x79, 0x66, 0xf1, 0x5e, 0x05, 0x65, 0x44, 0xbe, 0xa0, 0xd3, 0x15, - 0xe0, 0x67, 0xa7, 0x03, 0x19, 0x31, 0xa2, 0x46, 0xa6, 0xc3, 0x87, 0x5d, 0x2f, 0x67, 0x8a, 0xcb, - 0xa6, 0x4f, 0x70, 0xaf, 0x88, 0xae, 0x56, 0xb6, 0xf8, 0x75, 0x81, 0xc0, 0xe2, 0x3e, 0x6b, 0x08, - 0xf4, 0x49, 0x03, 0x1d, 0xe3, 0x12, 0x81, 0x4e, 0xc6, 0xf3, 0x19, 0x29, 0x1f, 0x4a, 0x05, 0x16, - 0xbd, 0xae, 0x85, 0x92, 0x4b, 0x3c, 0xb1, 0xd0, 0xa2, 0xe3, 0x3a, 0x30, 0xc6, 0xd7, 0x95, 0x99, - 0x8a, 0x0f, 0xed, 0xdb, 0xac, 0x86, 0x5a, 0x09, 0xbc, 0xd1, 0x27, 0xfb, 0x56, 0x2e, 0xd6, 0x0a, - 0xb5, 0x5a, 0x0a, 0x5b, 0x51, 0xa1, 0x2a, 0x8b, 0xe3, 0x48, 0x99, 0xc3, 0xe0, 0x47, 0x51, 0x1a, - 0xd9, 0xa0, 0x9c, 0xea, 0x3c, 0xe7, 0x5f, 0xe3, 0x96, 0x98, 0x07, 0x03, 0x17, 0xa7, 0x13, 0x39, - 0x55, 0x22, 0x25, 0xed, 0x11, 0x77, 0xf4, 0x45, 0x84, 0xac, 0x8c, 0xfa, 0x6c, 0x4e, 0xb5, 0xfc, - 0x7e, 0x82, 0xcb, 0xab, 0xfc, 0x95, 0x38, 0x1b, 0x08, 0x09, 0x98, 0x44, 0x21, 0x29, 0xc2, 0xf8, - 0x1f, 0x13, 0x5e, 0xd1, 0x4c, 0xe6, 0x0a, 0x91, 0x36, 0x9d, 0x23, 0x22, 0xbe, 0xf2, 0x5e, 0x3c, - 0x08, 0xb6, 0xbe, 0x45, 0x12, 0x4a, 0x43, 0xe2, 0xeb, 0x77, 0x95, 0x3f, 0x84, 0xdc, 0x85, 0x53, - }, - { - 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7, 0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97, - 0x52, 0x48, 0xc4, 0x95, 0x90, 0x14, 0x12, 0x6a, 0x6e, 0x8a, 0x84, 0xf1, 0x1d, 0x1a, 0x9e, 0x1c, - 0x06, 0x59, 0x02, 0xe4, 0xb6, 0x20, 0xf6, 0xcc, 0x36, 0xc8, 0x58, 0x9f, 0x66, 0x43, 0x2f, 0x2b, - 0xd3, 0x9d, 0x56, 0x6b, 0xc6, 0xbc, 0xe3, 0x01, 0x07, 0x68, 0x15, 0x15, 0x49, 0xf3, 0x87, 0x3f, - 0xb6, 0xd1, 0xe6, 0xc4, 0xa5, 0xe4, 0x77, 0x1c, 0xad, 0x79, 0x53, 0x8d, 0xf2, 0x95, 0xfb, 0x11, - 0xc6, 0x8c, 0x1d, 0x5c, 0x55, 0x9a, 0x97, 0x41, 0x23, 0xdf, 0x1d, 0xbc, 0x52, 0xa4, 0x3b, 0x89, - 0xc5, 0xec, 0xf8, 0x8d, 0xe8, 0x97, 0xfd, 0x57, 0xfe, 0xd3, 0x01, 0x70, 0x1b, 0x82, 0xa2, 0x59, - 0xec, 0xcb, 0xe1, 0x3d, 0xe1, 0xfc, 0xc9, 0x1c, 0x11, 0xa0, 0xb2, 0x6c, 0x0b, 0xc8, 0xfa, 0x4d, - 0xe7, 0xa7, 0x25, 0x74, 0xf8, 0x78, 0x2a, 0xe2, 0x6a, 0xab, 0xcf, 0x9e, 0xbc, 0xd6, 0x60, 0x65, - 0xbd, 0xf0, 0x32, 0x4e, 0x60, 0x83, 0xdc, 0xc6, 0xd3, 0xce, 0xdd, 0x3c, 0xa8, 0xc5, 0x3c, 0x16, - 0xb4, 0x01, 0x10, 0xc4, 0x19, 0x0b, 0x56, 0x22, 0xa9, 0x61, 0x16, 0xb0, 0x01, 0x7e, 0xd2, 0x97, - 0xff, 0xa0, 0xb5, 0x14, 0x64, 0x7e, 0xc0, 0x4f, 0x63, 0x06, 0xb8, 0x92, 0xae, 0x66, 0x11, 0x81, - 0xd0, 0x3d, 0x1b, 0xc0, 0x3c, 0xd3, 0x3d, 0x70, 0xdf, 0xf9, 0xfa, 0x5d, 0x71, 0x96, 0x3e, 0xbd, - 0x8a, 0x44, 0x12, 0x64, 0x11, 0xea, 0xa7, 0x8b, 0xd5, 0x1e, 0x8d, 0x87, 0xa8, 0x87, 0x9b, 0xf5, - 0xfa, 0xbe, 0xb7, 0x60, 0x28, 0xad, 0xe2, 0xd0, 0xe4, 0x87, 0x22, 0xe4, 0x6c, 0x46, 0x15, 0xa3, - 0xc0, 0x5d, 0x88, 0xab, 0xd5, 0x03, 0x57, 0xf9, 0x35, 0xa6, 0x3c, 0x59, 0xee, 0x53, 0x76, 0x23, - 0xff, 0x38, 0x26, 0x5c, 0x16, 0x42, 0xc1, 0xab, 0xe8, 0xd3, 0xc2, 0xfe, 0x5e, 0x57, 0x2b, 0xf8, - 0xa3, 0x6a, 0x4c, 0x30, 0x1a, 0xe8, 0xac, 0x13, 0x61, 0x0c, 0xcb, 0xc1, 0x22, 0x56, 0xca, 0xcc, - }, - { - 0x05, 0x95, 0xe5, 0x7f, 0xe5, 0xf0, 0xbb, 0x3c, 0x70, 0x6e, 0xda, 0xc8, 0xa4, 0xb2, 0xdb, 0x11, - 0xdf, 0xde, 0x31, 0x34, 0x4a, 0x1a, 0xf7, 0x69, 0xc7, 0x4f, 0x07, 0x0a, 0xee, 0x9e, 0x23, 0x26, - 0xb0, 0x6b, 0x9b, 0x1e, 0x19, 0x5d, 0x13, 0xd8, 0xf4, 0xa7, 0x99, 0x5c, 0x45, 0x53, 0xac, 0x05, - 0x6b, 0xd2, 0x37, 0x8e, 0xc3, 0x41, 0xc9, 0xa4, 0x2f, 0x37, 0xba, 0x79, 0xf8, 0x8a, 0x32, 0xff, - 0xe7, 0x0b, 0xce, 0x1d, 0xf7, 0x64, 0x5a, 0xdb, 0x5d, 0x2c, 0x41, 0x30, 0x21, 0x5c, 0x35, 0x22, - 0x9a, 0x57, 0x30, 0xc7, 0xfc, 0xb4, 0xc9, 0xaf, 0x51, 0xff, 0xda, 0x89, 0xc7, 0xf1, 0xad, 0x22, - 0x04, 0x85, 0x05, 0x5f, 0xd4, 0xf6, 0xf0, 0xd9, 0x63, 0xef, 0x5a, 0xb9, 0xa5, 0x47, 0x69, 0x82, - 0x59, 0x1f, 0xc6, 0x6b, 0xcd, 0xa1, 0x0e, 0x45, 0x2b, 0x03, 0xd4, 0x55, 0x1f, 0x6b, 0x62, 0xac, - 0x27, 0x53, 0xcc, 0x83, 0x98, 0x8a, 0xfa, 0x3e, 0x16, 0x88, 0xa1, 0xd3, 0xb4, 0x2c, 0x9a, 0x02, - 0x93, 0x61, 0x0d, 0x52, 0x3d, 0x1d, 0x3f, 0x00, 0x62, 0xb3, 0xc2, 0xa3, 0xbb, 0xc7, 0xc7, 0xf0, - 0x96, 0xc2, 0x48, 0x61, 0x0a, 0xad, 0xed, 0xfe, 0xaf, 0x89, 0x78, 0xc0, 0x3d, 0xe8, 0x20, 0x5a, - 0x0e, 0x31, 0x7b, 0x3d, 0x1c, 0x73, 0xb9, 0xe9, 0xa4, 0x68, 0x8f, 0x29, 0x6d, 0x13, 0x3a, 0x19, - 0xbd, 0xf0, 0xe6, 0xc3, 0xcc, 0xa5, 0xb5, 0xb9, 0xd5, 0x33, 0xb6, 0x9c, 0x56, 0xad, 0xa1, 0x20, - 0x88, 0xa2, 0x18, 0xb6, 0xe2, 0xec, 0xe1, 0xe6, 0x24, 0x6d, 0x44, 0xc7, 0x59, 0xd1, 0x9b, 0x10, - 0x68, 0x66, 0x39, 0x7e, 0x95, 0xc1, 0x40, 0x53, 0x4f, 0x94, 0x26, 0x34, 0x21, 0x00, 0x6e, 0x40, - 0x32, 0xcb, 0x0a, 0x1e, 0x95, 0x42, 0xc6, 0xb3, 0xb8, 0xb3, 0x98, 0xab, 0xc3, 0xb0, 0xf1, 0xd5, - 0x29, 0xa0, 0xb8, 0xae, 0xd5, 0x4a, 0x13, 0x23, 0x24, 0xc6, 0x2e, 0x42, 0x3f, 0x54, 0xb4, 0xc8, - 0x3c, 0xb0, 0xf3, 0xb5, 0x02, 0x0a, 0x98, 0xb8, 0x2a, 0xf9, 0xfe, 0x15, 0x44, 0x84, 0xa1, 0x68, - }, - { - 0xea, 0xa6, 0xbd, 0x25, 0x88, 0x0b, 0xf9, 0x3d, 0x3f, 0x5d, 0x1e, 0x4c, 0xa2, 0x61, 0x1d, 0x91, - 0xcf, 0xa4, 0x5c, 0x9f, 0x7e, 0x71, 0x4b, 0x54, 0xbd, 0xfa, 0x80, 0x02, 0x7c, 0xb1, 0x43, 0x80, - 0x11, 0x4a, 0xe3, 0x44, 0xde, 0xd7, 0x1b, 0x35, 0xf2, 0xe6, 0x0f, 0xeb, 0xad, 0x72, 0x7f, 0xd8, - 0x02, 0xe1, 0xe7, 0x05, 0x6b, 0x0f, 0x62, 0x39, 0x00, 0x49, 0x64, 0x22, 0x94, 0x3e, 0x97, 0xb6, - 0x91, 0xcb, 0x93, 0xc7, 0x87, 0x96, 0x4e, 0x10, 0xd9, 0x52, 0x7d, 0x99, 0x9c, 0x6f, 0x93, 0x6b, - 0x49, 0xb1, 0x8b, 0x42, 0xf8, 0xe8, 0x36, 0x7c, 0xbe, 0xb5, 0xef, 0x10, 0x4b, 0xa1, 0xc7, 0xcd, - 0x87, 0x08, 0x4b, 0x3b, 0xa7, 0x00, 0xba, 0xde, 0x95, 0x56, 0x10, 0x67, 0x27, 0x45, 0xb3, 0x74, - 0xe7, 0xa7, 0xb9, 0xe9, 0xec, 0x54, 0x0d, 0x5f, 0xf4, 0x3b, 0xdb, 0x12, 0x79, 0x2d, 0x1b, 0x35, - 0xc7, 0x99, 0xb5, 0x96, 0x73, 0x8f, 0x6b, 0x01, 0x8c, 0x76, 0xc7, 0x4b, 0x17, 0x59, 0xbd, 0x90, - 0x7f, 0xec, 0x5b, 0xfd, 0x9f, 0x9b, 0x89, 0xce, 0x65, 0x48, 0x30, 0x90, 0x92, 0xd7, 0xe9, 0x58, - 0x40, 0xf2, 0x50, 0xb2, 0x6d, 0x1f, 0x09, 0x6a, 0x4a, 0xfd, 0x4c, 0x34, 0x0a, 0x58, 0x88, 0x15, - 0x3e, 0x34, 0x13, 0x5c, 0x79, 0xdb, 0x01, 0x02, 0x00, 0x76, 0x76, 0x51, 0xcf, 0x26, 0x30, 0x73, - 0xf6, 0x56, 0xab, 0xcc, 0xf8, 0x8d, 0xd8, 0x27, 0x02, 0x7b, 0x2c, 0xe9, 0x17, 0xd4, 0x64, 0xec, - 0x18, 0xb6, 0x25, 0x03, 0xbf, 0xbc, 0x07, 0x7f, 0xba, 0xbb, 0x98, 0xf2, 0x0d, 0x98, 0xab, 0x34, - 0x8a, 0xed, 0x95, 0xee, 0x5b, 0x0d, 0xcb, 0xfb, 0xef, 0x4e, 0xb2, 0x1d, 0x3a, 0x3f, 0x52, 0xf9, - 0x62, 0x5a, 0x1a, 0xb0, 0x0e, 0xe3, 0x9a, 0x53, 0x27, 0x34, 0x6b, 0xdd, 0xb0, 0x1a, 0x9c, 0x18, - 0xa1, 0x3a, 0x7c, 0x79, 0xc7, 0xe1, 0x19, 0xb5, 0xab, 0x02, 0x96, 0xab, 0x28, 0xc3, 0x00, 0xb9, - 0xf3, 0xe4, 0xc0, 0xa2, 0xe0, 0x2d, 0x1d, 0x01, 0xf7, 0xf0, 0xa7, 0x46, 0x18, 0xaf, 0x2b, 0x48, - }, -}; - -unsigned char testdata2[][16 * 18] = { - { - 0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a, 0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda, - 0x20, 0xf0, 0x60, 0xc2, 0xf2, 0xe5, 0x12, 0x65, 0x01, 0xd3, 0xd4, 0xfe, 0xa1, 0x0d, 0x5f, 0xc0, - 0xfa, 0xa1, 0x48, 0xe9, 0x90, 0x46, 0x18, 0x1f, 0xec, 0x6b, 0x20, 0x85, 0xf3, 0xb2, 0x0e, 0xd9, - 0xf0, 0xda, 0xf5, 0xba, 0xb3, 0xd5, 0x96, 0x83, 0x98, 0x57, 0x84, 0x6f, 0x73, 0xfb, 0xfe, 0x5a, - 0x1c, 0x7e, 0x2f, 0xc4, 0x63, 0x92, 0x32, 0xfe, 0x29, 0x75, 0x84, 0xb2, 0x96, 0x99, 0x6b, 0xc8, - 0x3d, 0xb9, 0xb2, 0x49, 0x40, 0x6c, 0xc8, 0xed, 0xff, 0xac, 0x55, 0xcc, 0xd3, 0x22, 0xba, 0x12, - 0xe4, 0xf9, 0xf7, 0xe0, 0x06, 0x61, 0x54, 0xbb, 0xd1, 0x25, 0xb7, 0x45, 0x56, 0x9b, 0xc8, 0x97, - 0x75, 0xd5, 0xef, 0x26, 0x2b, 0x44, 0xc4, 0x1a, 0x9c, 0xf6, 0x3a, 0xe1, 0x45, 0x68, 0xe1, 0xb9, - 0x6d, 0xa4, 0x53, 0xdb, 0xf8, 0x1e, 0x82, 0x33, 0x4a, 0x3d, 0x88, 0x66, 0xcb, 0x50, 0xa1, 0xe3, - 0x78, 0x28, 0xd0, 0x74, 0x11, 0x9c, 0xab, 0x5c, 0x22, 0xb2, 0x94, 0xd7, 0xa9, 0xbf, 0xa0, 0xbb, - 0xad, 0xb8, 0x9c, 0xea, 0x9a, 0x15, 0xfb, 0xe6, 0x17, 0x29, 0x5b, 0xd0, 0x4b, 0x8c, 0xa0, 0x5c, - 0x62, 0x51, 0xd8, 0x7f, 0xd4, 0xaa, 0xae, 0x9a, 0x7e, 0x4a, 0xd5, 0xc2, 0x17, 0xd3, 0xf3, 0x00, - 0xe7, 0x11, 0x9b, 0xd6, 0xdd, 0x9b, 0x22, 0xaf, 0xe8, 0xf8, 0x95, 0x85, 0x43, 0x28, 0x81, 0xe2, - 0x78, 0x5b, 0x60, 0xfd, 0x7e, 0xc4, 0xe9, 0xfc, 0xb6, 0x54, 0x5f, 0x35, 0x0d, 0x66, 0x0f, 0xab, - 0xaf, 0xec, 0xc0, 0x37, 0xfd, 0xb7, 0xb0, 0x83, 0x8e, 0xb3, 0xd7, 0x0b, 0xcd, 0x26, 0x83, 0x82, - 0xdb, 0xc1, 0xa7, 0xb4, 0x9d, 0x57, 0x35, 0x8c, 0xc9, 0xfa, 0x6d, 0x61, 0xd7, 0x3b, 0x7c, 0xf0, - 0x63, 0x49, 0xd1, 0x26, 0xa3, 0x7a, 0xfc, 0xba, 0x89, 0x79, 0x4f, 0x98, 0x04, 0x91, 0x4f, 0xdc, - 0xbf, 0x42, 0xc3, 0x01, 0x8c, 0x2f, 0x7c, 0x66, 0xbf, 0xde, 0x52, 0x49, 0x75, 0x76, 0x81, 0x15, - }, - { - 0xbc, 0x92, 0x22, 0xdb, 0xd3, 0x27, 0x4d, 0x8f, 0xc6, 0x6d, 0x14, 0xcc, 0xbd, 0xa6, 0x69, 0x0b, - 0x7a, 0xe6, 0x27, 0x41, 0x0c, 0x9a, 0x2b, 0xe6, 0x93, 0xdf, 0x5b, 0xb7, 0x48, 0x5a, 0x63, 0xe3, - 0x3f, 0x09, 0x31, 0xaa, 0x03, 0xde, 0xfb, 0x30, 0x0f, 0x06, 0x01, 0x03, 0x82, 0x6f, 0x2a, 0x64, - 0xbe, 0xaa, 0x9e, 0xc8, 0xd5, 0x9b, 0xb6, 0x81, 0x29, 0xf3, 0x02, 0x7c, 0x96, 0x36, 0x11, 0x81, - 0x74, 0xe0, 0x4d, 0xb4, 0x6d, 0x28, 0x64, 0x8d, 0x7d, 0xee, 0x8a, 0x00, 0x64, 0xb0, 0x6c, 0xfe, - 0x9b, 0x5e, 0x81, 0xc6, 0x2f, 0xe0, 0x23, 0xc5, 0x5b, 0xe4, 0x2f, 0x87, 0xbb, 0xf9, 0x32, 0xb8, - 0xce, 0x17, 0x8f, 0xc1, 0x82, 0x6e, 0xfe, 0xcb, 0xc1, 0x82, 0xf5, 0x79, 0x99, 0xa4, 0x61, 0x40, - 0x8b, 0xdf, 0x55, 0xcd, 0x55, 0x06, 0x1c, 0x06, 0xdb, 0xa6, 0xbe, 0x11, 0xde, 0x4a, 0x57, 0x8a, - 0x62, 0x6f, 0x5f, 0x4d, 0xce, 0x65, 0x25, 0x01, 0xf3, 0x08, 0x7d, 0x39, 0xc9, 0x2c, 0xc3, 0x49, - 0x42, 0xda, 0xac, 0x6a, 0x8f, 0x9a, 0xb9, 0xa7, 0xfd, 0x13, 0x7c, 0x60, 0x37, 0x82, 0x56, 0x82, - 0xcc, 0x03, 0xfd, 0xb7, 0x91, 0x92, 0xa2, 0x07, 0x31, 0x2f, 0x53, 0xf5, 0xd4, 0xdc, 0x33, 0xd9, - 0xf7, 0x0f, 0x14, 0x12, 0x2a, 0x1c, 0x98, 0xa3, 0x15, 0x5d, 0x28, 0xb8, 0xa0, 0xa8, 0xa4, 0x1d, - 0x2a, 0x3a, 0x30, 0x7a, 0xb2, 0x70, 0x8a, 0x9c, 0x00, 0xfe, 0x0b, 0x42, 0xf9, 0xc2, 0xd6, 0xa1, - 0x86, 0x26, 0x17, 0x62, 0x7d, 0x22, 0x61, 0xea, 0xb0, 0xb1, 0x24, 0x65, 0x97, 0xca, 0x0a, 0xe9, - 0x55, 0xf8, 0x77, 0xce, 0x4f, 0x2e, 0x1d, 0xdb, 0xbf, 0x8e, 0x13, 0xe2, 0xcd, 0xe0, 0xfd, 0xc8, - 0x1b, 0x15, 0x56, 0xcb, 0x93, 0x5f, 0x17, 0x33, 0x37, 0x70, 0x5f, 0xbb, 0x5d, 0x50, 0x1f, 0xc1, - 0xec, 0xd0, 0xe9, 0x66, 0x02, 0xbe, 0x7f, 0x8d, 0x50, 0x92, 0x81, 0x6c, 0xcc, 0xf2, 0xc2, 0xe9, - 0x02, 0x78, 0x81, 0xfa, 0xb4, 0x99, 0x3a, 0x1c, 0x26, 0x20, 0x24, 0xa9, 0x4f, 0xff, 0x3f, 0x61, - }, - { - 0xbb, 0xf6, 0x09, 0xde, 0x94, 0x13, 0x17, 0x2d, 0x07, 0x66, 0x0c, 0xb6, 0x80, 0x71, 0x69, 0x26, - 0x46, 0x10, 0x1a, 0x6d, 0xab, 0x43, 0x11, 0x5d, 0x6c, 0x52, 0x2b, 0x4f, 0xe9, 0x36, 0x04, 0xa9, - 0xcb, 0xe1, 0xff, 0xf2, 0x1c, 0x96, 0xf3, 0xee, 0xf6, 0x1e, 0x8f, 0xe0, 0x54, 0x2c, 0xbd, 0xf0, - 0x34, 0x79, 0x38, 0xbf, 0xfa, 0x40, 0x09, 0xc5, 0x12, 0xcf, 0xb4, 0x03, 0x4b, 0x0d, 0xd1, 0xa7, - 0x78, 0x67, 0xa7, 0x86, 0xd0, 0x0a, 0x71, 0x47, 0x90, 0x4d, 0x76, 0xdd, 0xf1, 0xe5, 0x20, 0xe3, - 0x8d, 0x3e, 0x9e, 0x1c, 0xae, 0xfc, 0xcc, 0xb3, 0xfb, 0xf8, 0xd1, 0x8f, 0x64, 0x12, 0x0b, 0x32, - 0x94, 0x23, 0x37, 0xf8, 0xfd, 0x76, 0xf0, 0xfa, 0xe8, 0xc5, 0x2d, 0x79, 0x54, 0x81, 0x06, 0x72, - 0xb8, 0x54, 0x8c, 0x10, 0xf5, 0x16, 0x67, 0xf6, 0xe6, 0x0e, 0x18, 0x2f, 0xa1, 0x9b, 0x30, 0xf7, - 0x02, 0x11, 0xc7, 0xc6, 0x19, 0x0c, 0x9e, 0xfd, 0x12, 0x37, 0xc3, 0x4c, 0x8f, 0x2e, 0x06, 0xc4, - 0xbd, 0xa6, 0x4f, 0x65, 0x27, 0x6d, 0x2a, 0xac, 0xb8, 0xf9, 0x02, 0x12, 0x20, 0x3a, 0x80, 0x8e, - 0xbd, 0x38, 0x20, 0xf7, 0x32, 0xff, 0xb5, 0x3e, 0xc1, 0x93, 0xe7, 0x9d, 0x33, 0xe2, 0x7c, 0x73, - 0xd0, 0x16, 0x86, 0x16, 0x86, 0x19, 0x07, 0xd4, 0x82, 0xe3, 0x6c, 0xda, 0xc8, 0xcf, 0x57, 0x49, - 0x97, 0xb0, 0xf0, 0xf2, 0x24, 0xb2, 0xd2, 0x31, 0x71, 0x14, 0x80, 0x8f, 0xb0, 0x3a, 0xf7, 0xa0, - 0xe5, 0x96, 0x16, 0xe4, 0x69, 0x78, 0x79, 0x39, 0xa0, 0x63, 0xce, 0xea, 0x9a, 0xf9, 0x56, 0xd1, - 0xc4, 0x7e, 0x0d, 0xc1, 0x66, 0x09, 0x19, 0xc1, 0x11, 0x01, 0x20, 0x8f, 0x9e, 0x69, 0xaa, 0x1f, - 0x5a, 0xe4, 0xf1, 0x28, 0x96, 0xb8, 0x37, 0x9a, 0x2a, 0xad, 0x89, 0xb5, 0xb5, 0x53, 0xd6, 0xb0, - 0x6b, 0x6b, 0x09, 0x8d, 0x0c, 0x29, 0x3b, 0xc2, 0x99, 0x3d, 0x80, 0xbf, 0x05, 0x18, 0xb6, 0xd9, - 0x81, 0x70, 0xcc, 0x3c, 0xcd, 0x92, 0xa6, 0x98, 0x62, 0x1b, 0x93, 0x9d, 0xd3, 0x8f, 0xe7, 0xb9, - }, - { - 0xab, 0x65, 0xc2, 0x6e, 0xdd, 0xb2, 0x87, 0x60, 0x0d, 0xb2, 0xfd, 0xa1, 0x0d, 0x1e, 0x60, 0x5c, - 0xbb, 0x75, 0x90, 0x10, 0xc2, 0x96, 0x58, 0xf2, 0xc7, 0x2d, 0x93, 0xa2, 0xd1, 0x6d, 0x29, 0x30, - 0xb9, 0x01, 0xe8, 0x03, 0x6e, 0xd1, 0xc3, 0x83, 0xcd, 0x3c, 0x4c, 0x4d, 0xd0, 0xa6, 0xab, 0x05, - 0x3d, 0x25, 0xce, 0x49, 0x22, 0x92, 0x4c, 0x55, 0xf0, 0x64, 0x94, 0x33, 0x53, 0xd7, 0x8a, 0x6c, - 0x12, 0xc1, 0xaa, 0x44, 0xbb, 0xf8, 0x7e, 0x75, 0xe6, 0x11, 0xf6, 0x9b, 0x2c, 0x38, 0xf4, 0x9b, - 0x28, 0xf2, 0xb3, 0x43, 0x4b, 0x65, 0xc0, 0x98, 0x77, 0x47, 0x00, 0x44, 0xc6, 0xea, 0x17, 0x0d, - 0xbd, 0x9e, 0xf8, 0x22, 0xde, 0x52, 0x88, 0x19, 0x61, 0x34, 0xcf, 0x8a, 0xf7, 0x83, 0x93, 0x04, - 0x67, 0x55, 0x9c, 0x23, 0xf0, 0x52, 0x15, 0x84, 0x70, 0xa2, 0x96, 0xf7, 0x25, 0x73, 0x5a, 0x32, - 0x8b, 0xab, 0x26, 0xfb, 0xc2, 0xc1, 0x2b, 0x0f, 0x13, 0xe2, 0xab, 0x18, 0x5e, 0xab, 0xf2, 0x41, - 0x31, 0x18, 0x5a, 0x6d, 0x69, 0x6f, 0x0c, 0xfa, 0x9b, 0x42, 0x80, 0x8b, 0x38, 0xe1, 0x32, 0xa2, - 0x56, 0x4d, 0x3d, 0xae, 0x18, 0x3c, 0x52, 0x34, 0xc8, 0xaf, 0x1e, 0x51, 0x06, 0x1c, 0x44, 0xb5, - 0x3c, 0x07, 0x78, 0xa7, 0xb5, 0xf7, 0x2d, 0x3c, 0x23, 0xa3, 0x13, 0x5c, 0x7d, 0x67, 0xb9, 0xf4, - 0xf3, 0x43, 0x69, 0x89, 0x0f, 0xcf, 0x16, 0xfb, 0x51, 0x7d, 0xca, 0xae, 0x44, 0x63, 0xb2, 0xdd, - 0x02, 0xf3, 0x1c, 0x81, 0xe8, 0x20, 0x07, 0x31, 0xb8, 0x99, 0xb0, 0x28, 0xe7, 0x91, 0xbf, 0xa7, - 0x72, 0xda, 0x64, 0x62, 0x83, 0x22, 0x8c, 0x14, 0x30, 0x08, 0x53, 0x70, 0x17, 0x95, 0x61, 0x6f, - 0x4e, 0x0a, 0x8c, 0x6f, 0x79, 0x34, 0xa7, 0x88, 0xe2, 0x26, 0x5e, 0x81, 0xd6, 0xd0, 0xc8, 0xf4, - 0x43, 0x8d, 0xd5, 0xea, 0xfe, 0xa0, 0x11, 0x1b, 0x6f, 0x36, 0xb4, 0xb9, 0x38, 0xda, 0x2a, 0x68, - 0x5f, 0x6b, 0xfc, 0x73, 0x81, 0x58, 0x74, 0xd9, 0x71, 0x00, 0xf0, 0x86, 0x97, 0x93, 0x57, 0xd8, - }, - { - 0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1, 0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30, - 0xc3, 0x66, 0xfd, 0xea, 0xcf, 0x9c, 0xa8, 0x04, 0x36, 0xbe, 0x7c, 0x35, 0x84, 0x24, 0xd2, 0x0b, - 0xb3, 0x39, 0x4a, 0x40, 0xaa, 0xbf, 0x75, 0xcb, 0xa4, 0x22, 0x82, 0xef, 0x25, 0xa0, 0x05, 0x9f, - 0x48, 0x47, 0xd8, 0x1d, 0xa4, 0x94, 0x2d, 0xbc, 0x24, 0x9d, 0xef, 0xc4, 0x8c, 0x92, 0x2b, 0x9f, - 0x08, 0x12, 0x8c, 0x46, 0x9f, 0x27, 0x53, 0x42, 0xad, 0xda, 0x20, 0x2b, 0x2b, 0x58, 0xda, 0x95, - 0x97, 0x0d, 0xac, 0xef, 0x40, 0xad, 0x98, 0x72, 0x3b, 0xac, 0x5d, 0x69, 0x55, 0xb8, 0x17, 0x61, - 0x3c, 0xb8, 0x99, 0x93, 0xb0, 0x7b, 0x0c, 0xed, 0x93, 0xde, 0x13, 0xd2, 0xa1, 0x10, 0x13, 0xac, - 0xef, 0x2d, 0x67, 0x6f, 0x15, 0x45, 0xc2, 0xc1, 0x3d, 0xc6, 0x80, 0xa0, 0x2f, 0x4a, 0xdb, 0xfe, - 0xb6, 0x05, 0x95, 0x51, 0x4f, 0x24, 0xbc, 0x9f, 0xe5, 0x22, 0xa6, 0xca, 0xd7, 0x39, 0x36, 0x44, - 0xb5, 0x15, 0xa8, 0xc5, 0x01, 0x17, 0x54, 0xf5, 0x90, 0x03, 0x05, 0x8b, 0xdb, 0x81, 0x51, 0x4e, - 0x3c, 0x70, 0x04, 0x7e, 0x8c, 0xbc, 0x03, 0x8e, 0x3b, 0x98, 0x20, 0xdb, 0x60, 0x1d, 0xa4, 0x95, - 0x11, 0x75, 0xda, 0x6e, 0xe7, 0x56, 0xde, 0x46, 0xa5, 0x3e, 0x2b, 0x07, 0x56, 0x60, 0xb7, 0x70, - 0x00, 0xa5, 0x42, 0xbb, 0xa0, 0x21, 0x11, 0xcc, 0x2c, 0x65, 0xb3, 0x8e, 0xbd, 0xba, 0x58, 0x7e, - 0x58, 0x65, 0xfd, 0xbb, 0x5b, 0x48, 0x06, 0x41, 0x04, 0xe8, 0x30, 0xb3, 0x80, 0xf2, 0xae, 0xde, - 0x34, 0xb2, 0x1a, 0xd2, 0xad, 0x44, 0xe9, 0x99, 0xdb, 0x2d, 0x7f, 0x08, 0x63, 0xf0, 0xd9, 0xb6, - 0x84, 0xa9, 0x21, 0x8f, 0xc3, 0x6e, 0x8a, 0x5f, 0x2c, 0xcf, 0xbe, 0xae, 0x53, 0xa2, 0x7d, 0x25, - 0xa2, 0x22, 0x1a, 0x11, 0xb8, 0x33, 0xcc, 0xb4, 0x98, 0xa5, 0x95, 0x40, 0xf0, 0x54, 0x5f, 0x4a, - 0x5b, 0xbe, 0xb4, 0x78, 0x7d, 0x59, 0xe5, 0x37, 0x3f, 0xdb, 0xea, 0x6c, 0x6f, 0x75, 0xc2, 0x9b, - }, - { - 0x54, 0xb6, 0x4e, 0x6b, 0x5a, 0x20, 0xb5, 0xe2, 0xec, 0x84, 0x59, 0x3d, 0xc7, 0x98, 0x9d, 0xa7, - 0xc1, 0x35, 0xee, 0xe2, 0x37, 0xa8, 0x54, 0x65, 0xff, 0x97, 0xdc, 0x03, 0x92, 0x4f, 0x45, 0xce, - 0xcf, 0xcc, 0x92, 0x2f, 0xb4, 0xa1, 0x4a, 0xb4, 0x5d, 0x61, 0x75, 0xaa, 0xbb, 0xf2, 0xd2, 0x01, - 0x83, 0x7b, 0x87, 0xe2, 0xa4, 0x46, 0xad, 0x0e, 0xf7, 0x98, 0xac, 0xd0, 0x2b, 0x94, 0x12, 0x4f, - 0x17, 0xa6, 0xdb, 0xd6, 0x64, 0x92, 0x6a, 0x06, 0x36, 0xb3, 0xf4, 0xc3, 0x7a, 0x4f, 0x46, 0x94, - 0x4a, 0x5f, 0x9f, 0x26, 0xae, 0xee, 0xd4, 0xd4, 0xa2, 0x5f, 0x63, 0x2d, 0x30, 0x52, 0x33, 0xd9, - 0x80, 0xa3, 0xd0, 0x1e, 0xf0, 0x0c, 0x8e, 0x9a, 0x42, 0x09, 0xc1, 0x7f, 0x4e, 0xeb, 0x35, 0x8c, - 0xd1, 0x5e, 0x7d, 0x5f, 0xfa, 0xaa, 0xbc, 0x02, 0x07, 0xbf, 0x20, 0x0a, 0x11, 0x77, 0x93, 0xa2, - 0x34, 0x96, 0x82, 0xbf, 0x58, 0x8e, 0xaa, 0x52, 0xd0, 0xaa, 0x15, 0x60, 0x34, 0x6a, 0xea, 0xfa, - 0xf5, 0x85, 0x4c, 0xdb, 0x76, 0xc8, 0x89, 0xe3, 0xad, 0x63, 0x35, 0x4e, 0x5f, 0x72, 0x75, 0xe3, - 0x53, 0x2c, 0x7c, 0xec, 0xcb, 0x39, 0xdf, 0x32, 0x36, 0x31, 0x84, 0x05, 0xa4, 0xb1, 0x27, 0x9c, - 0xba, 0xef, 0xe6, 0xd9, 0xce, 0xb6, 0x51, 0x84, 0x22, 0x60, 0xe0, 0xd1, 0xe0, 0x5e, 0x3b, 0x90, - 0xe8, 0x2d, 0x8c, 0x6d, 0xb5, 0x4e, 0x3c, 0x63, 0x3f, 0x58, 0x1c, 0x95, 0x2b, 0xa0, 0x42, 0x07, - 0x4b, 0x16, 0xe5, 0x0a, 0xbd, 0x38, 0x1b, 0xd7, 0x09, 0x00, 0xa9, 0xcd, 0x9a, 0x62, 0xcb, 0x23, - 0x36, 0x82, 0xee, 0x33, 0xbd, 0x14, 0x8b, 0xd9, 0xf5, 0x86, 0x56, 0xcd, 0x8f, 0x30, 0xd9, 0xfb, - 0x1e, 0x5a, 0x0b, 0x84, 0x75, 0x04, 0x5d, 0x9b, 0x20, 0xb2, 0x62, 0x86, 0x24, 0xed, 0xfd, 0x9e, - 0x63, 0xed, 0xd6, 0x84, 0xfb, 0x82, 0x62, 0x82, 0xfe, 0x52, 0x8f, 0x9c, 0x0e, 0x92, 0x37, 0xbc, - 0xe4, 0xdd, 0x2e, 0x98, 0xd6, 0x96, 0x0f, 0xae, 0x0b, 0x43, 0x54, 0x54, 0x56, 0x74, 0x33, 0x91, - }, - { - 0xdd, 0x5b, 0xcb, 0x00, 0x18, 0xe9, 0x22, 0xd4, 0x94, 0x75, 0x9d, 0x7c, 0x39, 0x5d, 0x02, 0xd3, - 0xc8, 0x44, 0x6f, 0x8f, 0x77, 0xab, 0xf7, 0x37, 0x68, 0x53, 0x53, 0xeb, 0x89, 0xa1, 0xc9, 0xeb, - 0xaf, 0x3e, 0x30, 0xf9, 0xc0, 0x95, 0x04, 0x59, 0x38, 0x15, 0x15, 0x75, 0xc3, 0xfb, 0x90, 0x98, - 0xf8, 0xcb, 0x62, 0x74, 0xdb, 0x99, 0xb8, 0x0b, 0x1d, 0x20, 0x12, 0xa9, 0x8e, 0xd4, 0x8f, 0x0e, - 0x25, 0xc3, 0x00, 0x5a, 0x1c, 0xb8, 0x5d, 0xe0, 0x76, 0x25, 0x98, 0x39, 0xab, 0x71, 0x98, 0xab, - 0x9d, 0xcb, 0xc1, 0x83, 0xe8, 0xcb, 0x99, 0x4b, 0x72, 0x7b, 0x75, 0xbe, 0x31, 0x80, 0x76, 0x9c, - 0xa1, 0xd3, 0x07, 0x8d, 0xfa, 0x91, 0x69, 0x50, 0x3e, 0xd9, 0xd4, 0x49, 0x1d, 0xee, 0x4e, 0xb2, - 0x85, 0x14, 0xa5, 0x49, 0x58, 0x58, 0x09, 0x6f, 0x59, 0x6e, 0x4b, 0xcd, 0x66, 0xb1, 0x06, 0x65, - 0x5f, 0x40, 0xd5, 0x9e, 0xc1, 0xb0, 0x3b, 0x33, 0x73, 0x8e, 0xfa, 0x60, 0xb2, 0x25, 0x5d, 0x31, - 0x34, 0x77, 0xc7, 0xf7, 0x64, 0xa4, 0x1b, 0xac, 0xef, 0xf9, 0x0b, 0xf1, 0x4f, 0x92, 0xb7, 0xcc, - 0xac, 0x4e, 0x95, 0x36, 0x8d, 0x99, 0xb9, 0xeb, 0x78, 0xb8, 0xda, 0x8f, 0x81, 0xff, 0xa7, 0x95, - 0x8c, 0x3c, 0x13, 0xf8, 0xc2, 0x38, 0x8b, 0xb7, 0x3f, 0x38, 0x57, 0x6e, 0x65, 0xb7, 0xc4, 0x46, - 0x13, 0xc4, 0xb9, 0xc1, 0xdf, 0xb6, 0x65, 0x79, 0xed, 0xdd, 0x8a, 0x28, 0x0b, 0x9f, 0x73, 0x16, - 0xdd, 0xd2, 0x78, 0x20, 0x55, 0x01, 0x26, 0x69, 0x8e, 0xfa, 0xad, 0xc6, 0x4b, 0x64, 0xf6, 0x6e, - 0xf0, 0x8f, 0x2e, 0x66, 0xd2, 0x8e, 0xd1, 0x43, 0xf3, 0xa2, 0x37, 0xcf, 0x9d, 0xe7, 0x35, 0x59, - 0x9e, 0xa3, 0x6c, 0x52, 0x55, 0x31, 0xb8, 0x80, 0xba, 0x12, 0x43, 0x34, 0xf5, 0x7b, 0x0b, 0x70, - 0xd5, 0xa3, 0x9e, 0x3d, 0xfc, 0xc5, 0x02, 0x80, 0xba, 0xc4, 0xa6, 0xb5, 0xaa, 0x0d, 0xca, 0x7d, - 0x37, 0x0b, 0x1c, 0x1f, 0xe6, 0x55, 0x91, 0x6d, 0x97, 0xfd, 0x0d, 0x47, 0xca, 0x1d, 0x72, 0xb8, - }, -}; - -int main(void) -{ - int err = 0; - RC4_STATE state; - unsigned char buf[4096 + 16]; - size_t i, j; - - for (i = 0; i < sizeof(keybits)/sizeof(keybits[0]); i++) { - int e = 0; - rc4_init(&state, key1, keybits[i]/8); - rc4_generate_keystream(&state, sizeof(buf), buf); - for (j = 0; j < sizeof(testindex)/sizeof(testindex[0]); j++) { - if (memcmp(buf + testindex[j], &testdata1[i][j * 16], 16) != 0) { - e++; - } - } - fprintf(stderr, "rc4 test 1.%zu %s\n", i+1, e ? "failed" : "ok"); - if (e) { - err++; - } - } - - for (i = 0; i < sizeof(keybits)/sizeof(keybits[0]); i++) { - int e = 0; - rc4_init(&state, key2 + sizeof(key2) - keybits[i]/8, keybits[i]/8); - rc4_generate_keystream(&state, sizeof(buf), buf); - for (j = 0; j < sizeof(testindex)/sizeof(testindex[0]); j++) { - if (memcmp(buf + testindex[j], &testdata2[i][j * 16], 16) != 0) { - e++; - } - } - fprintf(stderr, "rc4 test 2.%zu %s\n", i+1, e ? "failed" : "ok"); - if (e) { - err++; - } - } - - return err; -} + + + +#include +#include +#include +#include + + +/* tests from RFC 6229 Test Vectors for the Stream Cipher RC4 */ + +unsigned char key1[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, +}; + +unsigned char key2[] = { + 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21, + 0xc1, 0x09, 0x16, 0x39, 0x08, 0xeb, 0xe5, 0x1d, + 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, + 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a, +}; + +int keybits[] = { + 40, + 56, + 64, + 80, + 128, + 192, + 256, +}; + +int testindex[] = { + 0, + 16, + 240, + 256, + 496, + 512, + 752, + 768, + 1008, + 1024, + 1520, + 1536, + 2032, + 2048, + 3056, + 3072, + 4080, + 4096, +}; + +unsigned char testdata1[][16 * 18] = { + { + 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27, 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8, + 0x69, 0x82, 0x94, 0x4f, 0x18, 0xfc, 0x82, 0xd5, 0x89, 0xc4, 0x03, 0xa4, 0x7a, 0x0d, 0x09, 0x19, + 0x28, 0xcb, 0x11, 0x32, 0xc9, 0x6c, 0xe2, 0x86, 0x42, 0x1d, 0xca, 0xad, 0xb8, 0xb6, 0x9e, 0xae, + 0x1c, 0xfc, 0xf6, 0x2b, 0x03, 0xed, 0xdb, 0x64, 0x1d, 0x77, 0xdf, 0xcf, 0x7f, 0x8d, 0x8c, 0x93, + 0x42, 0xb7, 0xd0, 0xcd, 0xd9, 0x18, 0xa8, 0xa3, 0x3d, 0xd5, 0x17, 0x81, 0xc8, 0x1f, 0x40, 0x41, + 0x64, 0x59, 0x84, 0x44, 0x32, 0xa7, 0xda, 0x92, 0x3c, 0xfb, 0x3e, 0xb4, 0x98, 0x06, 0x61, 0xf6, + 0xec, 0x10, 0x32, 0x7b, 0xde, 0x2b, 0xee, 0xfd, 0x18, 0xf9, 0x27, 0x76, 0x80, 0x45, 0x7e, 0x22, + 0xeb, 0x62, 0x63, 0x8d, 0x4f, 0x0b, 0xa1, 0xfe, 0x9f, 0xca, 0x20, 0xe0, 0x5b, 0xf8, 0xff, 0x2b, + 0x45, 0x12, 0x90, 0x48, 0xe6, 0xa0, 0xed, 0x0b, 0x56, 0xb4, 0x90, 0x33, 0x8f, 0x07, 0x8d, 0xa5, + 0x30, 0xab, 0xbc, 0xc7, 0xc2, 0x0b, 0x01, 0x60, 0x9f, 0x23, 0xee, 0x2d, 0x5f, 0x6b, 0xb7, 0xdf, + 0x32, 0x94, 0xf7, 0x44, 0xd8, 0xf9, 0x79, 0x05, 0x07, 0xe7, 0x0f, 0x62, 0xe5, 0xbb, 0xce, 0xea, + 0xd8, 0x72, 0x9d, 0xb4, 0x18, 0x82, 0x25, 0x9b, 0xee, 0x4f, 0x82, 0x53, 0x25, 0xf5, 0xa1, 0x30, + 0x1e, 0xb1, 0x4a, 0x0c, 0x13, 0xb3, 0xbf, 0x47, 0xfa, 0x2a, 0x0b, 0xa9, 0x3a, 0xd4, 0x5b, 0x8b, + 0xcc, 0x58, 0x2f, 0x8b, 0xa9, 0xf2, 0x65, 0xe2, 0xb1, 0xbe, 0x91, 0x12, 0xe9, 0x75, 0xd2, 0xd7, + 0xf2, 0xe3, 0x0f, 0x9b, 0xd1, 0x02, 0xec, 0xbf, 0x75, 0xaa, 0xad, 0xe9, 0xbc, 0x35, 0xc4, 0x3c, + 0xec, 0x0e, 0x11, 0xc4, 0x79, 0xdc, 0x32, 0x9d, 0xc8, 0xda, 0x79, 0x68, 0xfe, 0x96, 0x56, 0x81, + 0x06, 0x83, 0x26, 0xa2, 0x11, 0x84, 0x16, 0xd2, 0x1f, 0x9d, 0x04, 0xb2, 0xcd, 0x1c, 0xa0, 0x50, + 0xff, 0x25, 0xb5, 0x89, 0x95, 0x99, 0x67, 0x07, 0xe5, 0x1f, 0xbd, 0xf0, 0x8b, 0x34, 0xd8, 0x75, + }, + { + 0x29, 0x3f, 0x02, 0xd4, 0x7f, 0x37, 0xc9, 0xb6, 0x33, 0xf2, 0xaf, 0x52, 0x85, 0xfe, 0xb4, 0x6b, + 0xe6, 0x20, 0xf1, 0x39, 0x0d, 0x19, 0xbd, 0x84, 0xe2, 0xe0, 0xfd, 0x75, 0x20, 0x31, 0xaf, 0xc1, + 0x91, 0x4f, 0x02, 0x53, 0x1c, 0x92, 0x18, 0x81, 0x0d, 0xf6, 0x0f, 0x67, 0xe3, 0x38, 0x15, 0x4c, + 0xd0, 0xfd, 0xb5, 0x83, 0x07, 0x3c, 0xe8, 0x5a, 0xb8, 0x39, 0x17, 0x74, 0x0e, 0xc0, 0x11, 0xd5, + 0x75, 0xf8, 0x14, 0x11, 0xe8, 0x71, 0xcf, 0xfa, 0x70, 0xb9, 0x0c, 0x74, 0xc5, 0x92, 0xe4, 0x54, + 0x0b, 0xb8, 0x72, 0x02, 0x93, 0x8d, 0xad, 0x60, 0x9e, 0x87, 0xa5, 0xa1, 0xb0, 0x79, 0xe5, 0xe4, + 0xc2, 0x91, 0x12, 0x46, 0xb6, 0x12, 0xe7, 0xe7, 0xb9, 0x03, 0xdf, 0xed, 0xa1, 0xda, 0xd8, 0x66, + 0x32, 0x82, 0x8f, 0x91, 0x50, 0x2b, 0x62, 0x91, 0x36, 0x8d, 0xe8, 0x08, 0x1d, 0xe3, 0x6f, 0xc2, + 0xf3, 0xb9, 0xa7, 0xe3, 0xb2, 0x97, 0xbf, 0x9a, 0xd8, 0x04, 0x51, 0x2f, 0x90, 0x63, 0xef, 0xf1, + 0x8e, 0xcb, 0x67, 0xa9, 0xba, 0x1f, 0x55, 0xa5, 0xa0, 0x67, 0xe2, 0xb0, 0x26, 0xa3, 0x67, 0x6f, + 0xd2, 0xaa, 0x90, 0x2b, 0xd4, 0x2d, 0x0d, 0x7c, 0xfd, 0x34, 0x0c, 0xd4, 0x58, 0x10, 0x52, 0x9f, + 0x78, 0xb2, 0x72, 0xc9, 0x6e, 0x42, 0xea, 0xb4, 0xc6, 0x0b, 0xd9, 0x14, 0xe3, 0x9d, 0x06, 0xe3, + 0xf4, 0x33, 0x2f, 0xd3, 0x1a, 0x07, 0x93, 0x96, 0xee, 0x3c, 0xee, 0x3f, 0x2a, 0x4f, 0xf0, 0x49, + 0x05, 0x45, 0x97, 0x81, 0xd4, 0x1f, 0xda, 0x7f, 0x30, 0xc1, 0xbe, 0x7e, 0x12, 0x46, 0xc6, 0x23, + 0xad, 0xfd, 0x38, 0x68, 0xb8, 0xe5, 0x14, 0x85, 0xd5, 0xe6, 0x10, 0x01, 0x7e, 0x3d, 0xd6, 0x09, + 0xad, 0x26, 0x58, 0x1c, 0x0c, 0x5b, 0xe4, 0x5f, 0x4c, 0xea, 0x01, 0xdb, 0x2f, 0x38, 0x05, 0xd5, + 0xf3, 0x17, 0x2c, 0xef, 0xfc, 0x3b, 0x3d, 0x99, 0x7c, 0x85, 0xcc, 0xd5, 0xaf, 0x1a, 0x95, 0x0c, + 0xe7, 0x4b, 0x0b, 0x97, 0x31, 0x22, 0x7f, 0xd3, 0x7c, 0x0e, 0xc0, 0x8a, 0x47, 0xdd, 0xd8, 0xb8, + }, + { + 0x97, 0xab, 0x8a, 0x1b, 0xf0, 0xaf, 0xb9, 0x61, 0x32, 0xf2, 0xf6, 0x72, 0x58, 0xda, 0x15, 0xa8, + 0x82, 0x63, 0xef, 0xdb, 0x45, 0xc4, 0xa1, 0x86, 0x84, 0xef, 0x87, 0xe6, 0xb1, 0x9e, 0x5b, 0x09, + 0x96, 0x36, 0xeb, 0xc9, 0x84, 0x19, 0x26, 0xf4, 0xf7, 0xd1, 0xf3, 0x62, 0xbd, 0xdf, 0x6e, 0x18, + 0xd0, 0xa9, 0x90, 0xff, 0x2c, 0x05, 0xfe, 0xf5, 0xb9, 0x03, 0x73, 0xc9, 0xff, 0x4b, 0x87, 0x0a, + 0x73, 0x23, 0x9f, 0x1d, 0xb7, 0xf4, 0x1d, 0x80, 0xb6, 0x43, 0xc0, 0xc5, 0x25, 0x18, 0xec, 0x63, + 0x16, 0x3b, 0x31, 0x99, 0x23, 0xa6, 0xbd, 0xb4, 0x52, 0x7c, 0x62, 0x61, 0x26, 0x70, 0x3c, 0x0f, + 0x49, 0xd6, 0xc8, 0xaf, 0x0f, 0x97, 0x14, 0x4a, 0x87, 0xdf, 0x21, 0xd9, 0x14, 0x72, 0xf9, 0x66, + 0x44, 0x17, 0x3a, 0x10, 0x3b, 0x66, 0x16, 0xc5, 0xd5, 0xad, 0x1c, 0xee, 0x40, 0xc8, 0x63, 0xd0, + 0x27, 0x3c, 0x9c, 0x4b, 0x27, 0xf3, 0x22, 0xe4, 0xe7, 0x16, 0xef, 0x53, 0xa4, 0x7d, 0xe7, 0xa4, + 0xc6, 0xd0, 0xe7, 0xb2, 0x26, 0x25, 0x9f, 0xa9, 0x02, 0x34, 0x90, 0xb2, 0x61, 0x67, 0xad, 0x1d, + 0x1f, 0xe8, 0x98, 0x67, 0x13, 0xf0, 0x7c, 0x3d, 0x9a, 0xe1, 0xc1, 0x63, 0xff, 0x8c, 0xf9, 0xd3, + 0x83, 0x69, 0xe1, 0xa9, 0x65, 0x61, 0x0b, 0xe8, 0x87, 0xfb, 0xd0, 0xc7, 0x91, 0x62, 0xaa, 0xfb, + 0x0a, 0x01, 0x27, 0xab, 0xb4, 0x44, 0x84, 0xb9, 0xfb, 0xef, 0x5a, 0xbc, 0xae, 0x1b, 0x57, 0x9f, + 0xc2, 0xcd, 0xad, 0xc6, 0x40, 0x2e, 0x8e, 0xe8, 0x66, 0xe1, 0xf3, 0x7b, 0xdb, 0x47, 0xe4, 0x2c, + 0x26, 0xb5, 0x1e, 0xa3, 0x7d, 0xf8, 0xe1, 0xd6, 0xf7, 0x6f, 0xc3, 0xb6, 0x6a, 0x74, 0x29, 0xb3, + 0xbc, 0x76, 0x83, 0x20, 0x5d, 0x4f, 0x44, 0x3d, 0xc1, 0xf2, 0x9d, 0xda, 0x33, 0x15, 0xc8, 0x7b, + 0xd5, 0xfa, 0x5a, 0x34, 0x69, 0xd2, 0x9a, 0xaa, 0xf8, 0x3d, 0x23, 0x58, 0x9d, 0xb8, 0xc8, 0x5b, + 0x3f, 0xb4, 0x6e, 0x2c, 0x8f, 0x0f, 0x06, 0x8e, 0xdc, 0xe8, 0xcd, 0xcd, 0x7d, 0xfc, 0x58, 0x62, + }, + { + 0xed, 0xe3, 0xb0, 0x46, 0x43, 0xe5, 0x86, 0xcc, 0x90, 0x7d, 0xc2, 0x18, 0x51, 0x70, 0x99, 0x02, + 0x03, 0x51, 0x6b, 0xa7, 0x8f, 0x41, 0x3b, 0xeb, 0x22, 0x3a, 0xa5, 0xd4, 0xd2, 0xdf, 0x67, 0x11, + 0x3c, 0xfd, 0x6c, 0xb5, 0x8e, 0xe0, 0xfd, 0xde, 0x64, 0x01, 0x76, 0xad, 0x00, 0x00, 0x04, 0x4d, + 0x48, 0x53, 0x2b, 0x21, 0xfb, 0x60, 0x79, 0xc9, 0x11, 0x4c, 0x0f, 0xfd, 0x9c, 0x04, 0xa1, 0xad, + 0x3e, 0x8c, 0xea, 0x98, 0x01, 0x71, 0x09, 0x97, 0x90, 0x84, 0xb1, 0xef, 0x92, 0xf9, 0x9d, 0x86, + 0xe2, 0x0f, 0xb4, 0x9b, 0xdb, 0x33, 0x7e, 0xe4, 0x8b, 0x8d, 0x8d, 0xc0, 0xf4, 0xaf, 0xef, 0xfe, + 0x5c, 0x25, 0x21, 0xea, 0xcd, 0x79, 0x66, 0xf1, 0x5e, 0x05, 0x65, 0x44, 0xbe, 0xa0, 0xd3, 0x15, + 0xe0, 0x67, 0xa7, 0x03, 0x19, 0x31, 0xa2, 0x46, 0xa6, 0xc3, 0x87, 0x5d, 0x2f, 0x67, 0x8a, 0xcb, + 0xa6, 0x4f, 0x70, 0xaf, 0x88, 0xae, 0x56, 0xb6, 0xf8, 0x75, 0x81, 0xc0, 0xe2, 0x3e, 0x6b, 0x08, + 0xf4, 0x49, 0x03, 0x1d, 0xe3, 0x12, 0x81, 0x4e, 0xc6, 0xf3, 0x19, 0x29, 0x1f, 0x4a, 0x05, 0x16, + 0xbd, 0xae, 0x85, 0x92, 0x4b, 0x3c, 0xb1, 0xd0, 0xa2, 0xe3, 0x3a, 0x30, 0xc6, 0xd7, 0x95, 0x99, + 0x8a, 0x0f, 0xed, 0xdb, 0xac, 0x86, 0x5a, 0x09, 0xbc, 0xd1, 0x27, 0xfb, 0x56, 0x2e, 0xd6, 0x0a, + 0xb5, 0x5a, 0x0a, 0x5b, 0x51, 0xa1, 0x2a, 0x8b, 0xe3, 0x48, 0x99, 0xc3, 0xe0, 0x47, 0x51, 0x1a, + 0xd9, 0xa0, 0x9c, 0xea, 0x3c, 0xe7, 0x5f, 0xe3, 0x96, 0x98, 0x07, 0x03, 0x17, 0xa7, 0x13, 0x39, + 0x55, 0x22, 0x25, 0xed, 0x11, 0x77, 0xf4, 0x45, 0x84, 0xac, 0x8c, 0xfa, 0x6c, 0x4e, 0xb5, 0xfc, + 0x7e, 0x82, 0xcb, 0xab, 0xfc, 0x95, 0x38, 0x1b, 0x08, 0x09, 0x98, 0x44, 0x21, 0x29, 0xc2, 0xf8, + 0x1f, 0x13, 0x5e, 0xd1, 0x4c, 0xe6, 0x0a, 0x91, 0x36, 0x9d, 0x23, 0x22, 0xbe, 0xf2, 0x5e, 0x3c, + 0x08, 0xb6, 0xbe, 0x45, 0x12, 0x4a, 0x43, 0xe2, 0xeb, 0x77, 0x95, 0x3f, 0x84, 0xdc, 0x85, 0x53, + }, + { + 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7, 0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97, + 0x52, 0x48, 0xc4, 0x95, 0x90, 0x14, 0x12, 0x6a, 0x6e, 0x8a, 0x84, 0xf1, 0x1d, 0x1a, 0x9e, 0x1c, + 0x06, 0x59, 0x02, 0xe4, 0xb6, 0x20, 0xf6, 0xcc, 0x36, 0xc8, 0x58, 0x9f, 0x66, 0x43, 0x2f, 0x2b, + 0xd3, 0x9d, 0x56, 0x6b, 0xc6, 0xbc, 0xe3, 0x01, 0x07, 0x68, 0x15, 0x15, 0x49, 0xf3, 0x87, 0x3f, + 0xb6, 0xd1, 0xe6, 0xc4, 0xa5, 0xe4, 0x77, 0x1c, 0xad, 0x79, 0x53, 0x8d, 0xf2, 0x95, 0xfb, 0x11, + 0xc6, 0x8c, 0x1d, 0x5c, 0x55, 0x9a, 0x97, 0x41, 0x23, 0xdf, 0x1d, 0xbc, 0x52, 0xa4, 0x3b, 0x89, + 0xc5, 0xec, 0xf8, 0x8d, 0xe8, 0x97, 0xfd, 0x57, 0xfe, 0xd3, 0x01, 0x70, 0x1b, 0x82, 0xa2, 0x59, + 0xec, 0xcb, 0xe1, 0x3d, 0xe1, 0xfc, 0xc9, 0x1c, 0x11, 0xa0, 0xb2, 0x6c, 0x0b, 0xc8, 0xfa, 0x4d, + 0xe7, 0xa7, 0x25, 0x74, 0xf8, 0x78, 0x2a, 0xe2, 0x6a, 0xab, 0xcf, 0x9e, 0xbc, 0xd6, 0x60, 0x65, + 0xbd, 0xf0, 0x32, 0x4e, 0x60, 0x83, 0xdc, 0xc6, 0xd3, 0xce, 0xdd, 0x3c, 0xa8, 0xc5, 0x3c, 0x16, + 0xb4, 0x01, 0x10, 0xc4, 0x19, 0x0b, 0x56, 0x22, 0xa9, 0x61, 0x16, 0xb0, 0x01, 0x7e, 0xd2, 0x97, + 0xff, 0xa0, 0xb5, 0x14, 0x64, 0x7e, 0xc0, 0x4f, 0x63, 0x06, 0xb8, 0x92, 0xae, 0x66, 0x11, 0x81, + 0xd0, 0x3d, 0x1b, 0xc0, 0x3c, 0xd3, 0x3d, 0x70, 0xdf, 0xf9, 0xfa, 0x5d, 0x71, 0x96, 0x3e, 0xbd, + 0x8a, 0x44, 0x12, 0x64, 0x11, 0xea, 0xa7, 0x8b, 0xd5, 0x1e, 0x8d, 0x87, 0xa8, 0x87, 0x9b, 0xf5, + 0xfa, 0xbe, 0xb7, 0x60, 0x28, 0xad, 0xe2, 0xd0, 0xe4, 0x87, 0x22, 0xe4, 0x6c, 0x46, 0x15, 0xa3, + 0xc0, 0x5d, 0x88, 0xab, 0xd5, 0x03, 0x57, 0xf9, 0x35, 0xa6, 0x3c, 0x59, 0xee, 0x53, 0x76, 0x23, + 0xff, 0x38, 0x26, 0x5c, 0x16, 0x42, 0xc1, 0xab, 0xe8, 0xd3, 0xc2, 0xfe, 0x5e, 0x57, 0x2b, 0xf8, + 0xa3, 0x6a, 0x4c, 0x30, 0x1a, 0xe8, 0xac, 0x13, 0x61, 0x0c, 0xcb, 0xc1, 0x22, 0x56, 0xca, 0xcc, + }, + { + 0x05, 0x95, 0xe5, 0x7f, 0xe5, 0xf0, 0xbb, 0x3c, 0x70, 0x6e, 0xda, 0xc8, 0xa4, 0xb2, 0xdb, 0x11, + 0xdf, 0xde, 0x31, 0x34, 0x4a, 0x1a, 0xf7, 0x69, 0xc7, 0x4f, 0x07, 0x0a, 0xee, 0x9e, 0x23, 0x26, + 0xb0, 0x6b, 0x9b, 0x1e, 0x19, 0x5d, 0x13, 0xd8, 0xf4, 0xa7, 0x99, 0x5c, 0x45, 0x53, 0xac, 0x05, + 0x6b, 0xd2, 0x37, 0x8e, 0xc3, 0x41, 0xc9, 0xa4, 0x2f, 0x37, 0xba, 0x79, 0xf8, 0x8a, 0x32, 0xff, + 0xe7, 0x0b, 0xce, 0x1d, 0xf7, 0x64, 0x5a, 0xdb, 0x5d, 0x2c, 0x41, 0x30, 0x21, 0x5c, 0x35, 0x22, + 0x9a, 0x57, 0x30, 0xc7, 0xfc, 0xb4, 0xc9, 0xaf, 0x51, 0xff, 0xda, 0x89, 0xc7, 0xf1, 0xad, 0x22, + 0x04, 0x85, 0x05, 0x5f, 0xd4, 0xf6, 0xf0, 0xd9, 0x63, 0xef, 0x5a, 0xb9, 0xa5, 0x47, 0x69, 0x82, + 0x59, 0x1f, 0xc6, 0x6b, 0xcd, 0xa1, 0x0e, 0x45, 0x2b, 0x03, 0xd4, 0x55, 0x1f, 0x6b, 0x62, 0xac, + 0x27, 0x53, 0xcc, 0x83, 0x98, 0x8a, 0xfa, 0x3e, 0x16, 0x88, 0xa1, 0xd3, 0xb4, 0x2c, 0x9a, 0x02, + 0x93, 0x61, 0x0d, 0x52, 0x3d, 0x1d, 0x3f, 0x00, 0x62, 0xb3, 0xc2, 0xa3, 0xbb, 0xc7, 0xc7, 0xf0, + 0x96, 0xc2, 0x48, 0x61, 0x0a, 0xad, 0xed, 0xfe, 0xaf, 0x89, 0x78, 0xc0, 0x3d, 0xe8, 0x20, 0x5a, + 0x0e, 0x31, 0x7b, 0x3d, 0x1c, 0x73, 0xb9, 0xe9, 0xa4, 0x68, 0x8f, 0x29, 0x6d, 0x13, 0x3a, 0x19, + 0xbd, 0xf0, 0xe6, 0xc3, 0xcc, 0xa5, 0xb5, 0xb9, 0xd5, 0x33, 0xb6, 0x9c, 0x56, 0xad, 0xa1, 0x20, + 0x88, 0xa2, 0x18, 0xb6, 0xe2, 0xec, 0xe1, 0xe6, 0x24, 0x6d, 0x44, 0xc7, 0x59, 0xd1, 0x9b, 0x10, + 0x68, 0x66, 0x39, 0x7e, 0x95, 0xc1, 0x40, 0x53, 0x4f, 0x94, 0x26, 0x34, 0x21, 0x00, 0x6e, 0x40, + 0x32, 0xcb, 0x0a, 0x1e, 0x95, 0x42, 0xc6, 0xb3, 0xb8, 0xb3, 0x98, 0xab, 0xc3, 0xb0, 0xf1, 0xd5, + 0x29, 0xa0, 0xb8, 0xae, 0xd5, 0x4a, 0x13, 0x23, 0x24, 0xc6, 0x2e, 0x42, 0x3f, 0x54, 0xb4, 0xc8, + 0x3c, 0xb0, 0xf3, 0xb5, 0x02, 0x0a, 0x98, 0xb8, 0x2a, 0xf9, 0xfe, 0x15, 0x44, 0x84, 0xa1, 0x68, + }, + { + 0xea, 0xa6, 0xbd, 0x25, 0x88, 0x0b, 0xf9, 0x3d, 0x3f, 0x5d, 0x1e, 0x4c, 0xa2, 0x61, 0x1d, 0x91, + 0xcf, 0xa4, 0x5c, 0x9f, 0x7e, 0x71, 0x4b, 0x54, 0xbd, 0xfa, 0x80, 0x02, 0x7c, 0xb1, 0x43, 0x80, + 0x11, 0x4a, 0xe3, 0x44, 0xde, 0xd7, 0x1b, 0x35, 0xf2, 0xe6, 0x0f, 0xeb, 0xad, 0x72, 0x7f, 0xd8, + 0x02, 0xe1, 0xe7, 0x05, 0x6b, 0x0f, 0x62, 0x39, 0x00, 0x49, 0x64, 0x22, 0x94, 0x3e, 0x97, 0xb6, + 0x91, 0xcb, 0x93, 0xc7, 0x87, 0x96, 0x4e, 0x10, 0xd9, 0x52, 0x7d, 0x99, 0x9c, 0x6f, 0x93, 0x6b, + 0x49, 0xb1, 0x8b, 0x42, 0xf8, 0xe8, 0x36, 0x7c, 0xbe, 0xb5, 0xef, 0x10, 0x4b, 0xa1, 0xc7, 0xcd, + 0x87, 0x08, 0x4b, 0x3b, 0xa7, 0x00, 0xba, 0xde, 0x95, 0x56, 0x10, 0x67, 0x27, 0x45, 0xb3, 0x74, + 0xe7, 0xa7, 0xb9, 0xe9, 0xec, 0x54, 0x0d, 0x5f, 0xf4, 0x3b, 0xdb, 0x12, 0x79, 0x2d, 0x1b, 0x35, + 0xc7, 0x99, 0xb5, 0x96, 0x73, 0x8f, 0x6b, 0x01, 0x8c, 0x76, 0xc7, 0x4b, 0x17, 0x59, 0xbd, 0x90, + 0x7f, 0xec, 0x5b, 0xfd, 0x9f, 0x9b, 0x89, 0xce, 0x65, 0x48, 0x30, 0x90, 0x92, 0xd7, 0xe9, 0x58, + 0x40, 0xf2, 0x50, 0xb2, 0x6d, 0x1f, 0x09, 0x6a, 0x4a, 0xfd, 0x4c, 0x34, 0x0a, 0x58, 0x88, 0x15, + 0x3e, 0x34, 0x13, 0x5c, 0x79, 0xdb, 0x01, 0x02, 0x00, 0x76, 0x76, 0x51, 0xcf, 0x26, 0x30, 0x73, + 0xf6, 0x56, 0xab, 0xcc, 0xf8, 0x8d, 0xd8, 0x27, 0x02, 0x7b, 0x2c, 0xe9, 0x17, 0xd4, 0x64, 0xec, + 0x18, 0xb6, 0x25, 0x03, 0xbf, 0xbc, 0x07, 0x7f, 0xba, 0xbb, 0x98, 0xf2, 0x0d, 0x98, 0xab, 0x34, + 0x8a, 0xed, 0x95, 0xee, 0x5b, 0x0d, 0xcb, 0xfb, 0xef, 0x4e, 0xb2, 0x1d, 0x3a, 0x3f, 0x52, 0xf9, + 0x62, 0x5a, 0x1a, 0xb0, 0x0e, 0xe3, 0x9a, 0x53, 0x27, 0x34, 0x6b, 0xdd, 0xb0, 0x1a, 0x9c, 0x18, + 0xa1, 0x3a, 0x7c, 0x79, 0xc7, 0xe1, 0x19, 0xb5, 0xab, 0x02, 0x96, 0xab, 0x28, 0xc3, 0x00, 0xb9, + 0xf3, 0xe4, 0xc0, 0xa2, 0xe0, 0x2d, 0x1d, 0x01, 0xf7, 0xf0, 0xa7, 0x46, 0x18, 0xaf, 0x2b, 0x48, + }, +}; + +unsigned char testdata2[][16 * 18] = { + { + 0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a, 0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda, + 0x20, 0xf0, 0x60, 0xc2, 0xf2, 0xe5, 0x12, 0x65, 0x01, 0xd3, 0xd4, 0xfe, 0xa1, 0x0d, 0x5f, 0xc0, + 0xfa, 0xa1, 0x48, 0xe9, 0x90, 0x46, 0x18, 0x1f, 0xec, 0x6b, 0x20, 0x85, 0xf3, 0xb2, 0x0e, 0xd9, + 0xf0, 0xda, 0xf5, 0xba, 0xb3, 0xd5, 0x96, 0x83, 0x98, 0x57, 0x84, 0x6f, 0x73, 0xfb, 0xfe, 0x5a, + 0x1c, 0x7e, 0x2f, 0xc4, 0x63, 0x92, 0x32, 0xfe, 0x29, 0x75, 0x84, 0xb2, 0x96, 0x99, 0x6b, 0xc8, + 0x3d, 0xb9, 0xb2, 0x49, 0x40, 0x6c, 0xc8, 0xed, 0xff, 0xac, 0x55, 0xcc, 0xd3, 0x22, 0xba, 0x12, + 0xe4, 0xf9, 0xf7, 0xe0, 0x06, 0x61, 0x54, 0xbb, 0xd1, 0x25, 0xb7, 0x45, 0x56, 0x9b, 0xc8, 0x97, + 0x75, 0xd5, 0xef, 0x26, 0x2b, 0x44, 0xc4, 0x1a, 0x9c, 0xf6, 0x3a, 0xe1, 0x45, 0x68, 0xe1, 0xb9, + 0x6d, 0xa4, 0x53, 0xdb, 0xf8, 0x1e, 0x82, 0x33, 0x4a, 0x3d, 0x88, 0x66, 0xcb, 0x50, 0xa1, 0xe3, + 0x78, 0x28, 0xd0, 0x74, 0x11, 0x9c, 0xab, 0x5c, 0x22, 0xb2, 0x94, 0xd7, 0xa9, 0xbf, 0xa0, 0xbb, + 0xad, 0xb8, 0x9c, 0xea, 0x9a, 0x15, 0xfb, 0xe6, 0x17, 0x29, 0x5b, 0xd0, 0x4b, 0x8c, 0xa0, 0x5c, + 0x62, 0x51, 0xd8, 0x7f, 0xd4, 0xaa, 0xae, 0x9a, 0x7e, 0x4a, 0xd5, 0xc2, 0x17, 0xd3, 0xf3, 0x00, + 0xe7, 0x11, 0x9b, 0xd6, 0xdd, 0x9b, 0x22, 0xaf, 0xe8, 0xf8, 0x95, 0x85, 0x43, 0x28, 0x81, 0xe2, + 0x78, 0x5b, 0x60, 0xfd, 0x7e, 0xc4, 0xe9, 0xfc, 0xb6, 0x54, 0x5f, 0x35, 0x0d, 0x66, 0x0f, 0xab, + 0xaf, 0xec, 0xc0, 0x37, 0xfd, 0xb7, 0xb0, 0x83, 0x8e, 0xb3, 0xd7, 0x0b, 0xcd, 0x26, 0x83, 0x82, + 0xdb, 0xc1, 0xa7, 0xb4, 0x9d, 0x57, 0x35, 0x8c, 0xc9, 0xfa, 0x6d, 0x61, 0xd7, 0x3b, 0x7c, 0xf0, + 0x63, 0x49, 0xd1, 0x26, 0xa3, 0x7a, 0xfc, 0xba, 0x89, 0x79, 0x4f, 0x98, 0x04, 0x91, 0x4f, 0xdc, + 0xbf, 0x42, 0xc3, 0x01, 0x8c, 0x2f, 0x7c, 0x66, 0xbf, 0xde, 0x52, 0x49, 0x75, 0x76, 0x81, 0x15, + }, + { + 0xbc, 0x92, 0x22, 0xdb, 0xd3, 0x27, 0x4d, 0x8f, 0xc6, 0x6d, 0x14, 0xcc, 0xbd, 0xa6, 0x69, 0x0b, + 0x7a, 0xe6, 0x27, 0x41, 0x0c, 0x9a, 0x2b, 0xe6, 0x93, 0xdf, 0x5b, 0xb7, 0x48, 0x5a, 0x63, 0xe3, + 0x3f, 0x09, 0x31, 0xaa, 0x03, 0xde, 0xfb, 0x30, 0x0f, 0x06, 0x01, 0x03, 0x82, 0x6f, 0x2a, 0x64, + 0xbe, 0xaa, 0x9e, 0xc8, 0xd5, 0x9b, 0xb6, 0x81, 0x29, 0xf3, 0x02, 0x7c, 0x96, 0x36, 0x11, 0x81, + 0x74, 0xe0, 0x4d, 0xb4, 0x6d, 0x28, 0x64, 0x8d, 0x7d, 0xee, 0x8a, 0x00, 0x64, 0xb0, 0x6c, 0xfe, + 0x9b, 0x5e, 0x81, 0xc6, 0x2f, 0xe0, 0x23, 0xc5, 0x5b, 0xe4, 0x2f, 0x87, 0xbb, 0xf9, 0x32, 0xb8, + 0xce, 0x17, 0x8f, 0xc1, 0x82, 0x6e, 0xfe, 0xcb, 0xc1, 0x82, 0xf5, 0x79, 0x99, 0xa4, 0x61, 0x40, + 0x8b, 0xdf, 0x55, 0xcd, 0x55, 0x06, 0x1c, 0x06, 0xdb, 0xa6, 0xbe, 0x11, 0xde, 0x4a, 0x57, 0x8a, + 0x62, 0x6f, 0x5f, 0x4d, 0xce, 0x65, 0x25, 0x01, 0xf3, 0x08, 0x7d, 0x39, 0xc9, 0x2c, 0xc3, 0x49, + 0x42, 0xda, 0xac, 0x6a, 0x8f, 0x9a, 0xb9, 0xa7, 0xfd, 0x13, 0x7c, 0x60, 0x37, 0x82, 0x56, 0x82, + 0xcc, 0x03, 0xfd, 0xb7, 0x91, 0x92, 0xa2, 0x07, 0x31, 0x2f, 0x53, 0xf5, 0xd4, 0xdc, 0x33, 0xd9, + 0xf7, 0x0f, 0x14, 0x12, 0x2a, 0x1c, 0x98, 0xa3, 0x15, 0x5d, 0x28, 0xb8, 0xa0, 0xa8, 0xa4, 0x1d, + 0x2a, 0x3a, 0x30, 0x7a, 0xb2, 0x70, 0x8a, 0x9c, 0x00, 0xfe, 0x0b, 0x42, 0xf9, 0xc2, 0xd6, 0xa1, + 0x86, 0x26, 0x17, 0x62, 0x7d, 0x22, 0x61, 0xea, 0xb0, 0xb1, 0x24, 0x65, 0x97, 0xca, 0x0a, 0xe9, + 0x55, 0xf8, 0x77, 0xce, 0x4f, 0x2e, 0x1d, 0xdb, 0xbf, 0x8e, 0x13, 0xe2, 0xcd, 0xe0, 0xfd, 0xc8, + 0x1b, 0x15, 0x56, 0xcb, 0x93, 0x5f, 0x17, 0x33, 0x37, 0x70, 0x5f, 0xbb, 0x5d, 0x50, 0x1f, 0xc1, + 0xec, 0xd0, 0xe9, 0x66, 0x02, 0xbe, 0x7f, 0x8d, 0x50, 0x92, 0x81, 0x6c, 0xcc, 0xf2, 0xc2, 0xe9, + 0x02, 0x78, 0x81, 0xfa, 0xb4, 0x99, 0x3a, 0x1c, 0x26, 0x20, 0x24, 0xa9, 0x4f, 0xff, 0x3f, 0x61, + }, + { + 0xbb, 0xf6, 0x09, 0xde, 0x94, 0x13, 0x17, 0x2d, 0x07, 0x66, 0x0c, 0xb6, 0x80, 0x71, 0x69, 0x26, + 0x46, 0x10, 0x1a, 0x6d, 0xab, 0x43, 0x11, 0x5d, 0x6c, 0x52, 0x2b, 0x4f, 0xe9, 0x36, 0x04, 0xa9, + 0xcb, 0xe1, 0xff, 0xf2, 0x1c, 0x96, 0xf3, 0xee, 0xf6, 0x1e, 0x8f, 0xe0, 0x54, 0x2c, 0xbd, 0xf0, + 0x34, 0x79, 0x38, 0xbf, 0xfa, 0x40, 0x09, 0xc5, 0x12, 0xcf, 0xb4, 0x03, 0x4b, 0x0d, 0xd1, 0xa7, + 0x78, 0x67, 0xa7, 0x86, 0xd0, 0x0a, 0x71, 0x47, 0x90, 0x4d, 0x76, 0xdd, 0xf1, 0xe5, 0x20, 0xe3, + 0x8d, 0x3e, 0x9e, 0x1c, 0xae, 0xfc, 0xcc, 0xb3, 0xfb, 0xf8, 0xd1, 0x8f, 0x64, 0x12, 0x0b, 0x32, + 0x94, 0x23, 0x37, 0xf8, 0xfd, 0x76, 0xf0, 0xfa, 0xe8, 0xc5, 0x2d, 0x79, 0x54, 0x81, 0x06, 0x72, + 0xb8, 0x54, 0x8c, 0x10, 0xf5, 0x16, 0x67, 0xf6, 0xe6, 0x0e, 0x18, 0x2f, 0xa1, 0x9b, 0x30, 0xf7, + 0x02, 0x11, 0xc7, 0xc6, 0x19, 0x0c, 0x9e, 0xfd, 0x12, 0x37, 0xc3, 0x4c, 0x8f, 0x2e, 0x06, 0xc4, + 0xbd, 0xa6, 0x4f, 0x65, 0x27, 0x6d, 0x2a, 0xac, 0xb8, 0xf9, 0x02, 0x12, 0x20, 0x3a, 0x80, 0x8e, + 0xbd, 0x38, 0x20, 0xf7, 0x32, 0xff, 0xb5, 0x3e, 0xc1, 0x93, 0xe7, 0x9d, 0x33, 0xe2, 0x7c, 0x73, + 0xd0, 0x16, 0x86, 0x16, 0x86, 0x19, 0x07, 0xd4, 0x82, 0xe3, 0x6c, 0xda, 0xc8, 0xcf, 0x57, 0x49, + 0x97, 0xb0, 0xf0, 0xf2, 0x24, 0xb2, 0xd2, 0x31, 0x71, 0x14, 0x80, 0x8f, 0xb0, 0x3a, 0xf7, 0xa0, + 0xe5, 0x96, 0x16, 0xe4, 0x69, 0x78, 0x79, 0x39, 0xa0, 0x63, 0xce, 0xea, 0x9a, 0xf9, 0x56, 0xd1, + 0xc4, 0x7e, 0x0d, 0xc1, 0x66, 0x09, 0x19, 0xc1, 0x11, 0x01, 0x20, 0x8f, 0x9e, 0x69, 0xaa, 0x1f, + 0x5a, 0xe4, 0xf1, 0x28, 0x96, 0xb8, 0x37, 0x9a, 0x2a, 0xad, 0x89, 0xb5, 0xb5, 0x53, 0xd6, 0xb0, + 0x6b, 0x6b, 0x09, 0x8d, 0x0c, 0x29, 0x3b, 0xc2, 0x99, 0x3d, 0x80, 0xbf, 0x05, 0x18, 0xb6, 0xd9, + 0x81, 0x70, 0xcc, 0x3c, 0xcd, 0x92, 0xa6, 0x98, 0x62, 0x1b, 0x93, 0x9d, 0xd3, 0x8f, 0xe7, 0xb9, + }, + { + 0xab, 0x65, 0xc2, 0x6e, 0xdd, 0xb2, 0x87, 0x60, 0x0d, 0xb2, 0xfd, 0xa1, 0x0d, 0x1e, 0x60, 0x5c, + 0xbb, 0x75, 0x90, 0x10, 0xc2, 0x96, 0x58, 0xf2, 0xc7, 0x2d, 0x93, 0xa2, 0xd1, 0x6d, 0x29, 0x30, + 0xb9, 0x01, 0xe8, 0x03, 0x6e, 0xd1, 0xc3, 0x83, 0xcd, 0x3c, 0x4c, 0x4d, 0xd0, 0xa6, 0xab, 0x05, + 0x3d, 0x25, 0xce, 0x49, 0x22, 0x92, 0x4c, 0x55, 0xf0, 0x64, 0x94, 0x33, 0x53, 0xd7, 0x8a, 0x6c, + 0x12, 0xc1, 0xaa, 0x44, 0xbb, 0xf8, 0x7e, 0x75, 0xe6, 0x11, 0xf6, 0x9b, 0x2c, 0x38, 0xf4, 0x9b, + 0x28, 0xf2, 0xb3, 0x43, 0x4b, 0x65, 0xc0, 0x98, 0x77, 0x47, 0x00, 0x44, 0xc6, 0xea, 0x17, 0x0d, + 0xbd, 0x9e, 0xf8, 0x22, 0xde, 0x52, 0x88, 0x19, 0x61, 0x34, 0xcf, 0x8a, 0xf7, 0x83, 0x93, 0x04, + 0x67, 0x55, 0x9c, 0x23, 0xf0, 0x52, 0x15, 0x84, 0x70, 0xa2, 0x96, 0xf7, 0x25, 0x73, 0x5a, 0x32, + 0x8b, 0xab, 0x26, 0xfb, 0xc2, 0xc1, 0x2b, 0x0f, 0x13, 0xe2, 0xab, 0x18, 0x5e, 0xab, 0xf2, 0x41, + 0x31, 0x18, 0x5a, 0x6d, 0x69, 0x6f, 0x0c, 0xfa, 0x9b, 0x42, 0x80, 0x8b, 0x38, 0xe1, 0x32, 0xa2, + 0x56, 0x4d, 0x3d, 0xae, 0x18, 0x3c, 0x52, 0x34, 0xc8, 0xaf, 0x1e, 0x51, 0x06, 0x1c, 0x44, 0xb5, + 0x3c, 0x07, 0x78, 0xa7, 0xb5, 0xf7, 0x2d, 0x3c, 0x23, 0xa3, 0x13, 0x5c, 0x7d, 0x67, 0xb9, 0xf4, + 0xf3, 0x43, 0x69, 0x89, 0x0f, 0xcf, 0x16, 0xfb, 0x51, 0x7d, 0xca, 0xae, 0x44, 0x63, 0xb2, 0xdd, + 0x02, 0xf3, 0x1c, 0x81, 0xe8, 0x20, 0x07, 0x31, 0xb8, 0x99, 0xb0, 0x28, 0xe7, 0x91, 0xbf, 0xa7, + 0x72, 0xda, 0x64, 0x62, 0x83, 0x22, 0x8c, 0x14, 0x30, 0x08, 0x53, 0x70, 0x17, 0x95, 0x61, 0x6f, + 0x4e, 0x0a, 0x8c, 0x6f, 0x79, 0x34, 0xa7, 0x88, 0xe2, 0x26, 0x5e, 0x81, 0xd6, 0xd0, 0xc8, 0xf4, + 0x43, 0x8d, 0xd5, 0xea, 0xfe, 0xa0, 0x11, 0x1b, 0x6f, 0x36, 0xb4, 0xb9, 0x38, 0xda, 0x2a, 0x68, + 0x5f, 0x6b, 0xfc, 0x73, 0x81, 0x58, 0x74, 0xd9, 0x71, 0x00, 0xf0, 0x86, 0x97, 0x93, 0x57, 0xd8, + }, + { + 0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1, 0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30, + 0xc3, 0x66, 0xfd, 0xea, 0xcf, 0x9c, 0xa8, 0x04, 0x36, 0xbe, 0x7c, 0x35, 0x84, 0x24, 0xd2, 0x0b, + 0xb3, 0x39, 0x4a, 0x40, 0xaa, 0xbf, 0x75, 0xcb, 0xa4, 0x22, 0x82, 0xef, 0x25, 0xa0, 0x05, 0x9f, + 0x48, 0x47, 0xd8, 0x1d, 0xa4, 0x94, 0x2d, 0xbc, 0x24, 0x9d, 0xef, 0xc4, 0x8c, 0x92, 0x2b, 0x9f, + 0x08, 0x12, 0x8c, 0x46, 0x9f, 0x27, 0x53, 0x42, 0xad, 0xda, 0x20, 0x2b, 0x2b, 0x58, 0xda, 0x95, + 0x97, 0x0d, 0xac, 0xef, 0x40, 0xad, 0x98, 0x72, 0x3b, 0xac, 0x5d, 0x69, 0x55, 0xb8, 0x17, 0x61, + 0x3c, 0xb8, 0x99, 0x93, 0xb0, 0x7b, 0x0c, 0xed, 0x93, 0xde, 0x13, 0xd2, 0xa1, 0x10, 0x13, 0xac, + 0xef, 0x2d, 0x67, 0x6f, 0x15, 0x45, 0xc2, 0xc1, 0x3d, 0xc6, 0x80, 0xa0, 0x2f, 0x4a, 0xdb, 0xfe, + 0xb6, 0x05, 0x95, 0x51, 0x4f, 0x24, 0xbc, 0x9f, 0xe5, 0x22, 0xa6, 0xca, 0xd7, 0x39, 0x36, 0x44, + 0xb5, 0x15, 0xa8, 0xc5, 0x01, 0x17, 0x54, 0xf5, 0x90, 0x03, 0x05, 0x8b, 0xdb, 0x81, 0x51, 0x4e, + 0x3c, 0x70, 0x04, 0x7e, 0x8c, 0xbc, 0x03, 0x8e, 0x3b, 0x98, 0x20, 0xdb, 0x60, 0x1d, 0xa4, 0x95, + 0x11, 0x75, 0xda, 0x6e, 0xe7, 0x56, 0xde, 0x46, 0xa5, 0x3e, 0x2b, 0x07, 0x56, 0x60, 0xb7, 0x70, + 0x00, 0xa5, 0x42, 0xbb, 0xa0, 0x21, 0x11, 0xcc, 0x2c, 0x65, 0xb3, 0x8e, 0xbd, 0xba, 0x58, 0x7e, + 0x58, 0x65, 0xfd, 0xbb, 0x5b, 0x48, 0x06, 0x41, 0x04, 0xe8, 0x30, 0xb3, 0x80, 0xf2, 0xae, 0xde, + 0x34, 0xb2, 0x1a, 0xd2, 0xad, 0x44, 0xe9, 0x99, 0xdb, 0x2d, 0x7f, 0x08, 0x63, 0xf0, 0xd9, 0xb6, + 0x84, 0xa9, 0x21, 0x8f, 0xc3, 0x6e, 0x8a, 0x5f, 0x2c, 0xcf, 0xbe, 0xae, 0x53, 0xa2, 0x7d, 0x25, + 0xa2, 0x22, 0x1a, 0x11, 0xb8, 0x33, 0xcc, 0xb4, 0x98, 0xa5, 0x95, 0x40, 0xf0, 0x54, 0x5f, 0x4a, + 0x5b, 0xbe, 0xb4, 0x78, 0x7d, 0x59, 0xe5, 0x37, 0x3f, 0xdb, 0xea, 0x6c, 0x6f, 0x75, 0xc2, 0x9b, + }, + { + 0x54, 0xb6, 0x4e, 0x6b, 0x5a, 0x20, 0xb5, 0xe2, 0xec, 0x84, 0x59, 0x3d, 0xc7, 0x98, 0x9d, 0xa7, + 0xc1, 0x35, 0xee, 0xe2, 0x37, 0xa8, 0x54, 0x65, 0xff, 0x97, 0xdc, 0x03, 0x92, 0x4f, 0x45, 0xce, + 0xcf, 0xcc, 0x92, 0x2f, 0xb4, 0xa1, 0x4a, 0xb4, 0x5d, 0x61, 0x75, 0xaa, 0xbb, 0xf2, 0xd2, 0x01, + 0x83, 0x7b, 0x87, 0xe2, 0xa4, 0x46, 0xad, 0x0e, 0xf7, 0x98, 0xac, 0xd0, 0x2b, 0x94, 0x12, 0x4f, + 0x17, 0xa6, 0xdb, 0xd6, 0x64, 0x92, 0x6a, 0x06, 0x36, 0xb3, 0xf4, 0xc3, 0x7a, 0x4f, 0x46, 0x94, + 0x4a, 0x5f, 0x9f, 0x26, 0xae, 0xee, 0xd4, 0xd4, 0xa2, 0x5f, 0x63, 0x2d, 0x30, 0x52, 0x33, 0xd9, + 0x80, 0xa3, 0xd0, 0x1e, 0xf0, 0x0c, 0x8e, 0x9a, 0x42, 0x09, 0xc1, 0x7f, 0x4e, 0xeb, 0x35, 0x8c, + 0xd1, 0x5e, 0x7d, 0x5f, 0xfa, 0xaa, 0xbc, 0x02, 0x07, 0xbf, 0x20, 0x0a, 0x11, 0x77, 0x93, 0xa2, + 0x34, 0x96, 0x82, 0xbf, 0x58, 0x8e, 0xaa, 0x52, 0xd0, 0xaa, 0x15, 0x60, 0x34, 0x6a, 0xea, 0xfa, + 0xf5, 0x85, 0x4c, 0xdb, 0x76, 0xc8, 0x89, 0xe3, 0xad, 0x63, 0x35, 0x4e, 0x5f, 0x72, 0x75, 0xe3, + 0x53, 0x2c, 0x7c, 0xec, 0xcb, 0x39, 0xdf, 0x32, 0x36, 0x31, 0x84, 0x05, 0xa4, 0xb1, 0x27, 0x9c, + 0xba, 0xef, 0xe6, 0xd9, 0xce, 0xb6, 0x51, 0x84, 0x22, 0x60, 0xe0, 0xd1, 0xe0, 0x5e, 0x3b, 0x90, + 0xe8, 0x2d, 0x8c, 0x6d, 0xb5, 0x4e, 0x3c, 0x63, 0x3f, 0x58, 0x1c, 0x95, 0x2b, 0xa0, 0x42, 0x07, + 0x4b, 0x16, 0xe5, 0x0a, 0xbd, 0x38, 0x1b, 0xd7, 0x09, 0x00, 0xa9, 0xcd, 0x9a, 0x62, 0xcb, 0x23, + 0x36, 0x82, 0xee, 0x33, 0xbd, 0x14, 0x8b, 0xd9, 0xf5, 0x86, 0x56, 0xcd, 0x8f, 0x30, 0xd9, 0xfb, + 0x1e, 0x5a, 0x0b, 0x84, 0x75, 0x04, 0x5d, 0x9b, 0x20, 0xb2, 0x62, 0x86, 0x24, 0xed, 0xfd, 0x9e, + 0x63, 0xed, 0xd6, 0x84, 0xfb, 0x82, 0x62, 0x82, 0xfe, 0x52, 0x8f, 0x9c, 0x0e, 0x92, 0x37, 0xbc, + 0xe4, 0xdd, 0x2e, 0x98, 0xd6, 0x96, 0x0f, 0xae, 0x0b, 0x43, 0x54, 0x54, 0x56, 0x74, 0x33, 0x91, + }, + { + 0xdd, 0x5b, 0xcb, 0x00, 0x18, 0xe9, 0x22, 0xd4, 0x94, 0x75, 0x9d, 0x7c, 0x39, 0x5d, 0x02, 0xd3, + 0xc8, 0x44, 0x6f, 0x8f, 0x77, 0xab, 0xf7, 0x37, 0x68, 0x53, 0x53, 0xeb, 0x89, 0xa1, 0xc9, 0xeb, + 0xaf, 0x3e, 0x30, 0xf9, 0xc0, 0x95, 0x04, 0x59, 0x38, 0x15, 0x15, 0x75, 0xc3, 0xfb, 0x90, 0x98, + 0xf8, 0xcb, 0x62, 0x74, 0xdb, 0x99, 0xb8, 0x0b, 0x1d, 0x20, 0x12, 0xa9, 0x8e, 0xd4, 0x8f, 0x0e, + 0x25, 0xc3, 0x00, 0x5a, 0x1c, 0xb8, 0x5d, 0xe0, 0x76, 0x25, 0x98, 0x39, 0xab, 0x71, 0x98, 0xab, + 0x9d, 0xcb, 0xc1, 0x83, 0xe8, 0xcb, 0x99, 0x4b, 0x72, 0x7b, 0x75, 0xbe, 0x31, 0x80, 0x76, 0x9c, + 0xa1, 0xd3, 0x07, 0x8d, 0xfa, 0x91, 0x69, 0x50, 0x3e, 0xd9, 0xd4, 0x49, 0x1d, 0xee, 0x4e, 0xb2, + 0x85, 0x14, 0xa5, 0x49, 0x58, 0x58, 0x09, 0x6f, 0x59, 0x6e, 0x4b, 0xcd, 0x66, 0xb1, 0x06, 0x65, + 0x5f, 0x40, 0xd5, 0x9e, 0xc1, 0xb0, 0x3b, 0x33, 0x73, 0x8e, 0xfa, 0x60, 0xb2, 0x25, 0x5d, 0x31, + 0x34, 0x77, 0xc7, 0xf7, 0x64, 0xa4, 0x1b, 0xac, 0xef, 0xf9, 0x0b, 0xf1, 0x4f, 0x92, 0xb7, 0xcc, + 0xac, 0x4e, 0x95, 0x36, 0x8d, 0x99, 0xb9, 0xeb, 0x78, 0xb8, 0xda, 0x8f, 0x81, 0xff, 0xa7, 0x95, + 0x8c, 0x3c, 0x13, 0xf8, 0xc2, 0x38, 0x8b, 0xb7, 0x3f, 0x38, 0x57, 0x6e, 0x65, 0xb7, 0xc4, 0x46, + 0x13, 0xc4, 0xb9, 0xc1, 0xdf, 0xb6, 0x65, 0x79, 0xed, 0xdd, 0x8a, 0x28, 0x0b, 0x9f, 0x73, 0x16, + 0xdd, 0xd2, 0x78, 0x20, 0x55, 0x01, 0x26, 0x69, 0x8e, 0xfa, 0xad, 0xc6, 0x4b, 0x64, 0xf6, 0x6e, + 0xf0, 0x8f, 0x2e, 0x66, 0xd2, 0x8e, 0xd1, 0x43, 0xf3, 0xa2, 0x37, 0xcf, 0x9d, 0xe7, 0x35, 0x59, + 0x9e, 0xa3, 0x6c, 0x52, 0x55, 0x31, 0xb8, 0x80, 0xba, 0x12, 0x43, 0x34, 0xf5, 0x7b, 0x0b, 0x70, + 0xd5, 0xa3, 0x9e, 0x3d, 0xfc, 0xc5, 0x02, 0x80, 0xba, 0xc4, 0xa6, 0xb5, 0xaa, 0x0d, 0xca, 0x7d, + 0x37, 0x0b, 0x1c, 0x1f, 0xe6, 0x55, 0x91, 0x6d, 0x97, 0xfd, 0x0d, 0x47, 0xca, 0x1d, 0x72, 0xb8, + }, +}; + +int main(void) +{ + int err = 0; + RC4_STATE state; + unsigned char buf[4096 + 16]; + size_t i, j; + + for (i = 0; i < sizeof(keybits)/sizeof(keybits[0]); i++) { + int e = 0; + rc4_init(&state, key1, keybits[i]/8); + rc4_generate_keystream(&state, sizeof(buf), buf); + for (j = 0; j < sizeof(testindex)/sizeof(testindex[0]); j++) { + if (memcmp(buf + testindex[j], &testdata1[i][j * 16], 16) != 0) { + e++; + } + } + fprintf(stderr, "rc4 test 1.%zu %s\n", i+1, e ? "failed" : "ok"); + if (e) { + err++; + } + } + + for (i = 0; i < sizeof(keybits)/sizeof(keybits[0]); i++) { + int e = 0; + rc4_init(&state, key2 + sizeof(key2) - keybits[i]/8, keybits[i]/8); + rc4_generate_keystream(&state, sizeof(buf), buf); + for (j = 0; j < sizeof(testindex)/sizeof(testindex[0]); j++) { + if (memcmp(buf + testindex[j], &testdata2[i][j * 16], 16) != 0) { + e++; + } + } + fprintf(stderr, "rc4 test 2.%zu %s\n", i+1, e ? "failed" : "ok"); + if (e) { + err++; + } + } + + return err; +} diff --git a/tests/sha1test.c b/tests/sha1test.c index 2a5bb32c..386de0ea 100644 --- a/tests/sha1test.c +++ b/tests/sha1test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,66 +7,67 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static char *teststr[] = { - "abc", - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "a", - "0123456701234567012345670123456701234567012345670123456701234567", -}; - -static size_t testcnt[] = { - 1, - 1, - 1000000, - 10, -}; - -static char *dgsthex[] = { - "A9993E364706816ABA3E25717850C26C9CD0D89D", - "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", - "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", - "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452", -}; - -int main(void) -{ - int err = 0; - SHA1_CTX ctx; - uint8_t dgst[20]; - uint8_t dgstbuf[20]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { - hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstlen); - - sha1_init(&ctx); - for (j = 0; j < testcnt[i]; j++) { - sha1_update(&ctx, (uint8_t *)teststr[i], strlen(teststr[i])); - } - sha1_finish(&ctx, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - printf("sha1 test %lu failed\n", i+1); - printf("%s\n", dgsthex[i]); - for (j = 0; j < sizeof(dgst); j++) { - printf("%02X", dgst[j]); - } - printf("\n"); - err++; - } else { - printf("sha1 test %lu ok\n", i+1); - } - } - - return err; -} + + +#include +#include +#include +#include +#include +#include + + +static char *teststr[] = { + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "a", + "0123456701234567012345670123456701234567012345670123456701234567", +}; + +static size_t testcnt[] = { + 1, + 1, + 1000000, + 10, +}; + +static char *dgsthex[] = { + "A9993E364706816ABA3E25717850C26C9CD0D89D", + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", + "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", + "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452", +}; + +int main(void) +{ + int err = 0; + SHA1_CTX ctx; + uint8_t dgst[20]; + uint8_t dgstbuf[20]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstlen); + + sha1_init(&ctx); + for (j = 0; j < testcnt[i]; j++) { + sha1_update(&ctx, (uint8_t *)teststr[i], strlen(teststr[i])); + } + sha1_finish(&ctx, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + printf("sha1 test %lu failed\n", i+1); + printf("%s\n", dgsthex[i]); + for (j = 0; j < sizeof(dgst); j++) { + printf("%02X", dgst[j]); + } + printf("\n"); + err++; + } else { + printf("sha1 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/sha224test.c b/tests/sha224test.c index e9e94ce5..abc84360 100644 --- a/tests/sha224test.c +++ b/tests/sha224test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,88 +7,89 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -#define TEST1 "abc" -#define TEST2 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" -#define TEST3 "a" -#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" -#define TEST5 "\x07" -#define TEST6 "\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29\x9d\x6f\x9d\x93\xdf\x62" -#define TEST7 \ - "\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52\x06\x22\xd1\xac\x97\xd5" \ - "\xcd\xbe\x8c\xb3\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba\x09\xab" \ - "\xc8\x53\x3c\x52\x50\x88\x7a\x43\xbe\xbb\xac\x90\x6c\x2e\x18\x37" \ - "\xf2\x6b\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89\x6b\x71\x8b\x2a" \ - "\x38\x3e\xcd\xac\x16\xb9\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74" \ - "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11\x12\x24\x5f\x48\xee\x47" \ - "\x0d\x39\x6c\x1e\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee\xa8\x14" \ - "\xb6\x13\x5e\xca\x54\x39\x2b\xde\xdb\x94\x89\xbc\x9b\x87\x5a\x8b" \ - "\xaf\x0d\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2\x64\xbc\x07\x9d" \ - "\x26\x9f\x2c\x0d\x7e\xdd\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c" \ - "\x87\x82\x73" - - -#define DGST1 "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" -#define DGST2 "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" -#define DGST3 "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" -#define DGST4 "567F69F168CD7844E65259CE658FE7AADFA25216E68ECA0EB7AB8262" -#define DGST5 "00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450BEE2AA8C2A" -#define DGST6 "DF90D78AA78821C99B40BA4C966921ACCD8FFB1E98AC388E56191DB1" -#define DGST7 "0B31894EC8937AD9B91BDFBCBA294D9ADEFAA18E09305E9F20D5C3A4" - -struct { - char *data; - size_t length; - size_t count; - char *dgsthex; -} tests[7] = { - {TEST1, sizeof(TEST1) - 1, 1, DGST1}, - {TEST2, sizeof(TEST2) - 1, 1, DGST2}, - {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, - {TEST4, sizeof(TEST4) - 1, 10, DGST4}, - {TEST5, sizeof(TEST5) - 1, 1, DGST5}, - {TEST6, sizeof(TEST6) - 1, 1, DGST6}, - {TEST7, sizeof(TEST7) - 1, 1, DGST7}, -}; - -int main(int argc, char **argv) -{ - int err = 0; - SHA224_CTX ctx; - uint8_t dgst[SHA224_DIGEST_SIZE]; - uint8_t dgstbuf[SHA224_DIGEST_SIZE]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < 7; i++) { - hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); - - sha224_init(&ctx); - for (j = 0; j < tests[i].count; j++) { - sha224_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); - } - sha224_finish(&ctx, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - printf("sha224 test %lu failed\n", i+1); - printf("%s\n", tests[i].dgsthex); - for (j = 0; j < sizeof(dgst); j++) { - printf("%02X", dgst[j]); - } - printf("\n"); - err++; - } else { - printf("sha224 test %lu ok\n", i+1); - } - } - - return err; -} + + +#include +#include +#include +#include +#include +#include + + +#define TEST1 "abc" +#define TEST2 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +#define TEST3 "a" +#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" +#define TEST5 "\x07" +#define TEST6 "\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29\x9d\x6f\x9d\x93\xdf\x62" +#define TEST7 \ + "\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52\x06\x22\xd1\xac\x97\xd5" \ + "\xcd\xbe\x8c\xb3\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba\x09\xab" \ + "\xc8\x53\x3c\x52\x50\x88\x7a\x43\xbe\xbb\xac\x90\x6c\x2e\x18\x37" \ + "\xf2\x6b\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89\x6b\x71\x8b\x2a" \ + "\x38\x3e\xcd\xac\x16\xb9\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74" \ + "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11\x12\x24\x5f\x48\xee\x47" \ + "\x0d\x39\x6c\x1e\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee\xa8\x14" \ + "\xb6\x13\x5e\xca\x54\x39\x2b\xde\xdb\x94\x89\xbc\x9b\x87\x5a\x8b" \ + "\xaf\x0d\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2\x64\xbc\x07\x9d" \ + "\x26\x9f\x2c\x0d\x7e\xdd\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c" \ + "\x87\x82\x73" + + +#define DGST1 "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" +#define DGST2 "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" +#define DGST3 "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" +#define DGST4 "567F69F168CD7844E65259CE658FE7AADFA25216E68ECA0EB7AB8262" +#define DGST5 "00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450BEE2AA8C2A" +#define DGST6 "DF90D78AA78821C99B40BA4C966921ACCD8FFB1E98AC388E56191DB1" +#define DGST7 "0B31894EC8937AD9B91BDFBCBA294D9ADEFAA18E09305E9F20D5C3A4" + +struct { + char *data; + size_t length; + size_t count; + char *dgsthex; +} tests[7] = { + {TEST1, sizeof(TEST1) - 1, 1, DGST1}, + {TEST2, sizeof(TEST2) - 1, 1, DGST2}, + {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, + {TEST4, sizeof(TEST4) - 1, 10, DGST4}, + {TEST5, sizeof(TEST5) - 1, 1, DGST5}, + {TEST6, sizeof(TEST6) - 1, 1, DGST6}, + {TEST7, sizeof(TEST7) - 1, 1, DGST7}, +}; + +int main(int argc, char **argv) +{ + int err = 0; + SHA224_CTX ctx; + uint8_t dgst[SHA224_DIGEST_SIZE]; + uint8_t dgstbuf[SHA224_DIGEST_SIZE]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < 7; i++) { + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); + + sha224_init(&ctx); + for (j = 0; j < tests[i].count; j++) { + sha224_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); + } + sha224_finish(&ctx, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + printf("sha224 test %lu failed\n", i+1); + printf("%s\n", tests[i].dgsthex); + for (j = 0; j < sizeof(dgst); j++) { + printf("%02X", dgst[j]); + } + printf("\n"); + err++; + } else { + printf("sha224 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/sha256test.c b/tests/sha256test.c index c0de8a7e..65d43d2b 100644 --- a/tests/sha256test.c +++ b/tests/sha256test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,87 +7,88 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -#define TEST1 "abc" -#define TEST2 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" -#define TEST3 "a" -#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" -#define TEST5 "\x19" -#define TEST6 "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" -#define TEST7 "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ - "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ - "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ - "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ - "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ - "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ - "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ - "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ - "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ - "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ - "\x3d\x54\xd6" - -#define DGST1 "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD" -#define DGST2 "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1" -#define DGST3 "CDC76E5C9914FB9281A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" -#define DGST4 "594847328451BDFA85056225462CC1D867D877FB388DF0CE35F25AB5562BFBB5" -#define DGST5 "68AA2E2EE5DFF96E3355E6C7EE373E3D6A4E17F75F9518D843709C0C9BC3E3D4" -#define DGST6 "175EE69B02BA9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" -#define DGST7 "97DBCA7DF46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" - -struct { - char *data; - size_t length; - size_t count; - char *dgsthex; -} tests[7] = { - {TEST1, sizeof(TEST1) - 1, 1, DGST1}, - {TEST2, sizeof(TEST2) - 1, 1, DGST2}, - {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, - {TEST4, sizeof(TEST4) - 1, 10, DGST4}, - {TEST5, sizeof(TEST5) - 1, 1, DGST5}, - {TEST6, sizeof(TEST6) - 1, 1, DGST6}, - {TEST7, sizeof(TEST7) - 1, 1, DGST7}, -}; - -int main(int argc, char **argv) -{ - int err = 0; - SHA256_CTX ctx; - uint8_t dgst[SHA256_DIGEST_SIZE]; - uint8_t dgstbuf[SHA256_DIGEST_SIZE]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < 7; i++) { - hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); - - sha256_init(&ctx); - for (j = 0; j < tests[i].count; j++) { - sha256_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); - } - sha256_finish(&ctx, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - printf("sha256 test %lu failed\n", i+1); - printf("%s\n", tests[i].dgsthex); - for (j = 0; j < sizeof(dgst); j++) { - printf("%02X", dgst[j]); - } - printf("\n"); - err++; - } else { - printf("sha256 test %lu ok\n", i+1); - } - } - - return err; -} + + + +#include +#include +#include +#include +#include +#include + + +#define TEST1 "abc" +#define TEST2 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +#define TEST3 "a" +#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" +#define TEST5 "\x19" +#define TEST6 "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" +#define TEST7 "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ + "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ + "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ + "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ + "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ + "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ + "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ + "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ + "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ + "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ + "\x3d\x54\xd6" + +#define DGST1 "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD" +#define DGST2 "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1" +#define DGST3 "CDC76E5C9914FB9281A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" +#define DGST4 "594847328451BDFA85056225462CC1D867D877FB388DF0CE35F25AB5562BFBB5" +#define DGST5 "68AA2E2EE5DFF96E3355E6C7EE373E3D6A4E17F75F9518D843709C0C9BC3E3D4" +#define DGST6 "175EE69B02BA9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" +#define DGST7 "97DBCA7DF46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" + +struct { + char *data; + size_t length; + size_t count; + char *dgsthex; +} tests[7] = { + {TEST1, sizeof(TEST1) - 1, 1, DGST1}, + {TEST2, sizeof(TEST2) - 1, 1, DGST2}, + {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, + {TEST4, sizeof(TEST4) - 1, 10, DGST4}, + {TEST5, sizeof(TEST5) - 1, 1, DGST5}, + {TEST6, sizeof(TEST6) - 1, 1, DGST6}, + {TEST7, sizeof(TEST7) - 1, 1, DGST7}, +}; + +int main(int argc, char **argv) +{ + int err = 0; + SHA256_CTX ctx; + uint8_t dgst[SHA256_DIGEST_SIZE]; + uint8_t dgstbuf[SHA256_DIGEST_SIZE]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < 7; i++) { + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); + + sha256_init(&ctx); + for (j = 0; j < tests[i].count; j++) { + sha256_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); + } + sha256_finish(&ctx, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + printf("sha256 test %lu failed\n", i+1); + printf("%s\n", tests[i].dgsthex); + for (j = 0; j < sizeof(dgst); j++) { + printf("%02X", dgst[j]); + } + printf("\n"); + err++; + } else { + printf("sha256 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/sha384test.c b/tests/sha384test.c index 4f5088e1..99df58c5 100644 --- a/tests/sha384test.c +++ b/tests/sha384test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,93 +7,94 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -#define TEST1 "abc" -#define TEST2 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" \ - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" -#define TEST3 "a" -#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" -#define TEST5 "\xb9" -#define TEST6 "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39" -#define TEST7 "\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb\x69\x12\xec\x10\xff\xcf" \ - "\x74\x79\x03\x49\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21\xdb\x0f" \ - "\x3e\x7d\xc8\x7f\x82\x32\x64\xbb\xe4\x0d\x18\x11\xc9\xea\x20\x61" \ - "\xe1\xc8\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02\xfc\x3f\x50\x42" \ - "\xe6\xbf\x58\xcb\xa8\xa2\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71" \ - "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86\x5f\x25\xcc\x22\xb5\xe8" \ - "\x77\x84\xa1\x2f\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a\x2c\xe6" \ - "\x56\x5c\xbd\xf1\x3d\xca\x40\x38\x32\xcf\xcb\x0e\x8b\x72\x11\xe8" \ - "\x3a\xf3\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5\x1c\xc0\x27\xaa" \ - "\xed\xef\xf8\x5a\xad\x7c\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a" \ - "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15\x1c\xb9\xbc\x51\x25\xa4" \ - "\x22\xe9\x41\xde\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd\xd0\x96" \ - "\x76\x71\x1c\xf3\xdb\x0a\x34\x40\x72\x0e\x16\x15\xc1\xf2\x2f\xbc" \ - "\x3c\x72\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77\x40\x86\x42\x14" \ - "\x7e\xd0\x96" - -#define DGST1 "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" -#define DGST2 "09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" -#define DGST3 "9D0E1809716474CB086E834E310A4A1CED149E9C00F248527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" -#define DGST4 "2FC64A4F500DDB6828F6A3430B8DD72A368EB7F3A8322A70BC84275B9C0B3AB00D27A5CC3C2D224AA6B61A0D79FB4596" -#define DGST5 "BC8089A19007C0B14195F4ECC74094FEC64F01F90929282C2FB392881578208AD466828B1C6C283D2722CF0AD1AB6938" -#define DGST6 "C9A68443A005812256B8EC76B00516F0DBB74FAB26D665913F194B6FFB0E91EA9967566B58109CBC675CC208E4C823F7" -#define DGST7 "4F440DB1E6EDD2899FA335F09515AA025EE177A79F4B4AAF38E42B5C4DE660F5DE8FB2A5B2FBD2A3CBFFD20CFF1288C0" - - -struct { - char *data; - size_t length; - size_t count; - char *dgsthex; -} tests[7] = { - {TEST1, sizeof(TEST1) - 1, 1, DGST1}, - {TEST2, sizeof(TEST2) - 1, 1, DGST2}, - {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, - {TEST4, sizeof(TEST4) - 1, 10, DGST4}, - {TEST5, sizeof(TEST5) - 1, 1, DGST5}, - {TEST6, sizeof(TEST6) - 1, 1, DGST6}, - {TEST7, sizeof(TEST7) - 1, 1, DGST7}, -}; - -int main(void) -{ - int err = 0; - SHA384_CTX ctx; - uint8_t dgst[SHA384_DIGEST_SIZE]; - uint8_t dgstbuf[SHA384_DIGEST_SIZE]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < 7; i++) { - hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); - - sha384_init(&ctx); - for (j = 0; j < tests[i].count; j++) { - sha384_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); - } - sha384_finish(&ctx, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - printf("sha384 test %lu failed\n", i+1); - printf("%s\n", tests[i].dgsthex); - for (j = 0; j < sizeof(dgst); j++) { - printf("%02x", dgst[j]); - } - printf("\n"); - err++; - } else { - printf("sha384 test %lu ok\n", i+1); - } - } - - return err; -} + + + +#include +#include +#include +#include +#include +#include + + +#define TEST1 "abc" +#define TEST2 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" \ + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" +#define TEST3 "a" +#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" +#define TEST5 "\xb9" +#define TEST6 "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39" +#define TEST7 "\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb\x69\x12\xec\x10\xff\xcf" \ + "\x74\x79\x03\x49\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21\xdb\x0f" \ + "\x3e\x7d\xc8\x7f\x82\x32\x64\xbb\xe4\x0d\x18\x11\xc9\xea\x20\x61" \ + "\xe1\xc8\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02\xfc\x3f\x50\x42" \ + "\xe6\xbf\x58\xcb\xa8\xa2\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71" \ + "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86\x5f\x25\xcc\x22\xb5\xe8" \ + "\x77\x84\xa1\x2f\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a\x2c\xe6" \ + "\x56\x5c\xbd\xf1\x3d\xca\x40\x38\x32\xcf\xcb\x0e\x8b\x72\x11\xe8" \ + "\x3a\xf3\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5\x1c\xc0\x27\xaa" \ + "\xed\xef\xf8\x5a\xad\x7c\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a" \ + "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15\x1c\xb9\xbc\x51\x25\xa4" \ + "\x22\xe9\x41\xde\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd\xd0\x96" \ + "\x76\x71\x1c\xf3\xdb\x0a\x34\x40\x72\x0e\x16\x15\xc1\xf2\x2f\xbc" \ + "\x3c\x72\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77\x40\x86\x42\x14" \ + "\x7e\xd0\x96" + +#define DGST1 "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" +#define DGST2 "09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" +#define DGST3 "9D0E1809716474CB086E834E310A4A1CED149E9C00F248527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" +#define DGST4 "2FC64A4F500DDB6828F6A3430B8DD72A368EB7F3A8322A70BC84275B9C0B3AB00D27A5CC3C2D224AA6B61A0D79FB4596" +#define DGST5 "BC8089A19007C0B14195F4ECC74094FEC64F01F90929282C2FB392881578208AD466828B1C6C283D2722CF0AD1AB6938" +#define DGST6 "C9A68443A005812256B8EC76B00516F0DBB74FAB26D665913F194B6FFB0E91EA9967566B58109CBC675CC208E4C823F7" +#define DGST7 "4F440DB1E6EDD2899FA335F09515AA025EE177A79F4B4AAF38E42B5C4DE660F5DE8FB2A5B2FBD2A3CBFFD20CFF1288C0" + + +struct { + char *data; + size_t length; + size_t count; + char *dgsthex; +} tests[7] = { + {TEST1, sizeof(TEST1) - 1, 1, DGST1}, + {TEST2, sizeof(TEST2) - 1, 1, DGST2}, + {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, + {TEST4, sizeof(TEST4) - 1, 10, DGST4}, + {TEST5, sizeof(TEST5) - 1, 1, DGST5}, + {TEST6, sizeof(TEST6) - 1, 1, DGST6}, + {TEST7, sizeof(TEST7) - 1, 1, DGST7}, +}; + +int main(void) +{ + int err = 0; + SHA384_CTX ctx; + uint8_t dgst[SHA384_DIGEST_SIZE]; + uint8_t dgstbuf[SHA384_DIGEST_SIZE]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < 7; i++) { + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); + + sha384_init(&ctx); + for (j = 0; j < tests[i].count; j++) { + sha384_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); + } + sha384_finish(&ctx, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + printf("sha384 test %lu failed\n", i+1); + printf("%s\n", tests[i].dgsthex); + for (j = 0; j < sizeof(dgst); j++) { + printf("%02x", dgst[j]); + } + printf("\n"); + err++; + } else { + printf("sha384 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/sha512test.c b/tests/sha512test.c index cd95dfa9..e0116ae3 100644 --- a/tests/sha512test.c +++ b/tests/sha512test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,94 +7,95 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include - - -#define TEST1 "abc" -#define TEST2 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" \ - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" -#define TEST3 "a" -#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" -#define TEST5 "\xD0" -#define TEST6 "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" -#define TEST7 \ - "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ - "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ - "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ - "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ - "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ - "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ - "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ - "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ - "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ - "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" \ - "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1" \ - "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8" \ - "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b" \ - "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7" \ - "\xfb\x40\xd2" - -#define DGST1 "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F" -#define DGST2 "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909" -#define DGST3 "E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B" -#define DGST4 "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB510813A39CD5A84C4ACAA64D3F3FB7BAE9" -#define DGST5 "9992202938E882E73E20F6B69E68A0A7149090423D93C81BAB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA8306826C4AD6E74CECE9631BFA8A549B4AB3FBBA15" -#define DGST6 "CB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75ACBDD1C153C9828924C3DDEDAAFE669C5FDD0BC66F630F6773988213EB1B16F517AD0DE4B2F0C95C90F8" -#define DGST7 "C665BEFB36DA189D78822D10528CBF3B12B3EEF726039909C1A16A270D48719377966B957A878E720584779A62825C18DA26415E49A7176A894E7510FD1451F5" - - -struct { - char *data; - size_t length; - size_t count; - char *dgsthex; -} tests[7] = { - {TEST1, sizeof(TEST1) - 1, 1, DGST1}, - {TEST2, sizeof(TEST2) - 1, 1, DGST2}, - {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, - {TEST4, sizeof(TEST4) - 1, 10, DGST4}, - {TEST5, sizeof(TEST5) - 1, 1, DGST5}, - {TEST6, sizeof(TEST6) - 1, 1, DGST6}, - {TEST7, sizeof(TEST7) - 1, 1, DGST7}, -}; - -int main(void) -{ - int err = 0; - SHA512_CTX ctx; - uint8_t dgst[SHA512_DIGEST_SIZE]; - uint8_t dgstbuf[SHA512_DIGEST_SIZE]; - size_t dgstlen; - size_t i, j; - - for (i = 0; i < 7; i++) { - hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); - - sha512_init(&ctx); - for (j = 0; j < tests[i].count; j++) { - sha512_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); - } - sha512_finish(&ctx, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - printf("sha512 test %lu failed\n", i+1); - printf("%s\n", tests[i].dgsthex); - for (j = 0; j < sizeof(dgst); j++) { - printf("%02x", dgst[j]); - } - printf("\n"); - err++; - } else { - printf("sha512 test %lu ok\n", i+1); - } - } - - return err; -} + + + +#include +#include +#include +#include +#include +#include + + +#define TEST1 "abc" +#define TEST2 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" \ + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" +#define TEST3 "a" +#define TEST4 "0123456701234567012345670123456701234567012345670123456701234567" +#define TEST5 "\xD0" +#define TEST6 "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" +#define TEST7 \ + "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ + "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ + "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ + "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ + "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ + "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ + "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ + "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ + "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ + "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" \ + "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1" \ + "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8" \ + "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b" \ + "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7" \ + "\xfb\x40\xd2" + +#define DGST1 "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F" +#define DGST2 "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909" +#define DGST3 "E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B" +#define DGST4 "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB510813A39CD5A84C4ACAA64D3F3FB7BAE9" +#define DGST5 "9992202938E882E73E20F6B69E68A0A7149090423D93C81BAB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA8306826C4AD6E74CECE9631BFA8A549B4AB3FBBA15" +#define DGST6 "CB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75ACBDD1C153C9828924C3DDEDAAFE669C5FDD0BC66F630F6773988213EB1B16F517AD0DE4B2F0C95C90F8" +#define DGST7 "C665BEFB36DA189D78822D10528CBF3B12B3EEF726039909C1A16A270D48719377966B957A878E720584779A62825C18DA26415E49A7176A894E7510FD1451F5" + + +struct { + char *data; + size_t length; + size_t count; + char *dgsthex; +} tests[7] = { + {TEST1, sizeof(TEST1) - 1, 1, DGST1}, + {TEST2, sizeof(TEST2) - 1, 1, DGST2}, + {TEST3, sizeof(TEST3) - 1, 1000000, DGST3}, + {TEST4, sizeof(TEST4) - 1, 10, DGST4}, + {TEST5, sizeof(TEST5) - 1, 1, DGST5}, + {TEST6, sizeof(TEST6) - 1, 1, DGST6}, + {TEST7, sizeof(TEST7) - 1, 1, DGST7}, +}; + +int main(void) +{ + int err = 0; + SHA512_CTX ctx; + uint8_t dgst[SHA512_DIGEST_SIZE]; + uint8_t dgstbuf[SHA512_DIGEST_SIZE]; + size_t dgstlen; + size_t i, j; + + for (i = 0; i < 7; i++) { + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); + + sha512_init(&ctx); + for (j = 0; j < tests[i].count; j++) { + sha512_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); + } + sha512_finish(&ctx, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + printf("sha512 test %lu failed\n", i+1); + printf("%s\n", tests[i].dgsthex); + for (j = 0; j < sizeof(dgst); j++) { + printf("%02x", dgst[j]); + } + printf("\n"); + err++; + } else { + printf("sha512 test %lu ok\n", i+1); + } + } + + return err; +} diff --git a/tests/sm2test.c b/tests/sm2test.c index 59622337..a3f86d49 100644 --- a/tests/sm2test.c +++ b/tests/sm2test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,850 +7,851 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - -#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中 - - -#define hex_fp_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567" -#define hex_fp_sub_x_y "768d77882a23097d05db3562fed0a840bf3984422c3bc4a26e7b12a412128426" -#define hex_fp_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9" -#define hex_fp_neg_x "cd3b51d2e0e67ee6a066fbb995c6366b701cf43f0d99f41f8ea5ba76ccb38b38" -#define hex_fp_mul_x_y "edd7e745bdc4630ccfa1da1057033a525346dbf202f082f3c431349991ace76a" -#define hex_fp_squ_x "f4e2cca0bcfd67fba8531eebff519e4cb3d47f9fe8c5eff5151f4c497ec99fbf" -#define hex_fp_exp_x_y "8cafd11b1a0d2072b82911ba87e0d376103a1be5986fce91d8d297b758f68146" -#define hex_fp_inv_x "053b878fb82e213c17e554b9a574b7bd31775222704b7fd9c7d6f8441026cd80" - -#define hex_fn_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567" -#define hex_fn_sub_x_y "768d77882a23097d05db3562fed0a840313d63ae4e01c9ccc23706ad4be7c54a" -#define hex_fn_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9" -#define hex_fn_neg_x "cd3b51d2e0e67ee6a066fbb995c6366ae220d3ab2f5ff949e261ae800688cc5c" -#define hex_fn_mul_x_y "cf7296d5cbf0b64bb5e9a11b294962e9c779b41c038e9c8d815234a0df9d6623" -#define hex_fn_sqr_x "82d3d1b296d3a3803888b7ffc78f23eca824e7ec8d7ddaf231ffb0d256a19da2" -#define hex_fn_exp_x_y "0cf4df7e76d7d49ff23b94853a98aba1e36e9ca0358acbf23a3bbda406f46df3" -#define hex_fn_inv_x "96340ec8b80f44e9b345a706bdb5c9e3ab8a6474a5cb4e0d4645dbaecf1cf03d" -#define hex_v "d3da0ef661be97360e1b32f834e6ca5673b1984b22bb420133da05e56ccd59fb" -#define hex_fn_mul_x_v "0375c61e1ed13e460f4b5d462dc5b2c846f36c7b481cd4bed8f7dd55908a6afd" - -#define hex_t "2fbadf57b52dc19e8470bf201cb182e0a4f7fa5e28d356b15da173132b94b325" - - -int test_sm2_bn(void) -{ - SM2_BN r; - SM2_BN x; - SM2_BN y; - int ok, i = 1; - - char hex[65]; - - SM2_BN v = { - 0x6ccd59fb, 0x33da05e5, 0x22bb4201, 0x73b1984b, - 0x34e6ca56, 0x0e1b32f8, 0x61be9736, 0xd3da0ef6, - }; - - SM2_BN t; - - sm2_bn_copy(x, SM2_G->X); - sm2_bn_copy(y, SM2_G->Y); - - sm2_bn_from_hex(r, hex_v); - ok = (sm2_bn_cmp(r, v) == 0); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - // fp tests - sm2_fp_add(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fp_add_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fp_sub(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fp_sub_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fp_mul(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fp_mul_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fp_exp(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fp_exp_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fp_inv(r, x); - ok = sm2_bn_equ_hex(r, hex_fp_inv_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fp_neg(r, x); - ok = sm2_bn_equ_hex(r, hex_fp_neg_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - // fn tests - sm2_fn_add(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fn_add_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_sub(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fn_sub_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_sub(r, y, x); - ok = sm2_bn_equ_hex(r, hex_fn_sub_y_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_neg(r, x); - ok = sm2_bn_equ_hex(r, hex_fn_neg_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_mul(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fn_mul_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_mul(r, x, v); - ok = sm2_bn_equ_hex(r, hex_fn_mul_x_v); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_sqr(r, x); - ok = sm2_bn_equ_hex(r, hex_fn_sqr_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_exp(r, x, y); - ok = sm2_bn_equ_hex(r, hex_fn_exp_x_y); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_fn_inv(r, x); - ok = sm2_bn_equ_hex(r, hex_fn_inv_x); - printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - SM2_BN tv = { - 0x2b94b325, 0x5da17313, 0x28d356b1, 0xa4f7fa5e, - 0x1cb182e0, 0x8470bf20, 0xb52dc19e, 0x2fbadf57, - }; - sm2_bn_from_hex(t, hex_t); - ok = (sm2_bn_cmp(t, tv) == 0); - if (!ok) return -1; - - sm2_bn_to_hex(t, hex); - - return 1; -} - - -#define hex_G \ - "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \ - "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0" -#define hex_2G \ - "56cefd60d7c87c000d58ef57fa73ba4d9c0dfa08c08a7331495c2e1da3f2bd52" \ - "31b7e7e6cc8189f668535ce0f8eaf1bd6de84c182f6c8e716f780d3a970a23c3" -#define hex_3G \ - "a97f7cd4b3c993b4be2daa8cdb41e24ca13f6bd945302244e26918f1d0509ebf" \ - "530b5dd88c688ef5ccc5cec08a72150f7c400ee5cd045292aaacdd037458f6e6" -#define hex_negG \ - "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \ - "43c8c95c0b098863a642311c9496deac2f56788239d5b8c0fd20cd1adec60f5f" -#define hex_10G \ - "d3f94862519621c121666061f65c3e32b2d0d065cd219e3284a04814db522756" \ - "4b9030cf676f6a742ebd57d146dca428f6b743f64d1482d147d46fb2bab82a14" -#define hex_bG \ - "528470bc74a6ebc663c06fc4cfa1b630d1e9d4a80c0a127b47f73c324c46c0ba" \ - "832cf9c5a15b997e60962b4cf6e2c9cee488faaec98d20599d323d4cabfc1bf4" - -#define hex_P \ - "504cfe2fae749d645e99fbb5b25995cc6fed70196007b039bdc44706bdabc0d9" \ - "b80a8018eda5f55ddc4b870d7784b7b84e53af02f575ab53ed8a99a3bbe2abc2" -#define hex_2P \ - "a53d20e89312b5243f66aec12ef6471f5911941d86302d5d8337cb70937d65ae" \ - "96953c46815e4259363256ddd6c77fcc33787aeafc6a57beec5833f476dd69e0" - -#define hex_tP \ - "02deff2c5b3656ca3f7c7ca9d710ca1d69860c75a9c7ec284b96b8adc50b2936" \ - "b74bcba937e9267fce4ccc069a6681f5b04dcedd9e2794c6a25ddc7856df7145" - - -int test_sm2_jacobian_point(void) -{ - SM2_JACOBIAN_POINT _P, *P = &_P; - SM2_JACOBIAN_POINT _G, *G = &_G; - SM2_BN k; - int i = 1, ok; - - uint8_t buf[64]; - - printf("sm2_jacobian_point_test\n"); - - sm2_jacobian_point_copy(G, SM2_G); - ok = sm2_jacobian_point_equ_hex(G, hex_G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - ok = sm2_jacobian_point_is_on_curve(G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_dbl(P, G); - ok = sm2_jacobian_point_equ_hex(P, hex_2G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_add(P, P, G); - ok = sm2_jacobian_point_equ_hex(P, hex_3G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_sub(P, P, G); - ok = sm2_jacobian_point_equ_hex(P, hex_2G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_neg(P, G); - ok = sm2_jacobian_point_equ_hex(P, hex_negG); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_bn_set_word(k, 10); - sm2_jacobian_point_mul(P, k, G); - ok = sm2_jacobian_point_equ_hex(P, hex_10G); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_mul_generator(P, SM2_B); - ok = sm2_jacobian_point_equ_hex(P, hex_bG); - printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); - if (!ok) return -1; - - sm2_jacobian_point_to_bytes(P, buf); - sm2_jacobian_point_from_hex(P, hex_P); - - return 1; -} - -#define hex_d "5aebdfd947543b713bc0df2c65baaecc5dadd2cab39c6971402daf92c263fad2" -#define hex_e "c0881c19beec741b9af27cc26493dcc33b05d481bfeab2f3ce9cc056e6ff8400" -#define hex_k "981325ee1ab171e9d2cffb317181a02957b18a34bca610a6d2f8afcdeb53f6b8" -#define hex_x1 "17d2dfe83f23cce8499bca983950d59f0fd56c4c671dd63c04b27e4e94cfd767" -#define hex_r "d85afc01fe104103e48e475a9de4b2624adb40ce2708892fd34f3ea57bcf5b67" -#define hex_rd "a70ba64f9c30e05095f39fe26675114e3f157b2c35191bf6ff06246452f82eb3" -#define hex_di "3ecfdb51c24b0eecb2d4238d1da8c013b8b575cef14ef43e2ddb7bce740ce9cf" -#define hex_krd "f1077f9d7e8091993cdc5b4f0b0c8eda8a9fee73a952f9db27ae7f72d2310928" -#define hex_s "006bac5b8057ca829534dfde72a0d7883444a3b9bfe9bcdfb383fb90ed7d9486" - - -static int test_sm2_point(void) -{ - SM2_POINT P, Q; - uint8_t k[32] = {0}; - uint8_t buf[65] = {0}; - int i; - - for (i = 1; i < 8; i++) { - k[31] = (uint8_t)i; - - if (sm2_point_mul_generator(&P, k) != 1 - || sm2_point_is_on_curve(&P) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "k = %d, ", i); - sm2_point_print(stderr, 0, 0, "k * G", &P); - - memset(buf, 0, sizeof(buf)); - sm2_point_to_compressed_octets(&P, buf); - format_bytes(stderr, 0, 4, "compressedPoint", buf, 33); - memset(&Q, 0, sizeof(Q)); - if (sm2_point_from_x(&Q, buf + 1, buf[0]) != 1 - || memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { - - sm2_point_print(stderr, 0, 4, "P", &P); - sm2_point_print(stderr, 0, 4, "Q", &Q); - - error_print(); - return -1; - } - - memset(buf, 0, sizeof(buf)); - sm2_point_to_uncompressed_octets(&P, buf); - format_bytes(stderr, 0, 4, "compressedPoint", buf, 65); - memset(&Q, 0, sizeof(Q)); - if (sm2_point_from_octets(&Q, buf, 65) != 1 - || memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { - error_print(); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_point_der(void) -{ - SM2_POINT P, Q; - uint8_t k[32] = {0}; - uint8_t buf[512]; - int i; - - for (i = 1; i < 8; i++) { - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - k[31] = i; - memset(&P, 0, sizeof(P)); - memset(&Q, 0, sizeof(Q)); - - if (sm2_point_mul_generator(&P, k) != 1 - || sm2_point_to_der(&P, &p, &len) != 1 - || format_bytes(stderr, 0, 4, "ECPoint", buf, len) != 1 - || sm2_point_from_der(&Q, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { - error_print(); - sm2_point_print(stderr, 0, 4, "P", &P); - sm2_point_print(stderr, 0, 4, "Q", &Q); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_point_octets(void) -{ - SM2_POINT P, Q; - uint8_t k[32] = {0}; - uint8_t buf[33]; - int i; - - for (i = 1; i < 8; i++) { - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - k[31] = i; - memset(&P, 0, sizeof(P)); - memset(&Q, 0, sizeof(Q)); - - if (sm2_point_mul_generator(&P, k) != 1) { - error_print(); - return -1; - } - sm2_point_to_compressed_octets(&P, buf); - format_bytes(stderr, 0, 4, "compressedPoint", buf, sizeof(buf)); - if (sm2_point_from_octets(&Q, buf, sizeof(buf)) != 1) { - error_print(); - return -1; - } - if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { - error_print(); - sm2_point_print(stderr, 0, 4, "P", &P); - sm2_point_print(stderr, 0, 4, "Q", &Q); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_point_from_x(void) -{ - SM2_POINT P, Q; - uint8_t k[32] = {0}; - uint8_t buf[33]; - int i; - - for (i = 1; i < 8; i++) { - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - k[31] = i; - memset(&P, 0, sizeof(P)); - memset(&Q, 0, sizeof(Q)); - - if (sm2_point_mul_generator(&P, k) != 1) { - error_print(); - return -1; - } - sm2_point_to_compressed_octets(&P, buf); - if (sm2_point_from_x(&Q, buf + 1, buf[0]) != 1) { - error_print(); - return -1; - } - if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { - error_print(); - sm2_point_print(stderr, 0, 4, "P", &P); - sm2_point_print(stderr, 0, 4, "Q", &Q); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_signature(void) -{ - SM2_SIGNATURE sig; - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - // MinLen - memset(&sig, 0x00, sizeof(sig)); - cp = p = buf; len = 0; - if (sm2_signature_to_der(&sig, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "SM2_MIN_SIGNATURE_SIZE: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - sm2_signature_print(stderr, 0, 4, "signature", buf, len); - if (len != SM2_MIN_SIGNATURE_SIZE) { - error_print(); - return -1; - } - if (sm2_signature_from_der(&sig, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - - // MaxLen - memset(&sig, 0x80, sizeof(sig)); - cp = p = buf; len = 0; - if (sm2_signature_to_der(&sig, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "SM2_MAX_SIGNATURE_SIZE: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - sm2_signature_print(stderr, 0, 4, "signature", buf, len); - if (len != SM2_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - if (sm2_signature_from_der(&sig, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_sign(void) -{ - int ret; - SM2_KEY sm2_key; - SM2_SIGN_CTX sign_ctx; - uint8_t msg[] = "Hello World!"; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE] = {0}; - size_t siglen; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); - - if (sm2_sign_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 - || sm2_sign_update(&sign_ctx, msg, sizeof(msg)) != 1 - || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "signature", sig, siglen); - sm2_signature_print(stderr, 0, 4, "signature", sig, siglen); - - if (sm2_verify_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 - || sm2_verify_update(&sign_ctx, msg, sizeof(msg)) != 1 - || (ret = sm2_verify_finish(&sign_ctx, sig, siglen)) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "verification: %s\n", ret ? "success" : "failed"); - - - // FIXME: 还应该增加验证不通过的测试 - // 还应该增加底层的参数 - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -// 由于当前Ciphertext中椭圆曲线点数据不正确,因此无法通过测试 -static int test_sm2_ciphertext(void) -{ - SM2_CIPHERTEXT C; - uint8_t buf[1024]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - memset(&C, 0, sizeof(SM2_CIPHERTEXT)); - - cp = p = buf; len = 0; - if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "SM2_NULL_CIPHERTEXT_SIZE: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - - - if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - - // {0, 0, Hash, MinLen} - C.ciphertext_size = SM2_MIN_PLAINTEXT_SIZE; - cp = p = buf; len = 0; - if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "SM2_MIN_PLAINTEXT_SIZE: %zu\n", SM2_MIN_PLAINTEXT_SIZE); - format_print(stderr, 0, 4, "SM2_MIN_CIPHERTEXT_SIZE: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - if (len != SM2_MIN_CIPHERTEXT_SIZE) { - error_print(); - return -1; - } - if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - // { 33, 33, Hash, NULL } - memset(&C, 0x80, sizeof(SM2_POINT)); - cp = p = buf; len = 0; - if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "ciphertext len: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - // { 33, 33, Hash, MaxLen } - C.ciphertext_size = SM2_MAX_PLAINTEXT_SIZE;//SM2_MAX_PLAINTEXT_SIZE; - cp = p = buf; len = 0; - if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "SM2_MAX_PLAINTEXT_SIZE: %zu\n", SM2_MAX_PLAINTEXT_SIZE); - format_print(stderr, 0, 4, "SM2_MAX_CIPHERTEXT_SIZE: %zu\n", len); - format_bytes(stderr, 0, 4, "", buf, len); - if (len != SM2_MAX_CIPHERTEXT_SIZE) { - error_print(); - return -1; - } - if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - -static int test_sm2_do_encrypt(void) -{ - SM2_KEY sm2_key; - uint8_t plaintext[] = "Hello World!"; - SM2_CIPHERTEXT ciphertext; - - uint8_t plainbuf[SM2_MAX_PLAINTEXT_SIZE] = {0}; - size_t plainlen = 0; - int r = 0; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - - if (sm2_do_encrypt(&sm2_key, plaintext, sizeof(plaintext), &ciphertext) != 1 - || sm2_do_decrypt(&sm2_key, &ciphertext, plainbuf, &plainlen) != 1) { - error_print(); - return -1; - } - - if (plainlen != sizeof(plaintext) - || memcmp(plainbuf, plaintext, sizeof(plaintext)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - -static int test_sm2_encrypt(void) -{ - SM2_KEY sm2_key; - uint8_t msg[SM2_MAX_PLAINTEXT_SIZE]; - uint8_t cbuf[SM2_MAX_CIPHERTEXT_SIZE+100]; - uint8_t mbuf[SM2_MAX_CIPHERTEXT_SIZE]; - size_t lens[] = { -// 0, - 1, - 16, - SM2_MAX_PLAINTEXT_SIZE, - }; - size_t clen, mlen; - int i; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - - for (i = 0; i < sizeof(msg); i++) { - msg[i] = (uint8_t)i; - } - - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - format_print(stderr, 0, 0, "test %d\n", i + 1); - format_bytes(stderr, 0, 4, "plaintext", msg, lens[i]); - if (sm2_encrypt(&sm2_key, msg, lens[i], cbuf, &clen) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "ciphertext", cbuf, clen); - sm2_ciphertext_print(stderr, 0, 4, "Ciphertext", cbuf, clen); - format_print(stderr, 0, 0, "\n"); - - if (sm2_decrypt(&sm2_key, cbuf, clen, mbuf, &mlen) != 1) { - error_print(); - return -1; - } - if (mlen != lens[i] - || memcmp(mbuf, msg, lens[i]) != 0) { - error_print(); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - - -static int test_sm2_private_key(void) -{ - SM2_KEY sm2_key; - SM2_KEY tmp_key; - uint8_t buf[SM2_PRIVATE_KEY_BUF_SIZE]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); - - if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "ECPrivateKey", buf, len); - format_print(stderr, 0, 4, "#define SM2_PRIVATE_KEY_DEFAULT_SIZE %zu\n", len); - if (sm2_private_key_from_der(&tmp_key, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - if (memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { - - sm2_key_print(stderr, 0, 0, "sm2_key", &sm2_key); - sm2_key_print(stderr, 0, 0, "tmp_key", &tmp_key); - - - error_print(); - return -1; - } - - cp = p = buf; len = 0; - memset(&tmp_key, 0, sizeof(tmp_key)); - if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - sm2_private_key_print(stderr, 0, 4, "ECPrivateKey", d, dlen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_private_key_info(void) -{ - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - SM2_KEY sm2_key; - SM2_KEY tmp_key; - const uint8_t *attrs; - size_t attrs_len; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); - - if (sm2_private_key_info_to_der(&sm2_key, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "PrivateKeyInfo", buf, len); - format_print(stderr, 0, 4, "sizeof(PrivateKeyInfo): %zu\n", len); - if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - sm2_private_key_info_print(stderr, 0, 4, "PrivateKeyInfo", d, dlen); - - cp = p = buf; len = 0; - if (sm2_private_key_info_to_der(&sm2_key, &p, &len) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_info_from_der(&tmp_key, &attrs, &attrs_len, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1 - || memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm2_enced_private_key_info(void) -{ - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - SM2_KEY sm2_key; - SM2_KEY tmp_key; - const uint8_t *attrs; - size_t attrs_len; - const char *pass = "Password"; - - if (sm2_key_generate(&sm2_key) != 1) { - error_print(); - return -1; - } - sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); - - if (sm2_private_key_info_encrypt_to_der(&sm2_key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "EncryptedPrivateKeyInfo", buf, len); - format_print(stderr, 0, 4, "sizeof(EncryptedPrivateKeyInfo): %zu\n", len); - if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - pkcs8_enced_private_key_info_print(stderr, 0, 4, "EncryptedPrivateKeyInfo", d, dlen); - - - cp = p = buf; len = 0; - if (sm2_private_key_info_encrypt_to_der(&sm2_key, pass, &p, &len) != 1) { - error_print(); - return -1; - } - if (sm2_private_key_info_decrypt_from_der(&tmp_key, &attrs, &attrs_len, pass, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1 - || memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - -int main(void) -{ - if (test_sm2_bn() != 1) goto err; - if (test_sm2_jacobian_point() != 1) goto err; - if (test_sm2_point() != 1) goto err; - if (test_sm2_point_octets() != 1) goto err; - if (test_sm2_point_from_x() != 1) goto err; - if (test_sm2_point_der() != 1) goto err; - if (test_sm2_private_key() != 1) goto err; - if (test_sm2_private_key_info() != 1) goto err; - if (test_sm2_enced_private_key_info() != 1) goto err; - if (test_sm2_signature() != 1) goto err; - if (test_sm2_sign() != 1) goto err; - //if (test_sm2_ciphertext() != 1) goto err; // 需要正确的Ciphertext数据 - if (test_sm2_do_encrypt() != 1) goto err; - if (test_sm2_encrypt() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include + +#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中 + + +#define hex_fp_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567" +#define hex_fp_sub_x_y "768d77882a23097d05db3562fed0a840bf3984422c3bc4a26e7b12a412128426" +#define hex_fp_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9" +#define hex_fp_neg_x "cd3b51d2e0e67ee6a066fbb995c6366b701cf43f0d99f41f8ea5ba76ccb38b38" +#define hex_fp_mul_x_y "edd7e745bdc4630ccfa1da1057033a525346dbf202f082f3c431349991ace76a" +#define hex_fp_squ_x "f4e2cca0bcfd67fba8531eebff519e4cb3d47f9fe8c5eff5151f4c497ec99fbf" +#define hex_fp_exp_x_y "8cafd11b1a0d2072b82911ba87e0d376103a1be5986fce91d8d297b758f68146" +#define hex_fp_inv_x "053b878fb82e213c17e554b9a574b7bd31775222704b7fd9c7d6f8441026cd80" + +#define hex_fn_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567" +#define hex_fn_sub_x_y "768d77882a23097d05db3562fed0a840313d63ae4e01c9ccc23706ad4be7c54a" +#define hex_fn_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9" +#define hex_fn_neg_x "cd3b51d2e0e67ee6a066fbb995c6366ae220d3ab2f5ff949e261ae800688cc5c" +#define hex_fn_mul_x_y "cf7296d5cbf0b64bb5e9a11b294962e9c779b41c038e9c8d815234a0df9d6623" +#define hex_fn_sqr_x "82d3d1b296d3a3803888b7ffc78f23eca824e7ec8d7ddaf231ffb0d256a19da2" +#define hex_fn_exp_x_y "0cf4df7e76d7d49ff23b94853a98aba1e36e9ca0358acbf23a3bbda406f46df3" +#define hex_fn_inv_x "96340ec8b80f44e9b345a706bdb5c9e3ab8a6474a5cb4e0d4645dbaecf1cf03d" +#define hex_v "d3da0ef661be97360e1b32f834e6ca5673b1984b22bb420133da05e56ccd59fb" +#define hex_fn_mul_x_v "0375c61e1ed13e460f4b5d462dc5b2c846f36c7b481cd4bed8f7dd55908a6afd" + +#define hex_t "2fbadf57b52dc19e8470bf201cb182e0a4f7fa5e28d356b15da173132b94b325" + + +int test_sm2_bn(void) +{ + SM2_BN r; + SM2_BN x; + SM2_BN y; + int ok, i = 1; + + char hex[65]; + + SM2_BN v = { + 0x6ccd59fb, 0x33da05e5, 0x22bb4201, 0x73b1984b, + 0x34e6ca56, 0x0e1b32f8, 0x61be9736, 0xd3da0ef6, + }; + + SM2_BN t; + + sm2_bn_copy(x, SM2_G->X); + sm2_bn_copy(y, SM2_G->Y); + + sm2_bn_from_hex(r, hex_v); + ok = (sm2_bn_cmp(r, v) == 0); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + // fp tests + sm2_fp_add(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fp_add_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fp_sub(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fp_sub_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fp_mul(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fp_mul_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fp_exp(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fp_exp_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fp_inv(r, x); + ok = sm2_bn_equ_hex(r, hex_fp_inv_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fp_neg(r, x); + ok = sm2_bn_equ_hex(r, hex_fp_neg_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + // fn tests + sm2_fn_add(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fn_add_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_sub(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fn_sub_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_sub(r, y, x); + ok = sm2_bn_equ_hex(r, hex_fn_sub_y_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_neg(r, x); + ok = sm2_bn_equ_hex(r, hex_fn_neg_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_mul(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fn_mul_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_mul(r, x, v); + ok = sm2_bn_equ_hex(r, hex_fn_mul_x_v); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_sqr(r, x); + ok = sm2_bn_equ_hex(r, hex_fn_sqr_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_exp(r, x, y); + ok = sm2_bn_equ_hex(r, hex_fn_exp_x_y); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_fn_inv(r, x); + ok = sm2_bn_equ_hex(r, hex_fn_inv_x); + printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + SM2_BN tv = { + 0x2b94b325, 0x5da17313, 0x28d356b1, 0xa4f7fa5e, + 0x1cb182e0, 0x8470bf20, 0xb52dc19e, 0x2fbadf57, + }; + sm2_bn_from_hex(t, hex_t); + ok = (sm2_bn_cmp(t, tv) == 0); + if (!ok) return -1; + + sm2_bn_to_hex(t, hex); + + return 1; +} + + +#define hex_G \ + "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \ + "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0" +#define hex_2G \ + "56cefd60d7c87c000d58ef57fa73ba4d9c0dfa08c08a7331495c2e1da3f2bd52" \ + "31b7e7e6cc8189f668535ce0f8eaf1bd6de84c182f6c8e716f780d3a970a23c3" +#define hex_3G \ + "a97f7cd4b3c993b4be2daa8cdb41e24ca13f6bd945302244e26918f1d0509ebf" \ + "530b5dd88c688ef5ccc5cec08a72150f7c400ee5cd045292aaacdd037458f6e6" +#define hex_negG \ + "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \ + "43c8c95c0b098863a642311c9496deac2f56788239d5b8c0fd20cd1adec60f5f" +#define hex_10G \ + "d3f94862519621c121666061f65c3e32b2d0d065cd219e3284a04814db522756" \ + "4b9030cf676f6a742ebd57d146dca428f6b743f64d1482d147d46fb2bab82a14" +#define hex_bG \ + "528470bc74a6ebc663c06fc4cfa1b630d1e9d4a80c0a127b47f73c324c46c0ba" \ + "832cf9c5a15b997e60962b4cf6e2c9cee488faaec98d20599d323d4cabfc1bf4" + +#define hex_P \ + "504cfe2fae749d645e99fbb5b25995cc6fed70196007b039bdc44706bdabc0d9" \ + "b80a8018eda5f55ddc4b870d7784b7b84e53af02f575ab53ed8a99a3bbe2abc2" +#define hex_2P \ + "a53d20e89312b5243f66aec12ef6471f5911941d86302d5d8337cb70937d65ae" \ + "96953c46815e4259363256ddd6c77fcc33787aeafc6a57beec5833f476dd69e0" + +#define hex_tP \ + "02deff2c5b3656ca3f7c7ca9d710ca1d69860c75a9c7ec284b96b8adc50b2936" \ + "b74bcba937e9267fce4ccc069a6681f5b04dcedd9e2794c6a25ddc7856df7145" + + +int test_sm2_jacobian_point(void) +{ + SM2_JACOBIAN_POINT _P, *P = &_P; + SM2_JACOBIAN_POINT _G, *G = &_G; + SM2_BN k; + int i = 1, ok; + + uint8_t buf[64]; + + printf("sm2_jacobian_point_test\n"); + + sm2_jacobian_point_copy(G, SM2_G); + ok = sm2_jacobian_point_equ_hex(G, hex_G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + ok = sm2_jacobian_point_is_on_curve(G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_dbl(P, G); + ok = sm2_jacobian_point_equ_hex(P, hex_2G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_add(P, P, G); + ok = sm2_jacobian_point_equ_hex(P, hex_3G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_sub(P, P, G); + ok = sm2_jacobian_point_equ_hex(P, hex_2G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_neg(P, G); + ok = sm2_jacobian_point_equ_hex(P, hex_negG); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_bn_set_word(k, 10); + sm2_jacobian_point_mul(P, k, G); + ok = sm2_jacobian_point_equ_hex(P, hex_10G); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_mul_generator(P, SM2_B); + ok = sm2_jacobian_point_equ_hex(P, hex_bG); + printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); + if (!ok) return -1; + + sm2_jacobian_point_to_bytes(P, buf); + sm2_jacobian_point_from_hex(P, hex_P); + + return 1; +} + +#define hex_d "5aebdfd947543b713bc0df2c65baaecc5dadd2cab39c6971402daf92c263fad2" +#define hex_e "c0881c19beec741b9af27cc26493dcc33b05d481bfeab2f3ce9cc056e6ff8400" +#define hex_k "981325ee1ab171e9d2cffb317181a02957b18a34bca610a6d2f8afcdeb53f6b8" +#define hex_x1 "17d2dfe83f23cce8499bca983950d59f0fd56c4c671dd63c04b27e4e94cfd767" +#define hex_r "d85afc01fe104103e48e475a9de4b2624adb40ce2708892fd34f3ea57bcf5b67" +#define hex_rd "a70ba64f9c30e05095f39fe26675114e3f157b2c35191bf6ff06246452f82eb3" +#define hex_di "3ecfdb51c24b0eecb2d4238d1da8c013b8b575cef14ef43e2ddb7bce740ce9cf" +#define hex_krd "f1077f9d7e8091993cdc5b4f0b0c8eda8a9fee73a952f9db27ae7f72d2310928" +#define hex_s "006bac5b8057ca829534dfde72a0d7883444a3b9bfe9bcdfb383fb90ed7d9486" + + +static int test_sm2_point(void) +{ + SM2_POINT P, Q; + uint8_t k[32] = {0}; + uint8_t buf[65] = {0}; + int i; + + for (i = 1; i < 8; i++) { + k[31] = (uint8_t)i; + + if (sm2_point_mul_generator(&P, k) != 1 + || sm2_point_is_on_curve(&P) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "k = %d, ", i); + sm2_point_print(stderr, 0, 0, "k * G", &P); + + memset(buf, 0, sizeof(buf)); + sm2_point_to_compressed_octets(&P, buf); + format_bytes(stderr, 0, 4, "compressedPoint", buf, 33); + memset(&Q, 0, sizeof(Q)); + if (sm2_point_from_x(&Q, buf + 1, buf[0]) != 1 + || memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { + + sm2_point_print(stderr, 0, 4, "P", &P); + sm2_point_print(stderr, 0, 4, "Q", &Q); + + error_print(); + return -1; + } + + memset(buf, 0, sizeof(buf)); + sm2_point_to_uncompressed_octets(&P, buf); + format_bytes(stderr, 0, 4, "compressedPoint", buf, 65); + memset(&Q, 0, sizeof(Q)); + if (sm2_point_from_octets(&Q, buf, 65) != 1 + || memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_point_der(void) +{ + SM2_POINT P, Q; + uint8_t k[32] = {0}; + uint8_t buf[512]; + int i; + + for (i = 1; i < 8; i++) { + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + k[31] = i; + memset(&P, 0, sizeof(P)); + memset(&Q, 0, sizeof(Q)); + + if (sm2_point_mul_generator(&P, k) != 1 + || sm2_point_to_der(&P, &p, &len) != 1 + || format_bytes(stderr, 0, 4, "ECPoint", buf, len) != 1 + || sm2_point_from_der(&Q, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { + error_print(); + sm2_point_print(stderr, 0, 4, "P", &P); + sm2_point_print(stderr, 0, 4, "Q", &Q); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_point_octets(void) +{ + SM2_POINT P, Q; + uint8_t k[32] = {0}; + uint8_t buf[33]; + int i; + + for (i = 1; i < 8; i++) { + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + k[31] = i; + memset(&P, 0, sizeof(P)); + memset(&Q, 0, sizeof(Q)); + + if (sm2_point_mul_generator(&P, k) != 1) { + error_print(); + return -1; + } + sm2_point_to_compressed_octets(&P, buf); + format_bytes(stderr, 0, 4, "compressedPoint", buf, sizeof(buf)); + if (sm2_point_from_octets(&Q, buf, sizeof(buf)) != 1) { + error_print(); + return -1; + } + if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { + error_print(); + sm2_point_print(stderr, 0, 4, "P", &P); + sm2_point_print(stderr, 0, 4, "Q", &Q); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_point_from_x(void) +{ + SM2_POINT P, Q; + uint8_t k[32] = {0}; + uint8_t buf[33]; + int i; + + for (i = 1; i < 8; i++) { + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + k[31] = i; + memset(&P, 0, sizeof(P)); + memset(&Q, 0, sizeof(Q)); + + if (sm2_point_mul_generator(&P, k) != 1) { + error_print(); + return -1; + } + sm2_point_to_compressed_octets(&P, buf); + if (sm2_point_from_x(&Q, buf + 1, buf[0]) != 1) { + error_print(); + return -1; + } + if (memcmp(&P, &Q, sizeof(SM2_POINT)) != 0) { + error_print(); + sm2_point_print(stderr, 0, 4, "P", &P); + sm2_point_print(stderr, 0, 4, "Q", &Q); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_signature(void) +{ + SM2_SIGNATURE sig; + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + // MinLen + memset(&sig, 0x00, sizeof(sig)); + cp = p = buf; len = 0; + if (sm2_signature_to_der(&sig, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "SM2_MIN_SIGNATURE_SIZE: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + sm2_signature_print(stderr, 0, 4, "signature", buf, len); + if (len != SM2_MIN_SIGNATURE_SIZE) { + error_print(); + return -1; + } + if (sm2_signature_from_der(&sig, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + + // MaxLen + memset(&sig, 0x80, sizeof(sig)); + cp = p = buf; len = 0; + if (sm2_signature_to_der(&sig, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "SM2_MAX_SIGNATURE_SIZE: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + sm2_signature_print(stderr, 0, 4, "signature", buf, len); + if (len != SM2_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + if (sm2_signature_from_der(&sig, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_sign(void) +{ + int ret; + SM2_KEY sm2_key; + SM2_SIGN_CTX sign_ctx; + uint8_t msg[] = "Hello World!"; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE] = {0}; + size_t siglen; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); + + if (sm2_sign_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 + || sm2_sign_update(&sign_ctx, msg, sizeof(msg)) != 1 + || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "signature", sig, siglen); + sm2_signature_print(stderr, 0, 4, "signature", sig, siglen); + + if (sm2_verify_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1 + || sm2_verify_update(&sign_ctx, msg, sizeof(msg)) != 1 + || (ret = sm2_verify_finish(&sign_ctx, sig, siglen)) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "verification: %s\n", ret ? "success" : "failed"); + + + // FIXME: 还应该增加验证不通过的测试 + // 还应该增加底层的参数 + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +// 由于当前Ciphertext中椭圆曲线点数据不正确,因此无法通过测试 +static int test_sm2_ciphertext(void) +{ + SM2_CIPHERTEXT C; + uint8_t buf[1024]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + memset(&C, 0, sizeof(SM2_CIPHERTEXT)); + + cp = p = buf; len = 0; + if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "SM2_NULL_CIPHERTEXT_SIZE: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + + + if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + + // {0, 0, Hash, MinLen} + C.ciphertext_size = SM2_MIN_PLAINTEXT_SIZE; + cp = p = buf; len = 0; + if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "SM2_MIN_PLAINTEXT_SIZE: %zu\n", SM2_MIN_PLAINTEXT_SIZE); + format_print(stderr, 0, 4, "SM2_MIN_CIPHERTEXT_SIZE: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + if (len != SM2_MIN_CIPHERTEXT_SIZE) { + error_print(); + return -1; + } + if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + // { 33, 33, Hash, NULL } + memset(&C, 0x80, sizeof(SM2_POINT)); + cp = p = buf; len = 0; + if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "ciphertext len: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + // { 33, 33, Hash, MaxLen } + C.ciphertext_size = SM2_MAX_PLAINTEXT_SIZE;//SM2_MAX_PLAINTEXT_SIZE; + cp = p = buf; len = 0; + if (sm2_ciphertext_to_der(&C, &p, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "SM2_MAX_PLAINTEXT_SIZE: %zu\n", SM2_MAX_PLAINTEXT_SIZE); + format_print(stderr, 0, 4, "SM2_MAX_CIPHERTEXT_SIZE: %zu\n", len); + format_bytes(stderr, 0, 4, "", buf, len); + if (len != SM2_MAX_CIPHERTEXT_SIZE) { + error_print(); + return -1; + } + if (sm2_ciphertext_from_der(&C, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + +static int test_sm2_do_encrypt(void) +{ + SM2_KEY sm2_key; + uint8_t plaintext[] = "Hello World!"; + SM2_CIPHERTEXT ciphertext; + + uint8_t plainbuf[SM2_MAX_PLAINTEXT_SIZE] = {0}; + size_t plainlen = 0; + int r = 0; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + + if (sm2_do_encrypt(&sm2_key, plaintext, sizeof(plaintext), &ciphertext) != 1 + || sm2_do_decrypt(&sm2_key, &ciphertext, plainbuf, &plainlen) != 1) { + error_print(); + return -1; + } + + if (plainlen != sizeof(plaintext) + || memcmp(plainbuf, plaintext, sizeof(plaintext)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + +static int test_sm2_encrypt(void) +{ + SM2_KEY sm2_key; + uint8_t msg[SM2_MAX_PLAINTEXT_SIZE]; + uint8_t cbuf[SM2_MAX_CIPHERTEXT_SIZE+100]; + uint8_t mbuf[SM2_MAX_CIPHERTEXT_SIZE]; + size_t lens[] = { +// 0, + 1, + 16, + SM2_MAX_PLAINTEXT_SIZE, + }; + size_t clen, mlen; + int i; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + + for (i = 0; i < sizeof(msg); i++) { + msg[i] = (uint8_t)i; + } + + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + format_print(stderr, 0, 0, "test %d\n", i + 1); + format_bytes(stderr, 0, 4, "plaintext", msg, lens[i]); + if (sm2_encrypt(&sm2_key, msg, lens[i], cbuf, &clen) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "ciphertext", cbuf, clen); + sm2_ciphertext_print(stderr, 0, 4, "Ciphertext", cbuf, clen); + format_print(stderr, 0, 0, "\n"); + + if (sm2_decrypt(&sm2_key, cbuf, clen, mbuf, &mlen) != 1) { + error_print(); + return -1; + } + if (mlen != lens[i] + || memcmp(mbuf, msg, lens[i]) != 0) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + +static int test_sm2_private_key(void) +{ + SM2_KEY sm2_key; + SM2_KEY tmp_key; + uint8_t buf[SM2_PRIVATE_KEY_BUF_SIZE]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); + + if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "ECPrivateKey", buf, len); + format_print(stderr, 0, 4, "#define SM2_PRIVATE_KEY_DEFAULT_SIZE %zu\n", len); + if (sm2_private_key_from_der(&tmp_key, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + if (memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { + + sm2_key_print(stderr, 0, 0, "sm2_key", &sm2_key); + sm2_key_print(stderr, 0, 0, "tmp_key", &tmp_key); + + + error_print(); + return -1; + } + + cp = p = buf; len = 0; + memset(&tmp_key, 0, sizeof(tmp_key)); + if (sm2_private_key_to_der(&sm2_key, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + sm2_private_key_print(stderr, 0, 4, "ECPrivateKey", d, dlen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_private_key_info(void) +{ + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + SM2_KEY sm2_key; + SM2_KEY tmp_key; + const uint8_t *attrs; + size_t attrs_len; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); + + if (sm2_private_key_info_to_der(&sm2_key, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "PrivateKeyInfo", buf, len); + format_print(stderr, 0, 4, "sizeof(PrivateKeyInfo): %zu\n", len); + if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + sm2_private_key_info_print(stderr, 0, 4, "PrivateKeyInfo", d, dlen); + + cp = p = buf; len = 0; + if (sm2_private_key_info_to_der(&sm2_key, &p, &len) != 1) { + error_print(); + return -1; + } + if (sm2_private_key_info_from_der(&tmp_key, &attrs, &attrs_len, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_enced_private_key_info(void) +{ + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + SM2_KEY sm2_key; + SM2_KEY tmp_key; + const uint8_t *attrs; + size_t attrs_len; + const char *pass = "Password"; + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return -1; + } + sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2_key); + + if (sm2_private_key_info_encrypt_to_der(&sm2_key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "EncryptedPrivateKeyInfo", buf, len); + format_print(stderr, 0, 4, "sizeof(EncryptedPrivateKeyInfo): %zu\n", len); + if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + pkcs8_enced_private_key_info_print(stderr, 0, 4, "EncryptedPrivateKeyInfo", d, dlen); + + + cp = p = buf; len = 0; + if (sm2_private_key_info_encrypt_to_der(&sm2_key, pass, &p, &len) != 1) { + error_print(); + return -1; + } + if (sm2_private_key_info_decrypt_from_der(&tmp_key, &attrs, &attrs_len, pass, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1 + || memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + +int main(void) +{ + if (test_sm2_bn() != 1) goto err; + if (test_sm2_jacobian_point() != 1) goto err; + if (test_sm2_point() != 1) goto err; + if (test_sm2_point_octets() != 1) goto err; + if (test_sm2_point_from_x() != 1) goto err; + if (test_sm2_point_der() != 1) goto err; + if (test_sm2_private_key() != 1) goto err; + if (test_sm2_private_key_info() != 1) goto err; + if (test_sm2_enced_private_key_info() != 1) goto err; + if (test_sm2_signature() != 1) goto err; + if (test_sm2_sign() != 1) goto err; + //if (test_sm2_ciphertext() != 1) goto err; // 需要正确的Ciphertext数据 + if (test_sm2_do_encrypt() != 1) goto err; + if (test_sm2_encrypt() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/sm3test.c b/tests/sm3test.c index 0339a1c3..249473b7 100644 --- a/tests/sm3test.c +++ b/tests/sm3test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,178 +7,179 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static int test_sm3(void) -{ - const char *testhex[] = { - /* 0 "abc" */ - "616263", - /* 1 "abcd" 16 times */ - "6162636461626364616263646162636461626364616263646162636461626364" - "6162636461626364616263646162636461626364616263646162636461626364", - /* 2 p.57 ZA */ - "0090" - "414C494345313233405941484F4F2E434F4D" - "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" - "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" - "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" - "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" - "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A" - "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857", - /* 3 p.59 ZA */ - "0090" - "414C494345313233405941484F4F2E434F4D" - "000000000000000000000000000000000000000000000000000000000000000000" - "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" - "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" - "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" - "0165961645281A8626607B917F657D7E9382F1EA5CD931F40F6627F357542653B2" - "01686522130D590FB8DE635D8FCA715CC6BF3D05BEF3F75DA5D543454448166612", - /* 4 p.72 ZA */ - "0090" - "414C494345313233405941484F4F2E434F4D" - "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" - "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" - "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" - "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" - "3099093BF3C137D8FCBBCDF4A2AE50F3B0F216C3122D79425FE03A45DBFE1655" - "3DF79E8DAC1CF0ECBAA2F2B49D51A4B387F2EFAF482339086A27A8E05BAED98B", - /* 5 p.72 ZB */ - "0088" - "42494C4C343536405941484F4F2E434F4D" - "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" - "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" - "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" - "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" - "245493D446C38D8CC0F118374690E7DF633A8A4BFB3329B5ECE604B2B4F37F43" - "53C0869F4B9E17773DE68FEC45E14904E0DEA45BF6CECF9918C85EA047C60A4C", - /* 6 p.75 ZA */ - "0090" - "414C494345313233405941484F4F2E434F4D" - "000000000000000000000000000000000000000000000000000000000000000000" - "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" - "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" - "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" - "008E3BDB2E11F9193388F1F901CCC857BF49CFC065FB38B9069CAAE6D5AFC3592F" - "004555122AAC0075F42E0A8BBD2C0665C789120DF19D77B4E3EE4712F598040415", - /* 7 p.76 ZB */ - "0088" - "42494C4C343536405941484F4F2E434F4D" - "000000000000000000000000000000000000000000000000000000000000000000" - "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" - "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" - "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" - "0034297DD83AB14D5B393B6712F32B2F2E938D4690B095424B89DA880C52D4A7D9" - "0199BBF11AC95A0EA34BBD00CA50B93EC24ACB68335D20BA5DCFE3B33BDBD2B62D", - /* 8 TopsecCA cert ZA */ - "0080" - "31323334353637383132333435363738" - "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC" - "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93" - "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7" - "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" - "D69C2F1EEC3BFB6B95B30C28085C77B125D77A9C39525D8190768F37D6B205B5" - "89DCD316BBE7D89A9DC21917F17799E698531F5E6E3E10BD31370B259C3F81C3", - /* 9 */ - "4D38D2958CA7FD2CFAE3AF04486959CF92C8EF48E8B83A05C112E739D5F181D0" - "3082020CA003020102020900" - "AF28725D98D33143300C06082A811CCF" - "550183750500307D310B300906035504" - "060C02636E310B300906035504080C02" - "626A310B300906035504070C02626A31" - "0F300D060355040A0C06746F70736563" - "310F300D060355040B0C06746F707365" - "633111300F06035504030C08546F7073" - "65634341311F301D06092A864886F70D" - "0109010C10626A40746F707365632E63" - "6F6D2E636E301E170D31323036323430" - "37353433395A170D3332303632303037" - "353433395A307D310B30090603550406" - "0C02636E310B300906035504080C0262" - "6A310B300906035504070C02626A310F" - "300D060355040A0C06746F7073656331" - "0F300D060355040B0C06746F70736563" - "3111300F06035504030C08546F707365" - "634341311F301D06092A864886F70D01" - "09010C10626A40746F707365632E636F" - "6D2E636E3059301306072A8648CE3D02" - "0106082A811CCF5501822D03420004D6" - "9C2F1EEC3BFB6B95B30C28085C77B125" - "D77A9C39525D8190768F37D6B205B589" - "DCD316BBE7D89A9DC21917F17799E698" - "531F5E6E3E10BD31370B259C3F81C3A3" - "733071300F0603551D130101FF040530" - "030101FF301D0603551D0E041604148E" - "5D90347858BAAAD870D8BDFBA6A85E7B" - "563B64301F0603551D23041830168014" - "8E5D90347858BAAAD870D8BDFBA6A85E" - "7B563B64300B0603551D0F0404030201" - "06301106096086480186F84201010404" - "03020057", - }; - - const char *dgsthex[] = { - "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", - "debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", - "F4A38489E32B45B6F876E3AC2168CA392362DC8F23459C1D1146FC3DBFB7BC9A", - "26352AF82EC19F207BBC6F9474E11E90CE0F7DDACE03B27F801817E897A81FD5", - "E4D1D0C3CA4C7F11BC8FF8CB3F4C02A78F108FA098E51A668487240F75E20F31", - "6B4B6D0E276691BD4A11BF72F4FB501AE309FDACB72FA6CC336E6656119ABD67", - "329c2f6030cc7e0ca3af6c97b76243ca250338ad3d3dc3a8b322d1cfdf98c2b7", - /*"ECF0080215977B2E5D6D61B98A99442F03E8803DC39E349F8DCA5621A9ACDF2B",*/ - "557BAD30E183559AEEC3B2256E1C7C11F870D22B165D015ACF9465B09B87B527", - "4D38D2958CA7FD2CFAE3AF04486959CF92C8EF48E8B83A05C112E739D5F181D0", - "C3B02E500A8B60B77DEDCF6F4C11BEF8D56E5CDE708C72065654FD7B2167915A", - }; - - int err = 0; - char *p; - uint8_t testbuf[sizeof(testhex)/2 + 1000]; - uint8_t dgstbuf[32]; - size_t testbuflen, dgstbuflen; - uint8_t dgst[32]; - size_t i; - - for (i = 0; i < sizeof(testhex)/sizeof(testhex[0]); i++) { - hex_to_bytes(testhex[i], strlen(testhex[i]), testbuf, &testbuflen); - hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); - - sm3_digest(testbuf, testbuflen, dgst); - - if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { - int n; - fprintf(stderr, "sm3 test %lu failed\n", i+1); - fprintf(stderr, "error calculating SM3 on %s\n", testhex[i]); - fprintf(stderr, " digest(corret) = "); - for (n = 0; n < sizeof(dgst); n++) { - fprintf(stderr, "%02X", dgst[n]); - } - fprintf(stderr, "\n"); - fprintf(stderr, " digest(error) = %s\n", dgsthex[i]); - return -1; - } - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - -int main(void) -{ - if (test_sm3() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm3(void) +{ + const char *testhex[] = { + /* 0 "abc" */ + "616263", + /* 1 "abcd" 16 times */ + "6162636461626364616263646162636461626364616263646162636461626364" + "6162636461626364616263646162636461626364616263646162636461626364", + /* 2 p.57 ZA */ + "0090" + "414C494345313233405941484F4F2E434F4D" + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" + "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A" + "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857", + /* 3 p.59 ZA */ + "0090" + "414C494345313233405941484F4F2E434F4D" + "000000000000000000000000000000000000000000000000000000000000000000" + "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" + "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" + "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" + "0165961645281A8626607B917F657D7E9382F1EA5CD931F40F6627F357542653B2" + "01686522130D590FB8DE635D8FCA715CC6BF3D05BEF3F75DA5D543454448166612", + /* 4 p.72 ZA */ + "0090" + "414C494345313233405941484F4F2E434F4D" + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" + "3099093BF3C137D8FCBBCDF4A2AE50F3B0F216C3122D79425FE03A45DBFE1655" + "3DF79E8DAC1CF0ECBAA2F2B49D51A4B387F2EFAF482339086A27A8E05BAED98B", + /* 5 p.72 ZB */ + "0088" + "42494C4C343536405941484F4F2E434F4D" + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498" + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A" + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D" + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2" + "245493D446C38D8CC0F118374690E7DF633A8A4BFB3329B5ECE604B2B4F37F43" + "53C0869F4B9E17773DE68FEC45E14904E0DEA45BF6CECF9918C85EA047C60A4C", + /* 6 p.75 ZA */ + "0090" + "414C494345313233405941484F4F2E434F4D" + "000000000000000000000000000000000000000000000000000000000000000000" + "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" + "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" + "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" + "008E3BDB2E11F9193388F1F901CCC857BF49CFC065FB38B9069CAAE6D5AFC3592F" + "004555122AAC0075F42E0A8BBD2C0665C789120DF19D77B4E3EE4712F598040415", + /* 7 p.76 ZB */ + "0088" + "42494C4C343536405941484F4F2E434F4D" + "000000000000000000000000000000000000000000000000000000000000000000" + "00E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B" + "00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD" + "013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E" + "0034297DD83AB14D5B393B6712F32B2F2E938D4690B095424B89DA880C52D4A7D9" + "0199BBF11AC95A0EA34BBD00CA50B93EC24ACB68335D20BA5DCFE3B33BDBD2B62D", + /* 8 TopsecCA cert ZA */ + "0080" + "31323334353637383132333435363738" + "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC" + "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93" + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7" + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" + "D69C2F1EEC3BFB6B95B30C28085C77B125D77A9C39525D8190768F37D6B205B5" + "89DCD316BBE7D89A9DC21917F17799E698531F5E6E3E10BD31370B259C3F81C3", + /* 9 */ + "4D38D2958CA7FD2CFAE3AF04486959CF92C8EF48E8B83A05C112E739D5F181D0" + "3082020CA003020102020900" + "AF28725D98D33143300C06082A811CCF" + "550183750500307D310B300906035504" + "060C02636E310B300906035504080C02" + "626A310B300906035504070C02626A31" + "0F300D060355040A0C06746F70736563" + "310F300D060355040B0C06746F707365" + "633111300F06035504030C08546F7073" + "65634341311F301D06092A864886F70D" + "0109010C10626A40746F707365632E63" + "6F6D2E636E301E170D31323036323430" + "37353433395A170D3332303632303037" + "353433395A307D310B30090603550406" + "0C02636E310B300906035504080C0262" + "6A310B300906035504070C02626A310F" + "300D060355040A0C06746F7073656331" + "0F300D060355040B0C06746F70736563" + "3111300F06035504030C08546F707365" + "634341311F301D06092A864886F70D01" + "09010C10626A40746F707365632E636F" + "6D2E636E3059301306072A8648CE3D02" + "0106082A811CCF5501822D03420004D6" + "9C2F1EEC3BFB6B95B30C28085C77B125" + "D77A9C39525D8190768F37D6B205B589" + "DCD316BBE7D89A9DC21917F17799E698" + "531F5E6E3E10BD31370B259C3F81C3A3" + "733071300F0603551D130101FF040530" + "030101FF301D0603551D0E041604148E" + "5D90347858BAAAD870D8BDFBA6A85E7B" + "563B64301F0603551D23041830168014" + "8E5D90347858BAAAD870D8BDFBA6A85E" + "7B563B64300B0603551D0F0404030201" + "06301106096086480186F84201010404" + "03020057", + }; + + const char *dgsthex[] = { + "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", + "debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", + "F4A38489E32B45B6F876E3AC2168CA392362DC8F23459C1D1146FC3DBFB7BC9A", + "26352AF82EC19F207BBC6F9474E11E90CE0F7DDACE03B27F801817E897A81FD5", + "E4D1D0C3CA4C7F11BC8FF8CB3F4C02A78F108FA098E51A668487240F75E20F31", + "6B4B6D0E276691BD4A11BF72F4FB501AE309FDACB72FA6CC336E6656119ABD67", + "329c2f6030cc7e0ca3af6c97b76243ca250338ad3d3dc3a8b322d1cfdf98c2b7", + /*"ECF0080215977B2E5D6D61B98A99442F03E8803DC39E349F8DCA5621A9ACDF2B",*/ + "557BAD30E183559AEEC3B2256E1C7C11F870D22B165D015ACF9465B09B87B527", + "4D38D2958CA7FD2CFAE3AF04486959CF92C8EF48E8B83A05C112E739D5F181D0", + "C3B02E500A8B60B77DEDCF6F4C11BEF8D56E5CDE708C72065654FD7B2167915A", + }; + + int err = 0; + char *p; + uint8_t testbuf[sizeof(testhex)/2 + 1000]; + uint8_t dgstbuf[32]; + size_t testbuflen, dgstbuflen; + uint8_t dgst[32]; + size_t i; + + for (i = 0; i < sizeof(testhex)/sizeof(testhex[0]); i++) { + hex_to_bytes(testhex[i], strlen(testhex[i]), testbuf, &testbuflen); + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); + + sm3_digest(testbuf, testbuflen, dgst); + + if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { + int n; + fprintf(stderr, "sm3 test %lu failed\n", i+1); + fprintf(stderr, "error calculating SM3 on %s\n", testhex[i]); + fprintf(stderr, " digest(corret) = "); + for (n = 0; n < sizeof(dgst); n++) { + fprintf(stderr, "%02X", dgst[n]); + } + fprintf(stderr, "\n"); + fprintf(stderr, " digest(error) = %s\n", dgsthex[i]); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + +int main(void) +{ + if (test_sm3() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/sm4test.c b/tests/sm4test.c index c23489e6..a4cdd709 100644 --- a/tests/sm4test.c +++ b/tests/sm4test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,544 +7,545 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static int test_sm4(void) -{ - const uint8_t user_key[16] = { - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - }; - const uint32_t rk[32] = { - 0xf12186f9, 0x41662b61, 0x5a6ab19a, 0x7ba92077, - 0x367360f4, 0x776a0c61, 0xb6bb89b3, 0x24763151, - 0xa520307c, 0xb7584dbd, 0xc30753ed, 0x7ee55b57, - 0x6988608c, 0x30d895b7, 0x44ba14af, 0x104495a1, - 0xd120b428, 0x73b55fa3, 0xcc874966, 0x92244439, - 0xe89e641f, 0x98ca015a, 0xc7159060, 0x99e1fd2e, - 0xb79bd80c, 0x1d2115b0, 0x0e228aeb, 0xf1780c81, - 0x428d3654, 0x62293496, 0x01cf72e5, 0x9124a012, - }; - const uint8_t plaintext[16] = { - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - }; - const uint8_t ciphertext[16] = { - 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, - 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46, - }; - const uint8_t ciphertext1m[16] = { - 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, - 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66, - }; - - SM4_KEY key; - unsigned char buf[16]; - int i; - - /* test key scheduling */ - sm4_set_encrypt_key(&key, user_key); - - if (memcmp(key.rk, rk, sizeof(rk)) != 0) { - fprintf(stderr, "sm4 key scheduling not passed!\n"); - return -1; - } - - /* test encrypt once */ - sm4_encrypt(&key, plaintext, buf); - if (memcmp(buf, ciphertext, sizeof(ciphertext)) != 0) { - fprintf(stderr, "sm4 encrypt not pass!\n"); - return -1; - } - - /* test encrypt 1000000 times */ - memcpy(buf, plaintext, sizeof(plaintext)); - for (i = 0; i < 1000000; i++) { - sm4_encrypt(&key, buf, buf); - } - if (memcmp(buf, ciphertext1m, sizeof(ciphertext1m)) != 0) { - fprintf(stderr, "sm4 encrypt 1000000 times not pass!\n"); - return -1; - } - - /* test decrypt */ - memset(&key, 0, sizeof(key)); - memset(buf, 0, sizeof(buf)); - sm4_set_decrypt_key(&key, user_key); - sm4_decrypt(&key, ciphertext, buf); - if (memcmp(buf, plaintext, sizeof(plaintext)) != 0) { - fprintf(stderr, "sm4 decrypt not pass!\n"); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_cbc(void) -{ - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t buf1[32] = {0}; - uint8_t buf2[32] = {0}; - uint8_t buf3[32] = {0}; - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2); - sm4_set_decrypt_key(&sm4_key, key); - sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3); - - if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_cbc_padding(void) -{ - SM4_KEY enc_key; - SM4_KEY dec_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t buf1[64]; - uint8_t buf2[128]; - uint8_t buf3[128]; - size_t len1, len2, len3; - - sm4_set_encrypt_key(&enc_key, key); - sm4_set_decrypt_key(&dec_key, key); - - len1 = 0; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 7; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 16; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 33; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = sizeof(buf1); - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_ctr(void) -{ - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t ctr[16]; - uint8_t buf1[30] = {0}; - uint8_t buf2[30] = {0}; - uint8_t buf3[30] = {0}; - - sm4_set_encrypt_key(&sm4_key, key); - memset(ctr, 0, sizeof(ctr)); - sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); - - memset(ctr, 0, sizeof(ctr)); - sm4_ctr_decrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3); - - if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_gcm(void) -{ - // gcm test vectors from rfc 8998 A.1 - const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; - const char *hex_iv = "00001234567800000000ABCD"; - const char *hex_aad = "FEEDFACEDEADBEEFFEEDFACEDEADBEEF" - "ABADDAD2"; - const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF" - "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"; - const char *hex_out = "17F399F08C67D5EE19D0DC9969C4BB7D" - "5FD46FD3756489069157B282BB200735" - "D82710CA5C22F0CCFA7CBF93D496AC15" - "A56834CBCF98C397B4024A2691233B8D"; - const char *hex_tag = "83DE3541E4C2B58177E065A9BF7B62EC"; - - SM4_KEY sm4_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t aad[20]; - uint8_t in[64]; - uint8_t out[64]; - uint8_t tag[16]; - size_t keylen, ivlen, aadlen, inlen, outlen, taglen; - - uint8_t buf[64]; - uint8_t mac[16]; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); - hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); - hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); - - memset(buf, 0, sizeof(buf)); - memset(mac, 0, sizeof(mac)); - - sm4_set_encrypt_key(&sm4_key, key); - - // test gcm encrypt - sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); - if (memcmp(buf, out, outlen) != 0) { - error_print(); - return -1; - } - if (memcmp(mac, tag, taglen) != 0) { - error_print(); - return -1; - } - - // test gcm decrypt - memset(buf, 0, sizeof(buf)); - sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); - if (memcmp(buf, in, inlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_cbc_update(void) -{ - SM4_KEY sm4_key; - SM4_CBC_CTX enc_ctx; - SM4_CBC_CTX dec_ctx; - - uint8_t key[16]; - uint8_t iv[16]; - uint8_t mbuf[16 * 10]; - uint8_t cbuf[16 * 11]; - uint8_t pbuf[16 * 11]; - size_t mlen = 0; - size_t clen = 0; - size_t plen = 0; - - uint8_t *in; - uint8_t *out; - size_t len; - size_t lens[] = { 1,5,17,80 }; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - - - // first test - - mlen = 16; - rand_bytes(mbuf, mlen); - - if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1 - || sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 - || sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertext - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); - if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1 - || sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 - || sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { - error_print(); - return -1; - } - plen += len; - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - - // second test - - rand_bytes(mbuf, sizeof(mbuf)); - - if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) { - error_print(); - return -1; - } - in = mbuf; - out = cbuf; - mlen = 0; - clen = 0; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - mlen += lens[i]; - out += len; - clen += len; - - } - if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertest - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); - if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) { - error_print(); - return -1; - } - plen = 0; - in = cbuf; - out = pbuf; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - clen -= lens[i]; - out += len; - plen += len; - } - if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { - error_print(); - return -1; - } - out += len; - plen += len; - if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_ctr_update(void) -{ - SM4_KEY sm4_key; - SM4_CTR_CTX enc_ctx; - SM4_CTR_CTX dec_ctx; - - uint8_t key[16]; - uint8_t iv[16]; - uint8_t ctr[16]; - uint8_t mbuf[16 * 10]; - uint8_t cbuf[16 * 11]; - uint8_t pbuf[16 * 11]; - size_t mlen = 0; - size_t clen = 0; - size_t plen = 0; - - uint8_t *in; - uint8_t *out; - size_t len; - size_t lens[] = { 1,5,17,80 }; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - // first test - - mlen = 16; - rand_bytes(mbuf, mlen); - memcpy(ctr, iv, sizeof(iv)); - if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1 - || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 - || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertext - sm4_set_encrypt_key(&sm4_key, key); - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // 注意:sm4_ctr_encrypt() 会修改ctr的值 - memcpy(ctr, iv, sizeof(iv)); - if (memcmp(cbuf, pbuf, clen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1 - || sm4_ctr_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 - || sm4_ctr_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - - // second test - - rand_bytes(mbuf, sizeof(mbuf)); - - if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1) { - error_print(); - return -1; - } - in = mbuf; - out = cbuf; - mlen = 0; - clen = 0; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - mlen += lens[i]; - out += len; - clen += len; - - } - if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertest - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); - memcpy(ctr, iv, sizeof(iv)); - if (memcmp(pbuf, cbuf, mlen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1) { - error_print(); - return -1; - } - plen = 0; - in = cbuf; - out = pbuf; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_ctr_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - clen -= lens[i]; - out += len; - plen += len; - } - if (sm4_ctr_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { - error_print(); - return -1; - } - out += len; - plen += len; - if (sm4_ctr_decrypt_finish(&dec_ctx, out, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_sm4() != 1) goto err; - if (test_sm4_cbc() != 1) goto err; - if (test_sm4_cbc_padding() != 1) goto err; - if (test_sm4_ctr() != 1) goto err; - if (test_sm4_gcm() != 1) goto err; - if (test_sm4_cbc_update() != 1) goto err; - if (test_sm4_ctr_update() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm4(void) +{ + const uint8_t user_key[16] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + const uint32_t rk[32] = { + 0xf12186f9, 0x41662b61, 0x5a6ab19a, 0x7ba92077, + 0x367360f4, 0x776a0c61, 0xb6bb89b3, 0x24763151, + 0xa520307c, 0xb7584dbd, 0xc30753ed, 0x7ee55b57, + 0x6988608c, 0x30d895b7, 0x44ba14af, 0x104495a1, + 0xd120b428, 0x73b55fa3, 0xcc874966, 0x92244439, + 0xe89e641f, 0x98ca015a, 0xc7159060, 0x99e1fd2e, + 0xb79bd80c, 0x1d2115b0, 0x0e228aeb, 0xf1780c81, + 0x428d3654, 0x62293496, 0x01cf72e5, 0x9124a012, + }; + const uint8_t plaintext[16] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + const uint8_t ciphertext[16] = { + 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, + 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46, + }; + const uint8_t ciphertext1m[16] = { + 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, + 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66, + }; + + SM4_KEY key; + unsigned char buf[16]; + int i; + + /* test key scheduling */ + sm4_set_encrypt_key(&key, user_key); + + if (memcmp(key.rk, rk, sizeof(rk)) != 0) { + fprintf(stderr, "sm4 key scheduling not passed!\n"); + return -1; + } + + /* test encrypt once */ + sm4_encrypt(&key, plaintext, buf); + if (memcmp(buf, ciphertext, sizeof(ciphertext)) != 0) { + fprintf(stderr, "sm4 encrypt not pass!\n"); + return -1; + } + + /* test encrypt 1000000 times */ + memcpy(buf, plaintext, sizeof(plaintext)); + for (i = 0; i < 1000000; i++) { + sm4_encrypt(&key, buf, buf); + } + if (memcmp(buf, ciphertext1m, sizeof(ciphertext1m)) != 0) { + fprintf(stderr, "sm4 encrypt 1000000 times not pass!\n"); + return -1; + } + + /* test decrypt */ + memset(&key, 0, sizeof(key)); + memset(buf, 0, sizeof(buf)); + sm4_set_decrypt_key(&key, user_key); + sm4_decrypt(&key, ciphertext, buf); + if (memcmp(buf, plaintext, sizeof(plaintext)) != 0) { + fprintf(stderr, "sm4 decrypt not pass!\n"); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc(void) +{ + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t iv[16] = {0}; + uint8_t buf1[32] = {0}; + uint8_t buf2[32] = {0}; + uint8_t buf3[32] = {0}; + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2); + sm4_set_decrypt_key(&sm4_key, key); + sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3); + + if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc_padding(void) +{ + SM4_KEY enc_key; + SM4_KEY dec_key; + uint8_t key[16] = {0}; + uint8_t iv[16] = {0}; + uint8_t buf1[64]; + uint8_t buf2[128]; + uint8_t buf3[128]; + size_t len1, len2, len3; + + sm4_set_encrypt_key(&enc_key, key); + sm4_set_decrypt_key(&dec_key, key); + + len1 = 0; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 7; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 16; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 33; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = sizeof(buf1); + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr(void) +{ + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t ctr[16]; + uint8_t buf1[30] = {0}; + uint8_t buf2[30] = {0}; + uint8_t buf3[30] = {0}; + + sm4_set_encrypt_key(&sm4_key, key); + memset(ctr, 0, sizeof(ctr)); + sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); + + memset(ctr, 0, sizeof(ctr)); + sm4_ctr_decrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3); + + if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_gcm(void) +{ + // gcm test vectors from rfc 8998 A.1 + const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; + const char *hex_iv = "00001234567800000000ABCD"; + const char *hex_aad = "FEEDFACEDEADBEEFFEEDFACEDEADBEEF" + "ABADDAD2"; + const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" + "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD" + "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF" + "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"; + const char *hex_out = "17F399F08C67D5EE19D0DC9969C4BB7D" + "5FD46FD3756489069157B282BB200735" + "D82710CA5C22F0CCFA7CBF93D496AC15" + "A56834CBCF98C397B4024A2691233B8D"; + const char *hex_tag = "83DE3541E4C2B58177E065A9BF7B62EC"; + + SM4_KEY sm4_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[20]; + uint8_t in[64]; + uint8_t out[64]; + uint8_t tag[16]; + size_t keylen, ivlen, aadlen, inlen, outlen, taglen; + + uint8_t buf[64]; + uint8_t mac[16]; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); + hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); + hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); + + memset(buf, 0, sizeof(buf)); + memset(mac, 0, sizeof(mac)); + + sm4_set_encrypt_key(&sm4_key, key); + + // test gcm encrypt + sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); + if (memcmp(buf, out, outlen) != 0) { + error_print(); + return -1; + } + if (memcmp(mac, tag, taglen) != 0) { + error_print(); + return -1; + } + + // test gcm decrypt + memset(buf, 0, sizeof(buf)); + sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); + if (memcmp(buf, in, inlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc_update(void) +{ + SM4_KEY sm4_key; + SM4_CBC_CTX enc_ctx; + SM4_CBC_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t mbuf[16 * 10]; + uint8_t cbuf[16 * 11]; + uint8_t pbuf[16 * 11]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + + uint8_t *in; + uint8_t *out; + size_t len; + size_t lens[] = { 1,5,17,80 }; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + + + // first test + + mlen = 16; + rand_bytes(mbuf, mlen); + + if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1 + || sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 + || sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertext + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); + if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1 + || sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 + || sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { + error_print(); + return -1; + } + plen += len; + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + + // second test + + rand_bytes(mbuf, sizeof(mbuf)); + + if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + in = mbuf; + out = cbuf; + mlen = 0; + clen = 0; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + mlen += lens[i]; + out += len; + clen += len; + + } + if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertest + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); + if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) { + error_print(); + return -1; + } + plen = 0; + in = cbuf; + out = pbuf; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + clen -= lens[i]; + out += len; + plen += len; + } + if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { + error_print(); + return -1; + } + out += len; + plen += len; + if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr_update(void) +{ + SM4_KEY sm4_key; + SM4_CTR_CTX enc_ctx; + SM4_CTR_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t ctr[16]; + uint8_t mbuf[16 * 10]; + uint8_t cbuf[16 * 11]; + uint8_t pbuf[16 * 11]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + + uint8_t *in; + uint8_t *out; + size_t len; + size_t lens[] = { 1,5,17,80 }; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + // first test + + mlen = 16; + rand_bytes(mbuf, mlen); + memcpy(ctr, iv, sizeof(iv)); + if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1 + || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 + || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertext + sm4_set_encrypt_key(&sm4_key, key); + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // 注意:sm4_ctr_encrypt() 会修改ctr的值 + memcpy(ctr, iv, sizeof(iv)); + if (memcmp(cbuf, pbuf, clen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1 + || sm4_ctr_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 + || sm4_ctr_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + + // second test + + rand_bytes(mbuf, sizeof(mbuf)); + + if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1) { + error_print(); + return -1; + } + in = mbuf; + out = cbuf; + mlen = 0; + clen = 0; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + mlen += lens[i]; + out += len; + clen += len; + + } + if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertest + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); + memcpy(ctr, iv, sizeof(iv)); + if (memcmp(pbuf, cbuf, mlen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1) { + error_print(); + return -1; + } + plen = 0; + in = cbuf; + out = pbuf; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_ctr_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + clen -= lens[i]; + out += len; + plen += len; + } + if (sm4_ctr_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { + error_print(); + return -1; + } + out += len; + plen += len; + if (sm4_ctr_decrypt_finish(&dec_ctx, out, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_sm4() != 1) goto err; + if (test_sm4_cbc() != 1) goto err; + if (test_sm4_cbc_padding() != 1) goto err; + if (test_sm4_ctr() != 1) goto err; + if (test_sm4_gcm() != 1) goto err; + if (test_sm4_cbc_update() != 1) goto err; + if (test_sm4_ctr_update() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/sm9test.c b/tests/sm9test.c index dabbae9f..8408a4a4 100644 --- a/tests/sm9test.c +++ b/tests/sm9test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,621 +7,622 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static int sm9_bn_equ_hex(const sm9_bn_t a, const char *hex) -{ - sm9_bn_t b; - sm9_bn_from_hex(b, hex); - return (sm9_bn_cmp(a, b) == 0); -} - - -#define hex_iv "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321" -#define hex_fp_add "114efe24536598809df494ff7657484edff1812d51c3955b7d869149aa123d31" -#define hex_fp_sub "43cee97c9abed9be3efe7ffffc9d30abe1d643b9b27ea351460aabb2239d3fd4" -#define hex_fp_nsub "7271168367e4cd3397052b4ff8f19699401c4f9167fc4b8a9f64ef75bfb405a9" -#define hex_fp_dbl "551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05" -#define hex_fp_tri "248cdb7163e4d7e5606ac9d731a751d591b25db4f925dd9532a20de5c2de98c9" -#define hex_fp_div2 "9df779e83d83d9c517bf85bbd4e833b289e7dfb214ecc1501cf8039cdde8d35f" -#define hex_fp_neg "30910c2f8a3f9a597c884b28414d2725301567320b1c5b1790ef2f160ad0e43c" -#define hex_fp_mul "9e4d19bb5d94a47352e6f53f4116b2a71b16a1113dc789b26528ee19f46b72e0" -#define hex_fp_sqr "46dc2a5b8853234b341d9c57f9c4ca5709e95bbfef25356812e884e4f38cd0d6" -#define hex_fp_pow "5679a8f0a46ada5b9d48008cde0b8b7a233f882c08afe8f08a36a20ac845bb1a" -#define hex_fp_inv "7d404b0027a93e3fa8f8bc7ee367a96814c42a3b69feb1845093406948a34753" - -int test_sm9_fp() { - sm9_fp_t x; - sm9_fp_t y; - sm9_fp_t r; - int j = 1; - - sm9_bn_copy(x, SM9_P2->X[1]); - sm9_bn_copy(y, SM9_Ppubs->Y[0]); - - sm9_fp_t iv = {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}; - sm9_bn_from_hex(r, hex_iv); if (sm9_bn_cmp(r, iv) != 0) goto err; ++j; - - sm9_fp_add(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_add)) goto err; ++j; - sm9_fp_sub(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_sub)) goto err; ++j; - sm9_fp_sub(r, y, x); if (!sm9_bn_equ_hex(r, hex_fp_nsub)) goto err; ++j; - sm9_fp_dbl(r, x); if (!sm9_bn_equ_hex(r, hex_fp_dbl)) goto err; ++j; - sm9_fp_tri(r, x); if (!sm9_bn_equ_hex(r, hex_fp_tri)) goto err; ++j; - sm9_fp_div2(r, x); if (!sm9_bn_equ_hex(r, hex_fp_div2)) goto err; ++j; - sm9_fp_neg(r, x); if (!sm9_bn_equ_hex(r, hex_fp_neg)) goto err; ++j; - sm9_fp_mul(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_mul)) goto err; ++j; - sm9_fp_sqr(r, x); if (!sm9_bn_equ_hex(r, hex_fp_sqr)) goto err; ++j; - sm9_fp_pow(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_pow)) goto err; ++j; - sm9_fp_inv(r, x); if (!sm9_bn_equ_hex(r, hex_fp_inv)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s() test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_x "483f336f119053cba8c0e738cabc2bfdbf047caf7e1aaa92526fa48041ceea2b" -#define hex_y "3220b45276e3692a387faa7bf3cd46e390608f2f4298cce467bf2b7fda091edb" -#define hex_fn_add "7a5fe7c18873bcf5e14091b4be8972e14f650bdec0b37776ba2ed0001bd80906" -#define hex_fn_sub "161e7f1c9aaceaa170413cbcd6eee51a2ea3ed803b81ddadeab0790067c5cb50" -#define hex_fn_nsub "a02180e367f6bc5065c26e931e9fe22a1b4ea5cadd68ae40fabe689c6ed903d5" -#define hex_fn_mul "25c528484b65755b1ff57b47b77f2b32e20467be1dde566ede4264b2e092d223" -#define hex_fn_pow "445cb9b76f27e9d03a2c30fbabb59b0ea6d7b06259b0c8a1b30f21b9b274a055" -#define hex_fn_inv "3e3e849c2144c3596d9c79cb1f8ee7c60828787e298b06cc341a9a165191bc5e" - -int test_sm9_fn() { - sm9_fn_t x; - sm9_fn_t y; - sm9_fn_t r; - int j = 1; - - sm9_bn_from_hex(x, hex_x); - sm9_bn_from_hex(y, hex_y); - - sm9_fn_t iv = {0, 0, 0, 0, 0, 0, 0, 0}; if (!sm9_fn_is_zero(iv)) goto err; ++j; - sm9_fn_add(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_add)) goto err; ++j; - sm9_fn_sub(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_sub)) goto err; ++j; - sm9_fn_sub(r, y, x); if (!sm9_bn_equ_hex(r, hex_fn_nsub)) goto err; ++j; - sm9_fn_mul(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_mul)) goto err; ++j; - sm9_fn_pow(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_pow)) goto err; ++j; - sm9_fn_inv(r, x); if (!sm9_bn_equ_hex(r, hex_fn_inv)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_iv2 "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321-a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c" -#define hex_fp2_add "0074a3145c65ac547541612178e584a902248740e70606dcaaafe2bcbd2f6a21-1b6ac9eb2c47b62cf61608b26c3c7e20674a48c4c509ac130bbaf6d47d32c07c" -#define hex_fp2_dbl "2ea136125d08b824cd741a4c597dcdda0e6d52df468f917b0adb8ed709d7d72c-995e51aa30d8d45ae85f34da84c0589f6dece1e633b92146debbdc23afe20a11" -#define hex_fp2_tri "45f1d11b8b8d1437342e2772863cb4c715a3fc4ee9d75a38904956428ec3c2c2-8aed7a7f47f36b0f718cf99fcc59214c93ea0933c0583a7c5b61fca1962a6c5b" -#define hex_fp2_sub "2e2c92fe00a30bd05832b92ae09849310c48cb9e5f898a9e602bac1a4ca86d0b-7df387bf04911e2df2492c281883da7f06a299216eaf7533d300e54f32af4995" -#define hex_fp2_neg "9eef64f6d41f4adf6f499e29c8cfe0581abbe9db7733261e6001d3bc5e6559e7-0e70d72ae8e5694b76d23b3ab8673752da02d8b27360e6ca8359df8219b79db6" -#define hex_fp2_mul "192eb5c3350a03e4baf23dd035b8804af8d5189c710adda53edd9cc0633f2d67-27fe3a559abcc3e1b1fc3f1eb35b4bd5e465f0ef2bcb9997b36e3548637456b6" -#define hex_fp2_mul_u "27fe3a559abcc3e1b1fc3f1eb35b4bd5e465f0ef2bcb9997b36e3548637456b6-83e29479988f9f28601f2faf8a1dc6af304862123865339167b461a71cd2eaaf" -#define hex_fp2_mul_fp "546e5945201b73c6ae44053114761efe351d5884c737301cfc7d2376d349a616-3c2f6327ef1c5aa1d06e8cebc4100f0758c04476f40e8a0facb0a0bf09a9dd42" -#define hex_fp2_sqr "8896d4306fb19d0e4a0e09899240e35cafed70bebb3ad56cf7b07964fefdfb93-16bd622a907d7a92e475ed336e8ebca2cc1e38dd2ae69aaf2a96208eba0ee06e" -#define hex_fp2_sqr_u "16bd622a907d7a92e475ed336e8ebca2cc1e38dd2ae69aaf2a96208eba0ee06e-5b52579f25e413c717eb438cc69bc7d0e40a4518be8032dddb7e4385c8a693d4" -#define hex_fp2_inv "93ceda7dddd537eb9307a06313598e650a568d931d16ab98ca0a7483c3b502e2-6face8b958e2bdc0771fd9d700f2703f881ef0d13509f16937f0a0c344647175" -#define hex_fp2_div "ad68ff7c507f2d4e1cc6cd973c6b821906b9f5937a04fdedc84af1f75f97d00b-8a84a35da11d401c8dca50a572ce7a8c99e7117c45d251f57a2418613dab16bb" -#define hex_fp2_div2 "0ba84d8497422e09335d0693165f7376839b54b7d1a3e45ec2b6e3b5c275f5cb-af07946a8e30f24c1a9a8db2995b2b9bb4f126f1e0ca7b76a3c2ab66d67576a2" - -int test_sm9_fp2() { - sm9_fp2_t x; - sm9_fp2_t y; - sm9_fp2_t r; - sm9_fp2_t s; - sm9_fp_t k; - int j = 1; - - sm9_fp2_copy(x, SM9_P2->Y); - sm9_fp2_copy(y, SM9_Ppubs->X); - sm9_bn_from_hex(k, hex_iv); - - sm9_fp2_t iv2 = {{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, - {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}; - sm9_fp2_from_hex(r, hex_iv2); if (!sm9_fp2_equ(r, iv2)) goto err; ++j; - - sm9_fp2_add(r, x, y); sm9_fp2_from_hex(s, hex_fp2_add); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_dbl(r, x); sm9_fp2_from_hex(s, hex_fp2_dbl); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_tri(r, x); sm9_fp2_from_hex(s, hex_fp2_tri); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_sub(r, x, y); sm9_fp2_from_hex(s, hex_fp2_sub); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_neg(r, x); sm9_fp2_from_hex(s, hex_fp2_neg); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_mul(r, x, y); sm9_fp2_from_hex(s, hex_fp2_mul); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_mul_u(r, x, y); sm9_fp2_from_hex(s, hex_fp2_mul_u); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_mul_fp(r, x, k); sm9_fp2_from_hex(s, hex_fp2_mul_fp); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_sqr(r, x); sm9_fp2_from_hex(s, hex_fp2_sqr); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_sqr_u(r, x); sm9_fp2_from_hex(s, hex_fp2_sqr_u); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_inv(r, x); sm9_fp2_from_hex(s, hex_fp2_inv); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_div(r, x, y); sm9_fp2_from_hex(s, hex_fp2_div); if (!sm9_fp2_equ(r, s)) goto err; ++j; - sm9_fp2_div2(r, x); sm9_fp2_from_hex(s, hex_fp2_div2); if (!sm9_fp2_equ(r, s)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_iv4 \ - "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321\n" \ - "a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c\n" \ - "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321\n" \ - "a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c" -#define hex_fp4_mul \ - "11d8f3dc2c4a7cd3ff4d557d86871210cff65187190711430b2d898affd61cda\n" \ - "960ee85c0aaacd6cc805053293a4955245ba973c9972b6767d0c68450a905ee7\n" \ - "ac9891b21d82827f6ccc2cd8524179b833239019c0b66cad89d7d8735ee03782\n" \ - "8f456b1cee442d189d01fc42fff7fd8481173dae8dc547d85c01a843005a063e" -#define hex_fp4_mul_fp \ - "413b76fe8748ab9130dc2907a55c15da925b496395c2cd82d6311863a4d9cfa8\n" \ - "5cc754d5318f3ed489db7e53f94f3878a527053693983f4d4a61b30f6ea74984\n" \ - "6769891769934201aa8d6de63cc012ec2b722d7b0ad9c9039246a3eea6f3d479\n" \ - "408d33e58a4d3bfaf1d84a7ddad4e4026ca41f2aaa179611d9894584baed89d0" -#define hex_fp4_mul_fp2 \ - "242956015bdff53db568b970d64a7de56a0506309e1309b283317134dd52d53e\n" \ - "5333c472d44677df131eeb1180badb3e1e9f88ba58190d16a92d95f939efb2c3\n" \ - "0ccdaa76a6876ff69de6792161b614ca720bfcee2d5521533fbb28179ec0e31e\n" \ - "2a2d6b832e919c313920f2e13e822795e2ceda8c0d8f4abe78220e4e00aeb6fd" -#define hex_fp4_mul_v \ - "ac9891b21d82827f6ccc2cd8524179b833239019c0b66cad89d7d8735ee03782\n" \ - "8f456b1cee442d189d01fc42fff7fd8481173dae8dc547d85c01a843005a063e\n" \ - "960ee85c0aaacd6cc805053293a4955245ba973c9972b6767d0c68450a905ee7\n" \ - "928e1847aa0ead49d7690054e880a3238205f03ce86ccc55cf148811e3a50bc9" -#define hex_fp4_sqr \ - "8d3bc7848d4ad61017a7cb4efc280103bfe558e240c46c5765f1a4e2ec2e8c54\n" \ - "2f0f2ef9dd3979c7018b67837ba6e73938ba88ae66a101aaa0cf27ee449835ec\n" \ - "93838cbf9e5be34562c5bc031e27357d206f783837a6a921cbf4829292b69441\n" \ - "3681ecc58b68ffc15af31c5b1f1e10e1f3c60bdabb329c0dc7ffb2cc3925f005" -#define hex_fp4_sqr_v \ - "93838cbf9e5be34562c5bc031e27357d206f783837a6a921cbf4829292b69441\n" \ - "3681ecc58b68ffc15af31c5b1f1e10e1f3c60bdabb329c0dc7ffb2cc3925f005\n" \ - "2f0f2ef9dd3979c7018b67837ba6e73938ba88ae66a101aaa0cf27ee449835ec\n" \ - "520870f6eab1a1c37cb7c001f2cd8c82c41a74d1b36d0508fefbec89ee457252" -#define hex_fp4_inv \ - "1ec69309f84c5ad450750826fc804b72fb89fb48474222ba05be08bb1765f1d6\n" \ - "3f16de331f77f510a3ec06e79319e3be5b3777471f79cd53404652b485133e99\n" \ - "1cbf7f3bb04e2389184eade12de2752711cbff452363d2dfaf2bfef40618cebc\n" \ - "3a70e829b83dc311970bc8d3e3e652f88a1ecd49b4672aa18c1c613c9a97d86f" - -int test_sm9_fp4() { - sm9_fp4_t x; - sm9_fp4_t y; - sm9_fp4_t r; - sm9_fp4_t s; - sm9_fp2_t q; - sm9_fp_t k; - int j = 1; - - sm9_fp2_from_hex(x[0], hex_fp2_mul_fp); - sm9_fp2_from_hex(x[1], hex_fp2_sqr); - sm9_fp2_from_hex(y[0], hex_fp2_add); - sm9_fp2_from_hex(y[1], hex_fp2_tri); - sm9_bn_from_hex(k, hex_iv); - sm9_fp2_copy(q, SM9_Ppubs->X); - - sm9_fp4_t iv4 = {{{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, - {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}, - {{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, - {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}}; - sm9_fp4_from_hex(r, hex_iv4); if (!sm9_fp4_equ(r, iv4)) goto err; ++j; - - sm9_fp4_mul(r, x, y); sm9_fp4_from_hex(s, hex_fp4_mul); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_mul_fp(r, x, k); sm9_fp4_from_hex(s, hex_fp4_mul_fp); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_mul_fp2(r, x, q); sm9_fp4_from_hex(s, hex_fp4_mul_fp2); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_mul_v(r, x, y); sm9_fp4_from_hex(s, hex_fp4_mul_v); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_sqr(r, x); sm9_fp4_from_hex(s, hex_fp4_sqr); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_sqr_v(r, x); sm9_fp4_from_hex(s, hex_fp4_sqr_v); if (!sm9_fp4_equ(r, s)) goto err; ++j; - sm9_fp4_inv(r, x); sm9_fp4_from_hex(s, hex_fp4_inv); if (!sm9_fp4_equ(r, s)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_fp12_mul \ - "058d43459faee14ba2b6a69ff2d8c3ad933a1253e1764dedf5419b144a2ab82b\n" \ - "20ef84805ba02ef92a48fb2ae8086e566a644ab0639249f175268f18d8091ad4\n" \ - "83cc3be54a699ae24d8f920c87baa395befb424a6dcad1dcdfc2a006765ef8d5\n" \ - "1d705169165d9c2386c3bc673df3fa84975afa955a7be27f1b362000a96b8c2c\n" \ - "22b910d826f02961ff0fed439beb1e91f45193f87c2cdd9562da539290846ace\n" \ - "2c618991ae82d35063cfed629ff7d930b8070ba07d0652ba092f046e133e3491\n" \ - "137bc78a9aa182330bd71fb8859314422dd36f5e3c1f6fd36d6c9685fc39419f\n" \ - "8d83e7380abe10a2f3677864c2dbbcdad7ae5434e92043a2da3b71f3f9cedd8c\n" \ - "850c0562ac08996c05d22ea466cf4b1fa7a7064d4653b5fa725d623254bf7125\n" \ - "6dc41016b3ab9b44a4841aa8037e3b4d331cc7c8313abee0c5111a9be5915e90\n" \ - "6d1a15e5b765c4b139bf5c6c4a87214c269b26fb709ff5de885c053f405cf626\n" \ - "8d4d853489a4a5d809fa77e35627a5351651b926f001e1ee46e95808f9001d24" -#define hex_fp12_sqr \ - "3592cba3482fb39756b2ed1d3d756685caa005bd5e8288bc92841d29276aa321\n" \ - "8e3a49919e6de83b1ab1a5bb9eb993c3bbd68e8d305aed5c0b88cef0ef41c47f\n" \ - "3d3d9cc8e07619efd21745f6938a26f7cb0a83ad4aa3a9d066e18ad99833e3ac\n" \ - "25195ec7af551c42d7d37a0b120607d4adba6b9377299688b92a8393f3b8c20f\n" \ - "76f676d5d2cb8d1a2cc237fc78c8d544bef1cd560e654236f502aed0d8c9148c\n" \ - "6cde174a5e9d117175a4a163f041b65f868dffa05b5f3474f729b87f92493f2c\n" \ - "667a86d73e8f88a81306f7f0cd28789a55bf7e9cbe155fc6abb300ad027d8801\n" \ - "a49a66d48ec2ef72a9929413a40e316a8aee1d6236a1db8c56496524f1c23f11\n" \ - "1684bc9679aaba4afe35ec8c0852e438f41e15ab37620d9661018f90fe7415f1\n" \ - "8d37fb8b7edf942885b3009cf7e295bea89444d34091fc57380c778395b7c4e4\n" \ - "278b9d9ea61b6b2758e758ed9a64034576b520e65a9d276a0c82f079501a226e\n" \ - "01a333fa4177601de7cd8ed49ea4906f30e23988dcb7cde173da48499fce3ee5" -#define hex_fp12_inv \ - "47ae900b90945e31afde7fe09f0b69640c468a1648ee52070584a5d13af22bb9\n" \ - "8f273655182c3a9f184dc30421161ecdd50655c36a9266c7df1016e410f34102\n" \ - "a26e789013203804b5f8f1c5a51dd3fb50176d41108b235d6e66712721060252\n" \ - "090aaed5cb83068a0376c6eaca210007744d00c8b4ce53279a67cc069cc519e7\n" \ - "80ab89aa446df59ffe2f29cdb917b760d740ceb634c731b93bf1661aa5868b54\n" \ - "1e13ab51b3198619cc0016599562ed4d266d1481d0d273d3f97cffe5f8e0dd21\n" \ - "5aeb8ed89aafc971a857b8d02f3e3c37ef15ba0e3220e3a7c13c9da8af0c393b\n" \ - "518c338b1430e3129c2555650e5d5634d89513f694ba3a5f2aeb444c540f125a\n" \ - "aba8c5682695f3feee64772d0e49b432c96470e7d663098e9c271a91d4fc991a\n" \ - "0ed800dabe29af5fb41a41cc49fd4084deb02442e8e66f88186607f46395e533\n" \ - "a31b642cd5453c7bb16c82bc67bd3b66fa4db58b8e9aa45f9b579860f18d402c\n" \ - "798b84002e95753e3b07027a8d68b0a7ab2ac40328fc7ca3ea40780b3428dbc1" -#define hex_fp12_pow \ - "43291d68970ec9c00ed4616b8fa4b2b332c15a6e4ed833a4b1d68db20a06896c\n" \ - "48f861508cb878a1f1f806a486f3aa6889571bd5fb1010d73933550d219afd14\n" \ - "34b20766a4cc466efe1ee0d48206d683890494aec331d5b345e9a9adb5c5845a\n" \ - "0e3edea737b3db1083b776eb48e7bfaa4256a8d37d7ab13a370d7682daaf794d\n" \ - "9808adfd960da7837736fca5acb13a84d56962a21af424e48c0aa52c77dfd157\n" \ - "a8aa94ea4f3026eed8fa99ab9a793468db12bb7256c50570e72e375f981861a1\n" \ - "3fd308b4cdcec640fa4f17aac455b2f3daed3fb86a850b47c301c3941dbd6c4c\n" \ - "11b99f09fa20368e840c3d76e706939e4a3e8367165bb802de43acc83ae622d5\n" \ - "a5e97a50168650cae7b02b4c2511eeb194cd5ea5ff02a0284abd5961b46d47e4\n" \ - "b52a91d96353ef501bdbe6424ea26414faeeb930b9e618c2882a85d1fdeea3d0\n" \ - "6c78632b7dbbbdbf347a3f5fd6935a9f9b425125b7ac106e3586a7fbee3f2f20\n" \ - "6b35df1d1153684f1363fce020088a797802e18959df4f006bc5d7f4a632e9f9" - -int test_sm9_fp12() { - sm9_fp12_t x; - sm9_fp12_t y; - sm9_fp12_t r; - sm9_fp12_t s; - sm9_bn_t k; - int j = 1; - - sm9_fp4_from_hex(x[0], hex_fp4_mul); - sm9_fp4_from_hex(x[1], hex_fp4_mul_fp); - sm9_fp4_from_hex(x[2], hex_fp4_mul_fp2); - sm9_fp4_from_hex(y[0], hex_fp4_mul_v); - sm9_fp4_from_hex(y[1], hex_fp4_sqr); - sm9_fp4_from_hex(y[2], hex_fp4_inv); - sm9_bn_from_hex(k, hex_iv); - - sm9_fp12_mul(r, x, y); sm9_fp12_from_hex(s, hex_fp12_mul); if (!sm9_fp12_equ(r, s)) goto err; ++j; - sm9_fp12_sqr(r, x); sm9_fp12_from_hex(s, hex_fp12_sqr); if (!sm9_fp12_equ(r, s)) goto err; ++j; - sm9_fp12_inv(r, x); sm9_fp12_from_hex(s, hex_fp12_inv); if (!sm9_fp12_equ(r, s)) goto err; ++j; - sm9_fp12_pow(r, x, k); sm9_fp12_from_hex(s, hex_fp12_pow); if (!sm9_fp12_equ(r, s)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_point1 "917be49d159184fba140f4dfc5d653464e94f718fe195b226b3f715829e6e768-288578d9505d462867a50acee40ee143b896e72505be10e8ce4c6b0c945b642b" -#define hex_point2 "593417680f252445fd0522383e23c77a54b11fe222de4a886eabc26e16bffa3c-38e8fc9a8b60f5ba0c6c411f721c117044435a833757d8fee65828511b8b245d" -#define hex_point_dbl "268def7968f1e8c51635e277425403df88355fb2ecf16f7920f112eb2a7e50c9-5c596b534bbaa85c1d3aecf436e61ff1bfd9f70856f0309c2a63d8248205d84e" -#define hex_point_add "056610cb69f8d5659ea94e4a67bbf3b93fb0bd449672d7ca2525ec3b68c894d1-88f3f99ce78ed3ffe6ca1cface5242570cb5d053f16a8e0baae10414babd86a7" -#define hex_point_neg "917be49d159184fba140f4dfc5d653464e94f718fe195b226b3f715829e6e768-8dba8726b24660c96e5ea081117fe601695bac2614bcddf31723301b4ef5e152" -#define hex_point_sub "29e4a54cad98da9939b95f677784bff3b1dd9334c83d93e351e0f8f7c4ce2dc5-4473eba3b8ff990b8456c41ec0727b76cb2b0f960495b144949f70bf95643b82" -#define hex_point_mul "997fcff625adbae62566f684f9e89181713f972c5a9cd9ce6764636761ba87d1-8142a28d1bd109501452a649e2d68f012e265460e0c7d3da743fb036eb23b03b" -#define hex_point_mul_g "7cf689748f3714490d7a19eae0e7bfad0e0182498b7bcd8a6998dfd00f59be51-4e2e98d190e9d775e0caa943196bfb066d9c30818b2d768fb5299e7135830a6f" - -int test_sm9_point() { - SM9_POINT p; - SM9_POINT q; - SM9_POINT r; - SM9_POINT s; - sm9_bn_t k; - int j = 1; - uint8_t buf[65]; - - sm9_bn_from_hex(k, hex_iv); - - sm9_point_from_hex(&p, hex_point1); if (!sm9_point_is_on_curve(&p)) goto err; ++j; - sm9_point_from_hex(&q, hex_point2); if (!sm9_point_is_on_curve(&q)) goto err; ++j; - sm9_point_dbl(&r, &p); sm9_point_from_hex(&s, hex_point_dbl); if (!sm9_point_equ(&r, &s)) goto err; ++j; - sm9_point_add(&r, &p, &q); sm9_point_from_hex(&s, hex_point_add); if (!sm9_point_equ(&r, &s)) goto err; ++j; - sm9_point_neg(&r, &p); sm9_point_from_hex(&s, hex_point_neg); if (!sm9_point_equ(&r, &s)) goto err; ++j; - sm9_point_sub(&r, &p, &q); sm9_point_from_hex(&s, hex_point_sub); if (!sm9_point_equ(&r, &s)) goto err; ++j; - sm9_point_mul(&r, k, &p); sm9_point_from_hex(&s, hex_point_mul); if (!sm9_point_equ(&r, &s)) goto err; ++j; - sm9_point_mul_generator(&r, k); sm9_point_from_hex(&s, hex_point_mul_g); if (!sm9_point_equ(&r, &s)) goto err; ++j; - - sm9_point_to_uncompressed_octets(&p, buf); - sm9_point_from_uncompressed_octets(&q, buf); - if (!sm9_point_equ(&p, &q)) { - error_print(); - return -1; - } - - - - - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_tpoint1 \ - "83f6a65d85d51ec72eacf19bc38384e0369eb22a134a725a0191faa6e4f192ef\n" \ - "9a79bfd491ef1cb32d9b57f7d0590ccff6b1cfe63dd15c0823d692fafbe96dbc\n" \ - "9ed11c499291db0454d738555af0ce8a1df960056ee7425a6bf296eae60a5037\n" \ - "849d4434eb7113fc9fb3809b51d54064fa2f20503423d256bc044905b1eba3fb" -#define hex_tpoint2 \ - "a36232a9713f69157b7cdceef54aa0237b3ba0642a80dbb597af8935aea2c130\n" \ - "624b19114e49f00281e2aee1f1b9d4f0a081a135868f8bbdb7b7a7b7da5fd6bc\n" \ - "77966917ec1c5a294dd836c34691ab5e891f8c9f017443902c0a73ec54d449d8\n" \ - "1be45454b6fa085a53744b22fd398238e400c3e031c8796e59e1bd6222048af0" -#define hex_tpoint_neg \ - "83f6a65d85d51ec72eacf19bc38384e0369eb22a134a725a0191faa6e4f192ef\n" \ - "9a79bfd491ef1cb32d9b57f7d0590ccff6b1cfe63dd15c0823d692fafbe96dbc\n" \ - "176ee3b67011cbed812c72fa9a9df8bb03f93345ab93ac81797d043cfd46f546\n" \ - "31a2bbcb173292f536502ab4a3b986e027c372fae6571c85296b52223165a182" -#define hex_tpoint_dbl \ - "73cbced58a8e76ef5235b480050a74e906e4d27185bd85d7ebdcd43ad24475fd\n" \ - "58400f0eb23000d814f5b5d0706749a72909795b7b04f26d6d58b2cf478ad9c9\n" \ - "19b460e09ac9ddbb380d6441e078a47bfcaa7d4c3d60b3a6c0d05f896472dc3c\n" \ - "1d69f785f47d6f25cb901b131612c37edc5e89ee9ba2dac8c401ced40e340a39" -#define hex_tpoint_add \ - "5f443752a19e368f404b89abae20a386d2b534c424b93ededdbfd04d4c569e6b\n" \ - "a411bbd84ee92a6ee53e5ca9cb81bacc192c6ba406f6fdcb2b04d0ab9c42ae44\n" \ - "6a3dadfcaac134e8353dd3abf37d487b206ca28dfab1e0a9376649df748f1605\n" \ - "4fa25e5e6100a023d4923df385dd236749c6a7f8e68db55e0bd1e2263fc04d28" -#define hex_tpoint_sub \ - "3cbbf5fcc6c11a3579036e617bbf0b2861c53979f01e37f59fc4a10d991ccde7\n" \ - "1e9c3c99524c7867c9dbc4f52fdc938cf5aa4a980d3905cc91a5b91331235290\n" \ - "44027c5d814bab73ad93d14b564303aab153ad7355bcfbf8a8bed7cb577e7fd8\n" \ - "47a4037d1d6f6d2014aa04292fa91cf07b1f4331a85d4b66a6e048226ddfc43e" -#define hex_tpoint_mul \ - "5d704de3261290dbba39dbd14e6bc416025240fd1ed65ec982efed685ae41e8b\n" \ - "705c9ca4b5ef465c4e5db80ca4880627a6d9d6bcefd4756496baba9d5eaa3304\n" \ - "4e96eb3543aabf1e9a65cae24177b9d13b0f7fae9472145ba7ae2b14bb447aef\n" \ - "5d7ba50d7eac49a00b18fee2069afd3cc9719993fa78271e66b7a3efed46ac8b" -#define hex_tpoint_mulg \ - "920ef6fb3a2acff52aa0c004c18feca149dfd33d98086f8f402ea9e0de303c49\n" \ - "1f97dd359f2b065d63e0987f5bea2f3dc865c2cc112d7d161b46b83451716fd8\n" \ - "614881d4d05fef3173a4990465876c5200f58c5015e13354b23ae401c20c4aef\n" \ - "18a22e02b7d395a49f0646a79438e79cd37c32f163fe8923c13d56bab668e8a7" - -int test_sm9_twist_point() { - SM9_TWIST_POINT p; - SM9_TWIST_POINT q; - SM9_TWIST_POINT r; - SM9_TWIST_POINT s; - sm9_bn_t k; - int j = 1; - - sm9_bn_from_hex(k, hex_iv); - - sm9_twist_point_from_hex(&p, hex_tpoint1); if (!sm9_twist_point_is_on_curve(&p)) goto err; ++j; - sm9_twist_point_from_hex(&q, hex_tpoint2); if (!sm9_twist_point_is_on_curve(&q)) goto err; ++j; - sm9_twist_point_neg(&r, &p); sm9_twist_point_from_hex(&s, hex_tpoint_neg); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_dbl(&r, &p); sm9_twist_point_from_hex(&s, hex_tpoint_dbl); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_add(&r, &p, &q); sm9_twist_point_from_hex(&s, hex_tpoint_add); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_add_full(&r, &p, &q); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_sub(&r, &p, &q); sm9_twist_point_from_hex(&s, hex_tpoint_sub); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_mul(&r, k, &p); sm9_twist_point_from_hex(&s, hex_tpoint_mul); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - sm9_twist_point_mul_generator(&r, k); sm9_twist_point_from_hex(&s, hex_tpoint_mulg); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_pairing1 \ - "4e378fb5561cd0668f906b731ac58fee25738edf09cadc7a29c0abc0177aea6d\n" \ - "28b3404a61908f5d6198815c99af1990c8af38655930058c28c21bb539ce0000\n" \ - "38bffe40a22d529a0c66124b2c308dac9229912656f62b4facfced408e02380f\n" \ - "a01f2c8bee81769609462c69c96aa923fd863e209d3ce26dd889b55e2e3873db\n" \ - "67e0e0c2eed7a6993dce28fe9aa2ef56834307860839677f96685f2b44d0911f\n" \ - "5a1ae172102efd95df7338dbc577c66d8d6c15e0a0158c7507228efb078f42a6\n" \ - "1604a3fcfa9783e667ce9fcb1062c2a5c6685c316dda62de0548baa6ba30038b\n" \ - "93634f44fa13af76169f3cc8fbea880adaff8475d5fd28a75deb83c44362b439\n" \ - "b3129a75d31d17194675a1bc56947920898fbf390a5bf5d931ce6cbb3340f66d\n" \ - "4c744e69c4a2e1c8ed72f796d151a17ce2325b943260fc460b9f73cb57c9014b\n" \ - "84b87422330d7936eaba1109fa5a7a7181ee16f2438b0aeb2f38fd5f7554e57a\n" \ - "aab9f06a4eeba4323a7833db202e4e35639d93fa3305af73f0f071d7d284fcfb" - -#define hex_RA \ - "7CBA5B19069EE66AA79D490413D11846B9BA76DD22567F809CF23B6D964BB265\n" \ - "A9760C99CB6F706343FED05637085864958D6C90902ABA7D405FBEDF7B781599" -#define hex_deB \ - "74CCC3AC9C383C60AF083972B96D05C75F12C8907D128A17ADAFBAB8C5A4ACF7\n" \ - "01092FF4DE89362670C21711B6DBE52DCD5F8E40C6654B3DECE573C2AB3D29B2\n" \ - "44B0294AA04290E1524FF3E3DA8CFD432BB64DE3A8040B5B88D1B5FC86A4EBC1\n" \ - "8CFC48FB4FF37F1E27727464F3C34E2153861AD08E972D1625FC1A7BD18D5539" - -#define hex_pairing2 \ - "28542FB6954C84BE6A5F2988A31CB6817BA0781966FA83D9673A9577D3C0C134\n" \ - "5E27C19FC02ED9AE37F5BB7BE9C03C2B87DE027539CCF03E6B7D36DE4AB45CD1\n" \ - "A1ABFCD30C57DB0F1A838E3A8F2BF823479C978BD137230506EA6249C891049E\n" \ - "3497477913AB89F5E2960F382B1B5C8EE09DE0FA498BA95C4409D630D343DA40\n" \ - "4FEC93472DA33A4DB6599095C0CF895E3A7B993EE5E4EBE3B9AB7D7D5FF2A3D1\n" \ - "647BA154C3E8E185DFC33657C1F128D480F3F7E3F16801208029E19434C733BB\n" \ - "73F21693C66FC23724DB26380C526223C705DAF6BA18B763A68623C86A632B05\n" \ - "0F63A071A6D62EA45B59A1942DFF5335D1A232C9C5664FAD5D6AF54C11418B0D\n" \ - "8C8E9D8D905780D50E779067F2C4B1C8F83A8B59D735BB52AF35F56730BDE5AC\n" \ - "861CCD9978617267CE4AD9789F77739E62F2E57B48C2FF26D2E90A79A1D86B93\n" \ - "9B1CA08F64712E33AEDA3F44BD6CB633E0F722211E344D73EC9BBEBC92142765\n" \ - "6BA584CE742A2A3AB41C15D3EF94EDEB8EF74A2BDCDAAECC09ABA567981F6437" - - -#define hex_Ppube \ - "9174542668E8F14AB273C0945C3690C66E5DD09678B86F734C4350567ED06283\n" \ - "54E598C6BF749A3DACC9FFFEDD9DB6866C50457CFC7AA2A4AD65C3168FF74210" -#define rB "00018B98C44BEF9F8537FB7D071B2C928B3BC65BD3D69E1EEE213564905634FE" -#define hex_pairing3 \ - "1052D6E9D13E381909DFF7B2B41E13C987D0A9068423B769480DACCE6A06F492\n" \ - "5FFEB92AD870F97DC0893114DA22A44DBC9E7A8B6CA31A0CF0467265A1FB48C7\n" \ - "2C5C3B37E4F2FF83DB33D98C0317BCBBBBF4AC6DF6B89ECA58268B280045E612\n" \ - "6CED9E2D7C9CD3D5AD630DEFAB0B831506218037EE0F861CF9B43C78434AEC38\n" \ - "0AE7BF3E1AEC0CB67A03440906C7DFB3BCD4B6EEEBB7E371F0094AD4A816088D\n" \ - "98DBC791D0671CACA12236CDF8F39E15AEB96FAEB39606D5B04AC581746A663D\n" \ - "00DD2B7416BAA91172E89D5309D834F78C1E31B4483BB97185931BAD7BE1B9B5\n" \ - "7EBAC0349F8544469E60C32F6075FB0468A68147FF013537DF792FFCE024F857\n" \ - "10CC2B561A62B62DA36AEFD60850714F49170FD94A0010C6D4B651B64F3A3A5E\n" \ - "58C9687BEDDCD9E4FEDAB16B884D1FE6DFA117B2AB821F74E0BF7ACDA2269859\n" \ - "2A430968F16086061904CE201847934B11CA0F9E9528F5A9D0CE8F015C9AEA79\n" \ - "934FDDA6D3AB48C8571CE2354B79742AA498CB8CDDE6BD1FA5946345A1A652F6" - - -int test_sm9_pairing() { - SM9_TWIST_POINT p; - SM9_POINT q; - sm9_fp12_t r; - sm9_fp12_t s; - sm9_bn_t k; - int j = 1; - - sm9_pairing(r, SM9_Ppubs, SM9_P1); sm9_fp12_from_hex(s, hex_pairing1); if (!sm9_fp12_equ(r, s)) goto err; ++j; - - sm9_twist_point_from_hex(&p, hex_deB); sm9_point_from_hex(&q, hex_RA); - sm9_pairing(r, &p, &q); sm9_fp12_from_hex(s, hex_pairing2); if (!sm9_fp12_equ(r, s)) goto err; ++j; - - sm9_bn_from_hex(k, rB); sm9_point_from_hex(&q, hex_Ppube); - sm9_pairing(r, SM9_P2, &q); sm9_fp12_pow(r, r, k); sm9_fp12_from_hex(s, hex_pairing3); if (!sm9_fp12_equ(r, s)) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_ks "000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4" -#define hex_ds "A5702F05CF1315305E2D6EB64B0DEB923DB1A0BCF0CAFF90523AC8754AA69820-78559A844411F9825C109F5EE3F52D720DD01785392A727BB1556952B2B013D3" - -int test_sm9_sign() { - SM9_SIGN_CTX ctx; - SM9_SIGN_KEY key; - SM9_SIGN_MASTER_KEY mpk; - SM9_POINT ds; - uint8_t sig[1000] = {0}; - size_t siglen = 0; - int j = 1; - - uint8_t data[20] = {0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64}; - uint8_t IDA[5] = {0x41, 0x6C, 0x69, 0x63, 0x65}; - - sm9_bn_from_hex(mpk.ks, hex_ks); sm9_twist_point_mul_generator(&(mpk.Ppubs), mpk.ks); - if (sm9_sign_master_key_extract_key(&mpk, (char *)IDA, sizeof(IDA), &key) < 0) goto err; ++j; - sm9_point_from_hex(&ds, hex_ds); if (!sm9_point_equ(&(key.ds), &ds)) goto err; ++j; - - sm9_sign_init(&ctx); - sm9_sign_update(&ctx, data, sizeof(data)); - if (sm9_sign_finish(&ctx, &key, sig, &siglen) < 0) goto err; ++j; - - sm9_verify_init(&ctx); - sm9_verify_update(&ctx, data, sizeof(data)); - if (sm9_verify_finish(&ctx, sig, siglen, &mpk, (char *)IDA, sizeof(IDA)) != 1) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -#define hex_ke "0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22" - -#define hex_de \ - "94736ACD2C8C8796CC4785E938301A139A059D3537B6414140B2D31EECF41683\n" \ - "115BAE85F5D8BC6C3DBD9E5342979ACCCF3C2F4F28420B1CB4F8C0B59A19B158\n" \ - "7AA5E47570DA7600CD760A0CF7BEAF71C447F3844753FE74FA7BA92CA7D3B55F\n" \ - "27538A62E7F7BFB51DCE08704796D94C9D56734F119EA44732B50E31CDEB75C1" - -int test_sm9_ciphertext() -{ - SM9_POINT C1; - uint8_t c2[SM9_MAX_PLAINTEXT_SIZE]; - uint8_t c3[SM3_HMAC_SIZE]; - uint8_t buf[1024]; - uint8_t *p = buf; - size_t len = 0; - - sm9_point_copy(&C1, SM9_P1); - if (sm9_ciphertext_to_der(&C1, c2, sizeof(c2), c3, &p, &len) != 1) { - error_print(); - return -1; - } - //printf("SM9_MAX_CIPHERTEXT_SIZE %zu\n", len); - return 1; -} - - -int test_sm9_encrypt() { - SM9_ENC_MASTER_KEY msk; - SM9_ENC_KEY key; - SM9_TWIST_POINT de; - uint8_t out[1000] = {0}; - size_t outlen = 0; - int j = 1; - - uint8_t data[20] = {0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64}; - uint8_t dec[20] = {0}; - size_t declen = 20; - uint8_t IDB[3] = {0x42, 0x6F, 0x62}; - - sm9_bn_from_hex(msk.ke, hex_ke); sm9_point_mul_generator(&(msk.Ppube), msk.ke); - if (sm9_enc_master_key_extract_key(&msk, (char *)IDB, sizeof(IDB), &key) < 0) goto err; ++j; - sm9_twist_point_from_hex(&de, hex_de); if (!sm9_twist_point_equ(&(key.de), &de)) goto err; ++j; - - if (sm9_encrypt(&msk, (char *)IDB, sizeof(IDB), data, sizeof(data), out, &outlen) < 0) goto err; ++j; - if (sm9_decrypt(&key, (char *)IDB, sizeof(IDB), out, outlen, dec, &declen) < 0) goto err; ++j; - if (memcmp(data, dec, sizeof(data)) != 0) goto err; ++j; - - printf("%s() ok\n", __FUNCTION__); - return 1; -err: - printf("%s test %d failed\n", __FUNCTION__, j); - error_print(); - return -1; -} - -int main(void) { - if (test_sm9_fp() != 1) goto err; - if (test_sm9_fn() != 1) goto err; - if (test_sm9_fp2() != 1) goto err; - if (test_sm9_fp4() != 1) goto err; - if (test_sm9_fp12() != 1) goto err; - if (test_sm9_point() != 1) goto err; - if (test_sm9_twist_point() != 1) goto err; - if (test_sm9_pairing() != 1) goto err; - if (test_sm9_sign() != 1) goto err; - if (test_sm9_ciphertext() != 1) goto err; - if (test_sm9_encrypt() != 1) goto err; - - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include + + +static int sm9_bn_equ_hex(const sm9_bn_t a, const char *hex) +{ + sm9_bn_t b; + sm9_bn_from_hex(b, hex); + return (sm9_bn_cmp(a, b) == 0); +} + + +#define hex_iv "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321" +#define hex_fp_add "114efe24536598809df494ff7657484edff1812d51c3955b7d869149aa123d31" +#define hex_fp_sub "43cee97c9abed9be3efe7ffffc9d30abe1d643b9b27ea351460aabb2239d3fd4" +#define hex_fp_nsub "7271168367e4cd3397052b4ff8f19699401c4f9167fc4b8a9f64ef75bfb405a9" +#define hex_fp_dbl "551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05" +#define hex_fp_tri "248cdb7163e4d7e5606ac9d731a751d591b25db4f925dd9532a20de5c2de98c9" +#define hex_fp_div2 "9df779e83d83d9c517bf85bbd4e833b289e7dfb214ecc1501cf8039cdde8d35f" +#define hex_fp_neg "30910c2f8a3f9a597c884b28414d2725301567320b1c5b1790ef2f160ad0e43c" +#define hex_fp_mul "9e4d19bb5d94a47352e6f53f4116b2a71b16a1113dc789b26528ee19f46b72e0" +#define hex_fp_sqr "46dc2a5b8853234b341d9c57f9c4ca5709e95bbfef25356812e884e4f38cd0d6" +#define hex_fp_pow "5679a8f0a46ada5b9d48008cde0b8b7a233f882c08afe8f08a36a20ac845bb1a" +#define hex_fp_inv "7d404b0027a93e3fa8f8bc7ee367a96814c42a3b69feb1845093406948a34753" + +int test_sm9_fp() { + sm9_fp_t x; + sm9_fp_t y; + sm9_fp_t r; + int j = 1; + + sm9_bn_copy(x, SM9_P2->X[1]); + sm9_bn_copy(y, SM9_Ppubs->Y[0]); + + sm9_fp_t iv = {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}; + sm9_bn_from_hex(r, hex_iv); if (sm9_bn_cmp(r, iv) != 0) goto err; ++j; + + sm9_fp_add(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_add)) goto err; ++j; + sm9_fp_sub(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_sub)) goto err; ++j; + sm9_fp_sub(r, y, x); if (!sm9_bn_equ_hex(r, hex_fp_nsub)) goto err; ++j; + sm9_fp_dbl(r, x); if (!sm9_bn_equ_hex(r, hex_fp_dbl)) goto err; ++j; + sm9_fp_tri(r, x); if (!sm9_bn_equ_hex(r, hex_fp_tri)) goto err; ++j; + sm9_fp_div2(r, x); if (!sm9_bn_equ_hex(r, hex_fp_div2)) goto err; ++j; + sm9_fp_neg(r, x); if (!sm9_bn_equ_hex(r, hex_fp_neg)) goto err; ++j; + sm9_fp_mul(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_mul)) goto err; ++j; + sm9_fp_sqr(r, x); if (!sm9_bn_equ_hex(r, hex_fp_sqr)) goto err; ++j; + sm9_fp_pow(r, x, y); if (!sm9_bn_equ_hex(r, hex_fp_pow)) goto err; ++j; + sm9_fp_inv(r, x); if (!sm9_bn_equ_hex(r, hex_fp_inv)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s() test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_x "483f336f119053cba8c0e738cabc2bfdbf047caf7e1aaa92526fa48041ceea2b" +#define hex_y "3220b45276e3692a387faa7bf3cd46e390608f2f4298cce467bf2b7fda091edb" +#define hex_fn_add "7a5fe7c18873bcf5e14091b4be8972e14f650bdec0b37776ba2ed0001bd80906" +#define hex_fn_sub "161e7f1c9aaceaa170413cbcd6eee51a2ea3ed803b81ddadeab0790067c5cb50" +#define hex_fn_nsub "a02180e367f6bc5065c26e931e9fe22a1b4ea5cadd68ae40fabe689c6ed903d5" +#define hex_fn_mul "25c528484b65755b1ff57b47b77f2b32e20467be1dde566ede4264b2e092d223" +#define hex_fn_pow "445cb9b76f27e9d03a2c30fbabb59b0ea6d7b06259b0c8a1b30f21b9b274a055" +#define hex_fn_inv "3e3e849c2144c3596d9c79cb1f8ee7c60828787e298b06cc341a9a165191bc5e" + +int test_sm9_fn() { + sm9_fn_t x; + sm9_fn_t y; + sm9_fn_t r; + int j = 1; + + sm9_bn_from_hex(x, hex_x); + sm9_bn_from_hex(y, hex_y); + + sm9_fn_t iv = {0, 0, 0, 0, 0, 0, 0, 0}; if (!sm9_fn_is_zero(iv)) goto err; ++j; + sm9_fn_add(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_add)) goto err; ++j; + sm9_fn_sub(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_sub)) goto err; ++j; + sm9_fn_sub(r, y, x); if (!sm9_bn_equ_hex(r, hex_fn_nsub)) goto err; ++j; + sm9_fn_mul(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_mul)) goto err; ++j; + sm9_fn_pow(r, x, y); if (!sm9_bn_equ_hex(r, hex_fn_pow)) goto err; ++j; + sm9_fn_inv(r, x); if (!sm9_bn_equ_hex(r, hex_fn_inv)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_iv2 "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321-a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c" +#define hex_fp2_add "0074a3145c65ac547541612178e584a902248740e70606dcaaafe2bcbd2f6a21-1b6ac9eb2c47b62cf61608b26c3c7e20674a48c4c509ac130bbaf6d47d32c07c" +#define hex_fp2_dbl "2ea136125d08b824cd741a4c597dcdda0e6d52df468f917b0adb8ed709d7d72c-995e51aa30d8d45ae85f34da84c0589f6dece1e633b92146debbdc23afe20a11" +#define hex_fp2_tri "45f1d11b8b8d1437342e2772863cb4c715a3fc4ee9d75a38904956428ec3c2c2-8aed7a7f47f36b0f718cf99fcc59214c93ea0933c0583a7c5b61fca1962a6c5b" +#define hex_fp2_sub "2e2c92fe00a30bd05832b92ae09849310c48cb9e5f898a9e602bac1a4ca86d0b-7df387bf04911e2df2492c281883da7f06a299216eaf7533d300e54f32af4995" +#define hex_fp2_neg "9eef64f6d41f4adf6f499e29c8cfe0581abbe9db7733261e6001d3bc5e6559e7-0e70d72ae8e5694b76d23b3ab8673752da02d8b27360e6ca8359df8219b79db6" +#define hex_fp2_mul "192eb5c3350a03e4baf23dd035b8804af8d5189c710adda53edd9cc0633f2d67-27fe3a559abcc3e1b1fc3f1eb35b4bd5e465f0ef2bcb9997b36e3548637456b6" +#define hex_fp2_mul_u "27fe3a559abcc3e1b1fc3f1eb35b4bd5e465f0ef2bcb9997b36e3548637456b6-83e29479988f9f28601f2faf8a1dc6af304862123865339167b461a71cd2eaaf" +#define hex_fp2_mul_fp "546e5945201b73c6ae44053114761efe351d5884c737301cfc7d2376d349a616-3c2f6327ef1c5aa1d06e8cebc4100f0758c04476f40e8a0facb0a0bf09a9dd42" +#define hex_fp2_sqr "8896d4306fb19d0e4a0e09899240e35cafed70bebb3ad56cf7b07964fefdfb93-16bd622a907d7a92e475ed336e8ebca2cc1e38dd2ae69aaf2a96208eba0ee06e" +#define hex_fp2_sqr_u "16bd622a907d7a92e475ed336e8ebca2cc1e38dd2ae69aaf2a96208eba0ee06e-5b52579f25e413c717eb438cc69bc7d0e40a4518be8032dddb7e4385c8a693d4" +#define hex_fp2_inv "93ceda7dddd537eb9307a06313598e650a568d931d16ab98ca0a7483c3b502e2-6face8b958e2bdc0771fd9d700f2703f881ef0d13509f16937f0a0c344647175" +#define hex_fp2_div "ad68ff7c507f2d4e1cc6cd973c6b821906b9f5937a04fdedc84af1f75f97d00b-8a84a35da11d401c8dca50a572ce7a8c99e7117c45d251f57a2418613dab16bb" +#define hex_fp2_div2 "0ba84d8497422e09335d0693165f7376839b54b7d1a3e45ec2b6e3b5c275f5cb-af07946a8e30f24c1a9a8db2995b2b9bb4f126f1e0ca7b76a3c2ab66d67576a2" + +int test_sm9_fp2() { + sm9_fp2_t x; + sm9_fp2_t y; + sm9_fp2_t r; + sm9_fp2_t s; + sm9_fp_t k; + int j = 1; + + sm9_fp2_copy(x, SM9_P2->Y); + sm9_fp2_copy(y, SM9_Ppubs->X); + sm9_bn_from_hex(k, hex_iv); + + sm9_fp2_t iv2 = {{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, + {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}; + sm9_fp2_from_hex(r, hex_iv2); if (!sm9_fp2_equ(r, iv2)) goto err; ++j; + + sm9_fp2_add(r, x, y); sm9_fp2_from_hex(s, hex_fp2_add); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_dbl(r, x); sm9_fp2_from_hex(s, hex_fp2_dbl); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_tri(r, x); sm9_fp2_from_hex(s, hex_fp2_tri); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_sub(r, x, y); sm9_fp2_from_hex(s, hex_fp2_sub); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_neg(r, x); sm9_fp2_from_hex(s, hex_fp2_neg); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_mul(r, x, y); sm9_fp2_from_hex(s, hex_fp2_mul); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_mul_u(r, x, y); sm9_fp2_from_hex(s, hex_fp2_mul_u); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_mul_fp(r, x, k); sm9_fp2_from_hex(s, hex_fp2_mul_fp); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_sqr(r, x); sm9_fp2_from_hex(s, hex_fp2_sqr); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_sqr_u(r, x); sm9_fp2_from_hex(s, hex_fp2_sqr_u); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_inv(r, x); sm9_fp2_from_hex(s, hex_fp2_inv); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_div(r, x, y); sm9_fp2_from_hex(s, hex_fp2_div); if (!sm9_fp2_equ(r, s)) goto err; ++j; + sm9_fp2_div2(r, x); sm9_fp2_from_hex(s, hex_fp2_div2); if (!sm9_fp2_equ(r, s)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_iv4 \ + "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321\n" \ + "a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c\n" \ + "123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321\n" \ + "a39654024e243d806e492768664a2b72d632457dd14f49a9f1fdd299c9bb073c" +#define hex_fp4_mul \ + "11d8f3dc2c4a7cd3ff4d557d86871210cff65187190711430b2d898affd61cda\n" \ + "960ee85c0aaacd6cc805053293a4955245ba973c9972b6767d0c68450a905ee7\n" \ + "ac9891b21d82827f6ccc2cd8524179b833239019c0b66cad89d7d8735ee03782\n" \ + "8f456b1cee442d189d01fc42fff7fd8481173dae8dc547d85c01a843005a063e" +#define hex_fp4_mul_fp \ + "413b76fe8748ab9130dc2907a55c15da925b496395c2cd82d6311863a4d9cfa8\n" \ + "5cc754d5318f3ed489db7e53f94f3878a527053693983f4d4a61b30f6ea74984\n" \ + "6769891769934201aa8d6de63cc012ec2b722d7b0ad9c9039246a3eea6f3d479\n" \ + "408d33e58a4d3bfaf1d84a7ddad4e4026ca41f2aaa179611d9894584baed89d0" +#define hex_fp4_mul_fp2 \ + "242956015bdff53db568b970d64a7de56a0506309e1309b283317134dd52d53e\n" \ + "5333c472d44677df131eeb1180badb3e1e9f88ba58190d16a92d95f939efb2c3\n" \ + "0ccdaa76a6876ff69de6792161b614ca720bfcee2d5521533fbb28179ec0e31e\n" \ + "2a2d6b832e919c313920f2e13e822795e2ceda8c0d8f4abe78220e4e00aeb6fd" +#define hex_fp4_mul_v \ + "ac9891b21d82827f6ccc2cd8524179b833239019c0b66cad89d7d8735ee03782\n" \ + "8f456b1cee442d189d01fc42fff7fd8481173dae8dc547d85c01a843005a063e\n" \ + "960ee85c0aaacd6cc805053293a4955245ba973c9972b6767d0c68450a905ee7\n" \ + "928e1847aa0ead49d7690054e880a3238205f03ce86ccc55cf148811e3a50bc9" +#define hex_fp4_sqr \ + "8d3bc7848d4ad61017a7cb4efc280103bfe558e240c46c5765f1a4e2ec2e8c54\n" \ + "2f0f2ef9dd3979c7018b67837ba6e73938ba88ae66a101aaa0cf27ee449835ec\n" \ + "93838cbf9e5be34562c5bc031e27357d206f783837a6a921cbf4829292b69441\n" \ + "3681ecc58b68ffc15af31c5b1f1e10e1f3c60bdabb329c0dc7ffb2cc3925f005" +#define hex_fp4_sqr_v \ + "93838cbf9e5be34562c5bc031e27357d206f783837a6a921cbf4829292b69441\n" \ + "3681ecc58b68ffc15af31c5b1f1e10e1f3c60bdabb329c0dc7ffb2cc3925f005\n" \ + "2f0f2ef9dd3979c7018b67837ba6e73938ba88ae66a101aaa0cf27ee449835ec\n" \ + "520870f6eab1a1c37cb7c001f2cd8c82c41a74d1b36d0508fefbec89ee457252" +#define hex_fp4_inv \ + "1ec69309f84c5ad450750826fc804b72fb89fb48474222ba05be08bb1765f1d6\n" \ + "3f16de331f77f510a3ec06e79319e3be5b3777471f79cd53404652b485133e99\n" \ + "1cbf7f3bb04e2389184eade12de2752711cbff452363d2dfaf2bfef40618cebc\n" \ + "3a70e829b83dc311970bc8d3e3e652f88a1ecd49b4672aa18c1c613c9a97d86f" + +int test_sm9_fp4() { + sm9_fp4_t x; + sm9_fp4_t y; + sm9_fp4_t r; + sm9_fp4_t s; + sm9_fp2_t q; + sm9_fp_t k; + int j = 1; + + sm9_fp2_from_hex(x[0], hex_fp2_mul_fp); + sm9_fp2_from_hex(x[1], hex_fp2_sqr); + sm9_fp2_from_hex(y[0], hex_fp2_add); + sm9_fp2_from_hex(y[1], hex_fp2_tri); + sm9_bn_from_hex(k, hex_iv); + sm9_fp2_copy(q, SM9_Ppubs->X); + + sm9_fp4_t iv4 = {{{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, + {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}, + {{0xc9bb073c, 0xf1fdd299, 0xd14f49a9, 0xd632457d, 0x664a2b72, 0x6e492768, 0x4e243d80, 0xa3965402}, + {0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678, 0x87654321, 0x0fedcba9, 0x9abcdef0, 0x12345678}}}; + sm9_fp4_from_hex(r, hex_iv4); if (!sm9_fp4_equ(r, iv4)) goto err; ++j; + + sm9_fp4_mul(r, x, y); sm9_fp4_from_hex(s, hex_fp4_mul); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_mul_fp(r, x, k); sm9_fp4_from_hex(s, hex_fp4_mul_fp); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_mul_fp2(r, x, q); sm9_fp4_from_hex(s, hex_fp4_mul_fp2); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_mul_v(r, x, y); sm9_fp4_from_hex(s, hex_fp4_mul_v); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_sqr(r, x); sm9_fp4_from_hex(s, hex_fp4_sqr); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_sqr_v(r, x); sm9_fp4_from_hex(s, hex_fp4_sqr_v); if (!sm9_fp4_equ(r, s)) goto err; ++j; + sm9_fp4_inv(r, x); sm9_fp4_from_hex(s, hex_fp4_inv); if (!sm9_fp4_equ(r, s)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_fp12_mul \ + "058d43459faee14ba2b6a69ff2d8c3ad933a1253e1764dedf5419b144a2ab82b\n" \ + "20ef84805ba02ef92a48fb2ae8086e566a644ab0639249f175268f18d8091ad4\n" \ + "83cc3be54a699ae24d8f920c87baa395befb424a6dcad1dcdfc2a006765ef8d5\n" \ + "1d705169165d9c2386c3bc673df3fa84975afa955a7be27f1b362000a96b8c2c\n" \ + "22b910d826f02961ff0fed439beb1e91f45193f87c2cdd9562da539290846ace\n" \ + "2c618991ae82d35063cfed629ff7d930b8070ba07d0652ba092f046e133e3491\n" \ + "137bc78a9aa182330bd71fb8859314422dd36f5e3c1f6fd36d6c9685fc39419f\n" \ + "8d83e7380abe10a2f3677864c2dbbcdad7ae5434e92043a2da3b71f3f9cedd8c\n" \ + "850c0562ac08996c05d22ea466cf4b1fa7a7064d4653b5fa725d623254bf7125\n" \ + "6dc41016b3ab9b44a4841aa8037e3b4d331cc7c8313abee0c5111a9be5915e90\n" \ + "6d1a15e5b765c4b139bf5c6c4a87214c269b26fb709ff5de885c053f405cf626\n" \ + "8d4d853489a4a5d809fa77e35627a5351651b926f001e1ee46e95808f9001d24" +#define hex_fp12_sqr \ + "3592cba3482fb39756b2ed1d3d756685caa005bd5e8288bc92841d29276aa321\n" \ + "8e3a49919e6de83b1ab1a5bb9eb993c3bbd68e8d305aed5c0b88cef0ef41c47f\n" \ + "3d3d9cc8e07619efd21745f6938a26f7cb0a83ad4aa3a9d066e18ad99833e3ac\n" \ + "25195ec7af551c42d7d37a0b120607d4adba6b9377299688b92a8393f3b8c20f\n" \ + "76f676d5d2cb8d1a2cc237fc78c8d544bef1cd560e654236f502aed0d8c9148c\n" \ + "6cde174a5e9d117175a4a163f041b65f868dffa05b5f3474f729b87f92493f2c\n" \ + "667a86d73e8f88a81306f7f0cd28789a55bf7e9cbe155fc6abb300ad027d8801\n" \ + "a49a66d48ec2ef72a9929413a40e316a8aee1d6236a1db8c56496524f1c23f11\n" \ + "1684bc9679aaba4afe35ec8c0852e438f41e15ab37620d9661018f90fe7415f1\n" \ + "8d37fb8b7edf942885b3009cf7e295bea89444d34091fc57380c778395b7c4e4\n" \ + "278b9d9ea61b6b2758e758ed9a64034576b520e65a9d276a0c82f079501a226e\n" \ + "01a333fa4177601de7cd8ed49ea4906f30e23988dcb7cde173da48499fce3ee5" +#define hex_fp12_inv \ + "47ae900b90945e31afde7fe09f0b69640c468a1648ee52070584a5d13af22bb9\n" \ + "8f273655182c3a9f184dc30421161ecdd50655c36a9266c7df1016e410f34102\n" \ + "a26e789013203804b5f8f1c5a51dd3fb50176d41108b235d6e66712721060252\n" \ + "090aaed5cb83068a0376c6eaca210007744d00c8b4ce53279a67cc069cc519e7\n" \ + "80ab89aa446df59ffe2f29cdb917b760d740ceb634c731b93bf1661aa5868b54\n" \ + "1e13ab51b3198619cc0016599562ed4d266d1481d0d273d3f97cffe5f8e0dd21\n" \ + "5aeb8ed89aafc971a857b8d02f3e3c37ef15ba0e3220e3a7c13c9da8af0c393b\n" \ + "518c338b1430e3129c2555650e5d5634d89513f694ba3a5f2aeb444c540f125a\n" \ + "aba8c5682695f3feee64772d0e49b432c96470e7d663098e9c271a91d4fc991a\n" \ + "0ed800dabe29af5fb41a41cc49fd4084deb02442e8e66f88186607f46395e533\n" \ + "a31b642cd5453c7bb16c82bc67bd3b66fa4db58b8e9aa45f9b579860f18d402c\n" \ + "798b84002e95753e3b07027a8d68b0a7ab2ac40328fc7ca3ea40780b3428dbc1" +#define hex_fp12_pow \ + "43291d68970ec9c00ed4616b8fa4b2b332c15a6e4ed833a4b1d68db20a06896c\n" \ + "48f861508cb878a1f1f806a486f3aa6889571bd5fb1010d73933550d219afd14\n" \ + "34b20766a4cc466efe1ee0d48206d683890494aec331d5b345e9a9adb5c5845a\n" \ + "0e3edea737b3db1083b776eb48e7bfaa4256a8d37d7ab13a370d7682daaf794d\n" \ + "9808adfd960da7837736fca5acb13a84d56962a21af424e48c0aa52c77dfd157\n" \ + "a8aa94ea4f3026eed8fa99ab9a793468db12bb7256c50570e72e375f981861a1\n" \ + "3fd308b4cdcec640fa4f17aac455b2f3daed3fb86a850b47c301c3941dbd6c4c\n" \ + "11b99f09fa20368e840c3d76e706939e4a3e8367165bb802de43acc83ae622d5\n" \ + "a5e97a50168650cae7b02b4c2511eeb194cd5ea5ff02a0284abd5961b46d47e4\n" \ + "b52a91d96353ef501bdbe6424ea26414faeeb930b9e618c2882a85d1fdeea3d0\n" \ + "6c78632b7dbbbdbf347a3f5fd6935a9f9b425125b7ac106e3586a7fbee3f2f20\n" \ + "6b35df1d1153684f1363fce020088a797802e18959df4f006bc5d7f4a632e9f9" + +int test_sm9_fp12() { + sm9_fp12_t x; + sm9_fp12_t y; + sm9_fp12_t r; + sm9_fp12_t s; + sm9_bn_t k; + int j = 1; + + sm9_fp4_from_hex(x[0], hex_fp4_mul); + sm9_fp4_from_hex(x[1], hex_fp4_mul_fp); + sm9_fp4_from_hex(x[2], hex_fp4_mul_fp2); + sm9_fp4_from_hex(y[0], hex_fp4_mul_v); + sm9_fp4_from_hex(y[1], hex_fp4_sqr); + sm9_fp4_from_hex(y[2], hex_fp4_inv); + sm9_bn_from_hex(k, hex_iv); + + sm9_fp12_mul(r, x, y); sm9_fp12_from_hex(s, hex_fp12_mul); if (!sm9_fp12_equ(r, s)) goto err; ++j; + sm9_fp12_sqr(r, x); sm9_fp12_from_hex(s, hex_fp12_sqr); if (!sm9_fp12_equ(r, s)) goto err; ++j; + sm9_fp12_inv(r, x); sm9_fp12_from_hex(s, hex_fp12_inv); if (!sm9_fp12_equ(r, s)) goto err; ++j; + sm9_fp12_pow(r, x, k); sm9_fp12_from_hex(s, hex_fp12_pow); if (!sm9_fp12_equ(r, s)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_point1 "917be49d159184fba140f4dfc5d653464e94f718fe195b226b3f715829e6e768-288578d9505d462867a50acee40ee143b896e72505be10e8ce4c6b0c945b642b" +#define hex_point2 "593417680f252445fd0522383e23c77a54b11fe222de4a886eabc26e16bffa3c-38e8fc9a8b60f5ba0c6c411f721c117044435a833757d8fee65828511b8b245d" +#define hex_point_dbl "268def7968f1e8c51635e277425403df88355fb2ecf16f7920f112eb2a7e50c9-5c596b534bbaa85c1d3aecf436e61ff1bfd9f70856f0309c2a63d8248205d84e" +#define hex_point_add "056610cb69f8d5659ea94e4a67bbf3b93fb0bd449672d7ca2525ec3b68c894d1-88f3f99ce78ed3ffe6ca1cface5242570cb5d053f16a8e0baae10414babd86a7" +#define hex_point_neg "917be49d159184fba140f4dfc5d653464e94f718fe195b226b3f715829e6e768-8dba8726b24660c96e5ea081117fe601695bac2614bcddf31723301b4ef5e152" +#define hex_point_sub "29e4a54cad98da9939b95f677784bff3b1dd9334c83d93e351e0f8f7c4ce2dc5-4473eba3b8ff990b8456c41ec0727b76cb2b0f960495b144949f70bf95643b82" +#define hex_point_mul "997fcff625adbae62566f684f9e89181713f972c5a9cd9ce6764636761ba87d1-8142a28d1bd109501452a649e2d68f012e265460e0c7d3da743fb036eb23b03b" +#define hex_point_mul_g "7cf689748f3714490d7a19eae0e7bfad0e0182498b7bcd8a6998dfd00f59be51-4e2e98d190e9d775e0caa943196bfb066d9c30818b2d768fb5299e7135830a6f" + +int test_sm9_point() { + SM9_POINT p; + SM9_POINT q; + SM9_POINT r; + SM9_POINT s; + sm9_bn_t k; + int j = 1; + uint8_t buf[65]; + + sm9_bn_from_hex(k, hex_iv); + + sm9_point_from_hex(&p, hex_point1); if (!sm9_point_is_on_curve(&p)) goto err; ++j; + sm9_point_from_hex(&q, hex_point2); if (!sm9_point_is_on_curve(&q)) goto err; ++j; + sm9_point_dbl(&r, &p); sm9_point_from_hex(&s, hex_point_dbl); if (!sm9_point_equ(&r, &s)) goto err; ++j; + sm9_point_add(&r, &p, &q); sm9_point_from_hex(&s, hex_point_add); if (!sm9_point_equ(&r, &s)) goto err; ++j; + sm9_point_neg(&r, &p); sm9_point_from_hex(&s, hex_point_neg); if (!sm9_point_equ(&r, &s)) goto err; ++j; + sm9_point_sub(&r, &p, &q); sm9_point_from_hex(&s, hex_point_sub); if (!sm9_point_equ(&r, &s)) goto err; ++j; + sm9_point_mul(&r, k, &p); sm9_point_from_hex(&s, hex_point_mul); if (!sm9_point_equ(&r, &s)) goto err; ++j; + sm9_point_mul_generator(&r, k); sm9_point_from_hex(&s, hex_point_mul_g); if (!sm9_point_equ(&r, &s)) goto err; ++j; + + sm9_point_to_uncompressed_octets(&p, buf); + sm9_point_from_uncompressed_octets(&q, buf); + if (!sm9_point_equ(&p, &q)) { + error_print(); + return -1; + } + + + + + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_tpoint1 \ + "83f6a65d85d51ec72eacf19bc38384e0369eb22a134a725a0191faa6e4f192ef\n" \ + "9a79bfd491ef1cb32d9b57f7d0590ccff6b1cfe63dd15c0823d692fafbe96dbc\n" \ + "9ed11c499291db0454d738555af0ce8a1df960056ee7425a6bf296eae60a5037\n" \ + "849d4434eb7113fc9fb3809b51d54064fa2f20503423d256bc044905b1eba3fb" +#define hex_tpoint2 \ + "a36232a9713f69157b7cdceef54aa0237b3ba0642a80dbb597af8935aea2c130\n" \ + "624b19114e49f00281e2aee1f1b9d4f0a081a135868f8bbdb7b7a7b7da5fd6bc\n" \ + "77966917ec1c5a294dd836c34691ab5e891f8c9f017443902c0a73ec54d449d8\n" \ + "1be45454b6fa085a53744b22fd398238e400c3e031c8796e59e1bd6222048af0" +#define hex_tpoint_neg \ + "83f6a65d85d51ec72eacf19bc38384e0369eb22a134a725a0191faa6e4f192ef\n" \ + "9a79bfd491ef1cb32d9b57f7d0590ccff6b1cfe63dd15c0823d692fafbe96dbc\n" \ + "176ee3b67011cbed812c72fa9a9df8bb03f93345ab93ac81797d043cfd46f546\n" \ + "31a2bbcb173292f536502ab4a3b986e027c372fae6571c85296b52223165a182" +#define hex_tpoint_dbl \ + "73cbced58a8e76ef5235b480050a74e906e4d27185bd85d7ebdcd43ad24475fd\n" \ + "58400f0eb23000d814f5b5d0706749a72909795b7b04f26d6d58b2cf478ad9c9\n" \ + "19b460e09ac9ddbb380d6441e078a47bfcaa7d4c3d60b3a6c0d05f896472dc3c\n" \ + "1d69f785f47d6f25cb901b131612c37edc5e89ee9ba2dac8c401ced40e340a39" +#define hex_tpoint_add \ + "5f443752a19e368f404b89abae20a386d2b534c424b93ededdbfd04d4c569e6b\n" \ + "a411bbd84ee92a6ee53e5ca9cb81bacc192c6ba406f6fdcb2b04d0ab9c42ae44\n" \ + "6a3dadfcaac134e8353dd3abf37d487b206ca28dfab1e0a9376649df748f1605\n" \ + "4fa25e5e6100a023d4923df385dd236749c6a7f8e68db55e0bd1e2263fc04d28" +#define hex_tpoint_sub \ + "3cbbf5fcc6c11a3579036e617bbf0b2861c53979f01e37f59fc4a10d991ccde7\n" \ + "1e9c3c99524c7867c9dbc4f52fdc938cf5aa4a980d3905cc91a5b91331235290\n" \ + "44027c5d814bab73ad93d14b564303aab153ad7355bcfbf8a8bed7cb577e7fd8\n" \ + "47a4037d1d6f6d2014aa04292fa91cf07b1f4331a85d4b66a6e048226ddfc43e" +#define hex_tpoint_mul \ + "5d704de3261290dbba39dbd14e6bc416025240fd1ed65ec982efed685ae41e8b\n" \ + "705c9ca4b5ef465c4e5db80ca4880627a6d9d6bcefd4756496baba9d5eaa3304\n" \ + "4e96eb3543aabf1e9a65cae24177b9d13b0f7fae9472145ba7ae2b14bb447aef\n" \ + "5d7ba50d7eac49a00b18fee2069afd3cc9719993fa78271e66b7a3efed46ac8b" +#define hex_tpoint_mulg \ + "920ef6fb3a2acff52aa0c004c18feca149dfd33d98086f8f402ea9e0de303c49\n" \ + "1f97dd359f2b065d63e0987f5bea2f3dc865c2cc112d7d161b46b83451716fd8\n" \ + "614881d4d05fef3173a4990465876c5200f58c5015e13354b23ae401c20c4aef\n" \ + "18a22e02b7d395a49f0646a79438e79cd37c32f163fe8923c13d56bab668e8a7" + +int test_sm9_twist_point() { + SM9_TWIST_POINT p; + SM9_TWIST_POINT q; + SM9_TWIST_POINT r; + SM9_TWIST_POINT s; + sm9_bn_t k; + int j = 1; + + sm9_bn_from_hex(k, hex_iv); + + sm9_twist_point_from_hex(&p, hex_tpoint1); if (!sm9_twist_point_is_on_curve(&p)) goto err; ++j; + sm9_twist_point_from_hex(&q, hex_tpoint2); if (!sm9_twist_point_is_on_curve(&q)) goto err; ++j; + sm9_twist_point_neg(&r, &p); sm9_twist_point_from_hex(&s, hex_tpoint_neg); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_dbl(&r, &p); sm9_twist_point_from_hex(&s, hex_tpoint_dbl); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_add(&r, &p, &q); sm9_twist_point_from_hex(&s, hex_tpoint_add); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_add_full(&r, &p, &q); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_sub(&r, &p, &q); sm9_twist_point_from_hex(&s, hex_tpoint_sub); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_mul(&r, k, &p); sm9_twist_point_from_hex(&s, hex_tpoint_mul); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + sm9_twist_point_mul_generator(&r, k); sm9_twist_point_from_hex(&s, hex_tpoint_mulg); if (!sm9_twist_point_equ(&r, &s)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_pairing1 \ + "4e378fb5561cd0668f906b731ac58fee25738edf09cadc7a29c0abc0177aea6d\n" \ + "28b3404a61908f5d6198815c99af1990c8af38655930058c28c21bb539ce0000\n" \ + "38bffe40a22d529a0c66124b2c308dac9229912656f62b4facfced408e02380f\n" \ + "a01f2c8bee81769609462c69c96aa923fd863e209d3ce26dd889b55e2e3873db\n" \ + "67e0e0c2eed7a6993dce28fe9aa2ef56834307860839677f96685f2b44d0911f\n" \ + "5a1ae172102efd95df7338dbc577c66d8d6c15e0a0158c7507228efb078f42a6\n" \ + "1604a3fcfa9783e667ce9fcb1062c2a5c6685c316dda62de0548baa6ba30038b\n" \ + "93634f44fa13af76169f3cc8fbea880adaff8475d5fd28a75deb83c44362b439\n" \ + "b3129a75d31d17194675a1bc56947920898fbf390a5bf5d931ce6cbb3340f66d\n" \ + "4c744e69c4a2e1c8ed72f796d151a17ce2325b943260fc460b9f73cb57c9014b\n" \ + "84b87422330d7936eaba1109fa5a7a7181ee16f2438b0aeb2f38fd5f7554e57a\n" \ + "aab9f06a4eeba4323a7833db202e4e35639d93fa3305af73f0f071d7d284fcfb" + +#define hex_RA \ + "7CBA5B19069EE66AA79D490413D11846B9BA76DD22567F809CF23B6D964BB265\n" \ + "A9760C99CB6F706343FED05637085864958D6C90902ABA7D405FBEDF7B781599" +#define hex_deB \ + "74CCC3AC9C383C60AF083972B96D05C75F12C8907D128A17ADAFBAB8C5A4ACF7\n" \ + "01092FF4DE89362670C21711B6DBE52DCD5F8E40C6654B3DECE573C2AB3D29B2\n" \ + "44B0294AA04290E1524FF3E3DA8CFD432BB64DE3A8040B5B88D1B5FC86A4EBC1\n" \ + "8CFC48FB4FF37F1E27727464F3C34E2153861AD08E972D1625FC1A7BD18D5539" + +#define hex_pairing2 \ + "28542FB6954C84BE6A5F2988A31CB6817BA0781966FA83D9673A9577D3C0C134\n" \ + "5E27C19FC02ED9AE37F5BB7BE9C03C2B87DE027539CCF03E6B7D36DE4AB45CD1\n" \ + "A1ABFCD30C57DB0F1A838E3A8F2BF823479C978BD137230506EA6249C891049E\n" \ + "3497477913AB89F5E2960F382B1B5C8EE09DE0FA498BA95C4409D630D343DA40\n" \ + "4FEC93472DA33A4DB6599095C0CF895E3A7B993EE5E4EBE3B9AB7D7D5FF2A3D1\n" \ + "647BA154C3E8E185DFC33657C1F128D480F3F7E3F16801208029E19434C733BB\n" \ + "73F21693C66FC23724DB26380C526223C705DAF6BA18B763A68623C86A632B05\n" \ + "0F63A071A6D62EA45B59A1942DFF5335D1A232C9C5664FAD5D6AF54C11418B0D\n" \ + "8C8E9D8D905780D50E779067F2C4B1C8F83A8B59D735BB52AF35F56730BDE5AC\n" \ + "861CCD9978617267CE4AD9789F77739E62F2E57B48C2FF26D2E90A79A1D86B93\n" \ + "9B1CA08F64712E33AEDA3F44BD6CB633E0F722211E344D73EC9BBEBC92142765\n" \ + "6BA584CE742A2A3AB41C15D3EF94EDEB8EF74A2BDCDAAECC09ABA567981F6437" + + +#define hex_Ppube \ + "9174542668E8F14AB273C0945C3690C66E5DD09678B86F734C4350567ED06283\n" \ + "54E598C6BF749A3DACC9FFFEDD9DB6866C50457CFC7AA2A4AD65C3168FF74210" +#define rB "00018B98C44BEF9F8537FB7D071B2C928B3BC65BD3D69E1EEE213564905634FE" +#define hex_pairing3 \ + "1052D6E9D13E381909DFF7B2B41E13C987D0A9068423B769480DACCE6A06F492\n" \ + "5FFEB92AD870F97DC0893114DA22A44DBC9E7A8B6CA31A0CF0467265A1FB48C7\n" \ + "2C5C3B37E4F2FF83DB33D98C0317BCBBBBF4AC6DF6B89ECA58268B280045E612\n" \ + "6CED9E2D7C9CD3D5AD630DEFAB0B831506218037EE0F861CF9B43C78434AEC38\n" \ + "0AE7BF3E1AEC0CB67A03440906C7DFB3BCD4B6EEEBB7E371F0094AD4A816088D\n" \ + "98DBC791D0671CACA12236CDF8F39E15AEB96FAEB39606D5B04AC581746A663D\n" \ + "00DD2B7416BAA91172E89D5309D834F78C1E31B4483BB97185931BAD7BE1B9B5\n" \ + "7EBAC0349F8544469E60C32F6075FB0468A68147FF013537DF792FFCE024F857\n" \ + "10CC2B561A62B62DA36AEFD60850714F49170FD94A0010C6D4B651B64F3A3A5E\n" \ + "58C9687BEDDCD9E4FEDAB16B884D1FE6DFA117B2AB821F74E0BF7ACDA2269859\n" \ + "2A430968F16086061904CE201847934B11CA0F9E9528F5A9D0CE8F015C9AEA79\n" \ + "934FDDA6D3AB48C8571CE2354B79742AA498CB8CDDE6BD1FA5946345A1A652F6" + + +int test_sm9_pairing() { + SM9_TWIST_POINT p; + SM9_POINT q; + sm9_fp12_t r; + sm9_fp12_t s; + sm9_bn_t k; + int j = 1; + + sm9_pairing(r, SM9_Ppubs, SM9_P1); sm9_fp12_from_hex(s, hex_pairing1); if (!sm9_fp12_equ(r, s)) goto err; ++j; + + sm9_twist_point_from_hex(&p, hex_deB); sm9_point_from_hex(&q, hex_RA); + sm9_pairing(r, &p, &q); sm9_fp12_from_hex(s, hex_pairing2); if (!sm9_fp12_equ(r, s)) goto err; ++j; + + sm9_bn_from_hex(k, rB); sm9_point_from_hex(&q, hex_Ppube); + sm9_pairing(r, SM9_P2, &q); sm9_fp12_pow(r, r, k); sm9_fp12_from_hex(s, hex_pairing3); if (!sm9_fp12_equ(r, s)) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_ks "000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4" +#define hex_ds "A5702F05CF1315305E2D6EB64B0DEB923DB1A0BCF0CAFF90523AC8754AA69820-78559A844411F9825C109F5EE3F52D720DD01785392A727BB1556952B2B013D3" + +int test_sm9_sign() { + SM9_SIGN_CTX ctx; + SM9_SIGN_KEY key; + SM9_SIGN_MASTER_KEY mpk; + SM9_POINT ds; + uint8_t sig[1000] = {0}; + size_t siglen = 0; + int j = 1; + + uint8_t data[20] = {0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64}; + uint8_t IDA[5] = {0x41, 0x6C, 0x69, 0x63, 0x65}; + + sm9_bn_from_hex(mpk.ks, hex_ks); sm9_twist_point_mul_generator(&(mpk.Ppubs), mpk.ks); + if (sm9_sign_master_key_extract_key(&mpk, (char *)IDA, sizeof(IDA), &key) < 0) goto err; ++j; + sm9_point_from_hex(&ds, hex_ds); if (!sm9_point_equ(&(key.ds), &ds)) goto err; ++j; + + sm9_sign_init(&ctx); + sm9_sign_update(&ctx, data, sizeof(data)); + if (sm9_sign_finish(&ctx, &key, sig, &siglen) < 0) goto err; ++j; + + sm9_verify_init(&ctx); + sm9_verify_update(&ctx, data, sizeof(data)); + if (sm9_verify_finish(&ctx, sig, siglen, &mpk, (char *)IDA, sizeof(IDA)) != 1) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +#define hex_ke "0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22" + +#define hex_de \ + "94736ACD2C8C8796CC4785E938301A139A059D3537B6414140B2D31EECF41683\n" \ + "115BAE85F5D8BC6C3DBD9E5342979ACCCF3C2F4F28420B1CB4F8C0B59A19B158\n" \ + "7AA5E47570DA7600CD760A0CF7BEAF71C447F3844753FE74FA7BA92CA7D3B55F\n" \ + "27538A62E7F7BFB51DCE08704796D94C9D56734F119EA44732B50E31CDEB75C1" + +int test_sm9_ciphertext() +{ + SM9_POINT C1; + uint8_t c2[SM9_MAX_PLAINTEXT_SIZE]; + uint8_t c3[SM3_HMAC_SIZE]; + uint8_t buf[1024]; + uint8_t *p = buf; + size_t len = 0; + + sm9_point_copy(&C1, SM9_P1); + if (sm9_ciphertext_to_der(&C1, c2, sizeof(c2), c3, &p, &len) != 1) { + error_print(); + return -1; + } + //printf("SM9_MAX_CIPHERTEXT_SIZE %zu\n", len); + return 1; +} + + +int test_sm9_encrypt() { + SM9_ENC_MASTER_KEY msk; + SM9_ENC_KEY key; + SM9_TWIST_POINT de; + uint8_t out[1000] = {0}; + size_t outlen = 0; + int j = 1; + + uint8_t data[20] = {0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64}; + uint8_t dec[20] = {0}; + size_t declen = 20; + uint8_t IDB[3] = {0x42, 0x6F, 0x62}; + + sm9_bn_from_hex(msk.ke, hex_ke); sm9_point_mul_generator(&(msk.Ppube), msk.ke); + if (sm9_enc_master_key_extract_key(&msk, (char *)IDB, sizeof(IDB), &key) < 0) goto err; ++j; + sm9_twist_point_from_hex(&de, hex_de); if (!sm9_twist_point_equ(&(key.de), &de)) goto err; ++j; + + if (sm9_encrypt(&msk, (char *)IDB, sizeof(IDB), data, sizeof(data), out, &outlen) < 0) goto err; ++j; + if (sm9_decrypt(&key, (char *)IDB, sizeof(IDB), out, outlen, dec, &declen) < 0) goto err; ++j; + if (memcmp(data, dec, sizeof(data)) != 0) goto err; ++j; + + printf("%s() ok\n", __FUNCTION__); + return 1; +err: + printf("%s test %d failed\n", __FUNCTION__, j); + error_print(); + return -1; +} + +int main(void) { + if (test_sm9_fp() != 1) goto err; + if (test_sm9_fn() != 1) goto err; + if (test_sm9_fp2() != 1) goto err; + if (test_sm9_fp4() != 1) goto err; + if (test_sm9_fp12() != 1) goto err; + if (test_sm9_point() != 1) goto err; + if (test_sm9_twist_point() != 1) goto err; + if (test_sm9_pairing() != 1) goto err; + if (test_sm9_sign() != 1) goto err; + if (test_sm9_ciphertext() != 1) goto err; + if (test_sm9_encrypt() != 1) goto err; + + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/tls13test.c b/tests/tls13test.c index 6ca4a374..98a999d9 100644 --- a/tests/tls13test.c +++ b/tests/tls13test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,75 +7,76 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_tls13_gcm(void) -{ - - BLOCK_CIPHER_KEY block_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t seq_num[8] = {0,0,0,0,0,0,0,1}; - int record_type = TLS_record_handshake; - uint8_t in[40]; - size_t padding_len = 8; - uint8_t out[256]; - size_t outlen; - uint8_t buf[256]; - size_t buflen; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - rand_bytes(in, sizeof(in)); - - memset(out, 1, sizeof(out)); - outlen = 0; - memset(buf, 1, sizeof(buf)); - buflen = 0; - - if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { - error_print(); - return -1; - } - - if (tls13_gcm_encrypt(&block_key, iv, seq_num, record_type, in, sizeof(in), padding_len, out, &outlen) != 1) { - error_print(); - return -1; - } - if (tls13_gcm_decrypt(&block_key, iv, seq_num, out, outlen, &record_type, buf, &buflen) != 1) { - error_print(); - return -1; - } - - if (buflen != sizeof(in)) { - error_print(); - return -1; - } - if (memcmp(in, buf, buflen) != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_tls13_gcm() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_tls13_gcm(void) +{ + + BLOCK_CIPHER_KEY block_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t seq_num[8] = {0,0,0,0,0,0,0,1}; + int record_type = TLS_record_handshake; + uint8_t in[40]; + size_t padding_len = 8; + uint8_t out[256]; + size_t outlen; + uint8_t buf[256]; + size_t buflen; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(in, sizeof(in)); + + memset(out, 1, sizeof(out)); + outlen = 0; + memset(buf, 1, sizeof(buf)); + buflen = 0; + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { + error_print(); + return -1; + } + + if (tls13_gcm_encrypt(&block_key, iv, seq_num, record_type, in, sizeof(in), padding_len, out, &outlen) != 1) { + error_print(); + return -1; + } + if (tls13_gcm_decrypt(&block_key, iv, seq_num, out, outlen, &record_type, buf, &buflen) != 1) { + error_print(); + return -1; + } + + if (buflen != sizeof(in)) { + error_print(); + return -1; + } + if (memcmp(in, buf, buflen) != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_tls13_gcm() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/tlstest.c b/tests/tlstest.c index 402b3545..2c9bf08c 100644 --- a/tests/tlstest.c +++ b/tests/tlstest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,340 +7,341 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int test_tls_encode(void) -{ - uint8_t a1 = 200; - uint16_t a2 = 30000; - uint24_t a3 = 4000000; - uint32_t a4 = 4000000000; - uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8}; - - uint8_t r1; - uint16_t r2; - uint24_t r3; - uint32_t r4; - const uint8_t *pdata; - size_t datalen; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - tls_uint8_to_bytes(a1, &p, &len); - tls_uint16_to_bytes(a2, &p, &len); - tls_uint24_to_bytes(a3, &p, &len); - tls_uint32_to_bytes(a4, &p, &len); - tls_uint8array_to_bytes(data, 5, &p, &len); - tls_uint16array_to_bytes(data, 6, &p, &len); - tls_uint24array_to_bytes(data, 7, &p, &len); - - if (tls_uint8_from_bytes(&r1, &cp, &len) != 1 || r1 != a1 - || tls_uint16_from_bytes(&r2, &cp, &len) != 1 || r2 != a2 - || tls_uint24_from_bytes(&r3, &cp, &len) != 1 || r3 != a3 - || tls_uint32_from_bytes(&r4, &cp, &len) != 1 || r4 != a4 - || tls_uint8array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 5 || memcmp(pdata, data, 5) != 0 - || tls_uint16array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 6 || memcmp(pdata, data, 6) != 0 - || tls_uint24array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 7 || memcmp(pdata, data, 7) != 0 - || len > 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_cbc(void) -{ - uint8_t key[32] = {0}; - SM3_HMAC_CTX hmac_ctx; - SM4_KEY sm4_key; - uint8_t seq_num[8] = { 0,0,0,0,0,0,0,1 }; - uint8_t header[5]; - uint8_t in[] = "hello world"; - uint8_t out[256]; - uint8_t buf[256] = {0}; - size_t len; - size_t buflen; - - header[0] = TLS_record_handshake; - header[1] = TLS_protocol_tls12 >> 8; - header[2] = TLS_protocol_tls12 & 0xff; - header[3] = sizeof(in) >> 8; - header[4] = sizeof(in) & 0xff; - - sm3_hmac_init(&hmac_ctx, key, 32); - sm4_set_encrypt_key(&sm4_key, key); - tls_cbc_encrypt(&hmac_ctx, &sm4_key, seq_num, header, in, sizeof(in), out, &len); - - sm3_hmac_init(&hmac_ctx, key, 32); - sm4_set_decrypt_key(&sm4_key, key); - - tls_cbc_decrypt(&hmac_ctx, &sm4_key, seq_num, header, out, len, buf, &buflen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_random(void) -{ - uint8_t random[32]; - tls_random_generate(random); - tls_random_print(stdout, random, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_client_hello(void) -{ - uint8_t record[512]; - size_t recordlen = 0; - - int version = TLS_protocol_tlcp; - uint8_t random[32]; - int cipher_suites[] = { - TLS_cipher_ecc_sm4_cbc_sm3, - TLS_cipher_ecc_sm4_gcm_sm3, - TLS_cipher_ecdhe_sm4_cbc_sm3, - TLS_cipher_ecdhe_sm4_gcm_sm3, - TLS_cipher_ibsdh_sm4_cbc_sm3, - TLS_cipher_ibsdh_sm4_gcm_sm3, - TLS_cipher_ibc_sm4_cbc_sm3, - TLS_cipher_ibc_sm4_gcm_sm3, - TLS_cipher_rsa_sm4_cbc_sm3, - TLS_cipher_rsa_sm4_gcm_sm3, - TLS_cipher_rsa_sm4_cbc_sha256, - TLS_cipher_rsa_sm4_gcm_sha256, - }; - int comp_meths[] = {0}; - - tls_record_set_protocol(record, TLS_protocol_tlcp); - if (tls_record_set_handshake_client_hello(record, &recordlen, - version, - random, - NULL, 0, - cipher_suites, sizeof(cipher_suites)/sizeof(cipher_suites[0]), - NULL, 0) != 1) { - error_print(); - return -1; - } - tls_client_hello_print(stdout, record + 5 + 4, recordlen - 5 -4, 0, 4); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_server_hello(void) -{ - uint8_t record[512]; - size_t recordlen = 0; - - uint8_t random[32]; - uint16_t cipher_suite = TLS_cipher_ecdhe_sm4_cbc_sm3; - - - tls_record_set_protocol(record, TLS_protocol_tlcp); - if (tls_record_set_handshake_server_hello(record, &recordlen, - TLS_protocol_tlcp, - random, - NULL, 0, - cipher_suite, - NULL, 0) != 1) { - error_print(); - return -1; - } - tls_server_hello_print(stdout, record + 5 + 4, recordlen - 5 -4, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_certificate(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - FILE *fp = NULL; - - // 测试函数不要有外部的依赖 - // TODO: 输出一些握手过程的record字节数组和handshake字节数组,作为后续测试的测试数据 - - /* - if (!(fp = fopen("cacert.pem", "r"))) { - error_print(); - return -1; - } - if (tls_record_set_handshake_certificate_from_pem(record, &recordlen, fp) != 1) { - error_print(); - return -1; - } - tls_certificate_print(stdout, record + 9, recordlen - 9, 0, 0); - */ - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_server_key_exchange(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE] = {0xAA, 0xBB}; - const uint8_t *psig; - size_t siglen; - - tls_record_set_protocol(record, TLS_protocol_tlcp); - if (tlcp_record_set_handshake_server_key_exchange_pke(record, &recordlen, sig, sizeof(sig)) != 1) { - error_print(); - return -1; - } - if (tlcp_record_get_handshake_server_key_exchange_pke(record, &psig, &siglen) != 1) { - error_print(); - return -1; - } - format_bytes(stdout, 0, 0, "server_key_exchange siganture", psig, siglen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_certificate_verify(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - const uint8_t *psig; - size_t siglen; - - tls_record_set_protocol(record, TLS_protocol_tls12); - if (tls_record_set_handshake_certificate_verify(record, &recordlen, sig, sizeof(sig)) != 1) { - error_print(); - return -1; - } - if (tls_record_get_handshake_certificate_verify(record, &psig, &siglen) != 1) { - error_print(); - return -1; - } - tls_certificate_verify_print(stdout, psig, siglen, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_finished(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - uint8_t verify_data[12]; - const uint8_t *verify_data_ptr; - size_t verify_data_len; - - if (tls_record_set_handshake_finished(record, &recordlen, verify_data, sizeof(verify_data)) != 1) { - error_print(); - return -1; - } - if (tls_record_get_handshake_finished(record, &verify_data_ptr, &verify_data_len) != 1) { - error_print(); - return -1; - } - tls_finished_print(stdout, verify_data_ptr, verify_data_len, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_alert(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - int level; - int reason; - - if (tls_record_set_alert(record, &recordlen, TLS_alert_level_fatal, TLS_alert_close_notify) != 1) { - error_print(); - return -1; - } - if (tls_record_get_alert(record, &level, &reason) != 1) { - error_print(); - return -1; - } - tls_alert_print(stdout, record + 5, recordlen - 5, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_change_cipher_spec(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - - if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { - error_print(); - return -1; - } - if (tls_record_get_change_cipher_spec(record) != 1) { - error_print(); - return -1; - } - tls_change_cipher_spec_print(stdout, record + 5, recordlen - 5, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_tls_application_data(void) -{ - uint8_t record[1024]; - size_t recordlen = 0; - uint8_t data[88]; - const uint8_t *p; - size_t len; - - if (tls_record_set_application_data(record, &recordlen, data, sizeof(data)) != 1) { - error_print(); - return -1; - } - if (tls_record_get_application_data(record, &p, &len) != 1) { - error_print(); - return -1; - } - tls_application_data_print(stdout, p, len, 0, 0); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_tls_encode() != 1) goto err; - if (test_tls_cbc() != 1) goto err; - if (test_tls_random() != 1) goto err; - if (test_tls_client_hello() != 1) goto err; - if (test_tls_server_hello() != 1) goto err; - if (test_tls_certificate() != 1) goto err; - if (test_tls_server_key_exchange() != 1) goto err; - if (test_tls_certificate_verify() != 1) goto err; - if (test_tls_finished() != 1) goto err; - if (test_tls_alert() != 1) goto err; - if (test_tls_change_cipher_spec() != 1) goto err; - if (test_tls_application_data() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return -1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int test_tls_encode(void) +{ + uint8_t a1 = 200; + uint16_t a2 = 30000; + uint24_t a3 = 4000000; + uint32_t a4 = 4000000000; + uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8}; + + uint8_t r1; + uint16_t r2; + uint24_t r3; + uint32_t r4; + const uint8_t *pdata; + size_t datalen; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + tls_uint8_to_bytes(a1, &p, &len); + tls_uint16_to_bytes(a2, &p, &len); + tls_uint24_to_bytes(a3, &p, &len); + tls_uint32_to_bytes(a4, &p, &len); + tls_uint8array_to_bytes(data, 5, &p, &len); + tls_uint16array_to_bytes(data, 6, &p, &len); + tls_uint24array_to_bytes(data, 7, &p, &len); + + if (tls_uint8_from_bytes(&r1, &cp, &len) != 1 || r1 != a1 + || tls_uint16_from_bytes(&r2, &cp, &len) != 1 || r2 != a2 + || tls_uint24_from_bytes(&r3, &cp, &len) != 1 || r3 != a3 + || tls_uint32_from_bytes(&r4, &cp, &len) != 1 || r4 != a4 + || tls_uint8array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 5 || memcmp(pdata, data, 5) != 0 + || tls_uint16array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 6 || memcmp(pdata, data, 6) != 0 + || tls_uint24array_from_bytes(&pdata, &datalen, &cp, &len) != 1 || datalen != 7 || memcmp(pdata, data, 7) != 0 + || len > 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_cbc(void) +{ + uint8_t key[32] = {0}; + SM3_HMAC_CTX hmac_ctx; + SM4_KEY sm4_key; + uint8_t seq_num[8] = { 0,0,0,0,0,0,0,1 }; + uint8_t header[5]; + uint8_t in[] = "hello world"; + uint8_t out[256]; + uint8_t buf[256] = {0}; + size_t len; + size_t buflen; + + header[0] = TLS_record_handshake; + header[1] = TLS_protocol_tls12 >> 8; + header[2] = TLS_protocol_tls12 & 0xff; + header[3] = sizeof(in) >> 8; + header[4] = sizeof(in) & 0xff; + + sm3_hmac_init(&hmac_ctx, key, 32); + sm4_set_encrypt_key(&sm4_key, key); + tls_cbc_encrypt(&hmac_ctx, &sm4_key, seq_num, header, in, sizeof(in), out, &len); + + sm3_hmac_init(&hmac_ctx, key, 32); + sm4_set_decrypt_key(&sm4_key, key); + + tls_cbc_decrypt(&hmac_ctx, &sm4_key, seq_num, header, out, len, buf, &buflen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_random(void) +{ + uint8_t random[32]; + tls_random_generate(random); + tls_random_print(stdout, random, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_client_hello(void) +{ + uint8_t record[512]; + size_t recordlen = 0; + + int version = TLS_protocol_tlcp; + uint8_t random[32]; + int cipher_suites[] = { + TLS_cipher_ecc_sm4_cbc_sm3, + TLS_cipher_ecc_sm4_gcm_sm3, + TLS_cipher_ecdhe_sm4_cbc_sm3, + TLS_cipher_ecdhe_sm4_gcm_sm3, + TLS_cipher_ibsdh_sm4_cbc_sm3, + TLS_cipher_ibsdh_sm4_gcm_sm3, + TLS_cipher_ibc_sm4_cbc_sm3, + TLS_cipher_ibc_sm4_gcm_sm3, + TLS_cipher_rsa_sm4_cbc_sm3, + TLS_cipher_rsa_sm4_gcm_sm3, + TLS_cipher_rsa_sm4_cbc_sha256, + TLS_cipher_rsa_sm4_gcm_sha256, + }; + int comp_meths[] = {0}; + + tls_record_set_protocol(record, TLS_protocol_tlcp); + if (tls_record_set_handshake_client_hello(record, &recordlen, + version, + random, + NULL, 0, + cipher_suites, sizeof(cipher_suites)/sizeof(cipher_suites[0]), + NULL, 0) != 1) { + error_print(); + return -1; + } + tls_client_hello_print(stdout, record + 5 + 4, recordlen - 5 -4, 0, 4); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_server_hello(void) +{ + uint8_t record[512]; + size_t recordlen = 0; + + uint8_t random[32]; + uint16_t cipher_suite = TLS_cipher_ecdhe_sm4_cbc_sm3; + + + tls_record_set_protocol(record, TLS_protocol_tlcp); + if (tls_record_set_handshake_server_hello(record, &recordlen, + TLS_protocol_tlcp, + random, + NULL, 0, + cipher_suite, + NULL, 0) != 1) { + error_print(); + return -1; + } + tls_server_hello_print(stdout, record + 5 + 4, recordlen - 5 -4, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_certificate(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + FILE *fp = NULL; + + // 测试函数不要有外部的依赖 + // TODO: 输出一些握手过程的record字节数组和handshake字节数组,作为后续测试的测试数据 + + /* + if (!(fp = fopen("cacert.pem", "r"))) { + error_print(); + return -1; + } + if (tls_record_set_handshake_certificate_from_pem(record, &recordlen, fp) != 1) { + error_print(); + return -1; + } + tls_certificate_print(stdout, record + 9, recordlen - 9, 0, 0); + */ + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_server_key_exchange(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE] = {0xAA, 0xBB}; + const uint8_t *psig; + size_t siglen; + + tls_record_set_protocol(record, TLS_protocol_tlcp); + if (tlcp_record_set_handshake_server_key_exchange_pke(record, &recordlen, sig, sizeof(sig)) != 1) { + error_print(); + return -1; + } + if (tlcp_record_get_handshake_server_key_exchange_pke(record, &psig, &siglen) != 1) { + error_print(); + return -1; + } + format_bytes(stdout, 0, 0, "server_key_exchange siganture", psig, siglen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_certificate_verify(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + const uint8_t *psig; + size_t siglen; + + tls_record_set_protocol(record, TLS_protocol_tls12); + if (tls_record_set_handshake_certificate_verify(record, &recordlen, sig, sizeof(sig)) != 1) { + error_print(); + return -1; + } + if (tls_record_get_handshake_certificate_verify(record, &psig, &siglen) != 1) { + error_print(); + return -1; + } + tls_certificate_verify_print(stdout, psig, siglen, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_finished(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + uint8_t verify_data[12]; + const uint8_t *verify_data_ptr; + size_t verify_data_len; + + if (tls_record_set_handshake_finished(record, &recordlen, verify_data, sizeof(verify_data)) != 1) { + error_print(); + return -1; + } + if (tls_record_get_handshake_finished(record, &verify_data_ptr, &verify_data_len) != 1) { + error_print(); + return -1; + } + tls_finished_print(stdout, verify_data_ptr, verify_data_len, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_alert(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + int level; + int reason; + + if (tls_record_set_alert(record, &recordlen, TLS_alert_level_fatal, TLS_alert_close_notify) != 1) { + error_print(); + return -1; + } + if (tls_record_get_alert(record, &level, &reason) != 1) { + error_print(); + return -1; + } + tls_alert_print(stdout, record + 5, recordlen - 5, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_change_cipher_spec(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + + if (tls_record_set_change_cipher_spec(record, &recordlen) != 1) { + error_print(); + return -1; + } + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + return -1; + } + tls_change_cipher_spec_print(stdout, record + 5, recordlen - 5, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_application_data(void) +{ + uint8_t record[1024]; + size_t recordlen = 0; + uint8_t data[88]; + const uint8_t *p; + size_t len; + + if (tls_record_set_application_data(record, &recordlen, data, sizeof(data)) != 1) { + error_print(); + return -1; + } + if (tls_record_get_application_data(record, &p, &len) != 1) { + error_print(); + return -1; + } + tls_application_data_print(stdout, p, len, 0, 0); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_tls_encode() != 1) goto err; + if (test_tls_cbc() != 1) goto err; + if (test_tls_random() != 1) goto err; + if (test_tls_client_hello() != 1) goto err; + if (test_tls_server_hello() != 1) goto err; + if (test_tls_certificate() != 1) goto err; + if (test_tls_server_key_exchange() != 1) goto err; + if (test_tls_certificate_verify() != 1) goto err; + if (test_tls_finished() != 1) goto err; + if (test_tls_alert() != 1) goto err; + if (test_tls_change_cipher_spec() != 1) goto err; + if (test_tls_application_data() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tests/x509_algtest.c b/tests/x509_algtest.c index bb12cf0b..1b8466de 100644 --- a/tests/x509_algtest.c +++ b/tests/x509_algtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,192 +7,193 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_x509_digest_algor(void) -{ - char *names[] = { - "sm3", - "md5", - "sha1", - "sha224", - "sha256", - "sha384", - "sha512", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int oid; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_digest_algor_from_name(names[i]); - if (x509_digest_algor_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_digest_algor_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != x509_digest_algor_from_name(names[i])) { - error_print(); - return 1; - } - format_print(stderr, 0, 4, "%s\n", x509_digest_algor_name(oid)); - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_encryption_algor(void) -{ - char *names[] = { - "sm4-cbc", - "aes128-cbc", - "aes192-cbc", - "aes256-cbc", - }; - uint8_t iv[16] = {0}; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int oid; - const uint8_t *params; - size_t paramslen; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_encryption_algor_from_name(names[i]); - if (x509_encryption_algor_to_der(oid, iv, sizeof(iv), &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1 - || asn1_check(params != NULL) != 1 - || asn1_check(paramslen == sizeof(iv)) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_encryption_algor_name(oid)); - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_signature_algor(void) -{ - char *names[] = { - "sm2sign-with-sm3", - "rsasign-with-sm3", - "ecdsa-with-sha1", - "ecdsa-with-sha224", - "ecdsa-with-sha256", - "ecdsa-with-sha384", - "ecdsa-with-sha512", - "sha1WithRSAEncryption", - "sha224WithRSAEncryption", - "sha256WithRSAEncryption", - "sha384WithRSAEncryption", - "sha512WithRSAEncryption", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int oid; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_signature_algor_from_name(names[i]); - if (x509_signature_algor_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_signature_algor_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_signature_algor_name(oid)); - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_public_key_encryption_algor(void) -{ - char *names[] = { - "sm2encrypt", - // "rsaesOAEP", - // "rsaEncryption", - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int oid; - const uint8_t *params; - size_t paramslen; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_public_key_encryption_algor_from_name(names[i]); - if (x509_public_key_encryption_algor_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_public_key_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_public_key_encryption_algor_name(oid)); - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_x509_digest_algor() != 1) goto err; - if (test_x509_encryption_algor() != 1) goto err; - if (test_x509_signature_algor() != 1) goto err; - if (test_x509_public_key_encryption_algor() != 1) goto err; - printf("%s all tests passed!\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_digest_algor(void) +{ + char *names[] = { + "sm3", + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_digest_algor_from_name(names[i]); + if (x509_digest_algor_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_digest_algor_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_digest_algor_from_name(names[i])) { + error_print(); + return 1; + } + format_print(stderr, 0, 4, "%s\n", x509_digest_algor_name(oid)); + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_encryption_algor(void) +{ + char *names[] = { + "sm4-cbc", + "aes128-cbc", + "aes192-cbc", + "aes256-cbc", + }; + uint8_t iv[16] = {0}; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + const uint8_t *params; + size_t paramslen; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_encryption_algor_from_name(names[i]); + if (x509_encryption_algor_to_der(oid, iv, sizeof(iv), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1 + || asn1_check(params != NULL) != 1 + || asn1_check(paramslen == sizeof(iv)) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_encryption_algor_name(oid)); + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_signature_algor(void) +{ + char *names[] = { + "sm2sign-with-sm3", + "rsasign-with-sm3", + "ecdsa-with-sha1", + "ecdsa-with-sha224", + "ecdsa-with-sha256", + "ecdsa-with-sha384", + "ecdsa-with-sha512", + "sha1WithRSAEncryption", + "sha224WithRSAEncryption", + "sha256WithRSAEncryption", + "sha384WithRSAEncryption", + "sha512WithRSAEncryption", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_signature_algor_from_name(names[i]); + if (x509_signature_algor_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_signature_algor_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_signature_algor_name(oid)); + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_public_key_encryption_algor(void) +{ + char *names[] = { + "sm2encrypt", + // "rsaesOAEP", + // "rsaEncryption", + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + const uint8_t *params; + size_t paramslen; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_public_key_encryption_algor_from_name(names[i]); + if (x509_public_key_encryption_algor_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_public_key_encryption_algor_from_der(&oid, ¶ms, ¶mslen, &cp, &len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_public_key_encryption_algor_name(oid)); + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_x509_digest_algor() != 1) goto err; + if (test_x509_encryption_algor() != 1) goto err; + if (test_x509_signature_algor() != 1) goto err; + if (test_x509_public_key_encryption_algor() != 1) goto err; + printf("%s all tests passed!\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/x509_crltest.c b/tests/x509_crltest.c index 73c04d3e..b0438e80 100644 --- a/tests/x509_crltest.c +++ b/tests/x509_crltest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,146 +7,147 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_x509_crl_reason(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int reason; - int i; - - for (i = 0; i < 11; i++) { - if (x509_crl_reason_to_der(i, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < 11; i++) { - if (x509_crl_reason_from_der(&reason, &cp, &len) != 1 - || asn1_check(reason == i) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s (%d)\n", x509_crl_reason_name(reason), reason); - } - (void)asn1_length_is_zero(len); - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_crl_entry_ext(void) -{ - int exts[] = { - OID_ce_crl_reasons, - OID_ce_invalidity_date, - OID_ce_certificate_issuer, - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int oid; - int i; - - for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { - if (x509_crl_entry_ext_id_to_der(exts[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { - if (x509_crl_entry_ext_id_from_der(&oid, &cp, &len) != 1 - || asn1_check(oid == exts[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_crl_entry_ext_id_name(oid)); - } - (void)asn1_length_is_zero(len); - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_crl_entry_exts(void) -{ - uint8_t exts[256]; - size_t extslen = 0; - int reason = X509_cr_key_compromise; - time_t tv; - uint8_t issuer[256]; - size_t issuer_len = 0; - int critical = 1; - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - time(&tv); - if (x509_crl_entry_exts_add_reason(exts, &extslen, sizeof(exts), critical, reason) != 1 - || x509_crl_entry_exts_add_invalidity_date(exts, &extslen, sizeof(exts), critical, tv) != 1 - || x509_crl_entry_exts_add_certificate_issuer(exts, &extslen, sizeof(exts), critical, issuer, issuer_len) != 1 - || x509_crl_entry_exts_to_der(exts, extslen, &p, &len) != 1) { - error_print(); - return -1; - } - x509_crl_entry_exts_print(stderr, 0, 0, "CRLEntryExtensions", exts, extslen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_revoked_cert(void) -{ - uint8_t serial[20] = { 0x01,0x02 }; - time_t revoke_date; - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - const uint8_t *d; - size_t dlen; - - time(&revoke_date); - if (x509_revoked_cert_to_der(serial, sizeof(serial), revoke_date, NULL, 0, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_revoked_cert_print(stderr, 0, 0, "RevokedCertificate", d, dlen); - - return 1; -} - - -int main(void) -{ - if (test_x509_crl_reason() != 1) goto err; - if (test_x509_crl_entry_ext() != 1) goto err; - if (test_x509_crl_entry_exts() != 1) goto err; - if (test_x509_revoked_cert() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_crl_reason(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int reason; + int i; + + for (i = 0; i < 11; i++) { + if (x509_crl_reason_to_der(i, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < 11; i++) { + if (x509_crl_reason_from_der(&reason, &cp, &len) != 1 + || asn1_check(reason == i) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s (%d)\n", x509_crl_reason_name(reason), reason); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_crl_entry_ext(void) +{ + int exts[] = { + OID_ce_crl_reasons, + OID_ce_invalidity_date, + OID_ce_certificate_issuer, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int oid; + int i; + + for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { + if (x509_crl_entry_ext_id_to_der(exts[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(exts)/sizeof(exts[0]); i++) { + if (x509_crl_entry_ext_id_from_der(&oid, &cp, &len) != 1 + || asn1_check(oid == exts[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_crl_entry_ext_id_name(oid)); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_crl_entry_exts(void) +{ + uint8_t exts[256]; + size_t extslen = 0; + int reason = X509_cr_key_compromise; + time_t tv; + uint8_t issuer[256]; + size_t issuer_len = 0; + int critical = 1; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + time(&tv); + if (x509_crl_entry_exts_add_reason(exts, &extslen, sizeof(exts), critical, reason) != 1 + || x509_crl_entry_exts_add_invalidity_date(exts, &extslen, sizeof(exts), critical, tv) != 1 + || x509_crl_entry_exts_add_certificate_issuer(exts, &extslen, sizeof(exts), critical, issuer, issuer_len) != 1 + || x509_crl_entry_exts_to_der(exts, extslen, &p, &len) != 1) { + error_print(); + return -1; + } + x509_crl_entry_exts_print(stderr, 0, 0, "CRLEntryExtensions", exts, extslen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_revoked_cert(void) +{ + uint8_t serial[20] = { 0x01,0x02 }; + time_t revoke_date; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + const uint8_t *d; + size_t dlen; + + time(&revoke_date); + if (x509_revoked_cert_to_der(serial, sizeof(serial), revoke_date, NULL, 0, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_revoked_cert_print(stderr, 0, 0, "RevokedCertificate", d, dlen); + + return 1; +} + + +int main(void) +{ + if (test_x509_crl_reason() != 1) goto err; + if (test_x509_crl_entry_ext() != 1) goto err; + if (test_x509_crl_entry_exts() != 1) goto err; + if (test_x509_revoked_cert() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/x509_exttest.c b/tests/x509_exttest.c index 9668aa59..07dcaad3 100644 --- a/tests/x509_exttest.c +++ b/tests/x509_exttest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,854 +7,855 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define cnt(nodes) (sizeof(nodes)/sizeof(int)) - -static int test_x509_other_name(void) -{ - const uint32_t oid[] = { 1,3,5 }; - const uint8_t value[] = { 0x30,0x01,0x00 }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint32_t nodes[32]; - size_t nodes_cnt; - const uint8_t *val; - size_t vlen; - - if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_other_name_print(stderr, 0, 0, "OtherName", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 - || x509_other_name_from_der(nodes, &nodes_cnt, &val, &vlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - asn1_object_identifier_print(stderr, 0, 4, "type-id", NULL, nodes, nodes_cnt); - format_bytes(stderr, 0, 4, "value", val, vlen); - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_edi_party_name(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int assigner_tag; - const uint8_t *assigner; - size_t assigner_len; - int party_name_tag; - const uint8_t *party_name; - size_t party_name_len; - - if (x509_edi_party_name_to_der( - ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, - ASN1_TAG_PrintableString, (uint8_t *)"World", 5, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_edi_party_name_print(stderr, 0, 0, "EDIPartyName", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_edi_party_name_to_der( - ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, - ASN1_TAG_PrintableString, (uint8_t *)"World", 5, - &p, &len) != 1 - || x509_edi_party_name_from_der( - &assigner_tag, &assigner, &assigner_len, - &party_name_tag, &party_name, &party_name_len, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_directory_name_print(stderr, 0, 4, "nameAssigner", assigner_tag, assigner, assigner_len); - x509_directory_name_print(stderr, 0, 4, "partyName", party_name_tag, party_name, party_name_len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_general_name(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t gns[512]; - size_t gnslen; - uint32_t other_id[] = { 1,3,5,7 }; - uint8_t value[] = { ASN1_TAG_OCTET_STRING, 0x02, 0x05, 0x05 }; - uint8_t x400[] = { ASN1_TAG_SEQUENCE, 0x00 }; - uint8_t name[512]; - size_t namelen; - uint32_t reg_id[] = { 2,4,6,8 }; - - if (x509_name_set(name, &namelen, sizeof(name), - "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1) { - error_print(); - return -1; - } - gnslen = 0; - if (x509_general_names_add_other_name(gns, &gnslen, sizeof(gns), other_id, cnt(other_id), value, sizeof(value)) != 1 - || x509_general_names_add_rfc822_name(gns, &gnslen, sizeof(gns), "guan@pku.edu.cn") != 1 - || x509_general_names_add_dns_name(gns, &gnslen, sizeof(gns), "www.pku.edu.cn") != 1 - || x509_general_names_add_x400_address(gns, &gnslen, sizeof(gns), x400, sizeof(x400)) != 1 - || x509_general_names_add_directory_name(gns, &gnslen, sizeof(gns), name, namelen) != 1 - || x509_general_names_add_edi_party_name(gns, &gnslen, sizeof(gns), - ASN1_TAG_PrintableString, (uint8_t *)"Assigner", strlen("Assigner"), - ASN1_TAG_PrintableString, (uint8_t *)"PartyName", strlen("PartyName")) != 1 - || x509_general_names_add_uniform_resource_identifier(gns, &gnslen, sizeof(gns), "http://localhost") != 1 - || x509_general_names_add_ip_address(gns, &gnslen, sizeof(gns), "127.0.0.1") != 1 - || x509_general_names_add_registered_id(gns, &gnslen, sizeof(gns), reg_id, cnt(reg_id)) != 1 - || x509_general_names_to_der(gns, gnslen, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_general_names_print(stderr, 0, 0, "GeneralNames", d, dlen); - { - size_t i; - printf("uint8_t general_names[%zu] = {", dlen); - for (i = 0; i < dlen; i++) { - if (i % 16 == 0) { - printf("\n\t"); - } - printf("0x%02x,", d[i]); - } - printf("\n};\n"); - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -uint8_t general_names[202] = { - 0x80,0x0b,0x06,0x03,0x2b,0x05,0x07,0xa0,0x04,0x04,0x02,0x05,0x05,0x81,0x0f,0x67, - 0x75,0x61,0x6e,0x40,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x82,0x0e, - 0x77,0x77,0x77,0x2e,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x83,0x02, - 0x30,0x00,0x84,0x59,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43, - 0x4e,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x42,0x65,0x69,0x6a, - 0x69,0x6e,0x67,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x48,0x61, - 0x69,0x64,0x69,0x61,0x6e,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x0a,0x13,0x03, - 0x50,0x4b,0x55,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x0b,0x13,0x02,0x43,0x53, - 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x13,0x02,0x43,0x41,0x85,0x19,0xa0, - 0x0a,0x13,0x08,0x41,0x73,0x73,0x69,0x67,0x6e,0x65,0x72,0xa1,0x0b,0x13,0x09,0x50, - 0x61,0x72,0x74,0x79,0x4e,0x61,0x6d,0x65,0x86,0x10,0x68,0x74,0x74,0x70,0x3a,0x2f, - 0x2f,0x6c,0x6f,0x63,0x61,0x6c,0x68,0x6f,0x73,0x74,0x87,0x09,0x31,0x32,0x37,0x2e, - 0x30,0x2e,0x30,0x2e,0x31,0x88,0x03,0x54,0x06,0x08, -}; - -static int test_x509_authority_key_identifier(void) -{ - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t keyid[32]; - uint8_t serial[20]; - - const uint8_t *keyidp; - size_t keyidlen; - const uint8_t *issuerp; - size_t issuerlen; - const uint8_t *serialp; - size_t seriallen; - - sm3_digest((uint8_t *)"abc", 3, keyid); - rand_bytes(serial, sizeof(serial)); - - if (x509_authority_key_identifier_to_der( - keyid, sizeof(keyid), - general_names, sizeof(general_names), - serial, sizeof(serial), - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_authority_key_identifier_print(stderr, 0, 0, "AuthorityKeyIdentifier", d, dlen); - - p = buf; - cp = buf; - len = 0; - if (x509_authority_key_identifier_to_der( - keyid, sizeof(keyid), - general_names, sizeof(general_names), - serial, sizeof(serial), - &p, &len) != 1 - || x509_authority_key_identifier_from_der( - &keyidp, &keyidlen, - &issuerp, &issuerlen, - &serialp, &seriallen, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_key_usage(void) -{ - int tests[] = { - 0, - 1, - 2, - X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN, - 7, - 8, - X509_KU_DIGITAL_SIGNATURE|X509_KU_NON_REPUDIATION|X509_KU_DECIPHER_ONLY, - 0x1ff, - // 0x3ff, // this should return error - }; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int usage; - int i; - - for (i = 0; i <= 8; i++) { - format_print(stderr, 0, 4, "%d %s\n", i, x509_key_usage_name(1 << i)); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_key_usage_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_key_usage_from_der(&usage, &cp, &len) != 1 - || asn1_check(usage == tests[i]) != 1) { - error_print(); - return -1; - } - x509_key_usage_print(stderr, 0, 4, "KeyUsage", usage); - } - (void)asn1_length_is_zero(len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_notice_reference(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int notice_nums[] = { 1,2,3,4,5 }; - - int org_tag; - const uint8_t *org; - size_t orglen; - int nums[32]; - size_t nums_cnt; - - if (x509_notice_reference_to_der( - ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, - notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_notice_reference_print(stderr, 0, 0, "NoticeReference", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_notice_reference_to_der( - ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, - notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), - &p, &len) != 1 - || x509_notice_reference_from_der( - &org_tag, &org, &orglen, - nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]), - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_user_notice(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int notice_nums[] = { 1,2,3,4,5 }; - - int org_tag; - const uint8_t *org; - size_t orglen; - int nums[32]; - size_t nums_cnt; - int text_tag; - const uint8_t *text; - size_t textlen; - - if (x509_user_notice_to_der( - ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, - notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), - ASN1_TAG_IA5String, (uint8_t *)"World", 5, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_user_notice_print(stderr, 0, 0, "UserNotice", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_user_notice_to_der( - ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, - notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), - ASN1_TAG_IA5String, (uint8_t *)"World", 5, - &p, &len) != 1 - || x509_user_notice_from_der( - &org_tag, &org, &orglen, - nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]), - &text_tag, &text, &textlen, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_policy_qualifier_info(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - - if (x509_policy_qualifier_info_to_der( - OID_qt_cps, - (uint8_t *)"Qualifier", strlen("Qualifier"), - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_policy_qualifier_info_print(stderr, 0, 0, "PolicyQualifierInfo", d, dlen); - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_policy_mapping(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int issuer_policy_oid; - uint32_t issuer_policy_nodes[32]; - size_t issuer_policy_nodes_cnt; - int subject_policy_oid; - uint32_t subject_policy_nodes[32]; - size_t subject_policy_nodes_cnt; - - if (x509_policy_mapping_to_der( - OID_any_policy, NULL, 0, - OID_any_policy, NULL, 0, - &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_policy_mapping_print(stderr, 0, 0, "PolicyMapping", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_policy_mapping_to_der( - OID_any_policy, NULL, 0, - OID_any_policy, NULL, 0, - &p, &len) != 1 - || x509_policy_mapping_from_der( - &issuer_policy_oid, issuer_policy_nodes, &issuer_policy_nodes_cnt, - &subject_policy_oid, subject_policy_nodes, &subject_policy_nodes_cnt, - &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -// 这里的一些OID应该在RFC中有,但是我们不实现 -static int test_x509_attribute(void) -{ - // TODO - return 1; -} - -static int test_x509_basic_constraints(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int ca; - int path; - - if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); - - cp = p = buf; len = 0; - if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); - - - cp = p = buf; len = 0; - if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); - - cp = p = buf; len = 0; - if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1 - || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1 - || asn1_check(ca == 1) != 1 - || asn1_check(path == 4) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - cp = p = buf; len = 0; - if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1 - || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1 - || asn1_check(ca == 0) != 1 - || asn1_check(path == 4) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - cp = p = buf; len = 0; - if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 // should return error - || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != -1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_general_subtree(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t *dns = (uint8_t *)"www.pku.edu.cn"; - size_t dnslen = strlen((char *)dns); - - int choice; - const uint8_t *dns_name; - size_t dns_name_len; - int min_dis; - int max_dis; - - if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, 5, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_general_subtree_print(stderr, 0, 0, "GeneralSubtree", d, dlen); - - cp = p = buf; len = 0; - min_dis = max_dis = 99; - if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, -1, 5, &p, &len) != 1 - || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1 - || asn1_check(choice == X509_gn_dns_name) != 1 - || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1 - || asn1_check(min_dis == 0) != 1 - || asn1_check(max_dis == 5) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - cp = p = buf; len = 0; - min_dis = max_dis = 99; - if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, -1, &p, &len) != 1 - || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1 - || asn1_check(choice == X509_gn_dns_name) != 1 - || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1 - || asn1_check(min_dis == 1) != 1 - || asn1_check(max_dis == -1) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_policy_constraints(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int val1; - int val2; - - if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); - - cp = p = buf; len = 0; - if (x509_policy_constraints_to_der(2, -1, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); - - cp = p = buf; len = 0; - if (x509_policy_constraints_to_der(-1, 5, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); - - cp = p = buf; len = 0; - val1 = val2 = 99; - if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1 - || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1 - || asn1_check(val1 == 2) != 1 - || asn1_check(val2 == 5) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - cp = p = buf; len = 0; - val1 = val2 = 99; - if (x509_policy_constraints_to_der(-1, -1, &p, &len) != 1 - || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1 - || asn1_check(val1 == -1) != 1 - || asn1_check(val2 == -1) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_ext_key_usage(void) -{ - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int kp[] = { - OID_kp_server_auth, - OID_kp_client_auth, - OID_kp_code_signing, - OID_kp_email_protection, - OID_kp_time_stamping, - OID_kp_ocsp_signing, - }; - int oids[16] = {0}; - size_t oids_cnt; - int i; - - if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_ext_key_usage_print(stderr, 0, 0, "ExtKeyUsageSyntax", d, dlen); - - if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1 - || x509_ext_key_usage_from_der(oids, &oids_cnt, sizeof(oids)/sizeof(oids[0]), &cp, &len) != 1 - || asn1_check(oids_cnt == sizeof(kp)/sizeof(int)) != 1 - || asn1_check(memcmp(oids, kp, sizeof(kp)) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_revoke_reasons(void) -{ - int tests[] = { - 0, - 1, - 2, - X509_RF_SUPERSEDED|X509_RF_PRIVILEGE_WITHDRAWN|X509_RF_AA_COMPROMISE, - 0x1ff, - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int bits; - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_revoke_reasons_to_der(tests[i], &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_revoke_reasons_from_der(&bits, &cp, &len) != 1 - || asn1_check(bits == tests[i]) != 1) { - error_print(); - return -1; - } - x509_revoke_reasons_print(stderr, 0, 4, "ReasonFlags", bits); - } - (void)asn1_length_is_zero(len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_exts(void) -{ - uint8_t buf[1024]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - uint8_t exts[512]; - size_t extslen = 0; - uint8_t keyid[32] = {1}; - uint8_t serial[20] = {2}; - - if (0 - || x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1, - keyid, sizeof(keyid), - general_names, sizeof(general_names), - serial, sizeof(serial)) != 1 - || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0, - keyid, sizeof(keyid)) != 1 - || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0, - X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1 - || x509_exts_to_der(exts, extslen, &p, &len) != 1 - || x509_exts_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_exts_print(stderr, 0, 0, "Extensions", d, dlen); - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_cert_with_exts(void) -{ - uint8_t cert[1024]; - size_t certlen; - uint8_t serial[20]; - uint8_t name[256]; - size_t namelen; - time_t not_before, not_after; - SM2_KEY sm2_key; - uint8_t uniq_id[32]; - uint8_t exts[512]; - size_t extslen = 0; - uint8_t keyid[32] = {1}; - - - rand_bytes(serial, sizeof(serial)); - x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); - time(¬_before); - x509_validity_add_days(¬_after, not_before, 365); - sm2_key_generate(&sm2_key); - sm3_digest((uint8_t *)&(sm2_key.public_key), sizeof(SM2_POINT), uniq_id); - - if (x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1, - keyid, sizeof(keyid), - general_names, sizeof(general_names), - serial, sizeof(serial)) != 1 - || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0, - keyid, sizeof(keyid)) != 1 - || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0, - X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1) { - error_print(); - return -1; - } - - if (x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - name, namelen, - not_before, not_after, - name, namelen, - &sm2_key, - uniq_id, sizeof(uniq_id), - uniq_id, sizeof(uniq_id), - exts, extslen, - &sm2_key, - SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - error_print(); - return -1; - } - x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen); - - - return 1; -} - -int main(int argc, char **argv) -{ - if (test_x509_other_name() != 1) goto err; - if (test_x509_edi_party_name() != 1) goto err; - if (test_x509_general_name() != 1) goto err; - if (test_x509_authority_key_identifier() != 1) goto err; - if (test_x509_key_usage() != 1) goto err; - if (test_x509_notice_reference() != 1) goto err; - if (test_x509_user_notice() != 1) goto err; - if (test_x509_policy_qualifier_info() != 1) goto err; - if (test_x509_policy_mapping() != 1) goto err; - if (test_x509_basic_constraints() != 1) goto err; - if (test_x509_general_subtree() != 1) goto err; - if (test_x509_policy_constraints() != 1) goto err; - if (test_x509_ext_key_usage() != 1) goto err; - if (test_x509_revoke_reasons() != 1) goto err; - if (test_x509_exts() != 1) goto err; - if (test_x509_cert_with_exts() != 1) goto err; - printf("%s all tests passed!\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define cnt(nodes) (sizeof(nodes)/sizeof(int)) + +static int test_x509_other_name(void) +{ + const uint32_t oid[] = { 1,3,5 }; + const uint8_t value[] = { 0x30,0x01,0x00 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint32_t nodes[32]; + size_t nodes_cnt; + const uint8_t *val; + size_t vlen; + + if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_other_name_print(stderr, 0, 0, "OtherName", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1 + || x509_other_name_from_der(nodes, &nodes_cnt, &val, &vlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + asn1_object_identifier_print(stderr, 0, 4, "type-id", NULL, nodes, nodes_cnt); + format_bytes(stderr, 0, 4, "value", val, vlen); + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_edi_party_name(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int assigner_tag; + const uint8_t *assigner; + size_t assigner_len; + int party_name_tag; + const uint8_t *party_name; + size_t party_name_len; + + if (x509_edi_party_name_to_der( + ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, + ASN1_TAG_PrintableString, (uint8_t *)"World", 5, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_edi_party_name_print(stderr, 0, 0, "EDIPartyName", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_edi_party_name_to_der( + ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5, + ASN1_TAG_PrintableString, (uint8_t *)"World", 5, + &p, &len) != 1 + || x509_edi_party_name_from_der( + &assigner_tag, &assigner, &assigner_len, + &party_name_tag, &party_name, &party_name_len, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_directory_name_print(stderr, 0, 4, "nameAssigner", assigner_tag, assigner, assigner_len); + x509_directory_name_print(stderr, 0, 4, "partyName", party_name_tag, party_name, party_name_len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_general_name(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t gns[512]; + size_t gnslen; + uint32_t other_id[] = { 1,3,5,7 }; + uint8_t value[] = { ASN1_TAG_OCTET_STRING, 0x02, 0x05, 0x05 }; + uint8_t x400[] = { ASN1_TAG_SEQUENCE, 0x00 }; + uint8_t name[512]; + size_t namelen; + uint32_t reg_id[] = { 2,4,6,8 }; + + if (x509_name_set(name, &namelen, sizeof(name), + "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1) { + error_print(); + return -1; + } + gnslen = 0; + if (x509_general_names_add_other_name(gns, &gnslen, sizeof(gns), other_id, cnt(other_id), value, sizeof(value)) != 1 + || x509_general_names_add_rfc822_name(gns, &gnslen, sizeof(gns), "guan@pku.edu.cn") != 1 + || x509_general_names_add_dns_name(gns, &gnslen, sizeof(gns), "www.pku.edu.cn") != 1 + || x509_general_names_add_x400_address(gns, &gnslen, sizeof(gns), x400, sizeof(x400)) != 1 + || x509_general_names_add_directory_name(gns, &gnslen, sizeof(gns), name, namelen) != 1 + || x509_general_names_add_edi_party_name(gns, &gnslen, sizeof(gns), + ASN1_TAG_PrintableString, (uint8_t *)"Assigner", strlen("Assigner"), + ASN1_TAG_PrintableString, (uint8_t *)"PartyName", strlen("PartyName")) != 1 + || x509_general_names_add_uniform_resource_identifier(gns, &gnslen, sizeof(gns), "http://localhost") != 1 + || x509_general_names_add_ip_address(gns, &gnslen, sizeof(gns), "127.0.0.1") != 1 + || x509_general_names_add_registered_id(gns, &gnslen, sizeof(gns), reg_id, cnt(reg_id)) != 1 + || x509_general_names_to_der(gns, gnslen, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_general_names_print(stderr, 0, 0, "GeneralNames", d, dlen); + { + size_t i; + printf("uint8_t general_names[%zu] = {", dlen); + for (i = 0; i < dlen; i++) { + if (i % 16 == 0) { + printf("\n\t"); + } + printf("0x%02x,", d[i]); + } + printf("\n};\n"); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +uint8_t general_names[202] = { + 0x80,0x0b,0x06,0x03,0x2b,0x05,0x07,0xa0,0x04,0x04,0x02,0x05,0x05,0x81,0x0f,0x67, + 0x75,0x61,0x6e,0x40,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x82,0x0e, + 0x77,0x77,0x77,0x2e,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x83,0x02, + 0x30,0x00,0x84,0x59,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43, + 0x4e,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x42,0x65,0x69,0x6a, + 0x69,0x6e,0x67,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x48,0x61, + 0x69,0x64,0x69,0x61,0x6e,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x0a,0x13,0x03, + 0x50,0x4b,0x55,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x0b,0x13,0x02,0x43,0x53, + 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x13,0x02,0x43,0x41,0x85,0x19,0xa0, + 0x0a,0x13,0x08,0x41,0x73,0x73,0x69,0x67,0x6e,0x65,0x72,0xa1,0x0b,0x13,0x09,0x50, + 0x61,0x72,0x74,0x79,0x4e,0x61,0x6d,0x65,0x86,0x10,0x68,0x74,0x74,0x70,0x3a,0x2f, + 0x2f,0x6c,0x6f,0x63,0x61,0x6c,0x68,0x6f,0x73,0x74,0x87,0x09,0x31,0x32,0x37,0x2e, + 0x30,0x2e,0x30,0x2e,0x31,0x88,0x03,0x54,0x06,0x08, +}; + +static int test_x509_authority_key_identifier(void) +{ + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t keyid[32]; + uint8_t serial[20]; + + const uint8_t *keyidp; + size_t keyidlen; + const uint8_t *issuerp; + size_t issuerlen; + const uint8_t *serialp; + size_t seriallen; + + sm3_digest((uint8_t *)"abc", 3, keyid); + rand_bytes(serial, sizeof(serial)); + + if (x509_authority_key_identifier_to_der( + keyid, sizeof(keyid), + general_names, sizeof(general_names), + serial, sizeof(serial), + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_authority_key_identifier_print(stderr, 0, 0, "AuthorityKeyIdentifier", d, dlen); + + p = buf; + cp = buf; + len = 0; + if (x509_authority_key_identifier_to_der( + keyid, sizeof(keyid), + general_names, sizeof(general_names), + serial, sizeof(serial), + &p, &len) != 1 + || x509_authority_key_identifier_from_der( + &keyidp, &keyidlen, + &issuerp, &issuerlen, + &serialp, &seriallen, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_key_usage(void) +{ + int tests[] = { + 0, + 1, + 2, + X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN, + 7, + 8, + X509_KU_DIGITAL_SIGNATURE|X509_KU_NON_REPUDIATION|X509_KU_DECIPHER_ONLY, + 0x1ff, + // 0x3ff, // this should return error + }; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int usage; + int i; + + for (i = 0; i <= 8; i++) { + format_print(stderr, 0, 4, "%d %s\n", i, x509_key_usage_name(1 << i)); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_key_usage_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_key_usage_from_der(&usage, &cp, &len) != 1 + || asn1_check(usage == tests[i]) != 1) { + error_print(); + return -1; + } + x509_key_usage_print(stderr, 0, 4, "KeyUsage", usage); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_notice_reference(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int notice_nums[] = { 1,2,3,4,5 }; + + int org_tag; + const uint8_t *org; + size_t orglen; + int nums[32]; + size_t nums_cnt; + + if (x509_notice_reference_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_notice_reference_print(stderr, 0, 0, "NoticeReference", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_notice_reference_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + &p, &len) != 1 + || x509_notice_reference_from_der( + &org_tag, &org, &orglen, + nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]), + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_user_notice(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int notice_nums[] = { 1,2,3,4,5 }; + + int org_tag; + const uint8_t *org; + size_t orglen; + int nums[32]; + size_t nums_cnt; + int text_tag; + const uint8_t *text; + size_t textlen; + + if (x509_user_notice_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + ASN1_TAG_IA5String, (uint8_t *)"World", 5, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_user_notice_print(stderr, 0, 0, "UserNotice", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_user_notice_to_der( + ASN1_TAG_IA5String, (uint8_t *)"Hello", 5, + notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]), + ASN1_TAG_IA5String, (uint8_t *)"World", 5, + &p, &len) != 1 + || x509_user_notice_from_der( + &org_tag, &org, &orglen, + nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]), + &text_tag, &text, &textlen, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_policy_qualifier_info(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + + if (x509_policy_qualifier_info_to_der( + OID_qt_cps, + (uint8_t *)"Qualifier", strlen("Qualifier"), + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_policy_qualifier_info_print(stderr, 0, 0, "PolicyQualifierInfo", d, dlen); + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_policy_mapping(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int issuer_policy_oid; + uint32_t issuer_policy_nodes[32]; + size_t issuer_policy_nodes_cnt; + int subject_policy_oid; + uint32_t subject_policy_nodes[32]; + size_t subject_policy_nodes_cnt; + + if (x509_policy_mapping_to_der( + OID_any_policy, NULL, 0, + OID_any_policy, NULL, 0, + &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_policy_mapping_print(stderr, 0, 0, "PolicyMapping", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_policy_mapping_to_der( + OID_any_policy, NULL, 0, + OID_any_policy, NULL, 0, + &p, &len) != 1 + || x509_policy_mapping_from_der( + &issuer_policy_oid, issuer_policy_nodes, &issuer_policy_nodes_cnt, + &subject_policy_oid, subject_policy_nodes, &subject_policy_nodes_cnt, + &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +// 这里的一些OID应该在RFC中有,但是我们不实现 +static int test_x509_attribute(void) +{ + // TODO + return 1; +} + +static int test_x509_basic_constraints(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int ca; + int path; + + if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); + + cp = p = buf; len = 0; + if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); + + + cp = p = buf; len = 0; + if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen); + + cp = p = buf; len = 0; + if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1 + || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1 + || asn1_check(ca == 1) != 1 + || asn1_check(path == 4) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + cp = p = buf; len = 0; + if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1 + || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1 + || asn1_check(ca == 0) != 1 + || asn1_check(path == 4) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + cp = p = buf; len = 0; + if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 // should return error + || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != -1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_general_subtree(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t *dns = (uint8_t *)"www.pku.edu.cn"; + size_t dnslen = strlen((char *)dns); + + int choice; + const uint8_t *dns_name; + size_t dns_name_len; + int min_dis; + int max_dis; + + if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, 5, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_general_subtree_print(stderr, 0, 0, "GeneralSubtree", d, dlen); + + cp = p = buf; len = 0; + min_dis = max_dis = 99; + if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, -1, 5, &p, &len) != 1 + || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1 + || asn1_check(choice == X509_gn_dns_name) != 1 + || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1 + || asn1_check(min_dis == 0) != 1 + || asn1_check(max_dis == 5) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + cp = p = buf; len = 0; + min_dis = max_dis = 99; + if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, -1, &p, &len) != 1 + || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1 + || asn1_check(choice == X509_gn_dns_name) != 1 + || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1 + || asn1_check(min_dis == 1) != 1 + || asn1_check(max_dis == -1) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_policy_constraints(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int val1; + int val2; + + if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); + + cp = p = buf; len = 0; + if (x509_policy_constraints_to_der(2, -1, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); + + cp = p = buf; len = 0; + if (x509_policy_constraints_to_der(-1, 5, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen); + + cp = p = buf; len = 0; + val1 = val2 = 99; + if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1 + || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1 + || asn1_check(val1 == 2) != 1 + || asn1_check(val2 == 5) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + cp = p = buf; len = 0; + val1 = val2 = 99; + if (x509_policy_constraints_to_der(-1, -1, &p, &len) != 1 + || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1 + || asn1_check(val1 == -1) != 1 + || asn1_check(val2 == -1) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_ext_key_usage(void) +{ + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int kp[] = { + OID_kp_server_auth, + OID_kp_client_auth, + OID_kp_code_signing, + OID_kp_email_protection, + OID_kp_time_stamping, + OID_kp_ocsp_signing, + }; + int oids[16] = {0}; + size_t oids_cnt; + int i; + + if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_ext_key_usage_print(stderr, 0, 0, "ExtKeyUsageSyntax", d, dlen); + + if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1 + || x509_ext_key_usage_from_der(oids, &oids_cnt, sizeof(oids)/sizeof(oids[0]), &cp, &len) != 1 + || asn1_check(oids_cnt == sizeof(kp)/sizeof(int)) != 1 + || asn1_check(memcmp(oids, kp, sizeof(kp)) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_revoke_reasons(void) +{ + int tests[] = { + 0, + 1, + 2, + X509_RF_SUPERSEDED|X509_RF_PRIVILEGE_WITHDRAWN|X509_RF_AA_COMPROMISE, + 0x1ff, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int bits; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_revoke_reasons_to_der(tests[i], &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_revoke_reasons_from_der(&bits, &cp, &len) != 1 + || asn1_check(bits == tests[i]) != 1) { + error_print(); + return -1; + } + x509_revoke_reasons_print(stderr, 0, 4, "ReasonFlags", bits); + } + (void)asn1_length_is_zero(len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_exts(void) +{ + uint8_t buf[1024]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + uint8_t exts[512]; + size_t extslen = 0; + uint8_t keyid[32] = {1}; + uint8_t serial[20] = {2}; + + if (0 + || x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1, + keyid, sizeof(keyid), + general_names, sizeof(general_names), + serial, sizeof(serial)) != 1 + || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0, + keyid, sizeof(keyid)) != 1 + || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0, + X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1 + || x509_exts_to_der(exts, extslen, &p, &len) != 1 + || x509_exts_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_exts_print(stderr, 0, 0, "Extensions", d, dlen); + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_cert_with_exts(void) +{ + uint8_t cert[1024]; + size_t certlen; + uint8_t serial[20]; + uint8_t name[256]; + size_t namelen; + time_t not_before, not_after; + SM2_KEY sm2_key; + uint8_t uniq_id[32]; + uint8_t exts[512]; + size_t extslen = 0; + uint8_t keyid[32] = {1}; + + + rand_bytes(serial, sizeof(serial)); + x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA"); + time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + sm2_key_generate(&sm2_key); + sm3_digest((uint8_t *)&(sm2_key.public_key), sizeof(SM2_POINT), uniq_id); + + if (x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1, + keyid, sizeof(keyid), + general_names, sizeof(general_names), + serial, sizeof(serial)) != 1 + || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0, + keyid, sizeof(keyid)) != 1 + || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0, + X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1) { + error_print(); + return -1; + } + + if (x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, + uniq_id, sizeof(uniq_id), + uniq_id, sizeof(uniq_id), + exts, extslen, + &sm2_key, + SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen); + + + return 1; +} + +int main(int argc, char **argv) +{ + if (test_x509_other_name() != 1) goto err; + if (test_x509_edi_party_name() != 1) goto err; + if (test_x509_general_name() != 1) goto err; + if (test_x509_authority_key_identifier() != 1) goto err; + if (test_x509_key_usage() != 1) goto err; + if (test_x509_notice_reference() != 1) goto err; + if (test_x509_user_notice() != 1) goto err; + if (test_x509_policy_qualifier_info() != 1) goto err; + if (test_x509_policy_mapping() != 1) goto err; + if (test_x509_basic_constraints() != 1) goto err; + if (test_x509_general_subtree() != 1) goto err; + if (test_x509_policy_constraints() != 1) goto err; + if (test_x509_ext_key_usage() != 1) goto err; + if (test_x509_revoke_reasons() != 1) goto err; + if (test_x509_exts() != 1) goto err; + if (test_x509_cert_with_exts() != 1) goto err; + printf("%s all tests passed!\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/x509_oidtest.c b/tests/x509_oidtest.c index fb73eecc..b472d393 100644 --- a/tests/x509_oidtest.c +++ b/tests/x509_oidtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,281 +7,282 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_x509_name_type() -{ - char *names[] = { - "name", - "surname", - "givenName", - "initials", - "generationQualifier", - "commonName", - "localityName", - "stateOrProvinceName", - "organizationName", - "organizationalUnitName", - "title", - "dnQualifier", - "countryName", - "serialNumber", - "pseudonym", - "domainComponent", - }; - int oid; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_name_type_from_name(names[i]); - if (asn1_check(oid != OID_undef) != 1 - || x509_name_type_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_name_type_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != x509_name_type_from_name(names[i])) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_name_type_name(oid)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_ext_id() -{ - char *names[] = { - "AuthorityKeyIdentifier", - "SubjectKeyIdentifier", - "KeyUsage", - "CertificatePolicies", - "PolicyMappings", - "SubjectAltName", - "IssuerAltName", - "SubjectDirectoryAttributes", - "BasicConstraints", - "NameConstraints", - "PolicyConstraints", - "ExtKeyUsage", - "CRLDistributionPoints", - "InhibitAnyPolicy", - "FreshestCRL", - }; - int oid; - uint32_t nodes[32]; - size_t nodes_cnt; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_ext_id_from_name(names[i]); - if (asn1_check(oid != OID_undef) != 1 - || x509_ext_id_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "ExtnID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != x509_ext_id_from_name(names[i])) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_ext_id_name(oid)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_qualifier_id(void) -{ - char *names[] = { - "CPS", - "userNotice", - }; - int oid; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_qualifier_id_from_name(names[i]); - if (asn1_check(oid != OID_undef) != 1 - || x509_qualifier_id_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_qualifier_id_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - if (asn1_check(oid == x509_qualifier_id_from_name(names[i])) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_qualifier_id_name(oid)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_cert_policy_id(void) -{ - char *names[] = { - "anyPolicy", - }; - int oid; - uint32_t nodes[32]; - size_t nodes_cnt; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_cert_policy_id_from_name(names[i]); - if (asn1_check(oid != OID_undef) != 1 - || x509_cert_policy_id_to_der(oid, NULL, 0, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != x509_cert_policy_id_from_name(names[i])) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_cert_policy_id_name(oid)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_key_purpose(void) -{ - char *names[] = { - "serverAuth", - "clientAuth", - "codeSigning", - "emailProtection", - "timeStamping", - "OCSPSigning", - }; - int oid; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int i; - - format_print(stderr, 0, 0, "DER\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - oid = x509_key_purpose_from_name(names[i]); - if (asn1_check(oid != OID_undef) != 1 - || x509_key_purpose_to_der(oid, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - - format_print(stderr, 0, 0, "OID\n"); - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { - if (x509_key_purpose_from_der(&oid, &cp, &len) != 1) { - error_print(); - return -1; - } - if (oid != x509_key_purpose_from_name(names[i])) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_key_purpose_name(oid)); - } - if (len != 0) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_x509_name_type() != 1) goto err; - if (test_x509_ext_id() != 1) goto err; - if (test_x509_qualifier_id() != 1) goto err; - if (test_x509_cert_policy_id() != 1) goto err; - if (test_x509_key_purpose() != 1) goto err; - printf("%s all tests passed\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_name_type() +{ + char *names[] = { + "name", + "surname", + "givenName", + "initials", + "generationQualifier", + "commonName", + "localityName", + "stateOrProvinceName", + "organizationName", + "organizationalUnitName", + "title", + "dnQualifier", + "countryName", + "serialNumber", + "pseudonym", + "domainComponent", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_name_type_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_name_type_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_name_type_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_name_type_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_name_type_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_ext_id() +{ + char *names[] = { + "AuthorityKeyIdentifier", + "SubjectKeyIdentifier", + "KeyUsage", + "CertificatePolicies", + "PolicyMappings", + "SubjectAltName", + "IssuerAltName", + "SubjectDirectoryAttributes", + "BasicConstraints", + "NameConstraints", + "PolicyConstraints", + "ExtKeyUsage", + "CRLDistributionPoints", + "InhibitAnyPolicy", + "FreshestCRL", + }; + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_ext_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_ext_id_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "ExtnID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_ext_id_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_ext_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_qualifier_id(void) +{ + char *names[] = { + "CPS", + "userNotice", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_qualifier_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_qualifier_id_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_qualifier_id_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (asn1_check(oid == x509_qualifier_id_from_name(names[i])) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_qualifier_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_cert_policy_id(void) +{ + char *names[] = { + "anyPolicy", + }; + int oid; + uint32_t nodes[32]; + size_t nodes_cnt; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_cert_policy_id_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_cert_policy_id_to_der(oid, NULL, 0, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_cert_policy_id_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_cert_policy_id_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_key_purpose(void) +{ + char *names[] = { + "serverAuth", + "clientAuth", + "codeSigning", + "emailProtection", + "timeStamping", + "OCSPSigning", + }; + int oid; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int i; + + format_print(stderr, 0, 0, "DER\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + oid = x509_key_purpose_from_name(names[i]); + if (asn1_check(oid != OID_undef) != 1 + || x509_key_purpose_to_der(oid, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + + format_print(stderr, 0, 0, "OID\n"); + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) { + if (x509_key_purpose_from_der(&oid, &cp, &len) != 1) { + error_print(); + return -1; + } + if (oid != x509_key_purpose_from_name(names[i])) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_key_purpose_name(oid)); + } + if (len != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_x509_name_type() != 1) goto err; + if (test_x509_ext_id() != 1) goto err; + if (test_x509_qualifier_id() != 1) goto err; + if (test_x509_cert_policy_id() != 1) goto err; + if (test_x509_key_purpose() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/x509_reqtest.c b/tests/x509_reqtest.c index 7f89d8b5..ae0b0ac5 100644 --- a/tests/x509_reqtest.c +++ b/tests/x509_reqtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,212 +7,213 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_x509_request_info(void) -{ - uint8_t subject[256]; - size_t subject_len; - SM2_KEY sm2_key; - - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int version; - const uint8_t *subj; - size_t subj_len; - SM2_KEY pub_key; - const uint8_t *attrs; - size_t attrs_len; - - if (sm2_key_generate(&sm2_key) != 1 - || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 - || x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_request_info_print(stderr, 0, 0, "CertificationRequestInfo", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 - || x509_request_info_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "CertificationRequestInfo\n"); - format_print(stderr, 0, 4, "version: %d\n", version); - x509_name_print(stderr, 0, 4, "subject", subj, subj_len); - sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); - format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_request(void) -{ - uint8_t subject[256]; - size_t subject_len; - SM2_KEY sm2_key; - uint8_t signature[128] = { 0x01, 0x02 }; - - uint8_t buf[512]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - int version; - const uint8_t *subj; - size_t subj_len; - SM2_KEY pub_key; - const uint8_t *attrs; - size_t attrs_len; - int sig_alg; - const uint8_t *sig; - size_t siglen; - - if (sm2_key_generate(&sm2_key) != 1 - || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 - || x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, - OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_request_print(stderr, 0, 0, "CertificationRequest", d, dlen); - - p = buf; - cp = buf; - len = 0; - - if (x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, - OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 - || x509_request_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, - &sig_alg, &sig, &siglen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "CertificationRequest\n"); - format_print(stderr, 0, 4, "version: %d\n", version); - x509_name_print(stderr, 0, 4, "subject", subj, subj_len); - sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); - format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); - format_print(stderr, 0, 4, "signatureAlgor: %s\n", x509_signature_algor_name(sig_alg)); - format_bytes(stderr, 0, 4, "signature", sig, siglen); - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_req(void) -{ - uint8_t subject[256]; - size_t subject_len; - SM2_KEY sm2_key; - - uint8_t req[512]; - size_t reqlen = 0; - - int version; - const uint8_t *subj; - size_t subj_len; - SM2_KEY pub_key; - const uint8_t *attrs; - size_t attrs_len; - - if (sm2_key_generate(&sm2_key) != 1 - || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 - || x509_req_sign(req, &reqlen, sizeof(req), - X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, - OID_sm2sign_with_sm3, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - error_print(); - return -1; - } - x509_req_print(stderr, 0, 0, "CertificationRequest", req, reqlen); - - - - FILE *fp; - - if ((fp = fopen("req.pem", "w")) == NULL) { - error_print(); - return -1; - } - if (x509_req_to_pem(req, reqlen, fp) != 1) { - error_print(); - return -1; - } - fclose(fp); - x509_req_to_pem(req, reqlen, stderr); - - - memset(req, 0, sizeof(req)); - - if ((fp = fopen("req.pem", "r")) == NULL) { - error_print(); - return -1; - } - if (x509_req_from_pem(req, &reqlen, sizeof(req), fp) != 1) { - error_print(); - return -1; - } - if (x509_req_verify(req, reqlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 0, "x509_req_verify() success\n"); - - - - - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - - - - - - - - - - -int main(void) -{ - if (test_x509_request_info() != 1) goto err; - if (test_x509_request() != 1) goto err; - if (test_x509_req() != 1) goto err; - printf("%s all tests passed!\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} - + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_request_info(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_request_info_print(stderr, 0, 0, "CertificationRequestInfo", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_request_info_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, &p, &len) != 1 + || x509_request_info_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "CertificationRequestInfo\n"); + format_print(stderr, 0, 4, "version: %d\n", version); + x509_name_print(stderr, 0, 4, "subject", subj, subj_len); + sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); + format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_request(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + uint8_t signature[128] = { 0x01, 0x02 }; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + int sig_alg; + const uint8_t *sig; + size_t siglen; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_request_print(stderr, 0, 0, "CertificationRequest", d, dlen); + + p = buf; + cp = buf; + len = 0; + + if (x509_request_to_der(X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, signature, sizeof(signature), &p, &len) != 1 + || x509_request_from_der(&version, &subj, &subj_len, &pub_key, &attrs, &attrs_len, + &sig_alg, &sig, &siglen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "CertificationRequest\n"); + format_print(stderr, 0, 4, "version: %d\n", version); + x509_name_print(stderr, 0, 4, "subject", subj, subj_len); + sm2_public_key_print(stderr, 0, 4, "publicKey", &pub_key); + format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len); + format_print(stderr, 0, 4, "signatureAlgor: %s\n", x509_signature_algor_name(sig_alg)); + format_bytes(stderr, 0, 4, "signature", sig, siglen); + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_req(void) +{ + uint8_t subject[256]; + size_t subject_len; + SM2_KEY sm2_key; + + uint8_t req[512]; + size_t reqlen = 0; + + int version; + const uint8_t *subj; + size_t subj_len; + SM2_KEY pub_key; + const uint8_t *attrs; + size_t attrs_len; + + if (sm2_key_generate(&sm2_key) != 1 + || x509_name_set(subject, &subject_len, sizeof(subject), "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1 + || x509_req_sign(req, &reqlen, sizeof(req), + X509_version_v1, subject, subject_len, &sm2_key, NULL, 0, + OID_sm2sign_with_sm3, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + x509_req_print(stderr, 0, 0, "CertificationRequest", req, reqlen); + + + + FILE *fp; + + if ((fp = fopen("req.pem", "w")) == NULL) { + error_print(); + return -1; + } + if (x509_req_to_pem(req, reqlen, fp) != 1) { + error_print(); + return -1; + } + fclose(fp); + x509_req_to_pem(req, reqlen, stderr); + + + memset(req, 0, sizeof(req)); + + if ((fp = fopen("req.pem", "r")) == NULL) { + error_print(); + return -1; + } + if (x509_req_from_pem(req, &reqlen, sizeof(req), fp) != 1) { + error_print(); + return -1; + } + if (x509_req_verify(req, reqlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 0, "x509_req_verify() success\n"); + + + + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + + + + + + + + +int main(void) +{ + if (test_x509_request_info() != 1) goto err; + if (test_x509_request() != 1) goto err; + if (test_x509_req() != 1) goto err; + printf("%s all tests passed!\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} + diff --git a/tests/x509_strtest.c b/tests/x509_strtest.c index a7fe8d81..5dcf5cea 100644 --- a/tests/x509_strtest.c +++ b/tests/x509_strtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,73 +7,74 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int test_x509_directory_name(void) -{ - uint8_t str[] = { 'a', 'b', 'c', 0 }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int tag; - const uint8_t *d; - size_t dlen; - - if (x509_directory_name_check_ex(ASN1_TAG_UTF8String, str, 3, 1, 10) != 1 // str,4 will fail - || x509_directory_name_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 - || x509_directory_name_from_der(&tag, &d, &dlen, &cp, &len) != 1 - || asn1_check(tag == ASN1_TAG_UTF8String) != 1 - || asn1_check(dlen == 3) != 1 - || asn1_check(memcmp(str, d, dlen) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_x509_display_text(void) -{ - uint8_t str[] = { 'a', 'b', 'c', 0 }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - int tag; - const uint8_t *d; - size_t dlen; - - if (x509_display_text_check(ASN1_TAG_UTF8String, str, 3) != 1 // str,4 will fail - || x509_display_text_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 - || x509_display_text_from_der(&tag, &d, &dlen, &cp, &len) != 1 - || asn1_check(tag == ASN1_TAG_UTF8String) != 1 - || asn1_check(dlen == 3) != 1 - || asn1_check(memcmp(str, d, dlen) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -int main(void) -{ - if (test_x509_directory_name() != 1) goto err; - if (test_x509_display_text() != 1) goto err; - printf("%s all tests passed!\n", __FILE__); - return 0; -err: - error_print(); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + +static int test_x509_directory_name(void) +{ + uint8_t str[] = { 'a', 'b', 'c', 0 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int tag; + const uint8_t *d; + size_t dlen; + + if (x509_directory_name_check_ex(ASN1_TAG_UTF8String, str, 3, 1, 10) != 1 // str,4 will fail + || x509_directory_name_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 + || x509_directory_name_from_der(&tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(tag == ASN1_TAG_UTF8String) != 1 + || asn1_check(dlen == 3) != 1 + || asn1_check(memcmp(str, d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_x509_display_text(void) +{ + uint8_t str[] = { 'a', 'b', 'c', 0 }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int tag; + const uint8_t *d; + size_t dlen; + + if (x509_display_text_check(ASN1_TAG_UTF8String, str, 3) != 1 // str,4 will fail + || x509_display_text_to_der(ASN1_TAG_UTF8String, str, 3, &p, &len) != 1 + || x509_display_text_from_der(&tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(tag == ASN1_TAG_UTF8String) != 1 + || asn1_check(dlen == 3) != 1 + || asn1_check(memcmp(str, d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_x509_directory_name() != 1) goto err; + if (test_x509_display_text() != 1) goto err; + printf("%s all tests passed!\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/x509test.c b/tests/x509test.c index b16efd30..8d37e734 100644 --- a/tests/x509test.c +++ b/tests/x509test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,393 +7,394 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int test_x509_version(void) -{ - - int tests[] = { - X509_version_v1, - X509_version_v2, - X509_version_v3, - -1, - }; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - format_print(stderr, 0, 0, "Version\n"); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (x509_explicit_version_to_der(i, tests[i], &p, &len) < 0) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - } - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - int ver; - if (x509_explicit_version_from_der(i, &ver, &cp, &len) < 0 - || asn1_check(ver == tests[i]) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s\n", x509_version_name(ver)); - } - (void)asn1_length_is_zero(len); - printf("%s() ok\n", __FUNCTION__); - return 0; -} - - -static int test_x509_validity(void) -{ - time_t not_before, not_before_; - time_t not_after, not_after_; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - size_t i; - - time(¬_before); - - format_print(stderr, 0, 0, "Validity\n"); - if (x509_validity_add_days(¬_after, not_before, 365) != 1 - || x509_validity_to_der(not_before, not_after, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - if (x509_validity_from_der(¬_before_, ¬_after_, &cp, &len) != 1 - || asn1_check(not_before == not_before_) != 1 - || asn1_check(not_after == not_after_) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return 1; - } - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_x509_attr_type_and_value(void) -{ - int oid; - int tag; - const uint8_t *d; - size_t dlen; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - format_print(stderr, 0, 0, "AttributeTypeAndValue\n"); - if (x509_attr_type_and_value_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian"), &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - if (x509_attr_type_and_value_from_der(&oid, &tag, &d, &dlen, &cp, &len) != 1 - || asn1_check(oid == OID_at_locality_name) != 1 - || asn1_check(tag == ASN1_TAG_PrintableString) != 1 - || asn1_check(dlen == strlen("Haidian")) != 1 - || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); - format_string(stderr, 0, 0, "", d, dlen); - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_x509_rdn(void) -{ - int oid; - int tag; - const uint8_t *d; - size_t dlen; - const uint8_t *more; - size_t morelen; - uint8_t buf[256]; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - - format_print(stderr, 0, 0, "RDN\n"); - if (x509_rdn_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, - (uint8_t *)"Haidian", strlen("Haidian"), NULL, 0, &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "", buf, len); - if (x509_rdn_from_der(&oid, &tag, &d, &dlen, &more, &morelen, &cp, &len) != 1 - || asn1_check(oid == OID_at_locality_name) != 1 - || asn1_check(tag == ASN1_TAG_PrintableString) != 1 - || asn1_check(dlen == strlen("Haidian")) != 1 - || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 - || asn1_check(more == NULL) != 1 - || asn1_check(morelen == 0) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); - format_string(stderr, 0, 0, "", d, dlen); - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int test_x509_name(void) -{ - int err = 0; - uint8_t name[512]; - size_t namelen = 0; - uint8_t buf[1024]; - const uint8_t *cp = buf; - uint8_t *p = buf; - size_t len = 0; - - if (x509_name_add_country_name(name, &namelen, sizeof(name), "CN") != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - || x509_name_add_locality_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - || x509_name_add_state_or_province_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - || x509_name_add_organization_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - || x509_name_add_organizational_unit_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - || x509_name_add_common_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1 - || format_bytes(stderr, 0, 4, "", name, namelen) > 2 - ) { - error_print(); - return 1; - } - format_bytes(stdout, 0, 0, "der ", name, namelen); - x509_name_print(stdout, 0, 0, "Name", name, namelen); - return 0; -} - -static int test_x509_public_key_info(void) -{ - int err = 0; - SM2_KEY sm2_key; - SM2_KEY pub_key; - uint8_t buf[256]; - const uint8_t *cp = buf; - uint8_t *p = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - - if (sm2_key_generate(&sm2_key) != 1 - || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 - || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return 1; - } - x509_public_key_info_print(stdout, 0, 0, "PublicKeyInfo", d, dlen); - if (sm2_key_generate(&sm2_key) != 1 - || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 - || x509_public_key_info_from_der(&pub_key, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return 1; - } - sm2_public_key_print(stdout, 0, 8, "ECPublicKey", &pub_key); - - printf("%s() ok\n", __FUNCTION__); - return 0; -} - -static int set_x509_name(uint8_t *name, size_t *namelen, size_t maxlen) -{ - *namelen = 0; - if (x509_name_add_country_name(name, namelen, maxlen, "CN") != 1 - || x509_name_add_locality_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 - || x509_name_add_state_or_province_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 - || x509_name_add_organization_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 - || x509_name_add_organizational_unit_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 - || x509_name_add_common_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1) { - error_print(); - return -1; - } - return 1; -} - -static int test_x509_tbs_cert(void) -{ - uint8_t serial[20] = { 0x01, 0x00 }; - size_t serial_len; - uint8_t issuer[256]; - size_t issuer_len = 0; - time_t not_before, not_after; - uint8_t subject[256]; - size_t subject_len = 0; - SM2_KEY sm2_key; - uint8_t buf[1024] = {0}; - uint8_t *p = buf; - const uint8_t *cp = buf; - size_t len = 0; - const uint8_t *d; - size_t dlen; - - set_x509_name(issuer, &issuer_len, sizeof(issuer)); - time(¬_before); - x509_validity_add_days(¬_after, not_before, 365); - set_x509_name(subject, &subject_len, sizeof(subject)); - sm2_key_generate(&sm2_key); - - if (x509_tbs_cert_to_der( - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - issuer, issuer_len, - not_before, not_after, - subject, subject_len, - &sm2_key, - NULL, 0, - NULL, 0, - NULL, 0, - &p, &len) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 0, "tbs_cert", buf, len); - if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 - || asn1_length_is_zero(len) != 1) { - error_print(); - return -1; - } - x509_tbs_cert_print(stderr, 0, 4, "TBSCertificate", d, dlen); - - return 0; -} - -static int test_x509_cert_get(const uint8_t *cert, size_t certlen) -{ - const uint8_t *serial; - size_t serial_len; - const uint8_t *issuer; - size_t issuer_len; - const uint8_t *subject; - size_t subject_len; - SM2_KEY public_key; - - if (x509_cert_get_issuer_and_serial_number(cert, certlen, &issuer, &issuer_len, &serial, &serial_len) != 1 - || x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "SerialNumber", serial, serial_len); - x509_name_print(stderr, 0, 4, "Issuer", issuer, issuer_len); - x509_name_print(stderr, 0, 4, "Subject", subject, subject_len); - sm2_public_key_print(stderr, 0, 4, "SubjectPublicKey", &public_key); - return 0; -} - -static int test_x509_cert(void) -{ - uint8_t serial[20] = { 0x01, 0x00 }; - size_t serial_len; - uint8_t issuer[256]; - size_t issuer_len = 0; - time_t not_before, not_after; - uint8_t subject[256]; - size_t subject_len = 0; - SM2_KEY sm2_key; - uint8_t cert[1024] = {0}; - uint8_t *p = cert; - const uint8_t *cp = cert; - size_t certlen = 0; - - set_x509_name(issuer, &issuer_len, sizeof(issuer)); - time(¬_before); - x509_validity_add_days(¬_after, not_before, 365); - set_x509_name(subject, &subject_len, sizeof(subject)); - sm2_key_generate(&sm2_key); - - if (x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - issuer, issuer_len, - not_before, not_after, - subject, subject_len, - &sm2_key, - NULL, 0, - NULL, 0, - NULL, 0, - &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 4, "cert", cert, certlen); - x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); - - if (x509_cert_verify(cert, certlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - error_print(); - return -1; - } - printf("x509_cert_verify() success\n"); - - test_x509_cert_get(cert, certlen); - - - FILE *fp; - - if (!(fp = fopen("cert.pem", "w"))) { - error_print(); - return -1; - } - - x509_cert_to_pem(cert, certlen, fp); - x509_cert_to_pem(cert, certlen, stderr); - fclose(fp); - - - if (!(fp = fopen("cert.pem", "r"))) { - error_print(); - return -1; - } - - memset(cert, 0, sizeof(cert)); - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) != 1) { - error_print(); - return -1; - } - x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); - - return 0; -} - -int main(void) -{ - int err = 0; - err += test_x509_version(); - err += test_x509_validity(); - err += test_x509_attr_type_and_value(); - err += test_x509_rdn(); - err += test_x509_name(); - err += test_x509_public_key_info(); - err += test_x509_tbs_cert(); - err += test_x509_cert(); - return err; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_x509_version(void) +{ + + int tests[] = { + X509_version_v1, + X509_version_v2, + X509_version_v3, + -1, + }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + format_print(stderr, 0, 0, "Version\n"); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (x509_explicit_version_to_der(i, tests[i], &p, &len) < 0) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + int ver; + if (x509_explicit_version_from_der(i, &ver, &cp, &len) < 0 + || asn1_check(ver == tests[i]) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s\n", x509_version_name(ver)); + } + (void)asn1_length_is_zero(len); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + + +static int test_x509_validity(void) +{ + time_t not_before, not_before_; + time_t not_after, not_after_; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + size_t i; + + time(¬_before); + + format_print(stderr, 0, 0, "Validity\n"); + if (x509_validity_add_days(¬_after, not_before, 365) != 1 + || x509_validity_to_der(not_before, not_after, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_validity_from_der(¬_before_, ¬_after_, &cp, &len) != 1 + || asn1_check(not_before == not_before_) != 1 + || asn1_check(not_after == not_after_) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; + } + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_attr_type_and_value(void) +{ + int oid; + int tag; + const uint8_t *d; + size_t dlen; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0, 0, "AttributeTypeAndValue\n"); + if (x509_attr_type_and_value_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian"), &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_attr_type_and_value_from_der(&oid, &tag, &d, &dlen, &cp, &len) != 1 + || asn1_check(oid == OID_at_locality_name) != 1 + || asn1_check(tag == ASN1_TAG_PrintableString) != 1 + || asn1_check(dlen == strlen("Haidian")) != 1 + || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); + format_string(stderr, 0, 0, "", d, dlen); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_rdn(void) +{ + int oid; + int tag; + const uint8_t *d; + size_t dlen; + const uint8_t *more; + size_t morelen; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + format_print(stderr, 0, 0, "RDN\n"); + if (x509_rdn_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, + (uint8_t *)"Haidian", strlen("Haidian"), NULL, 0, &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "", buf, len); + if (x509_rdn_from_der(&oid, &tag, &d, &dlen, &more, &morelen, &cp, &len) != 1 + || asn1_check(oid == OID_at_locality_name) != 1 + || asn1_check(tag == ASN1_TAG_PrintableString) != 1 + || asn1_check(dlen == strlen("Haidian")) != 1 + || asn1_check(memcmp("Haidian", d, dlen) == 0) != 1 + || asn1_check(more == NULL) != 1 + || asn1_check(morelen == 0) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag)); + format_string(stderr, 0, 0, "", d, dlen); + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int test_x509_name(void) +{ + int err = 0; + uint8_t name[512]; + size_t namelen = 0; + uint8_t buf[1024]; + const uint8_t *cp = buf; + uint8_t *p = buf; + size_t len = 0; + + if (x509_name_add_country_name(name, &namelen, sizeof(name), "CN") != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_locality_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_state_or_province_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_organization_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_organizational_unit_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + || x509_name_add_common_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1 + || format_bytes(stderr, 0, 4, "", name, namelen) > 2 + ) { + error_print(); + return 1; + } + format_bytes(stdout, 0, 0, "der ", name, namelen); + x509_name_print(stdout, 0, 0, "Name", name, namelen); + return 0; +} + +static int test_x509_public_key_info(void) +{ + int err = 0; + SM2_KEY sm2_key; + SM2_KEY pub_key; + uint8_t buf[256]; + const uint8_t *cp = buf; + uint8_t *p = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + + if (sm2_key_generate(&sm2_key) != 1 + || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 + || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; + } + x509_public_key_info_print(stdout, 0, 0, "PublicKeyInfo", d, dlen); + if (sm2_key_generate(&sm2_key) != 1 + || x509_public_key_info_to_der(&sm2_key, &p, &len) != 1 + || x509_public_key_info_from_der(&pub_key, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return 1; + } + sm2_public_key_print(stdout, 0, 8, "ECPublicKey", &pub_key); + + printf("%s() ok\n", __FUNCTION__); + return 0; +} + +static int set_x509_name(uint8_t *name, size_t *namelen, size_t maxlen) +{ + *namelen = 0; + if (x509_name_add_country_name(name, namelen, maxlen, "CN") != 1 + || x509_name_add_locality_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1 + || x509_name_add_state_or_province_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1 + || x509_name_add_organization_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1 + || x509_name_add_organizational_unit_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1 + || x509_name_add_common_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1) { + error_print(); + return -1; + } + return 1; +} + +static int test_x509_tbs_cert(void) +{ + uint8_t serial[20] = { 0x01, 0x00 }; + size_t serial_len; + uint8_t issuer[256]; + size_t issuer_len = 0; + time_t not_before, not_after; + uint8_t subject[256]; + size_t subject_len = 0; + SM2_KEY sm2_key; + uint8_t buf[1024] = {0}; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + const uint8_t *d; + size_t dlen; + + set_x509_name(issuer, &issuer_len, sizeof(issuer)); + time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + set_x509_name(subject, &subject_len, sizeof(subject)); + sm2_key_generate(&sm2_key); + + if (x509_tbs_cert_to_der( + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + issuer, issuer_len, + not_before, not_after, + subject, subject_len, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &p, &len) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 0, "tbs_cert", buf, len); + if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1 + || asn1_length_is_zero(len) != 1) { + error_print(); + return -1; + } + x509_tbs_cert_print(stderr, 0, 4, "TBSCertificate", d, dlen); + + return 0; +} + +static int test_x509_cert_get(const uint8_t *cert, size_t certlen) +{ + const uint8_t *serial; + size_t serial_len; + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *subject; + size_t subject_len; + SM2_KEY public_key; + + if (x509_cert_get_issuer_and_serial_number(cert, certlen, &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "SerialNumber", serial, serial_len); + x509_name_print(stderr, 0, 4, "Issuer", issuer, issuer_len); + x509_name_print(stderr, 0, 4, "Subject", subject, subject_len); + sm2_public_key_print(stderr, 0, 4, "SubjectPublicKey", &public_key); + return 0; +} + +static int test_x509_cert(void) +{ + uint8_t serial[20] = { 0x01, 0x00 }; + size_t serial_len; + uint8_t issuer[256]; + size_t issuer_len = 0; + time_t not_before, not_after; + uint8_t subject[256]; + size_t subject_len = 0; + SM2_KEY sm2_key; + uint8_t cert[1024] = {0}; + uint8_t *p = cert; + const uint8_t *cp = cert; + size_t certlen = 0; + + set_x509_name(issuer, &issuer_len, sizeof(issuer)); + time(¬_before); + x509_validity_add_days(¬_after, not_before, 365); + set_x509_name(subject, &subject_len, sizeof(subject)); + sm2_key_generate(&sm2_key); + + if (x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + issuer, issuer_len, + not_before, not_after, + subject, subject_len, + &sm2_key, + NULL, 0, + NULL, 0, + NULL, 0, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 4, "cert", cert, certlen); + x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); + + if (x509_cert_verify(cert, certlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + error_print(); + return -1; + } + printf("x509_cert_verify() success\n"); + + test_x509_cert_get(cert, certlen); + + + FILE *fp; + + if (!(fp = fopen("cert.pem", "w"))) { + error_print(); + return -1; + } + + x509_cert_to_pem(cert, certlen, fp); + x509_cert_to_pem(cert, certlen, stderr); + fclose(fp); + + + if (!(fp = fopen("cert.pem", "r"))) { + error_print(); + return -1; + } + + memset(cert, 0, sizeof(cert)); + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) != 1) { + error_print(); + return -1; + } + x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen); + + return 0; +} + +int main(void) +{ + int err = 0; + err += test_x509_version(); + err += test_x509_validity(); + err += test_x509_attr_type_and_value(); + err += test_x509_rdn(); + err += test_x509_name(); + err += test_x509_public_key_info(); + err += test_x509_tbs_cert(); + err += test_x509_cert(); + return err; +} diff --git a/tests/zuctest.c b/tests/zuctest.c index e2bd1b35..cb8dcea5 100644 --- a/tests/zuctest.c +++ b/tests/zuctest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,477 +7,478 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - - -static void bswap_buf(uint32_t *buf, size_t nwords) -{ - size_t i; - for (i = 0; i < nwords; i++) { - uint32_t a = buf[i]; - buf[i] = (a >> 24) | ((a >> 8) & 0xff00) | - ((a << 8) & 0xff0000) | (a << 24); - } -} - -int zuc_test(void) -{ - int err = 0; - int i; - - unsigned char key[][16] = { - {0x00,0x00,0x00,0x00,0x00,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}, - {0x3d,0x4c,0x4b,0xe9,0x6a,0x82,0xfd,0xae,0xb5,0x8f,0x64,0x1d,0xb1,0x7b,0x45,0x5b}, - }; - unsigned char iv[][16] = { - {0x00,0x00,0x00,0x00,0x00,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}, - {0x84,0x31,0x9a,0xa8,0xde,0x69,0x15,0xca,0x1f,0x6b,0xda,0x6b,0xfb,0xd8,0xc7,0x66}, - }; - uint32_t ciphertext[][2] = { - {0x27bede74, 0x018082da}, - {0x0657cfa0, 0x7096398b}, - {0x14f1c272, 0x3279c419}, - }; - - for (i = 0; i < 3; i++) { - ZUC_STATE zuc = {{0}}; - uint32_t buf[3] = {0}; - zuc_init(&zuc, key[i], iv[i]); - zuc_generate_keystream(&zuc, 2, buf); - if (buf[0] != ciphertext[i][0] || buf[1] != ciphertext[i][1]) { - fprintf(stderr, "error generating ZUC key stream on test vector %d\n", i); - err++; - } else { - fprintf(stderr, "zuc test %d ok\n", i); - } - } - - return err; -} - -/* test vector from GM/T 0001.2-2012 */ -static int zuc_eea_test(void) -{ - int err = 0; - unsigned char key[][16] = { - {0x17, 0x3d, 0x14, 0xba, 0x50, 0x03, 0x73, 0x1d, - 0x7a, 0x60, 0x04, 0x94, 0x70, 0xf0, 0x0a, 0x29}, - {0xe5, 0xbd, 0x3e, 0xa0, 0xeb, 0x55, 0xad, 0xe8, - 0x66, 0xc6, 0xac, 0x58, 0xbd, 0x54, 0x30, 0x2a}, - {0xe1, 0x3f, 0xed, 0x21, 0xb4, 0x6e, 0x4e, 0x7e, - 0xc3, 0x12, 0x53, 0xb2, 0xbb, 0x17, 0xb3, 0xe0}, - }; - ZUC_UINT32 count[] = {0x66035492, 0x56823, 0x2738cdaa}; - ZUC_UINT5 bearer[] = {0x0f, 0x18, 0x1a}; - ZUC_BIT direction[] = {0, 1, 0}; - ZUC_UINT32 ibs0[] = { - 0x6cf65340, 0x735552ab, 0x0c9752fa, 0x6f9025fe, - 0x0bd675d9, 0x005875b2, 0x00000000, - }; - ZUC_UINT32 ibs1[] = { - 0x14a8ef69, 0x3d678507, 0xbbe7270a, 0x7f67ff50, - 0x06c3525b, 0x9807e467, 0xc4e56000, 0xba338f5d, - 0x42955903, 0x67518222, 0x46c80d3b, 0x38f07f4b, - 0xe2d8ff58, 0x05f51322, 0x29bde93b, 0xbbdcaf38, - 0x2bf1ee97, 0x2fbf9977, 0xbada8945, 0x847a2a6c, - 0x9ad34a66, 0x7554e04d, 0x1f7fa2c3, 0x3241bd8f, - 0x01ba220d, - }; - ZUC_UINT32 ibs2[] = { - 0x8d74e20d, 0x54894e06, 0xd3cb13cb, 0x3933065e, - 0x8674be62, 0xadb1c72b, 0x3a646965, 0xab63cb7b, - 0x7854dfdc, 0x27e84929, 0xf49c64b8, 0x72a490b1, - 0x3f957b64, 0x827e71f4, 0x1fbd4269, 0xa42c97f8, - 0x24537027, 0xf86e9f4a, 0xd82d1df4, 0x51690fdd, - 0x98b6d03f, 0x3a0ebe3a, 0x312d6b84, 0x0ba5a182, - 0x0b2a2c97, 0x09c090d2, 0x45ed267c, 0xf845ae41, - 0xfa975d33, 0x33ac3009, 0xfd40eba9, 0xeb5b8857, - 0x14b768b6, 0x97138baf, 0x21380eca, 0x49f644d4, - 0x8689e421, 0x5760b906, 0x739f0d2b, 0x3f091133, - 0xca15d981, 0xcbe401ba, 0xf72d05ac, 0xe05cccb2, - 0xd297f4ef, 0x6a5f58d9, 0x1246cfa7, 0x7215b892, - 0xab441d52, 0x78452795, 0xccb7f5d7, 0x9057a1c4, - 0xf77f80d4, 0x6db2033c, 0xb79bedf8, 0xe60551ce, - 0x10c667f6, 0x2a97abaf, 0xabbcd677, 0x2018df96, - 0xa282ea73, 0x7ce2cb33, 0x1211f60d, 0x5354ce78, - 0xf9918d9c, 0x206ca042, 0xc9b62387, 0xdd709604, - 0xa50af16d, 0x8d35a890, 0x6be484cf, 0x2e74a928, - 0x99403643, 0x53249b27, 0xb4c9ae29, 0xeddfc7da, - 0x6418791a, 0x4e7baa06, 0x60fa6451, 0x1f2d685c, - 0xc3a5ff70, 0xe0d2b742, 0x92e3b8a0, 0xcd6b04b1, - 0xc790b8ea, 0xd2703708, 0x540dea2f, 0xc09c3da7, - 0x70f65449, 0xc84d817a, 0x4f551055, 0xe19ab850, - 0x18a0028b, 0x71a144d9, 0x6791e9a3, 0x57793350, - 0x4eee0060, 0x340c69d2, 0x74e1bf9d, 0x805dcbcc, - 0x1a6faa97, 0x6800b6ff, 0x2b671dc4, 0x63652fa8, - 0xa33ee509, 0x74c1c21b, 0xe01eabb2, 0x16743026, - 0x9d72ee51, 0x1c9dde30, 0x797c9a25, 0xd86ce74f, - 0x5b961be5, 0xfdfb6807, 0x814039e7, 0x137636bd, - 0x1d7fa9e0, 0x9efd2007, 0x505906a5, 0xac45dfde, - 0xed7757bb, 0xee745749, 0xc2963335, 0x0bee0ea6, - 0xf409df45, 0x80160000, - }; - ZUC_UINT32 obs0[] = { - 0xa6c85fc6, 0x6afb8533, 0xaafc2518, 0xdfe78494, - 0x0ee1e4b0, 0x30238cc8, 0x00000000, - }; - ZUC_UINT32 obs1[] = { - 0x131d43e0, 0xdea1be5c, 0x5a1bfd97, 0x1d852cbf, - 0x712d7b4f, 0x57961fea, 0x3208afa8, 0xbca433f4, - 0x56ad09c7, 0x417e58bc, 0x69cf8866, 0xd1353f74, - 0x865e8078, 0x1d202dfb, 0x3ecff7fc, 0xbc3b190f, - 0xe82a204e, 0xd0e350fc, 0x0f6f2613, 0xb2f2bca6, - 0xdf5a473a, 0x57a4a00d, 0x985ebad8, 0x80d6f238, - 0x64a07b01, - }; - ZUC_UINT32 obs2[] = { - 0x94eaa4aa, 0x30a57137, 0xddf09b97, 0xb25618a2, - 0x0a13e2f1, 0x0fa5bf81, 0x61a879cc, 0x2ae797a6, - 0xb4cf2d9d, 0xf31debb9, 0x905ccfec, 0x97de605d, - 0x21c61ab8, 0x531b7f3c, 0x9da5f039, 0x31f8a064, - 0x2de48211, 0xf5f52ffe, 0xa10f392a, 0x04766998, - 0x5da454a2, 0x8f080961, 0xa6c2b62d, 0xaa17f33c, - 0xd60a4971, 0xf48d2d90, 0x9394a55f, 0x48117ace, - 0x43d708e6, 0xb77d3dc4, 0x6d8bc017, 0xd4d1abb7, - 0x7b7428c0, 0x42b06f2f, 0x99d8d07c, 0x9879d996, - 0x00127a31, 0x985f1099, 0xbbd7d6c1, 0x519ede8f, - 0x5eeb4a61, 0x0b349ac0, 0x1ea23506, 0x91756bd1, - 0x05c974a5, 0x3eddb35d, 0x1d4100b0, 0x12e522ab, - 0x41f4c5f2, 0xfde76b59, 0xcb8b96d8, 0x85cfe408, - 0x0d1328a0, 0xd636cc0e, 0xdc05800b, 0x76acca8f, - 0xef672084, 0xd1f52a8b, 0xbd8e0993, 0x320992c7, - 0xffbae17c, 0x408441e0, 0xee883fc8, 0xa8b05e22, - 0xf5ff7f8d, 0x1b48c74c, 0x468c467a, 0x028f09fd, - 0x7ce91109, 0xa570a2d5, 0xc4d5f4fa, 0x18c5dd3e, - 0x4562afe2, 0x4ef77190, 0x1f59af64, 0x5898acef, - 0x088abae0, 0x7e92d52e, 0xb2de5504, 0x5bb1b7c4, - 0x164ef2d7, 0xa6cac15e, 0xeb926d7e, 0xa2f08b66, - 0xe1f759f3, 0xaee44614, 0x725aa3c7, 0x482b3084, - 0x4c143ff8, 0x7b53f1e5, 0x83c50125, 0x7dddd096, - 0xb81268da, 0xa303f172, 0x34c23335, 0x41f0bb8e, - 0x190648c5, 0x807c866d, 0x71932286, 0x09adb948, - 0x686f7de2, 0x94a802cc, 0x38f7fe52, 0x08f5ea31, - 0x96d0167b, 0x9bdd02f0, 0xd2a5221c, 0xa508f893, - 0xaf5c4b4b, 0xb9f4f520, 0xfd84289b, 0x3dbe7e61, - 0x497a7e2a, 0x584037ea, 0x637b6981, 0x127174af, - 0x57b471df, 0x4b2768fd, 0x79c1540f, 0xb3edf2ea, - 0x22cb69be, 0xc0cf8d93, 0x3d9c6fdd, 0x645e8505, - 0x91cca3d6, 0x2c0cc000, - }; - ZUC_UINT32 *ibs[] = {ibs0, ibs1, ibs2}; - ZUC_UINT32 *obs[] = {obs0, obs1, obs2}; - size_t bits[] = {0xc1, 0x320, 0xfb3}; - ZUC_UINT32 buf[sizeof(obs2)/4]; - size_t i; - - for (i = 0; i < sizeof(key)/sizeof(key[i]); i++) { - zuc_eea_encrypt(ibs[i], buf, bits[i], key[i], count[i], bearer[i], direction[i]); - if (memcmp(buf, obs[i], (bits[i] + 31)/32) != 0) { - printf("zuc eea test %zu failed\n", i); - err++; - } else { - printf("zuc eea test %zu ok\n", i); - } - } - - return err; -} - -/* test vector from GM/T 0001.3-2012 */ -static int zuc_eia_test(void) -{ - int err = 0; - unsigned char key[][16] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, - 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a}, - {0x6b, 0x8b, 0x08, 0xee, 0x79, 0xe0, 0xb5, 0x98, - 0x2d, 0x6d, 0x12, 0x8e, 0xa9, 0xf2, 0x20, 0xcb}, - }; - ZUC_UINT32 count[] = {0, 0xa94059daU, 0x561eb2ddU}; - ZUC_UINT5 bearer[] = {0, 0x0a, 0x1c}; - ZUC_BIT direction[] = {0, 1, 0}; - ZUC_UINT32 mesg0[] = {0}; - ZUC_UINT32 mesg1[] = { - 0x983b41d4, 0x7d780c9e, 0x1ad11d7e, 0xb70391b1, - 0xde0b35da, 0x2dc62f83, 0xe7b78d63, 0x06ca0ea0, - 0x7e941b7b, 0xe91348f9, 0xfcb170e2, 0x217fecd9, - 0x7f9f68ad, 0xb16e5d7d, 0x21e569d2, 0x80ed775c, - 0xebde3f40, 0x93c53881, 0x00000000, - }; - ZUC_UINT32 mesg2[] = { - 0x5bad7247, 0x10ba1c56, 0xd5a315f8, 0xd40f6e09, - 0x3780be8e, 0x8de07b69, 0x92432018, 0xe08ed96a, - 0x5734af8b, 0xad8a575d, 0x3a1f162f, 0x85045cc7, - 0x70925571, 0xd9f5b94e, 0x454a77c1, 0x6e72936b, - 0xf016ae15, 0x7499f054, 0x3b5d52ca, 0xa6dbeab6, - 0x97d2bb73, 0xe41b8075, 0xdce79b4b, 0x86044f66, - 0x1d4485a5, 0x43dd7860, 0x6e0419e8, 0x059859d3, - 0xcb2b67ce, 0x0977603f, 0x81ff839e, 0x33185954, - 0x4cfbc8d0, 0x0fef1a4c, 0x8510fb54, 0x7d6b06c6, - 0x11ef44f1, 0xbce107cf, 0xa45a06aa, 0xb360152b, - 0x28dc1ebe, 0x6f7fe09b, 0x0516f9a5, 0xb02a1bd8, - 0x4bb0181e, 0x2e89e19b, 0xd8125930, 0xd178682f, - 0x3862dc51, 0xb636f04e, 0x720c47c3, 0xce51ad70, - 0xd94b9b22, 0x55fbae90, 0x6549f499, 0xf8c6d399, - 0x47ed5e5d, 0xf8e2def1, 0x13253e7b, 0x08d0a76b, - 0x6bfc68c8, 0x12f375c7, 0x9b8fe5fd, 0x85976aa6, - 0xd46b4a23, 0x39d8ae51, 0x47f680fb, 0xe70f978b, - 0x38effd7b, 0x2f7866a2, 0x2554e193, 0xa94e98a6, - 0x8b74bd25, 0xbb2b3f5f, 0xb0a5fd59, 0x887f9ab6, - 0x8159b717, 0x8d5b7b67, 0x7cb546bf, 0x41eadca2, - 0x16fc1085, 0x0128f8bd, 0xef5c8d89, 0xf96afa4f, - 0xa8b54885, 0x565ed838, 0xa950fee5, 0xf1c3b0a4, - 0xf6fb71e5, 0x4dfd169e, 0x82cecc72, 0x66c850e6, - 0x7c5ef0ba, 0x960f5214, 0x060e71eb, 0x172a75fc, - 0x1486835c, 0xbea65344, 0x65b055c9, 0x6a72e410, - 0x52241823, 0x25d83041, 0x4b40214d, 0xaa8091d2, - 0xe0fb010a, 0xe15c6de9, 0x0850973b, 0xdf1e423b, - 0xe148a237, 0xb87a0c9f, 0x34d4b476, 0x05b803d7, - 0x43a86a90, 0x399a4af3, 0x96d3a120, 0x0a62f3d9, - 0x507962e8, 0xe5bee6d3, 0xda2bb3f7, 0x237664ac, - 0x7a292823, 0x900bc635, 0x03b29e80, 0xd63f6067, - 0xbf8e1716, 0xac25beba, 0x350deb62, 0xa99fe031, - 0x85eb4f69, 0x937ecd38, 0x7941fda5, 0x44ba67db, - 0x09117749, 0x38b01827, 0xbcc69c92, 0xb3f772a9, - 0xd2859ef0, 0x03398b1f, 0x6bbad7b5, 0x74f7989a, - 0x1d10b2df, 0x798e0dbf, 0x30d65874, 0x64d24878, - 0xcd00c0ea, 0xee8a1a0c, 0xc753a279, 0x79e11b41, - 0xdb1de3d5, 0x038afaf4, 0x9f5c682c, 0x3748d8a3, - 0xa9ec54e6, 0xa371275f, 0x1683510f, 0x8e4f9093, - 0x8f9ab6e1, 0x34c2cfdf, 0x4841cba8, 0x8e0cff2b, - 0x0bcc8e6a, 0xdcb71109, 0xb5198fec, 0xf1bb7e5c, - 0x531aca50, 0xa56a8a3b, 0x6de59862, 0xd41fa113, - 0xd9cd9578, 0x08f08571, 0xd9a4bb79, 0x2af271f6, - 0xcc6dbb8d, 0xc7ec36e3, 0x6be1ed30, 0x8164c31c, - 0x7c0afc54, 0x1c000000, - }; - ZUC_UINT32 *mesg[] = {mesg0, mesg1, mesg2}; - size_t bits[] = {1, 0x241, 0x1626}; - ZUC_UINT32 mac[] = {0xc8a9595eU, 0xfae8ff0bU, 0x0ca12792U}; - size_t i; - - bswap_buf(mesg0, sizeof(mesg0)/sizeof(mesg0[0])); - bswap_buf(mesg1, sizeof(mesg1)/sizeof(mesg1[0])); - bswap_buf(mesg2, sizeof(mesg2)/sizeof(mesg2[0])); - - for (i = 0; i < sizeof(key)/sizeof(key[0]); i++) { - ZUC_UINT32 T; - T = zuc_eia_generate_mac(mesg[i], bits[i], key[i], - count[i], bearer[i], direction[i]); - if (T != mac[i]) { - printf("zuc eia test %zu failed\n", i); - err++; - } else { - printf("zuc eia test %zu ok\n", i); - } - } - - return err; -} - -/* from ZUC256 draft */ -int zuc256_test(void) -{ - int err = 0; - int i; - - unsigned char key[][32] = { - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,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, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} - }; - unsigned char iv[][23] = { - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,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, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff}, - }; - uint32_t ciphertext[][20] = { - {0x58d03ad6,0x2e032ce2,0xdafc683a,0x39bdcb03,0x52a2bc67, - 0xf1b7de74,0x163ce3a1,0x01ef5558,0x9639d75b,0x95fa681b, - 0x7f090df7,0x56391ccc,0x903b7612,0x744d544c,0x17bc3fad, - 0x8b163b08,0x21787c0b,0x97775bb8,0x4943c6bb,0xe8ad8afd}, - {0x3356cbae,0xd1a1c18b,0x6baa4ffe,0x343f777c,0x9e15128f, - 0x251ab65b,0x949f7b26,0xef7157f2,0x96dd2fa9,0xdf95e3ee, - 0x7a5be02e,0xc32ba585,0x505af316,0xc2f9ded2,0x7cdbd935, - 0xe441ce11,0x15fd0a80,0xbb7aef67,0x68989416,0xb8fac8c2} - }; - - for (i = 0; i < sizeof(key)/sizeof(key[0]); i++) { - ZUC_STATE zuc_key; - uint32_t buf[20] = {0}; - - zuc256_init(&zuc_key, key[i], iv[i]); - zuc_generate_keystream(&zuc_key, 20, buf); - - if (memcmp(buf, ciphertext[i], 20) != 0) { - printf("zuc256 test %d failed\n", i); - err++; - } else { - printf("zuc256 test %d ok\n", i); - } - } - - return err; -} - -int zuc256_mac_test(void) -{ - int err = 0; - unsigned char key[][32] = { - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,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, - 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} - }; - unsigned char iv[][23] = { - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,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, - 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}, - }; - unsigned char msg[][50] = { - /* 400 zero bits */ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - /* 4000 bits */ - {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, - /* 400 zero bits */ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - /* 4000 bits */ - {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, - }; - unsigned int msg_num[] = { - 1, - 10, - 1, - 10 - }; - unsigned int tag32[][1] = { - {0x9b972a74}, - {0x8754f5cf}, - {0x1f3079b4}, - {0x5c7c8b88}, - }; - unsigned int tag64[][2] = { - {0x673e5499,0x0034d38c}, - {0x130dc225,0xe72240cc}, - {0x8c71394d,0x39957725}, - {0xea1dee54,0x4bb6223b}, - }; - unsigned int tag128[][4] = { - {0xd85e54bb,0xcb960096,0x7084c952,0xa1654b26}, - {0xdf1e8307,0xb31cc62b,0xeca1ac6f,0x8190c22f}, - {0xa35bb274,0xb567c48b,0x28319f11,0x1af34fbd}, - {0x3a83b554,0xbe408ca5,0x494124ed,0x9d473205}, - }; - int i, j; - - bswap_buf((uint32_t *)tag32, sizeof(tag32)/4); - bswap_buf((uint32_t *)tag64, sizeof(tag64)/4); - bswap_buf((uint32_t *)tag128, sizeof(tag128)/4); - - for (i = 0; i < 4; i++) { - ZUC256_MAC_CTX ctx; - unsigned char mac[16]; - - zuc256_mac_init(&ctx, key[i], iv[i], 32); - for (j = 0; j < msg_num[i]; j++) { - zuc256_mac_update(&ctx, msg[i], 50); - } - zuc256_mac_finish(&ctx, NULL, 0, mac); - if (memcmp(mac, tag32[i], 4) != 0) { - printf("zuc256 mac test %d 32-bit failed\n", i); - err++; - } else { - printf("zuc256 mac test %d 32-bit ok\n", i); - } - - zuc256_mac_init(&ctx, key[i], iv[i], 64); - for (j = 0; j < msg_num[i]; j++) { - zuc256_mac_update(&ctx, msg[i], 50); - } - zuc256_mac_finish(&ctx, NULL, 0, mac); - if (memcmp(mac, tag64[i], 8) != 0) { - printf("zuc256 mac test %d 64-bit failed\n", i); - err++; - } else { - printf("zuc256 mac test %d 64-bit ok\n", i); - } - - zuc256_mac_init(&ctx, key[i], iv[i], 128); - for (j = 0; j < msg_num[i]; j++) { - zuc256_mac_update(&ctx, msg[i], 50); - } - zuc256_mac_finish(&ctx, NULL, 0, mac); - if (memcmp(mac, tag128[i], 16) != 0) { - printf("zuc256 mac test %d 128-bit failed\n", i); - err++; - } else { - printf("zuc256 mac test %d 128-bit ok\n", i); - } - } - - return err; -} - -int main(void) -{ - int err = 0; - err += zuc_test(); - err += zuc_eea_test(); - err += zuc_eia_test(); - err += zuc256_test(); - err += zuc256_mac_test(); - return err; -} + + +#include +#include +#include +#include + + +static void bswap_buf(uint32_t *buf, size_t nwords) +{ + size_t i; + for (i = 0; i < nwords; i++) { + uint32_t a = buf[i]; + buf[i] = (a >> 24) | ((a >> 8) & 0xff00) | + ((a << 8) & 0xff0000) | (a << 24); + } +} + +int zuc_test(void) +{ + int err = 0; + int i; + + unsigned char key[][16] = { + {0x00,0x00,0x00,0x00,0x00,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}, + {0x3d,0x4c,0x4b,0xe9,0x6a,0x82,0xfd,0xae,0xb5,0x8f,0x64,0x1d,0xb1,0x7b,0x45,0x5b}, + }; + unsigned char iv[][16] = { + {0x00,0x00,0x00,0x00,0x00,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}, + {0x84,0x31,0x9a,0xa8,0xde,0x69,0x15,0xca,0x1f,0x6b,0xda,0x6b,0xfb,0xd8,0xc7,0x66}, + }; + uint32_t ciphertext[][2] = { + {0x27bede74, 0x018082da}, + {0x0657cfa0, 0x7096398b}, + {0x14f1c272, 0x3279c419}, + }; + + for (i = 0; i < 3; i++) { + ZUC_STATE zuc = {{0}}; + uint32_t buf[3] = {0}; + zuc_init(&zuc, key[i], iv[i]); + zuc_generate_keystream(&zuc, 2, buf); + if (buf[0] != ciphertext[i][0] || buf[1] != ciphertext[i][1]) { + fprintf(stderr, "error generating ZUC key stream on test vector %d\n", i); + err++; + } else { + fprintf(stderr, "zuc test %d ok\n", i); + } + } + + return err; +} + +/* test vector from GM/T 0001.2-2012 */ +static int zuc_eea_test(void) +{ + int err = 0; + unsigned char key[][16] = { + {0x17, 0x3d, 0x14, 0xba, 0x50, 0x03, 0x73, 0x1d, + 0x7a, 0x60, 0x04, 0x94, 0x70, 0xf0, 0x0a, 0x29}, + {0xe5, 0xbd, 0x3e, 0xa0, 0xeb, 0x55, 0xad, 0xe8, + 0x66, 0xc6, 0xac, 0x58, 0xbd, 0x54, 0x30, 0x2a}, + {0xe1, 0x3f, 0xed, 0x21, 0xb4, 0x6e, 0x4e, 0x7e, + 0xc3, 0x12, 0x53, 0xb2, 0xbb, 0x17, 0xb3, 0xe0}, + }; + ZUC_UINT32 count[] = {0x66035492, 0x56823, 0x2738cdaa}; + ZUC_UINT5 bearer[] = {0x0f, 0x18, 0x1a}; + ZUC_BIT direction[] = {0, 1, 0}; + ZUC_UINT32 ibs0[] = { + 0x6cf65340, 0x735552ab, 0x0c9752fa, 0x6f9025fe, + 0x0bd675d9, 0x005875b2, 0x00000000, + }; + ZUC_UINT32 ibs1[] = { + 0x14a8ef69, 0x3d678507, 0xbbe7270a, 0x7f67ff50, + 0x06c3525b, 0x9807e467, 0xc4e56000, 0xba338f5d, + 0x42955903, 0x67518222, 0x46c80d3b, 0x38f07f4b, + 0xe2d8ff58, 0x05f51322, 0x29bde93b, 0xbbdcaf38, + 0x2bf1ee97, 0x2fbf9977, 0xbada8945, 0x847a2a6c, + 0x9ad34a66, 0x7554e04d, 0x1f7fa2c3, 0x3241bd8f, + 0x01ba220d, + }; + ZUC_UINT32 ibs2[] = { + 0x8d74e20d, 0x54894e06, 0xd3cb13cb, 0x3933065e, + 0x8674be62, 0xadb1c72b, 0x3a646965, 0xab63cb7b, + 0x7854dfdc, 0x27e84929, 0xf49c64b8, 0x72a490b1, + 0x3f957b64, 0x827e71f4, 0x1fbd4269, 0xa42c97f8, + 0x24537027, 0xf86e9f4a, 0xd82d1df4, 0x51690fdd, + 0x98b6d03f, 0x3a0ebe3a, 0x312d6b84, 0x0ba5a182, + 0x0b2a2c97, 0x09c090d2, 0x45ed267c, 0xf845ae41, + 0xfa975d33, 0x33ac3009, 0xfd40eba9, 0xeb5b8857, + 0x14b768b6, 0x97138baf, 0x21380eca, 0x49f644d4, + 0x8689e421, 0x5760b906, 0x739f0d2b, 0x3f091133, + 0xca15d981, 0xcbe401ba, 0xf72d05ac, 0xe05cccb2, + 0xd297f4ef, 0x6a5f58d9, 0x1246cfa7, 0x7215b892, + 0xab441d52, 0x78452795, 0xccb7f5d7, 0x9057a1c4, + 0xf77f80d4, 0x6db2033c, 0xb79bedf8, 0xe60551ce, + 0x10c667f6, 0x2a97abaf, 0xabbcd677, 0x2018df96, + 0xa282ea73, 0x7ce2cb33, 0x1211f60d, 0x5354ce78, + 0xf9918d9c, 0x206ca042, 0xc9b62387, 0xdd709604, + 0xa50af16d, 0x8d35a890, 0x6be484cf, 0x2e74a928, + 0x99403643, 0x53249b27, 0xb4c9ae29, 0xeddfc7da, + 0x6418791a, 0x4e7baa06, 0x60fa6451, 0x1f2d685c, + 0xc3a5ff70, 0xe0d2b742, 0x92e3b8a0, 0xcd6b04b1, + 0xc790b8ea, 0xd2703708, 0x540dea2f, 0xc09c3da7, + 0x70f65449, 0xc84d817a, 0x4f551055, 0xe19ab850, + 0x18a0028b, 0x71a144d9, 0x6791e9a3, 0x57793350, + 0x4eee0060, 0x340c69d2, 0x74e1bf9d, 0x805dcbcc, + 0x1a6faa97, 0x6800b6ff, 0x2b671dc4, 0x63652fa8, + 0xa33ee509, 0x74c1c21b, 0xe01eabb2, 0x16743026, + 0x9d72ee51, 0x1c9dde30, 0x797c9a25, 0xd86ce74f, + 0x5b961be5, 0xfdfb6807, 0x814039e7, 0x137636bd, + 0x1d7fa9e0, 0x9efd2007, 0x505906a5, 0xac45dfde, + 0xed7757bb, 0xee745749, 0xc2963335, 0x0bee0ea6, + 0xf409df45, 0x80160000, + }; + ZUC_UINT32 obs0[] = { + 0xa6c85fc6, 0x6afb8533, 0xaafc2518, 0xdfe78494, + 0x0ee1e4b0, 0x30238cc8, 0x00000000, + }; + ZUC_UINT32 obs1[] = { + 0x131d43e0, 0xdea1be5c, 0x5a1bfd97, 0x1d852cbf, + 0x712d7b4f, 0x57961fea, 0x3208afa8, 0xbca433f4, + 0x56ad09c7, 0x417e58bc, 0x69cf8866, 0xd1353f74, + 0x865e8078, 0x1d202dfb, 0x3ecff7fc, 0xbc3b190f, + 0xe82a204e, 0xd0e350fc, 0x0f6f2613, 0xb2f2bca6, + 0xdf5a473a, 0x57a4a00d, 0x985ebad8, 0x80d6f238, + 0x64a07b01, + }; + ZUC_UINT32 obs2[] = { + 0x94eaa4aa, 0x30a57137, 0xddf09b97, 0xb25618a2, + 0x0a13e2f1, 0x0fa5bf81, 0x61a879cc, 0x2ae797a6, + 0xb4cf2d9d, 0xf31debb9, 0x905ccfec, 0x97de605d, + 0x21c61ab8, 0x531b7f3c, 0x9da5f039, 0x31f8a064, + 0x2de48211, 0xf5f52ffe, 0xa10f392a, 0x04766998, + 0x5da454a2, 0x8f080961, 0xa6c2b62d, 0xaa17f33c, + 0xd60a4971, 0xf48d2d90, 0x9394a55f, 0x48117ace, + 0x43d708e6, 0xb77d3dc4, 0x6d8bc017, 0xd4d1abb7, + 0x7b7428c0, 0x42b06f2f, 0x99d8d07c, 0x9879d996, + 0x00127a31, 0x985f1099, 0xbbd7d6c1, 0x519ede8f, + 0x5eeb4a61, 0x0b349ac0, 0x1ea23506, 0x91756bd1, + 0x05c974a5, 0x3eddb35d, 0x1d4100b0, 0x12e522ab, + 0x41f4c5f2, 0xfde76b59, 0xcb8b96d8, 0x85cfe408, + 0x0d1328a0, 0xd636cc0e, 0xdc05800b, 0x76acca8f, + 0xef672084, 0xd1f52a8b, 0xbd8e0993, 0x320992c7, + 0xffbae17c, 0x408441e0, 0xee883fc8, 0xa8b05e22, + 0xf5ff7f8d, 0x1b48c74c, 0x468c467a, 0x028f09fd, + 0x7ce91109, 0xa570a2d5, 0xc4d5f4fa, 0x18c5dd3e, + 0x4562afe2, 0x4ef77190, 0x1f59af64, 0x5898acef, + 0x088abae0, 0x7e92d52e, 0xb2de5504, 0x5bb1b7c4, + 0x164ef2d7, 0xa6cac15e, 0xeb926d7e, 0xa2f08b66, + 0xe1f759f3, 0xaee44614, 0x725aa3c7, 0x482b3084, + 0x4c143ff8, 0x7b53f1e5, 0x83c50125, 0x7dddd096, + 0xb81268da, 0xa303f172, 0x34c23335, 0x41f0bb8e, + 0x190648c5, 0x807c866d, 0x71932286, 0x09adb948, + 0x686f7de2, 0x94a802cc, 0x38f7fe52, 0x08f5ea31, + 0x96d0167b, 0x9bdd02f0, 0xd2a5221c, 0xa508f893, + 0xaf5c4b4b, 0xb9f4f520, 0xfd84289b, 0x3dbe7e61, + 0x497a7e2a, 0x584037ea, 0x637b6981, 0x127174af, + 0x57b471df, 0x4b2768fd, 0x79c1540f, 0xb3edf2ea, + 0x22cb69be, 0xc0cf8d93, 0x3d9c6fdd, 0x645e8505, + 0x91cca3d6, 0x2c0cc000, + }; + ZUC_UINT32 *ibs[] = {ibs0, ibs1, ibs2}; + ZUC_UINT32 *obs[] = {obs0, obs1, obs2}; + size_t bits[] = {0xc1, 0x320, 0xfb3}; + ZUC_UINT32 buf[sizeof(obs2)/4]; + size_t i; + + for (i = 0; i < sizeof(key)/sizeof(key[i]); i++) { + zuc_eea_encrypt(ibs[i], buf, bits[i], key[i], count[i], bearer[i], direction[i]); + if (memcmp(buf, obs[i], (bits[i] + 31)/32) != 0) { + printf("zuc eea test %zu failed\n", i); + err++; + } else { + printf("zuc eea test %zu ok\n", i); + } + } + + return err; +} + +/* test vector from GM/T 0001.3-2012 */ +static int zuc_eia_test(void) +{ + int err = 0; + unsigned char key[][16] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, + 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a}, + {0x6b, 0x8b, 0x08, 0xee, 0x79, 0xe0, 0xb5, 0x98, + 0x2d, 0x6d, 0x12, 0x8e, 0xa9, 0xf2, 0x20, 0xcb}, + }; + ZUC_UINT32 count[] = {0, 0xa94059daU, 0x561eb2ddU}; + ZUC_UINT5 bearer[] = {0, 0x0a, 0x1c}; + ZUC_BIT direction[] = {0, 1, 0}; + ZUC_UINT32 mesg0[] = {0}; + ZUC_UINT32 mesg1[] = { + 0x983b41d4, 0x7d780c9e, 0x1ad11d7e, 0xb70391b1, + 0xde0b35da, 0x2dc62f83, 0xe7b78d63, 0x06ca0ea0, + 0x7e941b7b, 0xe91348f9, 0xfcb170e2, 0x217fecd9, + 0x7f9f68ad, 0xb16e5d7d, 0x21e569d2, 0x80ed775c, + 0xebde3f40, 0x93c53881, 0x00000000, + }; + ZUC_UINT32 mesg2[] = { + 0x5bad7247, 0x10ba1c56, 0xd5a315f8, 0xd40f6e09, + 0x3780be8e, 0x8de07b69, 0x92432018, 0xe08ed96a, + 0x5734af8b, 0xad8a575d, 0x3a1f162f, 0x85045cc7, + 0x70925571, 0xd9f5b94e, 0x454a77c1, 0x6e72936b, + 0xf016ae15, 0x7499f054, 0x3b5d52ca, 0xa6dbeab6, + 0x97d2bb73, 0xe41b8075, 0xdce79b4b, 0x86044f66, + 0x1d4485a5, 0x43dd7860, 0x6e0419e8, 0x059859d3, + 0xcb2b67ce, 0x0977603f, 0x81ff839e, 0x33185954, + 0x4cfbc8d0, 0x0fef1a4c, 0x8510fb54, 0x7d6b06c6, + 0x11ef44f1, 0xbce107cf, 0xa45a06aa, 0xb360152b, + 0x28dc1ebe, 0x6f7fe09b, 0x0516f9a5, 0xb02a1bd8, + 0x4bb0181e, 0x2e89e19b, 0xd8125930, 0xd178682f, + 0x3862dc51, 0xb636f04e, 0x720c47c3, 0xce51ad70, + 0xd94b9b22, 0x55fbae90, 0x6549f499, 0xf8c6d399, + 0x47ed5e5d, 0xf8e2def1, 0x13253e7b, 0x08d0a76b, + 0x6bfc68c8, 0x12f375c7, 0x9b8fe5fd, 0x85976aa6, + 0xd46b4a23, 0x39d8ae51, 0x47f680fb, 0xe70f978b, + 0x38effd7b, 0x2f7866a2, 0x2554e193, 0xa94e98a6, + 0x8b74bd25, 0xbb2b3f5f, 0xb0a5fd59, 0x887f9ab6, + 0x8159b717, 0x8d5b7b67, 0x7cb546bf, 0x41eadca2, + 0x16fc1085, 0x0128f8bd, 0xef5c8d89, 0xf96afa4f, + 0xa8b54885, 0x565ed838, 0xa950fee5, 0xf1c3b0a4, + 0xf6fb71e5, 0x4dfd169e, 0x82cecc72, 0x66c850e6, + 0x7c5ef0ba, 0x960f5214, 0x060e71eb, 0x172a75fc, + 0x1486835c, 0xbea65344, 0x65b055c9, 0x6a72e410, + 0x52241823, 0x25d83041, 0x4b40214d, 0xaa8091d2, + 0xe0fb010a, 0xe15c6de9, 0x0850973b, 0xdf1e423b, + 0xe148a237, 0xb87a0c9f, 0x34d4b476, 0x05b803d7, + 0x43a86a90, 0x399a4af3, 0x96d3a120, 0x0a62f3d9, + 0x507962e8, 0xe5bee6d3, 0xda2bb3f7, 0x237664ac, + 0x7a292823, 0x900bc635, 0x03b29e80, 0xd63f6067, + 0xbf8e1716, 0xac25beba, 0x350deb62, 0xa99fe031, + 0x85eb4f69, 0x937ecd38, 0x7941fda5, 0x44ba67db, + 0x09117749, 0x38b01827, 0xbcc69c92, 0xb3f772a9, + 0xd2859ef0, 0x03398b1f, 0x6bbad7b5, 0x74f7989a, + 0x1d10b2df, 0x798e0dbf, 0x30d65874, 0x64d24878, + 0xcd00c0ea, 0xee8a1a0c, 0xc753a279, 0x79e11b41, + 0xdb1de3d5, 0x038afaf4, 0x9f5c682c, 0x3748d8a3, + 0xa9ec54e6, 0xa371275f, 0x1683510f, 0x8e4f9093, + 0x8f9ab6e1, 0x34c2cfdf, 0x4841cba8, 0x8e0cff2b, + 0x0bcc8e6a, 0xdcb71109, 0xb5198fec, 0xf1bb7e5c, + 0x531aca50, 0xa56a8a3b, 0x6de59862, 0xd41fa113, + 0xd9cd9578, 0x08f08571, 0xd9a4bb79, 0x2af271f6, + 0xcc6dbb8d, 0xc7ec36e3, 0x6be1ed30, 0x8164c31c, + 0x7c0afc54, 0x1c000000, + }; + ZUC_UINT32 *mesg[] = {mesg0, mesg1, mesg2}; + size_t bits[] = {1, 0x241, 0x1626}; + ZUC_UINT32 mac[] = {0xc8a9595eU, 0xfae8ff0bU, 0x0ca12792U}; + size_t i; + + bswap_buf(mesg0, sizeof(mesg0)/sizeof(mesg0[0])); + bswap_buf(mesg1, sizeof(mesg1)/sizeof(mesg1[0])); + bswap_buf(mesg2, sizeof(mesg2)/sizeof(mesg2[0])); + + for (i = 0; i < sizeof(key)/sizeof(key[0]); i++) { + ZUC_UINT32 T; + T = zuc_eia_generate_mac(mesg[i], bits[i], key[i], + count[i], bearer[i], direction[i]); + if (T != mac[i]) { + printf("zuc eia test %zu failed\n", i); + err++; + } else { + printf("zuc eia test %zu ok\n", i); + } + } + + return err; +} + +/* from ZUC256 draft */ +int zuc256_test(void) +{ + int err = 0; + int i; + + unsigned char key[][32] = { + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,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, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} + }; + unsigned char iv[][23] = { + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,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, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + }; + uint32_t ciphertext[][20] = { + {0x58d03ad6,0x2e032ce2,0xdafc683a,0x39bdcb03,0x52a2bc67, + 0xf1b7de74,0x163ce3a1,0x01ef5558,0x9639d75b,0x95fa681b, + 0x7f090df7,0x56391ccc,0x903b7612,0x744d544c,0x17bc3fad, + 0x8b163b08,0x21787c0b,0x97775bb8,0x4943c6bb,0xe8ad8afd}, + {0x3356cbae,0xd1a1c18b,0x6baa4ffe,0x343f777c,0x9e15128f, + 0x251ab65b,0x949f7b26,0xef7157f2,0x96dd2fa9,0xdf95e3ee, + 0x7a5be02e,0xc32ba585,0x505af316,0xc2f9ded2,0x7cdbd935, + 0xe441ce11,0x15fd0a80,0xbb7aef67,0x68989416,0xb8fac8c2} + }; + + for (i = 0; i < sizeof(key)/sizeof(key[0]); i++) { + ZUC_STATE zuc_key; + uint32_t buf[20] = {0}; + + zuc256_init(&zuc_key, key[i], iv[i]); + zuc_generate_keystream(&zuc_key, 20, buf); + + if (memcmp(buf, ciphertext[i], 20) != 0) { + printf("zuc256 test %d failed\n", i); + err++; + } else { + printf("zuc256 test %d ok\n", i); + } + } + + return err; +} + +int zuc256_mac_test(void) +{ + int err = 0; + unsigned char key[][32] = { + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,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, + 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} + }; + unsigned char iv[][23] = { + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,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, + 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}, + }; + unsigned char msg[][50] = { + /* 400 zero bits */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* 4000 bits */ + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + /* 400 zero bits */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* 4000 bits */ + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + }; + unsigned int msg_num[] = { + 1, + 10, + 1, + 10 + }; + unsigned int tag32[][1] = { + {0x9b972a74}, + {0x8754f5cf}, + {0x1f3079b4}, + {0x5c7c8b88}, + }; + unsigned int tag64[][2] = { + {0x673e5499,0x0034d38c}, + {0x130dc225,0xe72240cc}, + {0x8c71394d,0x39957725}, + {0xea1dee54,0x4bb6223b}, + }; + unsigned int tag128[][4] = { + {0xd85e54bb,0xcb960096,0x7084c952,0xa1654b26}, + {0xdf1e8307,0xb31cc62b,0xeca1ac6f,0x8190c22f}, + {0xa35bb274,0xb567c48b,0x28319f11,0x1af34fbd}, + {0x3a83b554,0xbe408ca5,0x494124ed,0x9d473205}, + }; + int i, j; + + bswap_buf((uint32_t *)tag32, sizeof(tag32)/4); + bswap_buf((uint32_t *)tag64, sizeof(tag64)/4); + bswap_buf((uint32_t *)tag128, sizeof(tag128)/4); + + for (i = 0; i < 4; i++) { + ZUC256_MAC_CTX ctx; + unsigned char mac[16]; + + zuc256_mac_init(&ctx, key[i], iv[i], 32); + for (j = 0; j < msg_num[i]; j++) { + zuc256_mac_update(&ctx, msg[i], 50); + } + zuc256_mac_finish(&ctx, NULL, 0, mac); + if (memcmp(mac, tag32[i], 4) != 0) { + printf("zuc256 mac test %d 32-bit failed\n", i); + err++; + } else { + printf("zuc256 mac test %d 32-bit ok\n", i); + } + + zuc256_mac_init(&ctx, key[i], iv[i], 64); + for (j = 0; j < msg_num[i]; j++) { + zuc256_mac_update(&ctx, msg[i], 50); + } + zuc256_mac_finish(&ctx, NULL, 0, mac); + if (memcmp(mac, tag64[i], 8) != 0) { + printf("zuc256 mac test %d 64-bit failed\n", i); + err++; + } else { + printf("zuc256 mac test %d 64-bit ok\n", i); + } + + zuc256_mac_init(&ctx, key[i], iv[i], 128); + for (j = 0; j < msg_num[i]; j++) { + zuc256_mac_update(&ctx, msg[i], 50); + } + zuc256_mac_finish(&ctx, NULL, 0, mac); + if (memcmp(mac, tag128[i], 16) != 0) { + printf("zuc256 mac test %d 128-bit failed\n", i); + err++; + } else { + printf("zuc256 mac test %d 128-bit ok\n", i); + } + } + + return err; +} + +int main(void) +{ + int err = 0; + err += zuc_test(); + err += zuc_eea_test(); + err += zuc_eia_test(); + err += zuc256_test(); + err += zuc256_mac_test(); + return err; +} diff --git a/tools/README.md b/tools/README.md index 4d4dd049..3cb6aedb 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,41 +1,41 @@ -# 命令行工具 - -注意: - -* 命令行工具接口在v3版本正式发布前还会有较大调整 -* SM2, SM3, SM4等算法的命令相对比较底层,是对C语言接口的简单封装,命令行的应用开发者需要组合使用这些指令 - -命令行工具: - -* `sm3` 计算SM3杂凑值,支持带公钥和ID的Z值计算 -* `sm3hmac` 计算SM3-HMAC值 -* `sm2keygen` 生成SM2密钥对,以PKCS #8口令加密的PEM格式存储 -* `sm2sign`,`sm2verify` SM2签名和验证,生成DER二进制编码的SM2签名值 -* `sm2encrypt`,`sm2decrypt` SM2加解密,注意只支持较短的消息加密 -* `reqgen` 生成PKCS #10证书签名请求PEM文件 -* `reqparse` 解析打印REQ文件 -* `reqsign` CA用私钥对REQ文件签名,生成证书 -* `certgen`生成自签名证书 -* `certparse` 解析打印证书 -* `certverify` 验证证书链 - -TLS功能 - -* `tlcp_client` -* `tlcp_server` -* `tls12_client` -* `tls12_server` -* `tls13_client` -* `tls13_server` - -私钥总是默认以口令加密的方式存储 -SM3/HMAC-SM3 以二进制的格式输出 -签名和SM2Ciphertext以DER编码输出 - - -应该提供一个口令导出密钥的算法,由口令导出密钥 - -SM4加密需要外部提供key, iv -HMAC-SM3可以用命令行的方式拼合 -因此没必要提供一个单独的SM4-CBC-HMAC-SM3 - +# 命令行工具 + +注意: + +* 命令行工具接口在v3版本正式发布前还会有较大调整 +* SM2, SM3, SM4等算法的命令相对比较底层,是对C语言接口的简单封装,命令行的应用开发者需要组合使用这些指令 + +命令行工具: + +* `sm3` 计算SM3杂凑值,支持带公钥和ID的Z值计算 +* `sm3hmac` 计算SM3-HMAC值 +* `sm2keygen` 生成SM2密钥对,以PKCS #8口令加密的PEM格式存储 +* `sm2sign`,`sm2verify` SM2签名和验证,生成DER二进制编码的SM2签名值 +* `sm2encrypt`,`sm2decrypt` SM2加解密,注意只支持较短的消息加密 +* `reqgen` 生成PKCS #10证书签名请求PEM文件 +* `reqparse` 解析打印REQ文件 +* `reqsign` CA用私钥对REQ文件签名,生成证书 +* `certgen`生成自签名证书 +* `certparse` 解析打印证书 +* `certverify` 验证证书链 + +TLS功能 + +* `tlcp_client` +* `tlcp_server` +* `tls12_client` +* `tls12_server` +* `tls13_client` +* `tls13_server` + +私钥总是默认以口令加密的方式存储 +SM3/HMAC-SM3 以二进制的格式输出 +签名和SM2Ciphertext以DER编码输出 + + +应该提供一个口令导出密钥的算法,由口令导出密钥 + +SM4加密需要外部提供key, iv +HMAC-SM3可以用命令行的方式拼合 +因此没必要提供一个单独的SM4-CBC-HMAC-SM3 + diff --git a/tools/certgen.c b/tools/certgen.c index 19b340d7..cb70bb89 100644 --- a/tools/certgen.c +++ b/tools/certgen.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,204 +7,205 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = - "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num " - "-key file [-pass pass] " - "[-key_usage str]* [-out file]"; - - -static int ext_key_usage_set(int *usages, const char *usage_name) -{ - int flag; - if (x509_key_usage_from_name(&flag, usage_name) != 1) { - error_print(); - return -1; - } - *usages |= flag; - return 1; -} - -int certgen_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *country = NULL; - char *state = NULL; - char *locality = NULL; - char *org = NULL; - char *org_unit = NULL; - char *common_name = NULL; - int days = 0; - int key_usage = 0; - char *keyfile = NULL; - char *pass = NULL; - char *outfile = NULL; - - uint8_t serial[12]; - uint8_t name[256]; - size_t namelen; - time_t not_before; - time_t not_after; - uint8_t uniq_id[32]; - uint8_t exts[512]; - size_t extslen = 0; - FILE *keyfp = NULL; - SM2_KEY sm2_key; - uint8_t cert[1024]; - size_t certlen; - FILE *outfp = stdout; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-CN")) { - if (--argc < 1) goto bad; - common_name = *(++argv); - } else if (!strcmp(*argv, "-O")) { - if (--argc < 1) goto bad; - org = *(++argv); - } else if (!strcmp(*argv, "-OU")) { - if (--argc < 1) goto bad; - org_unit = *(++argv); - } else if (!strcmp(*argv, "-C")) { - if (--argc < 1) goto bad; - country = *(++argv); - } else if (!strcmp(*argv, "-ST")) { - if (--argc < 1) goto bad; - state = *(++argv); - } else if (!strcmp(*argv, "-L")) { - if (--argc < 1) goto bad; - locality = *(++argv); - } else if (!strcmp(*argv, "-days")) { - if (--argc < 1) goto bad; - days = atoi(*(++argv)); - if (days <= 0) { - fprintf(stderr, "%s: invalid '-days' value\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-key_usage")) { - char *usage; - if (--argc < 1) goto bad; - usage = *(++argv); - if (ext_key_usage_set(&key_usage, usage) != 1) { - fprintf(stderr, "%s: invalid -key_usage value '%s'\n", prog, usage); - goto end; - } - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!common_name) { - fprintf(stderr, "%s: '-CN' option required\n", prog); - goto end; - } - if (!days) { - fprintf(stderr, "%s: '-days' option required\n", prog); - goto end; - } - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - if (!key_usage) { - fprintf(stderr, "%s: '-key_usage' option required\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { - fprintf(stderr, "%s: load private key failed\n", prog); - goto end; - } - - if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1 - || x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, -1) != 1 - || x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - - time(¬_before); - if (rand_bytes(serial, sizeof(serial)) != 1 - || x509_name_set(name, &namelen, sizeof(name), - country, state, locality, org, org_unit, common_name) != 1 - || x509_validity_add_days(¬_after, not_before, days) != 1 - || x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - name, namelen, - not_before, not_after, - name, namelen, - &sm2_key, - NULL, 0, - NULL, 0, - exts, extslen, - &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (x509_cert_to_pem(cert, certlen, outfp) != 1) { - fprintf(stderr, "%s: output certificate failed\n", prog); - goto end; - } - ret = 0; - -end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); - if (keyfp) fclose(keyfp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = + "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num " + "-key file [-pass pass] " + "[-key_usage str]* [-out file]"; + + +static int ext_key_usage_set(int *usages, const char *usage_name) +{ + int flag; + if (x509_key_usage_from_name(&flag, usage_name) != 1) { + error_print(); + return -1; + } + *usages |= flag; + return 1; +} + +int certgen_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *country = NULL; + char *state = NULL; + char *locality = NULL; + char *org = NULL; + char *org_unit = NULL; + char *common_name = NULL; + int days = 0; + int key_usage = 0; + char *keyfile = NULL; + char *pass = NULL; + char *outfile = NULL; + + uint8_t serial[12]; + uint8_t name[256]; + size_t namelen; + time_t not_before; + time_t not_after; + uint8_t uniq_id[32]; + uint8_t exts[512]; + size_t extslen = 0; + FILE *keyfp = NULL; + SM2_KEY sm2_key; + uint8_t cert[1024]; + size_t certlen; + FILE *outfp = stdout; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-CN")) { + if (--argc < 1) goto bad; + common_name = *(++argv); + } else if (!strcmp(*argv, "-O")) { + if (--argc < 1) goto bad; + org = *(++argv); + } else if (!strcmp(*argv, "-OU")) { + if (--argc < 1) goto bad; + org_unit = *(++argv); + } else if (!strcmp(*argv, "-C")) { + if (--argc < 1) goto bad; + country = *(++argv); + } else if (!strcmp(*argv, "-ST")) { + if (--argc < 1) goto bad; + state = *(++argv); + } else if (!strcmp(*argv, "-L")) { + if (--argc < 1) goto bad; + locality = *(++argv); + } else if (!strcmp(*argv, "-days")) { + if (--argc < 1) goto bad; + days = atoi(*(++argv)); + if (days <= 0) { + fprintf(stderr, "%s: invalid '-days' value\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-key_usage")) { + char *usage; + if (--argc < 1) goto bad; + usage = *(++argv); + if (ext_key_usage_set(&key_usage, usage) != 1) { + fprintf(stderr, "%s: invalid -key_usage value '%s'\n", prog, usage); + goto end; + } + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!common_name) { + fprintf(stderr, "%s: '-CN' option required\n", prog); + goto end; + } + if (!days) { + fprintf(stderr, "%s: '-days' option required\n", prog); + goto end; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + if (!key_usage) { + fprintf(stderr, "%s: '-key_usage' option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + fprintf(stderr, "%s: load private key failed\n", prog); + goto end; + } + + if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1 + || x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, -1) != 1 + || x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + time(¬_before); + if (rand_bytes(serial, sizeof(serial)) != 1 + || x509_name_set(name, &namelen, sizeof(name), + country, state, locality, org, org_unit, common_name) != 1 + || x509_validity_add_days(¬_after, not_before, days) != 1 + || x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + name, namelen, + not_before, not_after, + name, namelen, + &sm2_key, + NULL, 0, + NULL, 0, + exts, extslen, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_cert_to_pem(cert, certlen, outfp) != 1) { + fprintf(stderr, "%s: output certificate failed\n", prog); + goto end; + } + ret = 0; + +end: + gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); + if (keyfp) fclose(keyfp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/certparse.c b/tools/certparse.c index f6ba6437..4783c5c5 100644 --- a/tools/certparse.c +++ b/tools/certparse.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,77 +7,78 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-in file] [-out file]"; - -int certparse_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - uint8_t cert[18192]; - size_t certlen; - - argc--; - argv++; - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - for (;;) { - int rv; - if ((rv = x509_cert_from_pem(cert, &certlen, sizeof(cert), infp)) != 1) { - if (rv < 0) fprintf(stderr, "%s: read certificate failure\n", prog); - else ret = 0; - goto end; - } - x509_cert_print(outfp, 0, 0, "Certificate", cert, certlen); - if (x509_cert_to_pem(cert, certlen, outfp) != 1) { - fprintf(stderr, "%s: output certficate failure\n", prog); - goto end; - } - } - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-in file] [-out file]"; + +int certparse_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + uint8_t cert[18192]; + size_t certlen; + + argc--; + argv++; + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + for (;;) { + int rv; + if ((rv = x509_cert_from_pem(cert, &certlen, sizeof(cert), infp)) != 1) { + if (rv < 0) fprintf(stderr, "%s: read certificate failure\n", prog); + else ret = 0; + goto end; + } + x509_cert_print(outfp, 0, 0, "Certificate", cert, certlen); + if (x509_cert_to_pem(cert, certlen, outfp) != 1) { + fprintf(stderr, "%s: output certficate failure\n", prog); + goto end; + } + } + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/certverify.c b/tools/certverify.c index 4078187b..5edb24e0 100644 --- a/tools/certverify.c +++ b/tools/certverify.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,169 +7,170 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -static const char *options = "-in pem [-double_certs] -cacert pem\n"; - -int certverify_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *cacertfile = NULL; - FILE *infp = stdin; - FILE *cacertfp = NULL; - uint8_t cert[1024]; - size_t certlen; - uint8_t cacert[1024]; - size_t cacertlen; - const uint8_t *subject; - size_t subject_len; - const uint8_t *subj; - size_t subj_len; - - int double_certs = 0; - uint8_t enc_cert[1024]; - size_t enc_cert_len; - int rv; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-double_certs")) { - double_certs = 1; - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - if (!(cacertfp = fopen(cacertfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - if (!cacertfile) { - fprintf(stderr, "%s: '-cacert' option required\n", prog); - goto end; - } - - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), infp) != 1 - || x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) { - fprintf(stderr, "%s: read certificate failure\n", prog); - goto end; - } - x509_name_print(stdout, 0, 0, "Certificate", subject, subject_len); - - if (double_certs) { - - if (x509_cert_from_pem(enc_cert, &enc_cert_len, sizeof(enc_cert), infp) != 1 - || x509_cert_get_subject(enc_cert, enc_cert_len, &subj, &subj_len) != 1) { - fprintf(stderr, "%s: read encryption certficate failure\n", prog); - goto end; - } - - if (subj_len != subject_len - || memcmp(subject, subj, subj_len) != 0) { - fprintf(stderr, "%s: double certificates not compatible\n", prog); - goto end; - } - } - - for (;;) { - if ((rv = x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), infp)) != 1) { - if (rv < 0) goto end; - goto final; - } - if (x509_cert_get_subject(cacert, cacertlen, &subject, &subject_len) != 1) { - goto end; - } - - if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - printf("Verification %s\n", rv ? "success" : "failure"); - - if (double_certs) { - x509_name_print(stdout, 0, 0, "Certificate", subj, subj_len); - - if ((rv = x509_cert_verify_by_ca_cert(enc_cert, enc_cert_len, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - printf("Verification %s\n", rv ? "success" : "failure"); - double_certs = 0; - } - x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); - - memcpy(cert, cacert, cacertlen); - certlen = cacertlen; - } - -final: - if (x509_cert_get_issuer(cert, certlen, &subject, &subject_len) != 1) { - fprintf(stderr, "%s: parse certificate error\n", prog); - goto end; - } - if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { - fprintf(stderr, "%s: load CA certificate failure\n", prog); - goto end; - } - if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - printf("Verification %s\n", rv ? "success" : "failure"); - x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); - - if (double_certs) { - if ((rv = x509_cert_verify_by_ca_cert(enc_cert, enc_cert_len, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - printf("Verification %s\n", rv ? "success" : "failure"); - } - - ret = 0; -end: - if (infile && infp) fclose(infp); - if (cacertfp) fclose(cacertfp); - return ret; -} + + +#include +#include +#include +#include +#include + + +static const char *options = "-in pem [-double_certs] -cacert pem\n"; + +int certverify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *cacertfile = NULL; + FILE *infp = stdin; + FILE *cacertfp = NULL; + uint8_t cert[1024]; + size_t certlen; + uint8_t cacert[1024]; + size_t cacertlen; + const uint8_t *subject; + size_t subject_len; + const uint8_t *subj; + size_t subj_len; + + int double_certs = 0; + uint8_t enc_cert[1024]; + size_t enc_cert_len; + int rv; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-double_certs")) { + double_certs = 1; + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + if (!(cacertfp = fopen(cacertfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + if (!cacertfile) { + fprintf(stderr, "%s: '-cacert' option required\n", prog); + goto end; + } + + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), infp) != 1 + || x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1) { + fprintf(stderr, "%s: read certificate failure\n", prog); + goto end; + } + x509_name_print(stdout, 0, 0, "Certificate", subject, subject_len); + + if (double_certs) { + + if (x509_cert_from_pem(enc_cert, &enc_cert_len, sizeof(enc_cert), infp) != 1 + || x509_cert_get_subject(enc_cert, enc_cert_len, &subj, &subj_len) != 1) { + fprintf(stderr, "%s: read encryption certficate failure\n", prog); + goto end; + } + + if (subj_len != subject_len + || memcmp(subject, subj, subj_len) != 0) { + fprintf(stderr, "%s: double certificates not compatible\n", prog); + goto end; + } + } + + for (;;) { + if ((rv = x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), infp)) != 1) { + if (rv < 0) goto end; + goto final; + } + if (x509_cert_get_subject(cacert, cacertlen, &subject, &subject_len) != 1) { + goto end; + } + + if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + printf("Verification %s\n", rv ? "success" : "failure"); + + if (double_certs) { + x509_name_print(stdout, 0, 0, "Certificate", subj, subj_len); + + if ((rv = x509_cert_verify_by_ca_cert(enc_cert, enc_cert_len, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + printf("Verification %s\n", rv ? "success" : "failure"); + double_certs = 0; + } + x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); + + memcpy(cert, cacert, cacertlen); + certlen = cacertlen; + } + +final: + if (x509_cert_get_issuer(cert, certlen, &subject, &subject_len) != 1) { + fprintf(stderr, "%s: parse certificate error\n", prog); + goto end; + } + if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { + fprintf(stderr, "%s: load CA certificate failure\n", prog); + goto end; + } + if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + printf("Verification %s\n", rv ? "success" : "failure"); + x509_name_print(stdout, 0, 0, "Signed by", subject, subject_len); + + if (double_certs) { + if ((rv = x509_cert_verify_by_ca_cert(enc_cert, enc_cert_len, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + printf("Verification %s\n", rv ? "success" : "failure"); + } + + ret = 0; +end: + if (infile && infp) fclose(infp); + if (cacertfp) fclose(cacertfp); + return ret; +} diff --git a/tools/cmsdecrypt.c b/tools/cmsdecrypt.c index 07c9d658..eb731cba 100644 --- a/tools/cmsdecrypt.c +++ b/tools/cmsdecrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,171 +7,172 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - - -static const char *options = "-key file -pass str -cert file -in file [-out file]"; - -int cmsdecrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyfile = NULL; - char *pass = NULL; - char *certfile = NULL; - char *infile = NULL; - char *outfile = NULL; - FILE *keyfp = NULL; - FILE *certfp = NULL; - FILE *infp = NULL; - FILE *outfp = stdout; - uint8_t cert[1024]; - size_t certlen; - struct stat st; - uint8_t *cms = NULL; - size_t cmslen, cms_maxlen; - SM2_KEY key; - int content_type; - uint8_t *content = NULL; - size_t content_len; - const uint8_t *rcpt_infos; - size_t rcpt_infos_len; - const uint8_t *shared_info1; - const uint8_t *shared_info2; - size_t shared_info1_len, shared_info2_len; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - if (!(certfp = fopen(certfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - if (!certfile) { - fprintf(stderr, "%s: '-cert' option required\n", prog); - goto end; - } - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - fprintf(stderr, "%s: private key decryption failure\n", prog); - goto end; - } - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { - fprintf(stderr, "%s: load certificate failure\n", prog); - goto end; - } - - fstat(fileno(infp), &st); - cms_maxlen = (st.st_size * 3)/4 + 1; - if (!(cms = malloc(cms_maxlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { - fprintf(stderr, "%s: read CMS failure\n", prog); - goto end; - } - - if (!(content = malloc(cmslen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - - if (cms_deenvelop(cms, cmslen, - &key, cert, certlen, - &content_type, content, &content_len, - &rcpt_infos, &rcpt_infos_len, - &shared_info1, &shared_info1_len, - &shared_info2, &shared_info2_len) != 1) { - fprintf(stderr, "%s: decryption failure\n", prog); - goto end; - } - if (content_type != OID_cms_data) { - fprintf(stderr, "%s: invalid CMS content type: %s\n", prog, cms_content_type_name(content_type)); - goto end; - } - - if (fwrite(content, 1, content_len, outfp) != content_len) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - - ret = 0; - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (keyfile && keyfp) fclose(keyfp); - if (cms) free(cms); - if (content) free(content); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + + +static const char *options = "-key file -pass str -cert file -in file [-out file]"; + +int cmsdecrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyfile = NULL; + char *pass = NULL; + char *certfile = NULL; + char *infile = NULL; + char *outfile = NULL; + FILE *keyfp = NULL; + FILE *certfp = NULL; + FILE *infp = NULL; + FILE *outfp = stdout; + uint8_t cert[1024]; + size_t certlen; + struct stat st; + uint8_t *cms = NULL; + size_t cmslen, cms_maxlen; + SM2_KEY key; + int content_type; + uint8_t *content = NULL; + size_t content_len; + const uint8_t *rcpt_infos; + size_t rcpt_infos_len; + const uint8_t *shared_info1; + const uint8_t *shared_info2; + size_t shared_info1_len, shared_info2_len; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + goto end; + } + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; + } + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { + fprintf(stderr, "%s: load certificate failure\n", prog); + goto end; + } + + fstat(fileno(infp), &st); + cms_maxlen = (st.st_size * 3)/4 + 1; + if (!(cms = malloc(cms_maxlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { + fprintf(stderr, "%s: read CMS failure\n", prog); + goto end; + } + + if (!(content = malloc(cmslen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + + if (cms_deenvelop(cms, cmslen, + &key, cert, certlen, + &content_type, content, &content_len, + &rcpt_infos, &rcpt_infos_len, + &shared_info1, &shared_info1_len, + &shared_info2, &shared_info2_len) != 1) { + fprintf(stderr, "%s: decryption failure\n", prog); + goto end; + } + if (content_type != OID_cms_data) { + fprintf(stderr, "%s: invalid CMS content type: %s\n", prog, cms_content_type_name(content_type)); + goto end; + } + + if (fwrite(content, 1, content_len, outfp) != content_len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + + ret = 0; + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (keyfile && keyfp) fclose(keyfp); + if (cms) free(cms); + if (content) free(content); + return ret; +} diff --git a/tools/cmsencrypt.c b/tools/cmsencrypt.c index 7ed80426..aea9393b 100644 --- a/tools/cmsencrypt.c +++ b/tools/cmsencrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,226 +7,227 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - -签名的时候要提供签名者的证书,并且提供签名私钥 -但是验证的时候假定CMS中已经包含签名者的证书了,但是我们要提供CA证书库 - -加密的时候要指定接收者的证书,并且可以有多个接收者 -解密的时候只提供一个解密私钥,但是最好配合解密者的证书,从这个证书中找到解密者的名字 - -如果即加密又签名,那么输出的是SignedAndEnveloped - -CMS有PEM吗? - -cms -encrypt -rcpt a.pem -rcpt b.pem -rcpt c.pem -in file -sign -signcert a.pem -signcert b.pem - -rcptcert -rcpt_cert -sign_cert b.pem -signkey - -首先接收者可以有多个证书 - -这里面有个问题,因为我们要输出一个加密的对象,因此我们必须把输入的内容读取进来。 - - -EnvelopedData 是一个封装的SEQUENCE中,因此必须读取所有的内容。 -如果是一个文件,就需要读取所有的文件内容,如果是一个stream ,也需要读取完整的内容到一个足够大的buffer中,如何设置这个buffer的大小呢 - - - -对于输入文件,如果输入有文件名的话,可以直接通过stat获取文件长度 -但是如果对于stream的话,实际上我们是没有办法获得输入长度的,那么就直接准备一个buffer好了。 -不要给自己找麻烦了,直接只支持文件输入吧 -encrypt - -*/ - -static const char *options = "-encrypt (-rcptcert pem)* -in file -out file"; - - -static int get_files_size(int argc, char **argv, const char *option, size_t *len) -{ - char *prog = argv[0]; - char *file = NULL; - FILE *fp = NULL; - struct stat st; - - argc--; - argv++; - - *len = 0; - while (argc > 1) { - if (!strcmp(*argv, option)) { - if (--argc < 1) { - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - return -1; - } - file = *(++argv); - if (!(fp = fopen(file, "r"))) { - fprintf(stderr, "%s: open '%s' failed : %s\n", prog, file, strerror(errno)); - return -1; - } - if (fstat(fileno(fp), &st) < 0) { - fprintf(stderr, "%s: access '%s' failed : %s\n", prog, file, strerror(errno)); - fclose(fp); - return -1; - } - *len += st.st_size; - fclose(fp); - } - argc--; - argv++; - } - - return 1; -} - -int cmsencrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int op = 0; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - uint8_t *rcpt_certs = NULL; - size_t rcpt_certs_len; - uint8_t key[16]; - uint8_t iv[16]; - uint8_t *inbuf = NULL; - size_t inlen; - uint8_t *cms = NULL; - size_t cmslen; - uint8_t *cert; - - if (argc < 2) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - // 预先统计证书缓冲大小和输入大小 - if (get_files_size(argc, argv, "-rcptcert", &rcpt_certs_len) != 1) { - goto end; - } - if (rcpt_certs_len <= 0) { - fprintf(stderr, "%s: invalid cert length\n", prog); - goto end; - } - rcpt_certs_len = (rcpt_certs_len * 3)/4; - if (!(rcpt_certs = malloc(rcpt_certs_len))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - cert = rcpt_certs; - - if (get_files_size(argc, argv, "-in", &inlen) != 1) { - goto end; - } - if (inlen <= 0) { - fprintf(stderr, "%s: invalid input length\n", prog); - goto end; - } - if (!(inbuf = malloc(inlen))) { - fprintf(stderr, "%s: %s\n", prog, strerror(errno)); - goto end; - } - - argc--; - argv++; - - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-rcptcert")) { - char *certfile; - FILE *certfp; - size_t certlen; - if (--argc < 1) goto bad; - certfile = *(++argv); - if (!(certfp = fopen(certfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); - goto end; - } - if (x509_cert_from_pem(cert, &certlen, rcpt_certs_len, certfp) != 1) { - fprintf(stderr, "%s: error\n", prog); - fclose(certfp); - goto end; - } - cert += certlen; - fclose(certfp); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - if ((inlen = fread(inbuf, 1, inlen, infp)) <= 0) { - fprintf(stderr, "%s: read data error: %s\n", prog, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - rcpt_certs_len = cert - rcpt_certs; - - if (rand_bytes(key, sizeof(key)) != 1 - || rand_bytes(iv, sizeof(iv)) != 1 - || cms_envelop(NULL, &cmslen, rcpt_certs, rcpt_certs_len, - OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), - OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (!(cms = malloc(cmslen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (cms_envelop(cms, &cmslen, rcpt_certs, rcpt_certs_len, - OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), - OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (cms_to_pem(cms, cmslen, outfp) != 1) { - fprintf(stderr, "%s: output CMS failure\n", prog); - goto end; - } - - ret = 0; - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (rcpt_certs) free(rcpt_certs); - if (cms) free(cms); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + +签名的时候要提供签名者的证书,并且提供签名私钥 +但是验证的时候假定CMS中已经包含签名者的证书了,但是我们要提供CA证书库 + +加密的时候要指定接收者的证书,并且可以有多个接收者 +解密的时候只提供一个解密私钥,但是最好配合解密者的证书,从这个证书中找到解密者的名字 + +如果即加密又签名,那么输出的是SignedAndEnveloped + +CMS有PEM吗? + +cms -encrypt -rcpt a.pem -rcpt b.pem -rcpt c.pem -in file -sign -signcert a.pem -signcert b.pem + -rcptcert -rcpt_cert -sign_cert b.pem -signkey + +首先接收者可以有多个证书 + +这里面有个问题,因为我们要输出一个加密的对象,因此我们必须把输入的内容读取进来。 + + +EnvelopedData 是一个封装的SEQUENCE中,因此必须读取所有的内容。 +如果是一个文件,就需要读取所有的文件内容,如果是一个stream ,也需要读取完整的内容到一个足够大的buffer中,如何设置这个buffer的大小呢 + + + +对于输入文件,如果输入有文件名的话,可以直接通过stat获取文件长度 +但是如果对于stream的话,实际上我们是没有办法获得输入长度的,那么就直接准备一个buffer好了。 +不要给自己找麻烦了,直接只支持文件输入吧 +encrypt + +*/ + +static const char *options = "-encrypt (-rcptcert pem)* -in file -out file"; + + +static int get_files_size(int argc, char **argv, const char *option, size_t *len) +{ + char *prog = argv[0]; + char *file = NULL; + FILE *fp = NULL; + struct stat st; + + argc--; + argv++; + + *len = 0; + while (argc > 1) { + if (!strcmp(*argv, option)) { + if (--argc < 1) { + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + return -1; + } + file = *(++argv); + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s: open '%s' failed : %s\n", prog, file, strerror(errno)); + return -1; + } + if (fstat(fileno(fp), &st) < 0) { + fprintf(stderr, "%s: access '%s' failed : %s\n", prog, file, strerror(errno)); + fclose(fp); + return -1; + } + *len += st.st_size; + fclose(fp); + } + argc--; + argv++; + } + + return 1; +} + +int cmsencrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int op = 0; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + uint8_t *rcpt_certs = NULL; + size_t rcpt_certs_len; + uint8_t key[16]; + uint8_t iv[16]; + uint8_t *inbuf = NULL; + size_t inlen; + uint8_t *cms = NULL; + size_t cmslen; + uint8_t *cert; + + if (argc < 2) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + // 预先统计证书缓冲大小和输入大小 + if (get_files_size(argc, argv, "-rcptcert", &rcpt_certs_len) != 1) { + goto end; + } + if (rcpt_certs_len <= 0) { + fprintf(stderr, "%s: invalid cert length\n", prog); + goto end; + } + rcpt_certs_len = (rcpt_certs_len * 3)/4; + if (!(rcpt_certs = malloc(rcpt_certs_len))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + cert = rcpt_certs; + + if (get_files_size(argc, argv, "-in", &inlen) != 1) { + goto end; + } + if (inlen <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(inbuf = malloc(inlen))) { + fprintf(stderr, "%s: %s\n", prog, strerror(errno)); + goto end; + } + + argc--; + argv++; + + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-rcptcert")) { + char *certfile; + FILE *certfp; + size_t certlen; + if (--argc < 1) goto bad; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } + if (x509_cert_from_pem(cert, &certlen, rcpt_certs_len, certfp) != 1) { + fprintf(stderr, "%s: error\n", prog); + fclose(certfp); + goto end; + } + cert += certlen; + fclose(certfp); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + if ((inlen = fread(inbuf, 1, inlen, infp)) <= 0) { + fprintf(stderr, "%s: read data error: %s\n", prog, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + rcpt_certs_len = cert - rcpt_certs; + + if (rand_bytes(key, sizeof(key)) != 1 + || rand_bytes(iv, sizeof(iv)) != 1 + || cms_envelop(NULL, &cmslen, rcpt_certs, rcpt_certs_len, + OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), + OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (!(cms = malloc(cmslen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (cms_envelop(cms, &cmslen, rcpt_certs, rcpt_certs_len, + OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv), + OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (cms_to_pem(cms, cmslen, outfp) != 1) { + fprintf(stderr, "%s: output CMS failure\n", prog); + goto end; + } + + ret = 0; + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (rcpt_certs) free(rcpt_certs); + if (cms) free(cms); + return ret; +} diff --git a/tools/cmsparse.c b/tools/cmsparse.c index 0efab849..66e46968 100644 --- a/tools/cmsparse.c +++ b/tools/cmsparse.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,82 +7,83 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-in file"; - -int cmsparse_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - FILE *infp = stdin; - struct stat st; - uint8_t *cms = NULL; - size_t cms_maxlen, cmslen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!infile) { - fprintf(stderr, "%s: option '-in' required'\n", prog); - goto end; - } - - if (fstat(fileno(infp), &st) < 0) { - fprintf(stderr, "%s: access '%s' failed : %s\n", prog, infile, strerror(errno)); - goto end; - } - cms_maxlen = (st.st_size * 3)/4 + 1; - if (!(cms = malloc(cms_maxlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { - fprintf(stderr, "%s: parse CMS error\n", prog); - goto end; - } - cms_print(stdout, 0, 0, "CMS", cms, cmslen); - ret = 0; -end: - if (infp) fclose(infp); - if (cms) free(cms); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-in file"; + +int cmsparse_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + FILE *infp = stdin; + struct stat st; + uint8_t *cms = NULL; + size_t cms_maxlen, cmslen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!infile) { + fprintf(stderr, "%s: option '-in' required'\n", prog); + goto end; + } + + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access '%s' failed : %s\n", prog, infile, strerror(errno)); + goto end; + } + cms_maxlen = (st.st_size * 3)/4 + 1; + if (!(cms = malloc(cms_maxlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { + fprintf(stderr, "%s: parse CMS error\n", prog); + goto end; + } + cms_print(stdout, 0, 0, "CMS", cms, cmslen); + ret = 0; +end: + if (infp) fclose(infp); + if (cms) free(cms); + return ret; +} diff --git a/tools/cmssign.c b/tools/cmssign.c index 40335745..dd8ba1bf 100644 --- a/tools/cmssign.c +++ b/tools/cmssign.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,202 +7,203 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -/* -302 typedef struct { -303 uint8_t *certs; -304 size_t certs_len; -305 SM2_KEY *sign_key; -306 } CMS_CERTS_AND_KEY; - - - -输出长度主要由输入长度和 - -*/ - -static const char *options = "-key file -pass str -cert file -in file [-out file]"; - -int cmssign_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyfile = NULL; - char *pass = NULL; - char *certfile = NULL; - char *infile = NULL; - char *outfile = NULL; - FILE *keyfp = NULL; - FILE *certfp = NULL; - FILE *infp = NULL; - FILE *outfp = stdout; - SM2_KEY key; - uint8_t cert[1024]; - size_t certlen; - struct stat st; - uint8_t *in = NULL; - size_t inlen; - uint8_t *cms = NULL; - size_t cmslen, cms_maxlen; - CMS_CERTS_AND_KEY cert_and_key; - - int content_type; - uint8_t *content = NULL; - size_t content_len; - - const uint8_t *rcpt_infos; - size_t rcpt_infos_len; - const uint8_t *shared_info1; - const uint8_t *shared_info2; - size_t shared_info1_len, shared_info2_len; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - if (!(certfp = fopen(certfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - if (!certfile) { - fprintf(stderr, "%s: '-cert' option required\n", prog); - goto end; - } - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - fprintf(stderr, "%s: private key decryption failure\n", prog); - goto end; - } - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { - fprintf(stderr, "%s: load certificate failure\n", prog); - goto end; - } - { - SM2_KEY public_key; - if (x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { - fprintf(stderr, "%s: parse certficate failure\n", prog); - goto end; - } - if (sm2_public_key_equ(&key, &public_key) != 1) { - fprintf(stderr, "%s: key and cert are not match!\n", prog); - goto end; - } - } - - cert_and_key.certs = cert; - cert_and_key.certs_len = certlen; - cert_and_key.sign_key = &key; - - if (fstat(fileno(infp), &st) < 0) { - fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); - goto end; - } - if ((inlen = st.st_size) <= 0) { - fprintf(stderr, "%s: invalid input length\n", prog); - goto end; - } - if (!(in = malloc(inlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (fread(in, 1, inlen, infp) != inlen) { - fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); - goto end; - } - - cms_maxlen = (inlen * 4)/3 + 4096; // 主要由SignerInfos,其中的DN长度决定 - if (!(cms = malloc(cms_maxlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - - if (cms_sign(cms, &cmslen, &cert_and_key, 1, OID_cms_data, in, inlen, NULL, 0) != 1) { - fprintf(stderr, "%s: sign failure\n", prog); - goto end; - } - - if (cms_to_pem(cms, cmslen, outfp) != 1) { - fprintf(stderr, "%s: output failure\n", prog); - goto end; - } - - ret = 0; - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (keyfile && keyfp) fclose(keyfp); - if (cms) free(cms); - if (in) free(in); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* +302 typedef struct { +303 uint8_t *certs; +304 size_t certs_len; +305 SM2_KEY *sign_key; +306 } CMS_CERTS_AND_KEY; + + + +输出长度主要由输入长度和 + +*/ + +static const char *options = "-key file -pass str -cert file -in file [-out file]"; + +int cmssign_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyfile = NULL; + char *pass = NULL; + char *certfile = NULL; + char *infile = NULL; + char *outfile = NULL; + FILE *keyfp = NULL; + FILE *certfp = NULL; + FILE *infp = NULL; + FILE *outfp = stdout; + SM2_KEY key; + uint8_t cert[1024]; + size_t certlen; + struct stat st; + uint8_t *in = NULL; + size_t inlen; + uint8_t *cms = NULL; + size_t cmslen, cms_maxlen; + CMS_CERTS_AND_KEY cert_and_key; + + int content_type; + uint8_t *content = NULL; + size_t content_len; + + const uint8_t *rcpt_infos; + size_t rcpt_infos_len; + const uint8_t *shared_info1; + const uint8_t *shared_info2; + size_t shared_info1_len, shared_info2_len; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + goto end; + } + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; + } + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { + fprintf(stderr, "%s: load certificate failure\n", prog); + goto end; + } + { + SM2_KEY public_key; + if (x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + fprintf(stderr, "%s: parse certficate failure\n", prog); + goto end; + } + if (sm2_public_key_equ(&key, &public_key) != 1) { + fprintf(stderr, "%s: key and cert are not match!\n", prog); + goto end; + } + } + + cert_and_key.certs = cert; + cert_and_key.certs_len = certlen; + cert_and_key.sign_key = &key; + + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); + goto end; + } + if ((inlen = st.st_size) <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(in = malloc(inlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (fread(in, 1, inlen, infp) != inlen) { + fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); + goto end; + } + + cms_maxlen = (inlen * 4)/3 + 4096; // 主要由SignerInfos,其中的DN长度决定 + if (!(cms = malloc(cms_maxlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + + if (cms_sign(cms, &cmslen, &cert_and_key, 1, OID_cms_data, in, inlen, NULL, 0) != 1) { + fprintf(stderr, "%s: sign failure\n", prog); + goto end; + } + + if (cms_to_pem(cms, cmslen, outfp) != 1) { + fprintf(stderr, "%s: output failure\n", prog); + goto end; + } + + ret = 0; + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (keyfile && keyfp) fclose(keyfp); + if (cms) free(cms); + if (in) free(in); + return ret; +} diff --git a/tools/cmsverify.c b/tools/cmsverify.c index fdc03a27..6d1aca35 100644 --- a/tools/cmsverify.c +++ b/tools/cmsverify.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,133 +7,134 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include - - - -static const char *options = "-in file [-out file]"; - -int cmsverify_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = NULL; - FILE *outfp = NULL; - struct stat st; - uint8_t *cms = NULL; - size_t cmslen, cms_maxlen; - - int content_type; - const uint8_t *content; - size_t content_len; - const uint8_t *certs; - size_t certslen; - const uint8_t *crls; - size_t crlslen; - const uint8_t *signer_infos; - size_t signer_infos_len; - int rv; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - fstat(fileno(infp), &st); - cms_maxlen = (st.st_size * 3)/4 + 1; - if (!(cms = malloc(cms_maxlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { - fprintf(stderr, "%s: read CMS failure\n", prog); - goto end; - } - - if ((rv = cms_verify(cms, cmslen, NULL, 0, NULL, 0, - &content_type, &content, &content_len, - &certs, &certslen, &crls, &crlslen, - &signer_infos, &signer_infos_len)) < 0) { - fprintf(stderr, "%s: verify error\n", prog); - goto end; - } - printf("verify %s\n", rv ? "success" : "failure"); - ret = rv ? 0 : 1; - - if (outfile) { - const uint8_t *p; - size_t len; - - if (content_type == OID_cms_data) { - if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1 - || asn1_length_is_zero(content_len) != 1) { - fprintf(stderr, "%s: invalid CMS\n", prog); - goto end; - } - if (len != fwrite(p, 1, len, outfp)) { - fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - } - - - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (cms) free(cms); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include + + + +static const char *options = "-in file [-out file]"; + +int cmsverify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = NULL; + FILE *outfp = NULL; + struct stat st; + uint8_t *cms = NULL; + size_t cmslen, cms_maxlen; + + int content_type; + const uint8_t *content; + size_t content_len; + const uint8_t *certs; + size_t certslen; + const uint8_t *crls; + size_t crlslen; + const uint8_t *signer_infos; + size_t signer_infos_len; + int rv; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + fstat(fileno(infp), &st); + cms_maxlen = (st.st_size * 3)/4 + 1; + if (!(cms = malloc(cms_maxlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) { + fprintf(stderr, "%s: read CMS failure\n", prog); + goto end; + } + + if ((rv = cms_verify(cms, cmslen, NULL, 0, NULL, 0, + &content_type, &content, &content_len, + &certs, &certslen, &crls, &crlslen, + &signer_infos, &signer_infos_len)) < 0) { + fprintf(stderr, "%s: verify error\n", prog); + goto end; + } + printf("verify %s\n", rv ? "success" : "failure"); + ret = rv ? 0 : 1; + + if (outfile) { + const uint8_t *p; + size_t len; + + if (content_type == OID_cms_data) { + if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1 + || asn1_length_is_zero(content_len) != 1) { + fprintf(stderr, "%s: invalid CMS\n", prog); + goto end; + } + if (len != fwrite(p, 1, len, outfp)) { + fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + } + + + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (cms) free(cms); + return ret; +} diff --git a/tools/copyright.sh b/tools/copyright.sh index 7c6022fb..4c629c35 100755 --- a/tools/copyright.sh +++ b/tools/copyright.sh @@ -3,7 +3,7 @@ YEAR=`date "+%Y"` COPYRIGHT="" COPYRIGHT+="/*"$'\n' -COPYRIGHT+=" * Copyright $YEAR The GmSSL Project. All Rights Reserved."$'\n' +COPYRIGHT+=" * Copyright 2014-$YEAR The GmSSL Project. All Rights Reserved."$'\n' COPYRIGHT+=" *"$'\n' COPYRIGHT+=" * Licensed under the Apache License, Version 2.0 (the "License"); you may"$'\n' COPYRIGHT+=" * not use this file except in compliance with the License."$'\n' @@ -50,4 +50,4 @@ function getDir() { getDir .. -rm -f $COPYRIGHT_FILE \ No newline at end of file +rm -f $COPYRIGHT_FILE diff --git a/tools/crlparse.c b/tools/crlparse.c index 1ee0b2f4..02701754 100644 --- a/tools/crlparse.c +++ b/tools/crlparse.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,102 +7,103 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-in file [-out file]"; - -int crlparse_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - struct stat st; - uint8_t *in = NULL; - size_t inlen; - const uint8_t *pin; - const uint8_t *crl = NULL; - size_t crllen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - if (fstat(fileno(infp), &st) < 0) { - fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); - goto end; - } - if ((inlen = st.st_size) <= 0) { - fprintf(stderr, "%s: invalid input length\n", prog); - goto end; - } - if (!(in = malloc(inlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (fread(in, 1, inlen, infp) != inlen) { - fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); - goto end; - } - pin = in; - if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 - || asn1_length_is_zero(inlen) != 1) { - fprintf(stderr, "%s: read CRL failure\n", prog); - goto end; - } - x509_crl_print(outfp, 0, 0, "CRL", crl, crllen); - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (in) free(in); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-in file [-out file]"; + +int crlparse_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + struct stat st; + uint8_t *in = NULL; + size_t inlen; + const uint8_t *pin; + const uint8_t *crl = NULL; + size_t crllen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); + goto end; + } + if ((inlen = st.st_size) <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(in = malloc(inlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (fread(in, 1, inlen, infp) != inlen) { + fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); + goto end; + } + pin = in; + if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + fprintf(stderr, "%s: read CRL failure\n", prog); + goto end; + } + x509_crl_print(outfp, 0, 0, "CRL", crl, crllen); + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (in) free(in); + return ret; +} diff --git a/tools/crlverify.c b/tools/crlverify.c index 5378d5a2..f3e448ce 100644 --- a/tools/crlverify.c +++ b/tools/crlverify.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,150 +7,151 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-in file -cacert file\n"; - -int crlverify_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *cacertfile = NULL; - FILE *infp = NULL; - FILE *cacertfp = NULL; - uint8_t *in = NULL; - size_t inlen; - struct stat st; - const uint8_t *pin; - const uint8_t *crl = NULL; - size_t crllen; - const uint8_t *subject; - size_t subject_len; - uint8_t cacert[1024]; - size_t cacertlen; - int rv; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - if (!(cacertfp = fopen(cacertfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!infile) { - fprintf(stderr, "%s: '-in' option required\n", prog); - goto end; - } - if (!cacertfile) { - fprintf(stderr, "%s: '-cacert' option required\n", prog); - goto end; - } - - - if (fstat(fileno(infp), &st) < 0) { - fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); - goto end; - } - if ((inlen = st.st_size) <= 0) { - fprintf(stderr, "%s: invalid input length\n", prog); - goto end; - } - if (!(in = malloc(inlen))) { - fprintf(stderr, "%s: malloc failure\n", prog); - goto end; - } - if (fread(in, 1, inlen, infp) != inlen) { - fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); - goto end; - } - pin = in; - if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 - || asn1_length_is_zero(inlen) != 1) { - fprintf(stderr, "%s: read CRL failure\n", prog); - goto end; - } - - if (x509_crl_get_issuer(crl, crllen, &subject, &subject_len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { - fprintf(stderr, "%s: read certificate failure\n", prog); - goto end; - } - if ((rv = x509_crl_verify_by_ca_cert(crl, crllen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { - fprintf(stderr, "%s: verification inner error\n", prog); - goto end; - } - - printf("Verification %s\n", rv ? "success" : "failure"); - if (rv == 1) ret = 0; - -end: - if (infile && infp) fclose(infp); - if (cacertfp) fclose(cacertfp); - if (in) free(in); - return ret; -} - - - - - - - - - - - - - - - - - - - - - + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-in file -cacert file\n"; + +int crlverify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *cacertfile = NULL; + FILE *infp = NULL; + FILE *cacertfp = NULL; + uint8_t *in = NULL; + size_t inlen; + struct stat st; + const uint8_t *pin; + const uint8_t *crl = NULL; + size_t crllen; + const uint8_t *subject; + size_t subject_len; + uint8_t cacert[1024]; + size_t cacertlen; + int rv; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + if (!(cacertfp = fopen(cacertfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!infile) { + fprintf(stderr, "%s: '-in' option required\n", prog); + goto end; + } + if (!cacertfile) { + fprintf(stderr, "%s: '-cacert' option required\n", prog); + goto end; + } + + + if (fstat(fileno(infp), &st) < 0) { + fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno)); + goto end; + } + if ((inlen = st.st_size) <= 0) { + fprintf(stderr, "%s: invalid input length\n", prog); + goto end; + } + if (!(in = malloc(inlen))) { + fprintf(stderr, "%s: malloc failure\n", prog); + goto end; + } + if (fread(in, 1, inlen, infp) != inlen) { + fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno)); + goto end; + } + pin = in; + if (x509_crl_from_der(&crl, &crllen, &pin, &inlen) != 1 + || asn1_length_is_zero(inlen) != 1) { + fprintf(stderr, "%s: read CRL failure\n", prog); + goto end; + } + + if (x509_crl_get_issuer(crl, crllen, &subject, &subject_len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), subject, subject_len, cacertfp) != 1) { + fprintf(stderr, "%s: read certificate failure\n", prog); + goto end; + } + if ((rv = x509_crl_verify_by_ca_cert(crl, crllen, cacert, cacertlen, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID))) < 0) { + fprintf(stderr, "%s: verification inner error\n", prog); + goto end; + } + + printf("Verification %s\n", rv ? "success" : "failure"); + if (rv == 1) ret = 0; + +end: + if (infile && infp) fclose(infp); + if (cacertfp) fclose(cacertfp); + if (in) free(in); + return ret; +} + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/gmssl.c b/tools/gmssl.c index 02c7f780..49db6efb 100644 --- a/tools/gmssl.c +++ b/tools/gmssl.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,204 +7,205 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include - - -extern int version_main(int argc, char **argv); -extern int rand_main(int argc, char **argv); -extern int certgen_main(int argc, char **argv); -extern int certparse_main(int argc, char **argv); -extern int certverify_main(int argc, char **argv); -extern int crlparse_main(int argc, char **argv); -extern int crlverify_main(int argc, char **argv); -extern int pbkdf2_main(int argc, char **argv); -extern int reqgen_main(int argc, char **argv); -extern int reqparse_main(int argc, char **argv); -extern int reqsign_main(int argc, char **argv); -extern int sm2keygen_main(int argc, char **argv); -extern int sm2sign_main(int argc, char **argv); -extern int sm2verify_main(int argc, char **argv); -extern int sm2encrypt_main(int argc, char **argv); -extern int sm2decrypt_main(int argc, char **argv); -extern int sm3_main(int argc, char **argv); -extern int sm3hmac_main(int argc, char **argv); -extern int sm4_main(int argc, char **argv); -extern int zuc_main(int argc, char **argv); -extern int sm9setup_main(int argc, char **argv); -extern int sm9keygen_main(int argc, char **argv); -extern int sm9sign_main(int argc, char **argv); -extern int sm9verify_main(int argc, char **argv); -extern int sm9encrypt_main(int argc, char **argv); -extern int sm9decrypt_main(int argc, char **argv); -extern int cmsparse_main(int argc, char **argv); -extern int cmsencrypt_main(int argc, char **argv); -extern int cmsdecrypt_main(int argc, char **argv); -extern int cmssign_main(int argc, char **argv); -extern int cmsverify_main(int argc, char **argv); -extern int tlcp_client_main(int argc, char **argv); -extern int tlcp_server_main(int argc, char **argv); -extern int tls12_client_main(int argc, char **argv); -extern int tls12_server_main(int argc, char **argv); -extern int tls13_client_main(int argc, char **argv); -extern int tls13_server_main(int argc, char **argv); -extern int sdfutil_main(int argc, char **argv); -extern int skfutil_main(int argc, char **argv); - - -static const char *options = - "command [options]\n" - "\n" - "Commands:\n" - " help Print this help message\n" - " version Print version\n" - " rand Generate random bytes\n" - " sm2keygen Generate SM2 keypair\n" - " sm2sign Generate SM2 signature\n" - " sm2verify Verify SM2 signature\n" - " sm2encrypt Encrypt with SM2 public key\n" - " sm2decrypt Decrypt with SM2 private key\n" - " sm3 Generate SM3 hash\n" - " sm3hmac Generate SM3 HMAC tag\n" - " sm4 Encrypt or decrypt with SM4\n" - " zuc Encrypt or decrypt with ZUC\n" - " sm9setup Generate SM9 master secret\n" - " sm9keygen Generate SM9 private key\n" - " sm9sign Generate SM9 signature\n" - " sm9verify Verify SM9 signature\n" - " sm9encrypt SM9 public key encryption\n" - " sm9decrypt SM9 decryption\n" - " pbkdf2 Generate key from password\n" - " reqgen Generate certificate signing request (CSR)\n" - " reqsign Generate certificate from CSR\n" - " reqparse Parse and print a CSR\n" - " crlparse Verify a CRL with certificate\n" - " crlverify Parse and print CRL\n" - " certgen Generate a self-signed certificate\n" - " certparse Parse and print certificates\n" - " certverify Verify certificate chain\n" - " cmsparse Parse cryptographic message syntax (CMS)\n" - " cmsencrypt Generate CMS EnvelopedData\n" - " cmsdecrypt Decrypt CMS EnvelopedData\n" - " cmssign Generate CMS SignedData\n" - " cmsverify Verify CMS SignedData\n" - " sdfutil SDF crypto device utility\n" - " skfutil SKF crypto device utility\n" - " tlcp_client TLCP client\n" - " tlcp_server TLCP server\n" - " tls12_client TLS 1.2 client\n" - " tls12_server TLS 1.2 server\n" - " tls13_client TLS 1.3 client\n" - " tls13_server TLS 1.3 server\n"; - - - -int main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - - argc--; - argv++; - - if (argc < 1) { - printf("Usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "version")) { - return version_main(argc, argv); - } else if (!strcmp(*argv, "rand")) { - return rand_main(argc, argv); - } else if (!strcmp(*argv, "certgen")) { - return certgen_main(argc, argv); - } else if (!strcmp(*argv, "certparse")) { - return certparse_main(argc, argv); - } else if (!strcmp(*argv, "certverify")) { - return certverify_main(argc, argv); - } else if (!strcmp(*argv, "crlparse")) { - return crlparse_main(argc, argv); - } else if (!strcmp(*argv, "crlverify")) { - return crlverify_main(argc, argv); - } else if (!strcmp(*argv, "reqgen")) { - return reqgen_main(argc, argv); - } else if (!strcmp(*argv, "reqparse")) { - return reqparse_main(argc, argv); - } else if (!strcmp(*argv, "reqsign")) { - return reqsign_main(argc, argv); - } else if (!strcmp(*argv, "pbkdf2")) { - return pbkdf2_main(argc, argv); - } else if (!strcmp(*argv, "sm2keygen")) { - return sm2keygen_main(argc, argv); - } else if (!strcmp(*argv, "sm2sign")) { - return sm2sign_main(argc, argv); - } else if (!strcmp(*argv, "sm2verify")) { - return sm2verify_main(argc, argv); - } else if (!strcmp(*argv, "sm2encrypt")) { - return sm2encrypt_main(argc, argv); - } else if (!strcmp(*argv, "sm2decrypt")) { - return sm2decrypt_main(argc, argv); - } else if (!strcmp(*argv, "sm3")) { - return sm3_main(argc, argv); - } else if (!strcmp(*argv, "sm3hmac")) { - return sm3hmac_main(argc, argv); - } else if (!strcmp(*argv, "sm4")) { - return sm4_main(argc, argv); - } else if (!strcmp(*argv, "zuc")) { - return zuc_main(argc, argv); - } else if (!strcmp(*argv, "sm9setup")) { - return sm9setup_main(argc, argv); - } else if (!strcmp(*argv, "sm9keygen")) { - return sm9keygen_main(argc, argv); - } else if (!strcmp(*argv, "sm9sign")) { - return sm9sign_main(argc, argv); - } else if (!strcmp(*argv, "sm9verify")) { - return sm9verify_main(argc, argv); - } else if (!strcmp(*argv, "sm9encrypt")) { - return sm9encrypt_main(argc, argv); - } else if (!strcmp(*argv, "sm9decrypt")) { - return sm9decrypt_main(argc, argv); - } else if (!strcmp(*argv, "cmsparse")) { - return cmsparse_main(argc, argv); - } else if (!strcmp(*argv, "cmsencrypt")) { - return cmsencrypt_main(argc, argv); - } else if (!strcmp(*argv, "cmsdecrypt")) { - return cmsdecrypt_main(argc, argv); - } else if (!strcmp(*argv, "cmssign")) { - return cmssign_main(argc, argv); - } else if (!strcmp(*argv, "cmsverify")) { - return cmsverify_main(argc, argv); - } else if (!strcmp(*argv, "tlcp_client")) { - return tlcp_client_main(argc, argv); - } else if (!strcmp(*argv, "tlcp_server")) { - return tlcp_server_main(argc, argv); - } else if (!strcmp(*argv, "tls12_client")) { - return tls12_client_main(argc, argv); - } else if (!strcmp(*argv, "tls12_server")) { - return tls12_server_main(argc, argv); - } else if (!strcmp(*argv, "tls13_client")) { - return tls13_client_main(argc, argv); - } else if (!strcmp(*argv, "tls13_server")) { - return tls13_server_main(argc, argv); - } else if (!strcmp(*argv, "sdfutil")) { - return sdfutil_main(argc, argv); - } else if (!strcmp(*argv, "skfutil")) { - return skfutil_main(argc, argv); - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - argc--; - argv++; - } - - return ret; -} + + +#include +#include +#include + + +extern int version_main(int argc, char **argv); +extern int rand_main(int argc, char **argv); +extern int certgen_main(int argc, char **argv); +extern int certparse_main(int argc, char **argv); +extern int certverify_main(int argc, char **argv); +extern int crlparse_main(int argc, char **argv); +extern int crlverify_main(int argc, char **argv); +extern int pbkdf2_main(int argc, char **argv); +extern int reqgen_main(int argc, char **argv); +extern int reqparse_main(int argc, char **argv); +extern int reqsign_main(int argc, char **argv); +extern int sm2keygen_main(int argc, char **argv); +extern int sm2sign_main(int argc, char **argv); +extern int sm2verify_main(int argc, char **argv); +extern int sm2encrypt_main(int argc, char **argv); +extern int sm2decrypt_main(int argc, char **argv); +extern int sm3_main(int argc, char **argv); +extern int sm3hmac_main(int argc, char **argv); +extern int sm4_main(int argc, char **argv); +extern int zuc_main(int argc, char **argv); +extern int sm9setup_main(int argc, char **argv); +extern int sm9keygen_main(int argc, char **argv); +extern int sm9sign_main(int argc, char **argv); +extern int sm9verify_main(int argc, char **argv); +extern int sm9encrypt_main(int argc, char **argv); +extern int sm9decrypt_main(int argc, char **argv); +extern int cmsparse_main(int argc, char **argv); +extern int cmsencrypt_main(int argc, char **argv); +extern int cmsdecrypt_main(int argc, char **argv); +extern int cmssign_main(int argc, char **argv); +extern int cmsverify_main(int argc, char **argv); +extern int tlcp_client_main(int argc, char **argv); +extern int tlcp_server_main(int argc, char **argv); +extern int tls12_client_main(int argc, char **argv); +extern int tls12_server_main(int argc, char **argv); +extern int tls13_client_main(int argc, char **argv); +extern int tls13_server_main(int argc, char **argv); +extern int sdfutil_main(int argc, char **argv); +extern int skfutil_main(int argc, char **argv); + + +static const char *options = + "command [options]\n" + "\n" + "Commands:\n" + " help Print this help message\n" + " version Print version\n" + " rand Generate random bytes\n" + " sm2keygen Generate SM2 keypair\n" + " sm2sign Generate SM2 signature\n" + " sm2verify Verify SM2 signature\n" + " sm2encrypt Encrypt with SM2 public key\n" + " sm2decrypt Decrypt with SM2 private key\n" + " sm3 Generate SM3 hash\n" + " sm3hmac Generate SM3 HMAC tag\n" + " sm4 Encrypt or decrypt with SM4\n" + " zuc Encrypt or decrypt with ZUC\n" + " sm9setup Generate SM9 master secret\n" + " sm9keygen Generate SM9 private key\n" + " sm9sign Generate SM9 signature\n" + " sm9verify Verify SM9 signature\n" + " sm9encrypt SM9 public key encryption\n" + " sm9decrypt SM9 decryption\n" + " pbkdf2 Generate key from password\n" + " reqgen Generate certificate signing request (CSR)\n" + " reqsign Generate certificate from CSR\n" + " reqparse Parse and print a CSR\n" + " crlparse Verify a CRL with certificate\n" + " crlverify Parse and print CRL\n" + " certgen Generate a self-signed certificate\n" + " certparse Parse and print certificates\n" + " certverify Verify certificate chain\n" + " cmsparse Parse cryptographic message syntax (CMS)\n" + " cmsencrypt Generate CMS EnvelopedData\n" + " cmsdecrypt Decrypt CMS EnvelopedData\n" + " cmssign Generate CMS SignedData\n" + " cmsverify Verify CMS SignedData\n" + " sdfutil SDF crypto device utility\n" + " skfutil SKF crypto device utility\n" + " tlcp_client TLCP client\n" + " tlcp_server TLCP server\n" + " tls12_client TLS 1.2 client\n" + " tls12_server TLS 1.2 server\n" + " tls13_client TLS 1.3 client\n" + " tls13_server TLS 1.3 server\n"; + + + +int main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + + argc--; + argv++; + + if (argc < 1) { + printf("Usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "version")) { + return version_main(argc, argv); + } else if (!strcmp(*argv, "rand")) { + return rand_main(argc, argv); + } else if (!strcmp(*argv, "certgen")) { + return certgen_main(argc, argv); + } else if (!strcmp(*argv, "certparse")) { + return certparse_main(argc, argv); + } else if (!strcmp(*argv, "certverify")) { + return certverify_main(argc, argv); + } else if (!strcmp(*argv, "crlparse")) { + return crlparse_main(argc, argv); + } else if (!strcmp(*argv, "crlverify")) { + return crlverify_main(argc, argv); + } else if (!strcmp(*argv, "reqgen")) { + return reqgen_main(argc, argv); + } else if (!strcmp(*argv, "reqparse")) { + return reqparse_main(argc, argv); + } else if (!strcmp(*argv, "reqsign")) { + return reqsign_main(argc, argv); + } else if (!strcmp(*argv, "pbkdf2")) { + return pbkdf2_main(argc, argv); + } else if (!strcmp(*argv, "sm2keygen")) { + return sm2keygen_main(argc, argv); + } else if (!strcmp(*argv, "sm2sign")) { + return sm2sign_main(argc, argv); + } else if (!strcmp(*argv, "sm2verify")) { + return sm2verify_main(argc, argv); + } else if (!strcmp(*argv, "sm2encrypt")) { + return sm2encrypt_main(argc, argv); + } else if (!strcmp(*argv, "sm2decrypt")) { + return sm2decrypt_main(argc, argv); + } else if (!strcmp(*argv, "sm3")) { + return sm3_main(argc, argv); + } else if (!strcmp(*argv, "sm3hmac")) { + return sm3hmac_main(argc, argv); + } else if (!strcmp(*argv, "sm4")) { + return sm4_main(argc, argv); + } else if (!strcmp(*argv, "zuc")) { + return zuc_main(argc, argv); + } else if (!strcmp(*argv, "sm9setup")) { + return sm9setup_main(argc, argv); + } else if (!strcmp(*argv, "sm9keygen")) { + return sm9keygen_main(argc, argv); + } else if (!strcmp(*argv, "sm9sign")) { + return sm9sign_main(argc, argv); + } else if (!strcmp(*argv, "sm9verify")) { + return sm9verify_main(argc, argv); + } else if (!strcmp(*argv, "sm9encrypt")) { + return sm9encrypt_main(argc, argv); + } else if (!strcmp(*argv, "sm9decrypt")) { + return sm9decrypt_main(argc, argv); + } else if (!strcmp(*argv, "cmsparse")) { + return cmsparse_main(argc, argv); + } else if (!strcmp(*argv, "cmsencrypt")) { + return cmsencrypt_main(argc, argv); + } else if (!strcmp(*argv, "cmsdecrypt")) { + return cmsdecrypt_main(argc, argv); + } else if (!strcmp(*argv, "cmssign")) { + return cmssign_main(argc, argv); + } else if (!strcmp(*argv, "cmsverify")) { + return cmsverify_main(argc, argv); + } else if (!strcmp(*argv, "tlcp_client")) { + return tlcp_client_main(argc, argv); + } else if (!strcmp(*argv, "tlcp_server")) { + return tlcp_server_main(argc, argv); + } else if (!strcmp(*argv, "tls12_client")) { + return tls12_client_main(argc, argv); + } else if (!strcmp(*argv, "tls12_server")) { + return tls12_server_main(argc, argv); + } else if (!strcmp(*argv, "tls13_client")) { + return tls13_client_main(argc, argv); + } else if (!strcmp(*argv, "tls13_server")) { + return tls13_server_main(argc, argv); + } else if (!strcmp(*argv, "sdfutil")) { + return sdfutil_main(argc, argv); + } else if (!strcmp(*argv, "skfutil")) { + return skfutil_main(argc, argv); + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + argc--; + argv++; + } + + return ret; +} diff --git a/tools/pbkdf2.c b/tools/pbkdf2.c index 7284f856..ac86383a 100644 --- a/tools/pbkdf2.c +++ b/tools/pbkdf2.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,136 +7,137 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-pass str -salt hex -iter num -outlen num [-bin|-hex] [-out file]"; - -int pbkdf2_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *pass = NULL; - char *salthex = NULL; - uint8_t salt[PBKDF2_MAX_SALT_SIZE]; - size_t saltlen; - int iter = 0; - int outlen = 0; - int bin = 0; - char *outfile = NULL; - uint8_t outbuf[64]; - FILE *outfp = stdout; - int i; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-salt")) { - if (--argc < 1) goto bad; - salthex = *(++argv); - if (strlen(salthex) > sizeof(salt) * 2) { - fprintf(stderr, "%s: invalid salt length\n", prog); - goto end; - } - if (hex_to_bytes(salthex, strlen(salthex), salt, &saltlen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-iter")) { - if (--argc < 1) goto bad; - iter = atoi(*(++argv)); - if (iter < PBKDF2_MIN_ITER || iter > INT_MAX) { - fprintf(stderr, "%s: invalid '-iter' value\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-outlen")) { - if (--argc < 1) goto bad; - outlen = atoi(*(++argv)); - if (outlen < 1 || outlen > sizeof(outbuf)) { - fprintf(stderr, "%s: invalid outlen\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-hex")) { - bin = 0; - } else if (!strcmp(*argv, "-bin")) { - bin = 1; - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!pass) { - fprintf(stderr, "%s: option '-pass' required\n", prog); - goto end; - } - if (!salthex) { - fprintf(stderr, "%s: option '-salt' required\n", prog); - goto end; - } - if (!iter) { - fprintf(stderr, "%s: option '-iter' required\n", prog); - goto end; - } - if (!outlen) { - fprintf(stderr, "%s: option '-outlen' required\n", prog); - goto end; - } - - if (pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, saltlen, iter, outlen, outbuf) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - - if (bin) { - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } else { - for (i = 0; i < outlen; i++) { - fprintf(outfp, "%02x", outbuf[i]); - } - fprintf(outfp, "\n"); - } - ret = 0; - -end: - gmssl_secure_clear(outbuf, sizeof(outbuf)); - gmssl_secure_clear(salt, sizeof(salt)); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-pass str -salt hex -iter num -outlen num [-bin|-hex] [-out file]"; + +int pbkdf2_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *pass = NULL; + char *salthex = NULL; + uint8_t salt[PBKDF2_MAX_SALT_SIZE]; + size_t saltlen; + int iter = 0; + int outlen = 0; + int bin = 0; + char *outfile = NULL; + uint8_t outbuf[64]; + FILE *outfp = stdout; + int i; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-salt")) { + if (--argc < 1) goto bad; + salthex = *(++argv); + if (strlen(salthex) > sizeof(salt) * 2) { + fprintf(stderr, "%s: invalid salt length\n", prog); + goto end; + } + if (hex_to_bytes(salthex, strlen(salthex), salt, &saltlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-iter")) { + if (--argc < 1) goto bad; + iter = atoi(*(++argv)); + if (iter < PBKDF2_MIN_ITER || iter > INT_MAX) { + fprintf(stderr, "%s: invalid '-iter' value\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-outlen")) { + if (--argc < 1) goto bad; + outlen = atoi(*(++argv)); + if (outlen < 1 || outlen > sizeof(outbuf)) { + fprintf(stderr, "%s: invalid outlen\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-hex")) { + bin = 0; + } else if (!strcmp(*argv, "-bin")) { + bin = 1; + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!pass) { + fprintf(stderr, "%s: option '-pass' required\n", prog); + goto end; + } + if (!salthex) { + fprintf(stderr, "%s: option '-salt' required\n", prog); + goto end; + } + if (!iter) { + fprintf(stderr, "%s: option '-iter' required\n", prog); + goto end; + } + if (!outlen) { + fprintf(stderr, "%s: option '-outlen' required\n", prog); + goto end; + } + + if (pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, saltlen, iter, outlen, outbuf) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + if (bin) { + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } else { + for (i = 0; i < outlen; i++) { + fprintf(outfp, "%02x", outbuf[i]); + } + fprintf(outfp, "\n"); + } + ret = 0; + +end: + gmssl_secure_clear(outbuf, sizeof(outbuf)); + gmssl_secure_clear(salt, sizeof(salt)); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/rand.c b/tools/rand.c index 7ecabcdd..a1f9467c 100644 --- a/tools/rand.c +++ b/tools/rand.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,114 +7,115 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-hex] [-rdrand] -outlen num [-out file]"; - -int rand_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int hex = 0; - int rdrand = 0; - int outlen = 0; - char *outfile = NULL; - FILE *outfp = stdout; - uint8_t buf[2048]; - int i; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-hex")) { - hex = 1; - } else if (!strcmp(*argv, "-rdrand")) { - rdrand = 1; - } else if (!strcmp(*argv, "-outlen")) { - if (--argc < 1) goto bad; - outlen = atoi(*(++argv)); - if (outlen < 1 || outlen > INT_MAX) { - fprintf(stderr, "%s: invalid outlen\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!outlen) { - fprintf(stderr, "%s: option -outlen missing\n", prog); - goto end; - } - - while (outlen) { - size_t len = outlen < sizeof(buf) ? outlen : sizeof(buf); - - if (rdrand) { -/* - if (rdrand_bytes(buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } -*/ - } else { - if (rand_bytes(buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - } - - if (hex) { - int i; - for (i = 0; i < len; i++) { - fprintf(outfp, "%02X", buf[i]); - } - } else { - if (fwrite(buf, 1, len, outfp) != len) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - outlen -= len; - } - if (hex) { - fprintf(outfp, "\n"); - } - ret = 0; -end: - gmssl_secure_clear(buf, sizeof(buf)); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-hex] [-rdrand] -outlen num [-out file]"; + +int rand_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int hex = 0; + int rdrand = 0; + int outlen = 0; + char *outfile = NULL; + FILE *outfp = stdout; + uint8_t buf[2048]; + int i; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-hex")) { + hex = 1; + } else if (!strcmp(*argv, "-rdrand")) { + rdrand = 1; + } else if (!strcmp(*argv, "-outlen")) { + if (--argc < 1) goto bad; + outlen = atoi(*(++argv)); + if (outlen < 1 || outlen > INT_MAX) { + fprintf(stderr, "%s: invalid outlen\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!outlen) { + fprintf(stderr, "%s: option -outlen missing\n", prog); + goto end; + } + + while (outlen) { + size_t len = outlen < sizeof(buf) ? outlen : sizeof(buf); + + if (rdrand) { +/* + if (rdrand_bytes(buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } +*/ + } else { + if (rand_bytes(buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + } + + if (hex) { + int i; + for (i = 0; i < len; i++) { + fprintf(outfp, "%02X", buf[i]); + } + } else { + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + outlen -= len; + } + if (hex) { + fprintf(outfp, "\n"); + } + ret = 0; +end: + gmssl_secure_clear(buf, sizeof(buf)); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/reqgen.c b/tools/reqgen.c index de59a397..3d548920 100644 --- a/tools/reqgen.c +++ b/tools/reqgen.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,153 +7,154 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = - "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num" - " -key file [-pass pass] [-out file]"; - -int reqgen_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *country = NULL; - char *state = NULL; - char *locality = NULL; - char *org = NULL; - char *org_unit = NULL; - char *common_name = NULL; - int days = 0; - char *keyfile = NULL; - char *pass = NULL; - char *outfile = NULL; - uint8_t name[256]; - size_t namelen = 0; - FILE *keyfp = NULL; - FILE *outfp = stdout; - uint8_t req[1024]; - size_t reqlen = 0; - SM2_KEY sm2_key; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-C")) { - if (--argc < 1) goto bad; - country = *(++argv); - } else if (!strcmp(*argv, "-ST")) { - if (--argc < 1) goto bad; - state = *(++argv); - } else if (!strcmp(*argv, "-L")) { - if (--argc < 1) goto bad; - locality = *(++argv); - } else if (!strcmp(*argv, "-O")) { - if (--argc < 1) goto bad; - org = *(++argv); - } else if (!strcmp(*argv, "-OU")) { - if (--argc < 1) goto bad; - org_unit = *(++argv); - } else if (!strcmp(*argv, "-CN")) { - if (--argc < 1) goto bad; - common_name = *(++argv); - } else if (!strcmp(*argv, "-days")) { - if (--argc < 1) goto bad; - days = atoi(*(++argv)); - if (days <= 0) { - fprintf(stderr, "%s: invalid '-days' value\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!common_name) { - fprintf(stderr, "%s: '-CN' option required\n", prog); - goto end; - } - if (!days) { - fprintf(stderr, "%s: '-days' option required\n", prog); - goto end; - } - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { - fprintf(stderr, "%s: load private key failed\n", prog); - goto end; - } - - if (x509_name_set(name, &namelen, sizeof(name), - country, state, locality, org, org_unit, common_name) != 1 - || x509_req_sign(req, &reqlen, sizeof(req), - X509_version_v1, - name, namelen, - &sm2_key, - NULL, 0, - OID_sm2sign_with_sm3, - &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (x509_req_to_pem(req, reqlen, outfp) != 1) { - fprintf(stderr, "%s: output CSR failed\n", prog); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); - if (keyfp) fclose(keyfp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = + "[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num" + " -key file [-pass pass] [-out file]"; + +int reqgen_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *country = NULL; + char *state = NULL; + char *locality = NULL; + char *org = NULL; + char *org_unit = NULL; + char *common_name = NULL; + int days = 0; + char *keyfile = NULL; + char *pass = NULL; + char *outfile = NULL; + uint8_t name[256]; + size_t namelen = 0; + FILE *keyfp = NULL; + FILE *outfp = stdout; + uint8_t req[1024]; + size_t reqlen = 0; + SM2_KEY sm2_key; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-C")) { + if (--argc < 1) goto bad; + country = *(++argv); + } else if (!strcmp(*argv, "-ST")) { + if (--argc < 1) goto bad; + state = *(++argv); + } else if (!strcmp(*argv, "-L")) { + if (--argc < 1) goto bad; + locality = *(++argv); + } else if (!strcmp(*argv, "-O")) { + if (--argc < 1) goto bad; + org = *(++argv); + } else if (!strcmp(*argv, "-OU")) { + if (--argc < 1) goto bad; + org_unit = *(++argv); + } else if (!strcmp(*argv, "-CN")) { + if (--argc < 1) goto bad; + common_name = *(++argv); + } else if (!strcmp(*argv, "-days")) { + if (--argc < 1) goto bad; + days = atoi(*(++argv)); + if (days <= 0) { + fprintf(stderr, "%s: invalid '-days' value\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!common_name) { + fprintf(stderr, "%s: '-CN' option required\n", prog); + goto end; + } + if (!days) { + fprintf(stderr, "%s: '-days' option required\n", prog); + goto end; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + fprintf(stderr, "%s: load private key failed\n", prog); + goto end; + } + + if (x509_name_set(name, &namelen, sizeof(name), + country, state, locality, org, org_unit, common_name) != 1 + || x509_req_sign(req, &reqlen, sizeof(req), + X509_version_v1, + name, namelen, + &sm2_key, + NULL, 0, + OID_sm2sign_with_sm3, + &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_req_to_pem(req, reqlen, outfp) != 1) { + fprintf(stderr, "%s: output CSR failed\n", prog); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); + if (keyfp) fclose(keyfp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/reqparse.c b/tools/reqparse.c index 14e0bfc8..01f8675d 100644 --- a/tools/reqparse.c +++ b/tools/reqparse.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,73 +7,74 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-in file] [-out file]"; - -int reqparse_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - uint8_t req[1024]; - size_t reqlen; - - argc--; - argv++; - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - goto end; - } else if(!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1) { - fprintf(stderr, "%s: read CSR failure\n", prog); - goto end; - } - x509_req_print(outfp, 0, 0, "CertificationRequest", req, reqlen); - if (x509_req_to_pem(req, reqlen, outfp) != 1) { - fprintf(stderr, "%s: output CSR failure\n", prog); - goto end; - } - ret = 0; -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-in file] [-out file]"; + +int reqparse_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + uint8_t req[1024]; + size_t reqlen; + + argc--; + argv++; + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + goto end; + } else if(!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1) { + fprintf(stderr, "%s: read CSR failure\n", prog); + goto end; + } + x509_req_print(outfp, 0, 0, "CertificationRequest", req, reqlen); + if (x509_req_to_pem(req, reqlen, outfp) != 1) { + fprintf(stderr, "%s: output CSR failure\n", prog); + goto end; + } + ret = 0; +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/reqsign.c b/tools/reqsign.c index c16ccbdf..66fea341 100644 --- a/tools/reqsign.c +++ b/tools/reqsign.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,239 +7,240 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-in pem] -days num -cacert pem -key pem [-pass str] [-out pem] " - "-key_usage oid -path_len_constraint num -crl_url url\n"; - -static int ext_key_usage_set(int *usages, const char *usage_name) -{ - int flag = 0; - if (x509_key_usage_from_name(&flag, usage_name) != 1) { - return -1; - } - *usages |= flag; - return 1; -} - -int reqsign_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - int days = 0; - char *cacertfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *cacertfp = NULL; - FILE *keyfp = NULL; - FILE *outfp = stdout; - - uint8_t req[512]; - size_t reqlen; - const uint8_t *subject; - size_t subject_len; - SM2_KEY subject_public_key; - - uint8_t cacert[1024]; - size_t cacertlen; - const uint8_t *issuer; - size_t issuer_len; - SM2_KEY issuer_public_key; - - SM2_KEY sm2_key; - - uint8_t cert[1024]; - size_t certlen; - uint8_t serial[12]; - time_t not_before, not_after; - uint8_t exts[512]; - size_t extslen = 0; - int key_usage = 0; - int path_len_constraint = -1; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc >= 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-days")) { - if (--argc < 1) goto bad; - days = atoi(*(++argv)); - if (days <= 0) { - fprintf(stderr, "%s: invalid '-days' value\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-key_usage")) { - if (--argc < 1) goto bad; - if (ext_key_usage_set(&key_usage, *(++argv)) != 1) { - fprintf(stderr, "%s: set KeyUsage extenstion failure\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-path_len_constraint")) { - if (--argc < 1) goto bad; - path_len_constraint = atoi(*(++argv)); - if (path_len_constraint < 0) { - fprintf(stderr, "%s: invalid value for '-path_len_constraint'\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-crl_url")) { - if (--argc < 1) goto bad; - //crl_url = *(++argv); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - if (!(cacertfp = fopen(cacertfile, "r"))) { - fprintf(stderr, "%s: invalid -key_usage value\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!days) { - fprintf(stderr, "%s: '-days' option required\n", prog); - goto end; - } - if (!cacertfile) { - fprintf(stderr, "%s: '-cacert' option required\n", prog); - goto end; - } - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - - - if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1 - || x509_req_get_details(req, reqlen, - NULL, &subject, &subject_len, &subject_public_key, - NULL, NULL, NULL, NULL, NULL) != 1) { - fprintf(stderr, "%s: parse CSR failure\n", prog); - goto end; - } - - if (x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), cacertfp) != 1 - || x509_cert_get_subject(cacert, cacertlen, &issuer, &issuer_len) != 1 - || x509_cert_get_subject_public_key(cacert, cacertlen, &issuer_public_key) != 1) { - fprintf(stderr, "%s: parse CA certificate failure\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { - fprintf(stderr, "%s: load private key failure\n", prog); - goto end; - } - if (sm2_public_key_equ(&sm2_key, &issuer_public_key) != 1) { - fprintf(stderr, "%s: private key and CA certificate not match\n", prog); - goto end; - } - - if (rand_bytes(serial, sizeof(serial)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - time(¬_before); - - - if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (path_len_constraint >= 0) { - if (x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, path_len_constraint) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - } - if (x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - - if (x509_validity_add_days(¬_after, not_before, days) != 1 - || x509_cert_sign( - cert, &certlen, sizeof(cert), - X509_version_v3, - serial, sizeof(serial), - OID_sm2sign_with_sm3, - issuer, issuer_len, - not_before, not_after, - subject, subject_len, - &subject_public_key, - NULL, 0, - NULL, 0, - exts, extslen, - &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (x509_cert_to_pem(cert, certlen, outfp) != 1) { - fprintf(stderr, "%s: output certificate failed\n", prog); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); - if (keyfp) fclose(keyfp); - if (cacertfp) fclose(cacertfp); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-in pem] -days num -cacert pem -key pem [-pass str] [-out pem] " + "-key_usage oid -path_len_constraint num -crl_url url\n"; + +static int ext_key_usage_set(int *usages, const char *usage_name) +{ + int flag = 0; + if (x509_key_usage_from_name(&flag, usage_name) != 1) { + return -1; + } + *usages |= flag; + return 1; +} + +int reqsign_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + int days = 0; + char *cacertfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *cacertfp = NULL; + FILE *keyfp = NULL; + FILE *outfp = stdout; + + uint8_t req[512]; + size_t reqlen; + const uint8_t *subject; + size_t subject_len; + SM2_KEY subject_public_key; + + uint8_t cacert[1024]; + size_t cacertlen; + const uint8_t *issuer; + size_t issuer_len; + SM2_KEY issuer_public_key; + + SM2_KEY sm2_key; + + uint8_t cert[1024]; + size_t certlen; + uint8_t serial[12]; + time_t not_before, not_after; + uint8_t exts[512]; + size_t extslen = 0; + int key_usage = 0; + int path_len_constraint = -1; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc >= 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-days")) { + if (--argc < 1) goto bad; + days = atoi(*(++argv)); + if (days <= 0) { + fprintf(stderr, "%s: invalid '-days' value\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-key_usage")) { + if (--argc < 1) goto bad; + if (ext_key_usage_set(&key_usage, *(++argv)) != 1) { + fprintf(stderr, "%s: set KeyUsage extenstion failure\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-path_len_constraint")) { + if (--argc < 1) goto bad; + path_len_constraint = atoi(*(++argv)); + if (path_len_constraint < 0) { + fprintf(stderr, "%s: invalid value for '-path_len_constraint'\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-crl_url")) { + if (--argc < 1) goto bad; + //crl_url = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + if (!(cacertfp = fopen(cacertfile, "r"))) { + fprintf(stderr, "%s: invalid -key_usage value\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!days) { + fprintf(stderr, "%s: '-days' option required\n", prog); + goto end; + } + if (!cacertfile) { + fprintf(stderr, "%s: '-cacert' option required\n", prog); + goto end; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + + + if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1 + || x509_req_get_details(req, reqlen, + NULL, &subject, &subject_len, &subject_public_key, + NULL, NULL, NULL, NULL, NULL) != 1) { + fprintf(stderr, "%s: parse CSR failure\n", prog); + goto end; + } + + if (x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), cacertfp) != 1 + || x509_cert_get_subject(cacert, cacertlen, &issuer, &issuer_len) != 1 + || x509_cert_get_subject_public_key(cacert, cacertlen, &issuer_public_key) != 1) { + fprintf(stderr, "%s: parse CA certificate failure\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) { + fprintf(stderr, "%s: load private key failure\n", prog); + goto end; + } + if (sm2_public_key_equ(&sm2_key, &issuer_public_key) != 1) { + fprintf(stderr, "%s: private key and CA certificate not match\n", prog); + goto end; + } + + if (rand_bytes(serial, sizeof(serial)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + time(¬_before); + + + if (x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 1, key_usage) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (path_len_constraint >= 0) { + if (x509_exts_add_basic_constraints(exts, &extslen, sizeof(exts), 1, 1, path_len_constraint) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + } + if (x509_exts_add_default_authority_key_identifier(exts, &extslen, sizeof(exts), &sm2_key) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + if (x509_validity_add_days(¬_after, not_before, days) != 1 + || x509_cert_sign( + cert, &certlen, sizeof(cert), + X509_version_v3, + serial, sizeof(serial), + OID_sm2sign_with_sm3, + issuer, issuer_len, + not_before, not_after, + subject, subject_len, + &subject_public_key, + NULL, 0, + NULL, 0, + exts, extslen, + &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (x509_cert_to_pem(cert, certlen, outfp) != 1) { + fprintf(stderr, "%s: output certificate failed\n", prog); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY)); + if (keyfp) fclose(keyfp); + if (cacertfp) fclose(cacertfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sdfutil.c b/tools/sdfutil.c index 09502afd..16910a43 100644 --- a/tools/sdfutil.c +++ b/tools/sdfutil.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,210 +7,211 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define OP_NONE 0 -#define OP_DEVINFO 1 -#define OP_EXPORTPUBKEY 2 -#define OP_SIGN 3 -#define OP_RAND 4 - - -static void print_usage(FILE *fp, const char *prog) -{ - fprintf(fp, "usage:\n"); - fprintf(fp, " %s -lib so_path -devinfo\n", prog); - fprintf(fp, " %s -lib so_path -exportpubkey -key index [-out file]\n", prog); - fprintf(fp, " %s -lib so_path -sign [-in file] [-out file]\n", prog); - fprintf(fp, " %s -lib so_path -rand num [-out file]\n", prog); -} - -int sdfutil_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *lib = NULL; - int op = 0; - int keyindex = -1; - char *pass = NULL; - char *id = SM2_DEFAULT_ID; - int num = 0; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - unsigned char buf[4096]; - unsigned int ulen; - int len; - SDF_DEVICE dev; - SDF_KEY key; - int dev_opened = 0; - int key_opened = 0; - - memset(&dev, 0, sizeof(dev)); - memset(&key, 0, sizeof(key)); - - argc--; - argv++; - - if (argc < 1) { - print_usage(stderr, prog); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - print_usage(stdout, prog); - goto end; - } else if (!strcmp(*argv, "-lib")) { - if (--argc < 1) goto bad; - lib = *(++argv); - } else if (!strcmp(*argv, "-devinfo")) { - op = OP_DEVINFO; - } else if (!strcmp(*argv, "-exportpubkey")) { - op = OP_EXPORTPUBKEY; - } else if (!strcmp(*argv, "-sign")) { - op = OP_SIGN; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyindex = atoi(*(++argv)); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-rand")) { - if (--argc < 1) goto bad; - len = atoi(*(++argv)); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!lib) { - fprintf(stderr, "%s: option '-lib' required\n", prog); - goto end; - } - if (sdf_load_library(lib, NULL) != 1) { - fprintf(stderr, "%s: load library failure\n", prog); - goto end; - } - - if (sdf_open_device(&dev) != 1) { - fprintf(stderr, "%s: open device failure\n", prog); - goto end; - } - dev_opened = 1; - - switch (op) { - case OP_DEVINFO: - sdf_print_device_info(stdout, 0, 0, "SDF", &dev); - break; - - case OP_EXPORTPUBKEY: - if (keyindex < 0) { - fprintf(stderr, "%s: invalid key index\n", prog); - goto end; - } - if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { - fprintf(stderr, "%s: load sign key failed\n", prog); - goto end; - } - key_opened = 1; - if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { - fprintf(stderr, "%s: output public key to PEM failed\n", prog); - goto end; - } - break; - - case OP_SIGN: - { - SM3_CTX sm3_ctx; - uint8_t dgst[32]; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { - fprintf(stderr, "%s: load sign key failed\n", prog); - goto end; - } - key_opened = 1; - - sm3_init(&sm3_ctx); - sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); - sm3_update(&sm3_ctx, dgst, sizeof(dgst)); - - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm3_update(&sm3_ctx, buf, len); - } - sm3_finish(&sm3_ctx, dgst); - - if ((ret = sdf_sign(&key, dgst, sig, &siglen)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(sig, 1, siglen, outfp) != siglen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - break; - - case OP_RAND: - if (sdf_rand_bytes(&dev, buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(buf, 1, len, outfp) != len) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - break; - - default: - fprintf(stderr, "%s: this should not happen\n", prog); - goto end; - } - ret = 0; - -end: - gmssl_secure_clear(buf, sizeof(buf)); - if (key_opened) sdf_release_key(&key); - if (dev_opened) sdf_close_device(&dev); - if (lib) sdf_unload_library(); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define OP_NONE 0 +#define OP_DEVINFO 1 +#define OP_EXPORTPUBKEY 2 +#define OP_SIGN 3 +#define OP_RAND 4 + + +static void print_usage(FILE *fp, const char *prog) +{ + fprintf(fp, "usage:\n"); + fprintf(fp, " %s -lib so_path -devinfo\n", prog); + fprintf(fp, " %s -lib so_path -exportpubkey -key index [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -sign [-in file] [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -rand num [-out file]\n", prog); +} + +int sdfutil_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *lib = NULL; + int op = 0; + int keyindex = -1; + char *pass = NULL; + char *id = SM2_DEFAULT_ID; + int num = 0; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + unsigned char buf[4096]; + unsigned int ulen; + int len; + SDF_DEVICE dev; + SDF_KEY key; + int dev_opened = 0; + int key_opened = 0; + + memset(&dev, 0, sizeof(dev)); + memset(&key, 0, sizeof(key)); + + argc--; + argv++; + + if (argc < 1) { + print_usage(stderr, prog); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + print_usage(stdout, prog); + goto end; + } else if (!strcmp(*argv, "-lib")) { + if (--argc < 1) goto bad; + lib = *(++argv); + } else if (!strcmp(*argv, "-devinfo")) { + op = OP_DEVINFO; + } else if (!strcmp(*argv, "-exportpubkey")) { + op = OP_EXPORTPUBKEY; + } else if (!strcmp(*argv, "-sign")) { + op = OP_SIGN; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyindex = atoi(*(++argv)); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-rand")) { + if (--argc < 1) goto bad; + len = atoi(*(++argv)); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!lib) { + fprintf(stderr, "%s: option '-lib' required\n", prog); + goto end; + } + if (sdf_load_library(lib, NULL) != 1) { + fprintf(stderr, "%s: load library failure\n", prog); + goto end; + } + + if (sdf_open_device(&dev) != 1) { + fprintf(stderr, "%s: open device failure\n", prog); + goto end; + } + dev_opened = 1; + + switch (op) { + case OP_DEVINFO: + sdf_print_device_info(stdout, 0, 0, "SDF", &dev); + break; + + case OP_EXPORTPUBKEY: + if (keyindex < 0) { + fprintf(stderr, "%s: invalid key index\n", prog); + goto end; + } + if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; + if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { + fprintf(stderr, "%s: output public key to PEM failed\n", prog); + goto end; + } + break; + + case OP_SIGN: + { + SM3_CTX sm3_ctx; + uint8_t dgst[32]; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; + + sm3_init(&sm3_ctx); + sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); + sm3_update(&sm3_ctx, dgst, sizeof(dgst)); + + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + sm3_update(&sm3_ctx, buf, len); + } + sm3_finish(&sm3_ctx, dgst); + + if ((ret = sdf_sign(&key, dgst, sig, &siglen)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(sig, 1, siglen, outfp) != siglen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + break; + + case OP_RAND: + if (sdf_rand_bytes(&dev, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + break; + + default: + fprintf(stderr, "%s: this should not happen\n", prog); + goto end; + } + ret = 0; + +end: + gmssl_secure_clear(buf, sizeof(buf)); + if (key_opened) sdf_release_key(&key); + if (dev_opened) sdf_close_device(&dev); + if (lib) sdf_unload_library(); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/skfutil.c b/tools/skfutil.c index 8c2e9cae..1918c66f 100644 --- a/tools/skfutil.c +++ b/tools/skfutil.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,251 +7,252 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define OP_NONE 0 -#define OP_DEVINFO 1 -#define OP_EXPORTPUBKEY 2 -#define OP_SIGN 3 -#define OP_RAND 4 - - - -static void print_usage(FILE *fp, const char *prog) -{ - fprintf(fp, "usage:\n"); - fprintf(fp, " %s -lib so_path -dev str -devinfo\n", prog); - fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -exportpubkey [-out file]\n", prog); - fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -sign [-in file] [-out file]\n", prog); - fprintf(fp, " %s -lib so_path -dev str -rand num [-out file]\n", prog); -} - -int skfutil_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *lib = NULL; - int op = 0; - char *devname = NULL; - char *authkeystr = NULL; - char *appname = NULL; - char *container_name = NULL; - char *pass = NULL; - char *id = SM2_DEFAULT_ID; - int num = 0; - char *infile = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - unsigned char buf[4096]; - unsigned int ulen; - int len; - - uint8_t authkey[16]; - size_t authkeylen; - SKF_DEVICE dev; - SKF_KEY key; - int dev_opened = 0; - int key_opened = 0; - - memset(&dev, 0, sizeof(dev)); - memset(&key, 0, sizeof(key)); - - argc--; - argv++; - - if (argc < 1) { - print_usage(stderr, prog); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - print_usage(stdout, prog); - goto end; - } else if (!strcmp(*argv, "-lib")) { - if (--argc < 1) goto bad; - lib = *(++argv); - } else if (!strcmp(*argv, "-lib")) { - if (--argc < 1) goto bad; - devname = *(++argv); - } else if (!strcmp(*argv, "-devinfo")) { - op = OP_DEVINFO; - } else if (!strcmp(*argv, "-dev")) { - if (--argc < 1) goto bad; - devname = *(++argv); - } else if (!strcmp(*argv, "-authkey")) { - if (--argc < 1) goto bad; - authkeystr = *(++argv); - if (strlen(authkeystr) != 32) { - fprintf(stderr, "%s: invalid authkey length\n", prog); - goto end; - } - hex_to_bytes(authkeystr, strlen(authkeystr), authkey, &authkeylen); - } else if (!strcmp(*argv, "-exportpubkey")) { - op = OP_EXPORTPUBKEY; - } else if (!strcmp(*argv, "-sign")) { - op = OP_SIGN; - } else if (!strcmp(*argv, "-app")) { - if (--argc < 1) goto bad; - appname = *(++argv); - } else if (!strcmp(*argv, "-container")) { - if (--argc < 1) goto bad; - container_name = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-rand")) { - if (--argc < 1) goto bad; - len = atoi(*(++argv)); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!lib) { - fprintf(stderr, "%s: option '-lib' required\n", prog); - goto end; - } - if (skf_load_library(lib, NULL) != 1) { - fprintf(stderr, "%s: load library failure\n", prog); - goto end; - } - - if (!op) { - fprintf(stderr, "%s: option of (-devinfo|-exportpubkey|-sign|-rand) required\n", prog); - goto end; - } - - if (!devname) { - fprintf(stderr, "%s: option '-dev' required\n", prog); - goto end; - } - if (op == OP_DEVINFO) { - skf_print_device_info(stdout, 0, 0, devname); - ret = 0; - goto end; - } - - if (skf_open_device(&dev, devname, authkey) != 1) { - fprintf(stderr, "%s: open device failure\n", prog); - goto end; - } - dev_opened = 1; - - if (op == OP_RAND) { - if (skf_rand_bytes(&dev, buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(buf, 1, len, outfp) != len) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - ret = 0; - goto end; - } - - if (!appname) { - fprintf(stderr, "%s: option '-app' required\n", prog); - goto end; - } - if (!container_name) { - fprintf(stderr, "%s: option '-container' required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: option '-pass' required\n", prog); - goto end; - } - - if (op == OP_EXPORTPUBKEY) { - if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { - fprintf(stderr, "%s: load sign key failed\n", prog); - goto end; - } - if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { - fprintf(stderr, "%s: output public key PEM failure\n", prog); - goto end; - } - ret = 0; - goto end; - } - - if (op == OP_SIGN) { - SM3_CTX sm3_ctx; - uint8_t dgst[32]; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { - fprintf(stderr, "%s: load sign key failed\n", prog); - goto end; - } - key_opened = 1; - - sm3_init(&sm3_ctx); - sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); - sm3_update(&sm3_ctx, dgst, sizeof(dgst)); - - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm3_update(&sm3_ctx, buf, len); - } - sm3_finish(&sm3_ctx, dgst); - - if ((ret = skf_sign(&key, dgst, sig, &siglen)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - ret = 0; - goto end; - - } else { - fprintf(stderr, "%s: this should not happen\n", prog); - goto end; - } - -end: - gmssl_secure_clear(buf, sizeof(buf)); - if (key_opened) skf_release_key(&key); - if (dev_opened) skf_close_device(&dev); - if (lib) skf_unload_library(); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define OP_NONE 0 +#define OP_DEVINFO 1 +#define OP_EXPORTPUBKEY 2 +#define OP_SIGN 3 +#define OP_RAND 4 + + + +static void print_usage(FILE *fp, const char *prog) +{ + fprintf(fp, "usage:\n"); + fprintf(fp, " %s -lib so_path -dev str -devinfo\n", prog); + fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -exportpubkey [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -sign [-in file] [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -dev str -rand num [-out file]\n", prog); +} + +int skfutil_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *lib = NULL; + int op = 0; + char *devname = NULL; + char *authkeystr = NULL; + char *appname = NULL; + char *container_name = NULL; + char *pass = NULL; + char *id = SM2_DEFAULT_ID; + int num = 0; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + unsigned char buf[4096]; + unsigned int ulen; + int len; + + uint8_t authkey[16]; + size_t authkeylen; + SKF_DEVICE dev; + SKF_KEY key; + int dev_opened = 0; + int key_opened = 0; + + memset(&dev, 0, sizeof(dev)); + memset(&key, 0, sizeof(key)); + + argc--; + argv++; + + if (argc < 1) { + print_usage(stderr, prog); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + print_usage(stdout, prog); + goto end; + } else if (!strcmp(*argv, "-lib")) { + if (--argc < 1) goto bad; + lib = *(++argv); + } else if (!strcmp(*argv, "-lib")) { + if (--argc < 1) goto bad; + devname = *(++argv); + } else if (!strcmp(*argv, "-devinfo")) { + op = OP_DEVINFO; + } else if (!strcmp(*argv, "-dev")) { + if (--argc < 1) goto bad; + devname = *(++argv); + } else if (!strcmp(*argv, "-authkey")) { + if (--argc < 1) goto bad; + authkeystr = *(++argv); + if (strlen(authkeystr) != 32) { + fprintf(stderr, "%s: invalid authkey length\n", prog); + goto end; + } + hex_to_bytes(authkeystr, strlen(authkeystr), authkey, &authkeylen); + } else if (!strcmp(*argv, "-exportpubkey")) { + op = OP_EXPORTPUBKEY; + } else if (!strcmp(*argv, "-sign")) { + op = OP_SIGN; + } else if (!strcmp(*argv, "-app")) { + if (--argc < 1) goto bad; + appname = *(++argv); + } else if (!strcmp(*argv, "-container")) { + if (--argc < 1) goto bad; + container_name = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-rand")) { + if (--argc < 1) goto bad; + len = atoi(*(++argv)); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!lib) { + fprintf(stderr, "%s: option '-lib' required\n", prog); + goto end; + } + if (skf_load_library(lib, NULL) != 1) { + fprintf(stderr, "%s: load library failure\n", prog); + goto end; + } + + if (!op) { + fprintf(stderr, "%s: option of (-devinfo|-exportpubkey|-sign|-rand) required\n", prog); + goto end; + } + + if (!devname) { + fprintf(stderr, "%s: option '-dev' required\n", prog); + goto end; + } + if (op == OP_DEVINFO) { + skf_print_device_info(stdout, 0, 0, devname); + ret = 0; + goto end; + } + + if (skf_open_device(&dev, devname, authkey) != 1) { + fprintf(stderr, "%s: open device failure\n", prog); + goto end; + } + dev_opened = 1; + + if (op == OP_RAND) { + if (skf_rand_bytes(&dev, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; + goto end; + } + + if (!appname) { + fprintf(stderr, "%s: option '-app' required\n", prog); + goto end; + } + if (!container_name) { + fprintf(stderr, "%s: option '-container' required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: option '-pass' required\n", prog); + goto end; + } + + if (op == OP_EXPORTPUBKEY) { + if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { + fprintf(stderr, "%s: output public key PEM failure\n", prog); + goto end; + } + ret = 0; + goto end; + } + + if (op == OP_SIGN) { + SM3_CTX sm3_ctx; + uint8_t dgst[32]; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; + + sm3_init(&sm3_ctx); + sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); + sm3_update(&sm3_ctx, dgst, sizeof(dgst)); + + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + sm3_update(&sm3_ctx, buf, len); + } + sm3_finish(&sm3_ctx, dgst); + + if ((ret = skf_sign(&key, dgst, sig, &siglen)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + ret = 0; + goto end; + + } else { + fprintf(stderr, "%s: this should not happen\n", prog); + goto end; + } + +end: + gmssl_secure_clear(buf, sizeof(buf)); + if (key_opened) skf_release_key(&key); + if (dev_opened) skf_close_device(&dev); + if (lib) skf_unload_library(); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm2decrypt.c b/tools/sm2decrypt.c index 5c6e54c0..426adc1c 100644 --- a/tools/sm2decrypt.c +++ b/tools/sm2decrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,113 +7,114 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "-key pem -pass str [-in file] [-out file]"; - -int sm2decrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyfile = NULL; - char *pass = NULL; - char *infile = NULL; - char *outfile = NULL; - FILE *keyfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - SM2_KEY key; - uint8_t inbuf[SM2_MAX_CIPHERTEXT_SIZE]; - uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE]; - size_t inlen, outlen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - - if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - fprintf(stderr, "%s: private key decryption failure\n", prog); - goto end; - } - - if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - fprintf(stderr, "%s: read input failed : %s\n", prog, strerror(errno)); - goto end; - } - if (sm2_decrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: decryption failure\n", prog); - goto end; - } - if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - fprintf(stderr, "%s: output plaintext failed : %s\n", prog, strerror(errno)); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&key, sizeof(key)); - if (keyfp) fclose(keyfp); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "-key pem -pass str [-in file] [-out file]"; + +int sm2decrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyfile = NULL; + char *pass = NULL; + char *infile = NULL; + char *outfile = NULL; + FILE *keyfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + SM2_KEY key; + uint8_t inbuf[SM2_MAX_CIPHERTEXT_SIZE]; + uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE]; + size_t inlen, outlen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; + } + + if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { + fprintf(stderr, "%s: read input failed : %s\n", prog, strerror(errno)); + goto end; + } + if (sm2_decrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: decryption failure\n", prog); + goto end; + } + if (outlen != fwrite(outbuf, 1, outlen, outfp)) { + fprintf(stderr, "%s: output plaintext failed : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&key, sizeof(key)); + if (keyfp) fclose(keyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm2encrypt.c b/tools/sm2encrypt.c index c75c7948..7614b345 100644 --- a/tools/sm2encrypt.c +++ b/tools/sm2encrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,138 +7,139 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "(-pubkey pem | -cert pem) [-in file] [-out file]"; - -int sm2encrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *pubkeyfile = NULL; - char *certfile = NULL; - char *infile = NULL; - char *outfile = NULL; - FILE *pubkeyfp = NULL; - FILE *certfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - uint8_t cert[1024]; - size_t certlen; - SM2_KEY key; - uint8_t inbuf[SM2_MAX_PLAINTEXT_SIZE + 1]; - uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE]; - size_t inlen, outlen = sizeof(outbuf); - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-pubkey")) { - if (certfile) { - fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); - goto end; - } - if (--argc < 1) goto bad; - pubkeyfile = *(++argv); - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-cert")) { - if (pubkeyfile) { - fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); - goto end; - } - if (--argc < 1) goto bad; - certfile = *(++argv); - if (!(certfp = fopen(certfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - - if (pubkeyfile) { - if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { - fprintf(stderr, "%s: parse public key failed\n", prog); - goto end; - } - } else if (certfile) { - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { - fprintf(stderr, "%s: parse certificate failed\n", prog); - goto end; - } - } else { - fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); - goto end; - } - - if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - fprintf(stderr, "%s: read input error : %s\n", prog, strerror(errno)); - goto end; - } - if (inlen > SM2_MAX_PLAINTEXT_SIZE) { - fprintf(stderr, "%s: input long than SM2_MAX_PLAINTEXT_SIZE (%d)\n", prog, SM2_MAX_PLAINTEXT_SIZE); - goto end; - } - - if (sm2_encrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - - if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno)); - goto end; - } - ret = 0; - -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (pubkeyfp) fclose(pubkeyfp); - if (certfp) fclose(certfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "(-pubkey pem | -cert pem) [-in file] [-out file]"; + +int sm2encrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *pubkeyfile = NULL; + char *certfile = NULL; + char *infile = NULL; + char *outfile = NULL; + FILE *pubkeyfp = NULL; + FILE *certfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + uint8_t cert[1024]; + size_t certlen; + SM2_KEY key; + uint8_t inbuf[SM2_MAX_PLAINTEXT_SIZE + 1]; + uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE]; + size_t inlen, outlen = sizeof(outbuf); + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-pubkey")) { + if (certfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } + if (--argc < 1) goto bad; + pubkeyfile = *(++argv); + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-cert")) { + if (pubkeyfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } + if (--argc < 1) goto bad; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + + if (pubkeyfile) { + if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; + } + } else if (certfile) { + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { + fprintf(stderr, "%s: parse certificate failed\n", prog); + goto end; + } + } else { + fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); + goto end; + } + + if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { + fprintf(stderr, "%s: read input error : %s\n", prog, strerror(errno)); + goto end; + } + if (inlen > SM2_MAX_PLAINTEXT_SIZE) { + fprintf(stderr, "%s: input long than SM2_MAX_PLAINTEXT_SIZE (%d)\n", prog, SM2_MAX_PLAINTEXT_SIZE); + goto end; + } + + if (sm2_encrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + if (outlen != fwrite(outbuf, 1, outlen, outfp)) { + fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; + +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (pubkeyfp) fclose(pubkeyfp); + if (certfp) fclose(certfp); + return ret; +} diff --git a/tools/sm2keygen.c b/tools/sm2keygen.c index 4bf09057..608601cf 100644 --- a/tools/sm2keygen.c +++ b/tools/sm2keygen.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,86 +7,87 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "-pass str [-out pem] [-pubout pem]"; - -int sm2keygen_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *pass = NULL; - char *outfile = NULL; - char *puboutfile = NULL; - FILE *outfp = stdout; - FILE *puboutfp = stdout; - SM2_KEY key; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pubout")) { - if (--argc < 1) goto bad; - puboutfile = *(++argv); - if (!(puboutfp = fopen(puboutfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - - if (sm2_key_generate(&key) != 1 - || sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1 - || sm2_public_key_info_to_pem(&key, puboutfp) != 1) { - fprintf(stderr, "%s: inner failure\n", prog); - goto end; - } - ret = 0; - -end: - gmssl_secure_clear(&key, sizeof(key)); - if (outfile && outfp) fclose(outfp); - if (puboutfile && puboutfp) fclose(puboutfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "-pass str [-out pem] [-pubout pem]"; + +int sm2keygen_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *pass = NULL; + char *outfile = NULL; + char *puboutfile = NULL; + FILE *outfp = stdout; + FILE *puboutfp = stdout; + SM2_KEY key; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pubout")) { + if (--argc < 1) goto bad; + puboutfile = *(++argv); + if (!(puboutfp = fopen(puboutfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + + if (sm2_key_generate(&key) != 1 + || sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1 + || sm2_public_key_info_to_pem(&key, puboutfp) != 1) { + fprintf(stderr, "%s: inner failure\n", prog); + goto end; + } + ret = 0; + +end: + gmssl_secure_clear(&key, sizeof(key)); + if (outfile && outfp) fclose(outfp); + if (puboutfile && puboutfp) fclose(puboutfp); + return ret; +} diff --git a/tools/sm2sign.c b/tools/sm2sign.c index 3fc6468a..225c530d 100644 --- a/tools/sm2sign.c +++ b/tools/sm2sign.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,125 +7,126 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "-key pem -pass str [-id str] [-in file] [-out file]"; - -int sm2sign_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyfile = NULL; - char *pass = NULL; - char *id = SM2_DEFAULT_ID; - char *infile = NULL; - char *outfile = NULL; - FILE *keyfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - SM2_KEY key; - SM2_SIGN_CTX sign_ctx; - uint8_t buf[4096]; - ssize_t len; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - goto end; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - goto end; - } - if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - fprintf(stderr, "%s: private key decryption failure\n", prog); - goto end; - } - - if (sm2_sign_init(&sign_ctx, &key, id, strlen(id)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - if (sm2_sign_update(&sign_ctx, buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - } - if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(sig, 1, siglen, outfp) != siglen) { - fprintf(stderr, "%s: output signature failed : %s\n", prog, strerror(errno)); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&key, sizeof(key)); - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - if (keyfp) fclose(keyfp); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "-key pem -pass str [-id str] [-in file] [-out file]"; + +int sm2sign_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyfile = NULL; + char *pass = NULL; + char *id = SM2_DEFAULT_ID; + char *infile = NULL; + char *outfile = NULL; + FILE *keyfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + SM2_KEY key; + SM2_SIGN_CTX sign_ctx; + uint8_t buf[4096]; + ssize_t len; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; + } + + if (sm2_sign_init(&sign_ctx, &key, id, strlen(id)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + if (sm2_sign_update(&sign_ctx, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + } + if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(sig, 1, siglen, outfp) != siglen) { + fprintf(stderr, "%s: output signature failed : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&key, sizeof(key)); + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + if (keyfp) fclose(keyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm2verify.c b/tools/sm2verify.c index 7cd30461..3c3cf6ef 100644 --- a/tools/sm2verify.c +++ b/tools/sm2verify.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,155 +7,156 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "(-pubkey pem | -cert pem) [-id str] [-in file] -sig file"; - -int sm2verify_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *id = SM2_DEFAULT_ID; - char *pubkeyfile = NULL; - char *certfile = NULL; - char *infile = NULL; - char *sigfile = NULL; - FILE *pubkeyfp = NULL; - FILE *certfp = NULL; - FILE *infp = stdin; - FILE *sigfp = NULL; - SM2_KEY key; - SM2_SIGN_CTX verify_ctx; - uint8_t cert[1024]; - size_t certlen; - uint8_t buf[4096]; - ssize_t len; - uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; - size_t siglen; - int vr; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-pubkey")) { - if (certfile) { - fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); - goto end; - } - if (--argc < 1) goto bad; - pubkeyfile = *(++argv); - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-cert")) { - if (pubkeyfile) { - fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); - goto end; - } - if (--argc < 1) goto bad; - certfile = *(++argv); - if (!(certfp = fopen(certfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-sig")) { - if (--argc < 1) goto bad; - sigfile = *(++argv); - if (!(sigfp = fopen(sigfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, sigfile, strerror(errno)); - goto end; - } - - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!sigfile) { - fprintf(stderr, "%s: '-sig' option required\n", prog); - goto end; - } - if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { - fprintf(stderr, "%s: read signature error : %s\n", prog, strerror(errno)); - goto end; - } - - if (pubkeyfile) { - if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { - fprintf(stderr, "%s: parse public key failed\n", prog); - goto end; - } - } else if (certfile) { - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { - fprintf(stderr, "%s: parse certificate failed\n", prog); - goto end; - } - } else { - fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); - goto end; - } - - - if (sm2_verify_init(&verify_ctx, &key, id, strlen(id)) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - if (sm2_verify_update(&verify_ctx, buf, len) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - } - if ((vr = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - - fprintf(stdout, "verify : %s\n", vr == 1 ? "success" : "failure"); - if (vr == 1) { - ret = 0; - } - -end: - if (infile && infp) fclose(infp); - if (pubkeyfp) fclose(pubkeyfp); - if (certfp) fclose(certfp); - if (sigfp) fclose(sigfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "(-pubkey pem | -cert pem) [-id str] [-in file] -sig file"; + +int sm2verify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *id = SM2_DEFAULT_ID; + char *pubkeyfile = NULL; + char *certfile = NULL; + char *infile = NULL; + char *sigfile = NULL; + FILE *pubkeyfp = NULL; + FILE *certfp = NULL; + FILE *infp = stdin; + FILE *sigfp = NULL; + SM2_KEY key; + SM2_SIGN_CTX verify_ctx; + uint8_t cert[1024]; + size_t certlen; + uint8_t buf[4096]; + ssize_t len; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + int vr; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-pubkey")) { + if (certfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } + if (--argc < 1) goto bad; + pubkeyfile = *(++argv); + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-cert")) { + if (pubkeyfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } + if (--argc < 1) goto bad; + certfile = *(++argv); + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-sig")) { + if (--argc < 1) goto bad; + sigfile = *(++argv); + if (!(sigfp = fopen(sigfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, sigfile, strerror(errno)); + goto end; + } + + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!sigfile) { + fprintf(stderr, "%s: '-sig' option required\n", prog); + goto end; + } + if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { + fprintf(stderr, "%s: read signature error : %s\n", prog, strerror(errno)); + goto end; + } + + if (pubkeyfile) { + if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; + } + } else if (certfile) { + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { + fprintf(stderr, "%s: parse certificate failed\n", prog); + goto end; + } + } else { + fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); + goto end; + } + + + if (sm2_verify_init(&verify_ctx, &key, id, strlen(id)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + if (sm2_verify_update(&verify_ctx, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + } + if ((vr = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + + fprintf(stdout, "verify : %s\n", vr == 1 ? "success" : "failure"); + if (vr == 1) { + ret = 0; + } + +end: + if (infile && infp) fclose(infp); + if (pubkeyfp) fclose(pubkeyfp); + if (certfp) fclose(certfp); + if (sigfp) fclose(sigfp); + return ret; +} diff --git a/tools/sm3.c b/tools/sm3.c index a8520d2c..dec9dad7 100644 --- a/tools/sm3.c +++ b/tools/sm3.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,132 +7,133 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-hex|-bin] [-pubkey pem [-id str]] [-in file] [-out file]"; - -int sm3_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int bin = 0; - char *pubkeyfile = NULL; - char *infile = NULL; - char *outfile = NULL; - char *id = NULL; - FILE *pubkeyfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - SM3_CTX sm3_ctx; - uint8_t dgst[32]; - uint8_t buf[4096]; - ssize_t len; - int i; - - argc--; - argv++; - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - printf("usage: echo -n \"abc\" | %s\n", prog); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-hex")) { - if (bin) { - error_print(); - goto end; - } - bin = 0; - } else if (!strcmp(*argv, "-bin")) { - bin = 1; - } else if (!strcmp(*argv, "-pubkey")) { - if (--argc < 1) goto bad; - pubkeyfile = *(++argv); - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - sm3_init(&sm3_ctx); - - if (pubkeyfile) { - SM2_KEY sm2_key; - uint8_t z[32]; - - if (sm2_public_key_info_from_pem(&sm2_key, pubkeyfp) != 1) { - fprintf(stderr, "%s: parse public key failed\n", prog); - goto end; - } - if (!id) { - id = SM2_DEFAULT_ID; - } - - sm2_compute_z(z, (SM2_POINT *)&sm2_key, id, strlen(id)); - sm3_update(&sm3_ctx, z, sizeof(z)); - } else { - if (id) { - fprintf(stderr, "%s: option '-id' must be with '-pubkey'\n", prog); - goto end; - } - } - - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm3_update(&sm3_ctx, buf, len); - } - sm3_finish(&sm3_ctx, dgst); - - if (bin) { - if (fwrite(dgst, 1, sizeof(dgst), outfp) != sizeof(dgst)) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } else { - for (i = 0; i < sizeof(dgst); i++) { - fprintf(outfp, "%02x", dgst[i]); - } - fprintf(outfp, "\n"); - } - ret = 0; -end: - if (pubkeyfp) fclose(pubkeyfp); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-hex|-bin] [-pubkey pem [-id str]] [-in file] [-out file]"; + +int sm3_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int bin = 0; + char *pubkeyfile = NULL; + char *infile = NULL; + char *outfile = NULL; + char *id = NULL; + FILE *pubkeyfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + SM3_CTX sm3_ctx; + uint8_t dgst[32]; + uint8_t buf[4096]; + ssize_t len; + int i; + + argc--; + argv++; + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + printf("usage: echo -n \"abc\" | %s\n", prog); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-hex")) { + if (bin) { + error_print(); + goto end; + } + bin = 0; + } else if (!strcmp(*argv, "-bin")) { + bin = 1; + } else if (!strcmp(*argv, "-pubkey")) { + if (--argc < 1) goto bad; + pubkeyfile = *(++argv); + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + sm3_init(&sm3_ctx); + + if (pubkeyfile) { + SM2_KEY sm2_key; + uint8_t z[32]; + + if (sm2_public_key_info_from_pem(&sm2_key, pubkeyfp) != 1) { + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; + } + if (!id) { + id = SM2_DEFAULT_ID; + } + + sm2_compute_z(z, (SM2_POINT *)&sm2_key, id, strlen(id)); + sm3_update(&sm3_ctx, z, sizeof(z)); + } else { + if (id) { + fprintf(stderr, "%s: option '-id' must be with '-pubkey'\n", prog); + goto end; + } + } + + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + sm3_update(&sm3_ctx, buf, len); + } + sm3_finish(&sm3_ctx, dgst); + + if (bin) { + if (fwrite(dgst, 1, sizeof(dgst), outfp) != sizeof(dgst)) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } else { + for (i = 0; i < sizeof(dgst); i++) { + fprintf(outfp, "%02x", dgst[i]); + } + fprintf(outfp, "\n"); + } + ret = 0; +end: + if (pubkeyfp) fclose(pubkeyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm3hmac.c b/tools/sm3hmac.c index cfb51988..cbe6e5fc 100644 --- a/tools/sm3hmac.c +++ b/tools/sm3hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,117 +7,118 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-key hex [-in file] [-bin|-hex] [-out file]"; - -int sm3hmac_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyhex = NULL; - int bin = 0; - char *infile = NULL; - char *outfile = NULL; - uint8_t key[SM3_DIGEST_SIZE]; - size_t keylen; - FILE *infp = stdin; - FILE *outfp = stdout; - uint8_t buf[4096]; - size_t len; - SM3_HMAC_CTX ctx; - uint8_t mac[SM3_HMAC_SIZE]; - size_t i; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyhex = *(++argv); - if (strlen(keyhex) > sizeof(key) * 2) { - fprintf(stderr, "%s: key should be less than 64 digits (32 bytes)\n", prog); - goto end; - } - if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-hex")) { - bin = 0; - } else if (!strcmp(*argv, "-bin")) { - bin = 1; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyhex) { - fprintf(stderr, "%s: option '-key' required\n", prog); - goto end; - } - - sm3_hmac_init(&ctx, key, keylen); - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm3_hmac_update(&ctx, buf, len); - } - sm3_hmac_finish(&ctx, mac); - - if (bin) { - if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } else { - for (i = 0; i < sizeof(mac); i++) { - fprintf(outfp, "%02x", mac[i]); - } - fprintf(outfp, "\n"); - } - ret = 0; -end: - gmssl_secure_clear(key, sizeof(key)); - gmssl_secure_clear(&ctx, sizeof(ctx)); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-key hex [-in file] [-bin|-hex] [-out file]"; + +int sm3hmac_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyhex = NULL; + int bin = 0; + char *infile = NULL; + char *outfile = NULL; + uint8_t key[SM3_DIGEST_SIZE]; + size_t keylen; + FILE *infp = stdin; + FILE *outfp = stdout; + uint8_t buf[4096]; + size_t len; + SM3_HMAC_CTX ctx; + uint8_t mac[SM3_HMAC_SIZE]; + size_t i; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyhex = *(++argv); + if (strlen(keyhex) > sizeof(key) * 2) { + fprintf(stderr, "%s: key should be less than 64 digits (32 bytes)\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-hex")) { + bin = 0; + } else if (!strcmp(*argv, "-bin")) { + bin = 1; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyhex) { + fprintf(stderr, "%s: option '-key' required\n", prog); + goto end; + } + + sm3_hmac_init(&ctx, key, keylen); + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + sm3_hmac_update(&ctx, buf, len); + } + sm3_hmac_finish(&ctx, mac); + + if (bin) { + if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } else { + for (i = 0; i < sizeof(mac); i++) { + fprintf(outfp, "%02x", mac[i]); + } + fprintf(outfp, "\n"); + } + ret = 0; +end: + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(&ctx, sizeof(ctx)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm4.c b/tools/sm4.c index 5a047349..b3a2fa4b 100644 --- a/tools/sm4.c +++ b/tools/sm4.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,220 +7,221 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -#define SM4_MODE_CBC 1 -#define SM4_MODE_CTR 2 - -static const char *options = "{-cbc|-ctr} {-encrypt|-decrypt} -key hex -iv hex [-in file] [-out file]"; - -int sm4_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyhex = NULL; - char *ivhex = NULL; - char *infile = NULL; - char *outfile = NULL; - uint8_t key[16]; - uint8_t iv[16]; - size_t keylen = sizeof(key); - size_t ivlen = sizeof(iv); - FILE *infp = stdin; - FILE *outfp = stdout; - int mode = 0; - int enc = -1; - SM4_CBC_CTX cbc_ctx; - SM4_CTR_CTX ctr_ctx; - uint8_t inbuf[4096]; - size_t inlen; - uint8_t outbuf[4196]; - size_t outlen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyhex = *(++argv); - if (strlen(keyhex) != sizeof(key) * 2) { - fprintf(stderr, "%s: invalid key length\n", prog); - goto end; - } - if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-iv")) { - if (--argc < 1) goto bad; - ivhex = *(++argv); - if (strlen(ivhex) != sizeof(iv) * 2) { - fprintf(stderr, "%s: invalid IV length\n", prog); - goto end; - } - if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-encrypt")) { - enc = 1; - } else if (!strcmp(*argv, "-decrypt")) { - enc = 0; - } else if (!strcmp(*argv, "-cbc")) { - if (mode) goto bad; - mode = SM4_MODE_CBC; - } else if (!strcmp(*argv, "-ctr")) { - if (mode) goto bad; - mode = SM4_MODE_CTR; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!mode) { - fprintf(stderr, "%s: mode not assigned, -cbc or -ctr option required\n", prog); - goto end; - } - if (!keyhex) { - fprintf(stderr, "%s: option '-key' missing\n", prog); - goto end; - } - if (!ivhex) { - fprintf(stderr, "%s: option '-iv' missing\n", prog); - goto end; - } - - - if (mode == SM4_MODE_CTR) { - if (sm4_ctr_encrypt_init(&ctr_ctx, key, iv) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { - if (sm4_ctr_encrypt_update(&ctr_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - if (sm4_ctr_encrypt_finish(&ctr_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - - ret = 0; - goto end; - } - - if (enc < 0) { - fprintf(stderr, "%s: option -encrypt or -decrypt should be set\n", prog); - goto end; - } - - if (enc) { - if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { - if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - - } else { - if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { - if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - ret = 0; - -end: - gmssl_secure_clear(&cbc_ctx, sizeof(cbc_ctx)); - gmssl_secure_clear(&ctr_ctx, sizeof(ctr_ctx)); - gmssl_secure_clear(key, sizeof(key)); - gmssl_secure_clear(iv, sizeof(iv)); - gmssl_secure_clear(inbuf, sizeof(inbuf)); - gmssl_secure_clear(outbuf, sizeof(outbuf)); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +#define SM4_MODE_CBC 1 +#define SM4_MODE_CTR 2 + +static const char *options = "{-cbc|-ctr} {-encrypt|-decrypt} -key hex -iv hex [-in file] [-out file]"; + +int sm4_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyhex = NULL; + char *ivhex = NULL; + char *infile = NULL; + char *outfile = NULL; + uint8_t key[16]; + uint8_t iv[16]; + size_t keylen = sizeof(key); + size_t ivlen = sizeof(iv); + FILE *infp = stdin; + FILE *outfp = stdout; + int mode = 0; + int enc = -1; + SM4_CBC_CTX cbc_ctx; + SM4_CTR_CTX ctr_ctx; + uint8_t inbuf[4096]; + size_t inlen; + uint8_t outbuf[4196]; + size_t outlen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyhex = *(++argv); + if (strlen(keyhex) != sizeof(key) * 2) { + fprintf(stderr, "%s: invalid key length\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-iv")) { + if (--argc < 1) goto bad; + ivhex = *(++argv); + if (strlen(ivhex) != sizeof(iv) * 2) { + fprintf(stderr, "%s: invalid IV length\n", prog); + goto end; + } + if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-encrypt")) { + enc = 1; + } else if (!strcmp(*argv, "-decrypt")) { + enc = 0; + } else if (!strcmp(*argv, "-cbc")) { + if (mode) goto bad; + mode = SM4_MODE_CBC; + } else if (!strcmp(*argv, "-ctr")) { + if (mode) goto bad; + mode = SM4_MODE_CTR; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!mode) { + fprintf(stderr, "%s: mode not assigned, -cbc or -ctr option required\n", prog); + goto end; + } + if (!keyhex) { + fprintf(stderr, "%s: option '-key' missing\n", prog); + goto end; + } + if (!ivhex) { + fprintf(stderr, "%s: option '-iv' missing\n", prog); + goto end; + } + + + if (mode == SM4_MODE_CTR) { + if (sm4_ctr_encrypt_init(&ctr_ctx, key, iv) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { + if (sm4_ctr_encrypt_update(&ctr_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + if (sm4_ctr_encrypt_finish(&ctr_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + + ret = 0; + goto end; + } + + if (enc < 0) { + fprintf(stderr, "%s: option -encrypt or -decrypt should be set\n", prog); + goto end; + } + + if (enc) { + if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { + if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + + } else { + if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { + if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + ret = 0; + +end: + gmssl_secure_clear(&cbc_ctx, sizeof(cbc_ctx)); + gmssl_secure_clear(&ctr_ctx, sizeof(ctr_ctx)); + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(iv, sizeof(iv)); + gmssl_secure_clear(inbuf, sizeof(inbuf)); + gmssl_secure_clear(outbuf, sizeof(outbuf)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm9decrypt.c b/tools/sm9decrypt.c index 46cba1dd..06b570a3 100644 --- a/tools/sm9decrypt.c +++ b/tools/sm9decrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,111 +7,112 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-in file] -key file -pass str -id str [-out file]"; - -int sm9decrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *id = NULL; - char *outfile = NULL; - FILE *keyfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - SM9_ENC_KEY key; - uint8_t inbuf[SM9_MAX_CIPHERTEXT_SIZE]; - uint8_t outbuf[SM9_MAX_CIPHERTEXT_SIZE]; - size_t inlen, outlen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - goto end; - } - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - argc--; - argv++; - } - - if (!keyfile || !pass || !id) { - error_print(); - goto end; - } - - if (sm9_enc_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - error_print(); - goto end; - } - if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - error_print(); - goto end; - } - if (sm9_decrypt(&key, id, strlen(id), inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - goto end; - } - if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - error_print(); - goto end; - } - ret = 0; - -end: - gmssl_secure_clear(&key, sizeof(key)); - gmssl_secure_clear(outbuf, sizeof(outbuf)); - if (keyfp) fclose(keyfp); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-in file] -key file -pass str -id str [-out file]"; + +int sm9decrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *keyfile = NULL; + char *pass = NULL; + char *id = NULL; + char *outfile = NULL; + FILE *keyfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + SM9_ENC_KEY key; + uint8_t inbuf[SM9_MAX_CIPHERTEXT_SIZE]; + uint8_t outbuf[SM9_MAX_CIPHERTEXT_SIZE]; + size_t inlen, outlen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + error_print(); + goto end; + } + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + argc--; + argv++; + } + + if (!keyfile || !pass || !id) { + error_print(); + goto end; + } + + if (sm9_enc_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + error_print(); + goto end; + } + if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { + error_print(); + goto end; + } + if (sm9_decrypt(&key, id, strlen(id), inbuf, inlen, outbuf, &outlen) != 1) { + error_print(); + goto end; + } + if (outlen != fwrite(outbuf, 1, outlen, outfp)) { + error_print(); + goto end; + } + ret = 0; + +end: + gmssl_secure_clear(&key, sizeof(key)); + gmssl_secure_clear(outbuf, sizeof(outbuf)); + if (keyfp) fclose(keyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm9encrypt.c b/tools/sm9encrypt.c index e18b5bee..47e72e86 100644 --- a/tools/sm9encrypt.c +++ b/tools/sm9encrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,103 +7,104 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -static const char *options = "-pubmaster file -id str [-in file] [-out file]"; - - -int sm9encrypt_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *mpkfile = NULL; - char *id = NULL; - char *infile = NULL; - char *outfile = NULL; - FILE *mpkfp = NULL; - FILE *infp = stdin; - FILE *outfp = stdout; - SM9_ENC_MASTER_KEY mpk; - uint8_t inbuf[SM9_MAX_PLAINTEXT_SIZE]; - uint8_t outbuf[SM9_MAX_CIPHERTEXT_SIZE]; - size_t inlen, outlen = sizeof(outbuf); - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-pubmaster")) { - if (--argc < 1) goto bad; - mpkfile = *(++argv); - if (!(mpkfp = fopen(mpkfile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(outfile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - goto end; - } - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - argc--; - argv++; - } - - if (!mpkfp || !id) { - error_print(); - goto end; - } - if (sm9_enc_master_public_key_from_pem(&mpk, mpkfp) != 1) { - error_print(); - return -1; - } - if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - error_print(); - goto end; - } - if (sm9_encrypt(&mpk, id, strlen(id), inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - goto end; - } - if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - error_print(); - goto end; - } - ret = 0; -end: - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - if (mpkfp) fclose(mpkfp); - return ret; -} + + +#include +#include +#include +#include +#include + + +static const char *options = "-pubmaster file -id str [-in file] [-out file]"; + + +int sm9encrypt_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *mpkfile = NULL; + char *id = NULL; + char *infile = NULL; + char *outfile = NULL; + FILE *mpkfp = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + SM9_ENC_MASTER_KEY mpk; + uint8_t inbuf[SM9_MAX_PLAINTEXT_SIZE]; + uint8_t outbuf[SM9_MAX_CIPHERTEXT_SIZE]; + size_t inlen, outlen = sizeof(outbuf); + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-pubmaster")) { + if (--argc < 1) goto bad; + mpkfile = *(++argv); + if (!(mpkfp = fopen(mpkfile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(outfile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + error_print(); + goto end; + } + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + argc--; + argv++; + } + + if (!mpkfp || !id) { + error_print(); + goto end; + } + if (sm9_enc_master_public_key_from_pem(&mpk, mpkfp) != 1) { + error_print(); + return -1; + } + if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { + error_print(); + goto end; + } + if (sm9_encrypt(&mpk, id, strlen(id), inbuf, inlen, outbuf, &outlen) != 1) { + error_print(); + goto end; + } + if (outlen != fwrite(outbuf, 1, outlen, outfp)) { + error_print(); + goto end; + } + ret = 0; +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (mpkfp) fclose(mpkfp); + return ret; +} diff --git a/tools/sm9keygen.c b/tools/sm9keygen.c index 04fa6bce..b1776d8c 100644 --- a/tools/sm9keygen.c +++ b/tools/sm9keygen.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,125 +7,126 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - -static const char *options = "-alg (sm9sign|sm9encrypt) -in master_key.pem -inpass str -id str [-out pem] -outpass str"; - -int sm9keygen_main(int argc, char **argv) -{ - int ret = -1; - char *prog = argv[0]; - char *alg = NULL; - char *infile = NULL; - char *inpass = NULL; - char *id = NULL; - char *outfile = NULL; - char *outpass = NULL; - int oid = 0; - FILE *infp = stdin; - FILE *outfp = stdout; - SM9_SIGN_MASTER_KEY sign_msk; - SM9_ENC_MASTER_KEY enc_msk; - SM9_SIGN_KEY sign_key; - SM9_ENC_KEY enc_key; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-alg")) { - if (--argc < 1) goto bad; - alg = *(++argv); - if ((oid = sm9_oid_from_name(alg)) < 1) { - fprintf(stdout, "%s: invalid alg '%s', should be sm9sign or sm9encrypt\n", prog, alg); - goto end; - } - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-inpass")) { - if (--argc < 1) goto bad; - inpass = *(++argv); - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-outpass")) { - if (--argc < 1) goto bad; - outpass = *(++argv); - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - - argc--; - argv++; - } - - if (!id) { - fprintf(stderr, "%s: option '-id' is required\n", prog); - goto end; - } - if (!inpass || !outpass) { - error_print(); - goto end; - } - - switch (oid) { - case OID_sm9sign: - if (sm9_sign_master_key_info_decrypt_from_pem(&sign_msk, inpass, infp) != 1 - || sm9_sign_master_key_extract_key(&sign_msk, id, strlen(id), &sign_key) != 1 - || sm9_sign_key_info_encrypt_to_pem(&sign_key, outpass, outfp) != 1) { - error_print(); - goto end; - } - break; - case OID_sm9encrypt: - if (sm9_enc_master_key_info_decrypt_from_pem(&enc_msk, inpass, infp) != 1 - || sm9_enc_master_key_extract_key(&enc_msk, id, strlen(id), &enc_key) != 1 - || sm9_enc_key_info_encrypt_to_pem(&enc_key, outpass, outfp) != 1) { - error_print(); - goto end; - } - break; - default: - error_print(); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&sign_msk, sizeof(sign_msk)); - gmssl_secure_clear(&enc_msk, sizeof(enc_msk)); - gmssl_secure_clear(&sign_key, sizeof(sign_key)); - gmssl_secure_clear(&enc_key, sizeof(enc_key)); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return 1; -} + + +#include +#include +#include +#include +#include +#include +#include + +static const char *options = "-alg (sm9sign|sm9encrypt) -in master_key.pem -inpass str -id str [-out pem] -outpass str"; + +int sm9keygen_main(int argc, char **argv) +{ + int ret = -1; + char *prog = argv[0]; + char *alg = NULL; + char *infile = NULL; + char *inpass = NULL; + char *id = NULL; + char *outfile = NULL; + char *outpass = NULL; + int oid = 0; + FILE *infp = stdin; + FILE *outfp = stdout; + SM9_SIGN_MASTER_KEY sign_msk; + SM9_ENC_MASTER_KEY enc_msk; + SM9_SIGN_KEY sign_key; + SM9_ENC_KEY enc_key; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-alg")) { + if (--argc < 1) goto bad; + alg = *(++argv); + if ((oid = sm9_oid_from_name(alg)) < 1) { + fprintf(stdout, "%s: invalid alg '%s', should be sm9sign or sm9encrypt\n", prog, alg); + goto end; + } + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-inpass")) { + if (--argc < 1) goto bad; + inpass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-outpass")) { + if (--argc < 1) goto bad; + outpass = *(++argv); + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + + argc--; + argv++; + } + + if (!id) { + fprintf(stderr, "%s: option '-id' is required\n", prog); + goto end; + } + if (!inpass || !outpass) { + error_print(); + goto end; + } + + switch (oid) { + case OID_sm9sign: + if (sm9_sign_master_key_info_decrypt_from_pem(&sign_msk, inpass, infp) != 1 + || sm9_sign_master_key_extract_key(&sign_msk, id, strlen(id), &sign_key) != 1 + || sm9_sign_key_info_encrypt_to_pem(&sign_key, outpass, outfp) != 1) { + error_print(); + goto end; + } + break; + case OID_sm9encrypt: + if (sm9_enc_master_key_info_decrypt_from_pem(&enc_msk, inpass, infp) != 1 + || sm9_enc_master_key_extract_key(&enc_msk, id, strlen(id), &enc_key) != 1 + || sm9_enc_key_info_encrypt_to_pem(&enc_key, outpass, outfp) != 1) { + error_print(); + goto end; + } + break; + default: + error_print(); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&sign_msk, sizeof(sign_msk)); + gmssl_secure_clear(&enc_msk, sizeof(enc_msk)); + gmssl_secure_clear(&sign_key, sizeof(sign_key)); + gmssl_secure_clear(&enc_key, sizeof(enc_key)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return 1; +} diff --git a/tools/sm9setup.c b/tools/sm9setup.c index 2967178a..3ae0f8ca 100644 --- a/tools/sm9setup.c +++ b/tools/sm9setup.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,133 +7,134 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - -static const char *options = "-alg (sm9sign|sm9encrypt) [-pass password] [-out pem] [-pubout pem]"; - -int sm9setup_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *alg = NULL; - char *pass = NULL; - char *outfile = NULL; - char *puboutfile = NULL; - int oid; - FILE *outfp = stdout; - FILE *puboutfp = stdout; - SM9_SIGN_MASTER_KEY sign_msk; - SM9_ENC_MASTER_KEY enc_msk; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-alg")) { - if (--argc < 1) goto bad; - alg = *(++argv); - if ((oid = sm9_oid_from_name(alg)) < 1) { - fprintf(stdout, "%s: invalid alg '%s', should be sm9sign or sm9encrypt\n", prog, alg); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-pubout")) { - if (--argc < 1) goto bad; - puboutfile = *(++argv); - if (!(puboutfp = fopen(puboutfile, "w"))) { - error_print(); - goto end; - } - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - argc--; - argv++; - } - - if (!alg) { - error_print(); - return -1; - } - if (!pass) { - error_print(); - return -1; - } - - switch (oid) { - case OID_sm9sign: - if (sm9_sign_master_key_generate(&sign_msk) != 1 - || sm9_sign_master_key_info_encrypt_to_pem(&sign_msk, pass, outfp) != 1 - || sm9_sign_master_public_key_to_pem(&sign_msk, puboutfp) != 1) { - error_print(); - goto end; - } - break; - case OID_sm9encrypt: - if (sm9_enc_master_key_generate(&enc_msk) != 1 - || sm9_enc_master_key_info_encrypt_to_pem(&enc_msk, pass, outfp) != 1 - || sm9_enc_master_public_key_to_pem(&enc_msk, puboutfp) != 1) { - error_print(); - goto end; - } - break; - default: - error_print(); - goto end; - } - ret = 0; - -end: - gmssl_secure_clear(&sign_msk, sizeof(sign_msk)); - gmssl_secure_clear(&enc_msk, sizeof(enc_msk)); - if (outfile && outfp) fclose(outfp); - if (puboutfile && puboutfp) fclose(puboutfp); - return 1; -} - - - - - - - - - - - - - - - - - - - - + + +#include +#include +#include +#include +#include +#include +#include + +static const char *options = "-alg (sm9sign|sm9encrypt) [-pass password] [-out pem] [-pubout pem]"; + +int sm9setup_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *alg = NULL; + char *pass = NULL; + char *outfile = NULL; + char *puboutfile = NULL; + int oid; + FILE *outfp = stdout; + FILE *puboutfp = stdout; + SM9_SIGN_MASTER_KEY sign_msk; + SM9_ENC_MASTER_KEY enc_msk; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-alg")) { + if (--argc < 1) goto bad; + alg = *(++argv); + if ((oid = sm9_oid_from_name(alg)) < 1) { + fprintf(stdout, "%s: invalid alg '%s', should be sm9sign or sm9encrypt\n", prog, alg); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-pubout")) { + if (--argc < 1) goto bad; + puboutfile = *(++argv); + if (!(puboutfp = fopen(puboutfile, "w"))) { + error_print(); + goto end; + } + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + argc--; + argv++; + } + + if (!alg) { + error_print(); + return -1; + } + if (!pass) { + error_print(); + return -1; + } + + switch (oid) { + case OID_sm9sign: + if (sm9_sign_master_key_generate(&sign_msk) != 1 + || sm9_sign_master_key_info_encrypt_to_pem(&sign_msk, pass, outfp) != 1 + || sm9_sign_master_public_key_to_pem(&sign_msk, puboutfp) != 1) { + error_print(); + goto end; + } + break; + case OID_sm9encrypt: + if (sm9_enc_master_key_generate(&enc_msk) != 1 + || sm9_enc_master_key_info_encrypt_to_pem(&enc_msk, pass, outfp) != 1 + || sm9_enc_master_public_key_to_pem(&enc_msk, puboutfp) != 1) { + error_print(); + goto end; + } + break; + default: + error_print(); + goto end; + } + ret = 0; + +end: + gmssl_secure_clear(&sign_msk, sizeof(sign_msk)); + gmssl_secure_clear(&enc_msk, sizeof(enc_msk)); + if (outfile && outfp) fclose(outfp); + if (puboutfile && puboutfp) fclose(puboutfp); + return 1; +} + + + + + + + + + + + + + + + + + + + + diff --git a/tools/sm9sign.c b/tools/sm9sign.c index eefce4dc..1149ad6a 100644 --- a/tools/sm9sign.c +++ b/tools/sm9sign.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,121 +7,122 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-in file] -key file -pass str [-out file]"; - - -int sm9sign_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *outfile = NULL; - FILE *infp = stdin; - FILE *keyfp = NULL; - FILE *outfp = stdout; - SM9_SIGN_KEY key; - SM9_SIGN_CTX ctx; - uint8_t buf[4096]; - ssize_t len; - uint8_t sig[SM9_SIGNATURE_SIZE]; - size_t siglen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - goto end; - } - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - argc--; - argv++; - } - - if (!keyfile || !pass) { - error_print(); - goto end; - } - - if (sm9_sign_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - error_print(); - return -1; - } - - if (sm9_sign_init(&ctx) != 1) { - error_print(); - goto end; - } - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - if (sm9_sign_update(&ctx, buf, len) != 1) { - error_print(); - goto end; - } - } - if (sm9_sign_finish(&ctx, &key, sig, &siglen) != 1) { - error_print(); - goto end; - } - - if (siglen != fwrite(sig, 1, siglen, outfp)) { - error_print(); - goto end; - } - - - - ret = 0; - -end: - gmssl_secure_clear(&key, sizeof(key)); - gmssl_secure_clear(&ctx, sizeof(ctx)); - gmssl_secure_clear(buf, sizeof(buf)); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-in file] -key file -pass str [-out file]"; + + +int sm9sign_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *keyfile = NULL; + char *pass = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *keyfp = NULL; + FILE *outfp = stdout; + SM9_SIGN_KEY key; + SM9_SIGN_CTX ctx; + uint8_t buf[4096]; + ssize_t len; + uint8_t sig[SM9_SIGNATURE_SIZE]; + size_t siglen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + if (!(keyfp = fopen(keyfile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + error_print(); + goto end; + } + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + argc--; + argv++; + } + + if (!keyfile || !pass) { + error_print(); + goto end; + } + + if (sm9_sign_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { + error_print(); + return -1; + } + + if (sm9_sign_init(&ctx) != 1) { + error_print(); + goto end; + } + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + if (sm9_sign_update(&ctx, buf, len) != 1) { + error_print(); + goto end; + } + } + if (sm9_sign_finish(&ctx, &key, sig, &siglen) != 1) { + error_print(); + goto end; + } + + if (siglen != fwrite(sig, 1, siglen, outfp)) { + error_print(); + goto end; + } + + + + ret = 0; + +end: + gmssl_secure_clear(&key, sizeof(key)); + gmssl_secure_clear(&ctx, sizeof(ctx)); + gmssl_secure_clear(buf, sizeof(buf)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +} diff --git a/tools/sm9verify.c b/tools/sm9verify.c index eb345959..962a6c5f 100644 --- a/tools/sm9verify.c +++ b/tools/sm9verify.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,122 +7,123 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include - - -static const char *options = "[-in file] -pubmaster file -id str -sig file"; - -int sm9verify_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *infile = NULL; - char *mpkfile = NULL; - char *id = NULL; - char *sigfile = NULL; - FILE *infp = stdin; - FILE *mpkfp = NULL; - FILE *sigfp = NULL; - SM9_SIGN_MASTER_KEY mpk; - SM9_SIGN_CTX ctx; - uint8_t buf[4096]; - ssize_t len; - uint8_t sig[SM9_SIGNATURE_SIZE]; - ssize_t siglen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - fprintf(stdout, "usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-pubmaster")) { - if (--argc < 1) goto bad; - mpkfile = *(++argv); - if (!(mpkfp = fopen(mpkfile, "r"))) { - error_print(); - goto end; - } - } else if (!strcmp(*argv, "-id")) { - if (--argc < 1) goto bad; - id = *(++argv); - } else if (!strcmp(*argv, "-sig")) { - if (--argc < 1) goto bad; - sigfile = *(++argv); - if (!(sigfp = fopen(sigfile, "r"))) { - error_print(); - goto end; - } - } else { -bad: - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; - } - - argc--; - argv++; - } - - if (!mpkfile || !id || !sigfile) { - error_print(); - goto end; - } - - if (sm9_sign_master_public_key_from_pem(&mpk, mpkfp) != 1) { - error_print(); - goto end; - } - - if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { - error_print(); - goto end; - } - - if (sm9_verify_init(&ctx) != 1) { - error_print(); - goto end; - } - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - if (sm9_verify_update(&ctx, buf, len) != 1) { - error_print(); - goto end; - } - } - if ((ret = sm9_verify_finish(&ctx, sig, siglen, &mpk, id, strlen(id))) != 1) { - error_print(); - goto end; - } - printf("%s %s\n", prog, ret ? "success" : "failure"); - -end: - if (infile && infp) fclose(infp); - if (mpkfile && mpkfp) fclose(mpkfp); - if (sigfile && sigfp) fclose(sigfp); - return ret; -} - - - - - - - - + + +#include +#include +#include +#include +#include + + +static const char *options = "[-in file] -pubmaster file -id str -sig file"; + +int sm9verify_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *infile = NULL; + char *mpkfile = NULL; + char *id = NULL; + char *sigfile = NULL; + FILE *infp = stdin; + FILE *mpkfp = NULL; + FILE *sigfp = NULL; + SM9_SIGN_MASTER_KEY mpk; + SM9_SIGN_CTX ctx; + uint8_t buf[4096]; + ssize_t len; + uint8_t sig[SM9_SIGNATURE_SIZE]; + ssize_t siglen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + fprintf(stdout, "usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-pubmaster")) { + if (--argc < 1) goto bad; + mpkfile = *(++argv); + if (!(mpkfp = fopen(mpkfile, "r"))) { + error_print(); + goto end; + } + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-sig")) { + if (--argc < 1) goto bad; + sigfile = *(++argv); + if (!(sigfp = fopen(sigfile, "r"))) { + error_print(); + goto end; + } + } else { +bad: + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + return 1; + } + + argc--; + argv++; + } + + if (!mpkfile || !id || !sigfile) { + error_print(); + goto end; + } + + if (sm9_sign_master_public_key_from_pem(&mpk, mpkfp) != 1) { + error_print(); + goto end; + } + + if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { + error_print(); + goto end; + } + + if (sm9_verify_init(&ctx) != 1) { + error_print(); + goto end; + } + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + if (sm9_verify_update(&ctx, buf, len) != 1) { + error_print(); + goto end; + } + } + if ((ret = sm9_verify_finish(&ctx, sig, siglen, &mpk, id, strlen(id))) != 1) { + error_print(); + goto end; + } + printf("%s %s\n", prog, ret ? "success" : "failure"); + +end: + if (infile && infp) fclose(infp); + if (mpkfile && mpkfp) fclose(mpkfp); + if (sigfile && sigfp) fclose(sigfp); + return ret; +} + + + + + + + + diff --git a/tools/tlcp_client.c b/tools/tlcp_client.c index 7a28716a..afd9a42e 100644 --- a/tools/tlcp_client.c +++ b/tools/tlcp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,197 +7,198 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int client_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, }; - -static const char *http_get = - "GET / HTTP/1.1\r\n" - "Hostname: aaa\r\n" - "\r\n\r\n"; - -static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; - -int tlcp_client_main(int argc, char *argv[]) -{ - int ret = -1; - char *prog = argv[0]; - char *host = NULL; - int port = 443; - char *cacertfile = NULL; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - struct hostent *hp; - struct sockaddr_in server; - int sock; - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1024] = {0}; - size_t len = sizeof(buf); - char send_buf[1024] = {0}; - size_t send_len; - - argc--; - argv++; - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - while (argc >= 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-host")) { - if (--argc < 1) goto bad; - host = *(++argv); - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 0; - } - argc--; - argv++; - } - - if (!host) { - fprintf(stderr, "%s: '-in' option required\n", prog); - return -1; - } - if (!(hp = gethostbyname(host))) { - herror("tlcp_client: '-host' invalid"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); - goto end; - } - if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); - goto end; - } - - if (tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - if (certfile) { - if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - - - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, sock) != 1 - || tls_do_handshake(&conn) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - - - for (;;) { - fd_set fds; - size_t sentlen; - - FD_ZERO(&fds); - FD_SET(conn.sock, &fds); - FD_SET(STDIN_FILENO, &fds); - - if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { - fprintf(stderr, "%s: select failed\n", prog); - goto end; - } - - if (FD_ISSET(conn.sock, &fds)) { - for (;;) { - memset(buf, 0, sizeof(buf)); - if (tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { - goto end; - } - fwrite(buf, 1, len, stdout); - fflush(stdout); - - // 应该调整tls_recv 逻辑、API或者其他方式 - if (conn.datalen == 0) { - break; - } - } - - } - if (FD_ISSET(STDIN_FILENO, &fds)) { - fprintf(stderr, "recv from stdin\n"); - - memset(send_buf, 0, sizeof(send_buf)); - - if (!fgets(send_buf, sizeof(send_buf), stdin)) { - if (feof(stdin)) { - tls_shutdown(&conn); - goto end; - } else { - continue; - } - } - if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { - fprintf(stderr, "%s: send error\n", prog); - goto end; - } - } - - fprintf(stderr, "end of this round\n"); - } - - -end: - close(sock); - tls_ctx_cleanup(&ctx); - tls_cleanup(&conn); - return 0; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int client_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, }; + +static const char *http_get = + "GET / HTTP/1.1\r\n" + "Hostname: aaa\r\n" + "\r\n\r\n"; + +static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; + +int tlcp_client_main(int argc, char *argv[]) +{ + int ret = -1; + char *prog = argv[0]; + char *host = NULL; + int port = 443; + char *cacertfile = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + struct hostent *hp; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1024] = {0}; + size_t len = sizeof(buf); + char send_buf[1024] = {0}; + size_t send_len; + + argc--; + argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc >= 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-host")) { + if (--argc < 1) goto bad; + host = *(++argv); + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 0; + } + argc--; + argv++; + } + + if (!host) { + fprintf(stderr, "%s: '-in' option required\n", prog); + return -1; + } + if (!(hp = gethostbyname(host))) { + herror("tlcp_client: '-host' invalid"); + goto end; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); + goto end; + } + + if (tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + if (certfile) { + if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, sock) != 1 + || tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + + + for (;;) { + fd_set fds; + size_t sentlen; + + FD_ZERO(&fds); + FD_SET(conn.sock, &fds); + FD_SET(STDIN_FILENO, &fds); + + if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { + fprintf(stderr, "%s: select failed\n", prog); + goto end; + } + + if (FD_ISSET(conn.sock, &fds)) { + for (;;) { + memset(buf, 0, sizeof(buf)); + if (tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { + goto end; + } + fwrite(buf, 1, len, stdout); + fflush(stdout); + + // 应该调整tls_recv 逻辑、API或者其他方式 + if (conn.datalen == 0) { + break; + } + } + + } + if (FD_ISSET(STDIN_FILENO, &fds)) { + fprintf(stderr, "recv from stdin\n"); + + memset(send_buf, 0, sizeof(send_buf)); + + if (!fgets(send_buf, sizeof(send_buf), stdin)) { + if (feof(stdin)) { + tls_shutdown(&conn); + goto end; + } else { + continue; + } + } + if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { + fprintf(stderr, "%s: send error\n", prog); + goto end; + } + } + + fprintf(stderr, "end of this round\n"); + } + + +end: + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); + return 0; +} diff --git a/tools/tlcp_server.c b/tools/tlcp_server.c index cc30b101..6f866996 100644 --- a/tools/tlcp_server.c +++ b/tools/tlcp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,194 +7,195 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-port num] -cert file -key file [-pass str] -ex_key file [-ex_pass str] [-cacert file]"; - -int tlcp_server_main(int argc , char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int port = 443; - char *certfile = NULL; - char *signkeyfile = NULL; - char *signpass = NULL; - char *enckeyfile = NULL; - char *encpass = NULL; - char *cacertfile = NULL; - - int server_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, }; - uint8_t verify_buf[4096]; - - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1600] = {0}; - size_t len = sizeof(buf); - - int sock; - struct sockaddr_in server_addr; - struct sockaddr_in client_addr; - socklen_t client_addrlen; - int conn_sock; - - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - signkeyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - signpass = *(++argv); - } else if (!strcmp(*argv, "-ex_key")) { - if (--argc < 1) goto bad; - enckeyfile = *(++argv); - } else if (!strcmp(*argv, "-ex_pass")) { - if (--argc < 1) goto bad; - encpass = *(++argv); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 1; - } - argc--; - argv++; - } - if (!certfile) { - fprintf(stderr, "%s: '-cert' option required\n", prog); - return 1; - } - if (!signkeyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - return 1; - } - if (!signpass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - return 1; - } - if (!enckeyfile) { - fprintf(stderr, "%s: '-ex_key' option required\n", prog); - return 1; - } - if (!encpass) { - fprintf(stderr, "%s: '-ex_pass' option required\n", prog); - return 1; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - if (tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_server_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 - || tls_ctx_set_tlcp_server_certificate_and_keys(&ctx, certfile, signkeyfile, signpass, enckeyfile, encpass) != 1) { - error_print(); - return -1; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - error_print(); - return -1; - } - } - - // Socket - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - error_print(); - return 1; - } - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(port); - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - error_print(); - perror("tlcp_accept: bind: "); - goto end; - } - puts("start listen ...\n"); - listen(sock, 1); - - - -restart: - - client_addrlen = sizeof(client_addr); - if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { - error_print(); - goto end; - } - puts("socket connected\n"); - - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, conn_sock) != 1) { - error_print(); - return -1; - } - - if (tls_do_handshake(&conn) != 1) { - error_print(); // 为什么这个会触发呢? - return -1; - } - - for (;;) { - - int rv; - size_t sentlen; - - do { - len = sizeof(buf); - if ((rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { - if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); - else fprintf(stderr, "%s: Disconnected by remote\n", prog); - - //close(conn.sock); - tls_cleanup(&conn); - goto restart; - } - } while (!len); - - if (tls_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { - fprintf(stderr, "%s: send failure, close connection\n", prog); - close(conn.sock); - goto end; - } - } - - -end: - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-port num] -cert file -key file [-pass str] -ex_key file [-ex_pass str] [-cacert file]"; + +int tlcp_server_main(int argc , char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int port = 443; + char *certfile = NULL; + char *signkeyfile = NULL; + char *signpass = NULL; + char *enckeyfile = NULL; + char *encpass = NULL; + char *cacertfile = NULL; + + int server_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, }; + uint8_t verify_buf[4096]; + + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1600] = {0}; + size_t len = sizeof(buf); + + int sock; + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + socklen_t client_addrlen; + int conn_sock; + + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + signkeyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + signpass = *(++argv); + } else if (!strcmp(*argv, "-ex_key")) { + if (--argc < 1) goto bad; + enckeyfile = *(++argv); + } else if (!strcmp(*argv, "-ex_pass")) { + if (--argc < 1) goto bad; + encpass = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 1; + } + argc--; + argv++; + } + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + return 1; + } + if (!signkeyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + return 1; + } + if (!signpass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + return 1; + } + if (!enckeyfile) { + fprintf(stderr, "%s: '-ex_key' option required\n", prog); + return 1; + } + if (!encpass) { + fprintf(stderr, "%s: '-ex_pass' option required\n", prog); + return 1; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + if (tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_server_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 + || tls_ctx_set_tlcp_server_certificate_and_keys(&ctx, certfile, signkeyfile, signpass, enckeyfile, encpass) != 1) { + error_print(); + return -1; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + error_print(); + return -1; + } + } + + // Socket + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return 1; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(port); + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_print(); + perror("tlcp_accept: bind: "); + goto end; + } + puts("start listen ...\n"); + listen(sock, 1); + + + +restart: + + client_addrlen = sizeof(client_addr); + if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { + error_print(); + goto end; + } + puts("socket connected\n"); + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, conn_sock) != 1) { + error_print(); + return -1; + } + + if (tls_do_handshake(&conn) != 1) { + error_print(); // 为什么这个会触发呢? + return -1; + } + + for (;;) { + + int rv; + size_t sentlen; + + do { + len = sizeof(buf); + if ((rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { + if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); + else fprintf(stderr, "%s: Disconnected by remote\n", prog); + + //close(conn.sock); + tls_cleanup(&conn); + goto restart; + } + } while (!len); + + if (tls_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { + fprintf(stderr, "%s: send failure, close connection\n", prog); + close(conn.sock); + goto end; + } + } + + +end: + return ret; +} diff --git a/tools/tls12_client.c b/tools/tls12_client.c index 43728f51..6e18971d 100644 --- a/tools/tls12_client.c +++ b/tools/tls12_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,194 +7,195 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -// TLSv1.2客户单和TLCP客户端可能没有什么区别 - -static int client_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3 }; - -static const char *http_get = - "GET / HTTP/1.1\r\n" - "Hostname: aaa\r\n" - "\r\n\r\n"; - -static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; - -int tls12_client_main(int argc, char *argv[]) -{ - int ret = -1; - char *prog = argv[0]; - char *host = NULL; - int port = 443; - char *cacertfile = NULL; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - struct hostent *hp; - struct sockaddr_in server; - int sock; - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1024] = {0}; - size_t len = sizeof(buf); - char send_buf[1024] = {0}; - size_t send_len; - - argc--; - argv++; - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - while (argc >= 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-host")) { - if (--argc < 1) goto bad; - host = *(++argv); - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 0; - } - argc--; - argv++; - } - - if (!host) { - fprintf(stderr, "%s: '-in' option required\n", prog); - return -1; - } - if (!(hp = gethostbyname(host))) { - herror("tls12_client: '-host' invalid"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); - goto end; - } - if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); - goto end; - } - - if (tls_ctx_init(&ctx, TLS_protocol_tls12, TLS_client_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - if (certfile) { - if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, sock) != 1 - || tls_do_handshake(&conn) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - for (;;) { - fd_set fds; - size_t sentlen; - - FD_ZERO(&fds); - FD_SET(conn.sock, &fds); - FD_SET(STDIN_FILENO, &fds); - - if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { - fprintf(stderr, "%s: select failed\n", prog); - goto end; - } - - if (FD_ISSET(conn.sock, &fds)) { - for (;;) { - memset(buf, 0, sizeof(buf)); - if (tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { - goto end; - } - fwrite(buf, 1, len, stdout); - fflush(stdout); - - // 应该调整tls_recv 逻辑、API或者其他方式 - if (conn.datalen == 0) { - break; - } - } - - } - if (FD_ISSET(STDIN_FILENO, &fds)) { - memset(send_buf, 0, sizeof(send_buf)); - - if (!fgets(send_buf, sizeof(send_buf), stdin)) { - if (feof(stdin)) { - tls_shutdown(&conn); - goto end; - } else { - continue; - } - } - if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { - fprintf(stderr, "%s: send error\n", prog); - goto end; - } - } - } - - -end: - close(sock); - tls_ctx_cleanup(&ctx); - tls_cleanup(&conn); - return 0; -} + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +// TLSv1.2客户单和TLCP客户端可能没有什么区别 + +static int client_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3 }; + +static const char *http_get = + "GET / HTTP/1.1\r\n" + "Hostname: aaa\r\n" + "\r\n\r\n"; + +static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; + +int tls12_client_main(int argc, char *argv[]) +{ + int ret = -1; + char *prog = argv[0]; + char *host = NULL; + int port = 443; + char *cacertfile = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + struct hostent *hp; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1024] = {0}; + size_t len = sizeof(buf); + char send_buf[1024] = {0}; + size_t send_len; + + argc--; + argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc >= 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-host")) { + if (--argc < 1) goto bad; + host = *(++argv); + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 0; + } + argc--; + argv++; + } + + if (!host) { + fprintf(stderr, "%s: '-in' option required\n", prog); + return -1; + } + if (!(hp = gethostbyname(host))) { + herror("tls12_client: '-host' invalid"); + goto end; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); + goto end; + } + + if (tls_ctx_init(&ctx, TLS_protocol_tls12, TLS_client_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + if (certfile) { + if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, sock) != 1 + || tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + for (;;) { + fd_set fds; + size_t sentlen; + + FD_ZERO(&fds); + FD_SET(conn.sock, &fds); + FD_SET(STDIN_FILENO, &fds); + + if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { + fprintf(stderr, "%s: select failed\n", prog); + goto end; + } + + if (FD_ISSET(conn.sock, &fds)) { + for (;;) { + memset(buf, 0, sizeof(buf)); + if (tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { + goto end; + } + fwrite(buf, 1, len, stdout); + fflush(stdout); + + // 应该调整tls_recv 逻辑、API或者其他方式 + if (conn.datalen == 0) { + break; + } + } + + } + if (FD_ISSET(STDIN_FILENO, &fds)) { + memset(send_buf, 0, sizeof(send_buf)); + + if (!fgets(send_buf, sizeof(send_buf), stdin)) { + if (feof(stdin)) { + tls_shutdown(&conn); + goto end; + } else { + continue; + } + } + if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { + fprintf(stderr, "%s: send error\n", prog); + goto end; + } + } + } + + +end: + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); + return 0; +} diff --git a/tools/tls12_server.c b/tools/tls12_server.c index 87d5ae35..713ab8b6 100644 --- a/tools/tls12_server.c +++ b/tools/tls12_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,178 +7,179 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; - -int tls12_server_main(int argc , char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int port = 443; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *cacertfile = NULL; - - int server_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3, }; - uint8_t verify_buf[4096]; - - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1600] = {0}; - size_t len = sizeof(buf); - - int sock; - struct sockaddr_in server_addr; - struct sockaddr_in client_addr; - socklen_t client_addrlen; - int conn_sock; - - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 1; - } - argc--; - argv++; - } - if (!certfile) { - fprintf(stderr, "%s: '-cert' option required\n", prog); - return 1; - } - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - return 1; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - return 1; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - if (tls_ctx_init(&ctx, TLS_protocol_tls12, TLS_server_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 - || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { - error_print(); - return -1; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - error_print(); - return -1; - } - } - - // Socket - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - error_print(); - return 1; - } - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(port); - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - error_print(); - perror("tlcp_accept: bind: "); - goto end; - } - puts("start listen ...\n"); - listen(sock, 1); - - - -restart: - - client_addrlen = sizeof(client_addr); - if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { - error_print(); - goto end; - } - puts("socket connected\n"); - - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, conn_sock) != 1) { - error_print(); - return -1; - } - - if (tls_do_handshake(&conn) != 1) { - error_print(); // 为什么这个会触发呢? - return -1; - } - - for (;;) { - - int rv; - size_t sentlen; - - do { - len = sizeof(buf); - if ((rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { - if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); - else fprintf(stderr, "%s: Disconnected by remote\n", prog); - - //close(conn.sock); - tls_cleanup(&conn); - goto restart; - } - } while (!len); - - if (tls_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { - fprintf(stderr, "%s: send failure, close connection\n", prog); - close(conn.sock); - goto end; - } - } - - -end: - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; + +int tls12_server_main(int argc , char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int port = 443; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + char *cacertfile = NULL; + + int server_ciphers[] = { TLS_cipher_ecdhe_sm4_cbc_sm3, }; + uint8_t verify_buf[4096]; + + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1600] = {0}; + size_t len = sizeof(buf); + + int sock; + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + socklen_t client_addrlen; + int conn_sock; + + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 1; + } + argc--; + argv++; + } + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + return 1; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + return 1; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + return 1; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + if (tls_ctx_init(&ctx, TLS_protocol_tls12, TLS_server_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 + || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + error_print(); + return -1; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + error_print(); + return -1; + } + } + + // Socket + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return 1; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(port); + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_print(); + perror("tlcp_accept: bind: "); + goto end; + } + puts("start listen ...\n"); + listen(sock, 1); + + + +restart: + + client_addrlen = sizeof(client_addr); + if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { + error_print(); + goto end; + } + puts("socket connected\n"); + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, conn_sock) != 1) { + error_print(); + return -1; + } + + if (tls_do_handshake(&conn) != 1) { + error_print(); // 为什么这个会触发呢? + return -1; + } + + for (;;) { + + int rv; + size_t sentlen; + + do { + len = sizeof(buf); + if ((rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { + if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); + else fprintf(stderr, "%s: Disconnected by remote\n", prog); + + //close(conn.sock); + tls_cleanup(&conn); + goto restart; + } + } while (!len); + + if (tls_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { + fprintf(stderr, "%s: send failure, close connection\n", prog); + close(conn.sock); + goto end; + } + } + + +end: + return ret; +} diff --git a/tools/tls13_client.c b/tools/tls13_client.c index 742a370b..9166f6d4 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,192 +7,193 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -// TLSv1.2客户单和TLCP客户端可能没有什么区别 - -static int client_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; - -static const char *http_get = - "GET / HTTP/1.1\r\n" - "Hostname: aaa\r\n" - "\r\n\r\n"; - -static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; - -int tls13_client_main(int argc, char *argv[]) -{ - int ret = -1; - char *prog = argv[0]; - char *host = NULL; - int port = 443; - char *cacertfile = NULL; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - struct hostent *hp; - struct sockaddr_in server; - int sock; - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1024] = {0}; - size_t len = sizeof(buf); - char send_buf[1024] = {0}; - size_t send_len; - - argc--; - argv++; - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - while (argc >= 1) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-host")) { - if (--argc < 1) goto bad; - host = *(++argv); - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 0; - } - argc--; - argv++; - } - - if (!host) { - fprintf(stderr, "%s: '-in' option required\n", prog); - return -1; - } - if (!(hp = gethostbyname(host))) { - herror("tls13_client: '-host' invalid"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); - goto end; - } - if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); - goto end; - } - - if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_client_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - if (certfile) { - if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - } - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, sock) != 1 - || tls_do_handshake(&conn) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - for (;;) { - fd_set fds; - size_t sentlen; - - FD_ZERO(&fds); - FD_SET(conn.sock, &fds); - FD_SET(STDIN_FILENO, &fds); - - if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { - fprintf(stderr, "%s: select failed\n", prog); - goto end; - } - - if (FD_ISSET(conn.sock, &fds)) { - for (;;) { - memset(buf, 0, sizeof(buf)); - if (tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { - goto end; - } - fwrite(buf, 1, len, stdout); - fflush(stdout); - - // 应该调整tls_recv 逻辑、API或者其他方式 - if (conn.datalen == 0) { - break; - } - } - - } - if (FD_ISSET(STDIN_FILENO, &fds)) { - memset(send_buf, 0, sizeof(send_buf)); - - if (!fgets(send_buf, sizeof(send_buf), stdin)) { - if (feof(stdin)) { - tls_shutdown(&conn); - goto end; - } else { - continue; - } - } - if (tls13_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { - fprintf(stderr, "%s: send error\n", prog); - goto end; - } - } - } - -end: - close(sock); - tls_ctx_cleanup(&ctx); - tls_cleanup(&conn); - return 0; -} + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +// TLSv1.2客户单和TLCP客户端可能没有什么区别 + +static int client_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + +static const char *http_get = + "GET / HTTP/1.1\r\n" + "Hostname: aaa\r\n" + "\r\n\r\n"; + +static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; + +int tls13_client_main(int argc, char *argv[]) +{ + int ret = -1; + char *prog = argv[0]; + char *host = NULL; + int port = 443; + char *cacertfile = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + struct hostent *hp; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1024] = {0}; + size_t len = sizeof(buf); + char send_buf[1024] = {0}; + size_t send_len; + + argc--; + argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc >= 1) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-host")) { + if (--argc < 1) goto bad; + host = *(++argv); + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 0; + } + argc--; + argv++; + } + + if (!host) { + fprintf(stderr, "%s: '-in' option required\n", prog); + return -1; + } + if (!(hp = gethostbyname(host))) { + herror("tls13_client: '-host' invalid"); + goto end; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); + goto end; + } + + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_client_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + if (certfile) { + if (tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + } + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, sock) != 1 + || tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; + } + + for (;;) { + fd_set fds; + size_t sentlen; + + FD_ZERO(&fds); + FD_SET(conn.sock, &fds); + FD_SET(STDIN_FILENO, &fds); + + if (select(conn.sock + 1, &fds, NULL, NULL, NULL) < 0) { + fprintf(stderr, "%s: select failed\n", prog); + goto end; + } + + if (FD_ISSET(conn.sock, &fds)) { + for (;;) { + memset(buf, 0, sizeof(buf)); + if (tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) { + goto end; + } + fwrite(buf, 1, len, stdout); + fflush(stdout); + + // 应该调整tls_recv 逻辑、API或者其他方式 + if (conn.datalen == 0) { + break; + } + } + + } + if (FD_ISSET(STDIN_FILENO, &fds)) { + memset(send_buf, 0, sizeof(send_buf)); + + if (!fgets(send_buf, sizeof(send_buf), stdin)) { + if (feof(stdin)) { + tls_shutdown(&conn); + goto end; + } else { + continue; + } + } + if (tls13_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { + fprintf(stderr, "%s: send error\n", prog); + goto end; + } + } + } + +end: + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); + return 0; +} diff --git a/tools/tls13_server.c b/tools/tls13_server.c index d30b0b88..6299ba16 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,178 +7,179 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; - -int tls13_server_main(int argc , char **argv) -{ - int ret = 1; - char *prog = argv[0]; - int port = 443; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *cacertfile = NULL; - - int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, }; - uint8_t verify_buf[4096]; - - TLS_CTX ctx; - TLS_CONNECT conn; - char buf[1600] = {0}; - size_t len = sizeof(buf); - - int sock; - struct sockaddr_in server_addr; - struct sockaddr_in client_addr; - socklen_t client_addrlen; - int conn_sock; - - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - return 0; - } else if (!strcmp(*argv, "-port")) { - if (--argc < 1) goto bad; - port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); - } else if (!strcmp(*argv, "-cacert")) { - if (--argc < 1) goto bad; - cacertfile = *(++argv); - } else { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; -bad: - fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); - return 1; - } - argc--; - argv++; - } - if (!certfile) { - fprintf(stderr, "%s: '-cert' option required\n", prog); - return 1; - } - if (!keyfile) { - fprintf(stderr, "%s: '-key' option required\n", prog); - return 1; - } - if (!pass) { - fprintf(stderr, "%s: '-pass' option required\n", prog); - return 1; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_server_mode) != 1 - || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 - || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { - error_print(); - return -1; - } - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - error_print(); - return -1; - } - } - - // Socket - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - error_print(); - return 1; - } - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(port); - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - error_print(); - perror("tlcp_accept: bind: "); - goto end; - } - puts("start listen ...\n"); - listen(sock, 1); - - - -restart: - - client_addrlen = sizeof(client_addr); - if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { - error_print(); - goto end; - } - puts("socket connected\n"); - - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, conn_sock) != 1) { - error_print(); - return -1; - } - - if (tls_do_handshake(&conn) != 1) { - error_print(); // 为什么这个会触发呢? - return -1; - } - - for (;;) { - - int rv; - size_t sentlen; - - do { - len = sizeof(buf); - if ((rv = tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { - if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); - else fprintf(stderr, "%s: Disconnected by remote\n", prog); - - //close(conn.sock); - tls_cleanup(&conn); - goto restart; - } - } while (!len); - - if (tls13_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { - fprintf(stderr, "%s: send failure, close connection\n", prog); - close(conn.sock); - goto end; - } - } - - -end: - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; + +int tls13_server_main(int argc , char **argv) +{ + int ret = 1; + char *prog = argv[0]; + int port = 443; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + char *cacertfile = NULL; + + int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, }; + uint8_t verify_buf[4096]; + + TLS_CTX ctx; + TLS_CONNECT conn; + char buf[1600] = {0}; + size_t len = sizeof(buf); + + int sock; + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + socklen_t client_addrlen; + int conn_sock; + + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; + } else if (!strcmp(*argv, "-port")) { + if (--argc < 1) goto bad; + port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cert")) { + if (--argc < 1) goto bad; + certfile = *(++argv); + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 1; + } + argc--; + argv++; + } + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + return 1; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + return 1; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + return 1; + } + + memset(&ctx, 0, sizeof(ctx)); + memset(&conn, 0, sizeof(conn)); + + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_server_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 + || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + error_print(); + return -1; + } + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + error_print(); + return -1; + } + } + + // Socket + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return 1; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(port); + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_print(); + perror("tlcp_accept: bind: "); + goto end; + } + puts("start listen ...\n"); + listen(sock, 1); + + + +restart: + + client_addrlen = sizeof(client_addr); + if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { + error_print(); + goto end; + } + puts("socket connected\n"); + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, conn_sock) != 1) { + error_print(); + return -1; + } + + if (tls_do_handshake(&conn) != 1) { + error_print(); // 为什么这个会触发呢? + return -1; + } + + for (;;) { + + int rv; + size_t sentlen; + + do { + len = sizeof(buf); + if ((rv = tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { + if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); + else fprintf(stderr, "%s: Disconnected by remote\n", prog); + + //close(conn.sock); + tls_cleanup(&conn); + goto restart; + } + } while (!len); + + if (tls13_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { + fprintf(stderr, "%s: send failure, close connection\n", prog); + close(conn.sock); + goto end; + } + } + + +end: + return ret; +} diff --git a/tools/version.c b/tools/version.c index 8f2f5bc7..c2a7e8a4 100644 --- a/tools/version.c +++ b/tools/version.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,15 +7,16 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include - - -int version_main(int argc, char **argv) -{ - printf("%s\n", gmssl_version_str()); - return 0; -} + + +#include +#include +#include +#include + + +int version_main(int argc, char **argv) +{ + printf("%s\n", gmssl_version_str()); + return 0; +} diff --git a/tools/zuc.c b/tools/zuc.c index e0c7ccb5..659258cd 100644 --- a/tools/zuc.c +++ b/tools/zuc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,138 +7,139 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char *options = "-key hex -iv hex [-in file] [-out file]"; - -int zuc_main(int argc, char **argv) -{ - int ret = 1; - char *prog = argv[0]; - char *keyhex = NULL; - char *ivhex = NULL; - char *infile = NULL; - char *outfile = NULL; - uint8_t key[16]; - uint8_t iv[16]; - size_t keylen = sizeof(key); - size_t ivlen = sizeof(iv); - FILE *infp = stdin; - FILE *outfp = stdout; - ZUC_CTX zuc_ctx; - uint8_t inbuf[4096]; - size_t inlen; - uint8_t outbuf[4196]; - size_t outlen; - - argc--; - argv++; - - if (argc < 1) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; - } - - while (argc > 0) { - if (!strcmp(*argv, "-help")) { - printf("usage: %s %s\n", prog, options); - ret = 0; - goto end; - } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyhex = *(++argv); - if (strlen(keyhex) != sizeof(key) * 2) { - fprintf(stderr, "%s: invalid key length\n", prog); - goto end; - } - if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-iv")) { - if (--argc < 1) goto bad; - ivhex = *(++argv); - if (strlen(ivhex) != sizeof(iv) * 2) { - fprintf(stderr, "%s: invalid IV length\n", prog); - goto end; - } - if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { - fprintf(stderr, "%s: invalid HEX digits\n", prog); - goto end; - } - } else if (!strcmp(*argv, "-in")) { - if (--argc < 1) goto bad; - infile = *(++argv); - if (!(infp = fopen(infile, "r"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); - goto end; - } - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) goto bad; - outfile = *(++argv); - if (!(outfp = fopen(outfile, "w"))) { - fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); - goto end; - } - } else { - fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto end; -bad: - fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); - goto end; - } - - argc--; - argv++; - } - - if (!keyhex) { - fprintf(stderr, "%s: option '-key' missing\n", prog); - goto end; - } - if (!ivhex) { - fprintf(stderr, "%s: option '-iv' missing\n", prog); - goto end; - } - - if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { - if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - } - if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) { - fprintf(stderr, "%s: inner error\n", prog); - goto end; - } - if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); - goto end; - } - ret = 0; -end: - gmssl_secure_clear(&zuc_ctx, sizeof(zuc_ctx)); - gmssl_secure_clear(key, sizeof(key)); - gmssl_secure_clear(iv, sizeof(iv)); - gmssl_secure_clear(inbuf, sizeof(inbuf)); - gmssl_secure_clear(outbuf, sizeof(outbuf)); - if (infile && infp) fclose(infp); - if (outfile && outfp) fclose(outfp); - return ret; -} + + +#include +#include +#include +#include +#include +#include +#include + + +static const char *options = "-key hex -iv hex [-in file] [-out file]"; + +int zuc_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *keyhex = NULL; + char *ivhex = NULL; + char *infile = NULL; + char *outfile = NULL; + uint8_t key[16]; + uint8_t iv[16]; + size_t keylen = sizeof(key); + size_t ivlen = sizeof(iv); + FILE *infp = stdin; + FILE *outfp = stdout; + ZUC_CTX zuc_ctx; + uint8_t inbuf[4096]; + size_t inlen; + uint8_t outbuf[4196]; + size_t outlen; + + argc--; + argv++; + + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { + if (--argc < 1) goto bad; + keyhex = *(++argv); + if (strlen(keyhex) != sizeof(key) * 2) { + fprintf(stderr, "%s: invalid key length\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-iv")) { + if (--argc < 1) goto bad; + ivhex = *(++argv); + if (strlen(ivhex) != sizeof(iv) * 2) { + fprintf(stderr, "%s: invalid IV length\n", prog); + goto end; + } + if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } + } else { + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; + } + + argc--; + argv++; + } + + if (!keyhex) { + fprintf(stderr, "%s: option '-key' missing\n", prog); + goto end; + } + if (!ivhex) { + fprintf(stderr, "%s: option '-iv' missing\n", prog); + goto end; + } + + if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { + if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } + if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&zuc_ctx, sizeof(zuc_ctx)); + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(iv, sizeof(iv)); + gmssl_secure_clear(inbuf, sizeof(inbuf)); + gmssl_secure_clear(outbuf, sizeof(outbuf)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; +}