From abec8fcfb99d4f6c70f98f0febbb130ac5c5826d Mon Sep 17 00:00:00 2001 From: K1 Date: Wed, 28 Feb 2024 16:54:10 +0800 Subject: [PATCH] SMTC integrates with crypto card based on atf-slibce engine;add sdf, TSAPI and etc. DRBG set reseed interval and reseed_time_interval according to GM/T 0105-2021. Modify of the integrity verification mechanism to SM2 signature. App rand supports getting entropy from specified source. Rename entropy rtc1 to rtcode, rtc2 to rtmem. Add rtsock entropy source. Support requesting entropy from specified entropy source. Support atf-slibce engine. Add sdf framework and partial APIs. Add sdf app. App speed add keygen for SM2 and GenerateKey with SDF. Add TSAPI, mainly includes functions such as random number, signature verification, encryption and decryption, etc. --- .github/workflows/ci.yml | 9 +- .github/workflows/compiler-zoo.yml | 3 +- .github/workflows/run-checker-ci.yml | 2 - .github/workflows/run-checker-daily.yml | 2 - .github/workflows/run-checker-merge.yml | 2 - Configurations/00-base-templates.conf | 6 + Configure | 71 +- VERSION.dat | 3 +- apps/build.info | 4 + apps/enc.c | 1 + apps/mod.c | 595 +++++--- apps/openssl.c | 115 +- apps/rand.c | 84 +- apps/s_server.c | 2 - apps/sdf.c | 516 +++++++ apps/speed.c | 326 +++- apps/version.c | 1 - crypto/bio/bss_log.c | 20 +- crypto/build.info | 15 +- crypto/ec/ec_key.c | 53 +- crypto/err/openssl.txt | 7 +- crypto/evp/m_sigver.c | 12 +- crypto/evp/pmeth_gn.c | 9 + crypto/evp/pmeth_lib.c | 76 + crypto/info.c | 16 +- crypto/init.c | 4 + crypto/o_syslog.c | 80 + crypto/provider.c | 10 + crypto/provider_core.c | 24 + crypto/provider_predefined.c | 13 +- crypto/rand/prov_seed.c | 28 + crypto/rand/rand_lib.c | 19 + crypto/rand/rand_pool.c | 8 + crypto/sdf/build.info | 3 + crypto/sdf/sdf_lib.c | 416 ++++++ crypto/sdf/sdf_local.h | 130 ++ crypto/sdf/sdf_meth.c | 168 +++ crypto/sm2/sm2_crypt.c | 56 + crypto/trace.c | 5 +- crypto/tsapi/build.info | 3 + crypto/tsapi/tsapi_lib.c | 1322 +++++++++++++++++ crypto/x509/v3_skid.c | 6 +- include/crypto/rand.h | 15 + include/crypto/rand_pool.h | 23 +- include/crypto/sm2.h | 5 + include/internal/cryptlib.h | 5 + include/internal/provider.h | 2 + include/internal/sdf.h | 16 + include/internal/smtc_names.h | 20 +- include/openssl/core_dispatch.h | 6 + include/openssl/crypto.h.in | 27 + include/openssl/evp.h | 6 + include/openssl/opensslv.h.in | 2 +- include/openssl/proverr.h | 6 +- include/openssl/provider.h | 2 + include/openssl/rand.h | 1 + include/openssl/sdf.h | 118 ++ include/openssl/self_test.h | 4 + include/openssl/sgd.h | 53 + include/openssl/trace.h | 3 +- include/openssl/tsapi.h | 98 ++ include/openssl/types.h | 2 + providers/build.info | 36 +- providers/common/include/prov/proverr.h | 2 +- providers/common/include/prov/provider_util.h | 8 +- providers/common/provider_err.c | 10 +- providers/implementations/rands/drbg_hash.c | 18 +- providers/implementations/rands/drbg_local.h | 32 +- .../implementations/rands/seeding/rand_unix.c | 125 +- .../implementations/rands/seeding/rand_win.c | 110 +- providers/implementations/rands/smtc_rng.c | 164 +- providers/prov_running.c | 2 + providers/smtc/README.md | 15 +- providers/smtc/self_test.c | 625 ++++++-- providers/smtc/self_test.h | 18 +- providers/smtc/self_test_data.inc | 142 +- providers/smtc/self_test_kats.c | 386 ++++- providers/smtc/self_test_rand.c | 102 +- providers/smtc/self_test_rand.h | 8 +- providers/smtc/smtckey.h.in | 11 +- providers/smtc/smtcprov.c | 322 +++- ssl/statem_ntls/ntls_statem_srvr.c | 2 +- ssl/t1_enc.c | 7 + ssl/t1_lib.c | 8 +- test/build.info | 6 +- test/{ssl-tests => ntls-tests}/31-ntls.cnf | 0 test/{ssl-tests => ntls-tests}/31-ntls.cnf.in | 0 .../32-ntls-force-ntls.cnf | 0 .../32-ntls-force-ntls.cnf.in | 0 .../39-ntls-sni-ticket.cnf | 0 .../39-ntls-sni-ticket.cnf.in | 0 .../40-ntls_client_auth.cnf | 0 .../40-ntls_client_auth.cnf.in | 0 .../41-ntls-alpn.cnf | 0 .../41-ntls-alpn.cnf.in | 0 test/recipes/00-prep_smtc_cnf.t | 7 +- test/recipes/20-test_cli_smtc.t | 95 +- test/recipes/20-test_mod.t | 2 +- test/recipes/80-test_ntls.t | 126 ++ test/recipes/80-test_ssl_new.t | 32 +- test/recipes/92-test_tsapi.t | 22 + test/{smtc-and-base.cnf => smtc.cnf} | 5 +- test/testutil/provider.c | 2 +- test/tsapi_test.c | 484 ++++++ util/libcrypto.num | 54 + util/wrap.pl.in | 57 +- 106 files changed, 6717 insertions(+), 987 deletions(-) create mode 100644 apps/sdf.c create mode 100644 crypto/o_syslog.c create mode 100644 crypto/sdf/build.info create mode 100644 crypto/sdf/sdf_lib.c create mode 100644 crypto/sdf/sdf_local.h create mode 100644 crypto/sdf/sdf_meth.c create mode 100644 crypto/tsapi/build.info create mode 100644 crypto/tsapi/tsapi_lib.c create mode 100644 include/internal/sdf.h create mode 100644 include/openssl/sdf.h create mode 100644 include/openssl/sgd.h create mode 100644 include/openssl/tsapi.h rename test/{ssl-tests => ntls-tests}/31-ntls.cnf (100%) rename test/{ssl-tests => ntls-tests}/31-ntls.cnf.in (100%) rename test/{ssl-tests => ntls-tests}/32-ntls-force-ntls.cnf (100%) rename test/{ssl-tests => ntls-tests}/32-ntls-force-ntls.cnf.in (100%) rename test/{ssl-tests => ntls-tests}/39-ntls-sni-ticket.cnf (100%) rename test/{ssl-tests => ntls-tests}/39-ntls-sni-ticket.cnf.in (100%) rename test/{ssl-tests => ntls-tests}/40-ntls_client_auth.cnf (100%) rename test/{ssl-tests => ntls-tests}/40-ntls_client_auth.cnf.in (100%) rename test/{ssl-tests => ntls-tests}/41-ntls-alpn.cnf (100%) rename test/{ssl-tests => ntls-tests}/41-ntls-alpn.cnf.in (100%) create mode 100644 test/recipes/80-test_ntls.t create mode 100644 test/recipes/92-test_tsapi.t rename test/{smtc-and-base.cnf => smtc.cnf} (82%) create mode 100644 test/tsapi_test.c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c40b7209..83b044878 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -209,7 +209,7 @@ jobs: - name: modprobe tls run: sudo modprobe tls - name: config - run: ./config --banner=Configured --strict-warnings no-ec enable-ssl-trace enable-zlib enable-zlib-dynamic enable-crypto-mdebug enable-crypto-mdebug-backtrace enable-egd enable-ktls enable-fips enable-ntls enable-optimize-chacha-choose enable-status enable-crypto-mdebug-count enable-cert-compression enable-delegated-credential enable-bn-method --with-rand-seed=getrandom,rtc && perl configdata.pm --dump + run: ./config --banner=Configured --strict-warnings no-ec enable-ssl-trace enable-zlib enable-zlib-dynamic enable-crypto-mdebug enable-crypto-mdebug-backtrace enable-egd enable-ktls enable-fips enable-ntls enable-optimize-chacha-choose enable-status enable-crypto-mdebug-count enable-cert-compression enable-delegated-credential enable-bn-method --with-rand-seed=rtcode,rtmem,rtsock && perl configdata.pm --dump - name: make run: make -s -j4 - name: make test @@ -399,8 +399,11 @@ jobs: run: ./config enable-ntls enable-smtc enable-smtc-debug --strict-warnings && perl configdata.pm --dump - name: make run: make -s -j4 - - name: make test - run: make test + - name: make test selected cases + run: | + make test TESTS="test_abort test_sanity test_symbol_presence test_test test_errstr test_internal_context \ + test_internal_sm3 test_internal_sm4 test_smtc_rand_self_test test_mod_sm2 test_cli_smtc test_ntlssni \ + test_tsapi test_sign_sm2 test_ntls" - name: make clean run: make clean - name: check dirty diff --git a/.github/workflows/compiler-zoo.yml b/.github/workflows/compiler-zoo.yml index 59d37425e..c89fb0b27 100644 --- a/.github/workflows/compiler-zoo.yml +++ b/.github/workflows/compiler-zoo.yml @@ -76,8 +76,7 @@ jobs: - name: config run: | CC=${{ matrix.zoo.cc }} ./config --banner=Configured no-shared \ - -Wall -Werror enable-ntls enable-smtc enable-smtc-debug \ - --strict-warnings + -Wall -Werror enable-ntls --strict-warnings - name: config dump run: ./configdata.pm --dump diff --git a/.github/workflows/run-checker-ci.yml b/.github/workflows/run-checker-ci.yml index 71660df1e..b5f07a7b8 100644 --- a/.github/workflows/run-checker-ci.yml +++ b/.github/workflows/run-checker-ci.yml @@ -32,8 +32,6 @@ jobs: no-tls1_3, enable-trace enable-fips, enable-ntls, - enable-smtc enable-smtc-debug, - enable-ntls enable-smtc enable-smtc-debug, no-ts, no-ui, ] diff --git a/.github/workflows/run-checker-daily.yml b/.github/workflows/run-checker-daily.yml index 1a927a904..7888e6277 100644 --- a/.github/workflows/run-checker-daily.yml +++ b/.github/workflows/run-checker-daily.yml @@ -114,8 +114,6 @@ jobs: enable-zlib-dynamic, no-zlib-dynamic, enable-ntls, - enable-smtc enable-smtc-debug, - enable-ntls enable-smtc enable-smtc-debug, enable-ec_elgamal enable-twisted_ec_elgamal, enable-bulletproofs, enable-bulletproofs enable-nizk enable-zkp-gadget enable-ec_elgamal enable-twisted_ec_elgamal, diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml index c5e0c3853..977e9fa52 100644 --- a/.github/workflows/run-checker-merge.yml +++ b/.github/workflows/run-checker-merge.yml @@ -27,8 +27,6 @@ jobs: enable-weak-ssl-ciphers, enable-zlib, enable-ntls, - enable-smtc enable-smtc-debug, - enable-ntls enable-smtc enable-smtc-debug, ] runs-on: ubuntu-latest steps: diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf index 073867565..5111bbe50 100644 --- a/Configurations/00-base-templates.conf +++ b/Configurations/00-base-templates.conf @@ -50,6 +50,9 @@ my %targets=( my @defs = ( 'OPENSSL_BUILDING_OPENSSL' ); push @defs, "ZLIB" unless $disabled{zlib}; push @defs, "ZLIB_SHARED" unless $disabled{"zlib-dynamic"}; + + push @defs, "SDF_LIB" unless $disabled{"sdf-lib"}; + push @defs, "SDF_LIB_SHARED" unless $disabled{"sdf-lib-dynamic"}; return [ @defs ]; }, includes => @@ -57,6 +60,9 @@ my %targets=( my @incs = (); push @incs, $withargs{zlib_include} if !$disabled{zlib} && $withargs{zlib_include}; + + push @incs, $withargs{sdf_include} + if !$disabled{sdf_lib} && $withargs{sdf_include}; return [ @incs ]; }, }, diff --git a/Configure b/Configure index ce92fd517..ce7b5c1aa 100755 --- a/Configure +++ b/Configure @@ -271,9 +271,14 @@ $config{builddir} = abs2rel($blddir, $blddir); # echo -n 'holy hand grenade of antioch' | openssl sha256 $config{FIPSKEY} = 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813'; -# echo -n "Tongsuo in hand, no worries about compliance" | tongsuo sm3 -$config{SMTCKEY} = - '5b3d9ad84fd72961e63f27a3d5da2bb663e2ed9c7b761b8ad6d041ebc68f5098'; +$config{SMTCPASSWD} = 'Tongsuo123'; +$config{SMTCPUBKEY} = +'-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAERjiZ5ubxrnOZnjhvqvuJ5UcdRI64 +sBEVwF0UztQK9eYzqOsFEm0PKkCjoYkdmiZ+Und0agHk94eFKhtUYsu0bw== +-----END PUBLIC KEY-----'; +$config{SMTCPUBKEY} =~ s|\n|\\n|g; + # Collect reconfiguration information if needed my @argvcopy=@ARGV; @@ -355,8 +360,6 @@ $config{tongsuo_prerelease} = $config{tongsuo_version} = "$config{tongsuo_major}.$config{tongsuo_minor}.$config{tongsuo_patch}"; $config{tongsuo_full_version} = "$config{tongsuo_version}$config{tongsuo_prerelease}"; -$config{tongsuo_smtc_info} = $version{TONGSUO_SMTC_INFO}; - die "erroneous version information in VERSION.dat: ", "$config{version}, $config{shlib_version}\n" unless (defined $version{MAJOR} @@ -404,6 +407,7 @@ my @dtls = qw(dtls1 dtls1_2); my @disablables = ( "acvp-tests", "afalgeng", + "atf_slibce", "asan", "asm", "async", @@ -474,6 +478,8 @@ my @disablables = ( "smtc-debug", "scrypt", "sctp", + "sdf-lib", + "sdf-lib-dynamic", "secure-memory", "shared", "siphash", @@ -588,8 +594,11 @@ our %disabled = ( # "what" => "comment" "zkp-gadget" => "default", "zkp-transcript" => "default", "bn-method" => "default", - "smtc" => "default", - "smtc-debug" => "default", + "smtc" => "default", + "smtc-debug" => "default", + "atf_slibce" => "default", + "sdf-lib" => "default", + "sdf-lib-dynamic" => "default", ); # Note: => pair form used for aesthetics, not to truly make a hash table @@ -677,8 +686,8 @@ my @disable_cascades = ( "deprecated-3.0" => [ "engine", "srp" ], # SMTC does not support ct for now - # SMTC only support builtin module for now - sub { !$disabled{"smtc"}} => [ "ct", "module" ], + sub { !$disabled{"smtc"}} => [ "ct" ], + "sdf-lib" => [ "sdf-lib-dynamic" ], ); # Avoid protocol support holes. Also disable all versions below N, if version @@ -796,7 +805,7 @@ my %cmdvars = (); # Stores FOO='blah' type arguments my %unsupported_options = (); my %deprecated_options = (); # If you change this, update apps/version.c -my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom rtc); +my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom rtcode rtmem rtsock); my @seed_sources = (); while (@argvcopy) { @@ -914,6 +923,10 @@ while (@argvcopy) { delete $disabled{"zlib"}; } + elsif ($1 eq "sdf-lib-dynamic") + { + delete $disabled{"sdf-lib"}; + } my $algo = $1; delete $disabled{$algo}; @@ -1011,6 +1024,18 @@ while (@argvcopy) push @seed_sources, $x; } } + elsif (/^--with-atf_slibce-lib=(.*)$/) + { + $withargs{atf_slibce_lib}=$1; + } + elsif (/^--with-sdf-lib=(.*)$/) + { + $withargs{sdf_lib}=$1; + } + elsif (/^--with-sdf-include=(.*)$/) + { + $withargs{sdf_include}=$1; + } elsif (/^--fips-key=(.*)$/) { $user{FIPSKEY}=lc($1); @@ -1021,15 +1046,25 @@ while (@argvcopy) die "FIPS key too long (64 bytes max)\n" if length $1 > 64; } - elsif (/^--smtc-key=(.*)$/) + elsif (/^--smtc-pubkey=(.*)$/) { - $user{SMTCKEY}=lc($1); - die "Non-hex character in SMTC key\n" - if $user{SMTCKEY} =~ /[^a-f0-9]/; - die "SMTC key must have even number of characters\n" - if length $1 & 1; - die "SMTC key too long (64 bytes max)\n" - if length $1 > 64; + open my $fh, "<", $1 or die "Can't open $1: $!\n"; + $user{SMTCPUBKEY} = do { local $/; <$fh> }; + close $fh; + chomp $user{SMTCPUBKEY}; + $user{SMTCPUBKEY} =~ s|\n|\\n|g; + } + elsif (/^--smtc-passwd=(.*)$/) + { + $user{SMTCPASSWD} = $1; + die "Invalid character in SMTC password (A-Z, a-z, 0-9)\n" + if $user{SMTCPASSWD} =~ /[^A-Za-z0-9]/; + die "Invalid SMTC password length (8 ~ 64 bytes)\n" + if length $1 < 8 or length $1 > 64; + } + elsif (/^--smtc-info=(.*)$/) + { + $config{tongsuo_smtc_info} = $1; } elsif (/^--banner=(.*)$/) { diff --git a/VERSION.dat b/VERSION.dat index 3b6f7ac66..d83daf21b 100644 --- a/VERSION.dat +++ b/VERSION.dat @@ -8,5 +8,4 @@ SHLIB_VERSION=3 TONGSUO_MAJOR=8 TONGSUO_MINOR=5 TONGSUO_PATCH=0 -TONGSUO_PRE_RELEASE_TAG=dev -TONGSUO_SMTC_INFO= +TONGSUO_PRE_RELEASE_TAG=dev \ No newline at end of file diff --git a/apps/build.info b/apps/build.info index 56ac5a3a3..80f1868de 100644 --- a/apps/build.info +++ b/apps/build.info @@ -85,6 +85,10 @@ IF[{- !$disabled{apps} -}] DEFINE[openssl]=SMTC_MODULE ENDIF + IF[{- !$disabled{'sdf_lib'} -}] + $OPENSSLSRC=$OPENSSLSRC sdf.c + ENDIF + # The nocheck attribute is picked up by progs.pl as a signal not to look # at that file; some systems may have locked it as the output file, and # therefore don't allow it to be read at the same time, making progs.pl diff --git a/apps/enc.c b/apps/enc.c index a1ec6b723..5b7bc994a 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -534,6 +534,7 @@ int enc_main(int argc, char **argv) BIO_printf(bio_err, "iv undefined\n"); goto end; } + if (hkey != NULL) { if (!set_hex(hkey, key, EVP_CIPHER_get_key_length(cipher))) { BIO_printf(bio_err, "invalid hex key value\n"); diff --git a/apps/mod.c b/apps/mod.c index 65cf4220e..575667a45 100644 --- a/apps/mod.c +++ b/apps/mod.c @@ -6,35 +6,45 @@ * in the file LICENSE in the source distribution or at * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt */ -#include +#include "internal/deprecated.h" +#include +#include +#include #include "apps.h" #include "progs.h" #include #include #include +#include #include #include #include #include +#include #include #include "internal/smtc_names.h" #include "../providers/smtc/smtckey.h" -#define PASSWD_BUF_SIZE 1024 -#define BUFSIZE 4096 +#define BUFSIZE 4096 +#define SMTC_AUTH_PASSWD_MAX_LEN 64 +#define SMTC_AUTH_KEY_LEN 64 +#define SMTC_AUTH_SALT_LEN 64 typedef struct { const char *section; const char *module_path; + char *sig; + const char *kek; + const char *eng; + const char *syslog; + char *key; + char *salt; + const char *rand_poweron_test; #ifndef OPENSSL_NO_SMTC_DEBUG - int verify_pass; + const char *verify_sig; + const char *verify_pass; #endif - int show_selftest; - unsigned char admin_salt[SM3_DIGEST_LENGTH]; - unsigned char admin_pass[SM3_DIGEST_LENGTH]; - unsigned char module_mac[EVP_MAX_MD_SIZE]; - size_t module_mac_len; } SMTC_CONF; typedef enum OPTION_choice { @@ -42,82 +52,131 @@ typedef enum OPTION_choice { OPT_EOF = 0, OPT_HELP, OPT_TEST, + OPT_RESET, OPT_MODULE, OPT_PROV_NAME, - OPT_SECTION_NAME, + OPT_SIGFILE, + OPT_STATUS, + OPT_INSTALL, + OPT_KEK, + OPT_ENGINE, + OPT_PASS, OPT_OUT, - OPT_SHOW_SELFTEST, #ifndef OPENSSL_NO_SMTC_DEBUG - OPT_NO_PASS, + OPT_NO_VERIFY, + OPT_NO_AUTH, + OPT_NO_RAND_POWERON_TEST, #endif - OPT_R_ENUM } OPTION_CHOICE; const OPTIONS mod_options[] = { OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"install", OPT_INSTALL, '-', "Install module, generate config file"}, {"test", OPT_TEST, '-', "Self test"}, - {"module", OPT_MODULE, '<', "File name of the provider module"}, - {"provider_name", OPT_PROV_NAME, 's', "SMTC provider name"}, - {"section_name", - OPT_SECTION_NAME, - 's', - "SMTC Provider config section name (optional)"}, - {"show_selftest", OPT_SHOW_SELFTEST, '-', "Show self test"}, + {"status", OPT_STATUS, '-', "Display the status of the module"}, + {"reset", OPT_RESET, '-', "Reset module, clear salt and password"}, + {"module", OPT_MODULE, 's', "File path of the module"}, + {"provider_name", OPT_PROV_NAME, 's', "Provider name"}, + {"pass", OPT_PASS, '-', "Setup password"}, + {"kek", OPT_KEK, 's', "The key for encrypting HMAC key"}, + {"engine", OPT_ENGINE, 's', "Use the engine e, possibly a hardware device"}, #ifndef OPENSSL_NO_SMTC_DEBUG - {"no_pass", OPT_NO_PASS, '-', "Do not setup password"}, + {"no_verify", OPT_NO_VERIFY, '-', "Do not verify the integrity of the software"}, + {"no_auth", OPT_NO_AUTH, '-', "No authentication required for user login"}, + {"no_rand_poweron_test", OPT_NO_RAND_POWERON_TEST, '-', "No random poweron test"}, #endif + + OPT_SECTION("Input"), + {"sigfile", OPT_SIGFILE, '<', "Signature file"}, + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output config file, used when generating"}, - {NULL}}; -static int setup_password(unsigned char *admin_salt, unsigned char *admin_pass) +static int check_passwd(const char *passwd, size_t len) { - int ret = 0; - char passwd[PASSWD_BUF_SIZE]; - EVP_MD_CTX *mctx = NULL; + size_t i; + int upper = 0, lower = 0, digit = 0; - if (EVP_read_pw_string(passwd, sizeof(passwd), "Setup password: ", 1) != 0) - goto end; + if (len < 8 || len > 64) + return 0; - if (RAND_bytes(admin_salt, SM3_DIGEST_LENGTH) <= 0) - goto end; + for (i = 0; i < len; i++) { + if (isupper(passwd[i])) + upper = 1; + else if (islower(passwd[i])) + lower = 1; + else if (isdigit(passwd[i])) + digit = 1; + else + return 0; + } - if ((mctx = EVP_MD_CTX_new()) == NULL - || !EVP_DigestInit_ex(mctx, EVP_sm3(), NULL) - || !EVP_DigestUpdate(mctx, admin_salt, SM3_DIGEST_LENGTH) - || !EVP_DigestUpdate(mctx, passwd, strlen(passwd)) - || !EVP_DigestFinal_ex(mctx, admin_pass, NULL)) - goto end; + if ((upper & lower & digit) == 0) + return 0; - ret = 1; -end: - EVP_MD_CTX_free(mctx); - return ret; + return 1; } -static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in, - unsigned char *out, size_t *out_len) + +static int setup_password(EVP_PKEY *kek, unsigned char *auth_salt, + unsigned char **auth_key, size_t *auth_key_len) { - int ret = 0; - int i; - size_t outsz = *out_len; + int ok = 0; + EVP_PKEY_CTX *ctx = NULL; + char passwd[SMTC_AUTH_PASSWD_MAX_LEN + 1] = {0}; + unsigned char key[SMTC_AUTH_KEY_LEN]; + unsigned char *enc_key = NULL; + size_t outlen; + + if (EVP_read_pw_string_min(passwd, 8, sizeof(passwd) - 1, + "Setup password: ", 1) != 0) + goto end; + + if (!check_passwd(passwd, strlen(passwd))) { + BIO_printf(bio_err, "Passwords should be 8-64 characters in length and" + "must contain number, uppercase and lowercase letter\n"); + goto end; + } - if (!EVP_MAC_init(ctx, NULL, 0, NULL)) - goto err; - if (EVP_MAC_CTX_get_mac_size(ctx) > outsz) + if (RAND_bytes(auth_salt, SMTC_AUTH_SALT_LEN) != 1) goto end; - while ((i = BIO_read(in, (char *)tmp, BUFSIZE)) != 0) { - if (i < 0 || !EVP_MAC_update(ctx, tmp, i)) - goto err; + + if (PKCS5_PBKDF2_HMAC(passwd, strlen(passwd), auth_salt, SMTC_AUTH_SALT_LEN, + 10000, EVP_sm3(), SMTC_AUTH_KEY_LEN, key) != 1) + goto end; + + if (kek) { + ctx = EVP_PKEY_CTX_new(kek, NULL); + if (ctx == NULL) + goto end; + + if (EVP_PKEY_encrypt_init(ctx) != 1) + goto end; + + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, key, SMTC_AUTH_KEY_LEN) != 1) + goto end; + + enc_key = OPENSSL_malloc(outlen); + + if (EVP_PKEY_encrypt(ctx, enc_key, &outlen, key, SMTC_AUTH_KEY_LEN) != 1 + ) { + BIO_printf(bio_err, "Failed to encrypt auth key\n"); + goto end; + } + + *auth_key = enc_key; + enc_key = NULL; + *auth_key_len = outlen; } + + ok = 1; + OSSL_syslog(LOG_NOTICE, "Setup password success\n"); end: - if (!EVP_MAC_final(ctx, out, out_len, outsz)) - goto err; - ret = 1; -err: - return ret; + EVP_PKEY_CTX_free(ctx); + OPENSSL_free(enc_key); + return ok; } static int write_config_header(BIO *out, const char *prov_name, @@ -130,20 +189,6 @@ static int write_config_header(BIO *out, const char *prov_name, && BIO_printf(out, "%s = %s\n\n", prov_name, section); } -static int print_hex(BIO *bio, const char *label, const unsigned char *val, - size_t len) -{ - int ret; - char *hexstr = NULL; - - hexstr = OPENSSL_buf2hexstr(val, (long)len); - if (hexstr == NULL) - return 0; - ret = BIO_printf(bio, "%s = %s\n", label, hexstr); - OPENSSL_free(hexstr); - return ret; -} - /* * Outputs a smtc related config file. * Returns 1 if the config file is written otherwise it returns 0 on error. @@ -156,34 +201,46 @@ static int write_config_smtc_section(BIO *out, SMTC_CONF *sc) || BIO_printf(out, "activate = 1\n") <= 0 || BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_MODULE_PATH, sc->module_path) <= 0 - || !print_hex(out, OSSL_PROV_SMTC_PARAM_MODULE_MAC, sc->module_mac, - sc->module_mac_len)) + || BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_MODULE_SIG, + sc->sig) <= 0) goto end; - if (sc->show_selftest) { - if (BIO_printf(out, "%s = 1\n", OSSL_PROV_SMTC_PARAM_SHOW_SELFTEST) - <= 0) - goto end; - } else { - if (BIO_printf(out, "%s = 0\n", OSSL_PROV_SMTC_PARAM_SHOW_SELFTEST) - <= 0) - goto end; - } + if (sc->kek && BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_AUTH_KEK, + sc->kek) <= 0) + goto end; -#ifndef OPENSSL_NO_SMTC_DEBUG - if (sc->verify_pass == 0) { - if (BIO_printf(out, "%s = 0\n", OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_PASS) - <= 0) - goto end; - } else { -#endif - if (!print_hex(out, OSSL_PROV_SMTC_PARAM_ADMIN_SALT, sc->admin_salt, - sizeof(sc->admin_salt)) - || !print_hex(out, OSSL_PROV_SMTC_PARAM_ADMIN_PASS, - sc->admin_pass, sizeof(sc->admin_pass))) + if (sc->eng && BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_ENGINE, + sc->eng) <= 0) + goto end; + + if (sc->key && BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_AUTH_KEY, + sc->key) <= 0) + goto end; + + if (sc->salt && BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_AUTH_SALT, + sc->salt) <= 0) + goto end; + + if (sc->syslog && BIO_printf(out, "%s = %s\n", OSSL_PROV_SMTC_PARAM_SYSLOG, + sc->syslog) <= 0) + goto end; + + if (sc->rand_poweron_test + && BIO_printf(out, "%s = %s\n", + OSSL_PROV_SMTC_PARAM_RANDOMNESS_POWERON_TEST, + sc->rand_poweron_test) <= 0) goto end; + #ifndef OPENSSL_NO_SMTC_DEBUG - } + if (sc->verify_sig && BIO_printf(out, "%s = %s\n", + OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_SIG, + sc->verify_sig) <= 0) + goto end; + + if (sc->verify_pass && BIO_printf(out, "%s = %s\n", + OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_PASS, + sc->verify_pass) <= 0) + goto end; #endif ret = 1; @@ -219,39 +276,45 @@ static CONF *generate_config_and_load(const char *prov_name, SMTC_CONF *sc) int mod_main(int argc, char **argv) { - int ret = 1; -#ifndef OPENSSL_NO_SMTC_DEBUG - int no_pass = 0; -#endif + int ret = 1, ok = 0, reset = 0, i, install = 0, pass = 0; char *prog; + unsigned char *sig = NULL, *auth_key = NULL; + int siglen = 0; + const char *sigfile = NULL, *kek_file = NULL; OPTION_CHOICE o; - int self_test = 0; - BIO *module_bio = NULL, *fout = NULL; - char *out_fname = NULL; - EVP_MAC *mac = NULL; - const char *mac_name = "HMAC"; - const char *prov_name = "smtc"; - SMTC_CONF sc = { - .section = "smtc_sect", - .show_selftest = 0, -#ifndef OPENSSL_NO_SMTC_DEBUG - .verify_pass = 1, + unsigned char buf[BUFSIZE]; + int self_test = 0, get_status = 0, status = 0; + BIO *module_bio = NULL, *fout = NULL, *kek_bio = NULL; +#ifndef OPENSSL_NO_ATF_SLIBCE + const char *eng_name = "atf_slibce"; +#else + const char *eng_name = NULL; #endif - }; - STACK_OF(OPENSSL_STRING) *opts = NULL; - unsigned char *read_buffer = NULL; - EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL; + const char *prov_name = "smtc", *sec_name = "smtc_sect"; + const char *conf_file = OPENSSL_info(OPENSSL_INFO_SMTC_MODULE_CONF); + const char *auth_kek = OPENSSL_info(OPENSSL_INFO_SMTC_AUTH_KEK); + SMTC_CONF sc; CONF *conf = NULL; + long eline; + EVP_PKEY *kek = NULL; + ENGINE *engine = NULL; + unsigned char auth_salt[SMTC_AUTH_SALT_LEN]; + size_t auth_key_len; + OSSL_PROVIDER *prov = NULL; +#ifndef OPENSSL_NO_SMTC_DEBUG + int no_verify = 0, no_auth = 0, no_rand_poweron_test = 0; +#endif - if ((opts = sk_OPENSSL_STRING_new_null()) == NULL) - goto end; + memset(&sc, 0, sizeof(sc)); + sc.section = sec_name; + sc.syslog = "1"; prog = opt_init(argc, argv, mod_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: - opthelp: +opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto cleanup; case OPT_HELP: @@ -261,155 +324,275 @@ int mod_main(int argc, char **argv) case OPT_TEST: self_test = 1; break; + case OPT_STATUS: + get_status = 1; + break; + case OPT_RESET: + reset = 1; + break; case OPT_PROV_NAME: prov_name = opt_arg(); break; case OPT_MODULE: sc.module_path = opt_arg(); break; - case OPT_SECTION_NAME: - sc.section = opt_arg(); + case OPT_PASS: + pass = 1; break; - case OPT_SHOW_SELFTEST: - sc.show_selftest = 1; + case OPT_SIGFILE: + sigfile = opt_arg(); break; -#ifndef OPENSSL_NO_SMTC_DEBUG - case OPT_NO_PASS: - no_pass = 1; - sc.verify_pass = 0; + case OPT_INSTALL: + install = 1; break; -#endif case OPT_OUT: - out_fname = opt_arg(); + conf_file = opt_arg(); break; - case OPT_R_CASES: - if (!opt_rand(o)) - goto end; + case OPT_KEK: + kek_file = opt_arg(); + break; + case OPT_ENGINE: + eng_name = opt_arg(); + engine = setup_engine(eng_name, 1); + break; +#ifndef OPENSSL_NO_SMTC_DEBUG + case OPT_NO_VERIFY: + no_verify = 1; break; + case OPT_NO_AUTH: + no_auth = 1; + break; + case OPT_NO_RAND_POWERON_TEST: + no_rand_poweron_test = 1; + break; +#endif } } + argc = opt_num_rest(); - argv = opt_rest(); + if (argc != 0) + goto opthelp; - if (self_test) { - if (OSSL_PROVIDER_available(app_get0_libctx(), "smtc")) { - OSSL_PROVIDER *prov = OSSL_PROVIDER_load(app_get0_libctx(), "smtc"); - if (prov == NULL) { - BIO_printf(bio_err, "Failed to load SMTC provider\n"); + if (reset || self_test || get_status) { + prov = OSSL_PROVIDER_load(app_get0_libctx(), "smtc"); + if (prov == NULL) { + BIO_printf(bio_err, "Failed to load SMTC provider\n"); + goto end; + } + + if (reset) { + if (OSSL_PROVIDER_reset(prov) != 1) { + BIO_printf(bio_err, "Failed to reset SMTC provider\n"); goto end; } + } + if (self_test) { if (OSSL_PROVIDER_self_test(prov) != 1) { - OSSL_PROVIDER_unload(prov); - BIO_printf(bio_err, "SMTC provider self test failed\n"); + BIO_printf(bio_err, "self test failed\n"); goto end; } - OSSL_PROVIDER_unload(prov); + BIO_printf(bio_out, "self test success\n"); + } + + if (get_status) { + status = OSSL_PROVIDER_status(prov); - ret = 0; - goto end; - } else { - BIO_printf(bio_err, "SMTC provider not available\n"); - goto end; + BIO_printf(bio_out, "status: %sactive\n", status ? "" : "in"); } + + ok = 1; + goto end; } + if (install) { + if (sigfile) { + BIO *sigbio = BIO_new_file(sigfile, "rb"); + + if (sigbio == NULL) { + BIO_printf(bio_err, "Can't open signature file %s\n", sigfile); + goto end; + } + siglen = bio_to_mem(&sig, 4096, sigbio); + BIO_free(sigbio); + + if (siglen < 0) { + BIO_printf(bio_err, "Error reading signature data\n"); + goto end; + } + + sc.sig = OPENSSL_buf2hexstr(sig, siglen); + if (sc.sig == NULL) + goto end; + } + #ifndef OPENSSL_NO_SMTC_DEBUG - if (!no_pass) + if (no_verify) + sc.verify_sig = "0"; + + if (no_auth) + sc.verify_pass = "0"; + + if (no_rand_poweron_test) + sc.rand_poweron_test = "0"; #endif - if (!setup_password(sc.admin_salt, sc.admin_pass)) - goto end; + sc.eng = eng_name; - if (sc.module_path == NULL) - goto opthelp; + if (sc.module_path == NULL) + goto opthelp; - if (!sk_OPENSSL_STRING_push(opts, "digest:SM3")) - goto end; - if (!sk_OPENSSL_STRING_push(opts, "hexkey:" SMTC_KEY_STRING)) - goto end; + if (kek_file) { + kek_bio = bio_open_default(kek_file, 'r', FORMAT_TEXT); + if (kek_bio == NULL) { + BIO_printf(bio_err, "Failed to open file %s\n", kek_file); + goto end; + } - module_bio = bio_open_default(sc.module_path, 'r', FORMAT_BINARY); - if (module_bio == NULL) { - BIO_printf(bio_err, "Failed to open module file\n"); - goto end; - } + fout = bio_open_default(auth_kek, 'w', FORMAT_TEXT); + if (fout == NULL) { + BIO_printf(bio_err, "Failed to open file %s\n", auth_kek); + goto end; + } - read_buffer = app_malloc(BUFSIZE, "I/O buffer"); - if (read_buffer == NULL) - goto end; + while (BIO_pending(kek_bio) || !BIO_eof(kek_bio)) { + ret = BIO_read(kek_bio, buf, BUFSIZE); + + if (ret < 0) { + BIO_printf(bio_err, "Read Error in '%s'\n", kek_file); + ERR_print_errors(bio_err); + goto end; + } + if (ret == 0) + break; + + if (BIO_write(fout, buf, ret) != ret) { + BIO_printf(bio_err, "Write Error in '%s'\n", auth_kek); + ERR_print_errors(bio_err); + goto end; + } + } - mac = EVP_MAC_fetch(app_get0_libctx(), mac_name, app_get0_propq()); - if (mac == NULL) { - BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name); - goto end; - } + sc.kek = auth_kek; + } + + conf = generate_config_and_load(prov_name, &sc); + if (conf == NULL) + goto end; + + fout = bio_open_default(conf_file, 'w', FORMAT_TEXT); + if (fout == NULL) { + BIO_printf(bio_err, "Failed to open file\n"); + goto end; + } + if (!write_config_smtc_section(fout, &sc)) + goto end; + + BIO_printf(bio_err, "INSTALL PASSED\n"); - ctx = EVP_MAC_CTX_new(mac); - if (ctx == NULL) { - BIO_printf(bio_err, "Unable to create MAC CTX for module check\n"); + ok = 1; goto end; } - if (opts != NULL) { - int ok = 1; - OSSL_PARAM *params - = app_params_new_from_opts(opts, EVP_MAC_settable_ctx_params(mac)); + if (pass) { + conf = NCONF_new(NCONF_default()); - if (params == NULL) + if (NCONF_load(conf, conf_file, &eline) != 1) { + BIO_printf(bio_err, "Failed to load config file %s\n", conf_file); goto end; + } + + STACK_OF(CONF_VALUE) *sect = NCONF_get_section(conf, sec_name); + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + CONF_VALUE *cv = sk_CONF_VALUE_value(sect, i); + + if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_MODULE_PATH) == 0) + sc.module_path = cv->value; + else if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_MODULE_SIG) == 0) + sc.sig = cv->value; + else if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_AUTH_KEK) == 0) + sc.kek = cv->value; + else if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_ENGINE) == 0) + sc.eng = cv->value; + else if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_SYSLOG) == 0) + sc.syslog = cv->value; + else if (strcmp(cv->name, + OSSL_PROV_SMTC_PARAM_RANDOMNESS_POWERON_TEST) == 0) + sc.rand_poweron_test = cv->value; + } - if (!EVP_MAC_CTX_set_params(ctx, params)) { - BIO_printf(bio_err, "MAC parameter error\n"); - ERR_print_errors(bio_err); - ok = 0; + if (sc.eng) { + engine = ENGINE_by_id(sc.eng); + if (engine == NULL) { + BIO_printf(bio_err, "Failed to load engine %s\n", sc.eng); + goto end; + } } - app_params_free(params); - if (!ok) + + kek = load_key(sc.kek, FORMAT_PEM, 0, NULL, engine, + "key encryption key"); + if (kek == NULL) goto end; - } - ctx2 = EVP_MAC_CTX_dup(ctx); - if (ctx2 == NULL) { - BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n"); - goto end; - } + if (!setup_password(kek, auth_salt, &auth_key, &auth_key_len)) { + BIO_printf(bio_err, "Failed to setup password!\n"); + goto end; + } - sc.module_mac_len = sizeof(sc.module_mac); - if (!do_mac(ctx, read_buffer, module_bio, sc.module_mac, &sc.module_mac_len)) - goto end; + sc.key = OPENSSL_buf2hexstr(auth_key, auth_key_len); + if (sc.key == NULL) + goto end; - conf = generate_config_and_load(prov_name, &sc); - if (conf == NULL) - goto end; + sc.salt = OPENSSL_buf2hexstr(auth_salt, sizeof(auth_salt)); + if (sc.salt == NULL) + goto end; - fout = out_fname == NULL ? dup_bio_out(FORMAT_TEXT) - : bio_open_default(out_fname, 'w', FORMAT_TEXT); - if (fout == NULL) { - BIO_printf(bio_err, "Failed to open file\n"); - goto end; - } - if (!write_config_smtc_section(fout, &sc)) - goto end; + fout = bio_open_default(conf_file, 'w', FORMAT_TEXT); + if (fout == NULL) { + BIO_printf(bio_err, "Failed to open file %s\n", conf_file); + goto end; + } - BIO_printf(bio_err, "INSTALL PASSED\n"); + if (!write_config_smtc_section(fout, &sc)) { + BIO_printf(bio_err, "Failed to write config file %s\n", conf_file); + goto end; + } + } - ret = 0; + ok = 1; end: - if (ret == 1) + if (ok == 0) { ERR_print_errors(bio_err); + ret = 1; + } else { + /* Exit the process after reset module */ + if (reset) + ret = -1; + else + ret = 0; + } cleanup: + if (install) + OPENSSL_free(sc.sig); + + if (prov) + OSSL_PROVIDER_unload(prov); + + release_engine(engine); + EVP_PKEY_free(kek); + OPENSSL_free(auth_key); + OPENSSL_free(sig); + OPENSSL_free(sc.key); + OPENSSL_free(sc.salt); BIO_free(fout); BIO_free(module_bio); - sk_OPENSSL_STRING_free(opts); - EVP_MAC_free(mac); - EVP_MAC_CTX_free(ctx2); - EVP_MAC_CTX_free(ctx); - OPENSSL_free(read_buffer); + BIO_free(kek_bio); + if (conf != NULL) { NCONF_free(conf); CONF_modules_unload(1); } + return ret; } diff --git a/apps/openssl.c b/apps/openssl.c index e23515772..293a698f0 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -28,6 +28,9 @@ #include "apps.h" #include "progs.h" +/* Special sentinel to exit the program. */ +#define EXIT_THE_PROGRAM (-1) + /* * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with * the base prototypes (we cast each variable inside the function to the @@ -236,11 +239,12 @@ int main(int argc, char *argv[]) { FUNCTION f, *fp; LHASH_OF(FUNCTION) *prog = NULL; - char *pname; - const char *fname; + char *p, *pname; + char buf[1024]; + const char *prompt, *fname; ARGS arg; int global_help = 0; - int ret = 0; + int first, n, i, ret = 0; arg.argv = NULL; arg.size = 0; @@ -289,11 +293,81 @@ int main(int argc, char *argv[]) argv[0] = pname; } - /* If there's a command, run with that, otherwise "help". */ - ret = argc == 0 || global_help - ? do_cmd(prog, 1, help_argv) - : do_cmd(prog, argc, argv); + if (global_help) { + ret = do_cmd(prog, 1, help_argv); + goto end; + } + + if (argc != 0) { + ret = do_cmd(prog, argc, argv); + goto end; + } + + /* interactive mode */ + for (;;) { + ret = 0; + /* Read a line, continue reading if line ends with \ */ + for (p = buf, n = sizeof(buf), i = 0, first = 1; n > 0; first = 0) { + prompt = first ? "Tongsuo> " : "> "; + p[0] = '\0'; +#ifndef READLINE + fputs(prompt, stdout); + fflush(stdout); + if (!fgets(p, n, stdin)) + goto end; + if (p[0] == '\0') + goto end; + i = strlen(p); + if (i <= 1) + break; + if (p[i - 2] != '\\') + break; + i -= 2; + p += i; + n -= i; +#else + { + extern char *readline(const char *); + extern void add_history(const char *cp); + char *text; + + text = readline(prompt); + if (text == NULL) + goto end; + i = strlen(text); + if (i == 0 || i > n) + break; + if (text[i - 1] != '\\') { + p += strlen(strcpy(p, text)); + free(text); + add_history(buf); + break; + } + + text[i - 1] = '\0'; + p += strlen(strcpy(p, text)); + free(text); + n -= i; + } +#endif + } + if (!chopup_args(&arg, buf)) { + BIO_printf(bio_err, "Can't parse (no memory?)\n"); + break; + } + + ret = do_cmd(prog, arg.argc, arg.argv); + if (ret == EXIT_THE_PROGRAM) { + ret = 0; + goto end; + } + if (ret != 0) + BIO_printf(bio_err, "error in %s\n", arg.argv[0]); + (void)BIO_flush(bio_out); + (void)BIO_flush(bio_err); + } + ret = 1; end: OPENSSL_free(default_config_file); lh_FUNCTION_free(prog); @@ -396,28 +470,6 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) if (argc <= 0 || argv[0] == NULL) return 0; -#ifdef SMTC_MODULE - /* Every app should run smtc self test firstly except mod, version and help */ - if (strcmp(argv[0], "mod") != 0 - && strcmp(argv[0], "version") != 0 - && strcmp(argv[0], "help") != 0) { - if (OSSL_PROVIDER_available(app_get0_libctx(), "smtc")) { - OSSL_PROVIDER *prov = OSSL_PROVIDER_load(app_get0_libctx(), "smtc"); - if (prov == NULL) { - BIO_printf(bio_err, "Failed to load smtc provider\n"); - return 0; - } - - if (OSSL_PROVIDER_self_test(prov) != 1) { - OSSL_PROVIDER_unload(prov); - BIO_printf(bio_err, "smtc self test failed\n"); - return 0; - } - - OSSL_PROVIDER_unload(prov); - } - } -#endif memset(&f, 0, sizeof(f)); f.name = argv[0]; fp = lh_FUNCTION_retrieve(prog, &f); @@ -451,6 +503,11 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) return 1; } + if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || + strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) + /* Special value to mean "exit the program. */ + return EXIT_THE_PROGRAM; + BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", argv[0]); return 1; diff --git a/apps/rand.c b/apps/rand.c index cbf495d5b..47be38976 100644 --- a/apps/rand.c +++ b/apps/rand.c @@ -17,10 +17,12 @@ #include #include #include +#include +#include "crypto/rand.h" typedef enum OPTION_choice { OPT_COMMON, - OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX, + OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX, OPT_ENTROPY, OPT_SOURCE, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -37,6 +39,8 @@ const OPTIONS rand_options[] = { {"out", OPT_OUT, '>', "Output file"}, {"base64", OPT_BASE64, '-', "Base64 encode output"}, {"hex", OPT_HEX, '-', "Hex encode output"}, + {"entropy", OPT_ENTROPY, '-', "Output entropy instead of random data"}, + {"source", OPT_SOURCE, 's', "Specify the entropy source"}, OPT_R_OPTIONS, OPT_PROV_OPTIONS, @@ -46,13 +50,48 @@ const OPTIONS rand_options[] = { {NULL} }; +static int opt_rand_source(const char *name) +{ + int ret = 0; + + if (strcmp(name, "getrandom") == 0) + ret = RAND_ENTROPY_SOURCE_GETRANDOM; + else if (strcmp(name, "devrandom") == 0) + ret = RAND_ENTROPY_SOURCE_DEVRANDOM; + else if (strcmp(name, "rdtsc") == 0) + ret = RAND_ENTROPY_SOURCE_RDTSC; + else if (strcmp(name, "rdcpu") == 0) + ret = RAND_ENTROPY_SOURCE_RDCPU; + else if (strcmp(name, "egd") == 0) + ret = RAND_ENTROPY_SOURCE_EGD; + else if (strcmp(name, "bcryptgenrandom") == 0) + ret = RAND_ENTROPY_SOURCE_BCRYPTGENRANDOM; + else if (strcmp(name, "cryptgenrandom_def_prov") == 0) + ret = RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_DEF_PROV; + else if (strcmp(name, "cryptgenrandom_intel_prov") == 0) + ret = RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_INTEL_PROV; + else if (strcmp(name, "rtcode") == 0) + ret = RAND_ENTROPY_SOURCE_RTCODE; + else if (strcmp(name, "rtmem") == 0) + ret = RAND_ENTROPY_SOURCE_RTMEM; + else if (strcmp(name, "rtsock") == 0) + ret = RAND_ENTROPY_SOURCE_RTSOCK; + else + BIO_printf(bio_err, "Unknown entropy source '%s'\n", name); + + return ret; +} + int rand_main(int argc, char **argv) { ENGINE *e = NULL; BIO *out = NULL; + int source = 0; char *outfile = NULL, *prog; OPTION_CHOICE o; - int format = FORMAT_BINARY, i, num = -1, r, ret = 1; + unsigned char *ent_buf = NULL, *p; + int format = FORMAT_BINARY, i, num = -1, r, ret = 1, entropy = 0; + size_t ent_len = 0; prog = opt_init(argc, argv, rand_options); while ((o = opt_next()) != OPT_EOF) { @@ -82,6 +121,13 @@ int rand_main(int argc, char **argv) case OPT_HEX: format = FORMAT_TEXT; break; + case OPT_ENTROPY: + entropy = 1; + break; + case OPT_SOURCE: + source |= opt_rand_source(opt_arg()); + RAND_set_entropy_source(source); + break; case OPT_PROV_CASES: if (!opt_provider(o)) goto end; @@ -114,24 +160,45 @@ int rand_main(int argc, char **argv) } while (num > 0) { - unsigned char buf[4096]; + /* When getting entropy from EGD, buf size must be less than 256 */ + unsigned char buf[255]; int chunk; chunk = num; if (chunk > (int)sizeof(buf)) chunk = sizeof(buf); - r = RAND_bytes(buf, chunk); - if (r <= 0) - goto end; + + if (entropy) { + ent_buf = TSAPI_GetEntropy(chunk, &ent_len); + if (ent_buf == NULL) + goto end; + } else { + r = RAND_bytes(buf, chunk); + if (r <= 0) + goto end; + } + + if (entropy) { + p = ent_buf; + chunk = ent_len; + } else { + p = buf; + } + if (format != FORMAT_TEXT) { - if (BIO_write(out, buf, chunk) != chunk) + if (BIO_write(out, p, chunk) != chunk) goto end; } else { for (i = 0; i < chunk; i++) - if (BIO_printf(out, "%02x", buf[i]) != 2) + if (BIO_printf(out, "%02x", p[i]) != 2) goto end; } num -= chunk; + + if (entropy) { + TSAPI_FreeEntropy(ent_buf, ent_len); + ent_buf = NULL; + } } if (format == FORMAT_TEXT) BIO_puts(out, "\n"); @@ -145,5 +212,6 @@ int rand_main(int argc, char **argv) ERR_print_errors(bio_err); release_engine(e); BIO_free_all(out); + TSAPI_FreeEntropy(ent_buf, ent_len); return ret; } diff --git a/apps/s_server.c b/apps/s_server.c index 088e403ab..e6243ed9d 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1898,8 +1898,6 @@ int s_server_main(int argc, char *argv[]) if (s_key_file == NULL) s_key_file = s_cert_file; - - if (!load_excert(&exc)) goto end; diff --git a/apps/sdf.c b/apps/sdf.c new file mode 100644 index 000000000..357d68ce4 --- /dev/null +++ b/apps/sdf.c @@ -0,0 +1,516 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ +#include "internal/deprecated.h" +#include +#include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" + +typedef enum OPTION_choice { + OPT_ERR = -1, + OPT_EOF = 0, + OPT_HELP, + OPT_IN, + OPT_INKEY, + OPT_INDEX, + OPT_GENSM2KEY, + OPT_DELSM2KEY, + OPT_UPDATESM2KEY, + OPT_EXPORTSM2PUBKEY, + OPT_EXPORTSM2KEY, + OPT_EXPORTSM2KEYWITHEVLP, + OPT_IMPORTSM2KEY, + OPT_IMPORTSM2KEYWITHEVLP, + OPT_LOGIN, + OPT_ENCRYPT, + OPT_DECRYPT, + OPT_PEERKEY, + OPT_TYPE, + OPT_OUT, + OPT_KEYOUT, + OPT_DEKOUT, + OPT_INDEK, + OPT_IV, + OPT_ISK, + OPT_ISKTYPE, + OPT_ALGORITHM, +} OPTION_CHOICE; + +/* + * Examples: + * + * Encrypt data with SM4 key which is encrypted with ISK: + * sdf -encrypt -algorithm sm4-cbc -inkey sm4key.enc -isk index -isktype sm2 -iv aabbcc -in data.txt -out data.enc + * + * Generate SM2 key pair with the index: + * sdf -gensm2key -index 1 + * + * Delete SM2 key pair with the index: + * sdf -delsm2key -index 1 + * + * Update SM2 key pair with the index: + * sdf -updatesm2key -index 1 + * + * Encrypt data with SM2 key with the index: + * sdf -encrypt -algorithm sm2 -index 1 -in data.txt -out data.enc + * + * Import SM2 key with the index, sm2 key is encrypted by sm4 key(indek), + * sm4 key is encrypted by ISK, default is 0: + * sdf -importsm2keywithevlp -type enc -index 7 -inkey sm2_enc.keyenc -indek sm4.keyenc + * + * Export SM2 key with the index: + * sdf -exportsm2key -index 1 -keyout sm2key.pem + * + * Export SM2 public key with the index: + * sdf -exportsm2pubkey -index 1 -keyout sm2pubkey.pem + */ + +const OPTIONS sdf_options[] = { + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt file"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt file"}, + {"importsm2key", OPT_IMPORTSM2KEY, '-', "Import SM2 key with the index"}, + {"importsm2keywithevlp", OPT_IMPORTSM2KEYWITHEVLP, '-', "Import SM2 key with digital envelope"}, + {"gensm2key", OPT_GENSM2KEY, '-', "Generate SM2 key pair with the index"}, + {"delsm2key", OPT_DELSM2KEY, '-', "Delete SM2 key pair with the index"}, + {"updatesm2key", OPT_UPDATESM2KEY, '-', "Update SM2 key pair with the index"}, + {"exportsm2key", OPT_EXPORTSM2KEY, '-', "Export SM2 key with the index"}, + {"exportsm2pubkey", OPT_EXPORTSM2PUBKEY, '-', "Export SM2 public key with the index"}, + {"exportsm2keywithevlp", OPT_EXPORTSM2KEYWITHEVLP, '-', "Export SM2 key with digital envelope"}, + {"login", OPT_LOGIN, 's', "Login with username:password"}, + + OPT_SECTION("Input"), + {"inkey", OPT_INKEY, 's', "Input key file"}, + {"index", OPT_INDEX, 's', "Specify the index of key"}, + {"peerkey", OPT_PEERKEY, 's', "Peer public key file used in exporting SM2 key with digital envelope"}, + {"type", OPT_TYPE, 's', "sign: signature key, enc: encryption key"}, + {"indek", OPT_INDEK, '>', "Input digital envelope key"}, + {"isk", OPT_ISK, 's', "Index of ISK key"}, + {"isktype", OPT_ISKTYPE, 's', "ISK type, sm2: SM2 key, rsa: RSA key"}, + {"iv", OPT_IV, 's', "IV in hex format"}, + {"algorithm", OPT_ALGORITHM, 's', "Algorithm to use"}, + {"in", OPT_IN, '>', "Input file"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"keyout", OPT_KEYOUT, '>', "Output key file"}, + {"dekout", OPT_DEKOUT, '>', "Output digital envelope key"}, + + {NULL} +}; + +int sdf_main(int argc, char **argv) +{ + char *prog; + OPTION_CHOICE o; + BIO *outkey = NULL, *outdek = NULL, *key_bio = NULL; + BIO *in = NULL, *out = NULL; + int ret = 1, index = -1, sign = 1, keylen = 0, deklen = 0, mode = 0; + int isk = -1; + int gensm2 = 0, delsm2 = 0, updatesm2 = 0; + int exportsm2pubkey = 0, exportsm2keywithevlp = 0, importsm2keywithevlp = 0; + int exportsm2key = 0, importsm2key = 0, encrypt = 0, decrypt = 0; + unsigned char *inkey = NULL, *indek = NULL, *inbuf = NULL, *outbuf = NULL; + char *p = NULL; + char *login = NULL; + char *outkeyfile = NULL, *peerkey_file = NULL, *indekfile = NULL; + char *outdekfile = NULL, *inkeyfile = NULL; + char *infile = NULL, *outfile = NULL; + const char *user = "admin", *password = "123123", *hexiv = NULL, *algo = NULL; + const char *isktype = "sm2"; + unsigned char *iv = NULL; + EVP_PKEY *pkey = NULL, *peer = NULL; + unsigned char *priv = NULL, *pub = NULL, *outevlp = NULL; + size_t privlen = 0, publen = 0, outevlplen = 0; + int inbuflen = -1; + size_t outbuflen = 0; + + prog = opt_init(argc, argv, sdf_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(sdf_options); + ret = 0; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_INKEY: + inkeyfile = opt_arg(); + break; + case OPT_GENSM2KEY: + gensm2 = 1; + break; + case OPT_DELSM2KEY: + delsm2 = 1; + break; + case OPT_UPDATESM2KEY: + updatesm2 = 1; + break; + case OPT_INDEX: + index = atoi(opt_arg()); + break; + case OPT_LOGIN: + login = opt_arg(); + break; + case OPT_EXPORTSM2KEY: + exportsm2key = 1; + break; + case OPT_EXPORTSM2PUBKEY: + exportsm2pubkey = 1; + break; + case OPT_EXPORTSM2KEYWITHEVLP: + exportsm2keywithevlp = 1; + break; + case OPT_IMPORTSM2KEY: + importsm2key = 1; + break; + case OPT_IMPORTSM2KEYWITHEVLP: + importsm2keywithevlp = 1; + break; + case OPT_PEERKEY: + peerkey_file = opt_arg(); + break; + case OPT_TYPE: + if (strcmp(opt_arg(), "sign") == 0) + sign = 1; + else if (strcmp(opt_arg(), "enc") == 0) + sign = 0; + else + goto opthelp; + break; + case OPT_KEYOUT: + outkeyfile = opt_arg(); + break; + case OPT_INDEK: + indekfile = opt_arg(); + break; + case OPT_DEKOUT: + outdekfile = opt_arg(); + break; + case OPT_ENCRYPT: + encrypt = 1; + break; + case OPT_DECRYPT: + decrypt = 1; + break; + case OPT_IV: + hexiv = opt_arg(); + break; + case OPT_ALGORITHM: + algo = opt_arg(); + break; + case OPT_ISK: + isk = atoi(opt_arg()); + break; + case OPT_ISKTYPE: + isktype = opt_arg(); + break; + } + } + + argc = opt_num_rest(); + if (argc != 0) + goto opthelp; + + if (login) { + user = login; + p = strchr(login, ':'); + if (p == NULL) { + BIO_printf(bio_err, "No password found"); + goto end; + } + + password = p + 1; + *p = '\0'; + } + + if (gensm2) { + if (!TSAPI_GenerateSM2KeyWithIndex(index, sign, user, password)) { + BIO_printf(bio_err, "Failed to generate SM2 key pair with index %d\n", index); + goto end; + } + } + + if (delsm2) { + if (!TSAPI_DelSm2KeyWithIndex(index, sign, user, password)) { + BIO_printf(bio_err, "Failed to delete SM2 key pair with index %d\n", index); + goto end; + } + } + + if (updatesm2) { + if (!TSAPI_UpdateSm2KeyWithIndex(index, sign, user, password)) { + BIO_printf(bio_err, "Failed to update SM2 key pair with index %d\n", index); + goto end; + } + } + + if (outkeyfile) { + outkey = bio_open_default(outkeyfile, 'w', FORMAT_BINARY); + if (outkey == NULL) + goto end; + } + + if (exportsm2key) { + pkey = TSAPI_ExportSM2KeyWithIndex(index, sign, user, password); + if (pkey == NULL) { + BIO_printf(bio_err, "Failed to export SM2 pubkey with index %d\n", index); + goto end; + } + + if (!PEM_write_bio_PrivateKey(outkey, pkey, NULL, NULL, 0, NULL, NULL)) { + BIO_printf(bio_err, "Failed to write SM2 key\n"); + ERR_print_errors(bio_err); + goto end; + } + } + + if (exportsm2pubkey) { + pkey = TSAPI_ExportSM2PubKeyWithIndex(index, sign); + if (pkey == NULL) { + BIO_printf(bio_err, "Failed to export SM2 pubkey with index %d\n", index); + goto end; + } + + if (!PEM_write_bio_PUBKEY(outkey, pkey)) { + BIO_printf(bio_err, "Failed to write SM2 pubkey"); + goto end; + } + } + + if (exportsm2keywithevlp) { + peer = load_pubkey(peerkey_file, FORMAT_PEM, 0, NULL, NULL, "peer key"); + if (peer == NULL) { + BIO_printf(bio_err, "Error reading peer key %s\n", peerkey_file); + return 0; + } + + if (!TSAPI_ExportSM2KeyWithEvlp(index, sign, user, password, peer, &priv, + &privlen, &pub, &publen, &outevlp, + &outevlplen)) { + BIO_printf(bio_err, "Failed to export SM2 key with digital envelope\n"); + goto end; + } + + if (outkey == NULL) { + BIO_printf(bio_err, "No output file specified\n"); + goto end; + } + + if (BIO_write(outkey, pub, publen) != (int)publen + || BIO_write(outkey, priv, privlen) != (int)privlen) { + BIO_printf(bio_err, "Failed to write public or private key\n"); + goto end; + } + + if (outdekfile == NULL) { + BIO_printf(bio_err, "No digital envelope file specified\n"); + goto end; + } + + outdek = bio_open_default(outdekfile, 'w', FORMAT_BINARY); + if (outdek == NULL) + goto end; + + if (BIO_write(outdek, outevlp, outevlplen) != (int)outevlplen) { + BIO_printf(bio_err, "Failed to write digital envelope\n"); + goto end; + } + } + + if (importsm2key) { + pkey = load_key(inkeyfile, FORMAT_PEM, 0, NULL, NULL, "key"); + + if (pkey == NULL) { + BIO_printf(bio_err, "Error reading key %s\n", inkeyfile); + goto end; + } + + if (!TSAPI_ImportSM2Key(index, sign, user, password, pkey)) { + BIO_printf(bio_err, "Failed to import SM2 key\n"); + goto end; + } + } + + if (inkeyfile) { + key_bio = BIO_new(BIO_s_file()); + if (key_bio == NULL) { + BIO_printf(bio_err, "Error creating key BIO\n"); + goto end; + } + + if (BIO_read_filename(key_bio, inkeyfile) <= 0) { + BIO_printf(bio_err, "Error reading key file %s\n", inkeyfile); + goto end; + } + + keylen = bio_to_mem(&inkey, 4096, key_bio); + BIO_free(key_bio); + key_bio = NULL; + + if (keylen < 0) { + BIO_printf(bio_err, "Error reading key\n"); + goto end; + } + } + + if (indekfile) { + key_bio = BIO_new(BIO_s_file()); + if (key_bio == NULL) { + BIO_printf(bio_err, "Error creating key BIO\n"); + goto end; + } + + if (BIO_read_filename(key_bio, indekfile) <= 0) { + BIO_printf(bio_err, "Error reading key file %s\n", indekfile); + goto end; + } + + deklen = bio_to_mem(&indek, 4096, key_bio); + BIO_free(key_bio); + key_bio = NULL; + + if (deklen < 0) { + BIO_printf(bio_err, "Error reading key\n"); + goto end; + } + } + + if (importsm2keywithevlp) { + if (inkey == NULL || indek == NULL) { + BIO_printf(bio_err, "No key or digital envelope specified\n"); + goto end; + } + + if (!TSAPI_ImportSM2KeyWithEvlp(index, sign, user, password, inkey, + keylen, indek, deklen)) { + BIO_printf(bio_err, "Failed to import SM2 key with digital envelope\n"); + goto end; + } + } + + if (infile) { + in = bio_open_default(infile, 'r', FORMAT_BINARY); + if (in == NULL) + goto end; + + /* Note: Only supports files less than 1GB */ + inbuflen = bio_to_mem(&inbuf, 1024 * 1024 * 1024, in); + if (inbuflen < 0) { + BIO_printf(bio_err, "Error reading input\n"); + goto end; + } + } + + if (outfile) { + out = bio_open_default(outfile, 'w', FORMAT_BINARY); + if (out == NULL) + goto end; + } + + if (encrypt || decrypt) { + if (inbuf == NULL || inbuflen < 0 || out == NULL || algo == NULL) { + BIO_printf(bio_err, "No input, output or algorithm specified\n"); + goto end; + } + + if (OPENSSL_strcasecmp(algo, "sm2") == 0) { + if (index < 0) { + BIO_printf(bio_err, "No SM2 key index specified\n"); + goto end; + } + + if (encrypt) + outbuf = TSAPI_SM2EncryptWithISK(index, inbuf, inbuflen, + &outbuflen); + else + outbuf = TSAPI_SM2DecryptWithISK(index, inbuf, inbuflen, + &outbuflen); + } else { + if (OPENSSL_strcasecmp(algo, "sm4-ecb") == 0) + mode = OSSL_SGD_SM4_ECB; + else if (OPENSSL_strcasecmp(algo, "sm4-cbc") == 0) + mode = OSSL_SGD_SM4_CBC; + else if (OPENSSL_strcasecmp(algo, "sm4-cfb") == 0) + mode = OSSL_SGD_SM4_CFB; + else if (OPENSSL_strcasecmp(algo, "sm4-ofb") == 0) + mode = OSSL_SGD_SM4_OFB; + else { + BIO_printf(bio_err, "Unknown algorithm %s\n", algo); + goto end; + } + + if (hexiv) { + iv = OPENSSL_hexstr2buf(hexiv, NULL); + if (iv == NULL) { + BIO_printf(bio_err, "Error reading IV\n"); + goto end; + } + } + + if (OPENSSL_strcasecmp(isktype, "sm2") == 0) { + if (encrypt) { + if ((outbuf = TSAPI_SM4Encrypt(mode, inkey, keylen, isk, iv, + inbuf, inbuflen, &outbuflen)) + == NULL) { + BIO_printf(bio_err, "Failed to encrypt data\n"); + goto end; + } + } else { + if ((outbuf = TSAPI_SM4Decrypt(mode, inkey, keylen, isk, iv, + inbuf, inbuflen, &outbuflen)) + == NULL) { + BIO_printf(bio_err, "Failed to decrypt data\n"); + goto end; + } + } + } else { + BIO_printf(bio_err, "Unknown ISK type %s\n", isktype); + goto end; + } + } + + if (BIO_write(out, outbuf, outbuflen) != (int)outbuflen) { + BIO_printf(bio_err, "Failed to write output\n"); + goto end; + } + } + + ret = 0; +end: + OPENSSL_free(iv); + OPENSSL_free(inbuf); + OPENSSL_free(outbuf); + BIO_free(in); + BIO_free(out); + OPENSSL_free(inkey); + BIO_free(outdek); + BIO_free(key_bio); + EVP_PKEY_free(pkey); + EVP_PKEY_free(peer); + BIO_free(outkey); + OPENSSL_free(priv); + OPENSSL_free(pub); + OPENSSL_free(outevlp); + return ret; +} diff --git a/apps/speed.c b/apps/speed.c index 1df5ce69d..25013523a 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -30,6 +30,7 @@ #define EdDSA_SECONDS PKEY_SECONDS #define SM2_SECONDS PKEY_SECONDS #define FFDH_SECONDS PKEY_SECONDS +#define KEYGEN_SECONDS PKEY_SECONDS /* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED @@ -48,6 +49,8 @@ #include #include #include +#include +#include #if !defined(OPENSSL_SYS_MSDOS) # include #endif @@ -121,6 +124,7 @@ typedef struct openssl_speed_sec_st { int ec_elgamal; int paillier; int bulletproofs; + int keygen; } openssl_speed_sec_t; static volatile int run = 0; @@ -260,7 +264,7 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, - OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC + OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_KEYGEN, OPT_SDF } OPTION_CHOICE; const OPTIONS speed_options[] = { @@ -291,6 +295,8 @@ const OPTIONS speed_options[] = { "Time decryption instead of encryption (only EVP)"}, {"aead", OPT_AEAD, '-', "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, + {"keygen", OPT_KEYGEN, 's', "Time the key generation using the specified algorithm"}, + {"sdf", OPT_SDF, 's', "Time the SDF operations using the specified operation"}, OPT_SECTION("Timing"), {"elapsed", OPT_ELAPSED, '-', @@ -316,7 +322,7 @@ enum { D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_RC5, D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES, - D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_SM3, D_CBC_SM4, + D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_SM3, D_CBC_SM4, D_ECB_SM4, D_EEA3_128_ZUC, D_EIA3_128_ZUC, D_SM2_ENCRYPT, D_SM2_DECRYPT, D_SM2_THRESHOLD_DECRYPT, ALGOR_NUM }; @@ -327,7 +333,7 @@ static const char *names[ALGOR_NUM] = { "des-cbc", "des-ede3", "rc4", "rc5-cbc", "aes-128-cbc", "aes-192-cbc", "aes-256-cbc", - "evp", "ghash", "rand", "cmac", "sm3", "sm4", + "evp", "ghash", "rand", "cmac", "sm3", "sm4-cbc", "sm4-ecb", "zuc-128-eea3", "zuc-128-eia3", "sm2-encrypt", "sm2-decrypt", "sm2-thr-dec", }; @@ -354,6 +360,7 @@ static const OPT_PAIR doit_choices[] = { #ifndef OPENSSL_NO_SM4 {"sm4-cbc", D_CBC_SM4}, {"sm4", D_CBC_SM4}, + {"sm4-ecb", D_ECB_SM4}, #endif #ifndef OPENSSL_NO_ZUC {"zuc-128-eea3", D_EEA3_128_ZUC}, @@ -646,9 +653,34 @@ static double bulletproofs_results[BULLETPROOFS_NUM][BULLETPROOFS_BITS_NUM][BULL #endif /* OPENSSL_NO_BULLETPROOFS */ +enum { + R_SM2, KEYGEN_NUM +}; +static const OPT_PAIR keygen_choices[KEYGEN_NUM] = { + {"sm2", R_SM2}, +}; + +static double keygen_results[KEYGEN_NUM]; + +enum { + R_GenerateKey, SDF_NUM +}; +static const OPT_PAIR sdf_choices[SDF_NUM] = { + {"GenerateKey", R_GenerateKey}, +}; + +static double sdf_results[SDF_NUM]; + #define COND(unused_cond) (run && count < INT_MAX) #define COUNT(d) (count) +typedef struct { + void *hSessionHandle; + void *hKeyHandle; +} HANDLE_PAIR; + +DEFINE_STACK_OF(HANDLE_PAIR) + typedef struct loopargs_st { ASYNC_JOB *inprogress_job; ASYNC_WAIT_CTX *wait_ctx; @@ -710,6 +742,10 @@ typedef struct loopargs_st { #endif EVP_CIPHER_CTX *ctx; EVP_MAC_CTX *mctx; + + void *hDeviceHandle; + void *hSessionHandle; + STACK_OF(HANDLE_PAIR) *key_handles; } loopargs_t; static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs); @@ -1379,6 +1415,24 @@ static int SM2_decrypt_loop(void *args) return count; } + +static int SM2_keygen_loop(void *args) +{ + int count; + + for (count = 0; COND(keygen_results[testnum]); count++) { + if (EVP_PKEY_Q_keygen(app_get0_libctx(), app_get0_propq(), "SM2") + == NULL) { + BIO_printf(bio_err, "SM2 keygen failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + + return count; +} + # ifndef OPENSSL_NO_SM2_THRESHOLD static long sm2_threshold_c[2]; @@ -1697,6 +1751,43 @@ static int BULLETPROOFS_loop(void *args) } #endif /* OPENSSL_NO_BULLETPROOFS */ +static void sdf_destroy_key(HANDLE_PAIR *pair) +{ + (void)TSAPI_SDF_DestroyKey(pair->hSessionHandle, pair->hKeyHandle); +} + +static int SDF_GenerateKey_loop(void *args) +{ + HANDLE_PAIR *pair = NULL; + loopargs_t *tempargs = *(loopargs_t **)args; + void *hSessionHandle = tempargs->hSessionHandle; + void *pkeyHandle = NULL; + int ret, count; + + for (count = 0; COND(1); count++) { + ret = TSAPI_SDF_GenerateKey(hSessionHandle, OSSL_SDFE_SYM_KEY_TYPE_SM4, + 1, 16, &pkeyHandle); + if (ret != OSSL_SDR_OK) { + BIO_printf(bio_err, "SDF_GenerateKey failed with %d\n", ret); + count = -1; + break; + } + + pair = OPENSSL_zalloc(sizeof(HANDLE_PAIR)); + if (pair == NULL) { + BIO_printf(bio_err, "Memory allocation failed\n"); + count = -1; + break; + } + pair->hSessionHandle = hSessionHandle; + pair->hKeyHandle = pkeyHandle; + + sk_HANDLE_PAIR_push(tempargs->key_handles, pair); + } + + return count; +} + static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs) { @@ -1943,7 +2034,8 @@ int speed_main(int argc, char **argv) OPTION_CHOICE o; int async_init = 0, multiblock = 0, pr_header = 0; uint8_t doit[ALGOR_NUM] = { 0 }; - int ret = 1, misalign = 0, lengths_single = 0, aead = 0; + int ret = 1, misalign = 0, lengths_single = 0, aead = 0, keygen = 0; + int sdf = 0; long count = 0; unsigned int size_num = SIZE_NUM; unsigned int i, k, loopargs_len = 0, async_jobs = 0; @@ -1959,7 +2051,8 @@ int speed_main(int argc, char **argv) ECDSA_SECONDS, ECDH_SECONDS, EdDSA_SECONDS, SM2_SECONDS, FFDH_SECONDS, EC_ELGAMAL_SECONDS, - PAILLIER_SECONDS, BULLETPROOFS_SECONDS }; + PAILLIER_SECONDS, BULLETPROOFS_SECONDS, + KEYGEN_SECONDS,}; static const unsigned char key32[32] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, @@ -2140,6 +2233,8 @@ int speed_main(int argc, char **argv) uint8_t ecdsa_doit[ECDSA_NUM] = { 0 }; uint8_t ecdh_doit[EC_NUM] = { 0 }; uint8_t eddsa_doit[EdDSA_NUM] = { 0 }; + uint8_t keygen_doit[KEYGEN_NUM] = { 0 }; + uint8_t sdf_doit[SDF_NUM] = { 0 }; /* checks declarated curves against choices list. */ OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448); @@ -2278,7 +2373,8 @@ int speed_main(int argc, char **argv) case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa = seconds.ecdh = seconds.eddsa - = seconds.sm2 = seconds.ffdh = atoi(opt_arg()); + = seconds.sm2 = seconds.ffdh = seconds.keygen + = atoi(opt_arg()); break; case OPT_BYTES: lengths_single = atoi(opt_arg()); @@ -2287,6 +2383,22 @@ int speed_main(int argc, char **argv) break; case OPT_AEAD: aead = 1; + break; + case OPT_KEYGEN: + keygen = 1; + if (opt_found(opt_arg(), keygen_choices, &i)) { + keygen_doit[i] = 1; + break; + } + + break; + case OPT_SDF: + sdf = 1; + if (opt_found(opt_arg(), sdf_choices, &i)) { + sdf_doit[i] = 1; + break; + } + break; } } @@ -2543,6 +2655,7 @@ int speed_main(int argc, char **argv) loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a"); loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b"); #endif + loopargs[i].key_handles = sk_HANDLE_PAIR_new_null(); } #ifndef NO_FORK @@ -2554,7 +2667,8 @@ int speed_main(int argc, char **argv) e = setup_engine(engine_id, 0); /* No parameters; turn on everything. */ - if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) { + if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC] + && !keygen && !sdf) { memset(doit, 1, sizeof(doit)); doit[D_EVP] = doit[D_EVP_CMAC] = 0; ERR_set_mark(); @@ -2604,6 +2718,8 @@ int speed_main(int argc, char **argv) memset(sm2_threshold_doit, 1, sizeof(sm2_threshold_doit)); # endif #endif + memset(keygen_doit, 1, sizeof(keygen_doit)); + memset(sdf_doit, 1, sizeof(sdf_doit)); } for (i = 0; i < ALGOR_NUM; i++) if (doit[i]) @@ -2966,27 +3082,31 @@ int speed_main(int argc, char **argv) } #ifndef OPENSSL_NO_SM4 - if (doit[D_CBC_SM4]) { - int st = 1; + for (k = 0; k < 2; k++) { + algindex = D_CBC_SM4 + k; - keylen = 16; - for (i = 0; st && i < loopargs_len; i++) { - loopargs[i].ctx = init_evp_cipher_ctx(names[D_CBC_SM4], - key32, keylen); - st = loopargs[i].ctx != NULL; - } + if (doit[algindex]) { + int st = 1; - for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[D_CBC_SM4], c[D_CBC_SM4][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); - d = Time_F(STOP); - print_result(D_CBC_SM4, testnum, count, d); + keylen = 16; + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx(names[algindex], + key32, keylen); + st = loopargs[i].ctx != NULL; + } + + for (testnum = 0; st && testnum < size_num; testnum++) { + print_message(names[algindex], c[algindex][testnum], + lengths[testnum], seconds.sym); + Time_F(START); + count = + run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); + d = Time_F(STOP); + print_result(algindex, testnum, count, d); + } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } - for (i = 0; i < loopargs_len; i++) - EVP_CIPHER_CTX_free(loopargs[i].ctx); } #endif @@ -3715,47 +3835,57 @@ int speed_main(int argc, char **argv) for (i = 0; st && i < loopargs_len; i++) { EVP_PKEY *pkey = NULL, *pubkey = NULL; - OSSL_PARAM *pub_params = NULL; EVP_PKEY_CTX *ctx = NULL; + BIO *tmpbio = NULL; st = 0; pkey = EVP_PKEY_Q_keygen(app_get0_libctx(), app_get0_propq(), "SM2"); if (pkey == NULL) break; - if (!EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &pub_params)) { + if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) + break; + + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (ctx == NULL) { EVP_PKEY_free(pkey); break; } - ctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); - if (ctx == NULL) { + tmpbio = BIO_new(BIO_s_mem()); + if (tmpbio == NULL) + break; + + if (!PEM_write_bio_PUBKEY(tmpbio, pkey)) { EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + BIO_free(tmpbio); break; } - if (EVP_PKEY_fromdata_init(ctx) <= 0 - || EVP_PKEY_fromdata(ctx, &pubkey, EVP_PKEY_PUBLIC_KEY, - pub_params) <= 0) { + if (!PEM_read_bio_PUBKEY(tmpbio, &pubkey, NULL, NULL)) { EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); + BIO_free(tmpbio); break; } EVP_PKEY_CTX_free(ctx); + BIO_free(tmpbio); loopargs[i].sm2_enc_pctx = EVP_PKEY_CTX_new(pubkey, NULL); if (loopargs[i].sm2_enc_pctx == NULL) { EVP_PKEY_free(pkey); + EVP_PKEY_free(pubkey); break; } + EVP_PKEY_free(pubkey); loopargs[i].sm2_dec_pctx = EVP_PKEY_CTX_new(pkey, NULL); if (loopargs[i].sm2_dec_pctx == NULL) { EVP_PKEY_free(pkey); break; } - EVP_PKEY_free(pkey); if (EVP_PKEY_encrypt_init(loopargs[i].sm2_enc_pctx) <= 0) @@ -3956,7 +4086,6 @@ int speed_main(int argc, char **argv) for (i = 0; i < loopargs_len; i++) { EVP_PKEY_CTX *sm2_pctx = NULL; EVP_PKEY_CTX *sm2_vfy_pctx = NULL; - EVP_PKEY_CTX *pctx = NULL; st = 0; loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new(); @@ -3967,16 +4096,12 @@ int speed_main(int argc, char **argv) sm2_pkey = NULL; - st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL - || EVP_PKEY_keygen_init(pctx) <= 0 - || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, - sm2_curves[testnum].nid) <= 0 - || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0); - EVP_PKEY_CTX_free(pctx); - if (st == 0) + sm2_pkey = EVP_PKEY_Q_keygen(app_get0_libctx(), app_get0_propq(), "SM2"); + if (sm2_pkey == NULL) break; - st = 0; /* set back to zero */ + if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2)) + break; /* attach it sooner to rely on main final cleanup */ loopargs[i].sm2_pkey[testnum] = sm2_pkey; loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey); @@ -4769,6 +4894,73 @@ int speed_main(int argc, char **argv) } #endif /* OPENSSL_NO_BULLETPROOFS */ + for (testnum = 0; testnum < KEYGEN_NUM; testnum++) { + if (!keygen_doit[testnum]) + continue; + + if (testnum == R_SM2) { + pkey_print_message("keygen", "sm2", 0, 128, seconds.keygen); + Time_F(START); +#ifndef OPENSSL_NO_SM2 + count = run_benchmark(async_jobs, SM2_keygen_loop, loopargs); +#else + count = 0; +#endif + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+F14:%ld:%s:%.2f\n" + : "%ld %s keygen in %.2fs\n", + count, keygen_choices[testnum].name, d); + keygen_results[testnum] = (double)count / d; + } + } + + for (testnum = 0; testnum < SDF_NUM; testnum++) { + int st = 1; + int res; + + if (!sdf_doit[testnum]) + continue; + + for (i = 0; i < loopargs_len; i++) { + st = 0; + + res = TSAPI_SDF_OpenDevice(&loopargs[i].hDeviceHandle); + if (res != OSSL_SDR_OK) { + BIO_printf(bio_err, "TSAPI_SDF_OpenDevice failed with %d\n", ret); + break; + } + + res = TSAPI_SDF_OpenSession(loopargs[i].hDeviceHandle, + &loopargs[i].hSessionHandle); + if (res != OSSL_SDR_OK) { + BIO_printf(bio_err, "TSAPI_SDF_OpenSession failed with %d\n", ret); + break; + } + + st = 1; + } + + if (st == 0) { + BIO_printf(bio_err, "SDF failure.\n"); + op_count = 1; + } else { + + if (testnum == R_GenerateKey) { + pkey_print_message("GenerateKey", "sm4", 0, 128, + seconds.keygen); + Time_F(START); + count = run_benchmark(async_jobs, SDF_GenerateKey_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+F15:%ld:%s:%.2f\n" + : "%ld %s keygen in %.2fs\n", + count, sdf_choices[testnum].name, d); + sdf_results[testnum] = (double)count / d; + } + } + } + #ifndef NO_FORK show_res: #endif @@ -5060,6 +5252,48 @@ int speed_main(int argc, char **argv) } #endif + testnum = 1; + for (k = 0; k < KEYGEN_NUM; k++) { + if (!keygen_doit[k]) + continue; + + if (testnum && !mr) { + printf("%30sop op/s\n", " "); + testnum = 0; + } + + if (mr) + printf("+F14:%u:%s:%f:%f\n", + k, keygen_choices[k].name, keygen_results[k], + 1.0 / keygen_results[k]); + else + printf("128 bits keygen (%s) %8.4fs %8.1f\n", + keygen_choices[k].name, 1.0 / keygen_results[k], + keygen_results[k]); + } + + testnum = 1; + for (k = 0; k < SDF_NUM; k++) { + if (!sdf_doit[k]) + continue; + + if (testnum && !mr) { + printf("%30sop op/s\n", " "); + testnum = 0; + } + + if (k == R_GenerateKey) { + if (mr) + printf("+F15:%u:%s:%f:%f\n", + k, sdf_choices[k].name, sdf_results[k], + 1.0 / sdf_results[k]); + else + printf("128 bits keygen (%s) %8.4fs %8.1f\n", + sdf_choices[k].name, 1.0 / sdf_results[k], + sdf_results[k]); + } + } + ret = 0; end: @@ -5156,6 +5390,14 @@ int speed_main(int argc, char **argv) #endif OPENSSL_free(loopargs[i].secret_a); OPENSSL_free(loopargs[i].secret_b); + + sk_HANDLE_PAIR_pop_free(loopargs[i].key_handles, sdf_destroy_key); + + if (loopargs[i].hSessionHandle != NULL) + TSAPI_SDF_CloseSession(loopargs[i].hSessionHandle); + + if (loopargs[i].hDeviceHandle != NULL) + TSAPI_SDF_CloseDevice(loopargs[i].hDeviceHandle); } OPENSSL_free(evp_hmac_name); OPENSSL_free(evp_cmac_name); diff --git a/apps/version.c b/apps/version.c index 874542349..63be8bf83 100644 --- a/apps/version.c +++ b/apps/version.c @@ -167,7 +167,6 @@ int version_main(int argc, char **argv) } #ifdef SMTC_MODULE if (smtc) { - printf("%s\n", OpenSSL_version(TONGSUO_VERSION)); printf("%s\n", OpenSSL_version(TONGSUO_SMTC_INFO)); } #endif diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c index 66d8f8868..9f379b8c3 100644 --- a/crypto/bio/bss_log.c +++ b/crypto/bio/bss_log.c @@ -22,30 +22,12 @@ #include "bio_local.h" #include "internal/cryptlib.h" -#if defined(OPENSSL_SYS_WINCE) -#elif defined(OPENSSL_SYS_WIN32) -#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) -# include -#endif - +#include #include #include #ifndef NO_SYSLOG -# if defined(OPENSSL_SYS_WIN32) -# define LOG_EMERG 0 -# define LOG_ALERT 1 -# define LOG_CRIT 2 -# define LOG_ERR 3 -# define LOG_WARNING 4 -# define LOG_NOTICE 5 -# define LOG_INFO 6 -# define LOG_DEBUG 7 - -# define LOG_DAEMON (3<<3) -# endif - static int slg_write(BIO *h, const char *buf, int num); static int slg_puts(BIO *h, const char *str); static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); diff --git a/crypto/build.info b/crypto/build.info index db0808cac..35b77e29a 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -6,7 +6,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ siphash sm3 des aes rc4 rc5 zuc \ sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ - ffc paillier zkp + ffc paillier zkp sdf tsapi LIBS=../libcrypto @@ -96,7 +96,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \ - punycode.c passphrase.c + punycode.c passphrase.c o_syslog.c SOURCE[../providers/libfips.a]=$UTIL_COMMON SOURCE[../libcrypto]=$UPLINKSRC @@ -128,3 +128,14 @@ INCLUDE[s390xcpuid.o]=. IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}] SHARED_SOURCE[../libcrypto]=dllmain.c ENDIF + +{- use File::Spec::Functions; + our $ex_lib = $withargs{sdf_lib} && + (file_name_is_absolute($withargs{sdf_lib}) ? + $withargs{sdf_lib} : catfile(updir(), $withargs{sdf_lib})); + "" +-} + +IF[{- !$disabled{sdf_lib} -}] + DEPEND[../libcrypto]={- $ex_lib -} +ENDIF diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index eb14f4e40..ab83ca915 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -25,9 +25,14 @@ #include #include "prov/providercommon.h" #include "crypto/bn.h" +#include "crypto/sm2.h" static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, void *cbarg); +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE) +static int sm2_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, + void *cbarg); +#endif #ifndef FIPS_MODULE EC_KEY *EC_KEY_new(void) @@ -322,7 +327,7 @@ static int ec_generate_key(EC_KEY *eckey, int pairwise_test) eckey->dirty_cnt++; -#ifdef FIPS_MODULE +#if defined(FIPS_MODULE) || defined(SMTC_MODULE) pairwise_test = 1; #endif /* FIPS_MODULE */ @@ -332,7 +337,12 @@ static int ec_generate_key(EC_KEY *eckey, int pairwise_test) void *cbarg = NULL; OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg); - ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg); +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE) + if (sm2) + ok = sm2_keygen_pairwise_test(eckey, cb, cbarg); + else +#endif + ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg); } err: /* Step (9): If there is an error return an invalid keypair. */ @@ -1026,3 +1036,42 @@ static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, ECDSA_SIG_free(sig); return ret; } + +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE) +static int sm2_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, + void *cbarg) +{ + int ret = 0; + unsigned char dgst[16] = {0}; + int dgst_len = (int)sizeof(dgst); + unsigned char *sig = NULL; + unsigned int sig_len = 0; + OSSL_SELF_TEST *st = NULL; + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + return 0; + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_SIGN_SM2); + + sig = OPENSSL_malloc(ECDSA_size(eckey)); + if (sig == NULL) + goto err; + + if (ossl_sm2_internal_sign(dgst, dgst_len, sig, &sig_len, eckey) <= 0) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, dgst); + + if (ossl_sm2_internal_verify(dgst, dgst_len, sig, sig_len, eckey) != 1) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + OPENSSL_free(sig); + return ret; +} +#endif diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index bd9bd818d..d1973c0eb 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -651,7 +651,6 @@ ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR:101:ess signing cert v2 add error ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE:108:\ missing signing certificate attribute EVP_R_AES_KEY_SETUP_FAILED:143:aes key setup failed -EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed EVP_R_BAD_ALGORITHM_NAME:200:bad algorithm name EVP_R_BAD_DECRYPT:100:bad decrypt EVP_R_BAD_KEY_LENGTH:195:bad key length @@ -990,6 +989,7 @@ PROV_R_FIPS_MODULE_IN_ERROR_STATE:225:fips module in error state PROV_R_GENERATE_ERROR:191:generate error PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ illegal or unsupported padding mode +PROV_R_INCORRECT_PASSWORD:231:incorrect password PROV_R_INDICATOR_INTEGRITY_FAILURE:210:indicator integrity failure PROV_R_INSUFFICIENT_DRBG_STRENGTH:181:insufficient drbg strength PROV_R_INVALID_AAD:108:invalid aad @@ -1069,6 +1069,9 @@ PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT:229:\ seed sources must not have a parent PROV_R_SELF_TEST_KAT_FAILURE:215:self test kat failure PROV_R_SELF_TEST_POST_FAILURE:216:self test post failure +PROV_R_SMTC_MODULE_CONDITIONAL_ERROR:232:smtc module conditional error +PROV_R_SMTC_MODULE_ENTERING_ERROR_STATE:350:smtc module entering error state +PROV_R_SMTC_MODULE_IN_ERROR_STATE:351:smtc module in error state PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_TAG_NOT_SET:119:tag not set PROV_R_TOO_MANY_RECORDS:126:too many records diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 76a6814b4..1d9534716 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -63,10 +63,16 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, if (ctx->pctx == NULL) { reinit = 0; - if (e == NULL) - ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); - else + if (e == NULL) { +#ifdef SMTC_MODULE + if (ver) + ctx->pctx = EVP_PKEY_CTX_new_from_pkey_provided(libctx, pkey, props); + else +#endif + ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); + } else { ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } } if (ctx->pctx == NULL) return 0; diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 8e4940ed5..48e222631 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -230,6 +230,11 @@ int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) default: goto not_supported; } + +# ifndef OPENSSL_NO_SM2 + if (ret > 0 && EVP_PKEY_CTX_is_a(ctx, "SM2")) + ret = EVP_PKEY_set_alias_type(*ppkey, EVP_PKEY_SM2); +# endif #endif end: @@ -271,6 +276,10 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); return -1; } + +#ifdef SMTC_MODULE + OSSL_syslog(LOG_INFO, "Creating a key pair\n"); +#endif return EVP_PKEY_generate(ctx, ppkey); } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 26d3e902d..a9cac26e3 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -375,6 +375,82 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, return int_ctx_new(libctx, pkey, NULL, NULL, propquery, -1); } +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey_provided(OSSL_LIB_CTX *libctx, + EVP_PKEY *pkey, + const char *propquery) +{ + EVP_PKEY_CTX *ret = NULL; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!evp_pkey_is_provided(pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); + return NULL; + } + + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (propquery != NULL) { + ret->propquery = OPENSSL_strdup(propquery); + if (ret->propquery == NULL) { + OPENSSL_free(ret); + return NULL; + } + } + + ret->libctx = libctx; + ret->operation = EVP_PKEY_OP_UNDEFINED; + ret->keymgmt = pkey->keymgmt; + EVP_KEYMGMT_up_ref(pkey->keymgmt); + + ret->keytype = EVP_KEYMGMT_get0_name(ret->keymgmt); + ret->pkey = pkey; + EVP_PKEY_up_ref(pkey); + + return ret; +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name_provided(OSSL_LIB_CTX *libctx, + const char *name, + const char *propquery) +{ + EVP_PKEY_CTX *ret = NULL; + EVP_KEYMGMT *keymgmt; + + keymgmt = EVP_KEYMGMT_fetch(libctx, name, propquery); + if (keymgmt == NULL) + return NULL; + + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) { + EVP_KEYMGMT_free(keymgmt); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (propquery != NULL) { + ret->propquery = OPENSSL_strdup(propquery); + if (ret->propquery == NULL) { + OPENSSL_free(ret); + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + } + + ret->operation = EVP_PKEY_OP_UNDEFINED; + ret->keymgmt = keymgmt; + ret->keytype = EVP_KEYMGMT_get0_name(keymgmt); + + return ret; +} + void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) { if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { diff --git a/crypto/info.c b/crypto/info.c index 69142d396..5984426fc 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -152,8 +152,14 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings) #ifdef OPENSSL_RAND_SEED_OS add_seeds_string("os-specific"); #endif -#ifdef OPENSSL_RAND_SEED_RTC - add_seeds_string("real-time-clock"); +#ifdef OPENSSL_RAND_SEED_RTCODE + add_seeds_string("real-time-code"); +#endif +#ifdef OPENSSL_RAND_SEED_RTMEM + add_seeds_string("real-time-memory"); +#endif +#ifdef OPENSSL_RAND_SEED_RTSOCK + add_seeds_string("real-time-socket"); #endif seed_sources = seeds; } @@ -200,6 +206,12 @@ const char *OPENSSL_info(int t) if (ossl_cpu_info_str[0] != '\0') return ossl_cpu_info_str + strlen(CPUINFO_PREFIX); break; +#ifdef SMTC_MODULE + case OPENSSL_INFO_SMTC_MODULE_CONF: + return SMTC_MODULE_CONF; + case OPENSSL_INFO_SMTC_AUTH_KEK: + return SMTC_AUTH_KEK; +#endif default: break; } diff --git a/crypto/init.c b/crypto/init.c index f4df1d983..4f20b7c33 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -10,6 +10,7 @@ /* We need to use some engine deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED +#include "internal/sdf.h" #include "internal/e_os.h" #include "crypto/cryptlib.h" #include @@ -445,6 +446,9 @@ void OPENSSL_cleanup(void) OSSL_CMP_log_close(); #endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_sdf_lib_cleanup()\n"); + ossl_sdf_lib_cleanup(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n"); ossl_trace_cleanup(); diff --git a/crypto/o_syslog.c b/crypto/o_syslog.c new file mode 100644 index 000000000..49ce4b437 --- /dev/null +++ b/crypto/o_syslog.c @@ -0,0 +1,80 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#include +#include +#include +#include "internal/nelem.h" + +static int logging = 0; + +void OSSL_enable_syslog(void) +{ + logging = 1; +} + +void OSSL_disable_syslog(void) +{ + logging = 0; +} + +void OSSL_syslog(int priority, const char *message, ...) +{ + va_list args; + unsigned char buf[4096]; + BIO *bio = NULL; + size_t i; + int written = 0, ret; + const struct { + int log_level; + const char *str; + } mapping[] = { + { LOG_EMERG, "EMERG" }, + { LOG_ALERT, "ALERT" }, + { LOG_CRIT, "CRIT" }, + { LOG_ERR, "ERROR" }, + { LOG_WARNING, "WARNING" }, + { LOG_NOTICE, "NOTICE" }, + { LOG_INFO, "INFO" }, + { LOG_DEBUG, "DEBUG" }, + }; + + if (logging == 0) + return; + + bio = BIO_new(BIO_s_log()); + if (bio == NULL) + return; + + for (i = 0; i < OSSL_NELEM(mapping); i++) { + if (mapping[i].log_level == priority) { + ret = BIO_snprintf((char *)buf, sizeof(buf), "%s ", mapping[i].str); + if (ret < 0) + goto end; + + written += ret; + break; + } + } + + va_start(args, message); + ret = BIO_vsnprintf((char *)buf, sizeof(buf) - written, message, args); + va_end(args); + + if (ret < 0) + goto end; + + written += ret; + + if (BIO_write(bio, buf, written) != written) + goto end; + +end: + BIO_free(bio); +} diff --git a/crypto/provider.c b/crypto/provider.c index 114b42692..e2001a2db 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -99,6 +99,16 @@ const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov) return ossl_provider_get0_dispatch(prov); } +int OSSL_PROVIDER_reset(OSSL_PROVIDER *prov) +{ + return ossl_provider_reset(prov); +} + +int OSSL_PROVIDER_status(const OSSL_PROVIDER *prov) +{ + return ossl_provider_status(prov); +} + int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov) { return ossl_provider_self_test(prov); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 177358f05..0c439ed6c 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -172,6 +172,8 @@ struct ossl_provider_st { OSSL_FUNC_provider_self_test_fn *self_test; OSSL_FUNC_provider_query_operation_fn *query_operation; OSSL_FUNC_provider_unquery_operation_fn *unquery_operation; + OSSL_FUNC_provider_status_fn *status; + OSSL_FUNC_provider_reset_fn *reset; /* * Cache of bit to indicate of query_operation() has been called on @@ -944,6 +946,12 @@ static int provider_init(OSSL_PROVIDER *prov) prov->unquery_operation = OSSL_FUNC_provider_unquery_operation(provider_dispatch); break; + case OSSL_FUNC_PROVIDER_STATUS: + prov->status = OSSL_FUNC_provider_status(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_RESET: + prov->reset = OSSL_FUNC_provider_reset(provider_dispatch); + break; #ifndef OPENSSL_NO_ERR # ifndef FIPS_MODULE case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: @@ -1492,6 +1500,22 @@ int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) ? 0 : prov->get_params(prov->provctx, params); } +int ossl_provider_reset(OSSL_PROVIDER *prov) +{ + if (prov->reset == NULL) + return 1; + + return prov->reset(prov->provctx); +} + +int ossl_provider_status(const OSSL_PROVIDER *prov) +{ + if (prov->status == NULL) + return 1; + + return prov->status(prov->provctx); +} + int ossl_provider_self_test(const OSSL_PROVIDER *prov) { int ret; diff --git a/crypto/provider_predefined.c b/crypto/provider_predefined.c index 938c1ba9a..e20fbe4c7 100644 --- a/crypto/provider_predefined.c +++ b/crypto/provider_predefined.c @@ -17,13 +17,21 @@ OSSL_provider_init_fn ossl_fips_intern_provider_init; #ifdef STATIC_LEGACY OSSL_provider_init_fn ossl_legacy_provider_init; #endif -#ifdef STATIC_SMTC +#ifdef SMTC_MODULE +# ifdef STATIC_SMTC OSSL_provider_init_fn ossl_smtc_provider_init; +# endif +OSSL_provider_init_fn ossl_smtc_intern_provider_init; #endif const OSSL_PROVIDER_INFO ossl_predefined_providers[] = { #ifdef FIPS_MODULE { "fips", NULL, ossl_fips_intern_provider_init, NULL, 1 }, +#elif defined(SMTC_MODULE) + { "inner-smtc", NULL, ossl_smtc_intern_provider_init, NULL, 1 }, +# ifdef STATIC_SMTC + { "smtc", NULL, ossl_smtc_provider_init, NULL, 0 }, +# endif #else { "default", NULL, ossl_default_provider_init, NULL, 1 }, # ifdef STATIC_LEGACY @@ -31,9 +39,6 @@ const OSSL_PROVIDER_INFO ossl_predefined_providers[] = { # endif { "base", NULL, ossl_base_provider_init, NULL, 0 }, { "null", NULL, ossl_null_provider_init, NULL, 0 }, -# ifdef STATIC_SMTC - { "smtc", NULL, ossl_smtc_provider_init, NULL, 0 }, -# endif #endif { NULL, NULL, NULL, NULL, 0 } }; diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c index afa85ab76..486153ec8 100644 --- a/crypto/rand/prov_seed.c +++ b/crypto/rand/prov_seed.c @@ -38,6 +38,34 @@ size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle, return ret; } +size_t ossl_rand_get_entropy_from_source(unsigned int source, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + size_t ret = 0; + size_t entropy_available; + RAND_POOL *pool; + + pool = ossl_rand_pool_new(entropy, 1, min_len, max_len); + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return 0; + } + + pool->entropy_source = source; + + /* Get entropy by polling system entropy sources. */ + entropy_available = ossl_pool_acquire_entropy(pool); + + if (entropy_available > 0) { + ret = ossl_rand_pool_length(pool); + *pout = ossl_rand_pool_detach(pool); + } + + ossl_rand_pool_free(pool); + return ret; +} + void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len) { diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index a00514e52..13092eadf 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -564,7 +564,11 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, if (dgbl == NULL) return NULL; +#ifdef SMTC_MODULE + name = dgbl->rng_name != NULL ? dgbl->rng_name : "HASH-DRBG"; +#else name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG"; +#endif rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq); if (rand == NULL) { ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); @@ -581,12 +585,22 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, * Rather than trying to decode the DRBG settings, just pass them through * and rely on the other end to ignore those it doesn't care about. */ +#ifdef SMTC_MODULE + cipher = dgbl->rng_digest != NULL ? dgbl->rng_digest : "SM3"; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, + cipher, 0); + + if (dgbl->rng_cipher != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + dgbl->rng_cipher, 0); +#else cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, cipher, 0); if (dgbl->rng_digest != NULL) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, dgbl->rng_digest, 0); +#endif if (dgbl->rng_propq != NULL) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, dgbl->rng_propq, 0); @@ -808,6 +822,11 @@ void ossl_random_add_conf_module(void) CONF_module_add("random", random_conf_init, random_conf_deinit); } +void RAND_set_entropy_source(unsigned int type) +{ + ossl_rand_pool_set_default_entropy_source(type); +} + int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq, const char *cipher, const char *digest) { diff --git a/crypto/rand/rand_pool.c b/crypto/rand/rand_pool.c index 55f14be60..4dae4a93c 100644 --- a/crypto/rand/rand_pool.c +++ b/crypto/rand/rand_pool.c @@ -16,6 +16,8 @@ #include "internal/thread_once.h" #include "crypto/rand_pool.h" +static unsigned int default_entropy_source = 0xFFFFFFFF; + /* * Allocate memory and initialize a new random pool */ @@ -49,6 +51,7 @@ RAND_POOL *ossl_rand_pool_new(int entropy_requested, int secure, pool->entropy_requested = entropy_requested; pool->secure = secure; + pool->entropy_source = default_entropy_source; return pool; err: @@ -410,3 +413,8 @@ int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy) return 1; } + +void ossl_rand_pool_set_default_entropy_source(unsigned int source) +{ + default_entropy_source = source; +} diff --git a/crypto/sdf/build.info b/crypto/sdf/build.info new file mode 100644 index 000000000..b847b6587 --- /dev/null +++ b/crypto/sdf/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + sdf_lib.c sdf_meth.c \ No newline at end of file diff --git a/crypto/sdf/sdf_lib.c b/crypto/sdf/sdf_lib.c new file mode 100644 index 000000000..ce8824196 --- /dev/null +++ b/crypto/sdf/sdf_lib.c @@ -0,0 +1,416 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#include +#include +#include +#include "internal/thread_once.h" +#include "internal/dso.h" +#include "internal/sdf.h" +#include "sdf_local.h" + +#ifdef SDF_LIB +# ifdef SDF_LIB_SHARED +static DSO *sdf_dso = NULL; +# else +extern int SDF_OpenDevice(void **phDeviceHandle) __attribute__((weak)); +extern int SDF_CloseDevice(void *hDeviceHandle) __attribute__((weak)); +extern int SDF_OpenSession(void *hDeviceHandle, void **phSessionHandle) __attribute__((weak)); +extern int SDF_CloseSession(void *hSessionHandle) __attribute__((weak)); + +extern int SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, + unsigned char *pucRandom) __attribute__((weak)); + +extern int SDF_GetPrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex, unsigned char *pucPassword, + unsigned int uiPwdLength); + +extern int SDF_ReleasePrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex); + +extern int SDF_ImportKeyWithISK_ECC(void *hSessionHandle, + unsigned int uiISKIndex, OSSL_ECCCipher *pucKey, + void **phKeyHandle) __attribute__((weak)); + +extern int SDF_ImportKeyWithKEK(void *hSessionHandle, + unsigned int uiAlgID, unsigned int uiKEKIndex, unsigned char *pucKey, + unsigned int puiKeyLength, void **phKeyHandle) __attribute__((weak)); + +extern int SDF_ExportSignPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, OSSL_ECCrefPublicKey *pucPublicKey) + __attribute__((weak)); + +extern int SDF_ExportEncPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, OSSL_ECCrefPublicKey *pucPublicKey) + __attribute__((weak)); + +extern int SDF_DestroyKey(void *hSessionHandle, void *hKeyHandle) + __attribute__((weak)); + +extern int SDF_InternalEncrypt_ECC(void *hSessionHandle, + unsigned int uiISKIndex, unsigned char *pucData, unsigned int uiDataLength, + OSSL_ECCCipher * pucEncData); + +extern int SDF_InternalDecrypt_ECC(void *hSessionHandle, + unsigned int uiISKIndex, OSSL_ECCCipher *pucEncData, + unsigned char *pucData, unsigned int *puiDataLength); + +extern int SDF_InternalSign_ECC(void * hSessionHandle, unsigned int uiISKIndex, + unsigned char * pucData, unsigned int uiDataLength, + OSSL_ECCSignature * pucSignature); + +extern 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) __attribute__((weak)); + +extern 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) __attribute__((weak)); + +extern 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) __attribute__((weak)); + +extern int SDFE_GenerateKey(void *hSessionHandle, uint8_t type, uint8_t no_kek, + uint32_t len, void **pkey_handle) __attribute__((weak)); +# endif + +static CRYPTO_ONCE sdf_lib_once = CRYPTO_ONCE_STATIC_INIT; +static SDF_METHOD sdfm; + +DEFINE_RUN_ONCE_STATIC(ossl_sdf_lib_init) +{ +# ifdef SDF_LIB_SHARED +# ifndef LIBSDF +# define LIBSDF "sdf" +# endif + + sdf_dso = DSO_load(NULL, LIBSDF, NULL, 0); + if (sdf_dso != NULL) { + sdfm.OpenDevice = DSO_bind_func(sdf_dso, "SDF_OpenDevice"); + sdfm.CloseDevice = DSO_bind_func(sdf_dso, "SDF_CloseDevice"); + sdfm.OpenSession = DSO_bind_func(sdf_dso, "SDF_OpenSession"); + sdfm.CloseSession = DSO_bind_func(sdf_dso, "SDF_CloseSession"); + sdfm.GenerateRandom = DSO_bind_func(sdf_dso, "SDF_GenerateRandom"); + sdfm.GetPrivateKeyAccessRight = DSO_bind_func(sdf_dso, "SDF_GetPrivateKeyAccessRight"); + sdfm.ReleasePrivateKeyAccessRight = DSO_bind_func(sdf_dso, "SDF_ReleasePrivateKeyAccessRight"); + sdfm.ImportKeyWithISK_ECC = DSO_bind_func(sdf_dso, "SDF_ImportKeyWithISK_ECC"); + sdfm.ImportKeyWithKEK = DSO_bind_func(sdf_dso, "SDF_ImportKeyWithKEK"); + sdfm.ExportSignPublicKey_ECC = DSO_bind_func(sdf_dso, "SDF_ExportSignPublicKey_ECC"); + sdfm.ExportEncPublicKey_ECC = DSO_bind_func(sdf_dso, "SDF_ExportEncPublicKey_ECC"); + sdfm.DestroyKey = DSO_bind_func(sdf_dso, "SDF_DestroyKey"); + sdfm.InternalEncrypt_ECC = DSO_bind_func(sdf_dso, "SDF_InternalEncrypt_ECC"); + sdfm.InternalDecrypt_ECC = DSO_bind_func(sdf_dso, "SDF_InternalDecrypt_ECC"); + sdfm.InternalSign_ECC = DSO_bind_func(sdf_dso, "SDF_InternalSign_ECC"); + sdfm.Encrypt = DSO_bind_func(sdf_dso, "SDF_Encrypt"); + sdfm.Decrypt = DSO_bind_func(sdf_dso, "SDF_Decrypt"); + sdfm.CalculateMAC = DSO_bind_func(sdf_dso, "SDF_CalculateMAC"); + sdfm.GenerateKey = DSO_bind_func(sdf_dso, "SDFE_GenerateKey"); + } +# else + sdfm.OpenDevice = SDF_OpenDevice; + sdfm.CloseDevice = SDF_CloseDevice; + sdfm.OpenSession = SDF_OpenSession; + sdfm.CloseSession = SDF_CloseSession; + sdfm.GenerateRandom = SDF_GenerateRandom; + sdfm.GetPrivateKeyAccessRight = SDF_GetPrivateKeyAccessRight; + sdfm.ReleasePrivateKeyAccessRight = SDF_ReleasePrivateKeyAccessRight; + sdfm.ImportKeyWithISK_ECC = SDF_ImportKeyWithISK_ECC; + sdfm.ImportKeyWithKEK = SDF_ImportKeyWithKEK; + sdfm.ExportSignPublicKey_ECC = SDF_ExportSignPublicKey_ECC; + sdfm.ExportEncPublicKey_ECC = SDF_ExportEncPublicKey_ECC; + sdfm.DestroyKey = SDF_DestroyKey; + sdfm.InternalEncrypt_ECC = SDF_InternalEncrypt_ECC; + sdfm.InternalDecrypt_ECC = SDF_InternalDecrypt_ECC; + sdfm.InternalSign_ECC = SDF_InternalSign_ECC; + sdfm.Encrypt = SDF_Encrypt; + sdfm.Decrypt = SDF_Decrypt; + sdfm.CalculateMAC = SDF_CalculateMAC; + sdfm.GenerateKey = SDFE_GenerateKey; +# endif + return 1; +} +#endif + +void ossl_sdf_lib_cleanup(void) +{ +#ifdef SDF_LIB_SHARED + DSO_free(sdf_dso); + sdf_dso = NULL; +#endif +} + +static const SDF_METHOD *sdf_get_method(void) +{ + const SDF_METHOD *meth = &ts_sdf_meth; + +#ifdef SDF_LIB + if (RUN_ONCE(&sdf_lib_once, ossl_sdf_lib_init)) + meth = &sdfm; +#endif + + return meth; +} + +int TSAPI_SDF_OpenDevice(void **phDeviceHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->OpenDevice == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->OpenDevice(phDeviceHandle); +} + +int TSAPI_SDF_CloseDevice(void *hDeviceHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (hDeviceHandle == NULL) + return OSSL_SDR_OK; + + if (meth == NULL || meth->CloseDevice == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->CloseDevice(hDeviceHandle); +} + +int TSAPI_SDF_OpenSession(void *hDeviceHandle, void **phSessionHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->OpenSession == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->OpenSession(hDeviceHandle, phSessionHandle); +} + +int TSAPI_SDF_CloseSession(void *hSessionHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (hSessionHandle == NULL) + return OSSL_SDR_OK; + + if (meth == NULL || meth->CloseSession == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->CloseSession(hSessionHandle); +} + +int TSAPI_SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, + unsigned char *pucRandom) +{ +#define MAX_RANDOM_LEN (2048) + int ret; + unsigned int len; + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->GenerateRandom == NULL) + return OSSL_SDR_NOTSUPPORT; + + do { + if (uiLength > MAX_RANDOM_LEN) + len = MAX_RANDOM_LEN; + else + len = uiLength; + + if ((ret = meth->GenerateRandom(hSessionHandle, len, pucRandom)) != 0) + return ret; + + uiLength -= len; + pucRandom += len; + } while (uiLength > 0); + + return OSSL_SDR_OK; +} + +int TSAPI_SDF_GetPrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->GetPrivateKeyAccessRight == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->GetPrivateKeyAccessRight(hSessionHandle, uiKeyIndex, + pucPassword, uiPwdLength); +} + +int TSAPI_SDF_ReleasePrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->ReleasePrivateKeyAccessRight == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->ReleasePrivateKeyAccessRight(hSessionHandle, uiKeyIndex); +} + +int TSAPI_SDF_ImportKeyWithISK_ECC(void *hSessionHandle, + unsigned int uiISKIndex, + OSSL_ECCCipher *pucKey, + void **phKeyHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->ImportKeyWithISK_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->ImportKeyWithISK_ECC(hSessionHandle, uiISKIndex, pucKey, + phKeyHandle); +} + +int TSAPI_SDF_ImportKeyWithKEK(void *hSessionHandle, unsigned int uiAlgID, + unsigned int uiKEKIndex, unsigned char *pucKey, + unsigned int puiKeyLength, void **phKeyHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->ImportKeyWithKEK == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->ImportKeyWithKEK(hSessionHandle, uiAlgID, uiKEKIndex, pucKey, + puiKeyLength, phKeyHandle); +} + +int TSAPI_SDF_Encrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucData, unsigned int uiDataLength, + unsigned char *pucEncData, unsigned int *puiEncDataLength) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->Encrypt == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->Encrypt(hSessionHandle, hKeyHandle, uiAlgID, pucIV, pucData, + uiDataLength, pucEncData, puiEncDataLength); +} + +int TSAPI_SDF_Decrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucEncData, unsigned int uiEncDataLength, + unsigned char *pucData, unsigned int *puiDataLength) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->Decrypt == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->Decrypt(hSessionHandle, hKeyHandle, uiAlgID, pucIV, + pucEncData, uiEncDataLength, pucData, puiDataLength); +} + +int TSAPI_SDF_CalculateMAC(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucData, unsigned int uiDataLength, + unsigned char *pucMac, unsigned int *puiMACLength) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->CalculateMAC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->CalculateMAC(hSessionHandle, hKeyHandle, uiAlgID, pucIV, + pucData, uiDataLength, pucMac, puiMACLength); +} + +int TSAPI_SDF_GenerateKey(void *hSessionHandle, uint8_t type, uint8_t no_kek, + uint32_t len, void **pkey_handle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->GenerateKey == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->GenerateKey(hSessionHandle, type, no_kek, len, pkey_handle); +} + +int TSAPI_SDF_DestroyKey(void *hSessionHandle, void *hKeyHandle) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->DestroyKey == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->DestroyKey(hSessionHandle, hKeyHandle); +} + +int TSAPI_SDF_ExportSignPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->ExportSignPublicKey_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->ExportSignPublicKey_ECC(hSessionHandle, uiKeyIndex, pucPublicKey); +} + +int TSAPI_SDF_ExportEncPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->ExportEncPublicKey_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->ExportEncPublicKey_ECC(hSessionHandle, uiKeyIndex, pucPublicKey); +} + +int TSAPI_SDF_InternalEncrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCCipher *pucEncData) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->InternalEncrypt_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->InternalEncrypt_ECC(hSessionHandle, uiISKIndex, pucData, + uiDataLength, pucEncData); +} + +int TSAPI_SDF_InternalDecrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + OSSL_ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->InternalDecrypt_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->InternalDecrypt_ECC(hSessionHandle, uiISKIndex, pucEncData, + pucData, puiDataLength); +} + +int TSAPI_SDF_InternalSign_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCSignature *pucSignature) +{ + const SDF_METHOD *meth = sdf_get_method(); + + if (meth == NULL || meth->InternalSign_ECC == NULL) + return OSSL_SDR_NOTSUPPORT; + + return meth->InternalSign_ECC(hSessionHandle, uiISKIndex, pucData, + uiDataLength, pucSignature); +} diff --git a/crypto/sdf/sdf_local.h b/crypto/sdf/sdf_local.h new file mode 100644 index 000000000..f2187c504 --- /dev/null +++ b/crypto/sdf/sdf_local.h @@ -0,0 +1,130 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#ifndef OSSL_CRYPTO_SDF_LOCAL_H +# define OSSL_CRYPTO_SDF_LOCAL_H + +# include +# include + +# define OSSL_ECCref_MAX_BITS 512 +# define OSSL_ECCref_MAX_LEN ((OSSL_ECCref_MAX_BITS + 7) / 8) + +# pragma pack(1) +struct OSSL_ECCrefPrivateKey_st { + unsigned int bits; + unsigned char K[OSSL_ECCref_MAX_LEN]; +}; + +struct OSSL_ECCrefPublicKey_st{ + unsigned int bits; + unsigned char x[OSSL_ECCref_MAX_LEN]; + unsigned char y[OSSL_ECCref_MAX_LEN]; +}; + +struct OSSL_ECCCipher_st { + unsigned char x[OSSL_ECCref_MAX_LEN]; + unsigned char y[OSSL_ECCref_MAX_LEN]; + unsigned char M[32]; + unsigned int L; + unsigned char C[1]; +}; + +struct OSSL_ECCSignature_st { + unsigned char r[OSSL_ECCref_MAX_LEN]; + unsigned char s[OSSL_ECCref_MAX_LEN]; +}; +# pragma pack() + +typedef int (*SDF_OpenDevice_fn)(void **phDeviceHandle); +typedef int (*SDF_CloseDevice_fn)(void *hDeviceHandle); +typedef int (*SDF_OpenSession_fn)(void *hDeviceHandle, void **phSessionHandle); +typedef int (*SDF_CloseSession_fn)(void *hSessionHandle); +typedef int (*SDF_GenerateRandom_fn)(void *hSessionHandle, + unsigned int uiLength, unsigned char *pucRandom); + +typedef int (*SDF_GetPrivateKeyAccessRight_fn)(void *hSessionHandle, + unsigned int uiKeyIndex, unsigned char *pucPassword, + unsigned int uiPwdLength); + +typedef int (*SDF_ReleasePrivateKeyAccessRight_fn)(void *hSessionHandle, + unsigned int uiKeyIndex); + +typedef int (*SDF_ImportKeyWithISK_ECC_fn)(void *hSessionHandle, + unsigned int uiISKIndex, OSSL_ECCCipher *pucKey, void **phKeyHandle); + +typedef int (*SDF_ImportKeyWithKEK_fn)(void *hSessionHandle, + unsigned int uiAlgID, unsigned int uiKEKIndex, unsigned char *pucKey, + unsigned int puiKeyLength, void **phKeyHandle); + +typedef int (*SDF_DestroyKey_fn)(void *hSessionHandle, void *hKeyHandle); + +typedef int (*SDF_Encrypt_fn)(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_fn)(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_fn)(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_GenerateKey_fn)(void *hSessionHandle, uint8_t type, + uint8_t no_kek, uint32_t len, void **pkey_handle); + +typedef int (*SDF_ExportSignPublicKey_ECC_fn)(void *hSessionHandle, + unsigned int uiKeyIndex, OSSL_ECCrefPublicKey *pucPublicKey); + +typedef int (*SDF_ExportEncPublicKey_ECC_fn)(void *hSessionHandle, + unsigned int uiKeyIndex, OSSL_ECCrefPublicKey *pucPublicKey); + +typedef int (*SDF_InternalEncrypt_ECC_fn)(void *hSessionHandle, + unsigned int uiISKIndex, unsigned char *pucData, unsigned int uiDataLength, + OSSL_ECCCipher *pucEncData); +typedef int (*SDF_InternalDecrypt_ECC_fn)(void *hSessionHandle, + unsigned int uiISKIndex, OSSL_ECCCipher *pucEncData, unsigned char *pucData, + unsigned int *puiDataLength); + +typedef int (*SDF_InternalSign_ECC_fn)(void *hSessionHandle, + unsigned int uiISKIndex, unsigned char *pucData, unsigned int uiDataLength, + OSSL_ECCSignature *pucSignature); +/* + * Returns 0 for success, others for error code + */ +struct sdf_method_st { + SDF_OpenDevice_fn OpenDevice; + SDF_CloseDevice_fn CloseDevice; + SDF_OpenSession_fn OpenSession; + SDF_CloseSession_fn CloseSession; + SDF_GenerateRandom_fn GenerateRandom; + SDF_GetPrivateKeyAccessRight_fn GetPrivateKeyAccessRight; + SDF_ReleasePrivateKeyAccessRight_fn ReleasePrivateKeyAccessRight; + SDF_ImportKeyWithISK_ECC_fn ImportKeyWithISK_ECC; + SDF_ImportKeyWithKEK_fn ImportKeyWithKEK; + SDF_ExportSignPublicKey_ECC_fn ExportSignPublicKey_ECC; + SDF_ExportEncPublicKey_ECC_fn ExportEncPublicKey_ECC; + SDF_DestroyKey_fn DestroyKey; + SDF_InternalEncrypt_ECC_fn InternalEncrypt_ECC; + SDF_InternalDecrypt_ECC_fn InternalDecrypt_ECC; + SDF_InternalSign_ECC_fn InternalSign_ECC; + SDF_Encrypt_fn Encrypt; + SDF_Decrypt_fn Decrypt; + SDF_CalculateMAC_fn CalculateMAC; + + /* SDF Ext API */ + SDF_GenerateKey_fn GenerateKey; +}; + +extern SDF_METHOD ts_sdf_meth; +#endif diff --git a/crypto/sdf/sdf_meth.c b/crypto/sdf/sdf_meth.c new file mode 100644 index 000000000..d28bc8f8b --- /dev/null +++ b/crypto/sdf/sdf_meth.c @@ -0,0 +1,168 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#include +#include +#include "sdf_local.h" + +static int x_OpenDevice(void **phDeviceHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_CloseDevice(void *hDeviceHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_OpenSession(void *hDeviceHandle, void **phSessionHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_CloseSession(void *hSessionHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_GenerateRandom(void *hSessionHandle, unsigned int uiLength, + unsigned char *pucRandom) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_GetPrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_ReleasePrivateKeyAccessRight(void *hSessionHandlek, + unsigned int uiKeyIndex) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_ImportKeyWithISK_ECC(void *hSessionHandle, + unsigned int uiISKIndex, + OSSL_ECCCipher *pucKey, + void **phKeyHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + + +static int x_ImportKeyWithKEK(void *hSessionHandle, unsigned int uiAlgID, + unsigned int uiKEKIndex, unsigned char *pucKey, + unsigned int puiKeyLength, void **phKeyHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_ExportSignPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_ExportEncPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_DestroyKey(void *hSessionHandle, void *hKeyHandle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_InternalEncrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCCipher *pucEncData) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_InternalDecrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + OSSL_ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_InternalSign_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char * pucData, + unsigned int uiDataLength, + OSSL_ECCSignature *pucSignature) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_Encrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_Decrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucEncData, unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_CalculateMAC(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, + unsigned char *pucData, unsigned int uiDataLength, + unsigned char *pucMac, unsigned int *puiMACLength) +{ + return OSSL_SDR_NOTSUPPORT; +} + +static int x_GenerateKey(void *hSessionHandle, uint8_t type, uint8_t no_kek, + uint32_t len, void **pkey_handle) +{ + return OSSL_SDR_NOTSUPPORT; +} + +SDF_METHOD ts_sdf_meth = { + x_OpenDevice, + x_CloseDevice, + x_OpenSession, + x_CloseSession, + x_GenerateRandom, + x_GetPrivateKeyAccessRight, + x_ReleasePrivateKeyAccessRight, + x_ImportKeyWithISK_ECC, + x_ImportKeyWithKEK, + x_ExportSignPublicKey_ECC, + x_ExportEncPublicKey_ECC, + x_DestroyKey, + x_InternalEncrypt_ECC, + x_InternalDecrypt_ECC, + x_InternalSign_ECC, + x_Encrypt, + x_Decrypt, + x_CalculateMAC, + + /* SDF Ext API */ + x_GenerateKey, +}; diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index 177df5bac..d899318d3 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -392,6 +392,62 @@ int ossl_sm2_decrypt(const EC_KEY *key, return rc; } +unsigned char *ossl_sm2_ciphertext_encode(const BIGNUM *C1x, const BIGNUM *C1y, + const uint8_t *C2_data, size_t C2_len, + const uint8_t *C3_data, size_t C3_len, + size_t *ciphertext_len) +{ + unsigned char *ciphertext_buf = NULL; + struct SM2_Ciphertext_st ctext_struct; + int ciphertext_leni; + + if (C1x == NULL || C1y == NULL || C2_data == NULL || C3_data == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + memset(&ctext_struct, 0, sizeof(ctext_struct)); + + ctext_struct.C1x = (BIGNUM *)C1x; + ctext_struct.C1y = (BIGNUM *)C1y; + ctext_struct.C2 = ASN1_OCTET_STRING_new(); + + if (ctext_struct.C2 == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!ASN1_OCTET_STRING_set(ctext_struct.C2, C2_data, C2_len)) + goto end; + + ctext_struct.C3 = ASN1_OCTET_STRING_new(); + + if (ctext_struct.C3 == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3_data, C3_len)) + goto end; + + ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf); + /* Ensure cast to size_t is safe */ + if (ciphertext_leni < 0) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); + goto end; + } + *ciphertext_len = (size_t)ciphertext_leni; + + end: + if (ctext_struct.C2 != NULL) + ASN1_OCTET_STRING_free(ctext_struct.C2); + + if (ctext_struct.C3 != NULL) + ASN1_OCTET_STRING_free(ctext_struct.C3); + + return ciphertext_buf; +} + int ossl_sm2_ciphertext_decode(const uint8_t *ciphertext, size_t ciphertext_len, EC_POINT **C1p, uint8_t **C2_data, size_t *C2_len, uint8_t **C3_data, diff --git a/crypto/trace.c b/crypto/trace.c index d790409a2..051b72425 100644 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -138,7 +138,10 @@ static const struct trace_category_st trace_categories[] = { TRACE_CATEGORY_(STORE), TRACE_CATEGORY_(DECODER), TRACE_CATEGORY_(ENCODER), - TRACE_CATEGORY_(REF_COUNT) + TRACE_CATEGORY_(REF_COUNT), +#ifdef SMTC_MODULE + TRACE_CATEGORY_(SMTC), +#endif }; const char *OSSL_trace_get_category_name(int num) diff --git a/crypto/tsapi/build.info b/crypto/tsapi/build.info new file mode 100644 index 000000000..703ddc366 --- /dev/null +++ b/crypto/tsapi/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + tsapi_lib.c \ No newline at end of file diff --git a/crypto/tsapi/tsapi_lib.c b/crypto/tsapi/tsapi_lib.c new file mode 100644 index 000000000..b022a07bf --- /dev/null +++ b/crypto/tsapi/tsapi_lib.c @@ -0,0 +1,1322 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#include "internal/deprecated.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/e_os.h" +#include "crypto/rand.h" +#include "crypto/sm2.h" +#include "../sdf/sdf_local.h" +#ifdef SDF_LIB +# include "sdfe_api.h" +#endif + +unsigned char *TSAPI_GetEntropy(int entropy, size_t *outlen) +{ + unsigned char *out = NULL; + size_t len; + + len = ossl_rand_get_entropy(NULL, &out, entropy, entropy, entropy * 4); + if (len == 0) { + *outlen = 0; + return NULL; + } + + *outlen = len; + return out; +} + +void TSAPI_FreeEntropy(unsigned char *ent, size_t len) +{ + ossl_rand_cleanup_entropy(NULL, ent, len); +} + +unsigned char *TSAPI_RandBytes(size_t len) +{ + unsigned char *buf = OPENSSL_malloc(len); + + if (buf == NULL) + return NULL; + + if (RAND_bytes(buf, (int)len) <= 0) { + OPENSSL_free(buf); + return NULL; + } + + return buf; +} + +char *TSAPI_Version(void) +{ + int ret; + int buflen = 1 + strlen(OpenSSL_version(TONGSUO_VERSION)) + 1 +#ifdef SMTC_MODULE + + strlen(OpenSSL_version(TONGSUO_SMTC_INFO)) + 1 +#endif + ; + char *buf = OPENSSL_malloc(buflen); + + ret = BIO_snprintf((char *)buf, buflen, "%s\n", + OpenSSL_version(TONGSUO_VERSION)); + if (ret < 0) { + OPENSSL_free(buf); + return NULL; + } + +#ifdef SMTC_MODULE + ret = BIO_snprintf(buf + ret, buflen - ret, "%s\n", + OpenSSL_version(TONGSUO_SMTC_INFO)); + if (ret < 0) { + OPENSSL_free(buf); + return NULL; + } +#endif + + return buf; +} + +#ifndef OPENSSL_NO_SM2 +int TSAPI_DelSm2KeyWithIndex(int index, int sign, const char *user, + const char *password) +{ + int ok = 0; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + int area; + + if (sign) { + area = SDFE_ASYM_KEY_AREA_SIGN; + } else { + area = SDFE_ASYM_KEY_AREA_ENC; + } + + memset(&login_arg, 0, sizeof(login_arg)); + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + if (SDFE_DelECCKey(hSessionHandle, area, index) + != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +int TSAPI_GenerateSM2KeyWithIndex(int index, int sign, const char *user, + const char *password) +{ + int ok = 0; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + int area; + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + memset(&login_arg, 0, sizeof(login_arg)); + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + if (SDFE_GenECCKey(hSessionHandle, area, index, 0, NULL) != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +EVP_PKEY *TSAPI_EVP_PKEY_new_from_ECCrefKey(const OSSL_ECCrefPublicKey *pubkey, + const OSSL_ECCrefPrivateKey *privkey) +{ + int ok = 0; + EC_KEY *eckey = NULL; + EC_GROUP *group = NULL; + BN_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + BIGNUM *x = NULL, *y = NULL; + int bytes; + + if (pubkey == NULL) + return NULL; + + eckey = EC_KEY_new(); + if (eckey == NULL) + return NULL; + + group = EC_GROUP_new_by_curve_name(NID_sm2); + if (group == NULL) + goto end; + + if (!EC_KEY_set_group(eckey, group)) + goto end; + + bytes = (pubkey->bits + 7) / 8; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto end; + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + + if (BN_bin2bn(pubkey->x + sizeof(pubkey->x) - bytes, bytes, x) == NULL) + goto end; + + if (BN_bin2bn(pubkey->y + sizeof(pubkey->y) - bytes, bytes, y) == NULL) + goto end; + + if (!EC_KEY_set_public_key_affine_coordinates(eckey, x, y)) + goto end; + + if (privkey) { + bytes = (privkey->bits + 7) / 8; + if (BN_bin2bn(privkey->K + sizeof(privkey->K) - bytes, bytes, x) == NULL) + goto end; + + if (!EC_KEY_set_private_key(eckey, x)) + goto end; + } + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + goto end; + + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) + goto end; + + eckey = NULL; + + ok = 1; +end: + if (!ok) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_GROUP_free(group); + EC_KEY_free(eckey); + return pkey; +} + +OSSL_ECCrefPublicKey *TSAPI_EVP_PKEY_get_ECCrefPublicKey(const EVP_PKEY *pkey) +{ + int ok = 0; + const EC_KEY *eckey = NULL; + const EC_GROUP *group = NULL; + const EC_POINT *point = NULL; + BIGNUM *x = NULL, *y = NULL; + BN_CTX *ctx = NULL; + OSSL_ECCrefPublicKey *outkey = NULL; + + if (pkey == NULL) + return NULL; + + eckey = EVP_PKEY_get0_EC_KEY(pkey); + if (eckey == NULL) + return NULL; + + group = EC_KEY_get0_group(eckey); + point = EC_KEY_get0_public_key(eckey); + if (group == NULL || point == NULL) + return NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + return NULL; + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto end; + + if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx)) + goto end; + + outkey = OPENSSL_zalloc(sizeof(*outkey)); + if (outkey == NULL) + goto end; + + outkey->bits = EVP_PKEY_get_bits(pkey); + + if (BN_bn2bin(x, outkey->x + sizeof(outkey->x) - BN_num_bytes(x)) < 0) + goto end; + if (BN_bn2bin(y, outkey->y + sizeof(outkey->y) - BN_num_bytes(y)) < 0) + goto end; + + ok = 1; +end: + if (!ok) { + OPENSSL_free(outkey); + outkey = NULL; + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return outkey; +} + +OSSL_ECCrefPrivateKey *TSAPI_EVP_PKEY_get_ECCrefPrivateKey(const EVP_PKEY *pkey) +{ + int ok = 0; + const EC_KEY *eckey = NULL; + const BIGNUM *priv = NULL; + OSSL_ECCrefPrivateKey *outkey = NULL; + + if (pkey == NULL) + return NULL; + + eckey = EVP_PKEY_get0_EC_KEY(pkey); + if (eckey == NULL) + return NULL; + + priv = EC_KEY_get0_private_key(eckey); + if (priv == NULL) + return NULL; + + outkey = OPENSSL_zalloc(sizeof(*outkey)); + if (outkey == NULL) + goto end; + + outkey->bits = EVP_PKEY_get_bits(pkey); + + if (BN_bn2bin(priv, outkey->K + sizeof(outkey->K) - BN_num_bytes(priv)) < 0) + goto end; + + ok = 1; +end: + if (!ok) { + OPENSSL_free(outkey); + outkey = NULL; + } + return outkey; +} + +int TSAPI_ImportSM2Key(int index, int sign, const char *user, + const char *password, const EVP_PKEY *sm2_pkey) +{ + int ok = 0; +#ifdef SDF_LIB + int area; + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCrefPrivateKey *privkey = NULL; + OSSL_ECCrefPublicKey *pubkey = NULL; + sdfe_asym_key_ecc_t sm2_key; + sdfe_login_arg_t login_arg; + + memset(&login_arg, 0, sizeof(login_arg)); + memset(&sm2_key, 0, sizeof(sm2_key)); + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + privkey = TSAPI_EVP_PKEY_get_ECCrefPrivateKey(sm2_pkey); + if (privkey == NULL) + goto end; + + pubkey = TSAPI_EVP_PKEY_get_ECCrefPublicKey(sm2_pkey); + if (pubkey == NULL) + goto end; + + sm2_key.area = area; + sm2_key.index = index; + sm2_key.type = SDFE_ASYM_KEY_TYPE_SM2; + sm2_key.privkey_bits = 256; + sm2_key.privkey_len = sm2_key.privkey_bits >> 3; + sm2_key.pubkey_bits = 256; + sm2_key.pubkey_len = (sm2_key.pubkey_bits >> 3) << 1; + + memcpy(sm2_key.pubkey, pubkey, sizeof(*pubkey)); + memcpy(sm2_key.privkey, privkey, sizeof(*privkey)); + + if (SDFE_ImportECCKey(hSessionHandle, &sm2_key, NULL) + != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +int TSAPI_ImportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, unsigned char *key, + size_t keylen, unsigned char *dek, size_t deklen) +{ + int ok = 0; +#ifdef SDF_LIB + int area; + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_asym_key_ecc_t sm2_key; + sdfe_sym_key_evlp_t sym_key_evlp; + sdfe_login_arg_t login_arg; + + memset(&login_arg, 0, sizeof(login_arg)); + memset(&sm2_key, 0, sizeof(sm2_key)); + memset(&sym_key_evlp, 0, sizeof(sym_key_evlp)); + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + sym_key_evlp.flags = SDFE_SYM_KEY_EVLP_F_IMPORT_KEY_INDEX_VALID; + sym_key_evlp.asym_key_type = SDFE_ASYM_KEY_TYPE_SM2; + sym_key_evlp.sym_key_type = SDFE_SYM_KEY_TYPE_SM4; + sym_key_evlp.sym_key_len = 16; + sym_key_evlp.asym_key_index = 0; + + if (deklen > sizeof(sym_key_evlp.data)) + goto end; + sym_key_evlp.data_len = deklen; + memcpy(sym_key_evlp.data, dek, deklen); + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + sm2_key.area = area; + sm2_key.index = index; + sm2_key.type = SDFE_ASYM_KEY_TYPE_SM2; + sm2_key.privkey_bits = 256; + sm2_key.privkey_len = sm2_key.privkey_bits >> 3; + sm2_key.pubkey_bits = 256; + sm2_key.pubkey_len = (sm2_key.pubkey_bits >> 3) << 1; + + if (keylen != sizeof(sm2_key.privkey) + sizeof(sm2_key.pubkey)) + goto end; + + memcpy(sm2_key.pubkey, key, sizeof(sm2_key.pubkey)); + memcpy(sm2_key.privkey, key + sizeof(sm2_key.pubkey), + sizeof(sm2_key.privkey)); + + if (SDFE_ImportECCKeyWithEvlp(hSessionHandle, &sm2_key, &sym_key_evlp, NULL) + != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +int TSAPI_ExportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, EVP_PKEY *sm2_pkey, + unsigned char **priv, size_t *privlen, + unsigned char **pub, size_t *publen, + unsigned char **outevlp, size_t *outevlplen) + +{ + int ok = 0; +#ifdef SDF_LIB + int area; + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCrefPublicKey *pubkey = NULL; + sdfe_asym_key_ecc_t sm2_key; + sdfe_sym_key_evlp_t sym_key_evlp; + sdfe_login_arg_t login_arg; + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + memset(&login_arg, 0, sizeof(login_arg)); + memset(&sm2_key, 0, sizeof(sm2_key)); + memset(&sym_key_evlp, 0, sizeof(sym_key_evlp)); + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + sm2_key.area = area; + sm2_key.index = index; + sm2_key.type = SDFE_ASYM_KEY_TYPE_SM2; + + sym_key_evlp.asym_key_type = SDFE_ASYM_KEY_TYPE_SM2; + sym_key_evlp.sym_key_type = SDFE_SYM_KEY_TYPE_SM4; + sym_key_evlp.sym_key_len = 16; + + pubkey = TSAPI_EVP_PKEY_get_ECCrefPublicKey(sm2_pkey); + if (pubkey == NULL) + goto end; + + if (SDFE_ExportECCKeyWithEvlp(hSessionHandle, &sm2_key, &sym_key_evlp, + (void *)pubkey) != OSSL_SDR_OK) + goto end; + + *outevlp = OPENSSL_malloc(sym_key_evlp.data_len); + if (*outevlp == NULL) + goto end; + + memcpy(*outevlp, sym_key_evlp.data, sym_key_evlp.data_len); + *outevlplen = sym_key_evlp.data_len; + + *priv = OPENSSL_malloc(sizeof(sm2_key.privkey)); + if (*priv == NULL) + goto end; + + memcpy(*priv, sm2_key.privkey, sizeof(sm2_key.privkey)); + *privlen = sizeof(sm2_key.privkey); + + *pub = OPENSSL_malloc(sizeof(sm2_key.pubkey)); + if (*pub == NULL) + goto end; + + memcpy(*pub, sm2_key.pubkey, sizeof(sm2_key.pubkey)); + *publen = sizeof(sm2_key.pubkey); + + ok = 1; +end: + if (!ok) { + OPENSSL_free(*priv); + OPENSSL_free(*pub); + OPENSSL_free(*outevlp); + *priv = NULL; + *pub = NULL; + *outevlp = NULL; + *privlen = 0; + *publen = 0; + *outevlplen = 0; + } + + OPENSSL_free(pubkey); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +EVP_PKEY *TSAPI_ExportSM2KeyWithIndex(int index, int sign, const char *user, + const char *password) +{ + EVP_PKEY *pkey = NULL; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + int area; + OSSL_ECCrefPrivateKey privkey; + OSSL_ECCrefPublicKey pubkey; + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + memset(&login_arg, 0, sizeof(login_arg)); + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + if (SDFE_ExportECCPrivKey(hSessionHandle, area, index, 0, NULL, + (ECCrefPrivateKey *)&privkey) != OSSL_SDR_OK) + goto end; + + if (sign && TSAPI_SDF_ExportSignPublicKey_ECC(hSessionHandle, index, + &pubkey) != OSSL_SDR_OK) + goto end; + + if (!sign && TSAPI_SDF_ExportEncPublicKey_ECC(hSessionHandle, index, + &pubkey) != OSSL_SDR_OK) + goto end; + + pkey = TSAPI_EVP_PKEY_new_from_ECCrefKey(&pubkey, &privkey); + if (pkey == NULL) + goto end; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return pkey; +} + +EVP_PKEY *TSAPI_ExportSM2PubKeyWithIndex(int index, int sign) +{ + EVP_PKEY *pkey = NULL; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCrefPublicKey pubkey; + EC_GROUP *group = NULL; + EC_KEY *eckey = NULL; + BIGNUM *x = NULL, *y = NULL; + int nbytes; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (sign) { + if (TSAPI_SDF_ExportSignPublicKey_ECC(hSessionHandle, index, &pubkey) + != OSSL_SDR_OK) + goto end; + } else { + if (TSAPI_SDF_ExportEncPublicKey_ECC(hSessionHandle, index, &pubkey) + != OSSL_SDR_OK) + goto end; + } + + group = EC_GROUP_new_by_curve_name(NID_sm2); + if (group == NULL) + goto end; + + eckey = EC_KEY_new(); + if (eckey == NULL) + goto end; + + EC_KEY_set_group(eckey, group); + + nbytes = (pubkey.bits + 7) / 8; + + x = BN_bin2bn(pubkey.x + sizeof(pubkey.x) - nbytes, nbytes, NULL); + if (x == NULL) + goto end; + + y = BN_bin2bn(pubkey.y + sizeof(pubkey.y) - nbytes, nbytes, NULL); + if (y == NULL) + goto end; + + if (!EC_KEY_set_public_key_affine_coordinates(eckey, x, y)) + goto end; + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + goto end; + + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) { + EVP_PKEY_free(pkey); + goto end; + } + eckey = NULL; + +end: + EC_KEY_free(eckey); + EC_GROUP_free(group); + BN_free(x); + BN_free(y); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return pkey; +} + +int TSAPI_UpdateSm2KeyWithIndex(int index, int sign, const char *user, const char *password) +{ + int ok = 0; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + int area; + + if (sign) + area = SDFE_ASYM_KEY_AREA_SIGN; + else + area = SDFE_ASYM_KEY_AREA_ENC; + + memset(&login_arg, 0, sizeof(login_arg)); + + if (user) { + if (strlen(user) >= sizeof(login_arg.name)) + return 0; + + strcpy((char *)login_arg.name, user); + } + + login_arg.passwd = (uint8_t *)password; + if (password) + login_arg.passwd_len = strlen(password); + else + login_arg.passwd_len = 0; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + if (SDFE_DelECCKey(hSessionHandle, area, index) + != OSSL_SDR_OK) + goto end; + + if (SDFE_GenECCKey(hSessionHandle, area, index, 0, NULL) + != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return ok; +} + +EVP_PKEY *TSAPI_SM2Keygen(void) +{ + return EVP_PKEY_Q_keygen(NULL, NULL, "SM2"); +} + +# ifndef OPENSSL_NO_SM3 +int TSAPI_SM2Verify(EVP_PKEY *key, const unsigned char *tbs, size_t tbslen, + const unsigned char *sig, size_t siglen) +{ + int ok = 0; + EVP_MD_CTX *ctx = NULL; + + if (key == NULL || tbs == NULL || sig == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return 0; + + if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sm3(), NULL, key) + || EVP_DigestVerify(ctx, sig, siglen, tbs, tbslen) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + + ok = 1; +end: + EVP_MD_CTX_free(ctx); + return ok; +} + +unsigned char *TSAPI_SM2Sign(EVP_PKEY *key, const unsigned char *tbs, + size_t tbslen, size_t *siglen) +{ + unsigned char *sig = NULL; + size_t len; + EVP_MD_CTX *ctx = NULL; + + if (key == NULL || tbs == NULL || siglen == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return NULL; + + if (!EVP_DigestSignInit(ctx, NULL, EVP_sm3(), NULL, key) + || !EVP_DigestSign(ctx, NULL, &len, tbs, tbslen)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + + sig = OPENSSL_malloc(len); + if (sig == NULL) + goto end; + + if (!EVP_DigestSign(ctx, sig, &len, tbs, tbslen)) { + OPENSSL_free(sig); + *siglen = 0; + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + + *siglen = len; +end: + EVP_MD_CTX_free(ctx); + return sig; +} +# endif + +static unsigned char *do_SM2Crypt(int enc, EVP_PKEY *key, + const unsigned char *in, size_t inlen, + size_t *outlen) +{ + EVP_PKEY_CTX *ctx = NULL; + size_t len = 0; + unsigned char *out = NULL; + + if (key == NULL || in == NULL || outlen == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (enc) { + ctx = EVP_PKEY_CTX_new_from_pkey_provided(NULL, key, NULL); + } else { + ctx = EVP_PKEY_CTX_new(key, NULL); + } + + if (ctx == NULL) + return NULL; + + if (enc) { + if (EVP_PKEY_encrypt_init(ctx) <= 0 + || EVP_PKEY_encrypt(ctx, NULL, &len, in, inlen) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + } else { + if (EVP_PKEY_decrypt_init(ctx) <= 0 + || EVP_PKEY_decrypt(ctx, NULL, &len, in, inlen) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + } + + out = OPENSSL_malloc(len); + if (out == NULL) + goto end; + + if (enc) { + if (EVP_PKEY_encrypt(ctx, out, &len, in, inlen) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + OPENSSL_free(out); + out = NULL; + len = 0; + } + } else { + if (EVP_PKEY_decrypt(ctx, out, &len, in, inlen) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + OPENSSL_free(out); + out = NULL; + len = 0; + } + } + + *outlen = len; +end: + EVP_PKEY_CTX_free(ctx); + return out; +} + +unsigned char *TSAPI_SM2DecryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen) +{ + unsigned char *out = NULL; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCCipher *ecc = NULL; + unsigned int len; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + return NULL; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_GetPrivateKeyAccessRight(hSessionHandle, isk, NULL, 0) + != OSSL_SDR_OK) + goto end; + + ecc = TSAPI_SM2Ciphertext_to_ECCCipher(in, inlen); + if (ecc == NULL) + goto end; + + len = ecc->L; + out = OPENSSL_malloc(len); + if (out == NULL) + goto end; + + if (TSAPI_SDF_InternalDecrypt_ECC(hSessionHandle, isk, ecc, out, &len) + != OSSL_SDR_OK) { + OPENSSL_free(out); + out = NULL; + *outlen = 0; + goto end; + } + + *outlen = len; +end: + OPENSSL_free(ecc); + TSAPI_SDF_ReleasePrivateKeyAccessRight(hSessionHandle, isk); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return out; +} + +unsigned char *TSAPI_SM2EncryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen) +{ + unsigned char *out = NULL; +#ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCCipher *ecc = NULL; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + return NULL; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + ecc = OPENSSL_zalloc(sizeof(OSSL_ECCCipher) + inlen); + if (ecc == NULL) + goto end; + + if (TSAPI_SDF_InternalEncrypt_ECC(hSessionHandle, isk, (unsigned char *)in, + inlen, ecc) + != OSSL_SDR_OK) + goto end; + + out = TSAPI_ECCCipher_to_SM2Ciphertext(ecc, outlen); + +end: + OPENSSL_free(ecc); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +#endif + return out; +} + +unsigned char *TSAPI_SM2Encrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen) +{ + return do_SM2Crypt(1, key, in, inlen, outlen); +} + +unsigned char *TSAPI_SM2Decrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen) +{ + return do_SM2Crypt(0, key, in, inlen, outlen); +} + +unsigned char *TSAPI_ECCCipher_to_SM2Ciphertext(const OSSL_ECCCipher *ecc, + size_t *ciphertext_len) +{ + BIGNUM *x = NULL, *y = NULL; + unsigned char *out = NULL; + + if (ecc == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((x = BN_bin2bn(ecc->x, sizeof(ecc->x), NULL)) == NULL + || (y = BN_bin2bn(ecc->y, sizeof(ecc->y), NULL)) == NULL) + goto end; + + out = ossl_sm2_ciphertext_encode(x, y, ecc->C, ecc->L, ecc->M, + sizeof(ecc->M), ciphertext_len); +end: + BN_free(x); + BN_free(y); + return out; + +} + +OSSL_ECCCipher *TSAPI_SM2Ciphertext_to_ECCCipher(const unsigned char *ciphertext, + size_t ciphertext_len) +{ + int ok = 0; + EC_POINT *C1 = NULL; + uint8_t *C2_data = NULL, *C3_data = NULL; + size_t C2_len, C3_len; + EC_GROUP *group = NULL; + BN_CTX *ctx = NULL; + BIGNUM *Cx = NULL, *Cy = NULL; + OSSL_ECCCipher *ecc = NULL; + + if (ciphertext == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!ossl_sm2_ciphertext_decode(ciphertext, ciphertext_len, &C1, &C2_data, + &C2_len, &C3_data, &C3_len)) + goto end; + + ecc = OPENSSL_zalloc(sizeof(OSSL_ECCCipher) + C2_len); + if (ecc == NULL) + goto end; + + if (C3_len != sizeof(ecc->M)) + goto end; + + memcpy(ecc->M, C3_data, C3_len); + ecc->L = C2_len; + memcpy(ecc->C, C2_data, C2_len); + + group = EC_GROUP_new_by_curve_name(NID_sm2); + if (group == NULL) + goto end; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto end; + + BN_CTX_start(ctx); + Cx = BN_CTX_get(ctx); + Cy = BN_CTX_get(ctx); + if (Cy == NULL) + goto end; + + if (!EC_POINT_get_affine_coordinates(group, C1, Cx, Cy, NULL)) + goto end; + + if (BN_bn2bin(Cx, ecc->x + sizeof(ecc->x) - BN_num_bytes(Cx)) + != BN_num_bytes(Cx) + || BN_bn2bin(Cy, ecc->y + sizeof(ecc->y) - BN_num_bytes(Cy)) + != BN_num_bytes(Cy)) + goto end; + + ok = 1; +end: + if (!ok) { + OPENSSL_free(ecc); + ecc = NULL; + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(C1); + OPENSSL_free(C2_data); + OPENSSL_free(C3_data); + return ecc; + +} +#endif + +#ifndef OPENSSL_NO_SM4 +static unsigned char *do_SM4Crypt(int mode, int enc, + const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen) +{ +# ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + void *hkeyHandle = NULL; + OSSL_ECCCipher *ecc = NULL; +# endif + const EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char *outbuf = NULL; + unsigned int len = 0; + int lenf = 0; + size_t max_out_len; + + if (isk < 0) { + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return 0; + + if (mode == OSSL_SGD_MODE_ECB) + cipher = EVP_sm4_ecb(); + else if (mode == OSSL_SGD_MODE_CBC) + cipher = EVP_sm4_cbc(); + else if (mode == OSSL_SGD_MODE_CFB) + cipher = EVP_sm4_cfb(); + else if (mode == OSSL_SGD_MODE_OFB) + cipher = EVP_sm4_ofb(); + else if (mode == OSSL_SGD_MODE_CTR) + cipher = EVP_sm4_ctr(); + else + goto end; + + if (!EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc) + || !EVP_CIPHER_CTX_set_padding(ctx, 0)) + goto end; + + max_out_len = inlen + EVP_CIPHER_CTX_get_block_size(ctx); + + outbuf = OPENSSL_malloc(max_out_len); + if (outbuf == NULL) + goto end; + + if (!EVP_CipherUpdate(ctx, outbuf, (int *)&len, in, inlen)) { + OPENSSL_free(outbuf); + outbuf = NULL; + len = 0; + goto end; + } + + if (!EVP_CipherFinal_ex(ctx, outbuf + len, &lenf)) { + OPENSSL_free(outbuf); + outbuf = NULL; + len = 0; + goto end; + } + + len += lenf; + } +# ifdef SDF_LIB + else { + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_GetPrivateKeyAccessRight(hSessionHandle, isk, NULL, 0) + != OSSL_SDR_OK) + goto end; + + ecc = TSAPI_SM2Ciphertext_to_ECCCipher(key, keylen); + if (ecc == NULL) + goto end; + + if (TSAPI_SDF_ImportKeyWithISK_ECC(hSessionHandle, isk, ecc, &hkeyHandle) + != OSSL_SDR_OK) + goto end; + + outbuf = (unsigned char *)OPENSSL_malloc(inlen) + 128; + if (outbuf == NULL) + goto end; + + if (enc) { + if (TSAPI_SDF_Encrypt(hSessionHandle, hkeyHandle, + OSSL_SGD_SM4 | mode, + (unsigned char *)iv, (unsigned char *)in, + inlen, outbuf, &len) != OSSL_SDR_OK) { + OPENSSL_free(outbuf); + outbuf = NULL; + goto end; + } + } else { + if (TSAPI_SDF_Decrypt(hSessionHandle, hkeyHandle, + OSSL_SGD_SM4 | mode, + (unsigned char *)iv, (unsigned char *)in, + inlen, outbuf, &len) != OSSL_SDR_OK) { + OPENSSL_free(outbuf); + outbuf = NULL; + goto end; + } + } + } +# endif + *outlen = len; +end: + EVP_CIPHER_CTX_free(ctx); +# ifdef SDF_LIB + if (isk >= 0) { + TSAPI_SDF_DestroyKey(hSessionHandle, hkeyHandle); + TSAPI_SDF_ReleasePrivateKeyAccessRight(hSessionHandle, isk); + OPENSSL_free(ecc); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); + } +# endif + return outbuf; +} + +unsigned char *TSAPI_SM4Decrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen) +{ + return do_SM4Crypt(mode, 0, key, keylen, isk, iv, in, inlen, outlen); +} + +unsigned char *TSAPI_SM4Encrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen) +{ + return do_SM4Crypt(mode, 1, key, keylen, isk, iv, in, inlen, outlen); +} +#endif + +#ifndef OPENSSL_NO_SM3 +unsigned char *TSAPI_SM3(const void *data, size_t datalen, size_t *outlen) +{ + EVP_MD_CTX *ctx = NULL; + unsigned char *out = NULL; + unsigned int len = 0; + + if (data == NULL || outlen == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return NULL; + + if (!EVP_DigestInit_ex(ctx, EVP_sm3(), NULL) + || !EVP_DigestUpdate(ctx, data, datalen)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + goto end; + } + + out = OPENSSL_malloc(EVP_MD_CTX_get_size(ctx)); + if (out == NULL) + goto end; + + if (!EVP_DigestFinal_ex(ctx, out, &len)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_EVP_LIB); + OPENSSL_free(out); + out = NULL; + len = 0; + } + + *outlen = len; +end: + EVP_MD_CTX_free(ctx); + return out; +} +#endif diff --git a/crypto/x509/v3_skid.c b/crypto/x509/v3_skid.c index 18223f2ef..8a80a4d46 100644 --- a/crypto/x509/v3_skid.c +++ b/crypto/x509/v3_skid.c @@ -69,7 +69,11 @@ ASN1_OCTET_STRING *ossl_x509_pubkey_hash(X509_PUBKEY *pubkey) } if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)) return NULL; - if ((md = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL) +#ifdef SMTC_MODULE + if ((md = EVP_MD_fetch(libctx, SN_sm3, propq)) == NULL) +#else + if ((md = EVP_MD_fetch(libctx, SN_sha1, NULL)) == NULL) +#endif return NULL; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { EVP_MD_free(md); diff --git a/include/crypto/rand.h b/include/crypto/rand.h index fa3b5b2b9..7b062cf93 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -32,6 +32,18 @@ # endif # endif +#define RAND_ENTROPY_SOURCE_GETRANDOM 0x0001 +#define RAND_ENTROPY_SOURCE_DEVRANDOM 0x0002 +#define RAND_ENTROPY_SOURCE_RDTSC 0x0004 +#define RAND_ENTROPY_SOURCE_RDCPU 0x0008 +#define RAND_ENTROPY_SOURCE_EGD 0x0010 +#define RAND_ENTROPY_SOURCE_BCRYPTGENRANDOM 0x0020 +#define RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_DEF_PROV 0x0040 +#define RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_INTEL_PROV 0x0080 +#define RAND_ENTROPY_SOURCE_RTCODE 0x0100 +#define RAND_ENTROPY_SOURCE_RTMEM 0x0200 +#define RAND_ENTROPY_SOURCE_RTSOCK 0x0400 + /* * Defines related to seed sources */ @@ -111,6 +123,9 @@ void ossl_random_add_conf_module(void); size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle, unsigned char **pout, int entropy, size_t min_len, size_t max_len); +size_t ossl_rand_get_entropy_from_source(unsigned int source, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len); size_t ossl_rand_get_nonce(ossl_unused OSSL_CORE_HANDLE *handle, diff --git a/include/crypto/rand_pool.h b/include/crypto/rand_pool.h index f4d1d954b..7be677965 100644 --- a/include/crypto/rand_pool.h +++ b/include/crypto/rand_pool.h @@ -32,9 +32,15 @@ * The factor 1.5 below is the pessimistic estimate for the extra amount * of entropy required when no get_nonce() callback is defined. */ -# define RAND_POOL_FACTOR 256 -# define RAND_POOL_MAX_LENGTH (RAND_POOL_FACTOR * \ - 3 * (RAND_DRBG_STRENGTH / 16)) + +# ifdef TONGSUO_RAND_GM_SRNG +/* As required by GM/T 0105-2021 section 5.3 */ +# define RAND_POOL_MAX_LENGTH 4096 +# else +# define RAND_POOL_FACTOR 256 +# define RAND_POOL_MAX_LENGTH (RAND_POOL_FACTOR * \ + 3 * (RAND_DRBG_STRENGTH / 16)) +# endif /* * = (RAND_POOL_FACTOR * \ * 1.5 * (RAND_DRBG_STRENGTH / 8)) @@ -57,7 +63,12 @@ * with 40 bytes. The value of forty eight is comfortably above this which * allows some slack in the platform specific values used. */ -# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48) +# ifdef TONGSUO_RAND_GM_SRNG +/* GM/T 0105-2021 DRNG requires the entropy pool should at least 512 bytes. */ +# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 512 : 1024) +# else +# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48) +# endif /* * The 'random pool' acts as a dumb container for collecting random @@ -80,6 +91,8 @@ typedef struct rand_pool_st { size_t alloc_len; /* current number of bytes allocated */ size_t entropy; /* current entropy count in bits */ size_t entropy_requested; /* requested entropy count in bits */ + + unsigned int entropy_source; } RAND_POOL; RAND_POOL *ossl_rand_pool_new(int entropy_requested, int secure, @@ -105,5 +118,5 @@ int ossl_rand_pool_add(RAND_POOL *pool, const unsigned char *buffer, size_t len, size_t entropy); unsigned char *ossl_rand_pool_add_begin(RAND_POOL *pool, size_t len); int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy); - +void ossl_rand_pool_set_default_entropy_source(unsigned int source); #endif /* OSSL_PROVIDER_RAND_POOL_H */ diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h index 108d821fb..22c9f7da8 100644 --- a/include/crypto/sm2.h +++ b/include/crypto/sm2.h @@ -79,6 +79,11 @@ int ossl_sm2_decrypt(const EC_KEY *key, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len); +unsigned char *ossl_sm2_ciphertext_encode(const BIGNUM *C1x, const BIGNUM *C1y, + const uint8_t *C2_data, size_t C2_len, + const uint8_t *C3_data, size_t C3_len, + size_t *ciphertext_len); + int ossl_sm2_ciphertext_decode(const uint8_t *ciphertext, size_t ciphertext_len, EC_POINT **C1p, uint8_t **C2p, size_t *C2_len, uint8_t **C3p, size_t *C3_len); diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index bfd035781..be81384db 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -70,6 +70,11 @@ DEFINE_LHASH_OF(MEM); # define X509_PRIVATE_DIR OPENSSLDIR "/private" # define CTLOG_FILE OPENSSLDIR "/ct_log_list.cnf" +# ifdef SMTC_MODULE +# define SMTC_MODULE_CONF OPENSSLDIR "/smtcmodule.cnf" +# define SMTC_AUTH_KEK OPENSSLDIR "/auth_kek.pem" +# endif + # define X509_CERT_DIR_EVP "SSL_CERT_DIR" # define X509_CERT_FILE_EVP "SSL_CERT_FILE" # define CTLOG_FILE_EVP "CTLOG_FILE" diff --git a/include/internal/provider.h b/include/internal/provider.h index d09829d05..585bbbf34 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -87,6 +87,8 @@ int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, OSSL_CALLBACK *cb, void *arg); +int ossl_provider_reset(OSSL_PROVIDER *prov); +int ossl_provider_status(const OSSL_PROVIDER *prov); int ossl_provider_self_test(const OSSL_PROVIDER *prov); const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, diff --git a/include/internal/sdf.h b/include/internal/sdf.h new file mode 100644 index 000000000..028f211e3 --- /dev/null +++ b/include/internal/sdf.h @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#ifndef OSSL_INTERNAL_SDF_H +# define OSSL_INTERNAL_SDF_H +# pragma once + +void ossl_sdf_lib_cleanup(void); + +#endif diff --git a/include/internal/smtc_names.h b/include/internal/smtc_names.h index fe67aae5c..0f934fd6e 100644 --- a/include/internal/smtc_names.h +++ b/include/internal/smtc_names.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Tongsuo Project Authors. All Rights Reserved. + * Copyright 2023-2024 The Tongsuo Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,17 +13,19 @@ # include -# define OSSL_PROV_SMTC_PARAM_MODULE_PATH "module-path" -# define OSSL_PROV_SMTC_PARAM_MODULE_MAC "module-mac" -# define OSSL_PROV_SMTC_PARAM_ADMIN_PASS "admin-pass" -# define OSSL_PROV_SMTC_PARAM_ADMIN_SALT "admin-salt" -# define OSSL_PROV_SMTC_PARAM_SHOW_SELFTEST "show-selftest" -# define OSSL_PROV_SMTC_PARAM_RNG_POWERON_TEST "rng-poweron-test" -# define OSSL_PROV_SMTC_PARAM_RNG_CONTINUOUS_TEST "rng-continuous-test" +# define OSSL_PROV_SMTC_PARAM_MODULE_PATH "module-path" +# define OSSL_PROV_SMTC_PARAM_MODULE_SIG "module-sig" +# define OSSL_PROV_SMTC_PARAM_AUTH_KEY "auth-key" +# define OSSL_PROV_SMTC_PARAM_AUTH_SALT "auth-salt" +# define OSSL_PROV_SMTC_PARAM_AUTH_KEK "auth-kek" +# define OSSL_PROV_SMTC_PARAM_ENGINE "engine" +# define OSSL_PROV_SMTC_PARAM_SYSLOG "syslog" +# define OSSL_PROV_SMTC_PARAM_RNG_POWERON_TEST "rng-poweron-test" +# define OSSL_PROV_SMTC_PARAM_RNG_CONTINUOUS_TEST "rng-continuous-test" # define OSSL_PROV_SMTC_PARAM_RANDOMNESS_POWERON_TEST "randomness-poweron-test" # ifndef OPENSSL_NO_SMTC_DEBUG -# define OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_MAC "verify-mac" +# define OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_SIG "verify-sig" # define OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_PASS "verify-pass" # endif diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 99fcda002..357dc2399 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -249,6 +249,12 @@ OSSL_CORE_MAKE_FUNC(int, provider_get_capabilities, (void *provctx, # define OSSL_FUNC_PROVIDER_SELF_TEST 1031 OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx)) +# define OSSL_FUNC_PROVIDER_STATUS 1032 +OSSL_CORE_MAKE_FUNC(int, provider_status, (void *provctx)) + +# define OSSL_FUNC_PROVIDER_RESET 1033 +OSSL_CORE_MAKE_FUNC(int, provider_reset, (void *provctx)) + /* Operations */ # define OSSL_OP_DIGEST 1 diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in index 47d91aedb..116f32ac4 100644 --- a/include/openssl/crypto.h.in +++ b/include/openssl/crypto.h.in @@ -53,10 +53,31 @@ use OpenSSL::stackhash qw(generate_stack_macros); # include # endif +#if defined(OPENSSL_SYS_WINCE) +#elif defined(OPENSSL_SYS_WIN32) +#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) +# include +#endif + #ifdef __cplusplus extern "C" { #endif +# ifndef NO_SYSLOG +# if defined(OPENSSL_SYS_WIN32) +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 + +# define LOG_DAEMON (3<<3) +# endif +# endif + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define SSLeay OpenSSL_version_num # define SSLeay_version OpenSSL_version @@ -184,6 +205,8 @@ const char *OPENSSL_info(int type); # define OPENSSL_INFO_LIST_SEPARATOR 1006 # define OPENSSL_INFO_SEED_SOURCE 1007 # define OPENSSL_INFO_CPU_SETTINGS 1008 +# define OPENSSL_INFO_SMTC_MODULE_CONF 1009 +# define OPENSSL_INFO_SMTC_AUTH_KEK 1010 int OPENSSL_issetugid(void); @@ -542,6 +565,10 @@ void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); +void OSSL_enable_syslog(void); +void OSSL_disable_syslog(void); +void OSSL_syslog(int priority, const char *message, ...); + # ifdef __cplusplus } # endif diff --git a/include/openssl/evp.h b/include/openssl/evp.h index efa47dfc6..ec26e09af 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1681,8 +1681,14 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const char *name, const char *propquery); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name_provided(OSSL_LIB_CTX *libctx, + const char *name, + const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, const char *propquery); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey_provided(OSSL_LIB_CTX *libctx, + EVP_PKEY *pkey, + const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); int EVP_PKEY_CTX_is_a(EVP_PKEY_CTX *ctx, const char *keytype); diff --git a/include/openssl/opensslv.h.in b/include/openssl/opensslv.h.in index dfc4e45b7..8c3d996d7 100644 --- a/include/openssl/opensslv.h.in +++ b/include/openssl/opensslv.h.in @@ -126,7 +126,7 @@ extern "C" { # define BABASSL_VERSION_NUMBER TONGSUO_VERSION_NUMBER # define BABASSL_VERSION_TEXT TONGSUO_VERSION_TEXT -# define TONGSUO_SMTC_INFO_STR "{- $config{TONGSUO_SMTC_INFO} -}" +# define TONGSUO_SMTC_INFO_STR "{- $config{tongsuo_smtc_info} -}" # ifdef __cplusplus } diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h index ad67a8f89..75351fc98 100644 --- a/include/openssl/proverr.h +++ b/include/openssl/proverr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -48,6 +48,7 @@ # define PROV_R_FIPS_MODULE_IN_ERROR_STATE 225 # define PROV_R_GENERATE_ERROR 191 # define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 +# define PROV_R_INCORRECT_PASSWORD 231 # define PROV_R_INDICATOR_INTEGRITY_FAILURE 210 # define PROV_R_INSUFFICIENT_DRBG_STRENGTH 181 # define PROV_R_INVALID_AAD 108 @@ -123,6 +124,9 @@ # define PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT 229 # define PROV_R_SELF_TEST_KAT_FAILURE 215 # define PROV_R_SELF_TEST_POST_FAILURE 216 +# define PROV_R_SMTC_MODULE_CONDITIONAL_ERROR 232 +# define PROV_R_SMTC_MODULE_ENTERING_ERROR_STATE 350 +# define PROV_R_SMTC_MODULE_IN_ERROR_STATE 351 # define PROV_R_TAG_NOT_NEEDED 120 # define PROV_R_TAG_NOT_SET 119 # define PROV_R_TOO_MANY_RECORDS 126 diff --git a/include/openssl/provider.h b/include/openssl/provider.h index dc86ff587..32cdf7838 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -32,6 +32,8 @@ int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); +int OSSL_PROVIDER_reset(OSSL_PROVIDER *prov); +int OSSL_PROVIDER_status(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, diff --git a/include/openssl/rand.h b/include/openssl/rand.h index ad3054fd5..1673631c7 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h @@ -87,6 +87,7 @@ int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq, const char *cipher, const char *digest); int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed, const char *propq); +void RAND_set_entropy_source(unsigned int source); void RAND_seed(const void *buf, int num); void RAND_keep_random_devices_open(int keep); diff --git a/include/openssl/sdf.h b/include/openssl/sdf.h new file mode 100644 index 000000000..5d07bc2a4 --- /dev/null +++ b/include/openssl/sdf.h @@ -0,0 +1,118 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#ifndef OPENSSL_SDF_H +# define OPENSSL_SDF_H +# pragma once + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/* SDF error codes from GM/T 0018-2012 Appendix A */ +# define OSSL_SDR_OK 0 +# define OSSL_SDR_BASE 0x01000000 +# define OSSL_SDR_UNKNOWNERR (OSSL_SDR_BASE + 1) +# define OSSL_SDR_NOTSUPPORT (OSSL_SDR_BASE + 2) +# define OSSL_SDR_COMMFAIL (OSSL_SDR_BASE + 3) +# define OSSL_SDR_HARDFAIL (OSSL_SDR_BASE + 4) +# define OSSL_SDR_OPENDEVICE (OSSL_SDR_BASE + 5) +# define OSSL_SDR_OPENSESSION (OSSL_SDR_BASE + 6) +# define OSSL_SDR_PARDENY (OSSL_SDR_BASE + 7) +# define OSSL_SDR_KEYNOTEXIST (OSSL_SDR_BASE + 8) +# define OSSL_SDR_ALGNOTSUPPORT (OSSL_SDR_BASE + 9) +# define OSSL_SDR_ALGMODNOTSUPPORT (OSSL_SDR_BASE + 10) +# define OSSL_SDR_PKOPERR (OSSL_SDR_BASE + 11) +# define OSSL_SDR_SKOPERR (OSSL_SDR_BASE + 12) +# define OSSL_SDR_SIGNERR (OSSL_SDR_BASE + 13) +# define OSSL_SDR_VERIFYERR (OSSL_SDR_BASE + 14) +# define OSSL_SDR_SYMOPERR (OSSL_SDR_BASE + 15) +# define OSSL_SDR_STEPERR (OSSL_SDR_BASE + 16) +# define OSSL_SDR_FILESIZEERR (OSSL_SDR_BASE + 17) +# define OSSL_SDR_FILENOTEXIST (OSSL_SDR_BASE + 18) +# define OSSL_SDR_FILEOFSERR (OSSL_SDR_BASE + 19) +# define OSSL_SDR_KEYTYPEERR (OSSL_SDR_BASE + 20) +# define OSSL_SDR_KEYERR (OSSL_SDR_BASE + 21) +# define OSSL_SDR_ENCDATAERR (OSSL_SDR_BASE + 22) +# define OSSL_SDR_RANDERR (OSSL_SDR_BASE + 23) +# define OSSL_SDR_PRKRERR (OSSL_SDR_BASE + 24) +# define OSSL_SDR_MACERR (OSSL_SDR_BASE + 25) +# define OSSL_SDR_FILEEXISTS (OSSL_SDR_BASE + 26) +# define OSSL_SDR_FILEWERR (OSSL_SDR_BASE + 27) +# define OSSL_SDR_NOBUFFER (OSSL_SDR_BASE + 28) +# define OSSL_SDR_INARGERR (OSSL_SDR_BASE + 29) +# define OSSL_SDR_OUTARGERR (OSSL_SDR_BASE + 30) + +#define OSSL_SDFE_ASYM_KEY_TYPE_SM2 (0xa0) +#define OSSL_SDFE_SYM_KEY_TYPE_SM4 (0xb0) + +typedef struct OSSL_ECCCipher_st OSSL_ECCCipher; +typedef struct OSSL_ECCSignature_st OSSL_ECCSignature; +typedef struct OSSL_ECCrefPrivateKey_st OSSL_ECCrefPrivateKey; +typedef struct OSSL_ECCrefPublicKey_st OSSL_ECCrefPublicKey; +int TSAPI_SDF_OpenDevice(void **phDeviceHandle); +int TSAPI_SDF_CloseDevice(void *hDeviceHandle); +int TSAPI_SDF_OpenSession(void *hDeviceHandle, void **phSessionHandle); +int TSAPI_SDF_CloseSession(void *hSessionHandle); +int TSAPI_SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, + unsigned char *pucRandom); +int TSAPI_SDF_GetPrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength); +int TSAPI_SDF_ReleasePrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex); +int TSAPI_SDF_ImportKeyWithISK_ECC(void *hSessionHandle, + unsigned int uiISKIndex, + OSSL_ECCCipher *pucKey, + void **phKeyHandle); +int TSAPI_SDF_ImportKeyWithKEK(void *hSessionHandle, unsigned int uiAlgID, + unsigned int uiKEKIndex, unsigned char *pucKey, unsigned int puiKeyLength, + void **phKeyHandle); +int TSAPI_SDF_ExportSignPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey); +int TSAPI_SDF_ExportEncPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey); +int TSAPI_SDF_DestroyKey(void *hSessionHandle, void *hKeyHandle); +int TSAPI_SDF_InternalEncrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCCipher *pucEncData); +int TSAPI_SDF_InternalDecrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + OSSL_ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength); +int TSAPI_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 TSAPI_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 TSAPI_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 TSAPI_SDF_GenerateKey(void *hSessionHandle, uint8_t type, uint8_t no_kek, + uint32_t len, void **pkey_handle); +int TSAPI_SDF_InternalSign_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCSignature *pucSignature); + +# ifdef __cplusplus +} +# endif +#endif /* OPENSSL_SDF_H */ diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h index 357e1a9d2..1ffdf5e8d 100644 --- a/include/openssl/self_test.h +++ b/include/openssl/self_test.h @@ -32,6 +32,7 @@ extern "C" { # define OSSL_SELF_TEST_TYPE_PCT "Conditional_PCT" # define OSSL_SELF_TEST_TYPE_KAT_CIPHER "KAT_Cipher" # define OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER "KAT_AsymmetricCipher" +# define OSSL_SELF_TEST_TYPE_PCT_ASYM_CIPHER "PCT_AsymmetricCipher" # define OSSL_SELF_TEST_TYPE_KAT_DIGEST "KAT_Digest" # define OSSL_SELF_TEST_TYPE_KAT_SIGNATURE "KAT_Signature" # define OSSL_SELF_TEST_TYPE_PCT_SIGNATURE "PCT_Signature" @@ -42,6 +43,7 @@ extern "C" { /* Test event sub categories */ # define OSSL_SELF_TEST_DESC_NONE "None" # define OSSL_SELF_TEST_DESC_INTEGRITY_HMAC "HMAC" +# define OSSL_SELF_TEST_DESC_INTEGRITY_VERIFY "Verify_Integrity" # define OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1 "RSA" # define OSSL_SELF_TEST_DESC_PCT_ECDSA "ECDSA" # define OSSL_SELF_TEST_DESC_PCT_DSA "DSA" @@ -56,6 +58,8 @@ extern "C" { # define OSSL_SELF_TEST_DESC_SIGN_DSA "DSA" # define OSSL_SELF_TEST_DESC_SIGN_RSA "RSA" # define OSSL_SELF_TEST_DESC_SIGN_SM2 "SM2" +# define OSSL_SELF_TEST_DESC_SIGN_SM2_SIGN "SM2_Sign" +# define OSSL_SELF_TEST_DESC_SIGN_SM2_VERIFY "SM2_Verify" # define OSSL_SELF_TEST_DESC_SIGN_ECDSA "ECDSA" # define OSSL_SELF_TEST_DESC_DRBG_CTR "CTR" # define OSSL_SELF_TEST_DESC_DRBG_HASH "HASH" diff --git a/include/openssl/sgd.h b/include/openssl/sgd.h new file mode 100644 index 000000000..e79267ff4 --- /dev/null +++ b/include/openssl/sgd.h @@ -0,0 +1,53 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#ifndef OPENSSL_SGD_H +# define OPENSSL_SGD_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_SGD_H +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* Defined in GM/T 0006-2012 */ +# define OSSL_SGD_MODE_ECB 0x00000001 +# define OSSL_SGD_MODE_CBC 0x00000002 +# define OSSL_SGD_MODE_CFB 0x00000004 +# define OSSL_SGD_MODE_OFB 0x00000008 +# define OSSL_SGD_MODE_MAC 0x00000010 +# define OSSL_SGD_MODE_CTR 0x00000020 +# define OSSL_SGD_MODE_XTS 0x00000040 + +# define OSSL_SGD_SM4 0x00000400 +# define OSSL_SGD_SM4_ECB (OSSL_SGD_SM4 | OSSL_SGD_MODE_ECB) +# define OSSL_SGD_SM4_CBC (OSSL_SGD_SM4 | OSSL_SGD_MODE_CBC) +# define OSSL_SGD_SM4_CFB (OSSL_SGD_SM4 | OSSL_SGD_MODE_CFB) +# define OSSL_SGD_SM4_OFB (OSSL_SGD_SM4 | OSSL_SGD_MODE_OFB) +# define OSSL_SGD_SM4_MAC (OSSL_SGD_SM4 | OSSL_SGD_MODE_MAC) + +# define OSSL_SGD_RSA 0x00010000 +# define OSSL_SGD_SM2 0x00020100 +# define OSSL_SGD_SM2_1 0x00020200 +# define OSSL_SGD_SM2_2 0x00020400 +# define OSSL_SGD_SM2_3 0x00020800 + +# define OSSL_SGD_SM3 0x00000001 + +# define OSSL_SGD_SM3_SM2 0x00020201 + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/trace.h b/include/openssl/trace.h index 282001336..d2a2d52ed 100644 --- a/include/openssl/trace.h +++ b/include/openssl/trace.h @@ -57,8 +57,9 @@ extern "C" { # define OSSL_TRACE_CATEGORY_DECODER 15 # define OSSL_TRACE_CATEGORY_ENCODER 16 # define OSSL_TRACE_CATEGORY_REF_COUNT 17 +# define OSSL_TRACE_CATEGORY_SMTC 18 /* Count of available categories. */ -# define OSSL_TRACE_CATEGORY_NUM 18 +# define OSSL_TRACE_CATEGORY_NUM 19 /* Returns the trace category number for the given |name| */ int OSSL_trace_get_category_num(const char *name); diff --git a/include/openssl/tsapi.h b/include/openssl/tsapi.h new file mode 100644 index 000000000..7d5adff78 --- /dev/null +++ b/include/openssl/tsapi.h @@ -0,0 +1,98 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#ifndef TONGSUO_API_H +# define TONGSUO_API_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_TSAPI_H +# endif + +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +unsigned char *TSAPI_GetEntropy(int entropy, size_t *outlen); +void TSAPI_FreeEntropy(unsigned char *ent, size_t len); +char *TSAPI_Version(void); +unsigned char *TSAPI_RandBytes(size_t len); + +# ifndef OPENSSL_NO_SM2 +EVP_PKEY *TSAPI_SM2Keygen(void); +# ifndef OPENSSL_NO_SM3 +unsigned char *TSAPI_SM2Sign(EVP_PKEY *key, const unsigned char *tbs, + size_t tbslen, size_t *siglen); +int TSAPI_SM2Verify(EVP_PKEY *key, const unsigned char *tbs, size_t tbslen, + const unsigned char *sig, size_t siglen); +# endif +unsigned char *TSAPI_SM2Encrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2Decrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2EncryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2DecryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_ECCCipher_to_SM2Ciphertext(const OSSL_ECCCipher *ecc, + size_t *ciphertext_len); +OSSL_ECCCipher *TSAPI_SM2Ciphertext_to_ECCCipher(const unsigned char *ciphertext, + size_t ciphertext_len); +int TSAPI_ImportSM2Key(int index, int sign, const char *user, + const char *password, const EVP_PKEY *sm2_pkey); +OSSL_ECCrefPublicKey *TSAPI_EVP_PKEY_get_ECCrefPublicKey(const EVP_PKEY *pkey); +OSSL_ECCrefPrivateKey *TSAPI_EVP_PKEY_get_ECCrefPrivateKey(const EVP_PKEY *pkey); +EVP_PKEY *TSAPI_ExportSM2KeyWithIndex(int index, int sign, const char *user, + const char *password); +EVP_PKEY *TSAPI_EVP_PKEY_new_from_ECCrefKey(const OSSL_ECCrefPublicKey *pubkey, + const OSSL_ECCrefPrivateKey *privkey); +int TSAPI_ImportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, unsigned char *key, + size_t keylen, unsigned char *dek, + size_t deklen); +int TSAPI_ExportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, EVP_PKEY *sm2_pubkey, + unsigned char **priv, size_t *privlen, + unsigned char **pub, size_t *publen, + unsigned char **outevlp, size_t *outevlplen); +int TSAPI_GenerateSM2KeyWithIndex(int index, int sign, const char *user, const char *password); +int TSAPI_DelSm2KeyWithIndex(int index, int sign, const char *user, + const char *password); +int TSAPI_UpdateSm2KeyWithIndex(int index, int sign, const char *user, + const char *password); +EVP_PKEY *TSAPI_ExportSM2PubKeyWithIndex(int index, int sign); +# endif + +# ifndef OPENSSL_NO_SM4 +unsigned char *TSAPI_SM4Encrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen); +unsigned char *TSAPI_SM4Decrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen); +# endif +# ifndef OPENSSL_NO_SM3 +unsigned char *TSAPI_SM3(const void *data, size_t datalen, size_t *outlen); +# endif + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/types.h b/include/openssl/types.h index 4e3bce468..ce5c076e6 100644 --- a/include/openssl/types.h +++ b/include/openssl/types.h @@ -244,6 +244,8 @@ typedef struct ossl_decoder_ctx_st OSSL_DECODER_CTX; typedef struct ossl_self_test_st OSSL_SELF_TEST; +typedef struct sdf_method_st SDF_METHOD; + #ifdef __cplusplus } #endif diff --git a/providers/build.info b/providers/build.info index 072bce04c..358f5d046 100644 --- a/providers/build.info +++ b/providers/build.info @@ -134,30 +134,26 @@ IF[{- !$disabled{smtc} -}] LIBS{noinst}=$LIBSMTC SUBDIRS=smtc - # Note: only support builtin module for now - IF[{- $disabled{module} -}] - # Become built in - $SMTCGOAL=../libcrypto - SOURCE[$SMTCGOAL]=$LIBSMTC - DEFINE[$SMTCGOAL]=STATIC_SMTC - DEFINE[$LIBSMTC]=STATIC_SMTC - ELSE - # TODO: become a module - $SMTCGOAL=smtc - MODULES=$SMTCGOAL - DEPEND[$SMTCGOAL]=$LIBSMTC - SOURCE[$SMTCGOAL]=smtc/smtc_entry.c - INCLUDE[$SMTCGOAL]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[$SMTCGOAL]=smtc.ld - GENERATE[smtc.ld]=../util/providers.num - ENDIF - SOURCE[$LIBSMTC]=prov_running.c - ENDIF + # Note: only support builtin for now + $SMTCGOAL=../libcrypto + SOURCE[$SMTCGOAL]=$LIBSMTC + DEFINE[$SMTCGOAL]=STATIC_SMTC + DEFINE[$LIBSMTC]=STATIC_SMTC DEFINE[$SMTCGOAL]=SMTC_MODULE DEFINE[$LIBDEFAULT]=SMTC_MODULE DEFINE[../libssl]=SMTC_MODULE + +{- use File::Spec::Functions; + our $ex_lib = $withargs{atf_slibce_lib} && + (file_name_is_absolute($withargs{atf_slibce_lib}) ? + $withargs{atf_slibce_lib} : catfile(updir(), $withargs{atf_slibce_lib})); + "" +-} + + IF[{- !$disabled{atf_slibce} -}] + DEPEND[$SMTCGOAL]={- $ex_lib -} + ENDIF ENDIF # diff --git a/providers/common/include/prov/proverr.h b/providers/common/include/prov/proverr.h index 5084af201..34247ed2f 100644 --- a/providers/common/include/prov/proverr.h +++ b/providers/common/include/prov/proverr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/include/prov/provider_util.h b/providers/common/include/prov/provider_util.h index dfe91f29b..b74e1373c 100644 --- a/providers/common/include/prov/provider_util.h +++ b/providers/common/include/prov/provider_util.h @@ -7,8 +7,11 @@ * https://www.openssl.org/source/license.html */ -#include -#include +#ifndef OSSL_PROV_PROVIDER_UTIL_H +# define OSSL_PROV_PROVIDER_UTIL_H + +# include +# include typedef struct { /* @@ -136,3 +139,4 @@ typedef struct ag_capable_st { */ void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in, OSSL_ALGORITHM *out); +#endif diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 344c12211..e541100cf 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,6 +62,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_GENERATE_ERROR), "generate error"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "illegal or unsupported padding mode"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INCORRECT_PASSWORD), + "incorrect password"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INDICATOR_INTEGRITY_FAILURE), "indicator integrity failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INSUFFICIENT_DRBG_STRENGTH), @@ -177,6 +179,12 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "self test kat failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE), "self test post failure"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SMTC_MODULE_CONDITIONAL_ERROR), + "smtc module conditional error"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SMTC_MODULE_ENTERING_ERROR_STATE), + "smtc module entering error state"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SMTC_MODULE_IN_ERROR_STATE), + "smtc module in error state"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_SET), "tag not set"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TOO_MANY_RECORDS), "too many records"}, diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index 617e75848..d473c6530 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -35,9 +35,6 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hash_gettable_ctx_params; static OSSL_FUNC_rand_get_ctx_params_fn drbg_hash_get_ctx_params; static OSSL_FUNC_rand_verify_zeroization_fn drbg_hash_verify_zeroization; -/* 888 bits from SP800-90Ar1 10.1 table 2 */ -#define HASH_PRNG_MAX_SEEDLEN (888/8) - /* 440 bits from SP800-90Ar1 10.1 table 2 */ #define HASH_PRNG_SMALL_SEEDLEN (440/8) @@ -45,15 +42,6 @@ static OSSL_FUNC_rand_verify_zeroization_fn drbg_hash_verify_zeroization; #define MAX_BLOCKLEN_USING_SMALL_SEEDLEN (256/8) #define INBYTE_IGNORE ((unsigned char)0xFF) -typedef struct rand_drbg_hash_st { - PROV_DIGEST digest; - EVP_MD_CTX *ctx; - size_t blocklen; - unsigned char V[HASH_PRNG_MAX_SEEDLEN]; - unsigned char C[HASH_PRNG_MAX_SEEDLEN]; - /* Temporary value storage: should always exceed max digest length */ - unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN]; -} PROV_DRBG_HASH; /* * SP800-90Ar1 10.3.1 Derivation function using a Hash Function (Hash_df). @@ -309,8 +297,10 @@ static int drbg_hash_reseed(PROV_DRBG *drbg, adin, adin_len)) return 0; } else { - /* (Step 1-2) V = Hash_df(0x01 || V || entropy_input || additional_input) */ - /* V about to be updated so use C as output instead */ + /* + * (Step 1-2) V=Hash_df(0x01 || V || entropy_input || additional_input) + * V about to be updated so use C as output instead + */ if (!hash_df(drbg, hash->C, 0x01, hash->V, drbg->seedlen, ent, ent_len, adin, adin_len)) return 0; diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h index a0877e379..bcdef411b 100644 --- a/providers/implementations/rands/drbg_local.h +++ b/providers/implementations/rands/drbg_local.h @@ -18,6 +18,7 @@ # include "internal/nelem.h" # include "internal/numbers.h" # include "prov/provider_ctx.h" +# include "prov/provider_util.h" /* How many times to read the TSC as a randomness source. */ # define TSC_READ_COUNT 4 @@ -49,13 +50,26 @@ */ # define DRBG_MAX_LENGTH INT32_MAX +/* 888 bits from SP800-90Ar1 10.1 table 2 */ +#define HASH_PRNG_MAX_SEEDLEN (888/8) + /* The default nonce */ -#ifdef CHARSET_EBCDIC -# define DRBG_DEFAULT_PERS_STRING { 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, \ +#ifdef TONGSUO_RAND_GM_SRNG +# ifdef CHARSET_EBCDIC +# define DRBG_DEFAULT_PERS_STRING { 0x54, 0x6f, 0x6e, 0x67, 0x73, 0x75, \ + 0x6f, 0x20, 0x47, 0x4d, 0x2f, 0x54, 0x20, 0x30, 0x31, 0x30, 0x35, 0x2d, \ + 0x32, 0x30, 0x32, 0x31, 0x20, 0x53, 0x52, 0x4e, 0x47, 0x00}; +# else +# define DRBG_DEFAULT_PERS_STRING "Tongsuo GM/T 0105-2021 SRNG" +# endif +#else +# ifdef CHARSET_EBCDIC +# define DRBG_DEFAULT_PERS_STRING { 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, \ 0x4c, 0x20, 0x4e, 0x49, 0x53, 0x54, 0x20, 0x53, 0x50, 0x20, 0x38, 0x30, \ 0x30, 0x2d, 0x39, 0x30, 0x41, 0x20, 0x44, 0x52, 0x42, 0x47, 0x00}; -#else -# define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG" +# else +# define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG" +# endif #endif typedef struct prov_drbg_st PROV_DRBG; @@ -178,6 +192,16 @@ struct prov_drbg_st { OSSL_CALLBACK *cleanup_nonce_fn; }; +typedef struct rand_drbg_hash_st { + PROV_DIGEST digest; + EVP_MD_CTX *ctx; + size_t blocklen; + unsigned char V[HASH_PRNG_MAX_SEEDLEN]; + unsigned char C[HASH_PRNG_MAX_SEEDLEN]; + /* Temporary value storage: should always exceed max digest length */ + unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN]; +} PROV_DRBG_HASH; + PROV_DRBG *ossl_rand_drbg_new (void *provctx, void *parent, const OSSL_DISPATCH *parent_dispatch, int (*dnew)(PROV_DRBG *ctx), diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index 6fb13195a..847f250d8 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -102,7 +102,14 @@ static uint64_t get_timer_bits(void); # undef OPENSSL_RAND_SEED_RDTSC # undef OPENSSL_RAND_SEED_RDCPU # undef OPENSSL_RAND_SEED_EGD -# undef OPENSSL_RAND_SEED_RTC +# undef OPENSSL_RAND_SEED_RTCODE +# undef OPENSSL_RAND_SEED_RTMEM +# undef OPENSSL_RAND_SEED_RTSOCK +#endif + +#if defined(OPENSSL_RAND_SEED_RTSOCK) +# include +# include #endif #if defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_RAND_SEED_NONE) @@ -606,8 +613,8 @@ void ossl_rand_pool_keep_random_devices_open(int keep) # endif /* defined(OPENSSL_RAND_SEED_DEVRANDOM) */ -# if defined(OPENSSL_RAND_SEED_RTC) -static size_t ossl_prov_acquire_entropy_from_rtc1(RAND_POOL *pool) +# if defined(OPENSSL_RAND_SEED_RTCODE) +static size_t ossl_prov_acquire_entropy_from_rtcode(RAND_POOL *pool) { size_t i, k, bytes_needed; struct timespec ts; @@ -635,8 +642,9 @@ static size_t ossl_prov_acquire_entropy_from_rtc1(RAND_POOL *pool) } return ossl_rand_pool_entropy_available(pool); } - -static size_t ossl_prov_acquire_entropy_from_rtc2(RAND_POOL *pool) +# endif +# if defined(OPENSSL_RAND_SEED_RTMEM) +static size_t ossl_prov_acquire_entropy_from_rtmem(RAND_POOL *pool) { size_t i, k, bytes_needed; struct timespec ts; @@ -667,6 +675,55 @@ static size_t ossl_prov_acquire_entropy_from_rtc2(RAND_POOL *pool) } # endif +# if defined(OPENSSL_RAND_SEED_RTSOCK) +static size_t ossl_prov_acquire_entropy_from_rtsock(RAND_POOL *pool) +{ + int fd[2], ret; + long data; + size_t i, bytes_needed; + struct timespec ts; + unsigned char v; + + bytes_needed = ossl_rand_pool_bytes_needed(pool, 4 /*entropy_factor*/); + + for (i = 0; i < bytes_needed; i++) { + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd); + if (ret == -1) + break; + + data = random(); + + while ((ret = write(fd[0], &data, sizeof(data))) < 0 && errno == EINTR); + if (ret < 0) { + close(fd[0]); + close(fd[1]); + break; + } + + while ((ret = read(fd[1], &data, sizeof(data))) < 0 && errno == EINTR); + if (ret < 0) { + close(fd[0]); + close(fd[1]); + break; + } + + /* sleep for 1/65536 of a second (15 us). */ + ts.tv_sec = 0; + ts.tv_nsec = 15000; + nanosleep(&ts, NULL); + + /* Get wall clock time, take 8 bits. */ + clock_gettime(CLOCK_REALTIME, &ts); + v = (unsigned char)(ts.tv_nsec & 0xFF); + ossl_rand_pool_add(pool, &v, sizeof(v), 2); + + close(fd[0]); + close(fd[1]); + } + + return ossl_rand_pool_entropy_available(pool); +} +# endif /* * Try the various seeding methods in turn, exit when successful. * @@ -694,7 +751,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) (void)entropy_available; /* avoid compiler warning */ # if defined(OPENSSL_RAND_SEED_GETRANDOM) - { + if (pool->entropy_source & RAND_ENTROPY_SOURCE_GETRANDOM) { size_t bytes_needed; unsigned char *buffer; ssize_t bytes; @@ -713,10 +770,11 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) break; } } + + entropy_available = ossl_rand_pool_entropy_available(pool); + if (entropy_available > 0) + return entropy_available; } - entropy_available = ossl_rand_pool_entropy_available(pool); - if (entropy_available > 0) - return entropy_available; # endif # if defined(OPENSSL_RAND_SEED_LIBRANDOM) @@ -726,7 +784,8 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) # endif # if defined(OPENSSL_RAND_SEED_DEVRANDOM) - if (wait_random_seeded()) { + if ((pool->entropy_source & RAND_ENTROPY_SOURCE_DEVRANDOM) + && wait_random_seeded()) { size_t bytes_needed; unsigned char *buffer; size_t i; @@ -766,19 +825,23 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) # endif # if defined(OPENSSL_RAND_SEED_RDTSC) - entropy_available = ossl_prov_acquire_entropy_from_tsc(pool); - if (entropy_available > 0) - return entropy_available; + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RDTSC) { + entropy_available = ossl_prov_acquire_entropy_from_tsc(pool); + if (entropy_available > 0) + return entropy_available; + } # endif # if defined(OPENSSL_RAND_SEED_RDCPU) - entropy_available = ossl_prov_acquire_entropy_from_cpu(pool); - if (entropy_available > 0) - return entropy_available; + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RDCPU) { + entropy_available = ossl_prov_acquire_entropy_from_cpu(pool); + if (entropy_available > 0) + return entropy_available; + } # endif # if defined(OPENSSL_RAND_SEED_EGD) - { + if (pool->entropy_source & RAND_ENTROPY_SOURCE_EGD) { static const char *paths[] = { DEVRANDOM_EGD, NULL }; size_t bytes_needed; unsigned char *buffer; @@ -804,14 +867,28 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) } # endif -# if defined(OPENSSL_RAND_SEED_RTC) - entropy_available = ossl_prov_acquire_entropy_from_rtc1(pool); - if (entropy_available > 0) - return entropy_available; +# if defined(OPENSSL_RAND_SEED_RTCODE) + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RTCODE) { + entropy_available = ossl_prov_acquire_entropy_from_rtcode(pool); + if (entropy_available > 0) + return entropy_available; + } +# endif + +# if defined(OPENSSL_RAND_SEED_RTMEM) + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RTMEM) { + entropy_available = ossl_prov_acquire_entropy_from_rtmem(pool); + if (entropy_available > 0) + return entropy_available; + } +# endif - entropy_available = ossl_prov_acquire_entropy_from_rtc2(pool); - if (entropy_available > 0) - return entropy_available; +# if defined(OPENSSL_RAND_SEED_RTSOCK) + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RTSOCK) { + entropy_available = ossl_prov_acquire_entropy_from_rtsock(pool); + if (entropy_available > 0) + return entropy_available; + } # endif return ossl_rand_pool_entropy_available(pool); diff --git a/providers/implementations/rands/seeding/rand_win.c b/providers/implementations/rands/seeding/rand_win.c index 704705425..6bf741a28 100644 --- a/providers/implementations/rands/seeding/rand_win.c +++ b/providers/implementations/rands/seeding/rand_win.c @@ -53,69 +53,79 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) # ifdef OPENSSL_RAND_SEED_RDTSC - entropy_available = ossl_prov_acquire_entropy_from_tsc(pool); - if (entropy_available > 0) - return entropy_available; + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RDTSC) { + entropy_available = ossl_prov_acquire_entropy_from_tsc(pool); + if (entropy_available > 0) + return entropy_available; + } # endif # ifdef OPENSSL_RAND_SEED_RDCPU - entropy_available = ossl_prov_acquire_entropy_from_cpu(pool); - if (entropy_available > 0) - return entropy_available; + if (pool->entropy_source & RAND_ENTROPY_SOURCE_RDCPU) { + entropy_available = ossl_prov_acquire_entropy_from_cpu(pool); + if (entropy_available > 0) + return entropy_available; + } # endif # ifdef USE_BCRYPTGENRANDOM - bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - buffer = ossl_rand_pool_add_begin(pool, bytes_needed); - if (buffer != NULL) { - size_t bytes = 0; - if (BCryptGenRandom(NULL, buffer, bytes_needed, - BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) - bytes = bytes_needed; - - ossl_rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = ossl_rand_pool_entropy_available(pool); - } - if (entropy_available > 0) - return entropy_available; -# else - bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - buffer = ossl_rand_pool_add_begin(pool, bytes_needed); - if (buffer != NULL) { - size_t bytes = 0; - /* poll the CryptoAPI PRNG */ - if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { - if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) + if (pool->entropy_source & RAND_ENTROPY_SOURCE_BCRYPTGENRANDOM) { + bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + buffer = ossl_rand_pool_add_begin(pool, bytes_needed); + if (buffer != NULL) { + size_t bytes = 0; + if (BCryptGenRandom(NULL, buffer, bytes_needed, + BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) bytes = bytes_needed; - CryptReleaseContext(hProvider, 0); + ossl_rand_pool_add_end(pool, bytes, 8 * bytes); + entropy_available = ossl_rand_pool_entropy_available(pool); } - - ossl_rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = ossl_rand_pool_entropy_available(pool); + if (entropy_available > 0) + return entropy_available; + } +# else + if (pool->entropy_source & RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_DEF_PROV) { + bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + buffer = ossl_rand_pool_add_begin(pool, bytes_needed); + if (buffer != NULL) { + size_t bytes = 0; + /* poll the CryptoAPI PRNG */ + if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { + if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) + bytes = bytes_needed; + + CryptReleaseContext(hProvider, 0); + } + + ossl_rand_pool_add_end(pool, bytes, 8 * bytes); + entropy_available = ossl_rand_pool_entropy_available(pool); + } + if (entropy_available > 0) + return entropy_available; } - if (entropy_available > 0) - return entropy_available; - - bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - buffer = ossl_rand_pool_add_begin(pool, bytes_needed); - if (buffer != NULL) { - size_t bytes = 0; - /* poll the Pentium PRG with CryptoAPI */ - if (CryptAcquireContextW(&hProvider, NULL, - INTEL_DEF_PROV, PROV_INTEL_SEC, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { - if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) - bytes = bytes_needed; - CryptReleaseContext(hProvider, 0); + if (pool->entropy_source & RAND_ENTROPY_SOURCE_CRYPTGENRANDOM_INTEL_PROV) { + bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + buffer = ossl_rand_pool_add_begin(pool, bytes_needed); + if (buffer != NULL) { + size_t bytes = 0; + /* poll the Pentium PRG with CryptoAPI */ + if (CryptAcquireContextW(&hProvider, NULL, + INTEL_DEF_PROV, PROV_INTEL_SEC, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { + if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) + bytes = bytes_needed; + + CryptReleaseContext(hProvider, 0); + } + ossl_rand_pool_add_end(pool, bytes, 8 * bytes); + entropy_available = ossl_rand_pool_entropy_available(pool); } - ossl_rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = ossl_rand_pool_entropy_available(pool); + if (entropy_available > 0) + return entropy_available; } - if (entropy_available > 0) - return entropy_available; # endif return ossl_rand_pool_entropy_available(pool); diff --git a/providers/implementations/rands/smtc_rng.c b/providers/implementations/rands/smtc_rng.c index e7c3aace0..8877966ff 100644 --- a/providers/implementations/rands/smtc_rng.c +++ b/providers/implementations/rands/smtc_rng.c @@ -24,20 +24,62 @@ #include "prov/seeding.h" #include "crypto/evp.h" -#define REPEAT_COUNT_TEST_THRESHOLD 26 typedef struct smtc_crng_test_global_st { CRYPTO_RWLOCK *lock; - unsigned char last_bit; + EVP_MD_CTX *md_ctx; + int sample; size_t cnt; } SMTC_CRNG_TEST_GLOBAL; -static int get_bit(const unsigned char *buf, int m) +/* Modified based on hash_df() in drbg_hash.c */ +static int sm3_df(EVP_MD_CTX *ctx, unsigned char *out, size_t outlen, + const unsigned char *in, size_t inlen) { - if (m < 0) - return 0; + unsigned char vtmp[EVP_MAX_MD_SIZE]; + /* tmp = counter || num_bits_returned */ + unsigned char tmp[1 + 4]; + int tmp_sz = 0; + size_t blocklen = EVP_MD_get_size(EVP_sm3()); + size_t num_bits_returned = outlen * 8; + + /* counter = 1 (tmp[0] is the 8 bit counter) */ + tmp[tmp_sz++] = 1; + /* tmp[1..4] is the fixed 32 bit no_of_bits_to_return */ + tmp[tmp_sz++] = (unsigned char)((num_bits_returned >> 24) & 0xff); + tmp[tmp_sz++] = (unsigned char)((num_bits_returned >> 16) & 0xff); + tmp[tmp_sz++] = (unsigned char)((num_bits_returned >> 8) & 0xff); + tmp[tmp_sz++] = (unsigned char)(num_bits_returned & 0xff); + + for (;;) { + /* + * out = out || Hash(tmp || in) + * (where tmp = counter || num_bits_returned) + */ + if (!(EVP_DigestInit_ex(ctx, EVP_sm3(), NULL) + && EVP_DigestUpdate(ctx, tmp, tmp_sz) + && EVP_DigestUpdate(ctx, in, inlen))) + return 0; + + if (outlen < blocklen) { + if (!EVP_DigestFinal(ctx, vtmp, NULL)) + return 0; + memcpy(out, vtmp, outlen); + OPENSSL_cleanse(vtmp, blocklen); + break; + } else if(!EVP_DigestFinal(ctx, out, NULL)) { + return 0; + } + + outlen -= blocklen; + if (outlen == 0) + break; - return (buf[m / 8] << (m % 8) >> 7) & 1; + tmp[0]++; + out += blocklen; + } + + return 1; } static void rand_smtc_crng_ossl_ctx_free(void *vcrngt_glob) @@ -45,6 +87,7 @@ static void rand_smtc_crng_ossl_ctx_free(void *vcrngt_glob) SMTC_CRNG_TEST_GLOBAL *smtc_glob = vcrngt_glob; CRYPTO_THREAD_lock_free(smtc_glob->lock); + EVP_MD_CTX_free(smtc_glob->md_ctx); OPENSSL_free(smtc_glob); } @@ -55,11 +98,19 @@ static void *rand_smtc_crng_ossl_ctx_new(OSSL_LIB_CTX *ctx) if (smtc_glob == NULL) return NULL; + if ((smtc_glob->md_ctx = EVP_MD_CTX_new()) == NULL) { + OPENSSL_free(smtc_glob); + return NULL; + } + if ((smtc_glob->lock = CRYPTO_THREAD_lock_new()) == NULL) { OPENSSL_free(smtc_glob); return NULL; } + smtc_glob->sample = -1; + smtc_glob->cnt = 0; + return smtc_glob; } @@ -69,34 +120,26 @@ static const OSSL_LIB_CTX_METHOD rand_smtc_ossl_ctx_method = { rand_smtc_crng_ossl_ctx_free, }; +/* 1 + ceil(20/H) */ +#define REPEAT_COUNT_TEST_THRESHOLD 4 /* * GM/T 0105-2021 Appendix D.2, Repeat Count Test */ static int smtc_rng_repeat_count_test(SMTC_CRNG_TEST_GLOBAL *crngt, - unsigned char *pout, size_t len, - OSSL_SELF_TEST *st) + const unsigned char *entropy, size_t len) { - size_t i = 0; + size_t i; - if (len <= 0) + if (entropy == NULL || len == 0) return 0; - if (crngt->cnt == 0) { - crngt->last_bit = get_bit(pout, 0); - crngt->cnt = i = 1; - } - - for (; i < len * 8; i++) { - unsigned char bit = get_bit(pout, i); - if (bit == crngt->last_bit) { + for (i = 0; i < len; i++) { + if (entropy[i] == crngt->sample) { crngt->cnt++; - if (crngt->cnt >= REPEAT_COUNT_TEST_THRESHOLD) { - crngt->cnt = 0; - OSSL_SELF_TEST_oncorrupt_byte(st, &pout[i / 8]); + if (crngt->cnt >= REPEAT_COUNT_TEST_THRESHOLD) return 0; - } } else { - crngt->last_bit = bit; + crngt->sample = entropy[i]; crngt->cnt = 1; } } @@ -108,14 +151,15 @@ size_t ossl_smtc_get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len, int prediction_resistance) { - int crng_test_pass = 0; + unsigned char buf[CRNGT_BUFSIZ]; + int crng_test_pass = 1; OSSL_CALLBACK *stcb = NULL; void *stcbarg = NULL; + unsigned char *ent, *entp, *entbuf; + unsigned char *p = NULL; OSSL_SELF_TEST *st = NULL; - size_t ret - = ossl_prov_get_entropy(drbg->provctx, pout, entropy, min_len, max_len); - if (ret == 0) - return 0; + size_t bytes_needed; + size_t r = 0, s, t, n; OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(drbg->provctx); SMTC_CRNG_TEST_GLOBAL *crngt_glob = ossl_lib_ctx_get_data( @@ -127,6 +171,20 @@ size_t ossl_smtc_get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, if (!CRYPTO_THREAD_write_lock(crngt_glob->lock)) return 0; + /* + * Calculate how many bytes of seed material we require, rounded up + * to the nearest byte. + */ + bytes_needed = (entropy + 7) / 8; + if (bytes_needed < min_len) + bytes_needed = min_len; + if (bytes_needed > max_len) + goto unlock_return; + + entp = ent = OPENSSL_secure_malloc(bytes_needed); + if (ent == NULL) + goto unlock_return; + OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg); if (stcb != NULL) { st = OSSL_SELF_TEST_new(stcb, stcbarg); @@ -136,16 +194,52 @@ size_t ossl_smtc_get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, OSSL_SELF_TEST_DESC_RNG); } - if (!smtc_rng_repeat_count_test(crngt_glob, *pout, ret, st)) { - ret = 0; - goto err; - } + for (t = bytes_needed; t > 0;) { + /* Care needs to be taken to avoid overrunning the buffer */ + s = t >= CRNGT_BUFSIZ ? CRNGT_BUFSIZ : t; + entbuf = t >= CRNGT_BUFSIZ ? entp : buf; + + n = ossl_prov_get_entropy(drbg->provctx, &p, 0, CRNGT_BUFSIZ, + CRNGT_BUFSIZ); + if (n == CRNGT_BUFSIZ) { + if (OSSL_SELF_TEST_oncorrupt_byte(st, p)) + memset(p, 0, n); + + if (!smtc_rng_repeat_count_test(crngt_glob, p, n)) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_CRNG); + crng_test_pass = 0; + goto err; + } + + if (!sm3_df(crngt_glob->md_ctx, entbuf, CRNGT_BUFSIZ, p, + CRNGT_BUFSIZ)) + goto err; + + ossl_prov_cleanup_entropy(drbg->provctx, p, n); + } + + if (n != 0) { + ossl_prov_cleanup_entropy(drbg->provctx, p, n); + p = NULL; + goto err; + } - crng_test_pass = 1; + if (t < CRNGT_BUFSIZ) + memcpy(entp, buf, t); -err: + entp += s; + t -= s; + } + r = bytes_needed; + *pout = ent; + ent = NULL; + + err: OSSL_SELF_TEST_onend(st, crng_test_pass); OSSL_SELF_TEST_free(st); + OPENSSL_secure_clear_free(ent, bytes_needed); + + unlock_return: CRYPTO_THREAD_unlock(crngt_glob->lock); - return ret; + return r; } diff --git a/providers/prov_running.c b/providers/prov_running.c index 379fd5d25..e51b7024f 100644 --- a/providers/prov_running.c +++ b/providers/prov_running.c @@ -10,6 +10,7 @@ #include #include "prov/providercommon.h" +#ifndef SMTC_MODULE /* By default, our providers don't have an error state */ void ossl_set_error_state(const char *type) { @@ -20,3 +21,4 @@ int ossl_prov_is_running(void) { return 1; } +#endif diff --git a/providers/smtc/README.md b/providers/smtc/README.md index 1a7f2ee22..43628a058 100644 --- a/providers/smtc/README.md +++ b/providers/smtc/README.md @@ -1,25 +1,22 @@ -# 构建SMTC +# Build SMTC ``` -./config enable-smtc enable-ntls no-shared enable-ssl-trace --prefix=/opt/tongsuo -Wl,-rpath,/opt/tongsuo/lib64 +./config enable-smtc enable-ntls no-shared enable-ssl-trace --prefix=/path/to/tongsuo -Wl,-rpath,/path/to/tongsuo/lib64 make make install ``` -# 配置SMTC +# Install SMTC ``` -/opt/tongsuo/bin/tongsuo mod -module /opt/tongsuo/bin/tongsuo -provider_name smtc -section_name smtc_sect -show_selftest -out /opt/tongsuo/ssl/smtcmodule.cnf - -# 修改/opt/tongsuo/ssl/openssl.cnf,包含smtcmodule.cnf,设置smtc section -sed -i -e 's|^# .include smtcmodule.cnf|.include /opt/tongsuo/ssl/smtcmodule.cnf|;s/^# smtc = smtc_sect/smtc = smtc_sect/' /opt/tongsuo/ssl/openssl.cnf +/path/to/tongsuo/bin/tongsuo mod -install -module /path/to/tongsuo/bin/tongsuo -sigfile signature.bin ``` -# SMTC自测试 +# SMTC Self Test ``` -/opt/tongsuo/bin/tongsuo mod -test +/path/to/tongsuo/bin/tongsuo mod -test ``` diff --git a/providers/smtc/self_test.c b/providers/smtc/self_test.c index e76027833..bf2118189 100644 --- a/providers/smtc/self_test.c +++ b/providers/smtc/self_test.c @@ -7,15 +7,23 @@ * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include +#include +#include #include #include #include +#include #include +#include #include "internal/cryptlib.h" #include +#include #include #include "crypto/evp.h" +#include "crypto/rand.h" #include "internal/e_os.h" #include "internal/thread_once.h" #include "prov/providercommon.h" @@ -25,18 +33,143 @@ #include "self_test.h" #include "self_test_rand.h" #include "../implementations/rands/drbg_local.h" -#include "../../crypto/evp/evp_local.h" +#include "crypto/evp/evp_local.h" +#include "crypto/evp/legacy_meth.h" /* The size of a temp buffer used to read in data */ -#define INTEGRITY_BUF_SIZE (4096) -#define MAX_MD_SIZE 64 -#define MAC_NAME "HMAC" -#define DIGEST_NAME "SM3" +#define INTEGRITY_BUF_SIZE 4096 +#define SMTC_PASSWD_LEN 64 +#define SMTC_AUTH_SALT_LEN 64 +#define SMTC_AUTH_KEY_LEN 64 + +#define SMTC_AUTH_ID "SMTC" +#define SMTC_AUTH_TEXT1 "login" +#define SMTC_AUTH_TEXT2 "_admin_" +#define SMTC_AUTH_TIMEOUT 60 + +static int SMTC_conditional_error_check = 1; static CRYPTO_RWLOCK *self_test_lock = NULL; static CRYPTO_RWLOCK *smtc_state_lock = NULL; static int smtc_state = SMTC_STATE_INIT; -static unsigned char fixed_key[32] = { SMTC_KEY_ELEMENTS }; +static unsigned char pubkey[] = SMTC_KEY_STRING; +static unsigned char smtc_passwd[] = {SMTC_DEFAULT_PASSWORD_ELEMENTS}; + +#ifndef OPENSSL_NO_ATF_SLIBCE +IMPLEMENT_LEGACY_EVP_MD_METH(sm3_sw, SM3) +static EVP_MD *sm3_md = NULL; +static const EVP_MD *sw_sm3_md(void) +{ + if (sm3_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sm3, NID_SM2_with_SM3)) == NULL + || !EVP_MD_meth_set_result_size(md, SM3_DIGEST_LENGTH) + || !EVP_MD_meth_set_input_blocksize(md, SM3_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(EVP_MD *) + sizeof(SM3_CTX)) + || !EVP_MD_meth_set_flags(md, 0) + || !EVP_MD_meth_set_init(md, sm3_sw_init) + || !EVP_MD_meth_set_update(md, sm3_sw_update) + || !EVP_MD_meth_set_final(md, sm3_sw_final)) { + EVP_MD_meth_free(md); + md = NULL; + } + sm3_md = md; + } + return sm3_md; +} + +static int sw_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + static int digest_nids[2] = { NID_sm3, 0}; + int ok = 1; + if (!digest) { + *nids = digest_nids; + return OSSL_NELEM(digest_nids); + } + + switch (nid) { + case NID_sm3: + *digest = sw_sm3_md(); + break; + default: + ok = 0; + *digest = NULL; + break; + } + + return ok; +} + +static CRYPTO_ONCE engine_atf_slibce = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(init_engine_atf_slibce) +{ + int ok = 0; + ENGINE *engine = NULL; + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE + extern ENGINE *engine_atf_slibce_load(const char* engine_name); + engine = engine_atf_slibce_load("atf_slibce"); +# else + engine = ENGINE_by_id("atf_slibce"); +# endif + if (engine == NULL) + return 0; + + if(!ENGINE_ctrl_cmd_string(engine, "engine_load", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_load\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_alloc_prsrc", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_alloc_prsrc\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_enable_sm2", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_enable_sm2\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_enable_sm4", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_enable_sm4\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_enable_asym_kek", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_enable_asym_kek\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_enable_kek", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_enable_kek\n"); + goto end; + } + + if(!ENGINE_ctrl_cmd_string(engine, "engine_enable_kgen_kek", NULL, 0)) { + OSSL_TRACE(SMTC, "Failed to execute cmd: engine_enable_kgen_kek\n"); + goto end; + } + + if (!ENGINE_set_digests(engine, sw_digests)) + goto end; + + if (!ENGINE_set_default_pkey_meths(engine)) + goto end; + + ok = 1; +end: +# ifdef OPENSSL_NO_DYNAMIC_ENGINE + if (ok == 0) +# endif + { + ENGINE_free(engine); + } + return ok; +} +#endif static CRYPTO_ONCE smtc_self_test_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_smtc_self_test_init) @@ -52,93 +185,241 @@ DEFINE_RUN_ONCE_STATIC(do_smtc_self_test_init) } /* - * Calculate the HMAC SM3 of data read using a BIO and read_cb, and verify - * the result matches the expected value. + * Verify the signatre(SM2withSM3) of data read using a BIO and read_cb, and + * verify the result matches the expected value. * Return 1 if verified, or 0 if it fails. */ -static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb, +static int verify_integrity(OSSL_CORE_BIO *bio, + OSSL_FUNC_BIO_read_ex_fn read_ex_cb, unsigned char *expected, size_t expected_len, - OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev, - const char *event_type) + OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev) { - int ret = 0, status; - unsigned char out[MAX_MD_SIZE]; + int ok = 0, status; + BIO *pkey_bio = NULL; unsigned char buf[INTEGRITY_BUF_SIZE]; - size_t bytes_read = 0, out_len = 0; - EVP_MAC *mac = NULL; - EVP_MAC_CTX *ctx = NULL; - OSSL_PARAM params[2], *p = params; + size_t bytes_read = 0; + EVP_MD_CTX *mctx = NULL; + EVP_PKEY *pkey = NULL; - OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC); + OSSL_SELF_TEST_onbegin(ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY, + OSSL_SELF_TEST_DESC_INTEGRITY_VERIFY); - mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL); - if (mac == NULL) - goto err; - ctx = EVP_MAC_CTX_new(mac); - if (ctx == NULL) - goto err; + pkey_bio = BIO_new_mem_buf(pubkey, sizeof(pubkey)); + if (pkey_bio == NULL) + goto end; - *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0); - *p = OSSL_PARAM_construct_end(); + pkey = PEM_read_bio_PUBKEY_ex(pkey_bio, NULL, NULL, NULL, libctx, NULL); + if (pkey == NULL) + goto end; - if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params)) - goto err; + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + goto end; + + if (EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey) != 1) + goto end; while (1) { status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read); if (status != 1) break; - if (!EVP_MAC_update(ctx, buf, bytes_read)) - goto err; - } - if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out))) - goto err; - - OSSL_SELF_TEST_oncorrupt_byte(ev, out); - if (expected_len != out_len - || memcmp(expected, out, out_len) != 0) - goto err; - ret = 1; -err: - OSSL_SELF_TEST_onend(ev, ret); - EVP_MAC_CTX_free(ctx); - EVP_MAC_free(mac); - return ret; + if (EVP_DigestVerifyUpdate(mctx, buf, bytes_read) != 1) + goto end; + } + + OSSL_SELF_TEST_oncorrupt_byte(ev, expected); + + if (EVP_DigestVerifyFinal(mctx, expected, expected_len) != 1) + goto end; + + ok = 1; +end: + BIO_free(pkey_bio); + EVP_PKEY_free(pkey); + EVP_MD_CTX_free(mctx); + OSSL_SELF_TEST_onend(ev, ok); + return ok; } #define PASSWD_BUF_SIZE 1024 -static int verify_password(OSSL_LIB_CTX *libctx, unsigned char *password, - size_t pass_len, unsigned char *salt, - size_t salt_len) +static int do_auth(time_t ts, const char *text2, unsigned char *mac, + size_t mac_len, const unsigned char *mac_key, + size_t mac_key_len) { - int ret = 0; - char passphrase[PASSWD_BUF_SIZE]; - EVP_MD_CTX *mctx = NULL; - unsigned char buf[EVP_MAX_MD_SIZE]; + int ok = 0; + time_t now = time(NULL); + char buf[128]; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int md_len; + int buflen; + + if (ts > now || now - ts > SMTC_AUTH_TIMEOUT) + return 0; + + if (text2 == NULL || strcmp(text2, SMTC_AUTH_TEXT2) != 0) + return 0; + + buflen = snprintf(buf, sizeof(buf), "%ld%s%s", ts, SMTC_AUTH_ID, + SMTC_AUTH_TEXT1); + if (buflen < 0 || buflen >= (int)sizeof(buf)) + return 0; + + if (HMAC(EVP_sm3(), mac_key, mac_key_len, (const unsigned char *)buf, + buflen, md, &md_len) == NULL) + goto end; + + if (md_len != mac_len || memcmp(md, mac, md_len) != 0) { + OSSL_TRACE(SMTC, "Incorrect password\n"); + goto end; + } + + ok = 1; +end: + return ok; +} + +static int verify_password(OSSL_LIB_CTX *libctx, const char *conf_key, + const char *conf_salt, const char *kek_file, + const char *eng) +{ + int ok = 0; + time_t ts; + unsigned char buf[128]; + unsigned char *mac_key = NULL, *salt = NULL; + long mac_key_len, salt_len; + char passphrase[SMTC_PASSWD_LEN]; + unsigned char key[SMTC_AUTH_KEY_LEN]; + unsigned char mkey[SMTC_AUTH_KEY_LEN]; + int buflen, keklen; + size_t outlen; + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + ENGINE *engine = NULL; + BIO *bio = NULL, *kekbio = NULL; + EVP_PKEY *pkek = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char kekbuf[4096]; + + if (conf_key == NULL && conf_salt == NULL) { + if (EVP_read_pw_string(passphrase, sizeof(passphrase), + "Enter password: ", 0) != 0) + goto end; - if (password == NULL || pass_len != SM3_DIGEST_LENGTH || salt == NULL - || salt_len != SM3_DIGEST_LENGTH) + if (memcmp(passphrase, smtc_passwd, sizeof(smtc_passwd)) != 0) { + OSSL_TRACE(SMTC, "Incorrect password\n"); + goto end; + } + + ok = 1; goto end; + } + + if (conf_key == NULL || conf_salt == NULL) + goto end; + + mac_key = OPENSSL_hexstr2buf(conf_key, &mac_key_len); + if (mac_key == NULL) + goto end; + + salt = OPENSSL_hexstr2buf(conf_salt, &salt_len); + if (salt == NULL || salt_len != SMTC_AUTH_SALT_LEN) + goto end; + + ts = time(NULL); if (EVP_read_pw_string(passphrase, sizeof(passphrase), "Enter password: ", 0) != 0) goto end; - if ((mctx = EVP_MD_CTX_new()) == NULL - || !EVP_DigestInit_ex(mctx, EVP_sm3(), NULL) - || !EVP_DigestUpdate(mctx, salt, salt_len) - || !EVP_DigestUpdate(mctx, passphrase, strlen(passphrase)) - || !EVP_DigestFinal_ex(mctx, buf, NULL)) + if (PKCS5_PBKDF2_HMAC(passphrase, strlen(passphrase), salt, salt_len, + 10000, EVP_sm3(), sizeof(key), key) != 1) + goto end; + + buflen = snprintf((char *)buf, sizeof(buf), "%ld%s%s", ts, SMTC_AUTH_ID, + SMTC_AUTH_TEXT1); + if (buflen < 0 || buflen >= (int)sizeof(buf)) + goto end; + + if (HMAC(EVP_sm3(), key, sizeof(key), buf, buflen, mac, &maclen) == NULL) + goto end; + + if (eng) { + engine = ENGINE_by_id(eng); + if (engine == NULL) { + OSSL_TRACE1(SMTC, "Can't load engine %s\n", eng); + goto end; + } + } + + kekbio = BIO_new_file(kek_file, "rb"); + if (kekbio == NULL) { + OSSL_TRACE1(SMTC, "Can't open auth kek file %s\n", kek_file); + goto end; + } + + keklen = BIO_read(kekbio, kekbuf, sizeof(kekbuf) - 1); + BIO_free(kekbio); + + if (keklen <= 0) { + OSSL_TRACE1(SMTC, "Error reading auth kek %s\n", kek_file); + goto end; + } + + kekbuf[keklen] = '\0'; + + /* + * atf_slibce engine doesn't support ENGINE_load_private_key(), use + * PEM_read_bio_PrivateKey() instead + */ +#ifdef OPENSSL_NO_ATF_SLIBCE + if (engine) { + pkek = ENGINE_load_private_key(engine, (const char *)kekbuf, NULL, + NULL); + } else { +#endif + bio = BIO_new_mem_buf((const void *)kekbuf, keklen); + if (bio == NULL) + goto end; + + pkek = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); +#ifdef OPENSSL_NO_ATF_SLIBCE + } +#endif + + if (pkek == NULL) goto end; - if (memcmp(buf, password, pass_len)) + ctx = EVP_PKEY_CTX_new(pkek, engine); + if (ctx == NULL) + goto end; + + outlen = sizeof(mkey); + + if (EVP_PKEY_decrypt_init(ctx) != 1 + || EVP_PKEY_decrypt(ctx, mkey, &outlen, mac_key, mac_key_len) != 1 + || outlen != sizeof(mkey)) goto end; - ret = 1; + if (do_auth(ts, SMTC_AUTH_TEXT2, mac, maclen, mkey, outlen) != 1) + goto end; + + ok = 1; end: - EVP_MD_CTX_free(mctx); - return ret; + if (!ok) { + OSSL_TRACE(SMTC, "Authentication failed\n"); + OSSL_syslog(LOG_ERR, "[SMTC] Admin login failed!\n"); + ossl_sleep(3000); + } else { + OSSL_syslog(LOG_INFO, "[SMTC] Admin login success\n"); + } + EVP_PKEY_CTX_free(ctx); + OPENSSL_free(mac_key); + OPENSSL_free(salt); + ENGINE_free(engine); + EVP_PKEY_free(pkek); + BIO_free_all(bio); + return ok; } int smtc_prov_get_state(void) @@ -161,82 +442,108 @@ static void smtc_set_state(int state) smtc_state = state; CRYPTO_THREAD_unlock(smtc_state_lock); } + + if (state == SMTC_STATE_ERROR) { + OSSL_syslog(LOG_ERR, "[SMTC] SMTC module entering error state\n"); + } else if (state == SMTC_STATE_RUNNING) { + OSSL_syslog(LOG_INFO, "[SMTC] SMTC module ready\n"); + } } -static int get_bit(const unsigned char *buf, int m) +/* + * GM/T 0105-2021 Appendix D.3, Adaptive Proportion Test + */ +static ossl_unused int smtc_adaptive_proportion_test( + const unsigned char *entropy, size_t len, int W, int C) { - if (m < 0) + size_t i; + int cnt = 0; + unsigned char sample = 0; + + if (entropy == NULL) return 0; - return (buf[m / 8] << (m % 8) >> 7) & 1; + for (i = 0; i < len; i++) { + if (i % W == 0) { + sample = entropy[i]; + cnt = 1; + } else if (entropy[i] == sample) { + cnt++; + if (cnt >= C) + return 0; + } + } + + return 1; } -/* - * GM/T 0105-2021 Appendix D.3, Adaptive Proportion Test - */ static int ossl_smtc_rng_poweron_test(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { - int res = 0, i; - int W = 1024, C = 670, cnt; - unsigned char buf[W / 8]; - size_t left = sizeof(buf); - size_t len, entropy_len; - int sample; + int ok = 0; unsigned char *entropy = NULL; - EVP_RAND *rand = NULL; - EVP_RAND_CTX *ctx = NULL; - PROV_DRBG *drbg; + size_t ret = 0; +#if defined(OPENSSL_RAND_SEED_RTCODE) || defined(OPENSSL_RAND_SEED_RTMEM) \ + || defined(OPENSSL_RAND_SEED_RTSOCK) + size_t len = 1024, W = 512, C = 13; +#endif OSSL_SELF_TEST_onbegin(st, "Poweron_RNG_Test", "RNG"); - rand = EVP_RAND_fetch(libctx, "HASH-DRBG", NULL); - if (rand == NULL) - goto end; - - ctx = EVP_RAND_CTX_new(rand, NULL); - if (ctx == NULL) +#if defined(OPENSSL_RAND_SEED_RTCODE) + ret = ossl_rand_get_entropy_from_source(RAND_ENTROPY_SOURCE_RTCODE, + &entropy, 0, len, len); + if (ret == len) { + if (!smtc_adaptive_proportion_test(entropy, len, W, C)) + goto end; + } else { goto end; + } - drbg = (PROV_DRBG *)ctx->algctx; - if (drbg == NULL) - goto end; + ossl_rand_cleanup_entropy(NULL, entropy, len); + entropy = NULL; +#endif - while (left > 0) { - entropy_len - = ossl_prov_get_entropy(drbg->provctx, &entropy, left * 8, - drbg->min_entropylen, drbg->max_entropylen); - if (entropy_len == 0) +#if defined(OPENSSL_RAND_SEED_RTMEM) + entropy = NULL; + ret = ossl_rand_get_entropy_from_source(RAND_ENTROPY_SOURCE_RTMEM, + &entropy, 0, len, len); + if (ret == len) { + if (!smtc_adaptive_proportion_test(entropy, len, W, C)) goto end; + } else { + goto end; + } - len = entropy_len > left ? left : entropy_len; - memcpy(buf + (sizeof(buf) - left), entropy, len); - left -= len; + ossl_rand_cleanup_entropy(NULL, entropy, len); + entropy = NULL; +#endif - ossl_prov_cleanup_entropy(drbg->provctx, entropy, entropy_len); - entropy = NULL; +#if defined(OPENSSL_RAND_SEED_RTSOCK) + ret = ossl_rand_get_entropy_from_source(RAND_ENTROPY_SOURCE_RTSOCK, + &entropy, 0, len, len); + if (ret == len) { + if (!smtc_adaptive_proportion_test(entropy, len, W, C)) + goto end; + } else { + goto end; } - sample = get_bit(buf, 0); - cnt = 1; + ossl_rand_cleanup_entropy(NULL, entropy, len); + entropy = NULL; +#endif - for (i = 1; i < W; i++) { - int cur = get_bit(buf, i); - if (cur == sample) { - cnt++; - if (cnt >= C) - goto end; - } else { - sample = cur; - cnt = 1; - } + ok = 1; +#if defined(OPENSSL_RAND_SEED_RTCODE) || defined(OPENSSL_RAND_SEED_RTMEM) \ + || defined(OPENSSL_RAND_SEED_RTSOCK) +end: +#endif + if (entropy) { + ossl_rand_cleanup_entropy(NULL, entropy, ret); + entropy = NULL; } - res = 1; -end: - OSSL_SELF_TEST_onend(st, res); - EVP_RAND_CTX_free(ctx); - EVP_RAND_free(rand); - return res; + OSSL_SELF_TEST_onend(st, ok); + return ok; } /* This API is triggered either on loading of the SMTC module or on demand */ @@ -244,16 +551,21 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) { int ok = 0; int loclstate; - long checksum_len; - long pass_len, salt_len; + long siglen; OSSL_CORE_BIO *bio_module = NULL; - unsigned char *module_checksum = NULL; - unsigned char *password = NULL, *salt = NULL; + unsigned char *module_sig = NULL; OSSL_SELF_TEST *ev = NULL; if (!RUN_ONCE(&smtc_self_test_init, do_smtc_self_test_init)) return 0; +#ifndef OPENSSL_NO_ATF_SLIBCE + if (!RUN_ONCE(&engine_atf_slibce, init_engine_atf_slibce)) { + OSSL_TRACE(SMTC, "Failed to load atf_slibce engine\n"); + goto end; + } +#endif + if (!CRYPTO_THREAD_write_lock(self_test_lock)) return 0; if (!CRYPTO_THREAD_read_lock(smtc_state_lock)) { @@ -285,25 +597,24 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) goto end; #ifndef OPENSSL_NO_SMTC_DEBUG - if (st->verify_mac == NULL || atoi(st->verify_mac) != 0) + if (st->verify_sig == NULL || atoi(st->verify_sig) != 0) #endif { - if (st->module_filename == NULL || st->module_checksum_data == NULL) { + if (st->module_filename == NULL || st->module_sig == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); goto end; } bio_module = ossl_prov_bio_new_file(st->module_filename, "rb"); - module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data, - &checksum_len); - if (bio_module == NULL || module_checksum == NULL) { + module_sig = OPENSSL_hexstr2buf(st->module_sig, &siglen); + if (bio_module == NULL || module_sig == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); goto end; } - if (!verify_integrity(bio_module, ossl_prov_bio_read_ex, - module_checksum, checksum_len, st->libctx, - ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) { + if (!verify_integrity(bio_module, ossl_prov_bio_read_ex, module_sig, + siglen, st->libctx, ev)) { + OSSL_TRACE(SMTC, "Module integrity verification failed\n"); ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE); goto end; } @@ -319,12 +630,20 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) if ((st->randomness_poweron_test == NULL || atoi(st->randomness_poweron_test) != 0) - && !smtc_randomness_test_poweron(ev, st->libctx)) { + && (!smtc_rand_poweron_test(ev, 0) +#ifdef SDF_LIB + || !smtc_rand_poweron_test(ev, 1) +#endif + )) { ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE); goto end; } } else { // SMTC_STATE_SELFTEST_WHILE_RUNNING - if (!smtc_randomness_test_single(ev, st->libctx)) { + if (!smtc_rand_single_test(ev, 0) +#ifdef SDF_LIB + || !smtc_rand_single_test(ev, 1) +#endif + ) { ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE); goto end; } @@ -339,46 +658,56 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) if (st->verify_pass == NULL || atoi(st->verify_pass) != 0) #endif if (loclstate == SMTC_STATE_SELFTEST_WHILE_IN_INIT) { - if (st->admin_pass == NULL || st->admin_salt == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); - goto end; - } - - password = OPENSSL_hexstr2buf(st->admin_pass, &pass_len); - salt = OPENSSL_hexstr2buf(st->admin_salt, &salt_len); - if (password == NULL || salt == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); - goto end; - } - - if (!verify_password(st->libctx, password, pass_len, salt, salt_len)) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); + if (!verify_password(st->libctx, st->auth_key, st->auth_salt, st->kek, + st->eng)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INCORRECT_PASSWORD); goto end; } } ok = 1; end: - OPENSSL_free(password); - OPENSSL_free(salt); OSSL_SELF_TEST_free(ev); - OPENSSL_free(module_checksum); + OPENSSL_free(module_sig); if (st != NULL) ossl_prov_bio_free(bio_module); - if (ok) + if (ok) { + OSSL_syslog(LOG_INFO, "[SMTC] Self-test passed\n"); smtc_set_state(SMTC_STATE_RUNNING); - else + } else { + OSSL_syslog(LOG_ERR, "[SMTC] Self-test failed\n"); smtc_set_state(SMTC_STATE_ERROR); + } CRYPTO_THREAD_unlock(self_test_lock); return ok; } -int smtc_prov_is_running(void) +void SELF_TEST_disable_conditional_error_state(void) +{ + SMTC_conditional_error_check = 0; +} + +void ossl_set_error_state(const char *type) +{ + int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0); + + if (!cond_test || (SMTC_conditional_error_check == 1)) { + smtc_set_state(SMTC_STATE_ERROR); + ERR_raise(ERR_LIB_PROV, PROV_R_SMTC_MODULE_ENTERING_ERROR_STATE); + } else { + ERR_raise(ERR_LIB_PROV, PROV_R_SMTC_MODULE_CONDITIONAL_ERROR); + } +} + +int ossl_prov_is_running(void) { int res; + if (!RUN_ONCE(&smtc_self_test_init, do_smtc_self_test_init)) + return 0; + if (!CRYPTO_THREAD_read_lock(smtc_state_lock)) return 0; res = smtc_state == SMTC_STATE_RUNNING diff --git a/providers/smtc/self_test.h b/providers/smtc/self_test.h index 3001fa92b..ffbec9618 100644 --- a/providers/smtc/self_test.h +++ b/providers/smtc/self_test.h @@ -19,15 +19,17 @@ typedef struct self_test_post_params_st { const char *module_filename; /* Module file to perform MAC on */ - const char *module_checksum_data; /* Expected module MAC integrity */ - const char *show_selftest; /* Output selftest results */ - const char *admin_pass; /* Admin password */ - const char *admin_salt; /* Salt of password */ - const char *rng_poweron_test; /* 熵源上电健康测试 */ - const char *rng_continuous_test; /* 熵源连续健康测试 */ - const char *randomness_poweron_test; /* 随机数上电自检 */ + const char *module_sig; /* Signature of module */ + const char *auth_key; /* key of HMAC, PBKDF(password, salt) */ + const char *auth_salt; /* Salt of PBKDF */ + const char *kek; /* key for encrypting HMAC key */ + const char *eng; /* Engine ID */ + const char *syslog; /* syslog switch */ + const char *rng_poweron_test; /* Entropy power-on health test */ + const char *rng_continuous_test; /* Entropy continuous health test */ + const char *randomness_poweron_test; /* Random power-on self-test */ #ifndef OPENSSL_NO_SMTC_DEBUG - const char *verify_mac; + const char *verify_sig; const char *verify_pass; #endif diff --git a/providers/smtc/self_test_data.inc b/providers/smtc/self_test_data.inc index be618233b..741466bf3 100644 --- a/providers/smtc/self_test_data.inc +++ b/providers/smtc/self_test_data.inc @@ -66,7 +66,7 @@ typedef struct st_kat_kdf_st { size_t expected_len; } ST_KAT_KDF; -typedef struct st_kat_drbg_st { +typedef struct st_kat_smtc_drbg_st { const char *desc; const char *algorithm; const char *param_name; @@ -85,9 +85,17 @@ typedef struct st_kat_drbg_st { size_t entropyaddin1len; const unsigned char *entropyaddin2; size_t entropyaddin2len; + const unsigned char *V; + size_t Vlen; + const unsigned char *C; + size_t Clen; + const unsigned char *V1; + size_t V1len; + const unsigned char *C1; + size_t C1len; const unsigned char *expected; size_t expectedlen; -} ST_KAT_DRBG; +} ST_KAT_SMTC_DRBG; typedef struct st_kat_kas_st { const char *desc; @@ -105,7 +113,10 @@ typedef struct st_kat_sign_st { const char *desc; const char *algorithm; const char *mdalgorithm; + int sign; const ST_KAT_PARAM *key; + const unsigned char *dgst; + size_t dgst_len; const unsigned char *sig_expected; /* Set to NULL if this value changes */ size_t sig_expected_len; } ST_KAT_SIGN; @@ -155,6 +166,20 @@ static const ST_KAT_DIGEST st_kat_digest_tests[] = /*- CIPHER TEST DATA */ #ifndef OPENSSL_NO_SM4 +/* SM4-ECB test data */ +static const unsigned char sm4_ecb_key[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +static const unsigned char sm4_ecb_pt[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +static const unsigned char sm4_ecb_ct[] = { + 0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E, + 0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46, +}; + /* SM4-CBC test data */ static const unsigned char sm4_cbc_key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, @@ -212,6 +237,16 @@ static const unsigned char sm4_gcm_tag[] = { static const ST_KAT_CIPHER st_kat_cipher_tests[] = { #ifndef OPENSSL_NO_SM4 + { + { + "SM4_ECB", + "SM4-ECB", + ITM(sm4_ecb_pt), + ITM(sm4_ecb_ct) + }, + CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT, + ITM(sm4_ecb_key), + }, { { "SM4_CBC", @@ -223,6 +258,7 @@ static const ST_KAT_CIPHER st_kat_cipher_tests[] = ITM(sm4_cbc_key), ITM(sm4_cbc_iv), }, +/* { { "SM4_GCM", @@ -236,6 +272,7 @@ static const ST_KAT_CIPHER st_kat_cipher_tests[] = ITM(sm4_gcm_aad), ITM(sm4_gcm_tag), }, +*/ #endif }; @@ -364,21 +401,60 @@ static const unsigned char drbg_hash_sm3_pr_addin1[] = { 0xb2, 0x94, 0x73, 0xe2, 0xfd, 0x39, 0x51, 0x2e, 0xad, 0x45, 0x69, 0xee, 0xe3, 0xe3, 0x80, 0x33, 0x14, 0xab, 0xa7, 0xa3 }; +static const unsigned char drbg_hash_sm3_V_expected[] = { + 0xd3, 0x51, 0x2a, 0xe4, 0x49, 0x45, 0x5b, 0xfc, 0x59, 0x63, 0x5c, 0xad, + 0xd2, 0xd9, 0xe0, 0xa3, 0x17, 0x05, 0xbb, 0x0e, 0x11, 0xc1, 0xc8, 0xce, + 0xfe, 0x6f, 0xd8, 0x87, 0x90, 0x0b, 0xfb, 0x95, 0xf0, 0x7c, 0xb2, 0x4c, + 0x85, 0x93, 0x99, 0x66, 0x89, 0x4f, 0xd6, 0x44, 0x6f, 0xb4, 0xfe, 0xb1, + 0xb1, 0x5b, 0x57, 0xd5, 0x88, 0x70, 0x3c, +}; +static const unsigned char drbg_hash_sm3_C_expected[] = { + 0xf6, 0x8a, 0x6f, 0x03, 0x6f, 0x26, 0xbb, 0x90, 0xc4, 0x3d, 0x08, 0x0e, + 0x99, 0x9b, 0x69, 0xba, 0x59, 0xc1, 0x1e, 0xa7, 0xd8, 0xbb, 0xb4, 0xe8, + 0x59, 0xbc, 0x77, 0x69, 0x27, 0x73, 0xbd, 0x66, 0xf4, 0xc2, 0xac, 0xd4, + 0xc7, 0x80, 0xb6, 0xf7, 0xcf, 0xe3, 0x51, 0xff, 0x0e, 0xec, 0x77, 0xed, + 0x45, 0xb3, 0x3b, 0xb1, 0xd6, 0x64, 0xce, +}; +static const unsigned char drbg_hash_sm3_V1_expected[] = { + 0x8a, 0xb9, 0x3c, 0x9d, 0x9f, 0xfc, 0xc0, 0x64, 0x54, 0x58, 0x48, 0x4c, + 0xa0, 0x0c, 0x01, 0x5f, 0x97, 0x24, 0xc7, 0x07, 0xed, 0x2c, 0x67, 0x5d, + 0xc5, 0xce, 0x7c, 0xf7, 0xba, 0x40, 0x96, 0x2a, 0x77, 0x5a, 0x9c, 0x79, + 0xa0, 0x37, 0xbb, 0xec, 0xb4, 0x48, 0xc0, 0xf2, 0x82, 0x03, 0x33, 0x7c, + 0xa9, 0x95, 0xb3, 0x9f, 0x9f, 0x6f, 0x66, +}; +static const unsigned char drbg_hash_sm3_C1_expected[] = { + 0xe7, 0xca, 0x05, 0x6c, 0x83, 0xcb, 0x42, 0x0e, 0x19, 0xf2, 0x9b, 0xdb, + 0x14, 0x11, 0xf3, 0x8a, 0x07, 0x13, 0xf4, 0x58, 0x43, 0x6d, 0xd6, 0x15, + 0x6e, 0xea, 0x6a, 0x77, 0x45, 0x6f, 0x24, 0x1b, 0xcf, 0x04, 0x15, 0xa1, + 0x8e, 0x63, 0x48, 0x67, 0xae, 0x72, 0x4d, 0xa0, 0xbf, 0x26, 0xae, 0x7f, + 0x5e, 0xc0, 0x97, 0x53, 0x4b, 0x33, 0x63, +}; static const unsigned char drbg_hash_sm3_pr_expected[] = { - 0xc0, 0xd1, 0xef, 0x6f, 0x52, 0xf4, 0x2a, 0xd7, 0xa1, 0xaa, 0x91, 0xbc, - 0x11, 0x7b, 0xdc, 0xa0, 0x74, 0xc0, 0xda, 0x26, 0xa9, 0xba, 0xb1, 0x6a, - 0x0e, 0x43, 0xa0, 0x1b, 0x7d, 0xa5, 0x85, 0xa9, 0xb5, 0x1b, 0xa7, 0xa3, - 0x81, 0x03, 0x70, 0x41, 0x38, 0xf9, 0x40, 0xb4, 0x20, 0x11, 0x99, 0x06, - 0x25, 0x14, 0x88, 0x0a, 0xf7, 0xd6, 0x03, 0x5d, 0x08, 0x13, 0xba, 0x7e, - 0x78, 0xb1, 0x76, 0x75, 0x49, 0x29, 0x7a, 0xf9, 0x54, 0x13, 0xcc, 0x6d, - 0x38, 0x63, 0x1a, 0xd5, 0x9f, 0xc4, 0x1a, 0xdb, 0x6d, 0x10, 0x68, 0x8d, - 0xdf, 0x64, 0xdc, 0x7e, 0xe2, 0x4a, 0x16, 0xde, 0x9a, 0x82, 0x11, 0x00, - 0xd5, 0xc9, 0x77, 0xf8, 0x81, 0x64, 0x66, 0xdb, 0x2a, 0x40, 0x27, 0xc0, - 0x61, 0xb2, 0x05, 0xc4, 0xa7, 0x66, 0xa3, 0x64, 0x61, 0x29, 0xb2, 0x3f, - 0x11, 0x8c, 0x50, 0xbf, 0x8b, 0x64, 0xc0, 0x72, -}; - -static const ST_KAT_DRBG st_kat_drbg_tests[] = + 0xbb, 0xb8, 0x89, 0x31, 0x02, 0x7a, 0xf6, 0x59, 0x27, 0xd6, 0x67, 0x98, + 0xe0, 0xd3, 0xc0, 0x49, 0x38, 0x71, 0x2e, 0x4d, 0x85, 0x62, 0x88, 0x2c, + 0xb4, 0xe3, 0x4d, 0x6f, 0x08, 0xa1, 0xac, 0xcc, 0xff, 0x2b, 0x53, 0xca, + 0x38, 0x52, 0x0b, 0xb9, 0xab, 0x58, 0x87, 0x7c, 0x1c, 0x57, 0xf2, 0x36, + 0xfe, 0x6c, 0x81, 0x91, 0x9e, 0x62, 0x88, 0xb1, 0x8c, 0x76, 0x94, 0xc5, + 0x23, 0x36, 0x48, 0xa8, 0x57, 0xcc, 0x2d, 0x7d, 0x02, 0x9b, 0xc3, 0x9d, + 0xd4, 0x6b, 0x60, 0x63, 0x15, 0xfc, 0x1b, 0xa0, 0x04, 0x17, 0x56, 0x31, + 0x78, 0x66, 0x10, 0xe7, 0x22, 0xe7, 0x53, 0x7d, 0x4f, 0xcd, 0x90, 0x02, + 0xd4, 0xfa, 0x1b, 0xda, 0xca, 0x66, 0xd2, 0x25, 0xa2, 0x47, 0x97, 0x87, + 0x26, 0xbc, 0xeb, 0x6c, 0x18, 0x58, 0x62, 0x07, 0x61, 0x45, 0xf0, 0x76, + 0xd5, 0x1a, 0x21, 0xba, 0xfc, 0x42, 0xf2, 0xc6, 0x98, 0x63, 0x49, 0x45, + 0xde, 0xdb, 0xfa, 0x14, 0x34, 0xc7, 0x30, 0xbe, 0x07, 0xfd, 0xee, 0x55, + 0x30, 0xce, 0xab, 0x54, 0x61, 0xee, 0xcd, 0xd9, 0xdd, 0x34, 0x26, 0x47, + 0xed, 0xf4, 0xbb, 0xa8, 0x32, 0xc6, 0xf6, 0xbc, 0x96, 0xc3, 0x56, 0x32, + 0xf1, 0x4d, 0x3b, 0x8f, 0x10, 0x01, 0x02, 0x69, 0x25, 0xff, 0x4a, 0x71, + 0x6e, 0x8d, 0x78, 0xd7, 0x1e, 0xb1, 0xb7, 0x17, 0x3f, 0x30, 0xd4, 0xa0, + 0x85, 0xe8, 0x87, 0xba, 0x63, 0x63, 0x9f, 0x32, 0x52, 0x27, 0x77, 0xcb, + 0x91, 0x01, 0x0d, 0xbd, 0x29, 0x06, 0xa4, 0x7d, 0x51, 0x58, 0xe3, 0xc1, + 0x29, 0x14, 0xeb, 0x51, 0x30, 0x45, 0xb0, 0x19, 0x2b, 0x4b, 0xe3, 0x9d, + 0xea, 0x40, 0x13, 0xb0, 0xcc, 0x9f, 0x2b, 0xda, 0xe3, 0xd7, 0x49, 0xdd, + 0x90, 0x46, 0xcc, 0x32, 0x28, 0xcc, 0xd5, 0x2e, 0x3f, 0x10, 0x79, 0x05, + 0xa9, 0x28, 0xa0, 0x79, +}; + +static const ST_KAT_SMTC_DRBG st_kat_drbg_tests[] = { { OSSL_SELF_TEST_DESC_DRBG_HASH, @@ -390,6 +466,10 @@ static const ST_KAT_DRBG st_kat_drbg_tests[] = ITM(drbg_hash_sm3_pr_entropyinpr1), ITM(drbg_hash_sm3_pr_addin0), ITM(drbg_hash_sm3_pr_addin1), + ITM(drbg_hash_sm3_V_expected), + ITM(drbg_hash_sm3_C_expected), + ITM(drbg_hash_sm3_V1_expected), + ITM(drbg_hash_sm3_C1_expected), ITM(drbg_hash_sm3_pr_expected) }, }; @@ -703,6 +783,21 @@ static const ST_KAT_PARAM sm2_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, sm2_pub), ST_KAT_PARAM_END() }; + +static const unsigned char dgst[] = { + 0xD7, 0xAD, 0x39, 0x7F, 0x6F, 0xFA, 0x5D, 0x4F, 0x7F, 0x11, 0xE7, 0x21, + 0x7F, 0x24, 0x16, 0x07, 0xDC, 0x30, 0x61, 0x8C, 0x23, 0x6D, 0x2C, 0x09, + 0xC1, 0xB9, 0xEA, 0x8F, 0xDA, 0xDE, 0xE2, 0xE8, +}; + +static const unsigned char sig_expected[] = { + 0x30, 0x46, 0x02, 0x21, 0x00, 0xAB, 0x1D, 0xB6, 0x4D, 0xE7, 0xC4, 0x0E, + 0xDB, 0xDE, 0x66, 0x51, 0xC9, 0xB8, 0xEB, 0xDB, 0x80, 0x46, 0x73, 0xDB, + 0x83, 0x6E, 0x5D, 0x5C, 0x7F, 0xE1, 0x5D, 0xCF, 0x9E, 0xD2, 0x72, 0x50, + 0x37, 0x02, 0x21, 0x00, 0xEB, 0xA7, 0x14, 0x45, 0x1F, 0xF6, 0x9B, 0x0B, + 0xB9, 0x30, 0xB3, 0x79, 0xE1, 0x92, 0xE7, 0xCD, 0x5F, 0xA6, 0xE3, 0xC4, + 0x1C, 0x7F, 0xBD, 0x83, 0x03, 0xB7, 0x99, 0xAB, 0x54, 0xA5, 0x46, 0x21, +}; #endif static const unsigned char sm2_asym_plaintext_encrypt[] = { @@ -729,15 +824,26 @@ static const unsigned char sm2_asym_expected_encrypt[] = { static const ST_KAT_SIGN st_kat_sign_tests[] = { #ifndef OPENSSL_NO_SM2 { - OSSL_SELF_TEST_DESC_SIGN_SM2, + OSSL_SELF_TEST_DESC_SIGN_SM2_SIGN, "SM2", "SM3", + 1, sm2_key, + ITM(dgst), /* * The SM2 signature changes each time due to it using a random k. * So there is no expected KAT for this case. */ }, + { + OSSL_SELF_TEST_DESC_SIGN_SM2_VERIFY, + "SM2", + "SM3", + 0, + sm2_pub_key, + ITM(dgst), + ITM(sig_expected), + }, #endif }; @@ -759,7 +865,7 @@ static const ST_KAT_ASYM_CIPHER st_kat_asym_cipher_tests[] = { OSSL_SELF_TEST_DESC_ASYM_SM2_DEC, "SM2", 0, - sm2_priv_key, + sm2_key, sm2_enc_params, ITM(sm2_asym_expected_encrypt), ITM(sm2_asym_plaintext_encrypt), diff --git a/providers/smtc/self_test_kats.c b/providers/smtc/self_test_kats.c index 4c4c95177..aa9094f0c 100644 --- a/providers/smtc/self_test_kats.c +++ b/providers/smtc/self_test_kats.c @@ -12,10 +12,22 @@ #include #include #include +#include +#include +#include +#include +#include "crypto/evp.h" #include "internal/cryptlib.h" #include "internal/nelem.h" #include "self_test.h" #include "self_test_data.inc" +#include "../implementations/rands/drbg_local.h" +#include "../../crypto/evp/evp_local.h" +#include "../../crypto/sdf/sdf_local.h" +#ifdef SDF_LIB +# include "sdfe_api.h" +#endif + static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) @@ -247,13 +259,15 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, return ret; } -static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, +static int self_test_drbg(const ST_KAT_SMTC_DRBG *t, OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 0; unsigned char out[256]; EVP_RAND *rand; EVP_RAND_CTX *test = NULL, *drbg = NULL; + PROV_DRBG *prov_drbg = NULL; + PROV_DRBG_HASH *hash_drbg = NULL; unsigned int strength = 256; int prediction_resistance = 1; /* Causes a reseed */ OSSL_PARAM drbg_params[3] = { @@ -289,9 +303,6 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, drbg_params[0] = OSSL_PARAM_construct_utf8_string(t->param_name, t->param_value, 0); - /* This is only used by HMAC-DRBG but it is ignored by the others */ - drbg_params[1] = - OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, "HMAC", 0); if (!EVP_RAND_CTX_set_params(drbg, drbg_params)) goto err; @@ -308,6 +319,18 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, NULL)) goto err; + prov_drbg = (PROV_DRBG *)drbg->algctx; + if (prov_drbg == NULL) + goto err; + + hash_drbg = (PROV_DRBG_HASH *)prov_drbg->data; + if (hash_drbg == NULL) + goto err; + + if (memcmp(hash_drbg->V, t->V, t->Vlen) != 0 + || memcmp(hash_drbg->C, t->C, t->Clen) != 0) + goto err; + drbg_params[0] = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, (void *)t->entropyinpr1, @@ -315,9 +338,13 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, if (!EVP_RAND_CTX_set_params(test, drbg_params)) goto err; - if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength, - prediction_resistance, - t->entropyaddin1, t->entropyaddin1len)) + if (EVP_RAND_reseed(drbg, prediction_resistance, + t->entropyinpr1, t->entropyinpr1len, + t->entropyaddin1, t->entropyaddin1len) != 1) + goto err; + + if (memcmp(hash_drbg->V, t->V1, t->V1len) != 0 + || memcmp(hash_drbg->C, t->C1, t->C1len) != 0) goto err; drbg_params[0] = @@ -358,8 +385,128 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, return ret; } -static int self_test_sign(const ST_KAT_SIGN *t, - OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +#ifdef SDF_LIB +static int bitmap_is_inuse(uint64_t *pu64, int32_t index) +{ + + int32_t pos, offset; + uint64_t mask; + + mask = 0x1ull; + + pos = index >> 6; + offset = (63 - (index & 0x3f)); + mask <<= offset; + + return (pu64[pos] & mask) ? 1 : 0; +} + +static int self_test_sign_with_sdf(const ST_KAT_SIGN *t, OSSL_SELF_TEST *st, + OSSL_LIB_CTX *libctx) +{ + int ok = 0; + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + OSSL_ECCrefPrivateKey privkey; + OSSL_ECCrefPublicKey pubkey; + sdfe_bitmap_t bitmap; + sdfe_asym_key_ecc_t asym; + const ST_KAT_PARAM *param; + OSSL_ECCSignature sig; + uint32_t cnt, i; + int index = -1; + const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; + + if (t->sig_expected == NULL) + typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE; + + OSSL_SELF_TEST_onbegin(st, typ, t->desc); + + memset(&privkey, 0, sizeof(privkey)); + memset(&pubkey, 0, sizeof(pubkey)); + memset(&asym, 0, sizeof(asym)); + memset(&login_arg, 0, sizeof(login_arg)); + + strcpy((char *)login_arg.name, "admin"); + login_arg.passwd = (uint8_t *)"123123"; + login_arg.passwd_len = 6; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + bitmap.start = 0; + bitmap.cnt = SDFE_BITMAP_U64_MAX_CNT; + if (SDFE_BitmapAsymKey(hSessionHandle, SDFE_ASYM_KEY_AREA_ENC, + SDFE_ASYM_KEY_TYPE_SM2, &bitmap) != OSSL_SDR_OK) + goto end; + + cnt = bitmap.cnt << 6; + for(i = 0; i < cnt; i++){ + if(!bitmap_is_inuse(bitmap.bitmap, i)) { + index = i; + break; + } + } + + if (index < 0) + goto end; + + asym.area = SDFE_ASYM_KEY_AREA_SIGN; + asym.index = index; + asym.type = SDFE_ASYM_KEY_TYPE_SM2; + asym.privkey_bits = 256; + asym.privkey_len = asym.privkey_bits >> 3; + asym.pubkey_bits = 256; + asym.pubkey_len = (asym.pubkey_bits >> 3) << 1; + + for (param = t->key; param->data; param++) { + if (strcmp(param->name, OSSL_PKEY_PARAM_PUB_KEY) == 0) { + pubkey.bits = 256; + memcpy(pubkey.x + sizeof(pubkey.x) - 32, + (unsigned char *)param->data + 1, 32); + memcpy(pubkey.y + sizeof(pubkey.y) - 32, + (unsigned char *)param->data + 1 + 32, 32); + } else if (strcmp(param->name, OSSL_PKEY_PARAM_PRIV_KEY) == 0) { + privkey.bits = 256; + memcpy(privkey.K + sizeof(privkey.K) - param->data_len, param->data, + param->data_len); + } + } + + memcpy(asym.pubkey, &pubkey, sizeof(pubkey)); + memcpy(asym.privkey, &privkey, sizeof(privkey)); + + if (SDFE_ImportECCKey(hSessionHandle, &asym, NULL) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_GetPrivateKeyAccessRight(hSessionHandle, index, NULL, 0) + != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_InternalSign_ECC(hSessionHandle, index, + (unsigned char *)t->dgst, + t->dgst_len, &sig) != OSSL_SDR_OK) + goto end; + + ok = 1; +end: + (void)SDFE_DelECCKey(hSessionHandle, asym.area, index); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); + OSSL_SELF_TEST_onend(st, ok); + return ok; +} +#endif + +static int self_test_sign(const ST_KAT_SIGN *t, OSSL_SELF_TEST *st, + OSSL_LIB_CTX *libctx) { int ret = 0; OSSL_PARAM *params = NULL, *params_sig = NULL; @@ -369,13 +516,13 @@ static int self_test_sign(const ST_KAT_SIGN *t, unsigned char sig[256]; BN_CTX *bnctx = NULL; size_t siglen = sizeof(sig); - static const unsigned char dgst[] = { - 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, - 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, - 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 - }; const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; +#ifdef SDF_LIB + if (t->sign) + return self_test_sign_with_sdf(t, st, libctx); +#endif + if (t->sig_expected == NULL) typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE; @@ -391,20 +538,20 @@ static int self_test_sign(const ST_KAT_SIGN *t, if (!add_params(bld, t->key, bnctx)) goto err; + params = OSSL_PARAM_BLD_to_param(bld); - /* Create a EVP_PKEY_CTX to load the DSA key into */ - kctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, ""); + kctx = EVP_PKEY_CTX_new_from_name_provided(libctx, t->algorithm, NULL); + if (kctx == NULL || params == NULL) goto err; + if (EVP_PKEY_fromdata_init(kctx) <= 0 || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) goto err; - /* Create a EVP_PKEY_CTX to use for the signing operation */ - sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); - if (sctx == NULL - || EVP_PKEY_sign_init(sctx) <= 0) + sctx = EVP_PKEY_CTX_new_from_pkey_provided(libctx, pkey, NULL); + if (sctx == NULL) goto err; /* set signature parameters */ @@ -412,47 +559,172 @@ static int self_test_sign(const ST_KAT_SIGN *t, t->mdalgorithm, strlen(t->mdalgorithm) + 1)) goto err; + params_sig = OSSL_PARAM_BLD_to_param(bld); - if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) + if (params_sig == NULL) goto err; - if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0 - || EVP_PKEY_verify_init(sctx) <= 0 + if (t->sign) { + if (EVP_PKEY_sign_init(sctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) + goto err; + + if (EVP_PKEY_sign(sctx, sig, &siglen, t->dgst, t->dgst_len) <= 0) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, sig); + + if (t->sig_expected != NULL + && (siglen != t->sig_expected_len + || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0)) + goto err; + } + + if (EVP_PKEY_verify_init(sctx) <= 0 || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) goto err; - /* - * Used by RSA, for other key types where the signature changes, we - * can only use the verify. - */ - if (t->sig_expected != NULL - && (siglen != t->sig_expected_len - || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0)) - goto err; + if (!t->sign) { + memcpy(sig, t->sig_expected, t->sig_expected_len); + siglen = t->sig_expected_len; + } OSSL_SELF_TEST_oncorrupt_byte(st, sig); - if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0) + if (EVP_PKEY_verify(sctx, sig, siglen, t->dgst, t->dgst_len) <= 0) goto err; + ret = 1; err: BN_CTX_free(bnctx); EVP_PKEY_free(pkey); - EVP_PKEY_CTX_free(kctx); EVP_PKEY_CTX_free(sctx); - OSSL_PARAM_free(params); OSSL_PARAM_free(params_sig); OSSL_PARAM_BLD_free(bld); OSSL_SELF_TEST_onend(st, ret); return ret; } -/* - * Test an encrypt or decrypt KAT.. - * - * FIPS 140-2 IG D.9 states that separate KAT tests are needed for encrypt - * and decrypt.. - */ -static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st, +#ifdef SDF_LIB +static int self_test_asym_decrypt_with_sdf(const ST_KAT_ASYM_CIPHER *t, + OSSL_SELF_TEST *st, + OSSL_LIB_CTX *libctx) +{ + int ok = 0; + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + OSSL_ECCrefPrivateKey privkey; + OSSL_ECCrefPublicKey pubkey; + sdfe_bitmap_t bitmap; + sdfe_asym_key_ecc_t asym; + const ST_KAT_PARAM *param; + OSSL_ECCCipher *pECCCipher = NULL; + unsigned char out[256]; + unsigned int outlen = sizeof(out); + uint32_t cnt, i; + int index = -1; + const char *typ = OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER; + + if (t->expected == NULL) + typ = OSSL_SELF_TEST_TYPE_PCT_ASYM_CIPHER; + + OSSL_SELF_TEST_onbegin(st, typ, t->desc); + + memset(&privkey, 0, sizeof(privkey)); + memset(&pubkey, 0, sizeof(pubkey)); + memset(&asym, 0, sizeof(asym)); + memset(&login_arg, 0, sizeof(login_arg)); + + strcpy((char *)login_arg.name, "admin"); + login_arg.passwd = (uint8_t *)"123123"; + login_arg.passwd_len = 6; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + bitmap.start = 0; + bitmap.cnt = SDFE_BITMAP_U64_MAX_CNT; + if (SDFE_BitmapAsymKey(hSessionHandle, SDFE_ASYM_KEY_AREA_ENC, + SDFE_ASYM_KEY_TYPE_SM2, &bitmap) != OSSL_SDR_OK) + goto end; + + cnt = bitmap.cnt << 6; + for(i = 0; i < cnt; i++){ + if(!bitmap_is_inuse(bitmap.bitmap, i)) { + index = i; + break; + } + } + + if (index < 0) + goto end; + + asym.area = SDFE_ASYM_KEY_AREA_ENC; + asym.index = index; + asym.type = SDFE_ASYM_KEY_TYPE_SM2; + asym.privkey_bits = 256; + asym.privkey_len = asym.privkey_bits >> 3; + asym.pubkey_bits = 256; + asym.pubkey_len = (asym.pubkey_bits >> 3) << 1; + + for (param = t->key; param->data; param++) { + if (strcmp(param->name, OSSL_PKEY_PARAM_PUB_KEY) == 0) { + pubkey.bits = 256; + memcpy(pubkey.x + sizeof(pubkey.x) - 32, + (unsigned char *)param->data + 1, 32); + memcpy(pubkey.y + sizeof(pubkey.y) - 32, + (unsigned char *)param->data + 1 + 32, 32); + } else if (strcmp(param->name, OSSL_PKEY_PARAM_PRIV_KEY) == 0) { + privkey.bits = 256; + memcpy(privkey.K + sizeof(privkey.K) - param->data_len, param->data, + param->data_len); + } + } + + memcpy(asym.pubkey, &pubkey, sizeof(pubkey)); + memcpy(asym.privkey, &privkey, sizeof(privkey)); + + if (SDFE_ImportECCKey(hSessionHandle, &asym, NULL) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_GetPrivateKeyAccessRight(hSessionHandle, index, NULL, 0) + != OSSL_SDR_OK) + goto end; + + pECCCipher = TSAPI_SM2Ciphertext_to_ECCCipher(t->in, t->in_len); + + if (TSAPI_SDF_InternalDecrypt_ECC(hSessionHandle, index, pECCCipher, + out, &outlen) != OSSL_SDR_OK) + goto end; + + OSSL_SELF_TEST_oncorrupt_byte(st, out); + + if (t->expected != NULL + && (outlen != t->expected_len + || memcmp(out, t->expected, t->expected_len) != 0)) + goto end; + + ok = 1; +end: + OPENSSL_free(pECCCipher); + (void)SDFE_DelECCKey(hSessionHandle, asym.area, index); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); + OSSL_SELF_TEST_onend(st, ok); + return ok; +} +#endif + +static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, + OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 0; @@ -463,8 +735,17 @@ static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st BN_CTX *bnctx = NULL; unsigned char out[256]; size_t outlen = sizeof(out); + const char *typ = OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER; + +#ifdef SDF_LIB + if (!t->encrypt) + return self_test_asym_decrypt_with_sdf(t, st, libctx); +#endif - OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER, t->desc); + if (t->expected == NULL) + typ = OSSL_SELF_TEST_TYPE_PCT_ASYM_CIPHER; + + OSSL_SELF_TEST_onbegin(st, typ, t->desc); bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) @@ -476,7 +757,7 @@ static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st || !add_params(keybld, t->key, bnctx)) goto err; keyparams = OSSL_PARAM_BLD_to_param(keybld); - keyctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL); + keyctx = EVP_PKEY_CTX_new_from_name_provided(libctx, t->algorithm, NULL); if (keyctx == NULL || keyparams == NULL) goto err; if (EVP_PKEY_fromdata_init(keyctx) <= 0 @@ -484,7 +765,7 @@ static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st goto err; /* Create a EVP_PKEY_CTX to use for the encrypt or decrypt operation */ - encctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL); + encctx = EVP_PKEY_CTX_new_from_pkey_provided(libctx, key, NULL); if (encctx == NULL || (t->encrypt && EVP_PKEY_encrypt_init(encctx) <= 0) || (!t->encrypt && EVP_PKEY_decrypt_init(encctx) <= 0)) @@ -614,17 +895,12 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 1; - if (!self_test_digests(st, libctx)) - ret = 0; - if (!self_test_ciphers(st, libctx)) - ret = 0; - if (!self_test_signatures(st, libctx)) - ret = 0; - if (!self_test_kdfs(st, libctx)) - ret = 0; - if (!self_test_drbgs(st, libctx)) - ret = 0; - if (!self_test_asym_ciphers(st, libctx)) + if (!self_test_digests(st, libctx) + || !self_test_ciphers(st, libctx) + || !self_test_asym_ciphers(st, libctx) + || !self_test_signatures(st, libctx) + || !self_test_kdfs(st, libctx) + || !self_test_drbgs(st, libctx)) ret = 0; return ret; diff --git a/providers/smtc/self_test_rand.c b/providers/smtc/self_test_rand.c index a35fd965c..78296b9f4 100644 --- a/providers/smtc/self_test_rand.c +++ b/providers/smtc/self_test_rand.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "internal/nelem.h" #include "self_test_rand.h" @@ -1903,19 +1904,36 @@ int rand_self_test_discrete_fourier_transform(const unsigned char *buf, return p_value >= alpha; } -int smtc_randomness_test_delivery(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +int smtc_rand_delivery_test(OSSL_SELF_TEST *st, int sdf) { int nbit = 1000000; unsigned char buf[nbit / 8]; int fail[15] = {0}; size_t i = 0, j, k; int retry = 1, res = 0; + void *hDeviceHandle = NULL, *hSessionHandle = NULL; - OSSL_SELF_TEST_onbegin(st, "Delivery_Test", "Randomness"); + if (sdf) + OSSL_SELF_TEST_onbegin(st, "Delivery_Test", "Randomness for device"); + else + OSSL_SELF_TEST_onbegin(st, "Delivery_Test", "Randomness"); + + if (sdf) { + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != 0) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != 0) + goto end; + } while (i++ < 50) { - if (RAND_bytes(buf, nbit / 8) != 1) - return 0; + if (sdf) { + if (TSAPI_SDF_GenerateRandom(hSessionHandle, nbit / 8, buf) != 0) + goto end; + } else { + if (RAND_bytes(buf, nbit / 8) != 1) + goto end; + } j = 0; fail[j++] += rand_self_test_frequency(buf, nbit, NULL) ^ 1; @@ -1948,23 +1966,42 @@ int smtc_randomness_test_delivery(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) res = 1; end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); OSSL_SELF_TEST_onend(st, res); return 1; } -int smtc_randomness_test_poweron(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +int smtc_rand_poweron_test(OSSL_SELF_TEST *st, int sdf) { int nbit = 1000000; unsigned char buf[nbit / 8]; int fail[15]; size_t i = 0, j, k; int retry = 1, res = 0; + void *hDeviceHandle = NULL, *hSessionHandle = NULL; - OSSL_SELF_TEST_onbegin(st, "Poweron_Test", "Randomness"); + if (sdf) + OSSL_SELF_TEST_onbegin(st, "Poweron_Test", "Randomness for device"); + else + OSSL_SELF_TEST_onbegin(st, "Poweron_Test", "Randomness"); - while(i++ < 20) { - if (RAND_bytes(buf, nbit / 8) != 1) + if (sdf) { + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != 0) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != 0) goto end; + } + + while(i++ < 20) { + if (sdf) { + if (TSAPI_SDF_GenerateRandom(hSessionHandle, nbit / 8, buf) != 0) + goto end; + } else { + if (RAND_bytes(buf, nbit / 8) != 1) + goto end; + } j = 0; fail[j++] += rand_self_test_frequency(buf, nbit, NULL) ^ 1; @@ -1997,25 +2034,37 @@ int smtc_randomness_test_poweron(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) res = 1; end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); OSSL_SELF_TEST_onend(st, res); return 1; } -int smtc_randomness_test_cyclical(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +int smtc_rand_cyclical_test(OSSL_SELF_TEST *st, int sdf) { int nbit = 20000; unsigned char buf[nbit / 8]; int fail[12] = {0}; size_t i = 0, j, k; int retry = 1, res = 0; + void *hDeviceHandle = NULL, *hSessionHandle = NULL; - OSSL_SELF_TEST_onbegin(st, "Cyclical_Test", "Randomness"); + if (sdf) + OSSL_SELF_TEST_onbegin(st, "Cyclical_Test", "Randomness for device"); + else + OSSL_SELF_TEST_onbegin(st, "Cyclical_Test", "Randomness"); while(i++ < 20) { - if (RAND_bytes(buf, nbit / 8) != 1) - goto end; + if (sdf) { + if (TSAPI_SDF_GenerateRandom(hSessionHandle, nbit / 8, buf) != 0) + goto end; + } else { + if (RAND_bytes(buf, nbit / 8) != 1) + goto end; + } j = 0; + fail[j++] += rand_self_test_frequency(buf, nbit, NULL) ^ 1; fail[j++] += rand_self_test_block_frequency(buf, nbit, 1000, NULL) ^ 1; fail[j++] += rand_self_test_poker(buf, nbit, 8, NULL) ^ 1; @@ -2043,22 +2092,41 @@ int smtc_randomness_test_cyclical(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) res = 1; end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); OSSL_SELF_TEST_onend(st, res); return 1; } -int smtc_randomness_test_single(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +int smtc_rand_single_test(OSSL_SELF_TEST *st, int sdf) { int nbit = 256; unsigned char buf[nbit / 8]; int retry = 1, res = 0; + void *hDeviceHandle = NULL, *hSessionHandle = NULL; - OSSL_SELF_TEST_onbegin(st, "Single_Test", "Randomness"); + if (sdf) + OSSL_SELF_TEST_onbegin(st, "Single_Test", "Randomness for device"); + else + OSSL_SELF_TEST_onbegin(st, "Single_Test", "Randomness"); - do { - if (RAND_bytes(buf, nbit / 8) != 1) + if (sdf) { + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != 0) goto end; + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != 0) + goto end; + } + + do { + if (sdf) { + if (TSAPI_SDF_GenerateRandom(hSessionHandle, nbit / 8, buf) != 0) + goto end; + } else { + if (RAND_bytes(buf, nbit / 8) != 1) + goto end; + } + if (rand_self_test_poker(buf, nbit, 2, NULL) == 1) break; else @@ -2067,6 +2135,8 @@ int smtc_randomness_test_single(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) res = 1; end: + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); OSSL_SELF_TEST_onend(st, res); return 1; } diff --git a/providers/smtc/self_test_rand.h b/providers/smtc/self_test_rand.h index 3dd69ff20..c33745a97 100644 --- a/providers/smtc/self_test_rand.h +++ b/providers/smtc/self_test_rand.h @@ -45,7 +45,7 @@ int rand_self_test_maurer_universal_statistical(const unsigned char *buf, int rand_self_test_discrete_fourier_transform(const unsigned char *buf, size_t nbit, double *P); -int smtc_randomness_test_delivery(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx); -int smtc_randomness_test_poweron(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx); -int smtc_randomness_test_cyclical(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx); -int smtc_randomness_test_single(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx); +int smtc_rand_delivery_test(OSSL_SELF_TEST *st, int sdf); +int smtc_rand_poweron_test(OSSL_SELF_TEST *st, int sdf); +int smtc_rand_cyclical_test(OSSL_SELF_TEST *st, int sdf); +int smtc_rand_single_test(OSSL_SELF_TEST *st, int sdf); diff --git a/providers/smtc/smtckey.h.in b/providers/smtc/smtckey.h.in index a6e30ed7a..68dec4216 100644 --- a/providers/smtc/smtckey.h.in +++ b/providers/smtc/smtckey.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 2023 The Tongsuo Project Authors. All Rights Reserved. + * Copyright 2023-2024 The Tongsuo Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,10 +9,7 @@ * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt */ -/* - * The SMTC validation HMAC key, usable as an array initializer. - */ -#define SMTC_KEY_ELEMENTS \ - {- join(', ', map { "0x$_" } unpack("(A2)*", $config{SMTCKEY})) -} +#define SMTC_KEY_STRING "{- $config{SMTCPUBKEY} -}" -#define SMTC_KEY_STRING "{- $config{SMTCKEY} -}" +#define SMTC_DEFAULT_PASSWORD_ELEMENTS \ + {- join(', ', map { sprintf '0x%02x', ord($_) } split //, $config{SMTCPASSWD}) -} diff --git a/providers/smtc/smtcprov.c b/providers/smtc/smtcprov.c index db5a92398..6455d50ad 100644 --- a/providers/smtc/smtcprov.c +++ b/providers/smtc/smtcprov.c @@ -8,11 +8,15 @@ */ #include +#include #include #include #include +#include +#include #include #include +#include #include "internal/cryptlib.h" #include "prov/implementations.h" #include "prov/bio.h" @@ -24,6 +28,14 @@ #include "self_test.h" #include "internal/core.h" #include "internal/smtc_names.h" +#include "internal/thread_once.h" + + +/* From GM/T 0105-2021 (Sec 6) */ +#define L1_RESEED_INTERVAL (1 << 20) +#define L1_RESEED_TIME_INTERVAL (10 * 60) /* 10 minutes */ +#define L2_RESEED_INTERVAL (1 << 10) +#define L2_RESEED_TIME_INTERVAL (60) /* 1 minute */ /* * Forward declarations to ensure that interface functions are correctly @@ -41,12 +53,6 @@ OSSL_provider_init_fn ossl_smtc_provider_init; # define OSSL_provider_init_int ossl_smtc_provider_init #endif -/* - * Should these function pointers be stored in the provider side provctx? Could - * they ever be different from one init to the next? We assume not for now. - */ -static BIO *bio_err = NULL; - /* Functions provided by the core */ static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL; static OSSL_FUNC_core_get_params_fn *c_get_params; @@ -91,32 +97,40 @@ static const OSSL_PARAM smtc_param_types[] = { static int smtc_get_params_from_core(SMTC_GLOBAL *fgbl) { - OSSL_PARAM core_params[11], *p = core_params; + OSSL_PARAM core_params[14], *p = core_params; *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_SMTC_PARAM_MODULE_PATH, (char **)&fgbl->selftest_params.module_filename, sizeof(fgbl->selftest_params.module_filename)); *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_SMTC_PARAM_MODULE_MAC, - (char **)&fgbl->selftest_params.module_checksum_data, - sizeof(fgbl->selftest_params.module_checksum_data)); + OSSL_PROV_SMTC_PARAM_MODULE_SIG, + (char **)&fgbl->selftest_params.module_sig, + sizeof(fgbl->selftest_params.module_sig)); + *p++ = OSSL_PARAM_construct_utf8_ptr( + OSSL_PROV_SMTC_PARAM_AUTH_KEY, + (char **)&fgbl->selftest_params.auth_key, + sizeof(fgbl->selftest_params.auth_key)); *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_SMTC_PARAM_SHOW_SELFTEST, - (char **)&fgbl->selftest_params.show_selftest, - sizeof(fgbl->selftest_params.show_selftest)); + OSSL_PROV_SMTC_PARAM_AUTH_SALT, + (char **)&fgbl->selftest_params.auth_salt, + sizeof(fgbl->selftest_params.auth_salt)); *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_SMTC_PARAM_ADMIN_PASS, - (char **)&fgbl->selftest_params.admin_pass, - sizeof(fgbl->selftest_params.admin_pass)); + OSSL_PROV_SMTC_PARAM_AUTH_KEK, + (char **)&fgbl->selftest_params.kek, + sizeof(fgbl->selftest_params.kek)); *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_SMTC_PARAM_ADMIN_SALT, - (char **)&fgbl->selftest_params.admin_salt, - sizeof(fgbl->selftest_params.admin_salt)); + OSSL_PROV_SMTC_PARAM_ENGINE, + (char **)&fgbl->selftest_params.eng, + sizeof(fgbl->selftest_params.eng)); *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_SMTC_PARAM_RNG_POWERON_TEST, (char **)&fgbl->selftest_params.rng_poweron_test, sizeof(fgbl->selftest_params.rng_poweron_test)); + *p++ = OSSL_PARAM_construct_utf8_ptr( + OSSL_PROV_SMTC_PARAM_SYSLOG, + (char **)&fgbl->selftest_params.syslog, + sizeof(fgbl->selftest_params.syslog)); *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_SMTC_PARAM_RNG_CONTINUOUS_TEST, (char **)&fgbl->selftest_params.rng_continuous_test, @@ -127,9 +141,9 @@ static int smtc_get_params_from_core(SMTC_GLOBAL *fgbl) sizeof(fgbl->selftest_params.randomness_poweron_test)); #ifndef OPENSSL_NO_SMTC_DEBUG *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_MAC, - (char **)&fgbl->selftest_params.verify_mac, - sizeof(fgbl->selftest_params.verify_mac)); + OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_SIG, + (char **)&fgbl->selftest_params.verify_sig, + sizeof(fgbl->selftest_params.verify_sig)); *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_SMTC_PARAM_MODULE_VERIFY_PASS, (char **)&fgbl->selftest_params.verify_pass, @@ -164,7 +178,7 @@ static int smtc_get_params(void *provctx, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, TONGSUO_FULL_VERSION_STR)) return 0; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); - if (p != NULL && !OSSL_PARAM_set_int(p, smtc_prov_is_running())) + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) return 0; return 1; } @@ -177,12 +191,6 @@ static int self_test_events(const OSSL_PARAM params[], void *arg) const char *phase = NULL, *type = NULL, *desc = NULL; int ret = 0; - if (bio_err == NULL) { - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); - if (bio_err == NULL) - return 0; - } - p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE); if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) goto err; @@ -198,11 +206,10 @@ static int self_test_events(const OSSL_PARAM params[], void *arg) goto err; type = (const char *)p->data; - if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0) - BIO_printf(bio_err, "%s : (%s) : %s\n", desc, type, phase); - else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0 - || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0) - BIO_printf(bio_err, "%s : (%s) : %s\n", desc, type, phase); + if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0 + || strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0 + || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0) + OSSL_TRACE3(SMTC, "%s : (%s) : %s\n", desc, type, phase); /* * The self test code will internally corrupt the KAT test result if an * error is returned during the corrupt phase. @@ -216,7 +223,7 @@ static int self_test_events(const OSSL_PARAM params[], void *arg) if (self_test_corrupt_type != NULL && strcmp(self_test_corrupt_type, type) != 0) goto end; - BIO_printf(bio_err, "%s : (%s) : %s\n", desc, type, phase); + OSSL_TRACE3(SMTC, "%s : (%s) : %s\n", desc, type, phase); goto err; } end: @@ -227,10 +234,8 @@ static int self_test_events(const OSSL_PARAM params[], void *arg) static void set_self_test_cb(SMTC_GLOBAL *fgbl) { - if (fgbl->selftest_params.show_selftest != NULL - && atoi(fgbl->selftest_params.show_selftest) != 0) - OSSL_SELF_TEST_set_callback(fgbl->selftest_params.libctx, - self_test_events, NULL); + OSSL_SELF_TEST_set_callback(fgbl->selftest_params.libctx, self_test_events, + NULL); if (c_stcbfn != NULL) { c_stcbfn((OPENSSL_CORE_CTX *)fgbl->selftest_params.libctx, @@ -244,14 +249,70 @@ static void set_self_test_cb(SMTC_GLOBAL *fgbl) static int smtc_self_test(void *provctx) { - SMTC_GLOBAL *fgbl = ossl_lib_ctx_get_data(ossl_prov_ctx_get0_libctx(provctx), - OSSL_LIB_CTX_SMTC_PROV_INDEX, - &smtc_prov_ossl_ctx_method); + SMTC_GLOBAL *fgbl = + ossl_lib_ctx_get_data(ossl_prov_ctx_get0_libctx(provctx), + OSSL_LIB_CTX_SMTC_PROV_INDEX, + &smtc_prov_ossl_ctx_method); set_self_test_cb(fgbl); return SELF_TEST_post(&fgbl->selftest_params, 1) ? 1 : 0; } +static int smtc_status(void *provctx) +{ + return ossl_prov_is_running(); +} + +static int smtc_reset(void *provctx) +{ + int ok = 0, i; + const char *conf_file = OPENSSL_info(OPENSSL_INFO_SMTC_MODULE_CONF); + CONF *conf = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + CONF_VALUE *cv = NULL; + const char *sec_name = "smtc_sect"; + BIO *out = NULL; + long eline; + + conf = NCONF_new(NCONF_default()); + if (conf == NULL) + goto end; + + if (NCONF_load(conf, conf_file, &eline) <= 0) + goto end; + + out = BIO_new_file(conf_file, "w"); + if (out == NULL) + goto end; + + if (BIO_printf(out, "[%s]\n", sec_name) <= 0 + || BIO_printf(out, "activate = 1\n") <= 0) + goto end; + + sect = NCONF_get_section(conf, sec_name); + + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + cv = sk_CONF_VALUE_value(sect, i); + + if (strcmp(cv->name, OSSL_PROV_SMTC_PARAM_MODULE_PATH) == 0 + || strcmp(cv->name, OSSL_PROV_SMTC_PARAM_MODULE_SIG) == 0 + || strcmp(cv->name, OSSL_PROV_SMTC_PARAM_AUTH_KEK) == 0 + || strcmp(cv->name, OSSL_PROV_SMTC_PARAM_ENGINE) == 0 + || strcmp(cv->name, OSSL_PROV_SMTC_PARAM_SYSLOG) == 0 + || strcmp(cv->name, OSSL_PROV_SMTC_PARAM_RANDOMNESS_POWERON_TEST) == 0) + if (BIO_printf(out, "%s = %s\n", cv->name, cv->value) <= 0) + goto end; + } + + ok = 1; + OSSL_syslog(LOG_NOTICE, "[SMTC] Reset module\n"); +end: + NCONF_free(conf); + BIO_free(out); + + return ok; +} + /* * For the algorithm names, we use the following formula for our primary * names: @@ -286,8 +347,13 @@ static const OSSL_ALGORITHM smtc_digests[] = { static const OSSL_ALGORITHM_CAPABLE smtc_ciphers[] = { #ifndef OPENSSL_NO_SM4 + ALG(PROV_NAMES_SM4_ECB, ossl_sm4128ecb_functions), ALG(PROV_NAMES_SM4_CBC, ossl_sm4128cbc_functions), + ALG(PROV_NAMES_SM4_CFB, ossl_sm4128cfb128_functions), + ALG(PROV_NAMES_SM4_OFB, ossl_sm4128ofb128_functions), + ALG(PROV_NAMES_SM4_CTR, ossl_sm4128ctr_functions), ALG(PROV_NAMES_SM4_GCM, ossl_sm4128gcm_functions), + ALG(PROV_NAMES_SM4_CCM, ossl_sm4128ccm_functions), #endif /* OPENSSL_NO_SM4 */ {{NULL, NULL, NULL}, NULL}}; @@ -300,6 +366,7 @@ static const OSSL_ALGORITHM smtc_macs[] = { static const OSSL_ALGORITHM smtc_kdfs[] = { { PROV_NAMES_TLS1_PRF, "provider=smtc", ossl_kdf_tls1_prf_functions }, + { PROV_NAMES_PBKDF2, "provider=smtc", ossl_kdf_pbkdf2_functions }, /* used by SM2 encryption and decryption */ { PROV_NAMES_X963KDF, "provider=smtc", ossl_kdf_x963_kdf_functions }, { NULL, NULL, NULL } @@ -307,6 +374,7 @@ static const OSSL_ALGORITHM smtc_kdfs[] = { static const OSSL_ALGORITHM smtc_rands[] = { { PROV_NAMES_HASH_DRBG, "provider=smtc", ossl_drbg_hash_functions }, + { PROV_NAMES_SEED_SRC, "provider=smtc", ossl_seed_src_functions }, { PROV_NAMES_TEST_RAND, "provider=smtc", ossl_test_rng_functions }, { NULL, NULL, NULL } }; @@ -349,11 +417,18 @@ static const OSSL_ALGORITHM smtc_keymgmt[] = { PROV_DESCS_SM2 }, #endif /* TLCP create HMAC, such as ECC-SM2-SM4-CBC-SM3 */ - { PROV_NAMES_HMAC, "provider=default", ossl_mac_legacy_keymgmt_functions, + { PROV_NAMES_HMAC, "provider=smtc", ossl_mac_legacy_keymgmt_functions, PROV_DESCS_HMAC_SIGN }, { NULL, NULL, NULL } }; +static const OSSL_ALGORITHM smtc_encoder[] = { +#define ENCODER_PROVIDER "smtc" +#include "../encoders.inc" + { NULL, NULL, NULL } +#undef ENCODER_PROVIDER +}; + static const OSSL_ALGORITHM smtc_decoder[] = { #define DECODER_PROVIDER "smtc" #include "../decoders.inc" @@ -361,6 +436,15 @@ static const OSSL_ALGORITHM smtc_decoder[] = { #undef DECODER_PROVIDER }; +static const OSSL_ALGORITHM smtc_store[] = { +#define STORE(name, _dummy, func_table) \ + { name, "provider=smtc", (func_table) }, + +#include "../stores.inc" + { NULL, NULL, NULL } +#undef STORE +}; + static const OSSL_ALGORITHM *smtc_query(void *provctx, int operation_id, int *no_cache) { @@ -390,35 +474,113 @@ static const OSSL_ALGORITHM *smtc_query(void *provctx, int operation_id, return smtc_asym_cipher; case OSSL_OP_KEM: return smtc_asym_kem; + case OSSL_OP_ENCODER: + return smtc_encoder; case OSSL_OP_DECODER: return smtc_decoder; + case OSSL_OP_STORE: + return smtc_store; } return NULL; } +static void smtc_teardown(void *provctx) +{ + BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); + OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx)); + ossl_prov_ctx_free(provctx); +} + static void smtc_intern_teardown(void *provctx) { - BIO_free(bio_err); + BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); /* * We know that the library context is the same as for the outer provider, * so no need to destroy it here. */ - BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); ossl_prov_ctx_free(provctx); } /* Functions we provide to the core */ static const OSSL_DISPATCH smtc_dispatch_table[] = { - { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))smtc_intern_teardown }, + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))smtc_teardown }, { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))smtc_gettable_params }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))smtc_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))smtc_query }, { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))ossl_prov_get_capabilities }, { OSSL_FUNC_PROVIDER_SELF_TEST, (void (*)(void))smtc_self_test }, + { OSSL_FUNC_PROVIDER_STATUS, (void (*)(void))smtc_status }, + { OSSL_FUNC_PROVIDER_RESET, (void (*)(void))smtc_reset }, + { 0, NULL } +}; + +/* Functions we provide to ourself */ +static const OSSL_DISPATCH intern_dispatch_table[] = { + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))smtc_intern_teardown }, + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))smtc_query }, { 0, NULL } }; +/* + * The internal init function used when the SMTC module uses EVP to call + * another algorithm also in the SMTC module. This is a recursive call that has + * been made from within the SMTC module itself. To make this work, we populate + * the provider context of this inner instance with the same library context + * that was used in the EVP call that initiated this recursive call. + */ +OSSL_provider_init_fn ossl_smtc_intern_provider_init; +int ossl_smtc_intern_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) +{ + OSSL_FUNC_core_get_libctx_fn *c_internal_get_libctx = NULL; + BIO_METHOD *corebiometh = NULL; + OSSL_LIB_CTX *libctx = NULL; + + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_LIBCTX: + c_internal_get_libctx = OSSL_FUNC_core_get_libctx(in); + break; + default: + break; + } + } + + if (c_internal_get_libctx == NULL) + return 0; + + if ((*provctx = ossl_prov_ctx_new()) == NULL) + return 0; + + if ((corebiometh = ossl_bio_prov_init_bio_method()) == NULL) + goto err; + + /* + * Using the parent library context only works because we are a built-in + * internal provider. This is not something that most providers would be + * able to do. + */ + libctx = (OSSL_LIB_CTX *)c_internal_get_libctx(handle); + + ossl_prov_ctx_set0_libctx(*provctx, libctx); + ossl_prov_ctx_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_core_bio_method(*provctx, corebiometh); + + *out = intern_dispatch_table; + return 1; + +err: + BIO_meth_free(corebiometh); + smtc_intern_teardown(*provctx); + *provctx = NULL; + OSSL_LIB_CTX_free(libctx); + return 0; +} + +OSSL_provider_init_fn OSSL_provider_init_int; int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, @@ -426,10 +588,30 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, { int ret; SMTC_GLOBAL *fgbl; - BIO_METHOD *corebiometh; + BIO_METHOD *corebiometh = NULL; OSSL_LIB_CTX *libctx = NULL; OSSL_FUNC_core_get_libctx_fn *c_internal_get_libctx = NULL; SELF_TEST_POST_PARAMS selftest_params; + EVP_RAND_CTX *pub_drbg, *pri_drbg; + unsigned int reseed_interval = L2_RESEED_INTERVAL; + time_t reseed_time_interval = L2_RESEED_TIME_INTERVAL; + OSSL_PARAM params[3]; + struct utmpx *cur; + + setutxent(); + while ((cur = getutxent()) != NULL) { + /* + * Root users are prohibited from logging in to prevent malicious + * tampering. + */ + if (strcmp(cur->ut_user, "root") == 0) { + OSSL_TRACE(SMTC, "root user detected, init failed\n"); + endutxent(); + return 0; + } + } + + endutxent(); memset(&selftest_params, 0, sizeof(selftest_params)); @@ -466,12 +648,11 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, if (ret != 1) return 0; - if ((*provctx = ossl_prov_ctx_new()) == NULL - || (corebiometh = ossl_bio_prov_init_bio_method()) == NULL) { - ossl_prov_ctx_free(*provctx); - *provctx = NULL; + if ((*provctx = ossl_prov_ctx_new()) == NULL) return 0; - } + + if ((corebiometh = ossl_bio_prov_init_bio_method()) == NULL) + goto err; if ((fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SMTC_PROV_INDEX, &smtc_prov_ossl_ctx_method)) == NULL) @@ -494,15 +675,48 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, goto err; } + ossl_prov_cache_exported_algorithms(smtc_ciphers, exported_ciphers); + + if (fgbl->selftest_params.syslog && atoi(fgbl->selftest_params.syslog) != 0) + OSSL_enable_syslog(); + + OSSL_syslog(LOG_INFO, "[SMTC] SMTC module init\n"); + + if (!SELF_TEST_post(&fgbl->selftest_params, 0)) { + OSSL_TRACE(SMTC, "SELF_TEST_post failed\n"); + ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE); + goto err; + } + + pub_drbg = RAND_get0_public(libctx); + if (pub_drbg == NULL) + goto err; + + pri_drbg = RAND_get0_private(libctx); + if (pri_drbg == NULL) + goto err; + + params[0] = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, + &reseed_interval); + params[1] = OSSL_PARAM_construct_time_t( + OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, + &reseed_time_interval); + params[2] = OSSL_PARAM_construct_end(); + + if (!EVP_RAND_CTX_set_params(pub_drbg, params) + || !EVP_RAND_CTX_set_params(pri_drbg, params)) + goto err; + ossl_prov_ctx_set0_libctx(*provctx, libctx); ossl_prov_ctx_set0_handle(*provctx, handle); ossl_prov_ctx_set0_core_bio_method(*provctx, corebiometh); *out = smtc_dispatch_table; - ossl_prov_cache_exported_algorithms(smtc_ciphers, exported_ciphers); + return 1; err: - smtc_intern_teardown(*provctx); + BIO_meth_free(corebiometh); + smtc_teardown(*provctx); *provctx = NULL; OSSL_LIB_CTX_free(libctx); return 0; diff --git a/ssl/statem_ntls/ntls_statem_srvr.c b/ssl/statem_ntls/ntls_statem_srvr.c index ed274c45e..b91d2528d 100644 --- a/ssl/statem_ntls/ntls_statem_srvr.c +++ b/ssl/statem_ntls/ntls_statem_srvr.c @@ -1584,7 +1584,7 @@ int tls_construct_server_key_exchange_ntls(SSL *s, WPACKET *pkt) { unsigned char *encodedPoint = NULL; size_t encodedlen = 0; - int curve_id = 0; + uint16_t curve_id = 0; const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg; unsigned long type; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 2b449e1bc..b7598056c 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -547,6 +547,13 @@ int tls1_setup_key_block(SSL *s) goto err; } +#if defined(SMTC_MODULE) && !defined(OPENSSL_NO_NTLS) + if (SSL_IS_NTLS(s) && (s->options & SSL_OP_NO_TICKET) + && (s->ctx->session_cache_mode == SSL_SESS_CACHE_OFF)) { + OPENSSL_cleanse(s->session->master_key, s->session->master_key_length); + } +#endif + OSSL_TRACE_BEGIN(TLS) { BIO_printf(trc_out, "key block\n"); BIO_dump_indent(trc_out, p, num, 4); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 22f2d7dd1..18ed9aa79 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -376,7 +376,13 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) * assumption to make (in which case perhaps we should document this * behaviour)? */ - if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) { + if (EVP_KEYMGMT_get0_provider(keymgmt) == provider +#ifdef SMTC_MODULE + || (strcmp(OSSL_PROVIDER_get0_name( + EVP_KEYMGMT_get0_provider(keymgmt)), "inner-smtc") == 0 + && strcmp(OSSL_PROVIDER_get0_name(provider), "smtc") == 0) +#endif + ) { /* We have a match - so we will use this group */ ctx->group_list_len++; ginf = NULL; diff --git a/test/build.info b/test/build.info index 6d53ee12f..a03023f4a 100644 --- a/test/build.info +++ b/test/build.info @@ -59,7 +59,7 @@ IF[{- !$disabled{tests} -}] context_internal_test aesgcmtest params_test evp_pkey_dparams_test \ keymgmt_internal_test hexstr_test provider_status_test defltfips_test \ bio_readbuffer_test user_property_test pkcs7_test upcallstest \ - provfetchtest prov_config_test rand_test babasslapitest + provfetchtest prov_config_test rand_test babasslapitest tsapi_test IF[{- !$disabled{'deprecated-3.0'} -}] PROGRAMS{noinst}=enginetest @@ -580,6 +580,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[cmp_client_test]=.. ../include ../apps/include DEPEND[cmp_client_test]=../libcrypto.a libtestutil.a + SOURCE[tsapi_test]=tsapi_test.c + INCLUDE[tsapi_test]=.. ../include ../apps/include + DEPEND[tsapi_test]=../libcrypto.a libtestutil.a + # Internal test programs. These are essentially a collection of internal # test routines. Some of them need to reach internal symbols that aren't # available through the shared library (at least on Linux and Windows diff --git a/test/ssl-tests/31-ntls.cnf b/test/ntls-tests/31-ntls.cnf similarity index 100% rename from test/ssl-tests/31-ntls.cnf rename to test/ntls-tests/31-ntls.cnf diff --git a/test/ssl-tests/31-ntls.cnf.in b/test/ntls-tests/31-ntls.cnf.in similarity index 100% rename from test/ssl-tests/31-ntls.cnf.in rename to test/ntls-tests/31-ntls.cnf.in diff --git a/test/ssl-tests/32-ntls-force-ntls.cnf b/test/ntls-tests/32-ntls-force-ntls.cnf similarity index 100% rename from test/ssl-tests/32-ntls-force-ntls.cnf rename to test/ntls-tests/32-ntls-force-ntls.cnf diff --git a/test/ssl-tests/32-ntls-force-ntls.cnf.in b/test/ntls-tests/32-ntls-force-ntls.cnf.in similarity index 100% rename from test/ssl-tests/32-ntls-force-ntls.cnf.in rename to test/ntls-tests/32-ntls-force-ntls.cnf.in diff --git a/test/ssl-tests/39-ntls-sni-ticket.cnf b/test/ntls-tests/39-ntls-sni-ticket.cnf similarity index 100% rename from test/ssl-tests/39-ntls-sni-ticket.cnf rename to test/ntls-tests/39-ntls-sni-ticket.cnf diff --git a/test/ssl-tests/39-ntls-sni-ticket.cnf.in b/test/ntls-tests/39-ntls-sni-ticket.cnf.in similarity index 100% rename from test/ssl-tests/39-ntls-sni-ticket.cnf.in rename to test/ntls-tests/39-ntls-sni-ticket.cnf.in diff --git a/test/ssl-tests/40-ntls_client_auth.cnf b/test/ntls-tests/40-ntls_client_auth.cnf similarity index 100% rename from test/ssl-tests/40-ntls_client_auth.cnf rename to test/ntls-tests/40-ntls_client_auth.cnf diff --git a/test/ssl-tests/40-ntls_client_auth.cnf.in b/test/ntls-tests/40-ntls_client_auth.cnf.in similarity index 100% rename from test/ssl-tests/40-ntls_client_auth.cnf.in rename to test/ntls-tests/40-ntls_client_auth.cnf.in diff --git a/test/ssl-tests/41-ntls-alpn.cnf b/test/ntls-tests/41-ntls-alpn.cnf similarity index 100% rename from test/ssl-tests/41-ntls-alpn.cnf rename to test/ntls-tests/41-ntls-alpn.cnf diff --git a/test/ssl-tests/41-ntls-alpn.cnf.in b/test/ntls-tests/41-ntls-alpn.cnf.in similarity index 100% rename from test/ssl-tests/41-ntls-alpn.cnf.in rename to test/ntls-tests/41-ntls-alpn.cnf.in diff --git a/test/recipes/00-prep_smtc_cnf.t b/test/recipes/00-prep_smtc_cnf.t index d32104921..004fed298 100644 --- a/test/recipes/00-prep_smtc_cnf.t +++ b/test/recipes/00-prep_smtc_cnf.t @@ -30,7 +30,6 @@ my $smtcconf = bldtop_file('test', 'smtcmodule.cnf'); plan tests => 1; # Create the smtc conf file -ok(run(app(['openssl', 'mod', - '-module', $bin, '-provider_name', 'smtc', '-no_pass', - '-section_name', 'smtc_sect', '-out', $smtcconf])), - "smtc install"); +ok(run(app(['openssl', 'mod', '-install', '-no_verify', '-no_auth', + '-no_rand_poweron_test', '-module', $bin, '-out', $smtcconf])), + "smtc install"); diff --git a/test/recipes/20-test_cli_smtc.t b/test/recipes/20-test_cli_smtc.t index 6996c3084..38d2e8bec 100644 --- a/test/recipes/20-test_cli_smtc.t +++ b/test/recipes/20-test_cli_smtc.t @@ -26,8 +26,7 @@ plan skip_all => "Test only supported in a smtc build" if disabled("smtc") || disabled("smtc-debug"); plan tests => 9; -my $defaultconf = srctop_file("test", "default.cnf"); -my $smtcconf = srctop_file("test", "smtc-and-base.cnf"); +my $smtcconf = srctop_file("test", "smtc.cnf"); my $tbs_data = abs_path(bldtop_file('apps', 'openssl' . platform->binext())); my $bogus_data = $smtcconf; @@ -64,16 +63,13 @@ sub pubfrompriv { } -my $tsignverify_count = 8; +my $tsignverify_count = 2; sub tsignverify { my $prefix = shift; my $smtc_key = shift; my $smtc_pub_key = shift; - my $nonsmtc_key = shift; - my $nonsmtc_pub_key = shift; my $md = shift; my $smtc_sigfile = $prefix.'.smtc.sig'; - my $nonsmtc_sigfile = $prefix.'.nonsmtc.sig'; my $sigfile = ''; my $testtext = ''; @@ -95,65 +91,6 @@ sub tsignverify { '-signature', $sigfile, $tbs_data])), $testtext); - - $testtext = $prefix.': '. - 'Verify a valid signature against the wrong data with a SMTC key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', $md, - '-verify', $smtc_pub_key, - '-signature', $sigfile, - $bogus_data])), - $testtext); - - $ENV{OPENSSL_CONF} = $defaultconf; - - $sigfile = $nonsmtc_sigfile; - $testtext = $prefix.': '. - 'Sign something with a non-SMTC key'. - ' with the default provider'; - ok(run(app(['openssl', 'dgst', $md, - '-sign', $nonsmtc_key, - '-out', $sigfile, - $tbs_data])), - $testtext); - - $testtext = $prefix.': '. - 'Verify something with a non-SMTC key'. - ' with the default provider'; - ok(run(app(['openssl', 'dgst', $md, - '-verify', $nonsmtc_pub_key, - '-signature', $sigfile, - $tbs_data])), - $testtext); - - $ENV{OPENSSL_CONF} = $smtcconf; - - $testtext = $prefix.': '. - 'Sign something with a non-SMTC key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', $md, - '-sign', $nonsmtc_key, - '-out', $prefix.'.nonsmtc.fail.sig', - $tbs_data])), - $testtext); - - $testtext = $prefix.': '. - 'Verify something with a non-SMTC key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', $md, - '-verify', $nonsmtc_pub_key, - '-signature', $sigfile, - $tbs_data])), - $testtext); - - $testtext = $prefix.': '. - 'Verify a valid signature against the wrong data with a non-SMTC key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', $md, - '-verify', $nonsmtc_pub_key, - '-signature', $sigfile, - $bogus_data])), - $testtext); } SKIP : { @@ -164,24 +101,10 @@ SKIP : { my $testtext_prefix = 'SM2'; my $smtc_key = $testtext_prefix.'.smtc.priv.pem'; my $smtc_pub_key = $testtext_prefix.'.smtc.pub.pem'; - my $a_nonsmtc_curve = 'brainpoolP256r1'; - my $nonsmtc_key = $testtext_prefix.'.nonsmtc.priv.pem'; - my $nonsmtc_pub_key = $testtext_prefix.'.nonsmtc.pub.pem'; my $testtext = ''; my $curvename = ''; - plan tests => 5 + $tsignverify_count; - - $ENV{OPENSSL_CONF} = $defaultconf; - $curvename = $a_nonsmtc_curve; - $testtext = $testtext_prefix.': '. - 'Generate a key with a non-SMTC algorithm with the default provider'; - ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-out', $nonsmtc_key])), - $testtext); - - pubfrompriv($testtext_prefix, $nonsmtc_key, $nonsmtc_pub_key, "non-SMTC"); + plan tests => 1 + 1 + $tsignverify_count; $ENV{OPENSSL_CONF} = $smtcconf; @@ -193,16 +116,6 @@ SKIP : { pubfrompriv($testtext_prefix, $smtc_key, $smtc_pub_key, "SMTC"); - $curvename = $a_nonsmtc_curve; - $testtext = $testtext_prefix.': '. - 'Generate a key with a non-SMTC algorithm'. - ' (should fail)'; - ok(!run(app(['openssl', 'genpkey', '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-out', $testtext_prefix.'.'.$curvename.'.priv.pem'])), - $testtext); - - tsignverify($testtext_prefix, $smtc_key, $smtc_pub_key, $nonsmtc_key, - $nonsmtc_pub_key, '-sm3'); + tsignverify($testtext_prefix, $smtc_key, $smtc_pub_key, '-sm3'); }; } diff --git a/test/recipes/20-test_mod.t b/test/recipes/20-test_mod.t index 92876338a..f1a2a1c3a 100644 --- a/test/recipes/20-test_mod.t +++ b/test/recipes/20-test_mod.t @@ -19,6 +19,6 @@ setup("test_mod"); plan skip_all => "Test only supported in a smtc build" if disabled("smtc"); plan tests => 1; -$ENV{OPENSSL_CONF} = abs_path(srctop_file("test", "smtc-and-base.cnf")); +$ENV{OPENSSL_CONF} = abs_path(srctop_file("test", "smtc.cnf")); ok(run(app(['openssl', 'mod', '-test'])), "mod self test"); diff --git a/test/recipes/80-test_ntls.t b/test/recipes/80-test_ntls.t new file mode 100644 index 000000000..a6ebf0dd6 --- /dev/null +++ b/test/recipes/80-test_ntls.t @@ -0,0 +1,126 @@ +#! /usr/bin/env perl +# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use strict; +use warnings; + +use File::Basename; +use File::Compare qw/compare_text/; +use File::Spec::Functions qw/devnull catdir/; +use OpenSSL::Glob; +use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir result_dir/; +use OpenSSL::Test::Utils qw/disabled alldisabled available_protocols/; + +BEGIN { +setup("test_ntls"); +} + +plan skip_all => "NTLS is not supported by this OpenSSL build" + if disabled("ntls"); + +use lib srctop_dir('Configurations'); +use lib bldtop_dir('.'); + +my $no_smtc = disabled('smtc') || disabled('smtc-debug'); + +$ENV{TEST_CERTS_DIR} = srctop_dir("test", "certs"); + +my @conf_srcs = glob(srctop_file("test", "ntls-tests", "*.cnf.in")); +my @conf_files = map { basename($_, ".in") } @conf_srcs; + +# We hard-code the number of tests to double-check that the globbing above +# finds all files as expected. +plan tests => 5; + + +# Add your test here if the test conf.in generates test cases and/or +# expectations dynamically based on the OpenSSL compile-time config. +my %conf_dependent_tests = ( + "31-ntls.cnf" => disabled("ntls"), + "32-ntls-force-ntls.cnf" => disabled("ntls"), + "39-ntls-sni-ticket.cnf" => disabled("ntls"), + "40-ntls_client_auth.cnf" => disabled("ntls"), + "41-ntls-alpn.cnf" => disabled("ntls"), +); + +# Add your test here if it should be skipped for some compile-time +# configurations. Default is $no_tls but some tests have different skip +# conditions. +my %skip = ( + "31-ntls.cnf" => disabled("ntls") || disabled("sm2") || disabled("sm3") + || disabled("sm4"), + "32-ntls-force-ntls.cnf" => disabled("ntls") || disabled("sm2") + || disabled("sm3") || disabled("sm4") + || !disabled("smtc"), + "39-ntls-sni-ticket.cnf" => disabled("ntls") || disabled("sm2") + || disabled("sm3") || disabled("sm4"), + "40-ntls_client_auth.cnf" => disabled("ntls") || disabled("sm2") + || disabled("sm3") || disabled("sm4"), + "41-ntls-alpn.cnf" => disabled("ntls") || disabled("sm2") || disabled("sm3") + || disabled("sm4"), +); + +foreach my $conf (@conf_files) { + subtest "Test configuration $conf" => sub { + plan tests => $no_smtc ? 6 : 3; + test_conf($conf, + $conf_dependent_tests{$conf} ? 0 : 1, $skip{$conf}, "none") + unless !$no_smtc; + test_conf($conf, 0, $skip{$conf}, "default") unless !$no_smtc; + test_conf($conf, 0, $skip{$conf}, "smtc") unless $no_smtc; + }; +} + +sub test_conf { + my ($conf, $check_source, $skip, $provider) = @_; + + my $conf_file = srctop_file("test", "ntls-tests", $conf); + my $input_file = $conf_file . ".in"; + my $output_file = $conf . "." . $provider; + my $run_test = 1; + + SKIP: { + # "Test" 1. Generate the source. + skip 'failure', 2 unless + ok(run(perltest(["generate_ssl_tests.pl", $input_file, $provider], + interpreter_args => [ "-I", srctop_dir("util", "perl")], + stdout => $output_file)), + "Getting output from generate_ssl_tests.pl."); + + SKIP: { + # Test 2. Compare against existing output in test/ntls-tests/ + skip "Skipping generated source test for $conf", 1 + if !$check_source; + + $run_test = is(cmp_text($output_file, $conf_file), 0, + "Comparing generated $output_file with $conf_file."); + } + + # Test 3. Run the test. + skip "No tests available; skipping tests", 1 if $skip; + skip "Stale sources; skipping tests", 1 if !$run_test; + + if ($provider eq "smtc") { + ok(run(test(["ssl_test", $output_file, $provider, + srctop_file("test", "smtc.cnf")])), + "running ssl_test $conf"); + } else { + ok(run(test(["ssl_test", $output_file, $provider])), + "running ssl_test $conf"); + } + } +} + +sub cmp_text { + return compare_text(@_, sub { + $_[0] =~ s/\R//g; + $_[1] =~ s/\R//g; + return $_[0] ne $_[1]; + }); +} diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t index edb42c3a3..0c417998c 100644 --- a/test/recipes/80-test_ssl_new.t +++ b/test/recipes/80-test_ssl_new.t @@ -25,7 +25,6 @@ use lib srctop_dir('Configurations'); use lib bldtop_dir('.'); my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); -my $no_smtc = disabled('smtc') || disabled('smtc-debug'); $ENV{TEST_CERTS_DIR} = srctop_dir("test", "certs"); $ENV{TEST_RUNS_DIR} = catdir(result_dir(), "..", "test_dc_sign"); @@ -35,7 +34,7 @@ my @conf_files = map { basename($_, ".in") } @conf_srcs; # We hard-code the number of tests to double-check that the globbing above # finds all files as expected. -plan tests => 37; +plan tests => 32; # Some test results depend on the configuration of enabled protocols. We only # verify generated sources in the default configuration. @@ -81,12 +80,7 @@ my %conf_dependent_tests = ( "27-ticket-appdata.cnf" => !$is_default_tls, "28-seclevel.cnf" => disabled("tls1_2") || $no_ec, "30-extended-master-secret.cnf" => disabled("tls1_2"), - "31-ntls.cnf" => disabled("ntls"), - "32-ntls-force-ntls.cnf" => disabled("ntls"), "38-delegated-credential.cnf" => disabled("delegated-credential"), - "39-ntls-sni-ticket.cnf" => disabled("ntls"), - "40-ntls_client_auth.cnf" => disabled("ntls"), - "41-ntls-alpn.cnf" => disabled("ntls"), ); # Add your test here if it should be skipped for some compile-time @@ -123,26 +117,12 @@ my %skip = ( "29-dtls-sctp-label-bug.cnf" => disabled("sctp") || disabled("sock"), "30-tls13-sm.cnf" => disabled("sm2") || disabled("sm3") || disabled("sm4") || disabled("tls1_3") || !$no_fips, - "31-ntls.cnf" => disabled("ntls") || disabled("sm2") || disabled("sm3") - || disabled("sm4") || !$no_fips, - "32-ntls-force-ntls.cnf" => disabled("ntls") || disabled("sm2") - || disabled("sm3") || disabled("sm4") - || !$no_fips || !disabled("smtc"), "38-delegated-credential.cnf" => disabled("delegated-credential"), - "39-ntls-sni-ticket.cnf" => disabled("ntls") || disabled("sm2") - || disabled("sm3") || disabled("sm4") - || !$no_fips, - "40-ntls_client_auth.cnf" => disabled("ntls") || disabled("sm2") - || disabled("sm3") || disabled("sm4") - || !$no_fips, - "41-ntls-alpn.cnf" => disabled("ntls") || disabled("sm2") - || disabled("sm3") || disabled("sm4") || !$no_fips, ); foreach my $conf (@conf_files) { subtest "Test configuration $conf" => sub { - plan tests => 6 + ($no_fips ? 0 : 3) - + ($conf !~ /^[0-9]+-ntls/ || $no_smtc ? 0 : 3); + plan tests => 6 + ($no_fips ? 0 : 3); test_conf($conf, $conf_dependent_tests{$conf} ? 0 : 1, defined($skip{$conf}) ? $skip{$conf} : $no_tls, @@ -155,10 +135,6 @@ foreach my $conf (@conf_files) { 0, defined($skip{$conf}) ? $skip{$conf} : $no_tls, "fips") unless $no_fips; - test_conf($conf, - 0, - defined($skip{$conf}) ? $skip{$conf} : $no_tls, - "smtc") unless ($conf !~ /^[0-9]+-ntls/ || $no_smtc); }; } @@ -201,10 +177,6 @@ sub test_conf { ok(run(test(["ssl_test", $output_file, $provider, srctop_file("test", "fips-and-base.cnf")])), "running ssl_test $conf"); - } elsif ($provider eq "smtc") { - ok(run(test(["ssl_test", $output_file, $provider, - srctop_file("test", "smtc-and-base.cnf")])), - "running ssl_test $conf"); } else { ok(run(test(["ssl_test", $output_file, $provider])), "running ssl_test $conf"); diff --git a/test/recipes/92-test_tsapi.t b/test/recipes/92-test_tsapi.t new file mode 100644 index 000000000..ba7bb0e0e --- /dev/null +++ b/test/recipes/92-test_tsapi.t @@ -0,0 +1,22 @@ +#! /usr/bin/env perl +# Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_tsapi"); + +my $no_smtc = disabled('smtc') || disabled('smtc-debug'); + +if (!$no_smtc) { + my $smtcconf = srctop_file("test", "smtc.cnf"); + $ENV{OPENSSL_CONF} = $smtcconf; +} + +simple_test("test_tsapi", "tsapi_test"); diff --git a/test/smtc-and-base.cnf b/test/smtc.cnf similarity index 82% rename from test/smtc-and-base.cnf rename to test/smtc.cnf index 4149104d4..c63fd0b03 100644 --- a/test/smtc-and-base.cnf +++ b/test/smtc.cnf @@ -9,9 +9,8 @@ config_diagnostics = 1 providers = provider_sect [provider_sect] +inner-smtc = inner_smtc_sect smtc = smtc_sect -base = base_sect -[base_sect] +[inner_smtc_sect] activate = 1 - diff --git a/test/testutil/provider.c b/test/testutil/provider.c index d073d732d..e817e4a58 100644 --- a/test/testutil/provider.c +++ b/test/testutil/provider.c @@ -57,7 +57,7 @@ int test_arg_libctx(OSSL_LIB_CTX **libctx, OSSL_PROVIDER **default_null_prov, TEST_error("usage: %s", usage); return 0; } - if (strcmp(module_name, "none") == 0) + if (strcmp(module_name, "none") == 0 || strcmp(module_name, "smtc") == 0) return 1; return test_get_libctx(libctx, default_null_prov, test_get_argument(argn + 1), provider, module_name); diff --git a/test/tsapi_test.c b/test/tsapi_test.c new file mode 100644 index 000000000..1c3dabb26 --- /dev/null +++ b/test/tsapi_test.c @@ -0,0 +1,484 @@ +/* + * Copyright 2024 The Tongsuo Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt + */ + +#include +#include +#include +#include +#include +#include "testutil.h" +#include "../crypto/sdf/sdf_local.h" +#ifdef SDF_LIB +# include "sdfe_api.h" +#endif + +static int test_TSAPI_Version(void) +{ + char *version = TSAPI_Version(); + + if (!TEST_ptr(version)) + return 0; + + OPENSSL_free(version); + return 1; +} + +static int test_TSAPI_RandBytes(void) +{ + int ret = 0; + size_t len = 32; + unsigned char *buf1 = NULL; + unsigned char *buf2 = NULL; + + buf1 = TSAPI_RandBytes(len); + if (!TEST_ptr(buf1)) + goto end; + + buf2 = TSAPI_RandBytes(len); + if (!TEST_ptr(buf2)) + goto end; + + if (!TEST_mem_ne(buf1, len, buf2, len)) + goto end; + + ret = 1; +end: + OPENSSL_free(buf1); + OPENSSL_free(buf2); + return ret; +} + +#ifndef OPENSSL_NO_SM2 +static int test_TSAPI_SM2Keygen(void) +{ + int ok = 0; + EVP_PKEY *key = NULL, *pubkey = NULL; + unsigned char *sig = NULL; + const char *input = "test"; + size_t siglen; + BIO *tmpbio = NULL; + + key = TSAPI_SM2Keygen(); + if (!TEST_ptr(key)) + return 0; + + tmpbio = BIO_new(BIO_s_mem()); + if (!TEST_ptr(tmpbio)) + goto end; + + if (!TEST_true(PEM_write_bio_PUBKEY(tmpbio, key))) + goto end; + + pubkey = PEM_read_bio_PUBKEY(tmpbio, NULL, NULL, NULL); + if (!TEST_ptr(pubkey)) + goto end; + + sig = TSAPI_SM2Sign(key, (const unsigned char *)input, strlen(input), + &siglen); + if (!TEST_ptr(sig)) + goto end; + + if (!TEST_true(TSAPI_SM2Verify(pubkey, (const unsigned char *)input, + strlen(input), sig, siglen))) + goto end; + + ok = 1; +end: + BIO_free(tmpbio); + OPENSSL_free(sig); + EVP_PKEY_free(pubkey); + EVP_PKEY_free(key); + return ok; +} + +static int test_TSAPI_SM2Sign(void) +{ + int ok = 0; + EVP_PKEY *key = NULL; + const char *input = "test"; + unsigned char *sig = NULL; + size_t siglen; + + key = TSAPI_SM2Keygen(); + if (!TEST_ptr(key)) + return 0; + + sig = TSAPI_SM2Sign(key, (const unsigned char *)input, strlen(input), + &siglen); + if (!TEST_ptr(sig) || !TEST_true(siglen > 0)) + goto end; + + ok = 1; +end: + OPENSSL_free(sig); + EVP_PKEY_free(key); + return ok; +} + +static int test_TSAPI_SM2Verify(void) +{ + int ok = 0; + EVP_PKEY *key = NULL; + BIO *bio = NULL; + const char *pem = "-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEOToq2eJ+Q6yqq4WhnTuFWR4UQGFX\n" +"F1rd03v3f/DK+e03/POotPVcA4UjJh/KZjav5qevoqFIKmBvXLOhiy4qHg==\n" +"-----END PUBLIC KEY-----"; + const char *input = "hello world"; + unsigned char sig[] = { + 0x30, 0x45, 0x02, 0x20, 0x6b, 0xa1, 0x2c, 0x29, 0xaf, 0x6a, 0x4d, 0xe7, + 0x6d, 0xb0, 0x85, 0xa1, 0xd3, 0x5f, 0xfa, 0x1d, 0x00, 0x77, 0xfc, 0x6a, + 0x13, 0xe4, 0xac, 0x1b, 0x64, 0xe6, 0x82, 0x9e, 0x34, 0x89, 0x71, 0xfb, + 0x02, 0x21, 0x00, 0xcb, 0xfe, 0xab, 0xc6, 0xcb, 0x61, 0x2d, 0x25, 0xe9, + 0x0a, 0xdc, 0x71, 0xde, 0xe3, 0x9a, 0xdb, 0xfa, 0xcf, 0x62, 0x4e, 0x5a, + 0xa9, 0x4b, 0x8d, 0xac, 0x7c, 0x7b, 0xa8, 0x4b, 0x7b, 0x77, 0x9c,}; + size_t siglen = sizeof(sig); + + bio = BIO_new_mem_buf(pem, -1); + if (!TEST_ptr(bio)) + return 0; + + key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + if (!TEST_ptr(key)) + goto end; + + if (!TEST_true(TSAPI_SM2Verify(key, (const unsigned char *)input, + strlen(input), sig, siglen))) + goto end; + + ok = 1; +end: + BIO_free(bio); + EVP_PKEY_free(key); + return ok; +} + +static int test_TSAPI_SM2Encrypt(void) +{ + int ok = 0; + EVP_PKEY *key = NULL; + BIO *bio = NULL; + const char *pem = "-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEOToq2eJ+Q6yqq4WhnTuFWR4UQGFX\n" +"F1rd03v3f/DK+e03/POotPVcA4UjJh/KZjav5qevoqFIKmBvXLOhiy4qHg==\n" +"-----END PUBLIC KEY-----"; + const char *input = "test"; + unsigned char *out = NULL; + size_t outlen; + + bio = BIO_new_mem_buf(pem, -1); + if (!TEST_ptr(bio)) + return 0; + + key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + if (!TEST_ptr(key)) + goto end; + + out = TSAPI_SM2Encrypt(key, (const unsigned char *)input, strlen(input), + &outlen); + if (!TEST_ptr(out) + || !TEST_true(outlen > 0)) + goto end; + + ok = 1; +end: + BIO_free(bio); + EVP_PKEY_free(key); + OPENSSL_free(out); + return ok; +} + +# ifdef SDF_LIB +static int bitmap_is_inuse(uint64_t *pu64, int32_t index) +{ + + int32_t pos, offset; + uint64_t mask; + + mask = 0x1ull; + + pos = index >> 6; + offset = (63 - (index & 0x3f)); + mask <<= offset; + + return (pu64[pos] & mask) ? 1 : 0; +} +# endif + +static int test_TSAPI_SM2Decrypt(void) +{ + int ok = 0; +# ifdef SDF_LIB + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + sdfe_login_arg_t login_arg; + OSSL_ECCrefPrivateKey *privkey = NULL; + OSSL_ECCrefPublicKey *pubkey = NULL; + sdfe_bitmap_t bitmap; + sdfe_asym_key_ecc_t asym; + OSSL_ECCCipher *pECCCipher = NULL; + uint32_t cnt, i; + int index = -1; + unsigned char out[256]; + unsigned int outlen = sizeof(out); +# else + unsigned char *out = NULL; + size_t outlen; +# endif + EVP_PKEY *key = NULL; + BIO *bio = NULL; + const char *pem = "-----BEGIN PRIVATE KEY-----\n" +"MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg0JFWczAXva2An9m7\n" +"2MaT9gIwWTFptvlKrxyO4TjMmbWhRANCAAQ5OirZ4n5DrKqrhaGdO4VZHhRAYVcX\n" +"Wt3Te/d/8Mr57Tf886i09VwDhSMmH8pmNq/mp6+ioUgqYG9cs6GLLioe\n" +"-----END PRIVATE KEY-----"; + unsigned char in[] = { + 0x30, 0x81, 0x8A, 0x02, 0x20, 0x46, 0x6B, 0xE2, 0xEF, 0x5C, 0x11, 0x78, + 0x2E, 0xC7, 0x78, 0x64, 0xA0, 0x05, 0x54, 0x17, 0xF4, 0x07, 0xA5, 0xAF, + 0xC1, 0x1D, 0x65, 0x3C, 0x6B, 0xCE, 0x69, 0xE4, 0x17, 0xBB, 0x1D, 0x05, + 0xB6, 0x02, 0x20, 0x62, 0xB5, 0x72, 0xE2, 0x1F, 0xF0, 0xDD, 0xF5, 0xC7, + 0x26, 0xBD, 0x3F, 0x9F, 0xF2, 0xEA, 0xE5, 0x6E, 0x62, 0x94, 0x71, 0x3A, + 0x60, 0x7E, 0x9B, 0x95, 0x25, 0x62, 0x89, 0x65, 0xF6, 0x2C, 0xC8, 0x04, + 0x20, 0x3C, 0x1B, 0x57, 0x13, 0xB5, 0xDB, 0x27, 0x28, 0xEB, 0x7B, 0xF7, + 0x75, 0xE4, 0x4F, 0x46, 0x89, 0xFC, 0x32, 0x66, 0x8B, 0xDC, 0x56, 0x4F, + 0x52, 0xEA, 0x45, 0xB0, 0x9E, 0x8D, 0xF2, 0xA5, 0xF4, 0x04, 0x22, 0x08, + 0x4A, 0x9D, 0x0C, 0xC2, 0x99, 0x70, 0x92, 0xB7, 0xD3, 0xC4, 0x04, 0xFC, + 0xE9, 0x59, 0x56, 0xEB, 0x60, 0x4D, 0x73, 0x2B, 0x23, 0x07, 0xA8, 0xE5, + 0xB8, 0x90, 0x0E, 0xD6, 0x60, 0x8C, 0xA5, 0xB1, 0x97,}; + const char *expected = "The floofy bunnies hop at midnight"; + + bio = BIO_new_mem_buf(pem, -1); + if (!TEST_ptr(bio)) + return 0; + + key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + if (!TEST_ptr(key)) + goto end; + +# ifdef SDF_LIB + memset(&login_arg, 0, sizeof(login_arg)); + + strcpy((char *)login_arg.name, "admin"); + login_arg.passwd = (uint8_t *)"123123"; + login_arg.passwd_len = 6; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + if (SDFE_LoginUsr(hSessionHandle, &login_arg) != OSSL_SDR_OK) + goto end; + + bitmap.start = 0; + bitmap.cnt = SDFE_BITMAP_U64_MAX_CNT; + if (SDFE_BitmapAsymKey(hSessionHandle, SDFE_ASYM_KEY_AREA_ENC, + SDFE_ASYM_KEY_TYPE_SM2, &bitmap) != OSSL_SDR_OK) + goto end; + + cnt = bitmap.cnt << 6; + for(i = 0; i < cnt; i++){ + if(!bitmap_is_inuse(bitmap.bitmap, i)) { + index = i; + break; + } + } + + if (index < 0) + goto end; + + asym.area = SDFE_ASYM_KEY_AREA_ENC; + asym.index = index; + asym.type = SDFE_ASYM_KEY_TYPE_SM2; + asym.privkey_bits = 256; + asym.privkey_len = asym.privkey_bits >> 3; + asym.pubkey_bits = 256; + asym.pubkey_len = (asym.pubkey_bits >> 3) << 1; + + pubkey = TSAPI_EVP_PKEY_get_ECCrefPublicKey(key); + if (!TEST_ptr(pubkey)) + goto end; + + privkey = TSAPI_EVP_PKEY_get_ECCrefPrivateKey(key); + if (!TEST_ptr(privkey)) + goto end; + + memcpy(asym.pubkey, pubkey, sizeof(*pubkey)); + memcpy(asym.privkey, privkey, sizeof(*privkey)); + + if (SDFE_ImportECCKey(hSessionHandle, &asym, NULL) != OSSL_SDR_OK) + goto end; + + if (TSAPI_SDF_GetPrivateKeyAccessRight(hSessionHandle, index, NULL, 0) + != OSSL_SDR_OK) + goto end; + + pECCCipher = TSAPI_SM2Ciphertext_to_ECCCipher(in, sizeof(in)); + + if (TSAPI_SDF_InternalDecrypt_ECC(hSessionHandle, index, pECCCipher, + out, &outlen) != OSSL_SDR_OK) + goto end; +# else + out = TSAPI_SM2Decrypt(key, in, sizeof(in), &outlen); + if (!TEST_ptr(out)) + goto end; +# endif + + if (!TEST_true(outlen == strlen(expected)) + || !TEST_mem_eq(out, outlen, expected, strlen(expected))) + goto end; + + ok = 1; +end: + BIO_free(bio); + EVP_PKEY_free(key); +# ifdef SDF_LIB + OPENSSL_free(pubkey); + OPENSSL_free(privkey); + OPENSSL_free(pECCCipher); + (void)SDFE_DelECCKey(hSessionHandle, asym.area, index); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); +# else + OPENSSL_free(out); +# endif + return ok; +} +#endif + +#ifndef OPENSSL_NO_SM4 +static int test_TSAPI_SM4Encrypt(void) +{ + unsigned char key[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char iv[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char in[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, + 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char expected[] = { + 0x26, 0x77, 0xF4, 0x6B, 0x09, 0xC1, 0x22, 0xCC, 0x97, 0x55, 0x33, 0x10, + 0x5B, 0xD4, 0xA2, 0x2A, 0xF6, 0x12, 0x5F, 0x72, 0x75, 0xCE, 0x55, 0x2C, + 0x3A, 0x2B, 0xBC, 0xF5, 0x33, 0xDE, 0x8A, 0x3B, + }; + unsigned char *out = NULL; + size_t outlen; + + out = TSAPI_SM4Encrypt(OSSL_SGD_MODE_CBC, key, sizeof(key), -1, iv, in, + sizeof(in), &outlen); + if (!TEST_ptr(out)) + return 0; + + if (!TEST_mem_eq(out, outlen, expected, sizeof(expected))) { + OPENSSL_free(out); + return 0; + } + + OPENSSL_free(out); + return 1; +} + +static int test_TSAPI_SM4Decrypt(void) +{ + unsigned char key[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char iv[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char in[] = { + 0x26, 0x77, 0xF4, 0x6B, 0x09, 0xC1, 0x22, 0xCC, 0x97, 0x55, 0x33, 0x10, + 0x5B, 0xD4, 0xA2, 0x2A, 0xF6, 0x12, 0x5F, 0x72, 0x75, 0xCE, 0x55, 0x2C, + 0x3A, 0x2B, 0xBC, 0xF5, 0x33, 0xDE, 0x8A, 0x3B, + }; + unsigned char expected[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, + 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + unsigned char *out = NULL; + size_t outlen; + + out = TSAPI_SM4Decrypt(OSSL_SGD_MODE_CBC, key, sizeof(key), -1, iv, in, + sizeof(in), &outlen); + if (!TEST_ptr(out)) + return 0; + + if (!TEST_mem_eq(out, outlen, expected, sizeof(expected))) { + OPENSSL_free(out); + return 0; + } + + OPENSSL_free(out); + return 1; +} +#endif + +#ifndef OPENSSL_NO_SM3 +static int test_TSAPI_SM3(void) +{ + unsigned char in[] = { + 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, + 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, + 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, + 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, + 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, + 0x61, 0x62, 0x63, 0x64, + }; + unsigned char expected[] = { + 0xDE, 0xBE, 0x9F, 0xF9, 0x22, 0x75, 0xB8, 0xA1, 0x38, 0x60, 0x48, 0x89, + 0xC1, 0x8E, 0x5A, 0x4D, 0x6F, 0xDB, 0x70, 0xE5, 0x38, 0x7E, 0x57, 0x65, + 0x29, 0x3d, 0xCb, 0xA3, 0x9C, 0x0C, 0x57, 0x32, + }; + size_t outlen; + unsigned char *out = TSAPI_SM3(in, sizeof(in), &outlen); + + if (!TEST_ptr(out)) + return 0; + + if (!TEST_mem_eq(out, outlen, expected, sizeof(expected))) { + OPENSSL_free(out); + return 0; + } + + OPENSSL_free(out); + return 1; +} +#endif + +int setup_tests(void) +{ + ADD_TEST(test_TSAPI_Version); + ADD_TEST(test_TSAPI_RandBytes); +#ifndef OPENSSL_NO_SM2 + ADD_TEST(test_TSAPI_SM2Keygen); + ADD_TEST(test_TSAPI_SM2Sign); + ADD_TEST(test_TSAPI_SM2Verify); + ADD_TEST(test_TSAPI_SM2Encrypt); + ADD_TEST(test_TSAPI_SM2Decrypt); +#endif +#ifndef OPENSSL_NO_SM4 + ADD_TEST(test_TSAPI_SM4Encrypt); + ADD_TEST(test_TSAPI_SM4Decrypt); +#endif +#ifndef OPENSSL_NO_SM3 + ADD_TEST(test_TSAPI_SM3); +#endif + + return 1; +} diff --git a/util/libcrypto.num b/util/libcrypto.num index 68c6edbf5..2602396b4 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5643,3 +5643,57 @@ PKCS12_create_ex2 5958 3_0_3 EXIST::FUNCTION: ASN1_item_unpack_ex 5960 3_0_3 EXIST::FUNCTION: PKCS12_SAFEBAG_get1_cert_ex 5961 3_0_3 EXIST::FUNCTION: PKCS12_SAFEBAG_get1_crl_ex 5962 3_0_3 EXIST::FUNCTION: +RAND_set_entropy_source 5963 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_OpenDevice 5964 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_CloseDevice 5965 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_OpenSession 5966 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_CloseSession 5967 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_ImportKeyWithKEK 5968 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_Encrypt 5969 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_Decrypt 5970 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_CalculateMAC 5971 3_0_3 EXIST::FUNCTION: +OSSL_enable_syslog 5972 3_0_3 EXIST::FUNCTION: +OSSL_disable_syslog 5973 3_0_3 EXIST::FUNCTION: +OSSL_syslog 5974 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_GetPrivateKeyAccessRight 5975 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_ReleasePrivateKeyAccessRight 5976 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_ImportKeyWithISK_ECC 5977 3_0_3 EXIST::FUNCTION: +TSAPI_GenerateSM2KeyWithIndex 5978 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SDF_GenerateKey 5979 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_DestroyKey 5980 3_0_3 EXIST::FUNCTION: +TSAPI_DelSm2KeyWithIndex 5981 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_UpdateSm2KeyWithIndex 5982 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_ExportSM2PubKeyWithIndex 5983 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SDF_ExportSignPublicKey_ECC 5984 3_0_3 EXIST::FUNCTION: +TSAPI_ImportSM2KeyWithEvlp 5985 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_ExportSM2KeyWithEvlp 5986 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM2Encrypt 5987 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_EVP_PKEY_new_from_ECCrefKey 5988 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_EVP_PKEY_get_ECCrefPublicKey 5989 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_EVP_PKEY_get_ECCrefPrivateKey 5990 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_ExportSM2KeyWithIndex 5991 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SDF_ExportEncPublicKey_ECC 5992 3_0_3 EXIST::FUNCTION: +TSAPI_ImportSM2Key 5993 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM3 5994 3_0_3 EXIST::FUNCTION:SM3 +TSAPI_SM2Ciphertext_to_ECCCipher 5995 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM4Encrypt 5996 3_0_3 EXIST::FUNCTION:SM4 +TSAPI_SM4Decrypt 5997 3_0_3 EXIST::FUNCTION:SM4 +TSAPI_Version 5998 3_0_3 EXIST::FUNCTION: +TSAPI_RandBytes 5999 3_0_3 EXIST::FUNCTION: +OSSL_PROVIDER_reset 6000 3_0_3 EXIST::FUNCTION: +OSSL_PROVIDER_status 6001 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_InternalEncrypt_ECC 6002 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_InternalDecrypt_ECC 6003 3_0_3 EXIST::FUNCTION: +TSAPI_SDF_InternalSign_ECC 6004 3_0_3 EXIST::FUNCTION: +EVP_PKEY_CTX_new_from_name_provided 6005 3_0_3 EXIST::FUNCTION: +EVP_PKEY_CTX_new_from_pkey_provided 6006 3_0_3 EXIST::FUNCTION: +TSAPI_GetEntropy 6007 3_0_3 EXIST::FUNCTION: +TSAPI_FreeEntropy 6008 3_0_3 EXIST::FUNCTION: +TSAPI_ECCCipher_to_SM2Ciphertext 6009 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM2EncryptWithISK 6010 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM2DecryptWithISK 6011 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM2Keygen 6012 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SM2Sign 6013 3_0_3 EXIST::FUNCTION:SM2,SM3 +TSAPI_SM2Verify 6014 3_0_3 EXIST::FUNCTION:SM2,SM3 +TSAPI_SM2Decrypt 6015 3_0_3 EXIST::FUNCTION:SM2 +TSAPI_SDF_GenerateRandom 6016 3_0_3 EXIST::FUNCTION: diff --git a/util/wrap.pl.in b/util/wrap.pl.in index 178734d0e..80bee9104 100644 --- a/util/wrap.pl.in +++ b/util/wrap.pl.in @@ -6,24 +6,43 @@ use warnings; use File::Basename; use File::Spec::Functions; -BEGIN { - # This method corresponds exactly to 'use OpenSSL::Util', - # but allows us to use a platform specific file spec. - require {- - use Cwd qw(abs_path); - - "'" . abs_path(catfile($config{sourcedir}, - 'util', 'perl', 'OpenSSL', 'Util.pm')) . "'"; - -}; - OpenSSL::Util->import(); -} - my $there = canonpath(catdir(dirname($0), updir())); my $std_engines = catdir($there, 'engines'); my $std_providers = catdir($there, 'providers'); my $std_openssl_conf = catdir($there, 'apps/openssl.cnf'); my $unix_shlib_wrap = catfile($there, 'util/shlib_wrap.sh'); +my $configdata; +my $configdata_loaded = 0; + +sub load_configdata { + $configdata = catfile($there, 'configdata.pm'); + require $configdata; + $configdata_loaded = 1; +} + +sub check_disabled { + no warnings 'once'; + return map { exists $configdata::disabled{lc $_} ? 1 : 0 } @_; +} + +sub anyof { + my $x = 0; + foreach (@_) { $x += $_ } + return $x > 0; +} + +sub anydisabled { + load_configdata() unless $configdata_loaded; + my @ret = check_disabled(@_); + return @ret if wantarray; + return anyof(@ret); +} + +sub disabled { + anydisabled(@_); +} + if ($ARGV[0] eq '-fips') { $std_openssl_conf = {- use Cwd qw(abs_path); @@ -38,6 +57,20 @@ if ($ARGV[0] eq '-fips') { && -d $std_openssl_conf_include; } +if (!disabled('smtc') && !disabled('smtc-debug')) { + $std_openssl_conf = {- + use Cwd qw(abs_path); + + "'" . abs_path(catfile($config{sourcedir}, 'test/smtc.cnf')) . "'"; + -}; + $ENV{OPENSSL_CONF} = $std_openssl_conf if -f $std_openssl_conf; + + my $std_openssl_conf_include = catdir($there, 'test'); + $ENV{OPENSSL_CONF_INCLUDE} = $std_openssl_conf_include + if ($ENV{OPENSSL_CONF_INCLUDE} // '') eq '' + && -d $std_openssl_conf_include; +} + $ENV{OPENSSL_ENGINES} = $std_engines if ($ENV{OPENSSL_ENGINES} // '') eq '' && -d $std_engines; $ENV{OPENSSL_MODULES} = $std_providers