diff --git a/CHANGES b/CHANGES index 20e170c4..2b281f8d 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,204 @@ Changes between 1.1.1 and 3.0.0 [xx XXX xxxx] + *) Enhanced the documentation of EVP_PKEY_size(), EVP_PKEY_bits() + and EVP_PKEY_security_bits(). Especially EVP_PKEY_size() needed + a new formulation to include all the things it can be used for, + as well as words of caution. + [Richard Levitte] + + *) All of the low level MD2, MD4, MD5, MDC2, RIPEMD160, SHA1, SHA224, SHA256, + SHA384, SHA512 and Whirlpool digest functions have been deprecated. + These include: + MD2, MD2_options, MD2_Init, MD2_Update, MD2_Final, MD4, MD4_Init, + MD4_Update, MD4_Final, MD4_Transform, MD5, MD5_Init, MD5_Update, + MD5_Final, MD5_Transform, MDC2, MDC2_Init, MDC2_Update, MDC2_Final, + RIPEMD160, RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final, + RIPEMD160_Transform, SHA1_Init, SHA1_Update, SHA1_Final, + SHA1_Transform, SHA224_Init, SHA224_Update, SHA224_Final, + SHA224_Transform, SHA256_Init, SHA256_Update, SHA256_Final, + SHA256_Transform, SHA384, SHA384_Init, SHA384_Update, SHA384_Final, + SHA512, SHA512_Init, SHA512_Update, SHA512_Final, SHA512_Transform, + WHIRLPOOL, WHIRLPOOL_Init, WHIRLPOOL_Update, WHIRLPOOL_BitUpdate + and WHIRLPOOL_Final. + Use of these low level functions has been informally discouraged for a long + time. Instead applications should instead use the EVP_DigestInit_ex, + EVP_DigestUpdate(3) and EVP_DigestFinal_ex(3) functions. + [Paul Dale] + + *) Corrected the documentation of the return values from the EVP_DigestSign* + set of functions. The documentation mentioned negative values for some + errors, but this was never the case, so the mention of negative values + was removed. + + Code that followed the documentation and thereby check with something + like 'EVP_DigestSignInit(...) <= 0' will continue to work undisturbed. + [Richard Levitte] + + *) All of the low level cipher functions have been deprecated including: + AES_options, AES_set_encrypt_key, AES_set_decrypt_key, AES_encrypt, + AES_decrypt, AES_ecb_encrypt, AES_cbc_encrypt, AES_cfb128_encrypt, + AES_cfb1_encrypt, AES_cfb8_encrypt, AES_ofb128_encrypt, + AES_wrap_key, AES_unwrap_key, BF_set_key, BF_encrypt, BF_decrypt, + BF_ecb_encrypt, BF_cbc_encrypt, BF_cfb64_encrypt, BF_ofb64_encrypt, + BF_options, Camellia_set_key, Camellia_encrypt, Camellia_decrypt, + Camellia_ecb_encrypt, Camellia_cbc_encrypt, Camellia_cfb128_encrypt, + Camellia_cfb1_encrypt, Camellia_cfb8_encrypt, Camellia_ofb128_encrypt, + Camellia_ctr128_encrypt, CAST_set_key, CAST_encrypt, CAST_decrypt, + CAST_ecb_encrypt, CAST_cbc_encrypt, CAST_cfb64_encrypt, + CAST_ofb64_encrypt, DES_options, DES_encrypt1, DES_encrypt2, + DES_encrypt3, DES_decrypt3, DES_cbc_encrypt, DES_ncbc_encrypt, + DES_pcbc_encrypt, DES_xcbc_encrypt, DES_cfb_encrypt, DES_cfb64_encrypt, + DES_ecb_encrypt, DES_ofb_encrypt, DES_ofb64_encrypt, DES_random_key, + DES_set_odd_parity, DES_check_key_parity, DES_is_weak_key, DES_set_key, + DES_key_sched, DES_set_key_checked, DES_set_key_unchecked, + DES_string_to_key, DES_string_to_2keys, DES_fixup_key_parity, + DES_ecb2_encrypt, DES_ede2_cbc_encrypt, DES_ede2_cfb64_encrypt, + DES_ede2_ofb64_encrypt, DES_ecb3_encrypt, DES_ede3_cbc_encrypt, + DES_ede3_cfb64_encrypt, DES_ede3_cfb_encrypt, DES_ede3_ofb64_encrypt, + DES_cbc_cksum, DES_quad_cksum, IDEA_encrypt, IDEA_options, + IDEA_ecb_encrypt, IDEA_set_encrypt_key, IDEA_set_decrypt_key, + IDEA_cbc_encrypt, IDEA_cfb64_encrypt, IDEA_ofb64_encrypt, RC2_set_key, + RC2_encrypt, RC2_decrypt, RC2_ecb_encrypt, RC2_cbc_encrypt, + RC2_cfb64_encrypt, RC2_ofb64_encrypt, RC4, RC4_options, RC4_set_key, + RC5_32_set_key, RC5_32_encrypt, RC5_32_decrypt, RC5_32_ecb_encrypt, + RC5_32_cbc_encrypt, RC5_32_cfb64_encrypt, RC5_32_ofb64_encrypt, + SEED_set_key, SEED_encrypt, SEED_decrypt, SEED_ecb_encrypt, + SEED_cbc_encrypt, SEED_cfb128_encrypt and SEED_ofb128_encrypt. + + Use of these low level functions has been informally discouraged for a long + time. Instead applications should use the high level EVP APIs, e.g. + EVP_EncryptInit_ex, EVP_EncryptUpdate, EVP_EncryptFinal_ex, and the + equivalently named decrypt functions. + [Matt Caswell and Paul Dale] + + *) Removed include/openssl/opensslconf.h.in and replaced it with + include/openssl/configuration.h.in, which differs in not including + . A short header include/openssl/opensslconf.h + was added to include both. + + This allows internal hacks where one might need to modify the set + of configured macros, for example this if deprecated symbols are + still supposed to be available internally: + + #include + + #undef OPENSSL_NO_DEPRECATED + #define OPENSSL_SUPPRESS_DEPRECATED + + #include + + This should not be used by applications that use the exported + symbols, as that will lead to linking errors. + [Richard Levitte] + + *) Fixed an an overflow bug in the x64_64 Montgomery squaring procedure + used in exponentiation with 512-bit moduli. No EC algorithms are + affected. Analysis suggests that attacks against 2-prime RSA1024, + 3-prime RSA1536, and DSA1024 as a result of this defect would be very + difficult to perform and are not believed likely. Attacks against DH512 + are considered just feasible. However, for an attack the target would + have to re-use the DH512 private key, which is not recommended anyway. + Also applications directly using the low level API BN_mod_exp may be + affected if they use BN_FLG_CONSTTIME. + (CVE-2019-1551) + [Andy Polyakov] + + *) Most memory-debug features have been deprecated, and the functionality + replaced with no-ops. + [Rich Salz] + + *) Introduced a new method type and API, OSSL_SERIALIZER, to + represent generic serializers. An implementation is expected to + be able to serialize an object associated with a given name (such + as an algorithm name for an asymmetric key) into forms given by + implementation properties. + + Serializers are primarily used from inside libcrypto, through + calls to functions like EVP_PKEY_print_private(), + PEM_write_bio_PrivateKey() and similar. + + Serializers are specified in such a way that they can be made to + directly handle the provider side portion of an object, if this + provider side part comes from the same provider as the serializer + itself, but can also be made to handle objects in parametrized + form (as an OSSL_PARAM array of data). This allows a provider to + offer generic serializers as a service for any other provider. + [Richard Levitte] + + *) Added a .pragma directive to the syntax of configuration files, to + allow varying behavior in a supported and predictable manner. + Currently added pragma: + + .pragma dollarid:on + + This allows dollar signs to be a keyword character unless it's + followed by a opening brace or parenthesis. This is useful for + platforms where dollar signs are commonly used in names, such as + volume names and system directory names on VMS. + [Richard Levitte] + + *) Added functionality to create an EVP_PKEY from user data. This + is effectively the same as creating a RSA, DH or DSA object and + then assigning them to an EVP_PKEY, but directly using algorithm + agnostic EVP functions. A benefit is that this should be future + proof for public key algorithms to come. + [Richard Levitte] + + *) Change the interpretation of the '--api' configuration option to + mean that this is a desired API compatibility level with no + further meaning. The previous interpretation, that this would + also mean to remove all deprecated symbols up to and including + the given version, no requires that 'no-deprecated' is also used + in the configuration. + + When building applications, the desired API compatibility level + can be set with the OPENSSL_API_COMPAT macro like before. For + API compatibility version below 3.0, the old style numerical + value is valid as before, such as -DOPENSSL_API_COMPAT=0x10100000L. + For version 3.0 and on, the value is expected to be the decimal + value calculated from the major and minor version like this: + + MAJOR * 10000 + MINOR * 100 + + Examples: + + -DOPENSSL_API_COMPAT=30000 For 3.0 + -DOPENSSL_API_COMPAT=30200 For 3.2 + + To hide declarations that are deprecated up to and including the + given API compatibility level, -DOPENSSL_NO_DEPRECATED must be + given when building the application as well. + [Richard Levitte] + + *) Added the X509_LOOKUP_METHOD called X509_LOOKUP_store, to allow + access to certificate and CRL stores via URIs and OSSL_STORE + loaders. + + This adds the following functions: + + X509_LOOKUP_store() + X509_STORE_load_file() + X509_STORE_load_path() + X509_STORE_load_store() + SSL_add_store_cert_subjects_to_stack() + SSL_CTX_set_default_verify_store() + SSL_CTX_load_verify_file() + SSL_CTX_load_verify_dir() + SSL_CTX_load_verify_store() + + Also, the following functions are now deprecated: + + - X509_STORE_load_locations() (use X509_STORE_load_file(), + X509_STORE_load_path() or X509_STORE_load_store() instead) + - SSL_CTX_load_verify_locations() (use SSL_CTX_load_verify_file(), + SSL_CTX_load_verify_dir() or SSL_CTX_load_verify_store() instead) + [Richard Levitte] + + *) Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. + The presence of this system service is determined at run-time. + [Richard Levitte] + *) Added functionality to create an EVP_PKEY context based on data for methods from providers. This takes an algorithm name and a property query string and simply stores them, with the intent @@ -27,6 +225,10 @@ pages for further details. [Matt Caswell] + *) Most common options (such as -rand/-writerand, TLS version control, etc) + were refactored and point to newly-enhanced descriptions in openssl.pod + [Rich Salz] + *) Over two thousand fixes were made to the documentation, including: adding missing command flags, better style conformance, documentation of internals, etc. @@ -332,15 +534,6 @@ *) Change the license to the Apache License v2.0. [Richard Levitte] - *) Change the possible version information given with OPENSSL_API_COMPAT. - It may be a pre-3.0.0 style numerical version number as it was defined - in 1.1.0, and it may also simply take the major version number. - - Because of the version numbering of pre-3.0.0 releases, the values 0, - 1 and 2 are equivalent to 0x00908000L (0.9.8), 0x10000000L (1.0.0) and - 0x10100000L (1.1.0), respectively. - [Richard Levitte] - *) Switch to a new version scheme using three numbers MAJOR.MINOR.PATCH. o Major releases (indicated by incrementing the MAJOR release number) diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf index 98200af7..451a808f 100644 --- a/Configurations/00-base-templates.conf +++ b/Configurations/00-base-templates.conf @@ -10,7 +10,7 @@ my %targets=( includes => [], lib_cflags => "", lib_cppflags => "", - lib_defines => [], + lib_defines => [ 'OPENSSL_BUILDING_OPENSSL' ], thread_scheme => "(unknown)", # Assume we don't know thread_defines => [], diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index e00e1c06..6306a231 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -211,17 +211,28 @@ my %targets = ( ex_libs => add("-lsocket -lnsl -ldl"), dso_scheme => "dlfcn", thread_scheme => "pthreads", + }, +#### Solaris common with Sun C setups + "solaris-common-cc" => { + inherit_from => [ "solaris-common" ], + template => 1, shared_target => "solaris", shared_ldflag => "-Wl,-Bsymbolic", shared_defflag => "-Wl,-M,", shared_sonameflag=> "-Wl,-h,", }, +#### Solaris common with GNU C setups + "solaris-common-gcc" => { + inherit_from => [ "solaris-common" ], + template => 1, + shared_target => "solaris-gcc", # The rest is on shared_info.pl + }, #### Solaris x86 with GNU C setups "solaris-x86-gcc" => { # NB. GNU C has to be configured to use GNU assembler, and not # /usr/ccs/bin/as. Failure to comply will result in compile # failures [at least] in 32-bit build. - inherit_from => [ "solaris-common" ], + inherit_from => [ "solaris-common-gcc" ], CC => "gcc", CFLAGS => add_before(picker(default => "-Wall", debug => "-O0 -g", @@ -244,7 +255,7 @@ my %targets = ( # code [thanks to inline assembler], I would actually recommend # to consider using gcc shared build even with vendor compiler:-) # -- - inherit_from => [ "solaris-common" ], + inherit_from => [ "solaris-common-gcc" ], CC => "gcc", CFLAGS => add_before(picker(default => "-Wall", debug => "-O0 -g", @@ -265,7 +276,7 @@ my %targets = ( # primarily because vendor assembler can't assemble our modules # with -KPIC flag. As result it, assembly support, was not even # available as option. But its lack means lack of side-channel - # resistant code, which is incompatible with security by todays + # resistant code, which is incompatible with security by today's # standards. Fortunately gcc is readily available prepackaged # option, which we can firmly point at... # @@ -274,7 +285,7 @@ my %targets = ( # Consider switching to solaris64-x86_64-gcc even here... # "solaris64-x86_64-cc" => { - inherit_from => [ "solaris-common" ], + inherit_from => [ "solaris-common-cc" ], CC => "cc", CFLAGS => add_before(picker(debug => "-g", release => "-xO5 -xdepend -xbuiltin")), @@ -294,7 +305,7 @@ my %targets = ( #### SPARC Solaris with GNU C setups "solaris-sparcv7-gcc" => { - inherit_from => [ "solaris-common" ], + inherit_from => [ "solaris-common-gcc" ], CC => "gcc", CFLAGS => add_before(picker(default => "-Wall", debug => "-O0 -g", @@ -332,7 +343,7 @@ my %targets = ( # SC4.2 is ok, better than gcc even on bn as long as you tell it -xarch=v8 # SC5.0 note: Compiler common patch 107357-01 or later is required! "solaris-sparcv7-cc" => { - inherit_from => [ "solaris-common" ], + inherit_from => [ "solaris-common-cc" ], CC => "cc", CFLAGS => add_before(picker(debug => "-g", release => "-xO5 -xdepend")), @@ -1352,7 +1363,6 @@ my %targets = ( }, "VC-WIN32" => { inherit_from => [ "VC-noCE-common" ], - CFLAGS => add("/WX"), AS => sub { vc_win32_info()->{AS} }, ASFLAGS => sub { vc_win32_info()->{ASFLAGS} }, asoutflag => sub { vc_win32_info()->{asoutflag} }, @@ -1766,7 +1776,7 @@ my %targets = ( debug => "/DEBUG/TRACEBACK", release => "/NODEBUG/NOTRACEBACK"), # Because of dso_cflags below, we can't set the generic |cflags| here, - # as it can't be overriden, so we set separate C flags for libraries + # as it can't be overridden, so we set separate C flags for libraries # and binaries instead. bin_cflags => add("/NAMES=(AS_IS,SHORTENED)/EXTERN_MODEL=STRICT_REFDEF"), lib_cflags => add("/NAMES=(AS_IS,SHORTENED)/EXTERN_MODEL=STRICT_REFDEF"), diff --git a/Configurations/common.tmpl b/Configurations/common.tmpl index a2591da7..5db3471f 100644 --- a/Configurations/common.tmpl +++ b/Configurations/common.tmpl @@ -151,10 +151,18 @@ generator_incs => $unified_info{includes}->{$script}, generator_deps => $unified_info{depends}->{$script}, deps => $unified_info{depends}->{$src}, - incs => [ @{$unified_info{includes}->{$obj}}, - @{$unified_info{includes}->{$bin}} ], - defs => [ @{$unified_info{defines}->{$obj}}, - @{$unified_info{defines}->{$bin}} ], + incs => [ defined $obj + ? @{$unified_info{includes}->{$obj}} + : (), + defined $bin + ? @{$unified_info{includes}->{$bin}} + : () ], + defs => [ defined $obj + ? @{$unified_info{defines}->{$obj}} + : (), + defined $bin + ? @{$unified_info{defines}->{$bin}} + : () ], %opts); foreach (@{$unified_info{depends}->{$src}}) { dogenerate($_, $obj, $bin, %opts); @@ -436,6 +444,22 @@ $cache{$dir} = 1; } + # dodocs is responsible for building documentation from .pods. + # It will call generatesrc. + sub dodocs { + my $type = shift; + my $section = shift; + foreach my $doc (@{$unified_info{"${type}docs"}->{$section}}) { + next if $cache{$doc}; + $OUT .= generatesrc(src => $doc, + generator => $unified_info{generate}->{$doc}); + foreach ((@{$unified_info{depends}->{$doc}})) { + dogenerate($_, undef, undef, %opts); + } + $cache{$doc} = 1; + } + } + # Start with populating the cache with all the overrides %cache = map { $_ => 1 } @{$unified_info{overrides}}; @@ -448,6 +472,7 @@ foreach (@{$unified_info{modules}}) { domodule($_); } foreach (@{$unified_info{programs}}) { dobin($_); } foreach (@{$unified_info{scripts}}) { doscript($_); } - + foreach (sort keys %{$unified_info{htmldocs}}) { dodocs('html', $_); } + foreach (sort keys %{$unified_info{mandocs}}) { dodocs('man', $_); } foreach (sort keys %{$unified_info{dirinfo}}) { dodir($_); } -} diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl index 28e7663a..d379a823 100644 --- a/Configurations/descrip.mms.tmpl +++ b/Configurations/descrip.mms.tmpl @@ -143,6 +143,10 @@ INSTALL_ENGINES={- join(", ", map { "-\n\t".$_.".EXE" } @install_engines) -} INSTALL_PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @install_programs) -} BIN_SCRIPTS={- join(", ", @install_bin_scripts) -} MISC_SCRIPTS={- join(", ", @install_misc_scripts) -} +HTMLDOCS1={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man1}}) -} +HTMLDOCS3={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man3}}) -} +HTMLDOCS5={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man5}}) -} +HTMLDOCS7={- join(", ", map { "-\n\t".$_ } @{$unified_info{htmldocs}->{man7}}) -} APPS_OPENSSL={- use File::Spec::Functions; catfile("apps","openssl") -} @@ -405,7 +409,7 @@ NODEBUG=@ # The main targets ################################################### -{- dependmagic('all'); -} : build_libs_nodep, build_modules_nodep, build_programs_nodep +{- dependmagic('build_sw'); -} : build_libs_nodep, build_modules_nodep, build_programs_nodep {- dependmagic('build_libs'); -} : build_libs_nodep {- dependmagic('build_modules'); -} : build_modules_nodep {- dependmagic('build_programs'); -} : build_programs_nodep @@ -415,18 +419,23 @@ build_libs_nodep : $(LIBS), $(SHLIBS) build_modules_nodep : $(MODULES) build_programs_nodep : $(PROGRAMS), $(SCRIPTS) +build_docs: build_html_docs +build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) + # Kept around for backward compatibility build_apps build_tests : build_programs # Convenience target to prebuild all generated files, not just the mandatory # ones -build_all_generated : $(GENERATED_MANDATORY) $(GENERATED) +build_all_generated : $(GENERATED_MANDATORY) $(GENERATED) build_docs @ ! {- output_off() if $disabled{makedepend}; "" -} @ WRITE SYS$OUTPUT "Warning: consider configuring with no-makedepend, because if" @ WRITE SYS$OUTPUT " target system doesn't have $(PERL)," @ WRITE SYS$OUTPUT " then make will fail..." @ ! {- output_on() if $disabled{makedepend}; "" -} +all : build_sw build_docs + test : tests {- dependmagic('tests'); -} : build_programs_nodep, build_modules_nodep @ ! {- output_off() if $disabled{tests}; "" -} @@ -437,10 +446,8 @@ test : tests DEFINE RESULT_D {- builddir(qw(test test-runs)) -} DEFINE OPENSSL_ENGINES {- builddir("engines") -} DEFINE OPENSSL_MODULES {- builddir("providers") -} - DEFINE OPENSSL_DEBUG_MEMORY "on" IF "$(VERBOSE)" .NES. "" THEN DEFINE VERBOSE "$(VERBOSE)" $(PERL) {- sourcefile("test", "run_tests.pl") -} $(TESTS) - DEASSIGN OPENSSL_DEBUG_MEMORY DEASSIGN OPENSSL_MODULES DEASSIGN OPENSSL_ENGINES DEASSIGN BLDTOP @@ -459,7 +466,9 @@ list-tests : @ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options" @ ! {- output_on() if !$disabled{tests}; "" -} -install : install_sw install_ssldirs install_docs +install : install_sw install_ssldirs install_docs install_final + +install_final : @ WRITE SYS$OUTPUT "" @ WRITE SYS$OUTPUT "######################################################################" @ WRITE SYS$OUTPUT "" @@ -496,6 +505,10 @@ libclean : {- join("\n\t", map { "- DELETE $_.EXE;*,$_.MAP;*" } @shlibs) || "@ !" -} clean : libclean + {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man1}}) || "@ !" -} + {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man3}}) || "@ !" -} + {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man5}}) || "@ !" -} + {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{htmldocs}->{man7}}) || "@ !" -} {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{programs}}) || "@ !" -} {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{modules}}) || "@ !" -} {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{scripts}}) || "@ !" -} @@ -659,11 +672,21 @@ vmsconfig.pm : configdata.pm WRITE CONFIG "1;" CLOSE CONFIG -install_html_docs : check_INSTALLTOP - sourcedir = F$PARSE("{- $sourcedir -}A.;","[]") - "]A.;" + ".DOC]" - $(PERL) {- sourcefile("util", "process_docs.pl") -} - - --sourcedir='sourcedir' --destdir=ossl_installroot:[HTML] - - --type=html +install_html_docs : check_INSTALLTOP build_html_docs + @ WRITE SYS$OUTPUT "*** Installing HTML docs" + - CREATE/DIR ossl_installroot:[HTML.MAN1] + - CREATE/DIR ossl_installroot:[HTML.MAN3] + - CREATE/DIR ossl_installroot:[HTML.MAN5] + - CREATE/DIR ossl_installroot:[HTML.MAN7] + {- join("\n ", + ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN1]" } + @{$unified_info{htmldocs}->{man1}} ), + ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN3]" } + @{$unified_info{htmldocs}->{man3}} ), + ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN5]" } + @{$unified_info{htmldocs}->{man5}} ), + ( map { "COPY/PROT=W:RE $_ ossl_installroot:[HTML.MAN7]" } + @{$unified_info{htmldocs}->{man7}} )) -} check_INSTALLTOP : @ IF "$(INSTALLTOP)" .EQS. "" THEN - @@ -756,7 +779,18 @@ reconfigure reconf : my $generator_incs = join("", map { ' "-I'.$_.'"' } @{$args{generator_incs}}); my $deps = join(", -\n\t\t", @{$args{generator_deps}}, @{$args{deps}}); - if (platform->isdef($args{src})) { + if ($args{src} =~ /\.html$/) { + my $title = basename($args{src}, ".html"); + my $pod = $args{generator}->[0]; + return <<"EOF"; +$args{src}: $pod + pipe pod2html "--podroot=\$(SRCDIR)/doc" --htmldir=.. - + --podpath=man1:man3:man5:man7 "--infile=$pod" - + "--title=$title" - + | \$(PERL) -pe "s|href=""http://man\\.he\\.net/(man\d/[^""]+)(?:\\.html)?""|href=""../\$1.html|g;" - + > \$\@ +EOF + } elsif (platform->isdef($args{src})) { my $target = platform->def($args{src}); my $mkdef = sourcefile('util', 'mkdef.pl'); my $ord_ver = $args{intent} eq 'lib' ? ' --version $(VERSION)' : ''; diff --git a/Configurations/shared-info.pl b/Configurations/shared-info.pl index f9420785..a673c7ca 100644 --- a/Configurations/shared-info.pl +++ b/Configurations/shared-info.pl @@ -84,4 +84,16 @@ my %shared_info; shared_sonameflag => '-h ', }; }, + 'solaris-gcc-shared' => sub { + return $shared_info{'linux-shared'} if detect_gnu_ld(); + return { + # Note: we should also have -shared here, but because some + # config targets define it with an added -static-libgcc + # following it, we don't want to change the order. This + # forces all solaris gcc config targets to define shared_ldflag + shared_ldflag => '-Wl,-Bsymbolic', + shared_defflag => "-Wl,-M,", + shared_sonameflag => "-Wl,-h,", + }; + }, ); diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index d5deb87e..f01040d3 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -162,6 +162,38 @@ MISC_SCRIPTS={- && $unified_info{attributes}->{scripts}->{$_}->{misc} } @{$unified_info{scripts}})) -} +HTMLDOCS1={- + join(" \\\n" . ' ' x 10, + fill_lines(" ", $COLUMNS - 10, map { platform->bin($_) } + @{$unified_info{htmldocs}->{man1}})) -} +HTMLDOCS3={- + join(" \\\n" . ' ' x 10, + fill_lines(" ", $COLUMNS - 10, map { platform->bin($_) } + @{$unified_info{htmldocs}->{man3}})) -} +HTMLDOCS5={- + join(" \\\n" . ' ' x 10, + fill_lines(" ", $COLUMNS - 10, map { platform->bin($_) } + @{$unified_info{htmldocs}->{man5}})) -} +HTMLDOCS7={- + join(" \\\n" . ' ' x 10, + fill_lines(" ", $COLUMNS - 10, map { platform->bin($_) } + @{$unified_info{htmldocs}->{man7}})) -} +MANDOCS1={- + join(" \\\n" . ' ' x 9, + fill_lines(" ", $COLUMNS - 9, map { platform->bin($_) } + @{$unified_info{mandocs}->{man1}})) -} +MANDOCS3={- + join(" \\\n" . ' ' x 9, + fill_lines(" ", $COLUMNS - 9, map { platform->bin($_) } + @{$unified_info{mandocs}->{man3}})) -} +MANDOCS5={- + join(" \\\n" . ' ' x 9, + fill_lines(" ", $COLUMNS - 9, map { platform->bin($_) } + @{$unified_info{mandocs}->{man5}})) -} +MANDOCS7={- + join(" \\\n" . ' ' x 9, + fill_lines(" ", $COLUMNS - 9, map { platform->bin($_) } + @{$unified_info{mandocs}->{man7}})) -} APPS_OPENSSL={- use File::Spec::Functions; catfile("apps","openssl") -} @@ -300,8 +332,15 @@ LIB_CPPFLAGS={- our $lib_cppflags = join(' ', $target{lib_cppflags} || (), $target{shared_cppflag} || (), (map { '-D'.$_ } + @{$target{lib_defines} || ()}, + @{$target{shared_defines} || ()}, @{$config{lib_defines} || ()}, @{$config{shared_defines} || ()}), + (map { '-I'.quotify1($_) } + @{$target{lib_includes}}, + @{$target{shared_includes}}, + @{$config{lib_includes}}, + @{$config{shared_includes}}), @{$config{lib_cppflags}}, @{$config{shared_cppflag}}); join(' ', $lib_cppflags, @@ -327,8 +366,15 @@ LIB_EX_LIBS=$(CNF_EX_LIBS) $(EX_LIBS) DSO_CPPFLAGS={- join(' ', $target{dso_cppflags} || (), $target{module_cppflags} || (), (map { '-D'.$_ } + @{$target{dso_defines}}, + @{$target{module_defines}}, @{$config{dso_defines} || ()}, @{$config{module_defines} || ()}), + (map { '-I'.quotify1($_) } + @{$target{dso_includes}}, + @{$target{module_includes}}, + @{$config{dso_includes}}, + @{$config{module_includes}}), @{$config{dso_cppflags}}, @{$config{module_cppflags}}, '$(CNF_CPPFLAGS)', '$(CPPFLAGS)') -} @@ -387,11 +433,15 @@ LANG=C # The main targets ################################################### -{- dependmagic('all'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils +{- dependmagic('build_sw'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils {- dependmagic('build_libs'); -}: build_libs_nodep {- dependmagic('build_modules'); -}: build_modules_nodep {- dependmagic('build_programs'); -}: build_programs_nodep +build_docs: build_man_docs build_html_docs +build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) +build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) + build_generated: $(GENERATED_MANDATORY) build_libs_nodep: libcrypto.pc libssl.pc openssl.pc build_modules_nodep: $(MODULES) @@ -402,13 +452,15 @@ build_apps build_tests: build_programs # Convenience target to prebuild all generated files, not just the mandatory # ones -build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) +build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs @ : {- output_off() if $disabled{makedepend}; "" -} @echo "Warning: consider configuring with no-makedepend, because if" @echo " target system doesn't have $(PERL)," @echo " then make will fail..." @ : {- output_on() if $disabled{makedepend}; "" -} +all: build_sw build_docs + test: tests {- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep link-utils @ : {- output_off() if $disabled{tests}; "" -} @@ -421,8 +473,7 @@ test: tests EXE_EXT={- platform->binext() -} \ OPENSSL_ENGINES=`cd ../$(BLDDIR)/engines 2>/dev/null && pwd` \ OPENSSL_MODULES=`cd ../$(BLDDIR)/providers 2>/dev/null && pwd` \ - OPENSSL_DEBUG_MEMORY=on \ - $(PERL) ../$(SRCDIR)/test/run_tests.pl $(TESTS) ) + $(PERL) ../$(SRCDIR)/test/run_tests.pl $(TESTS) ) @ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} @echo "Tests are not supported with your chosen Configure options" @ : {- output_on() if !$disabled{tests}; "" -} @@ -458,10 +509,12 @@ libclean: $(RM) *{- platform->defext() -} clean: libclean + $(RM) $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) + $(RM) $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) $(RM) $(PROGRAMS) $(TESTPROGS) $(MODULES) $(SCRIPTS) $(RM) $(GENERATED_MANDATORY) $(GENERATED) - -$(RM) `find . -name '*{- platform->depext() -}' \! -name '.*' -print` - -$(RM) `find . -name '*{- platform->objext() -}' \! -name '.*' -print` + -$(RM) `find . -name '*{- platform->depext() -}' \! -name '.*' \! -type d -print` + -$(RM) `find . -name '*{- platform->objext() -}' \! -name '.*' \! -type d -print` $(RM) core $(RM) tags TAGS doc-nits $(RM) -r test/test-runs @@ -764,29 +817,131 @@ uninstall_runtime_libs: @ : {- output_on() unless windowsdll(); "" -} -install_man_docs: +install_man_docs: build_man_docs @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(MANDIR)/man1 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(MANDIR)/man3 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(MANDIR)/man5 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(MANDIR)/man7 @$(ECHO) "*** Installing manpages" - $(PERL) $(SRCDIR)/util/process_docs.pl \ - --destdir=$(DESTDIR)$(MANDIR) --type=man --suffix=$(MANSUFFIX) + @set -e; for x in dummy $(MANDOCS1); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man1/$$fn"; \ + cp $$x $(DESTDIR)$(MANDIR)/man1/$$fn$(MANSUFFIX); \ + chmod 755 $(DESTDIR)$(MANDIR)/man1/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS3); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man3/$$fn"; \ + cp $$x $(DESTDIR)$(MANDIR)/man3/$$fn$(MANSUFFIX); \ + chmod 755 $(DESTDIR)$(MANDIR)/man3/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS5); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man5/$$fn"; \ + cp $$x $(DESTDIR)$(MANDIR)/man5/$$fn$(MANSUFFIX); \ + chmod 755 $(DESTDIR)$(MANDIR)/man5/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS7); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man7/$$fn"; \ + cp $$x $(DESTDIR)$(MANDIR)/man7/$$fn$(MANSUFFIX); \ + chmod 755 $(DESTDIR)$(MANDIR)/man7/$$fn$(MANSUFFIX); \ + done uninstall_man_docs: @$(ECHO) "*** Uninstalling manpages" - $(PERL) $(SRCDIR)/util/process_docs.pl \ - --destdir=$(DESTDIR)$(MANDIR) --type=man --suffix=$(MANSUFFIX) \ - --remove + @set -e; for x in dummy $(MANDOCS1); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man1/$$fn"; \ + $(RM) $(DESTDIR)$(MANDIR)/man1/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS3); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man3/$$fn"; \ + $(RM) $(DESTDIR)$(MANDIR)/man3/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS5); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man5/$$fn"; \ + $(RM) $(DESTDIR)$(MANDIR)/man5/$$fn$(MANSUFFIX); \ + done + @set -e; for x in dummy $(MANDOCS7); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man7/$$fn"; \ + $(RM) $(DESTDIR)$(MANDIR)/man7/$$fn$(MANSUFFIX); \ + done -install_html_docs: +install_html_docs: build_html_docs @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(HTMLDIR)/man1 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(HTMLDIR)/man3 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(HTMLDIR)/man5 + @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(HTMLDIR)/man7 @$(ECHO) "*** Installing HTML manpages" - $(PERL) $(SRCDIR)/util/process_docs.pl \ - --destdir=$(DESTDIR)$(HTMLDIR) --type=html + @set -e; for x in dummy $(HTMLDOCS1); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man1/$$fn"; \ + cp $$x $(DESTDIR)$(HTMLDIR)/man1/$$fn; \ + chmod 755 $(DESTDIR)$(HTMLDIR)/man1/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS3); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man3/$$fn"; \ + cp $$x $(DESTDIR)$(HTMLDIR)/man3/$$fn; \ + chmod 755 $(DESTDIR)$(HTMLDIR)/man3/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS5); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man5/$$fn"; \ + cp $$x $(DESTDIR)$(HTMLDIR)/man5/$$fn; \ + chmod 755 $(DESTDIR)$(HTMLDIR)/man5/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS7); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man7/$$fn"; \ + cp $$x $(DESTDIR)$(HTMLDIR)/man7/$$fn; \ + chmod 755 $(DESTDIR)$(HTMLDIR)/man7/$$fn; \ + done uninstall_html_docs: - @$(ECHO) "*** Uninstalling manpages" - $(PERL) $(SRCDIR)/util/process_docs.pl \ - --destdir=$(DESTDIR)$(HTMLDIR) --type=html --remove - + @$(ECHO) "*** Uninstalling HTML manpages" + @set -e; for x in dummy $(HTMLDOCS1); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(HTMLDIR)/man1/$$fn"; \ + $(RM) $(DESTDIR)$(HTMLDIR)/man1/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS3); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(HTMLDIR)/man3/$$fn"; \ + $(RM) $(DESTDIR)$(HTMLDIR)/man3/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS5); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(HTMLDIR)/man5/$$fn"; \ + $(RM) $(DESTDIR)$(HTMLDIR)/man5/$$fn; \ + done + @set -e; for x in dummy $(HTMLDOCS7); do \ + if [ "$$x" = "dummy" ]; then continue; fi; \ + fn=`basename $$x`; \ + $(ECHO) "$(RM) $(DESTDIR)$(HTMLDIR)/man7/$$fn"; \ + $(RM) $(DESTDIR)$(HTMLDIR)/man7/$$fn; \ + done # Developer targets (note: these are only available on Unix) ######### @@ -1027,7 +1182,27 @@ reconfigure reconf: my $defs = join("", map { " -D".$_ } @{$args{defs}}); my $deps = join(" ", @{$args{generator_deps}}, @{$args{deps}}); - if (platform->isdef($args{src})) { + if ($args{src} =~ /\.html$/) { + my $title = basename($args{src}, ".html"); + my $pod = $args{generator}->[0]; + return <<"EOF"; +$args{src}: $pod + pod2html "--podroot=\$(SRCDIR)/doc" --htmldir=.. \\ + --podpath=man1:man3:man5:man7 --infile=$pod "--title=$title" \\ + | \$(PERL) -pe 's|href="http://man\\.he\\.net/(man\\d/[^"]+)(?:\\.html)?"|href="../\$1.html|g;' \\ + > \$\@ +EOF + } elsif ($args{src} =~ /\.(\d)$/) { + my $section = $1; + my $name = uc basename($args{src}, ".$section"); + my $pod = $args{generator}->[0]; + return <<"EOF"; +$args{src}: $pod + pod2man --name=$name --section=$section --center=OpenSSL \\ + --release=\$(VERSION) $pod \\ + > \$\@ +EOF + } elsif (platform->isdef($args{src})) { my $target = platform->def($args{src}); (my $mkdef_os = $target{shared_target}) =~ s|-shared$||; my $ord_ver = $args{intent} eq 'lib' ? ' --version $(VERSION)' : ''; diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl index 19e3f4e0..275c93eb 100644 --- a/Configurations/windows-makefile.tmpl +++ b/Configurations/windows-makefile.tmpl @@ -3,6 +3,8 @@ ## ## {- join("\n## ", @autowarntext) -} {- + use File::Basename; + our $sover_dirname = platform->shlib_version_as_filename(); my $build_scheme = $target{build_scheme}; @@ -111,6 +113,22 @@ MISC_SCRIPTS={- && $unified_info{attributes}->{scripts}->{$_}->{misc} } @{$unified_info{scripts}}) -} +HTMLDOCS1={- our @HTMLDOCS1 = @{$unified_info{htmldocs}->{man1}}; + join(" ", @HTMLDOCS1) -} +HTMLDOCS3={- our @HTMLDOCS3 = @{$unified_info{htmldocs}->{man3}}; + join(" ", @HTMLDOCS3) -} +HTMLDOCS5={- our @HTMLDOCS5 = @{$unified_info{htmldocs}->{man5}}; + join(" ", @HTMLDOCS5) -} +HTMLDOCS7={- our @HTMLDOCS7 = @{$unified_info{htmldocs}->{man7}}; + join(" ", @HTMLDOCS7) -} +HTMLDOCS1_BLDDIRS={- my %dirs = map { dirname($_) => 1 } @HTMLDOCS1; + join(' ', sort keys %dirs) -} +HTMLDOCS3_BLDDIRS={- my %dirs = map { dirname($_) => 1 } @HTMLDOCS3; + join(' ', sort keys %dirs) -} +HTMLDOCS5_BLDDIRS={- my %dirs = map { dirname($_) => 1 } @HTMLDOCS5; + join(' ', sort keys %dirs) -} +HTMLDOCS7_BLDDIRS={- my %dirs = map { dirname($_) => 1 } @HTMLDOCS7; + join(' ', sort keys %dirs) -} APPS_OPENSSL={- use File::Spec::Functions; "\"".catfile("apps","openssl")."\"" -} @@ -183,29 +201,29 @@ libdir={- file_name_is_absolute($libdir) ##### User defined commands and flags ################################ -CC={- $config{CC} -} -CPP={- $config{CPP} -} +CC="{- $config{CC} -}" +CPP="{- $config{CPP} -}" CPPFLAGS={- our $cppflags1 = join(" ", (map { "-D".$_} @{$config{CPPDEFINES}}), - (map { " /I ".$_} @{$config{CPPINCLUDES}}), + (map { " -I ".$_} @{$config{CPPINCLUDES}}), @{$config{CPPFLAGS}}) -} CFLAGS={- join(' ', @{$config{CFLAGS}}) -} -LD={- $config{LD} -} +LD="{- $config{LD} -}" LDFLAGS={- join(' ', @{$config{LDFLAGS}}) -} EX_LIBS={- join(' ', @{$config{LDLIBS}}) -} PERL={- $config{PERL} -} -AR={- $config{AR} -} +AR="{- $config{AR} -}" ARFLAGS= {- join(' ', @{$config{ARFLAGS}}) -} -MT={- $config{MT} -} +MT="{- $config{MT} -}" MTFLAGS= {- join(' ', @{$config{MTFLAGS}}) -} -AS={- $config{AS} -} +AS="{- $config{AS} -}" ASFLAGS={- join(' ', @{$config{ASFLAGS}}) -} -RC={- $config{RC} -} +RC="{- $config{RC} -}" RCFLAGS={- join(' ', @{$config{RCFLAGS}}) -} ECHO="$(PERL)" "$(SRCDIR)\util\echo.pl" @@ -316,6 +334,7 @@ BIN_ASFLAGS={- join(' ', $target{bin_asflags} || (), @{$config{bin_asflags}}, '$(CNF_ASFLAGS)', '$(ASFLAGS)') -} BIN_CPPFLAGS={- join(' ', $target{bin_cppflags} || (), + (map { '-D'.$_ } @{$config{bin_defines} || ()}), @{$config{bin_cppflags}}, '$(CNF_CPPFLAGS)', '$(CPPFLAGS)') -} BIN_CFLAGS={- join(' ', $target{bin_cflags} || (), @@ -338,11 +357,14 @@ PROCESSOR= {- $config{processor} -} # The main targets ################################################### -{- dependmagic('all'); -}: build_libs_nodep build_modules_nodep build_programs_nodep +{- dependmagic('build_sw'); -}: build_libs_nodep build_modules_nodep build_programs_nodep {- dependmagic('build_libs'); -}: build_libs_nodep {- dependmagic('build_modules'); -}: build_modules_nodep {- dependmagic('build_programs'); -}: build_programs_nodep +build_docs: build_html_docs +build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) + build_generated: $(GENERATED_MANDATORY) build_libs_nodep: $(LIBS) {- join(" ",map { platform->sharedlib_import($_) // () } @{$unified_info{libraries}}) -} build_modules_nodep: $(MODULES) @@ -353,13 +375,15 @@ build_apps build_tests: build_programs # Convenience target to prebuild all generated files, not just the mandatory # ones -build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) +build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs @{- output_off() if $disabled{makedepend}; "" -} @$(ECHO) "Warning: consider configuring with no-makedepend, because if" @$(ECHO) " target system doesn't have $(PERL)," @$(ECHO) " then make will fail..." @{- output_on() if $disabled{makedepend}; "" -} +all: build_sw build_docs + test: tests {- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep @{- output_off() if $disabled{tests}; "" -} @@ -370,7 +394,6 @@ test: tests set PERL=$(PERL) set OPENSSL_ENGINES=$(MAKEDIR)\engines set OPENSSL_MODULES=$(MAKEDIR)\providers - set OPENSSL_DEBUG_MEMORY=on "$(PERL)" "$(SRCDIR)\test\run_tests.pl" $(TESTS) @{- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} @$(ECHO) "Tests are not supported with your chosen Configure options" @@ -393,6 +416,10 @@ libclean: -del /Q /F $(LIBS) libcrypto.* libssl.* ossl_static.pdb clean: libclean + -rmdir /Q /S $(HTMLDOCS1_BLDDIRS) + -rmdir /Q /S $(HTMLDOCS3_BLDDIRS) + -rmdir /Q /S $(HTMLDOCS5_BLDDIRS) + -rmdir /Q /S $(HTMLDOCS7_BLDDIRS) {- join("\n\t", map { "-del /Q /F $_" } @PROGRAMS) -} -del /Q /F $(MODULES) -del /Q /F $(SCRIPTS) @@ -432,7 +459,8 @@ install_ssldirs: @IF NOT EXIST "$(OPENSSLDIR)\openssl.cnf" \ "$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\apps\openssl.cnf" \ "$(OPENSSLDIR)\openssl.cnf" - @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(MISC_SCRIPTS) \ + @if not "$(MISC_SCRIPTS)"=="" \ + "$(PERL)" "$(SRCDIR)\util\copy.pl" $(MISC_SCRIPTS) \ "$(OPENSSLDIR)\misc" @"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\apps\ct_log_list.cnf" \ "$(OPENSSLDIR)\ct_log_list.cnf.dist" @@ -486,19 +514,35 @@ install_runtime_libs: build_libs install_programs: install_runtime_libs build_programs @if "$(INSTALLTOP)"=="" ( $(ECHO) "INSTALLTOP should not be empty" & exit 1 ) @$(ECHO) "*** Installing runtime programs" - @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\bin" - @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMS) \ + @if not "$(INSTALL_PROGRAMS)"=="" \ + "$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\bin" + @if not "$(INSTALL_PROGRAMS)"=="" \ + "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMS) \ "$(INSTALLTOP)\bin" - @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMPDBS) \ + @if not "$(INSTALL_PROGRAMS)"=="" \ + "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMPDBS) \ "$(INSTALLTOP)\bin" - @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BIN_SCRIPTS) \ + @if not "$(INSTALL_PROGRAMS)"=="" \ + "$(PERL)" "$(SRCDIR)\util\copy.pl" $(BIN_SCRIPTS) \ "$(INSTALLTOP)\bin" uninstall_runtime: -install_html_docs: - "$(PERL)" "$(SRCDIR)\util\process_docs.pl" \ - "--destdir=$(INSTALLTOP)\html" --type=html +install_html_docs: build_html_docs + @if "$(INSTALLTOP)"=="" ( echo INSTALLTOP should not be empty & exit 1 ) + @echo *** Installing HTML docs + @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\html\man1" + @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\html\man3" + @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\html\man5" + @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\html\man7" + @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BLDDIR)\doc\html\man1\*.html \ + "$(INSTALLTOP)\html\man1" + @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BLDDIR)\doc\html\man3\*.html \ + "$(INSTALLTOP)\html\man3" + @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BLDDIR)\doc\html\man5\*.html \ + "$(INSTALLTOP)\html\man5" + @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BLDDIR)\doc\html\man7\*.html \ + "$(INSTALLTOP)\html\man7" uninstall_html_docs: @@ -535,12 +579,22 @@ reconfigure reconf: my ($gen0, @gens) = @{$args{generator}}; my $generator = '"'.$gen0.'"'.join('', map { " $_" } @gens); my $generator_incs = join("", map { " -I \"$_\"" } @{$args{generator_incs}}); - my $incs = join("", map { " /I \"$_\"" } @{$args{incs}}); - my $defs = join("", map { " /D".$_ } @{$args{defs}}); + my $incs = join("", map { " -I \"$_\"" } @{$args{incs}}); + my $defs = join("", map { " -D".$_ } @{$args{defs}}); my $deps = @{$args{deps}} ? '"'.join('" "', @{$args{generator_deps}}, @{$args{deps}}).'"' : ''; - if (platform->isdef($args{src})) { + if ($args{src} =~ /\.html$/) { + my $title = basename($args{src}, ".html"); + my $pod = $args{generator}->[0]; + return <<"EOF"; +$args{src}: "$pod" + pod2html "--podroot=\$(SRCDIR)/doc" --htmldir=.. \\ + --podpath=man1:man3:man5:man7 "--infile=$pod" "--title=$title" \\ + | \$(PERL) -pe ^"s^|href=\\^"http://man\\.he\\.net/^(man\\d/[^^\\^"]+^)^(?:\.html^)?^"^|href=\\^"../\$\$1.html^|g;^" \\ + > \$\@ +EOF + } elsif (platform->isdef($args{src})) { my $target = platform->def($args{src}); my $mkdef = abs2rel(rel2abs(catfile($config{sourcedir}, "util", "mkdef.pl")), @@ -627,8 +681,8 @@ EOF ( @{$args{srcs}} ); my $srcs = '"'.join('" "', @srcs).'"'; my $deps = '"'.join('" "', @srcs, @{$args{deps}}).'"'; - my $incs = join("", map { ' /I "'.$_.'"' } @{$args{incs}}); - my $defs = join("", map { " /D".$_ } @{$args{defs}}); + my $incs = join("", map { ' -I "'.$_.'"' } @{$args{incs}}); + my $defs = join("", map { " -D".$_ } @{$args{defs}}); my $cflags = { shlib => ' $(LIB_CFLAGS)', lib => ' $(LIB_CFLAGS)', dso => ' $(DSO_CFLAGS)', @@ -660,7 +714,7 @@ EOF } elsif ($srcs[0] =~ /.S$/) { return <<"EOF"; $obj: $deps - \$(CC) /EP /D__ASSEMBLER__ $cflags $defs $srcs > \$@.asm && \$(AS) $asflags \$(ASOUTFLAG)\$\@ \$@.asm + \$(CC) /EP -D__ASSEMBLER__ $cflags $defs $srcs > \$@.asm && \$(AS) $asflags \$(ASOUTFLAG)\$\@ \$@.asm EOF } my $recipe = <<"EOF"; diff --git a/Configure b/Configure index 3df3e0c9..1e86bfa1 100755 --- a/Configure +++ b/Configure @@ -45,9 +45,11 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # # --cross-compile-prefix Add specified prefix to binutils components. # -# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0.0 / 3. -# Do not compile support for interfaces deprecated as of the -# specified OpenSSL version. +# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0 +# Define the public APIs as they were for that version +# including patch releases. If 'no-deprecated' is also +# given, do not compile support for interfaces deprecated +# up to and including the specified OpenSSL version. # # no-hw-xxx do not compile support for specific crypto hardware. # Generic OpenSSL-style methods relating to this support @@ -164,9 +166,9 @@ my @clang_devteam_warn = qw( -Wmissing-variable-declarations ); -# This adds backtrace information to the memory leak info. Is only used -# when crypto-mdebug-backtrace is enabled. -my $memleak_devteam_backtrace = "-rdynamic"; +my @cl_devteam_warn = qw( + /WX +); my $strict_warnings = 0; @@ -182,15 +184,24 @@ our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; # # API compatibility name to version number mapping. # -my $maxapi = "3.0.0"; # API for "no-deprecated" builds my $apitable = { - "3.0.0" => 3, - "1.1.1" => 2, - "1.1.0" => 2, - "1.0.2" => 1, - "1.0.1" => 1, - "1.0.0" => 1, - "0.9.8" => 0, + # This table expresses when API additions or changes can occur. + # The numbering used changes from 3.0 and on because we updated + # (solidified) our version numbering scheme at that point. + + # From 3.0 and on, we internalise the given version number in dedcimal + # as MAJOR * 10000 + MINOR * 100 + 0 + "3.0.0" => 30000, + "3.0" => 30000, + + # Note that before 3.0, we didn't have the same version number scheme. + # Still, the numbering we use here covers what we need. + "1.1.1" => 10101, + "1.1.0" => 10100, + "1.0.2" => 10002, + "1.0.1" => 10001, + "1.0.0" => 10000, + "0.9.8" => 908, }; our %table = (); @@ -255,38 +266,39 @@ if (grep /^reconf(igure)?$/, @argvcopy) { $config{perlargv} = [ @argvcopy ]; # Collect version numbers -$config{major} = "unknown"; -$config{minor} = "unknown"; -$config{patch} = "unknown"; -$config{prerelease} = ""; -$config{build_metadata} = ""; -$config{shlib_version} = "unknown"; +my %version = (); collect_information( - collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')), - qr/#\s+define\s+OPENSSL_VERSION_MAJOR\s+(\d+)/ => - sub { $config{major} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_MINOR\s+(\d+)/ => - sub { $config{minor} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_PATCH\s+(\d+)/ => - sub { $config{patch} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_PRE_RELEASE\s+"((?:\\.|[^"])*)"/ => - sub { $config{prerelease} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_BUILD_METADATA\s+"((?:\\.|[^"])*)"/ => - sub { $config{build_metadata} = $1; }, - qr/#\s+define\s+OPENSSL_SHLIB_VERSION\s+([\d\.]+)/ => - sub { $config{shlib_version} = $1; }, + collect_from_file(catfile($srcdir,'VERSION')), + qr/\s*(\w+)\s*=\s*(.*?)\s*$/ => + sub { + # Only define it if there is a value at all + $version{uc $1} = $2 if $2 ne ''; + }, + "OTHERWISE" => + sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION" }, ); -die "erroneous version information in opensslv.h: ", - "$config{major}.$config{minor}.$config{patch}, $config{shlib_version}\n" - if ($config{major} eq "unknown" - || $config{minor} eq "unknown" - || $config{patch} eq "unknown" - || $config{shlib_version} eq "unknown"); + +$config{major} = $version{MAJOR} // 'unknown'; +$config{minor} = $version{MINOR} // 'unknown'; +$config{patch} = $version{PATCH} // 'unknown'; +$config{prerelease} = + defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : ''; +$config{build_metadata} = + defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : ''; +$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown'; +$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx'; $config{version} = "$config{major}.$config{minor}.$config{patch}"; $config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}"; +die "erroneous version information in VERSION: ", + "$config{version}, $config{shlib_version}\n" + unless (defined $version{MAJOR} + && defined $version{MINOR} + && defined $version{PATCH} + && defined $version{SHLIB_VERSION}); + # Collect target configurations my $pattern = catfile(dirname($0), "Configurations", "*.conf"); @@ -329,7 +341,6 @@ my @dtls = qw(dtls1 dtls1_2); # For developers: keep it sorted alphabetically my @disablables = ( - "ktls", "afalgeng", "aria", "asan", @@ -350,7 +361,6 @@ my @disablables = ( "cms", "comp", "crypto-mdebug", - "crypto-mdebug-backtrace", "ct", "deprecated", "des", @@ -376,6 +386,7 @@ my @disablables = ( "fuzz-afl", "gost", "idea", + "ktls", "legacy", "makedepend", "md2", @@ -447,6 +458,7 @@ my @disablables_int = qw( my %deprecated_disablables = ( "ssl2" => undef, "buf-freelists" => undef, + "crypto-mdebug-backtrace" => undef, "hw" => "hw", # causes cascade, but no macro "hw-padlock" => "padlockeng", "ripemd" => "rmd160", @@ -547,6 +559,11 @@ my @disable_cascades = ( "legacy" => [ "md2" ], "cmp" => [ "crmf" ], + + # Padlock engine uses low-level AES APIs which are deprecated + sub { $disabled{"deprecated"} + && (!defined $config{"api"} || $config{"api"} >= 30000) } + => [ "padlockeng" ] ); # Avoid protocol support holes. Also disable all versions below N, if version @@ -573,7 +590,7 @@ while ((my $first, my $second) = (shift @list, shift @list)) { &usage if ($#ARGV < 0); -# For the "make variables" CINCLUDES and CDEFINES, we support lists with +# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with # platform specific list separators. Users from those platforms should # recognise those separators from how you set up the PATH to find executables. # The default is the Unix like separator, :, but as an exception, we also @@ -839,7 +856,10 @@ while (@argvcopy) } elsif (/^--api=(.*)$/) { - $config{api}=$1; + my $api = $1; + die "Unknown API compatibility level $api" + unless defined $apitable->{$api}; + $config{api}=$apitable->{$api}; } elsif (/^--libdir=(.*)$/) { @@ -956,10 +976,6 @@ while (@argvcopy) } } -if (defined($config{api}) && !exists $apitable->{$config{api}}) { - die "***** Unsupported api compatibility level: $config{api}\n", -} - if (keys %deprecated_options) { warn "***** Deprecated options: ", @@ -1014,7 +1030,11 @@ foreach (keys %user) { if (defined $value) { if (ref $user{$_} eq 'ARRAY') { - $user{$_} = [ split /$list_separator_re/, $value ]; + if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') { + $user{$_} = [ split /$list_separator_re/, $value ]; + } else { + $user{$_} = [ $value ]; + } } elsif (!defined $user{$_}) { $user{$_} = $value; } @@ -1224,46 +1244,6 @@ foreach (keys %useradd) { # Allow overriding the build file name $config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; -###################################################################### -# Build up information for skipping certain directories depending on disabled -# features, as well as setting up macros for disabled features. - -# This is a tentative database of directories to skip. Some entries may not -# correspond to anything real, but that's ok, they will simply be ignored. -# The actual processing of these entries is done in the build.info lookup -# loop further down. -# -# The key is a Unix formated path in the source tree, the value is an index -# into %disabled_info, so any existing path gets added to a corresponding -# 'skipped' entry in there with the list of skipped directories. -my %skipdir = (); -my %disabled_info = (); # For configdata.pm -foreach my $what (sort keys %disabled) { - # There are deprecated disablables that translate to themselves. - # They cause disabling cascades, but should otherwise not regiter. - next if $deprecated_disablables{$what}; - - $config{options} .= " no-$what"; - - if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', - 'module', 'pic', 'dynamic-engine', 'makedepend', - 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) { - (my $WHAT = uc $what) =~ s|-|_|g; - my $skipdir = $what; - - # fix-up crypto/directory name(s) - $skipdir = "ripemd" if $what eq "rmd160"; - $skipdir = "whrlpool" if $what eq "whirlpool"; - - my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; - push @{$config{openssl_feature_defines}}, $macro; - - $skipdir{engines} = $what if $what eq 'engine'; - $skipdir{"crypto/$skipdir"} = $what - unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; - } -} - # Make sure build_scheme is consistent. $target{build_scheme} = [ $target{build_scheme} ] if ref($target{build_scheme}) ne "ARRAY"; @@ -1360,11 +1340,6 @@ unless($disabled{threads}) { push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS"; } -# With "deprecated" disable all deprecated features. -if (defined($disabled{"deprecated"})) { - $config{api} = $maxapi; -} - my $no_shared_warn=0; if ($target{shared_target} eq "") { @@ -1374,10 +1349,8 @@ if ($target{shared_target} eq "") } if ($disabled{"dynamic-engine"}) { - push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; $config{dynamic_engines} = 0; } else { - push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; $config{dynamic_engines} = 1; } @@ -1426,14 +1399,18 @@ if ($target{sys_id} ne "") push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; } -unless ($disabled{asm}) { -} - my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); my %predefined_CXX = $config{CXX} ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX}) : (); +unless ($disabled{asm}) { + # big endian systems can use ELFv2 ABI + if ($target eq "linux-ppc64") { + $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2); + } +} + # Check for makedepend capabilities. if (!$disabled{makedepend}) { if ($config{target} =~ /^(VC|vms)-/) { @@ -1498,6 +1475,8 @@ foreach (sort split(/\s+/,$target{bn_ops})) { die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" if $count > 1; +$config{api} = $config{major} * 10000 + $config{minor} * 100 + unless $config{api}; # Hack cflags for better warnings (dev option) ####################### @@ -1509,7 +1488,7 @@ $config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } @{$config{cxxflags}} ] if $config{CXX}; $config{openssl_api_defines} = [ - "OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1) + "OPENSSL_CONFIGURED_API=".$config{api} ]; my @strict_warnings_collection=(); @@ -1518,11 +1497,20 @@ if ($strict_warnings) my $wopt; my $gccver = $predefined_C{__GNUC__} // -1; - warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike" - unless $gccver >= 4; - push @strict_warnings_collection, @gcc_devteam_warn; - push @strict_warnings_collection, @clang_devteam_warn - if (defined($predefined_C{__clang__})); + if ($gccver >= 4) + { + push @strict_warnings_collection, @gcc_devteam_warn; + push @strict_warnings_collection, @clang_devteam_warn + if (defined($predefined_C{__clang__})); + } + elsif ($config{target} =~ /^VC-/) + { + push @strict_warnings_collection, @cl_devteam_warn; + } + else + { + warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC" + } } if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) { @@ -1534,19 +1522,6 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings' : ( $_ ) } @{$config{CFLAGS}} ]; -unless ($disabled{"crypto-mdebug-backtrace"}) - { - foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) - { - push @{$config{cflags}}, $wopt - unless grep { $_ eq $wopt } @{$config{cflags}}; - } - if ($target =~ /^BSD-/) - { - push @{$config{ex_libs}}, "-lexecinfo"; - } - } - unless ($disabled{afalgeng}) { $config{afalgeng}=""; if (grep { $_ eq 'afalgeng' } @{$target{enable}}) { @@ -1569,7 +1544,20 @@ unless ($disabled{afalgeng}) { } } -push @{$config{openssl_feature_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng}); +unless ($disabled{devcryptoeng}) { + if ($target =~ m/^BSD/) { + my $maxver = 5*100 + 7; + my $sysstr = `uname -s`; + my $verstr = `uname -r`; + $sysstr =~ s|\R$||; + $verstr =~ s|\R$||; + my ($ma, $mi, @rest) = split m|\.|, $verstr; + my $ver = $ma*100 + $mi; + if ($sysstr eq 'OpenBSD' && $ver >= $maxver) { + disable('too-new-kernel', 'devcryptoeng'); + } + } +} unless ($disabled{ktls}) { $config{ktls}=""; @@ -1585,8 +1573,14 @@ unless ($disabled{ktls}) { if ($verstr[2] < $minver) { disable('too-old-kernel', 'ktls'); } + } elsif ($target =~ m/^BSD/) { + my $cc = $config{CROSS_COMPILE}.$config{CC}; + system("printf '#include \n#include ' | $cc -E - >/dev/null 2>&1"); + if ($? != 0) { + disable('too-old-freebsd', 'ktls'); + } } else { - disable('not-linux', 'ktls'); + disable('not-linux-or-freebsd', 'ktls'); } } @@ -1635,6 +1629,52 @@ $target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_l # ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON +###################################################################### +# Build up information for skipping certain directories depending on disabled +# features, as well as setting up macros for disabled features. + +# This is a tentative database of directories to skip. Some entries may not +# correspond to anything real, but that's ok, they will simply be ignored. +# The actual processing of these entries is done in the build.info lookup +# loop further down. +# +# The key is a Unix formatted path in the source tree, the value is an index +# into %disabled_info, so any existing path gets added to a corresponding +# 'skipped' entry in there with the list of skipped directories. +my %skipdir = (); +my %disabled_info = (); # For configdata.pm +foreach my $what (sort keys %disabled) { + # There are deprecated disablables that translate to themselves. + # They cause disabling cascades, but should otherwise not regiter. + next if $deprecated_disablables{$what}; + + $config{options} .= " no-$what"; + + if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', + 'module', 'pic', 'dynamic-engine', 'makedepend', + 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) { + (my $WHAT = uc $what) =~ s|-|_|g; + my $skipdir = $what; + + # fix-up crypto/directory name(s) + $skipdir = "ripemd" if $what eq "rmd160"; + $skipdir = "whrlpool" if $what eq "whirlpool"; + + my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; + push @{$config{openssl_feature_defines}}, $macro; + + $skipdir{engines} = $what if $what eq 'engine'; + $skipdir{"crypto/$skipdir"} = $what + unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; + } +} + +if ($disabled{"dynamic-engine"}) { + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; +} else { + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; +} + # If we use the unified build, collect information from build.info files my %unified_info = (); @@ -1750,6 +1790,8 @@ if ($builder eq "unified") { my %defines = (); my %depends = (); my %generate = (); + my %htmldocs = (); + my %mandocs = (); # Support for $variablename in build.info files. # Embedded perl code is the ultimate master, still. If its output @@ -1810,6 +1852,10 @@ if ($builder eq "unified") { # don't use it if the build tree is different. my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir); + + if ($buildinfo_debug) { + print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n"; + } push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); my $template = Text::Template->new(TYPE => 'FILE', @@ -1921,7 +1967,14 @@ if ($builder eq "unified") { @s); } }, - + qr/^\s* HTMLDOCS ${index_re} = ${value_re} $/x + => sub { push @{$htmldocs{$expand_variables->($+{INDEX})}}, + tokenize($expand_variables->($+{VALUE})) + if !@skip || $skip[$#skip] > 0 }, + qr/^\s* MANDOCS ${index_re} = ${value_re} $/x + => sub { push @{$mandocs{$expand_variables->($+{INDEX})}}, + tokenize($expand_variables->($+{VALUE})) + if !@skip || $skip[$#skip] > 0 }, qr/^\s* ORDINALS ${index_re} = ${value_re} $/x => sub { push @{$ordinals{$expand_variables->($+{INDEX})}}, tokenize($expand_variables->($+{VALUE})) @@ -2084,10 +2137,18 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); die "more than one generator for $dest: " - ,join(" ", @{$generate{$_}}),"\n" - if scalar @{$generate{$_}} > 1; + ,join(" ", @{$generate{$_}}),"\n" + if scalar @{$generate{$_}} > 1; my @generator = split /\s+/, $generate{$dest}->[0]; - $generator[0] = cleanfile($sourced, $generator[0], $blddir), + my $gen = $generator[0]; + $generator[0] = cleanfile($sourced, $gen, $blddir); + + # If the generator isn't in the source tree, we assume it's + # generated in the build tree + if ($generate{$gen}) { + $generator[0] = cleanfile($buildd, $gen, $blddir); + } + $unified_info{generate}->{$ddest} = [ @generator ]; } @@ -2179,6 +2240,20 @@ EOF } } } + + foreach my $section (keys %htmldocs) { + foreach (@{$htmldocs{$section}}) { + my $htmldocs = cleanfile($buildd, $_, $blddir); + $unified_info{htmldocs}->{$section}->{$htmldocs} = 1; + } + } + + foreach my $section (keys %mandocs) { + foreach (@{$mandocs{$section}}) { + my $mandocs = cleanfile($buildd, $_, $blddir); + $unified_info{mandocs}->{$section}->{$mandocs} = 1; + } + } } my $ordinals_text = join(', ', sort keys %ordinals); @@ -2339,7 +2414,8 @@ EOF $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; } # Two level structures - foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) { + foreach my $l1 (("sources", "shared_sources", "ldadd", "depends", + "htmldocs", "mandocs")) { foreach my $l2 (sort keys %{$unified_info{$l1}}) { my @items = sort @@ -2385,7 +2461,11 @@ EOF my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ], "dso" => [ @{$unified_info{modules}} ], "bin" => [ @{$unified_info{programs}} ], - "script" => [ @{$unified_info{scripts}} ] ); + "script" => [ @{$unified_info{scripts}} ], + "docs" => [ (map { @{$unified_info{htmldocs}->{$_} // []} } + keys %{$unified_info{htmldocs} // {}}), + (map { @{$unified_info{mandocs}->{$_} // []} } + keys %{$unified_info{mandocs} // {}}) ] ); foreach my $type (keys %loopinfo) { foreach my $product (@{$loopinfo{$type}}) { my %dirs = (); diff --git a/INSTALL b/INSTALL index c818ed72..36f27178 100644 --- a/INSTALL +++ b/INSTALL @@ -141,14 +141,20 @@ --openssldir depend in what configuration is used and what Windows implementation OpenSSL is built on. More notes on this in NOTES.WIN): - --api=x.y.z - Don't build with support for deprecated APIs below the - specified version number. For example "--api=1.1.0" will - remove support for all APIS that were deprecated in OpenSSL - version 1.1.0 or below. This is a rather specialized option - for developers. If you just intend to remove all deprecated - APIs entirely (up to the current version), it is easier - to add the 'no-deprecated' option instead (see below). + --api=x.y[.z] + Build the OpenSSL libraries to support the API for + the specified version. If "no-deprecated" is also + given, don't build with support for deprecated APIs + in or below the specified version number. For example + "--api=1.1.0" with "no-deprecated" will remove + support for all APIS that were deprecated in + OpenSSL version 1.1.0 or below. + This is a rather specialized option for developers. + If you just intend to remove all deprecated APIs + entirely (up to the current version), only specify + "-no-deprecated" (see below). + If "--api" isn't given, it defaults to the current + OpenSSL minor version. --cross-compile-prefix=PREFIX The PREFIX to include in front of commands for your @@ -338,27 +344,20 @@ work if the zlib or zlib-dynamic options are also chosen. enable-crypto-mdebug - Build support for debugging memory allocated via - OPENSSL_malloc() or OPENSSL_zalloc(). + This now only enables the failed-malloc feature. enable-crypto-mdebug-backtrace - As for crypto-mdebug, but additionally provide backtrace - information for allocated memory. - TO BE USED WITH CARE: this uses GNU C functionality, and - is therefore not usable for non-GNU config targets. If - your build complains about the use of '-rdynamic' or the - lack of header file execinfo.h, this option is not for you. - ALSO NOTE that even though execinfo.h is available on your - system (through Gnulib), the functions might just be stubs - that do nothing. + This is a no-op; the project uses the compiler's + address/leak sanitizer instead. no-ct Don't build support for Certificate Transparency. no-deprecated - Don't build with support for any deprecated APIs. This is the - same as using "--api" and supplying the latest version - number. + Don't build with support for deprecated APIs up + until and including the version given with + "--api" (or the current version of "--api" wasn't + given). no-dgram Don't build support for datagram based BIOs. Selecting this @@ -829,8 +828,8 @@ Configure creates a build file ("Makefile" on Unix, "makefile" on Windows and "descrip.mms" on OpenVMS) from a suitable template in Configurations, - and defines various macros in include/openssl/opensslconf.h (generated from - include/openssl/opensslconf.h.in). + and defines various macros in include/openssl/configuration.h (generated + from include/openssl/configuration.h.in). 1c. Configure OpenSSL for building outside of the source tree. @@ -1122,7 +1121,7 @@ HASHBANGPERL The command string for the Perl executable to insert in the - #! line of perl scripts that will be publically installed. + #! line of perl scripts that will be publicly installed. Default: /usr/bin/env perl Note: the value of this variable is added to the same scripts on all platforms, but it's only relevant on Unix-like platforms. @@ -1149,7 +1148,15 @@ described here. Examine the Makefiles themselves for the full list. all - The default target to build all the software components. + The target to build all the software components and + documentation. + + build_sw + Build all the software components. + THIS IS THE DEFAULT TARGET. + + build_docs + Build all documentation components. clean Remove all build artefacts and return the directory to a "clean" diff --git a/NEWS b/NEWS index 0463af6e..de439d6b 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ Major changes between OpenSSL 1.1.1 and OpenSSL 3.0.0 [under development] + o enable-crypto-mdebug and enable-crypto-mdebug-backtrace were mostly + disabled; the project uses address sanitize/leak-detect instead. + o Added OSSL_SERIALIZER, a generic serializer API. o Added error raising macros, ERR_raise() and ERR_raise_data(). o Deprecated ERR_put_error(). o Added OSSL_PROVIDER_available(), to check provider availibility. @@ -22,6 +25,11 @@ o Removed the heartbeat message in DTLS feature. o Added EVP_KDF, an EVP layer KDF API, and a generic EVP_PKEY to EVP_KDF bridge. + o All of the low level MD2, MD4, MD5, MDC2, RIPEMD160, SHA1, SHA224, + SHA256, SHA384, SHA512 and Whirlpool digest functions have been + deprecated. + o All of the low level AES, Blowfish, Camellia, CAST, DES, IDEA, RC2, + RC4, RC5 and SEED cipher functions have been deprecated. Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018] diff --git a/NOTES.ANDROID b/NOTES.ANDROID index 86459778..f19ec71b 100644 --- a/NOTES.ANDROID +++ b/NOTES.ANDROID @@ -15,22 +15,33 @@ Configuration ------------- - Android is naturally cross-compiled target and you can't use ./config. + Android is a naturally cross-compiled target and you can't use ./config. You have to use ./Configure and name your target explicitly; there are android-arm, android-arm64, android-mips, android-mip64, android-x86 - and android-x86_64. Do not pass --cross-compile-prefix (as you might - be tempted), as it will be "calculated" automatically based on chosen - platform. Though you still need to know the prefix to extend your PATH, - in order to invoke $(CROSS_COMPILE)gcc and company. (Configure will fail - and give you a hint if you get it wrong.) Apart from PATH adjustment - you need to set ANDROID_NDK_HOME environment to point at NDK directory - as /some/where/android-ndk-. Both variables are significant at both - configuration and compilation times. NDK customarily supports multiple - Android API levels, e.g. android-14, android-21, etc. By default latest - one available is chosen. If you need to target older platform, pass - additional -D__ANDROID_API__=N to Configure. N is numeric value of the - target platform version. For example, to compile for ICS on ARM with - NDK 10d: + and android-x86_64 (*MIPS targets are no longer supported with NDK R20+). + Do not pass --cross-compile-prefix (as you might be tempted), as it will + be "calculated" automatically based on chosen platform. Though you still + need to know the prefix to extend your PATH, in order to invoke + $(CROSS_COMPILE)clang [*gcc on NDK 19 and lower] and company. (Configure + will fail and give you a hint if you get it wrong.) Apart from PATH + adjustment you need to set ANDROID_NDK_HOME environment to point at the + NDK directory. If you're using a side-by-side NDK the path will look + something like /some/where/android-sdk/ndk/, and for a standalone + NDK the path will be something like /some/where/android-ndk-. + Both variables are significant at both configuration and compilation times. + The NDK customarily supports multiple Android API levels, e.g. android-14, + android-21, etc. By default latest API level is chosen. If you need to + target an older platform pass the argument -D__ANDROID_API__=N to Configure, + with N being the numerical value of the target platform version. For example, + to compile for Android 10 arm64 with a side-by-side NDK r20.0.5594570 + + export ANDROID_NDK_HOME=/home/whoever/Android/android-sdk/ndk/20.0.5594570 + PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH + ./Configure android-arm64 -D__ANDROID_API__=29 + make + + Older versions of the NDK have GCC under their common prebuilt tools directory, so the bin path + will be slightly different. EG: to compile for ICS on ARM with NDK 10d: export ANDROID_NDK_HOME=/some/where/android-ndk-10d PATH=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH diff --git a/README b/README index 35595664..5bd9e13f 100644 --- a/README +++ b/README @@ -1,6 +1,4 @@ - OpenSSL 3.0.0-dev - Copyright (c) 1998-2018 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson All rights reserved. diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..cba848ce --- /dev/null +++ b/VERSION @@ -0,0 +1,7 @@ +MAJOR=3 +MINOR=0 +PATCH=0 +PRE_RELEASE_TAG=dev +BUILD_METADATA= +RELEASE_DATE= +SHLIB_VERSION=3 diff --git a/apps/asn1pars.c b/apps/asn1pars.c index 14f1dcad..342e12d9 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c @@ -27,27 +27,32 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS asn1parse_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"oid", OPT_OID, '<', "file of extra oid definitions"}, + + OPT_SECTION("I/O"), {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"}, {"in", OPT_IN, '<', "input file"}, {"out", OPT_OUT, '>', "output file (output format is always DER)"}, - {"i", OPT_INDENT, 0, "indents the output"}, {"noout", OPT_NOOUT, 0, "do not produce any output"}, {"offset", OPT_OFFSET, 'p', "offset into file"}, {"length", OPT_LENGTH, 'p', "length of section in file"}, - {"oid", OPT_OID, '<', "file of extra oid definitions"}, - {"dump", OPT_DUMP, 0, "unknown data in hex form"}, - {"dlimit", OPT_DLIMIT, 'p', - "dump the first arg bytes of unknown data in hex form"}, {"strparse", OPT_STRPARSE, 'p', "offset; a series of these can be used to 'dig'"}, - {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"}, + {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, - {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, {"strictpem", OPT_STRICTPEM, 0, "do not attempt base64 decode outside PEM markers"}, {"item", OPT_ITEM, 's', "item to parse and print"}, + {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, + + OPT_SECTION("Formatting"), + {"i", OPT_INDENT, 0, "indents the output"}, + {"dump", OPT_DUMP, 0, "unknown data in hex form"}, + {"dlimit", OPT_DLIMIT, 'p', + "dump the first arg bytes of unknown data in hex form"}, {NULL} }; diff --git a/apps/ca.c b/apps/ca.c index b188b9b4..f201efe3 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -154,10 +154,32 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS ca_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [certreq...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"}, + {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, + {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"}, + {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, + {"out", OPT_OUT, '>', "Where to put the output file(s)"}, + {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, + {"batch", OPT_BATCH, '-', "Don't ask questions"}, + {"msie_hack", OPT_MSIE_HACK, '-', + "msie modifications to handle all Universal Strings"}, + {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, + {"spkac", OPT_SPKAC, '<', + "File contains DN and signed public key and challenge"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Configuration"), {"config", OPT_CONFIG, 's', "A config file"}, {"name", OPT_NAME, 's', "The particular CA definition to use"}, + {"policy", OPT_POLICY, 's', "The CA 'policy' to support"}, + + OPT_SECTION("Certificate"), {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"}, {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, {"create_serial", OPT_CREATE_SERIAL, '-', @@ -170,8 +192,21 @@ const OPTIONS ca_options[] = { {"enddate", OPT_ENDDATE, 's', "YYMMDDHHMMSSZ cert notAfter (overrides -days)"}, {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"}, + {"extensions", OPT_EXTENSIONS, 's', + "Extension section (override value in config file)"}, + {"extfile", OPT_EXTFILE, '<', + "Configuration file with X509v3 extensions to add"}, +#ifndef OPENSSL_NO_SM2 + {"sm2-id", OPT_SM2ID, 's', + "Specify an ID string to verify an SM2 certificate request"}, + {"sm2-hex-id", OPT_SM2HEXID, 's', + "Specify a hex ID string to verify an SM2 certificate request"}, +#endif + {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, + {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, + + OPT_SECTION("Signing"), {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"}, - {"policy", OPT_POLICY, 's', "The CA 'policy' to support"}, {"keyfile", OPT_KEYFILE, 's', "Private key"}, {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, @@ -179,31 +214,12 @@ const OPTIONS ca_options[] = { {"cert", OPT_CERT, '<', "The CA cert"}, {"selfsign", OPT_SELFSIGN, '-', "Sign a cert with the key associated with it"}, - {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"}, - {"out", OPT_OUT, '>', "Where to put the output file(s)"}, - {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, - {"batch", OPT_BATCH, '-', "Don't ask questions"}, - {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, - {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, + + OPT_SECTION("Revocation"), {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"}, - {"msie_hack", OPT_MSIE_HACK, '-', - "msie modifications to handle all those universal strings"}, - {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, - {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, - {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, - {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, - {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, - {"spkac", OPT_SPKAC, '<', - "File contains DN and signed public key and challenge"}, - {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, {"valid", OPT_VALID, 's', "Add a Valid(not-revoked) DB entry about a cert (given in file)"}, - {"extensions", OPT_EXTENSIONS, 's', - "Extension section (override value in config file)"}, - {"extfile", OPT_EXTFILE, '<', - "Configuration file with X509v3 extensions to add"}, {"status", OPT_STATUS, 's', "Shows cert status given the serial number"}, {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"}, {"crlexts", OPT_CRLEXTS, 's', @@ -215,16 +231,15 @@ const OPTIONS ca_options[] = { "sets compromise time to val and the revocation reason to keyCompromise"}, {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's', "sets compromise time to val and the revocation reason to CACompromise"}, + {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, + {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, + {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, + {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif -#ifndef OPENSSL_NO_SM2 - {"sm2-id", OPT_SM2ID, 's', - "Specify an ID string to verify an SM2 certificate request"}, - {"sm2-hex-id", OPT_SM2HEXID, 's', - "Specify a hex ID string to verify an SM2 certificate request"}, -#endif + + OPT_PARAMETERS(), + {"certreq", 0, 0, "Certificate requests to be signed (optional)"}, {NULL} }; diff --git a/apps/ciphers.c b/apps/ciphers.c index e51fac11..280a5ab4 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -31,35 +31,45 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS ciphers_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cipher]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, {"V", OPT_UPPER_V, '-', "Even more verbose"}, + {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, + {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, + + OPT_SECTION("Cipher specification"), {"s", OPT_S, '-', "Only supported ciphers"}, #ifndef OPENSSL_NO_SSL3 - {"ssl3", OPT_SSL3, '-', "SSL3 mode"}, + {"ssl3", OPT_SSL3, '-', "Ciphers compatible with SSL3"}, #endif #ifndef OPENSSL_NO_TLS1 - {"tls1", OPT_TLS1, '-', "TLS1 mode"}, + {"tls1", OPT_TLS1, '-', "Ciphers compatible with TLS1"}, #endif #ifndef OPENSSL_NO_TLS1_1 - {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"}, + {"tls1_1", OPT_TLS1_1, '-', "Ciphers compatible with TLS1.1"}, #endif #ifndef OPENSSL_NO_TLS1_2 - {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"}, + {"tls1_2", OPT_TLS1_2, '-', "Ciphers compatible with TLS1.2"}, #endif #ifndef OPENSSL_NO_TLS1_3 - {"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"}, + {"tls1_3", OPT_TLS1_3, '-', "Ciphers compatible with TLS1.3"}, #endif - {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, #ifndef OPENSSL_NO_PSK - {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"}, + {"psk", OPT_PSK, '-', "Include ciphersuites requiring PSK"}, #endif #ifndef OPENSSL_NO_SRP - {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"}, + {"srp", OPT_SRP, '-', "Include ciphersuites requiring SRP"}, #endif - {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, {"ciphersuites", OPT_CIPHERSUITES, 's', "Configure the TLSv1.3 ciphersuites to use"}, + + OPT_PARAMETERS(), + {"cipher", 0, 0, "Cipher string to decode (optional)"}, {NULL} }; diff --git a/apps/cms.c b/apps/cms.c index 0e0df5e0..d67116d3 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -75,7 +75,8 @@ typedef enum OPTION_choice { OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF, OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT, OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE, - OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT, + OPT_CAPATH, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, + OPT_CONTENT, OPT_PRINT, OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM, @@ -87,16 +88,36 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS cms_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', - " cert.pem... recipient certs for encryption\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, {"outform", OPT_OUTFORM, 'c', "Output format SMIME (default), PEM or DER"}, {"in", OPT_IN, '<', "Input file"}, {"out", OPT_OUT, '>', "Output file"}, + {"debug_decrypt", OPT_DEBUG_DECRYPT, '-', + "Disable MMA protection and return an error if no recipient found" + " (see documentation)"}, + {"stream", OPT_INDEF, '-', "Enable CMS streaming"}, + {"indef", OPT_INDEF, '-', "Same as -stream"}, + {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, + {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only" }, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CApath", OPT_CAPATH, '/', "trusted certificates directory"}, + {"CAstore", OPT_CASTORE, ':', "trusted certificates store URI"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +# endif + + OPT_SECTION("Action"), {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, {"sign", OPT_SIGN, '-', "Sign message"}, @@ -108,45 +129,42 @@ const OPTIONS cms_options[] = { "Exit non-zero on verification failure"}, {"verify_receipt", OPT_VERIFY_RECEIPT, '<', "Verify receipts; exit if receipt signatures do not verify"}, - {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"}, - {"data_out", OPT_DATA_OUT, '-', "Copy CMS \"Data\" object to output"}, - {"data_create", OPT_DATA_CREATE, '-', "Create a CMS \"Data\" object"}, {"digest_verify", OPT_DIGEST_VERIFY, '-', "Verify a CMS \"DigestedData\" object and output it"}, {"digest_create", OPT_DIGEST_CREATE, '-', "Create a CMS \"DigestedData\" object"}, {"compress", OPT_COMPRESS, '-', "Create a CMS \"CompressedData\" object"}, - {"uncompress", OPT_UNCOMPRESS, '-', "Uncompress a CMS \"CompressedData\" object"}, + {"uncompress", OPT_UNCOMPRESS, '-', + "Uncompress a CMS \"CompressedData\" object"}, {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-', "Decrypt CMS \"EncryptedData\" object using symmetric key"}, {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-', "Create CMS \"EncryptedData\" object using symmetric key"}, - {"debug_decrypt", OPT_DEBUG_DECRYPT, '-', - "Disable MMA protection and return an error if no recipient found" - " (see documentation)"}, - {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, - {"asciicrlf", OPT_ASCIICRLF, '-', - "Perform CRLF canonicalisation when signing"}, - {"nointern", OPT_NOINTERN, '-', - "Don't search certificates in message for signer"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, - {"nocerts", OPT_NOCERTS, '-', - "Don't include signers certificate when signing"}, - {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, - {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, - {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, - {"binary", OPT_BINARY, '-', "Don't translate message to text"}, - {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, - {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"data_out", OPT_DATA_OUT, '-', "Copy CMS \"Data\" object to output"}, + {"data_create", OPT_DATA_CREATE, '-', "Create a CMS \"Data\" object"}, + {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"}, {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-', "Do not verify signed content signatures"}, {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-', "Do not verify signed attribute signatures"}, - {"stream", OPT_INDEF, '-', "Enable CMS streaming"}, - {"indef", OPT_INDEF, '-', "Same as -stream"}, - {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, - {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only" }, - {"noout", OPT_NOOUT, '-', "For the -cmsout operation do not output the parsed CMS structure"}, + {"nointern", OPT_NOINTERN, '-', + "Don't search certificates in message for signer"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + + OPT_SECTION("Formatting"), + {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"asciicrlf", OPT_ASCIICRLF, '-', + "Perform CRLF canonicalisation when signing"}, + {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, + {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, + {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, + {"binary", OPT_BINARY, '-', "Don't translate message to text"}, + {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signers certificate when signing"}, + {"noout", OPT_NOOUT, '-', + "For the -cmsout operation do not output the parsed CMS structure"}, {"receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" }, {"receipt_request_all", OPT_RR_ALL, '-', "When signing, create a receipt request for all recipients"}, @@ -154,51 +172,54 @@ const OPTIONS cms_options[] = { "When signing, create a receipt request for first recipient"}, {"rctform", OPT_RCTFORM, 'F', "Receipt file format"}, {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, - {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, - {"CApath", OPT_CAPATH, '/', "trusted certificates directory"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, {"content", OPT_CONTENT, '<', "Supply or override content for detached signature"}, {"print", OPT_PRINT, '-', "For the -cmsout operation print out all fields of the CMS structure"}, + {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, + + OPT_SECTION("Keying"), {"secretkey", OPT_SECRETKEY, 's', "Use specified hex-encoded key to decrypt/encrypt recipients or content"}, {"secretkeyid", OPT_SECRETKEYID, 's', "Identity of the -secretkey for CMS \"KEKRecipientInfo\" object"}, {"pwri_password", OPT_PWRI_PASSWORD, 's', "Specific password for recipient"}, - {"econtent_type", OPT_ECONTENT_TYPE, 's', "OID for external content"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"inkey", OPT_INKEY, 's', + "Input private key (if not signer or recipient)"}, + {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, + {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, + + OPT_SECTION("Mail header"), + {"econtent_type", OPT_ECONTENT_TYPE, 's', "OID for external content"}, {"to", OPT_TO, 's', "To address"}, {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, {"signer", OPT_SIGNER, 's', "Signer certificate file"}, {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, - {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, - {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, - {"inkey", OPT_INKEY, 's', - "Input private key (if not signer or recipient)"}, - {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, - {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, {"receipt_request_from", OPT_RR_FROM, 's', "Create signed receipt request with specified email address"}, {"receipt_request_to", OPT_RR_TO, 's', "Create signed receipt targeted to specified address"}, + + OPT_SECTION("Encryption"), + {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, - OPT_R_OPTIONS, - OPT_V_OPTIONS, + + OPT_SECTION("Key-wrapping"), {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, # ifndef OPENSSL_NO_DES {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, # endif -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -# endif + + OPT_R_OPTIONS, + OPT_V_OPTIONS, + + OPT_PARAMETERS(), + {"cert", 0, 0, "Recipient certs (optional; used only when encrypting)"}, {NULL} }; @@ -219,9 +240,9 @@ int cms_main(int argc, char **argv) X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; - const char *CAfile = NULL, *CApath = NULL; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; char *certsoutfile = NULL; - int noCAfile = 0, noCApath = 0; + int noCAfile = 0, noCApath = 0, noCAstore = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL; char *to = NULL, *from = NULL, *subject = NULL, *prog; @@ -401,12 +422,18 @@ int cms_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_IN: infile = opt_arg(); break; @@ -825,7 +852,8 @@ int cms_main(int argc, char **argv) goto end; if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpmtouched) diff --git a/apps/crl.c b/apps/crl.c index d36b93ba..14410f35 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -22,19 +22,34 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY, OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT, - OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, - OPT_NOCAPATH, OPT_NOCAFILE, OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD, - OPT_NOOUT, OPT_NAMEOPT, OPT_MD + OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_VERIFY, OPT_TEXT, OPT_HASH, + OPT_HASH_OLD, OPT_NOOUT, OPT_NAMEOPT, OPT_MD } OPTION_CHOICE; const OPTIONS crl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format; default PEM"}, + {"verify", OPT_VERIFY, '-', "Verify CRL signature"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file - default stdin"}, - {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, - {"out", OPT_OUT, '>', "output file - default stdout"}, - {"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"}, + {"inform", OPT_INFORM, 'F', "Input format; default PEM"}, {"key", OPT_KEY, '<', "CRL signing Private key to use"}, + {"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "output file - default stdout"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"text", OPT_TEXT, '-', "Print out a text format version"}, + {"hash", OPT_HASH, '-', "Print hash value"}, +#ifndef OPENSSL_NO_MD5 + {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, +#endif + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"", OPT_MD, '-', "Any supported digest"}, + + OPT_SECTION("CRL"), {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, {"lastupdate", OPT_LASTUPDATE, '-', "Set lastUpdate field"}, {"nextupdate", OPT_NEXTUPDATE, '-', "Set nextUpdate field"}, @@ -43,20 +58,17 @@ const OPTIONS crl_options[] = { {"crlnumber", OPT_CRLNUMBER, '-', "Print CRL number"}, {"badsig", OPT_BADSIG, '-', "Corrupt last byte of loaded CRL signature (for test)" }, {"gendelta", OPT_GENDELTA, '<', "Other CRL to compare/diff to the Input one"}, + + OPT_SECTION("Certificate"), {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"}, {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"}, + {"CAstore", OPT_CASTORE, ':', "Verify CRL using certificates in store URI"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"verify", OPT_VERIFY, '-', "Verify CRL signature"}, - {"text", OPT_TEXT, '-', "Print out a text format version"}, - {"hash", OPT_HASH, '-', "Print hash value"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_MD5 - {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, -#endif + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, {NULL} }; @@ -71,12 +83,12 @@ int crl_main(int argc, char **argv) EVP_PKEY *pkey; const EVP_MD *digest = EVP_sha1(); char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; - const char *CAfile = NULL, *CApath = NULL, *prog; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog; OPTION_CHOICE o; int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0; - int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0; + int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0, noCAstore = 0; int i; #ifndef OPENSSL_NO_MD5 int hash_old = 0; @@ -126,12 +138,19 @@ int crl_main(int argc, char **argv) CAfile = opt_arg(); do_ver = 1; break; + case OPT_CASTORE: + CAstore = opt_arg(); + do_ver = 1; + break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_HASH_OLD: #ifndef OPENSSL_NO_MD5 hash_old = ++num; @@ -185,7 +204,8 @@ int crl_main(int argc, char **argv) goto end; if (do_ver) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) diff --git a/apps/crl2p7.c b/apps/crl2p7.c index 6f284cb1..ffbee4cb 100644 --- a/apps/crl2p7.c +++ b/apps/crl2p7.c @@ -27,14 +27,19 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS crl2pkcs7_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, {"nocrl", OPT_NOCRL, '-', "No crl to load, just certs from '-certfile'"}, {"certfile", OPT_CERTFILE, '<', "File of chain of certs to a trusted CA; can be repeated"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {NULL} }; diff --git a/apps/dgst.c b/apps/dgst.c index b44468bc..21f0f017 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 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 @@ -19,6 +19,7 @@ #include #include #include +#include #undef BUFSIZE #define BUFSIZE 1024*8 @@ -27,9 +28,15 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file); +static void show_digests(const OBJ_NAME *name, void *bio_); + +struct doall_dgst_digests { + BIO *bio; + int n; +}; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_LIST, OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, @@ -40,37 +47,44 @@ typedef enum OPTION_choice { const OPTIONS dgst_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, - {OPT_HELP_STR, 1, '-', - " file... files to digest (default is stdin)\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"c", OPT_C, '-', "Print the digest with separating colons"}, - {"r", OPT_R, '-', "Print the digest in coreutils format"}, - {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"sign", OPT_SIGN, 's', "Sign digest using private key"}, - {"verify", OPT_VERIFY, 's', - "Verify a signature using public key"}, - {"prverify", OPT_PRVERIFY, 's', - "Verify a signature using private key"}, - {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, - {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, - {"hex", OPT_HEX, '-', "Print as hex dump"}, - {"binary", OPT_BINARY, '-', "Print in binary form"}, - {"d", OPT_DEBUG, '-', "Print debug info"}, - {"debug", OPT_DEBUG, '-', "Print debug info"}, - {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', - "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, - {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, - {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, - {"", OPT_DIGEST, '-', "Any supported digest"}, - OPT_R_OPTIONS, + {"list", OPT_LIST, '-', "List digests"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, {"engine_impl", OPT_ENGINE_IMPL, '-', "Also use engine given by -engine for digest operations"}, #endif + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"c", OPT_C, '-', "Print the digest with separating colons"}, + {"r", OPT_R, '-', "Print the digest in coreutils format"}, + {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, + {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, + {"hex", OPT_HEX, '-', "Print as hex dump"}, + {"binary", OPT_BINARY, '-', "Print in binary form"}, + {"d", OPT_DEBUG, '-', "Print debug info"}, + {"debug", OPT_DEBUG, '-', "Print debug info"}, + + OPT_SECTION("Signing"), + {"sign", OPT_SIGN, 's', "Sign digest using private key"}, + {"verify", OPT_VERIFY, 's', "Verify a signature using public key"}, + {"prverify", OPT_PRVERIFY, 's', "Verify a signature using private key"}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, + {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, + {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, + {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, + {"", OPT_DIGEST, '-', "Any supported digest"}, + {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', + "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"file", 0, 0, "Files to digest (optional; default is stdin)"}, {NULL} }; @@ -92,6 +106,7 @@ int dgst_main(int argc, char **argv) int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; + struct doall_dgst_digests dec; prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); @@ -109,6 +124,15 @@ int dgst_main(int argc, char **argv) opt_help(dgst_options); ret = 0; goto end; + case OPT_LIST: + BIO_printf(bio_out, "Supported digests:\n"); + dec.bio = bio_out; + dec.n = 0; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, + show_digests, &dec); + BIO_printf(bio_out, "\n"); + ret = 0; + goto end; case OPT_C: separator = 1; break; @@ -414,6 +438,32 @@ int dgst_main(int argc, char **argv) return ret; } +static void show_digests(const OBJ_NAME *name, void *arg) +{ + struct doall_dgst_digests *dec = (struct doall_dgst_digests *)arg; + const EVP_MD *md = NULL; + + /* Filter out signed digests (a.k.a signature algorithms) */ + if (strstr(name->name, "rsa") != NULL || strstr(name->name, "RSA") != NULL) + return; + + if (!islower((unsigned char)*name->name)) + return; + + /* Filter out message digests that we cannot use */ + md = EVP_get_digestbyname(name->name); + if (md == NULL) + return; + + BIO_printf(dec->bio, "-%-25s", name->name); + if (++dec->n == 3) { + BIO_printf(dec->bio, "\n"); + dec->n = 0; + } else { + BIO_printf(dec->bio, " "); + } +} + /* * The newline_escape_filename function performs newline escaping for any * filename that contains a newline. This function also takes a pointer @@ -458,15 +508,16 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, const char *sig_name, const char *md_name, const char *file) { - size_t len; - int i, backslash = 0; + size_t len = BUFSIZE; + int i, backslash = 0, ret = 1; + unsigned char *sigbuf = NULL; while (BIO_pending(bp) || !BIO_eof(bp)) { i = BIO_read(bp, (char *)buf, BUFSIZE); if (i < 0) { BIO_printf(bio_err, "Read Error in %s\n", file); ERR_print_errors(bio_err); - return 1; + goto end; } if (i == 0) break; @@ -479,28 +530,35 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, BIO_printf(out, "Verified OK\n"); } else if (i == 0) { BIO_printf(out, "Verification Failure\n"); - return 1; + goto end; } else { BIO_printf(bio_err, "Error Verifying Data\n"); ERR_print_errors(bio_err); - return 1; + goto end; } - return 0; + ret = 0; + goto end; } if (key != NULL) { EVP_MD_CTX *ctx; + int pkey_len; BIO_get_md_ctx(bp, &ctx); - len = BUFSIZE; + pkey_len = EVP_PKEY_size(key); + if (pkey_len > BUFSIZE) { + len = pkey_len; + sigbuf = app_malloc(len, "Signature buffer"); + buf = sigbuf; + } if (!EVP_DigestSignFinal(ctx, buf, &len)) { BIO_printf(bio_err, "Error Signing Data\n"); ERR_print_errors(bio_err); - return 1; + goto end; } } else { len = BIO_gets(bp, (char *)buf, BUFSIZE); if ((int)len < 0) { ERR_print_errors(bio_err); - return 1; + goto end; } } @@ -535,5 +593,11 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, } BIO_printf(out, "\n"); } - return 0; + + ret = 0; + end: + if (sigbuf != NULL) + OPENSSL_clear_free(sigbuf, len); + + return ret; } diff --git a/apps/dhparam.c b/apps/dhparam.c index 7cd69b92..7a61241f 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -42,21 +42,11 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS dhparam_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, - {"out", OPT_OUT, '>', "Output file"}, {"check", OPT_CHECK, '-', "Check the DH parameters"}, - {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, - {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, - OPT_R_OPTIONS, - {"C", OPT_C, '-', "Print C code"}, - {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, - {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"}, - {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, # ifndef OPENSSL_NO_DSA {"dsaparam", OPT_DSAPARAM, '-', "Read or generate DSA parameters, convert to DH"}, @@ -64,6 +54,25 @@ const OPTIONS dhparam_options[] = { # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, + {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, + {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, + {"C", OPT_C, '-', "Print C code"}, + {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, + {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"}, + {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Number of bits if generating parameters (optional)"}, {NULL} }; diff --git a/apps/dsa.c b/apps/dsa.c index 629ba1d9..f0c9fc1c 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -36,18 +36,8 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS dsa_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"}, - {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"}, - {"in", OPT_IN, 's', "Input key"}, - {"out", OPT_OUT, '>', "Output file"}, - {"noout", OPT_NOOUT, '-', "Don't print key out"}, - {"text", OPT_TEXT, '-', "Print the key in text"}, - {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, - {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, - {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, # ifndef OPENSSL_NO_RC4 {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, @@ -57,6 +47,22 @@ const OPTIONS dsa_options[] = { # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input key"}, + {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"}, + {"noout", OPT_NOOUT, '-', "Don't print key out"}, + {"text", OPT_TEXT, '-', "Print the key in text"}, + {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, + {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {NULL} }; diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 959c3312..17068fb9 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -37,20 +37,31 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS dsaparam_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, - {"in", OPT_IN, '<', "Input file"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, - {"out", OPT_OUT, '>', "Output file"}, - {"text", OPT_TEXT, '-', "Print as text"}, - {"C", OPT_C, '-', "Output C code"}, - {"noout", OPT_NOOUT, '-', "No output"}, - {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, - OPT_R_OPTIONS, # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"text", OPT_TEXT, '-', "Print as text"}, + {"C", OPT_C, '-', "Output C code"}, + {"noout", OPT_NOOUT, '-', "No output"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Number of bits if generating parameters (optional)"}, {NULL} }; diff --git a/apps/ec.c b/apps/ec.c index c09d29d3..3d901bba 100644 --- a/apps/ec.c +++ b/apps/ec.c @@ -44,27 +44,32 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS ec_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("Input"), {"in", OPT_IN, 's', "Input file"}, {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"check", OPT_CHECK, '-', "check key consistency"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output file"}, {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key"}, {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"}, - {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"}, - {"check", OPT_CHECK, '-', "check key consistency"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"param_enc", OPT_PARAM_ENC, 's', - "Specifies the way the ec parameters are encoded"}, - {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif {NULL} }; diff --git a/apps/ecparam.c b/apps/ecparam.c index 6796af65..307eb1f3 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -35,31 +35,38 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS ecparam_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, - {"in", OPT_IN, '<', "Input file - default stdin"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"text", OPT_TEXT, '-', "Print the ec parameters in text form"}, - {"C", OPT_C, '-', "Print a 'C' function creating the parameters"}, - {"check", OPT_CHECK, '-', "Validate the ec parameters"}, - {"check_named", OPT_CHECK_NAMED, '-', - "Check that named EC curve parameters have not been modified"}, {"list_curves", OPT_LIST_CURVES, '-', "Prints a list of all curve 'short names'"}, - {"no_seed", OPT_NO_SEED, '-', - "If 'explicit' parameters are chosen do not use the seed"}, - {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, - {"name", OPT_NAME, 's', - "Use the ec parameters with specified 'short name'"}, - {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, - {"param_enc", OPT_PARAM_ENC, 's', - "Specifies the way the ec parameters are encoded"}, - {"genkey", OPT_GENKEY, '-', "Generate ec key"}, - OPT_R_OPTIONS, # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif + + {"genkey", OPT_GENKEY, '-', "Generate ec key"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + + OPT_SECTION("Output"), + {"text", OPT_TEXT, '-', "Print the ec parameters in text form"}, + {"C", OPT_C, '-', "Print a 'C' function creating the parameters"}, + {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + + OPT_SECTION("Parameter"), + {"check", OPT_CHECK, '-', "Validate the ec parameters"}, + {"check_named", OPT_CHECK_NAMED, '-', + "Check that named EC curve parameters have not been modified"}, + {"no_seed", OPT_NO_SEED, '-', + "If 'explicit' parameters are chosen do not use the seed"}, + {"name", OPT_NAME, 's', + "Use the ec parameters with specified 'short name'"}, + {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, + + OPT_R_OPTIONS, {NULL} }; diff --git a/apps/enc.c b/apps/enc.c index d2505639..2b23564f 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 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 @@ -49,27 +49,41 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS enc_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"ciphers", OPT_LIST, '-', "List ciphers"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"pass", OPT_PASS, 's', "Passphrase source"}, + {"list", OPT_LIST, '-', "List ciphers"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"ciphers", OPT_LIST, '-', "Alias for -list"}, +#endif {"e", OPT_E, '-', "Encrypt"}, {"d", OPT_D, '-', "Decrypt"}, {"p", OPT_P, '-', "Print the iv/key"}, {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"k", OPT_K, 's', "Passphrase"}, + {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"pass", OPT_PASS, 's', "Passphrase source"}, {"v", OPT_V, '-', "Verbose output"}, - {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, - {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"}, - {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"}, - {"debug", OPT_DEBUG, '-', "Print debug info"}, {"a", OPT_A, '-', "Base64 encode/decode, depending on encryption flag"}, {"base64", OPT_A, '-', "Same as option -a"}, {"A", OPT_UPPER_A, '-', "Used with -[base64|a] to specify base64 buffer as a single line"}, + + OPT_SECTION("Encryption"), + {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, + {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"}, + {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"}, + {"debug", OPT_DEBUG, '-', "Print debug info"}, + {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, - {"k", OPT_K, 's', "Passphrase"}, - {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, {"K", OPT_UPPER_K, 's', "Raw key, in hex"}, {"S", OPT_UPPER_S, 's', "Salt, in hex"}, {"iv", OPT_IV, 's', "IV in hex"}, @@ -77,14 +91,12 @@ const OPTIONS enc_options[] = { {"iter", OPT_ITER, 'p', "Specify the iteration count and force use of PBKDF2"}, {"pbkdf2", OPT_PBKDF2, '-', "Use password-based key derivation function 2"}, {"none", OPT_NONE, '-', "Don't encrypt"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, - OPT_R_OPTIONS, #ifdef ZLIB {"z", OPT_Z, '-', "Use zlib as the 'encryption'"}, #endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + {"", OPT_CIPHER, '-', "Any supported cipher"}, + + OPT_R_OPTIONS, {NULL} }; diff --git a/apps/engine.c b/apps/engine.c index 8444fe2d..a71e1110 100644 --- a/apps/engine.c +++ b/apps/engine.c @@ -30,20 +30,25 @@ typedef enum OPTION_choice { const OPTIONS engine_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"}, - {OPT_HELP_STR, 1, '-', - " engine... Engines to load\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"t", OPT_T, '-', "Check that specified engine is available"}, + {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, + {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, + + OPT_SECTION("Output"), {"v", OPT_V, '-', "List 'control commands' For each specified engine"}, {"vv", OPT_VV, '-', "Also display each command's description"}, {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, {"c", OPT_C, '-', "List the capabilities of specified engine"}, - {"t", OPT_T, '-', "Check that specified engine is available"}, {"tt", OPT_TT, '-', "Display error trace for unavailable engines"}, - {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, - {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, {OPT_MORE_STR, OPT_EOF, 1, "Commands are like \"SO_PATH:/lib/libdriver.so\""}, + + OPT_PARAMETERS(), + {"engine", 0, 0, "ID of engine(s) to load"}, {NULL} }; diff --git a/apps/errstr.c b/apps/errstr.c index df0253c4..9e97698b 100644 --- a/apps/errstr.c +++ b/apps/errstr.c @@ -22,8 +22,12 @@ typedef enum OPTION_choice { const OPTIONS errstr_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"}, - {OPT_HELP_STR, 1, '-', " errnum Error number\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_PARAMETERS(), + {"errnum", 0, 0, "Error number(s) to decode"}, {NULL} }; diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index fd28b484..564b2082 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "apps.h" #include "progs.h" @@ -25,28 +27,39 @@ #define VERSION_VAL "1" #define INSTALL_STATUS_VAL "INSTALL_SELF_TEST_KATS_RUN" +static OSSL_CALLBACK self_test_events; +static char *self_test_corrupt_desc = NULL; +static char *self_test_corrupt_type = NULL; +static int self_test_log = 1; + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_IN, OPT_OUT, OPT_MODULE, - OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY + OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY, + OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE } OPTION_CHOICE; const OPTIONS fipsinstall_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {OPT_MORE_STR, 0, 0, "e.g: openssl fipsinstall -provider_name fips" - "-section_name fipsinstall -out fips.conf -module ./fips.so" - "-mac_name HMAC -macopt digest:SHA256 -macopt hexkey:00"}, - {"verify", OPT_VERIFY, '-', "Verification mode, i.e verify a config file " - "instead of generating one"}, - {"in", OPT_IN, '<', "Input config file, used when verifying"}, - {"out", OPT_OUT, '>', "Output config file, used when generating"}, + {"verify", OPT_VERIFY, '-', + "Verify a config file instead of generating one"}, {"module", OPT_MODULE, '<', "File name of the provider module"}, {"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"}, {"section_name", OPT_SECTION_NAME, 's', "FIPS Provider config section name (optional)"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input config file, used when verifying"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output config file, used when generating"}, {"mac_name", OPT_MAC_NAME, 's', "MAC name"}, {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form. " "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, + {"noout", OPT_NO_LOG, '-', "Disable logging of self test events"}, + {"corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description"}, + {"corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type"}, {NULL} }; @@ -168,7 +181,7 @@ static CONF *generate_config_and_load(const char *prov_name, if (conf == NULL) goto end; - if (!CONF_modules_load(conf, NULL, 0)) + if (CONF_modules_load(conf, NULL, 0) <= 0) goto end; BIO_free(mem_bio); return conf; @@ -285,6 +298,15 @@ opthelp: case OPT_OUT: out_fname = opt_arg(); break; + case OPT_NO_LOG: + self_test_log = 0; + break; + case OPT_CORRUPT_DESC: + self_test_corrupt_desc = opt_arg(); + break; + case OPT_CORRUPT_TYPE: + self_test_corrupt_type = opt_arg(); + break; case OPT_PROV_NAME: prov_name = opt_arg(); break; @@ -316,6 +338,11 @@ opthelp: || argc != 0) goto opthelp; + if (self_test_log + || self_test_corrupt_desc != NULL + || self_test_corrupt_type != NULL) + OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL); + module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY); if (module_bio == NULL) { BIO_printf(bio_err, "Failed to open module file\n"); @@ -418,3 +445,53 @@ end: free_config_and_unload(conf); return ret; } + +static int self_test_events(const OSSL_PARAM params[], void *arg) +{ + const OSSL_PARAM *p = NULL; + const char *phase = NULL, *type = NULL, *desc = NULL; + int ret = 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; + phase = (const char *)p->data; + + p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + desc = (const char *)p->data; + + p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + type = (const char *)p->data; + + if (self_test_log) { + if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0) + BIO_printf(bio_out, "%s : (%s) : ", desc, type); + else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0 + || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0) + BIO_printf(bio_out, "%s\n", phase); + } + /* + * The self test code will internally corrupt the KAT test result if an + * error is returned during the corrupt phase. + */ + if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0 + && (self_test_corrupt_desc != NULL + || self_test_corrupt_type != NULL)) { + if (self_test_corrupt_desc != NULL + && strcmp(self_test_corrupt_desc, desc) != 0) + goto end; + if (self_test_corrupt_type != NULL + && strcmp(self_test_corrupt_type, type) != 0) + goto end; + BIO_printf(bio_out, "%s ", phase); + goto err; + } +end: + ret = 1; +err: + return ret; +} diff --git a/apps/gendsa.c b/apps/gendsa.c index 9671b234..12806ef2 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -32,17 +32,23 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS gendsa_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] dsaparam-file\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output the key to the specified file"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, OPT_R_OPTIONS, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + + OPT_PARAMETERS(), + {"dsaparam-file", 0, 0, "File containing DSA parameters"}, {NULL} }; diff --git a/apps/genpkey.c b/apps/genpkey.c index afae4b65..3ae508c1 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -28,20 +28,24 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS genpkey_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file"}, - {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, - {"pass", OPT_PASS, 's', "Output file pass phrase source"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif {"paramfile", OPT_PARAMFILE, '<', "Parameters file"}, {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, {"pkeyopt", OPT_PKEYOPT, 's', "Set the public key algorithm option as opt:value"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, + {"pass", OPT_PASS, 's', "Output file pass phrase source"}, {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, {"text", OPT_TEXT, '-', "Print the in text"}, {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + /* This is deliberately last. */ {OPT_HELP_STR, 1, 1, "Order of options may be important! See the documentation.\n"}, diff --git a/apps/genrsa.c b/apps/genrsa.c index ebf9c553..96fb23aa 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -42,19 +42,30 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS genrsa_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] numbits\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"3", OPT_3, '-', "Use 3 for the E value"}, - {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, - {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, - {"out", OPT_OUT, '>', "Output the key to specified file"}, - OPT_R_OPTIONS, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif + + OPT_SECTION("Input"), + {"3", OPT_3, '-', "Use 3 for the E value"}, + {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, + {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output the key to specified file"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Size of key in bits"}, {NULL} }; diff --git a/apps/include/apps.h b/apps/include/apps.h index 41db8074..c33a9877 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -58,20 +58,6 @@ extern const unsigned char tls13_aes128gcmsha256_id[]; extern const unsigned char tls13_aes256gcmsha384_id[]; extern BIO_ADDR *ourpeer; -BIO_METHOD *apps_bf_prefix(void); -/* - * The control used to set the prefix with BIO_ctrl() - * We make it high enough so the chance of ever clashing with the BIO library - * remains unlikely for the foreseeable future and beyond. - */ -#define PREFIX_CTRL_SET_PREFIX (1 << 15) -/* - * apps_bf_prefix() returns a dynamically created BIO_METHOD, which we - * need to destroy at some point. When created internally, it's stored - * in an internal pointer which can be freed with the following function - */ -void destroy_prefix_method(void); - BIO *dup_bio_in(int format); BIO *dup_bio_out(int format); BIO *dup_bio_err(int format); @@ -126,11 +112,13 @@ int load_certs(const char *file, STACK_OF(X509) **certs, int format, const char *pass, const char *cert_descrip); int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, const char *pass, const char *cert_descrip); -X509_STORE *setup_verify(const char *CAfile, const char *CApath, - int noCAfile, int noCApath); -__owur int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath, int noCAfile, - int noCApath); +X509_STORE *setup_verify(const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore); +__owur int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore); #ifndef OPENSSL_NO_CT diff --git a/apps/include/opt.h b/apps/include/opt.h index 54935630..ac2c2360 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -32,6 +32,7 @@ OPT_V__LAST # define OPT_V_OPTIONS \ + OPT_SECTION("Validation"), \ { "policy", OPT_V_POLICY, 's', "adds policy to the acceptable policy set"}, \ { "purpose", OPT_V_PURPOSE, 's', \ "certificate chain purpose"}, \ @@ -124,6 +125,7 @@ OPT_X__LAST # define OPT_X_OPTIONS \ + OPT_SECTION("Extended certificate"), \ { "xkey", OPT_X_KEY, '<', "key for Extended certificates"}, \ { "xcert", OPT_X_CERT, '<', "cert for Extended certificates"}, \ { "xchain", OPT_X_CHAIN, '<', "chain for Extended certificates"}, \ @@ -161,6 +163,7 @@ OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S__LAST # define OPT_S_OPTIONS \ + OPT_SECTION("TLS/SSL"), \ {"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \ {"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \ {"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \ @@ -254,6 +257,7 @@ OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST # define OPT_R_OPTIONS \ + OPT_SECTION("Random state"), \ {"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \ {"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"} @@ -267,6 +271,8 @@ extern const char OPT_HELP_STR[]; extern const char OPT_MORE_STR[]; extern const char OPT_SECTION_STR[]; +extern const char OPT_PARAM_STR[]; + typedef struct options_st { const char *name; int retval; @@ -309,7 +315,8 @@ typedef struct string_int_pair_st { OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) /* Divide options into sections when displaying usage */ -#define OPT_SECTION(sec) {OPT_SECTION_STR, 1, '-', sec " options:\n"} +#define OPT_SECTION(sec) { OPT_SECTION_STR, 1, '-', sec " options:\n" } +#define OPT_PARAMETERS() { OPT_PARAM_STR, 1, '-', "Parameters:\n" } char *opt_progname(const char *argv0); char *opt_getprog(void); @@ -342,7 +349,7 @@ int opt_num_rest(void); int opt_verify(int i, X509_VERIFY_PARAM *vpm); int opt_rand(int i); void opt_help(const OPTIONS * list); -void opt_print(const OPTIONS * opt, int width); +void opt_print(const OPTIONS * opt, int doingparams, int width); int opt_format_error(const char *s, unsigned long flags); int opt_isdir(const char *name); int opt_printf_stderr(const char *fmt, ...); diff --git a/apps/include/s_apps.h b/apps/include/s_apps.h index 4f976da0..1bbe5fe0 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -69,8 +69,9 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx); int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download); int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, - const char *vfyCAfile, const char *chCApath, - const char *chCAfile, STACK_OF(X509_CRL) *crls, + const char *vfyCAfile, const char *vfyCAstore, + const char *chCApath, const char *chCAfile, + const char *chCAstore, STACK_OF(X509_CRL) *crls, int crl_download); void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose); int set_keylog_file(SSL_CTX *ctx, const char *keylog_file); diff --git a/apps/info.c b/apps/info.c index 58691729..ae6e34c9 100644 --- a/apps/info.c +++ b/apps/info.c @@ -18,7 +18,11 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS info_options[] = { + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"configdir", OPT_CONFIGDIR, '-', "Default configuration file directory"}, {"enginesdir", OPT_ENGINESDIR, '-', "Default engine module directory"}, {"modulesdir", OPT_MODULESDIR, '-', diff --git a/apps/kdf.c b/apps/kdf.c index 35cc0db2..82818f1f 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -24,14 +24,20 @@ typedef enum OPTION_choice { const OPTIONS kdf_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"}, - {OPT_HELP_STR, 1, '-', "kdf_name\t KDF algorithm.\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form. " - "See 'Supported Controls' in the EVP_KDF_ docs"}, + {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form"}, + {OPT_MORE_STR, 1, '-', "See 'Supported Controls' in the EVP_KDF_ docs\n"}, {"keylen", OPT_KEYLEN, 's', "The size of the output derived key"}, + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, - {"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal " - "output)"}, + {"binary", OPT_BIN, '-', + "Output in binary format (default is hexadecimal)"}, + + OPT_PARAMETERS(), + {"kdf_name", 0, 0, "Name of the KDF algorithm"}, {NULL} }; @@ -132,6 +138,10 @@ opthelp: BIO_write(out, dkm_bytes, dkm_len); } else { hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len); + if (hexout == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } BIO_printf(out, "%s\n\n", hexout); } diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 73483d99..3a18cd00 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -125,18 +125,29 @@ int app_init(long mesgwin) } #endif -int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath, int noCAfile, int noCApath) +int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore) { - if (CAfile == NULL && CApath == NULL) { + if (CAfile == NULL && CApath == NULL && CAstore == NULL) { if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0) return 0; if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0) return 0; + if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0) + return 0; return 1; } - return SSL_CTX_load_verify_locations(ctx, CAfile, CApath); + + if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile)) + return 0; + if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath)) + return 0; + if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore)) + return 0; + return 1; } #ifndef OPENSSL_NO_CT @@ -1068,7 +1079,9 @@ void print_array(BIO *out, const char* title, int len, const unsigned char* d) BIO_printf(out, "\n};\n"); } -X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath) +X509_STORE *setup_verify(const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore) { X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup; @@ -1080,7 +1093,7 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; - if (CAfile) { + if (CAfile != NULL) { if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto end; @@ -1094,7 +1107,7 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; - if (CApath) { + if (CApath != NULL) { if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto end; @@ -1104,6 +1117,17 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i } } + if (CAstore != NULL || !noCAstore) { + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store()); + if (lookup == NULL) + goto end; + if (!X509_LOOKUP_add_store(lookup, CAstore)) { + if (CAstore != NULL) + BIO_printf(bio_err, "Error loading store URI %s\n", CAstore); + goto end; + } + } + ERR_clear_error(); return store; end: @@ -2300,8 +2324,8 @@ BIO *dup_bio_out(int format) if (FMT_istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { - b = BIO_push(BIO_new(apps_bf_prefix()), b); - BIO_ctrl(b, PREFIX_CTRL_SET_PREFIX, 0, prefix); + b = BIO_push(BIO_new(BIO_f_prefix()), b); + BIO_set_prefix(b, prefix); } return b; @@ -2318,17 +2342,6 @@ BIO *dup_bio_err(int format) return b; } -/* - * Because the prefix method is created dynamically, we must also be able - * to destroy it. - */ -void destroy_prefix_method(void) -{ - BIO_METHOD *prefix_method = apps_bf_prefix(); - BIO_meth_free(prefix_method); - prefix_method = NULL; -} - void unbuffer(FILE *fp) { /* diff --git a/apps/lib/build.info b/apps/lib/build.info index 0c24d76d..3f68a2ed 100644 --- a/apps/lib/build.info +++ b/apps/lib/build.info @@ -1,4 +1,4 @@ -# Auxilliary program source +# Auxiliary program source IF[{- $config{target} =~ /^(?:VC-|mingw)/ -}] # It's called 'init', but doesn't have much 'init' in it... $AUXLIBAPPSSRC=win32_init.c @@ -9,7 +9,7 @@ ENDIF # Source for libapps $LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \ - bf_prefix.c columns.c app_params.c names.c + columns.c app_params.c names.c IF[{- !$disabled{apps} -}] LIBS{noinst}=../libapps.a diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 44d2570a..767f35f6 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -26,9 +26,10 @@ #include #define MAX_OPT_HELP_WIDTH 30 -const char OPT_HELP_STR[] = "--"; -const char OPT_MORE_STR[] = "---"; -const char OPT_SECTION_STR[] = "----"; +const char OPT_HELP_STR[] = "-H"; +const char OPT_MORE_STR[] = "-M"; +const char OPT_SECTION_STR[] = "-S"; +const char OPT_PARAM_STR[] = "-P"; /* Our state */ static char **argv; @@ -128,14 +129,16 @@ char *opt_init(int ac, char **av, const OPTIONS *o) opt_progname(av[0]); unknown = NULL; - for (; o->name; ++o) { + /* Check all options up until the PARAM marker (if present) */ + for (; o->name != NULL && o->name != OPT_PARAM_STR; ++o) { #ifndef NDEBUG const OPTIONS *next; int duplicated, i; #endif - if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR || - o->name == OPT_SECTION_STR) + if (o->name == OPT_HELP_STR + || o->name == OPT_MORE_STR + || o->name == OPT_SECTION_STR) continue; #ifndef NDEBUG i = o->valtype; @@ -146,7 +149,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o) switch (i) { case 0: case '-': case '/': case '<': case '>': case 'E': case 'F': case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's': - case 'u': case 'c': + case 'u': case 'c': case ':': break; default: OPENSSL_assert(0); @@ -285,7 +288,7 @@ int opt_cipher(const char *name, const EVP_CIPHER **cipherp) *cipherp = EVP_get_cipherbyname(name); if (*cipherp != NULL) return 1; - opt_printf_stderr("%s: Unrecognized flag %s\n", prog, name); + opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); return 0; } @@ -297,7 +300,7 @@ int opt_md(const char *name, const EVP_MD **mdp) *mdp = EVP_get_digestbyname(name); if (*mdp != NULL) return 1; - opt_printf_stderr("%s: Unrecognized flag %s\n", prog, name); + opt_printf_stderr("%s: Unknown message digest: %s\n", prog, name); return 0; } @@ -686,6 +689,7 @@ int opt_next(void) switch (o->valtype) { default: case 's': + case ':': /* Just a string. */ break; case '/': @@ -758,7 +762,7 @@ int opt_next(void) dunno = p; return unknown->retval; } - opt_printf_stderr("%s: Option unknown option -%s\n", prog, p); + opt_printf_stderr("%s: Unknown option: -%s\n", prog, p); return -1; } @@ -804,6 +808,8 @@ static const char *valtype2param(const OPTIONS *o) case 0: case '-': return ""; + case ':': + return "uri"; case 's': return "val"; case '/': @@ -834,17 +840,26 @@ static const char *valtype2param(const OPTIONS *o) return "parm"; } -void opt_print(const OPTIONS *o, int width) +void opt_print(const OPTIONS *o, int doingparams, int width) { const char* help; char start[80 + 1]; char *p; help = o->helpstr ? o->helpstr : "(No additional info)"; - if (o->name == OPT_HELP_STR || o->name == OPT_SECTION_STR) { + if (o->name == OPT_HELP_STR) { opt_printf_stderr(help, prog); return; } + if (o->name == OPT_SECTION_STR) { + opt_printf_stderr("\n"); + opt_printf_stderr(help, prog); + return; + } + if (o->name == OPT_PARAM_STR) { + opt_printf_stderr("\nParameters:\n"); + return; + } /* Pad out prefix */ memset(start, ' ', sizeof(start) - 1); @@ -860,7 +875,8 @@ void opt_print(const OPTIONS *o, int width) /* Build up the "-flag [param]" part. */ p = start; *p++ = ' '; - *p++ = '-'; + if (!doingparams) + *p++ = '-'; if (o->name[0]) p += strlen(strcpy(p, o->name)); else @@ -882,9 +898,8 @@ void opt_print(const OPTIONS *o, int width) void opt_help(const OPTIONS *list) { const OPTIONS *o; - int i; + int i, sawparams = 0, width = 5; int standard_prolog; - int width = 5; char start[80 + 1]; /* Starts with its own help message? */ @@ -910,7 +925,9 @@ void opt_help(const OPTIONS *list) /* Now let's print. */ for (o = list; o->name; o++) { - opt_print(o, width); + if (o->name == OPT_PARAM_STR) + sawparams = 1; + opt_print(o, sawparams, width); } } diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index 47b8afe9..7b81d60f 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -1262,27 +1262,37 @@ int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, + const char *vfyCAstore, const char *chCApath, const char *chCAfile, + const char *chCAstore, STACK_OF(X509_CRL) *crls, int crl_download) { X509_STORE *vfy = NULL, *ch = NULL; int rv = 0; - if (vfyCApath != NULL || vfyCAfile != NULL) { + if (vfyCApath != NULL || vfyCAfile != NULL || vfyCAstore != NULL) { vfy = X509_STORE_new(); if (vfy == NULL) goto err; - if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) + if (vfyCAfile != NULL && !X509_STORE_load_file(vfy, vfyCAfile)) + goto err; + if (vfyCApath != NULL && !X509_STORE_load_path(vfy, vfyCApath)) + goto err; + if (vfyCAstore != NULL && !X509_STORE_load_store(vfy, vfyCAstore)) goto err; add_crls_store(vfy, crls); SSL_CTX_set1_verify_cert_store(ctx, vfy); if (crl_download) store_setup_crl_download(vfy); } - if (chCApath != NULL || chCAfile != NULL) { + if (chCApath != NULL || chCAfile != NULL || chCAstore != NULL) { ch = X509_STORE_new(); if (ch == NULL) goto err; - if (!X509_STORE_load_locations(ch, chCAfile, chCApath)) + if (chCAfile != NULL && !X509_STORE_load_file(ch, chCAfile)) + goto err; + if (chCApath != NULL && !X509_STORE_load_path(ch, chCApath)) + goto err; + if (chCAstore != NULL && !X509_STORE_load_store(ch, chCAstore)) goto err; SSL_CTX_set1_chain_cert_store(ctx, ch); } diff --git a/apps/list.c b/apps/list.c index 2e8867df..a5382ac2 100644 --- a/apps/list.c +++ b/apps/list.c @@ -366,6 +366,8 @@ static void list_options_for_command(const char *command) if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR + || o->name == OPT_SECTION_STR + || o->name == OPT_PARAM_STR || o->name[0] == '\0') continue; BIO_printf(bio_out, "%s %c\n", o->name, c == '\0' ? '-' : c); @@ -617,7 +619,11 @@ typedef enum HELPLIST_CHOICE { } HELPLIST_CHOICE; const OPTIONS list_options[] = { + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"1", OPT_ONE, '-', "List in one column"}, {"verbose", OPT_VERBOSE, '-', "Verbose listing"}, {"commands", OPT_COMMANDS, '-', "List of standard commands"}, diff --git a/apps/mac.c b/apps/mac.c index 8383d0d7..6abcfcd4 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -26,15 +26,22 @@ typedef enum OPTION_choice { const OPTIONS mac_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] mac_name\n"}, - {OPT_HELP_STR, 1, '-', "mac_name\t\t MAC algorithm (See list " - "-mac-algorithms)"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form. " - "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, + {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form"}, + {OPT_MORE_STR, 1, '-', "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file to MAC (default is stdin)"}, + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, - {"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal " - "output)"}, + {"binary", OPT_BIN, '-', + "Output in binary format (default is hexadecimal)"}, + + OPT_PARAMETERS(), + {"mac_name", 0, 0, "MAC algorithm"}, {NULL} }; diff --git a/apps/nseq.c b/apps/nseq.c index 6c883c0f..5b7ab67d 100644 --- a/apps/nseq.c +++ b/apps/nseq.c @@ -20,9 +20,14 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS nseq_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, + + OPT_SECTION("Output"), + {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, {"out", OPT_OUT, '>', "Output file"}, {NULL} }; diff --git a/apps/ocsp.c b/apps/ocsp.c index 71c6a56f..dc1b7601 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -115,7 +115,7 @@ static int acfd = (int) INVALID_SOCKET; static int index_changed(CA_DB *); static void spawn_loop(void); static int print_syslog(const char *str, size_t len, void *levPtr); -static void sock_timeout(int signum); +static void socket_timeout(int signum); # endif # ifndef OPENSSL_NO_SOCK @@ -134,11 +134,13 @@ typedef enum OPTION_choice { OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, - OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, + OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, + OPT_NOCAPATH, OPT_NOCASTORE, OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL, OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER, + OPT_PASSIN, OPT_RCID, OPT_V_ENUM, OPT_MD, @@ -146,31 +148,70 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS ocsp_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUTFILE, '>', "Output filename"}, - {"timeout", OPT_TIMEOUT, 'p', - "Connection timeout (in seconds) to the OCSP responder"}, - {"url", OPT_URL, 's', "Responder URL"}, - {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, - {"port", OPT_PORT, 'p', "Port to run responder on"}, {"ignore_err", OPT_IGNORE_ERR, '-', "Ignore error on OCSP request or response and continue running"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, - {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, - {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, + {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates store"}, + + OPT_SECTION("Responder"), + {"timeout", OPT_TIMEOUT, 'p', + "Connection timeout (in seconds) to the OCSP responder"}, {"resp_no_certs", OPT_RESP_NO_CERTS, '-', "Don't include any certificates in response"}, - {"resp_key_id", OPT_RESP_KEY_ID, '-', - "Identify response by signing certificate key ID"}, # ifdef OCSP_DAEMON {"multi", OPT_MULTI, 'p', "run multiple responder processes"}, # endif {"no_certs", OPT_NO_CERTS, '-', "Don't include any certificates in signed request"}, + {"badsig", OPT_BADSIG, '-', + "Corrupt last byte of loaded OSCP response signature (for test)"}, + {"CA", OPT_CA, '<', "CA certificate"}, + {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, + {"nrequest", OPT_REQUEST, 'p', + "Number of requests to accept (default unlimited)"}, + {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, + {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, + {"sign_other", OPT_SIGN_OTHER, '<', + "Additional certificates to include in signed request"}, + {"index", OPT_INDEX, '<', "Certificate status index file"}, + {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, + {"rsigner", OPT_RSIGNER, '<', + "Responder certificate to sign responses with"}, + {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, + {"passin", OPT_PASSIN, 's', "Responder key pass phrase source"}, + {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, + {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, + {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"}, + {"header", OPT_HEADER, 's', "key=value header to add"}, + {"rcid", OPT_RCID, 's', "Use specified algorithm for cert id in response"}, + {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, + + OPT_SECTION("Client"), + {"url", OPT_URL, 's', "Responder URL"}, + {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, + {"port", OPT_PORT, 'p', "Port to run responder on"}, + {"out", OPT_OUTFILE, '>', "Output filename"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, + {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, + {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', "Don't check signature on response"}, + {"resp_key_id", OPT_RESP_KEY_ID, '-', + "Identify response by signing certificate key ID"}, {"no_cert_verify", OPT_NO_CERT_VERIFY, '-', "Don't check signing certificate"}, + {"text", OPT_TEXT, '-', "Print text form of request and response"}, + {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, + {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', "Don't do additional checks on signing certificate"}, @@ -180,50 +221,21 @@ const OPTIONS ocsp_options[] = { "Don't verify additional certificates"}, {"no_intern", OPT_NO_INTERN, '-', "Don't search certificates contained in response for signer"}, - {"badsig", OPT_BADSIG, '-', - "Corrupt last byte of loaded OSCP response signature (for test)"}, - {"text", OPT_TEXT, '-', "Print text form of request and response"}, - {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, - {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, - {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"}, - {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, - {"sign_other", OPT_SIGN_OTHER, '<', - "Additional certificates to include in signed request"}, {"verify_other", OPT_VERIFY_OTHER, '<', "Additional certificates to search for signer"}, - {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, - {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, + {"path", OPT_PATH, 's', "Path to use in OCSP request"}, + {"cert", OPT_CERT, '<', "Certificate to check"}, + {"serial", OPT_SERIAL, 's', "Serial number to check"}, {"validity_period", OPT_VALIDITY_PERIOD, 'u', "Maximum validity discrepancy in seconds"}, - {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"}, {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"}, - {"path", OPT_PATH, 's', "Path to use in OCSP request"}, {"issuer", OPT_ISSUER, '<', "Issuer certificate"}, - {"cert", OPT_CERT, '<', "Certificate to check"}, - {"serial", OPT_SERIAL, 's', "Serial number to check"}, - {"index", OPT_INDEX, '<', "Certificate status index file"}, - {"CA", OPT_CA, '<', "CA certificate"}, - {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, - {"nrequest", OPT_REQUEST, 'p', - "Number of requests to accept (default unlimited)"}, - {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, - {"rsigner", OPT_RSIGNER, '<', - "Responder certificate to sign responses with"}, - {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, - {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, - {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, - {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"}, - {"header", OPT_HEADER, 's', "key=value header to add"}, - {"rcid", OPT_RCID, 's', "Use specified algorithm for cert id in response"}, - {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, + {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, + OPT_V_OPTIONS, {NULL} }; @@ -250,16 +262,17 @@ int ocsp_main(int argc, char **argv) X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *CAfile = NULL, *CApath = NULL; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; char *header, *value; char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; char *rca_filename = NULL, *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; char *rsignfile = NULL, *rkeyfile = NULL; + char *passinarg = NULL, *passin = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; char *signfile = NULL, *keyfile = NULL; char *thost = NULL, *tport = NULL, *tpath = NULL; - int noCAfile = 0, noCApath = 0; + int noCAfile = 0, noCApath = 0, noCAstore = 0; int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; int req_text = 0, resp_text = 0, ret = 1; @@ -395,12 +408,18 @@ int ocsp_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; @@ -479,6 +498,9 @@ int ocsp_main(int argc, char **argv) case OPT_RKEY: rkeyfile = opt_arg(); break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; case OPT_ROTHER: rcertfile = opt_arg(); break; @@ -581,7 +603,11 @@ int ocsp_main(int argc, char **argv) "responder other certificates")) goto end; } - rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, + if (!app_passwd(passinarg, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + rkey = load_key(rkeyfile, FORMAT_PEM, 0, passin, NULL, "responder private key"); if (rkey == NULL) goto end; @@ -606,7 +632,7 @@ int ocsp_main(int argc, char **argv) if (multi && acbio != NULL) spawn_loop(); if (acbio != NULL && req_timeout > 0) - signal(SIGALRM, sock_timeout); + signal(SIGALRM, socket_timeout); #endif if (acbio != NULL) @@ -765,7 +791,8 @@ redo_accept: } if (store == NULL) { - store = setup_verify(CAfile, CApath, noCAfile, noCApath); + store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore); if (!store) goto end; } @@ -1372,7 +1399,7 @@ static int urldecode(char *p) # endif # ifdef OCSP_DAEMON -static void sock_timeout(int signum) +static void socket_timeout(int signum) { if (acfd != (int)INVALID_SOCKET) (void)shutdown(acfd, SHUT_RD); diff --git a/apps/openssl.c b/apps/openssl.c index 123c1ff4..00ad9ca0 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -113,10 +113,10 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, tid = CRYPTO_THREAD_get_current_id(); hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); BIO_snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", - hex, OSSL_trace_get_category_name(category)); + hex == NULL ? "" : hex, + OSSL_trace_get_category_name(category)); OPENSSL_free(hex); - BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX, - strlen(buffer), buffer); + BIO_set_prefix(trace_data->bio, buffer); break; case OSSL_TRACE_CTRL_WRITE: if (!ossl_assert(trace_data->ingroup)) @@ -129,7 +129,7 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, return 0; trace_data->ingroup = 0; - BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX, 0, NULL); + BIO_set_prefix(trace_data->bio, NULL); break; } @@ -161,8 +161,7 @@ static void setup_trace_category(int category) if (OSSL_trace_enabled(category)) return; - channel = BIO_push(BIO_new(apps_bf_prefix()), - dup_bio_err(FORMAT_TEXT)); + channel = BIO_push(BIO_new(BIO_f_prefix()), dup_bio_err(FORMAT_TEXT)); trace_data = OPENSSL_zalloc(sizeof(*trace_data)); if (trace_data == NULL @@ -246,22 +245,10 @@ int main(int argc, char *argv[]) win32_utf8argv(&argc, &argv); #endif - /* - * We use the prefix method to get the trace output we want. Since some - * trace outputs happen with OPENSSL_cleanup(), which is run automatically - * after exit(), we need to destroy the prefix method as late as possible. - */ - atexit(destroy_prefix_method); - #ifndef OPENSSL_NO_TRACE setup_trace(getenv("OPENSSL_TRACE")); #endif - p = getenv("OPENSSL_DEBUG_MEMORY"); - if (p != NULL && strcmp(p, "on") == 0) - CRYPTO_set_mem_debug(1); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - if (getenv("OPENSSL_FIPS")) { BIO_printf(bio_err, "FIPS mode not supported.\n"); return 1; @@ -276,6 +263,13 @@ int main(int argc, char *argv[]) } prog = prog_init(); + if (prog == NULL) { + BIO_printf(bio_err, + "FATAL: Startup failure (dev note: prog_init() failed)\n"); + ERR_print_errors(bio_err); + ret = 1; + goto end; + } pname = opt_progname(argv[0]); /* first check the program name */ @@ -371,10 +365,6 @@ int main(int argc, char *argv[]) BIO_free(bio_in); BIO_free_all(bio_out); apps_shutdown(); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (CRYPTO_mem_leaks(bio_err) <= 0) - ret = 1; -#endif BIO_free(bio_err); EXIT(ret); } @@ -384,9 +374,13 @@ typedef enum HELP_CHOICE { } HELP_CHOICE; const OPTIONS help_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: help [options]\n"}, - {OPT_HELP_STR, 1, '-', " help [command]\n"}, + {OPT_HELP_STR, 1, '-', "Usage: help [options] [command]\n"}, + + OPT_SECTION("General"), {"help", OPT_hHELP, '-', "Display this summary"}, + + OPT_PARAMETERS(), + {"command", 0, 0, "Name of command to display help (optional)"}, {NULL} }; diff --git a/apps/passwd.c b/apps/passwd.c index 95662365..c17bfd83 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -59,15 +59,24 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS passwd_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [password]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Read passwords from file"}, {"noverify", OPT_NOVERIFY, '-', "Never verify when reading password from terminal"}, + {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, + + OPT_SECTION("Output"), {"quiet", OPT_QUIET, '-', "No warnings"}, {"table", OPT_TABLE, '-', "Format output as table"}, {"reverse", OPT_REVERSE, '-', "Switch table columns"}, + + OPT_SECTION("Cryptographic"), {"salt", OPT_SALT, 's', "Use provided salt"}, - {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, {"6", OPT_6, '-', "SHA512-based password algorithm"}, {"5", OPT_5, '-', "SHA256-based password algorithm"}, {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"}, @@ -76,7 +85,11 @@ const OPTIONS passwd_options[] = { #ifndef OPENSSL_NO_DES {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"}, #endif + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"password", 0, 0, "Password text to digest (optional)"}, {NULL} }; @@ -807,7 +820,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ (*salt_p)[i] = 0; # ifdef CHARSET_EBCDIC - /* The password encryption funtion will convert back to ASCII */ + /* The password encryption function will convert back to ASCII */ ascii2ebcdic(*salt_p, *salt_p, saltlen); # endif } diff --git a/apps/pkcs12.c b/apps/pkcs12.c index a708064d..5eff88b6 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -53,27 +53,65 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS, OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER, - OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, + OPT_DESCERT, OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, - OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE, + OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, OPT_R_ENUM } OPTION_CHOICE; const OPTIONS pkcs12_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, - {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, - {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("CA"), + {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, + + OPT_SECTION("Input"), + {"inkey", OPT_INKEY, 's', "Private key if not infile"}, + {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, + {"name", OPT_NAME, 's', "Use name as friendly name"}, + {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, + {"caname", OPT_CANAME, 's', + "Use name as CA friendly name (can be repeated)"}, + {"in", OPT_IN, '<', "Input filename"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, + {"LMK", OPT_LMK, '-', + "Add local machine keyset attribute to private key"}, + {"macalg", OPT_MACALG, 's', + "Digest algorithm used in MAC (default SHA1)"}, + {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, + {"out", OPT_OUT, '>', "Output filename"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"password", OPT_PASSWORD, 's', "Set import/export password source"}, {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"}, {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"}, - {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, {"chain", OPT_CHAIN, '-', "Add certificate chain"}, {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, + {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, + {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, + {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, + {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, + + OPT_SECTION("Encryption"), # ifndef OPENSSL_NO_RC2 {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (default RC2-40)"}, @@ -83,39 +121,15 @@ const OPTIONS pkcs12_options[] = { {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, # endif - {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, - {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, - {"maciter", OPT_MACITER, '-', "Use MAC iteration"}, + {"iter", OPT_ITER, 'p', "Specify the iteration count for encryption key and MAC"}, + {"noiter", OPT_NOITER, '-', "Don't use encryption key iteration"}, + {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"}, {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"}, {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, - {"LMK", OPT_LMK, '-', - "Add local machine keyset attribute to private key"}, {"nodes", OPT_NODES, '-', "Don't encrypt private keys"}, - {"macalg", OPT_MACALG, 's', - "Digest algorithm used in MAC (default SHA1)"}, - {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, - OPT_R_OPTIONS, - {"inkey", OPT_INKEY, 's', "Private key if not infile"}, - {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, - {"name", OPT_NAME, 's', "Use name as friendly name"}, - {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, - {"caname", OPT_CANAME, 's', - "Use name as CA friendly name (can be repeated)"}, - {"in", OPT_IN, '<', "Input filename"}, - {"out", OPT_OUT, '>', "Output filename"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"password", OPT_PASSWORD, 's', "Set import/export password source"}, - {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, - {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif + + OPT_R_OPTIONS, {NULL} }; @@ -137,8 +151,8 @@ int pkcs12_main(int argc, char **argv) char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL, *macalg = NULL; char *cpass = NULL, *mpass = NULL, *badpass = NULL; - const char *CApath = NULL, *CAfile = NULL, *prog; - int noCApath = 0, noCAfile = 0; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog; + int noCApath = 0, noCAfile = 0, noCAstore = 0; ENGINE *e = NULL; BIO *in = NULL, *out = NULL; PKCS12 *p12 = NULL; @@ -201,11 +215,16 @@ int pkcs12_main(int argc, char **argv) if (!opt_cipher(opt_unknown(), &enc)) goto opthelp; break; + case OPT_ITER: + if (!opt_int(opt_arg(), &iter)) + goto opthelp; + maciter = iter; + break; case OPT_NOITER: iter = 1; break; case OPT_MACITER: - maciter = PKCS12_DEFAULT_ITER; + /* no-op */ break; case OPT_NOMACITER: maciter = 1; @@ -270,12 +289,18 @@ int pkcs12_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_NOCAFILE: noCAfile = 1; break; @@ -404,7 +429,8 @@ int pkcs12_main(int argc, char **argv) int vret; STACK_OF(X509) *chain2; X509_STORE *store; - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto export_end; diff --git a/apps/pkcs7.c b/apps/pkcs7.c index a385f909..bd1cb101 100644 --- a/apps/pkcs7.c +++ b/apps/pkcs7.c @@ -27,9 +27,17 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS pkcs7_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + + OPT_SECTION("Output"), {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"out", OPT_OUT, '>', "Output file"}, {"noout", OPT_NOOUT, '-', "Don't output encoded data"}, @@ -37,9 +45,6 @@ const OPTIONS pkcs7_options[] = { {"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"}, {"print_certs", OPT_PRINT_CERTS, '-', "Print_certs print any certs or crl in the input"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif {NULL} }; diff --git a/apps/pkcs8.c b/apps/pkcs8.c index 26ab0eef..1ccaff06 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -30,31 +30,39 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS pkcs8_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, - {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, - {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, - OPT_R_OPTIONS, - {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, - {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, - {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"}, - {"iter", OPT_ITER, 'p', "Specify the iteration count"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, + {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, + {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, + {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, + {"iter", OPT_ITER, 'p', "Specify the iteration count"}, + {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, + #ifndef OPENSSL_NO_SCRYPT + OPT_SECTION("Scrypt"), {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"}, {"scrypt_N", OPT_SCRYPT_N, 's', "Set scrypt N parameter"}, {"scrypt_r", OPT_SCRYPT_R, 's', "Set scrypt r parameter"}, {"scrypt_p", OPT_SCRYPT_P, 's', "Set scrypt p parameter"}, #endif + + OPT_R_OPTIONS, {NULL} }; diff --git a/apps/pkey.c b/apps/pkey.c index 0806b4e0..6100f8dc 100644 --- a/apps/pkey.c +++ b/apps/pkey.c @@ -23,27 +23,33 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS pkey_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"in", OPT_IN, 's', "Input key"}, - {"out", OPT_OUT, '>', "Output file"}, - {"pubin", OPT_PUBIN, '-', - "Read public key from input (default is private key)"}, - {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, - {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"}, - {"text", OPT_TEXT, '-', "Output in plaintext as well"}, - {"noout", OPT_NOOUT, '-', "Don't output the key"}, - {"", OPT_MD, '-', "Any supported cipher"}, - {"traditional", OPT_TRADITIONAL, '-', - "Use traditional format for private keys"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif {"check", OPT_CHECK, '-', "Check key consistency"}, {"pubcheck", OPT_PUB_CHECK, '-', "Check public key consistency"}, + {"", OPT_MD, '-', "Any supported cipher"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input key"}, + {"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"pubin", OPT_PUBIN, '-', + "Read public key from input (default is private key)"}, + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private keys"}, + + OPT_SECTION("Output"), + {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, + {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"}, + {"text", OPT_TEXT, '-', "Output in plaintext as well"}, + {"noout", OPT_NOOUT, '-', "Don't output the key"}, + {NULL} }; diff --git a/apps/pkeyparam.c b/apps/pkeyparam.c index 1b037aea..552ba56d 100644 --- a/apps/pkeyparam.c +++ b/apps/pkeyparam.c @@ -22,15 +22,20 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS pkeyparam_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"text", OPT_TEXT, '-', "Print parameters as text"}, - {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif {"check", OPT_CHECK, '-', "Check key param consistency"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"text", OPT_TEXT, '-', "Print parameters as text"}, + {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, {NULL} }; diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 6b012211..a8cd2a0e 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -49,41 +49,49 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS pkeyutl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file - default stdin"}, - {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, - {"digest", OPT_DIGEST, 's', - "Specify the digest algorithm when signing the raw input data"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"pubin", OPT_PUBIN, '-', "Input is a public key"}, - {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, - {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"}, - {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, - {"sign", OPT_SIGN, '-', "Sign input data with private key"}, - {"verify", OPT_VERIFY, '-', "Verify with public key"}, - {"verifyrecover", OPT_VERIFYRECOVER, '-', - "Verify with public key, recover original data"}, - {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, - {"derive", OPT_DERIVE, '-', "Derive shared secret"}, - {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, - {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, - {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, - {"inkey", OPT_INKEY, 's', "Input private key file"}, - {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"}, - {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, - {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, - {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', - "Public key option that is read as a passphrase argument opt:passphrase"}, - OPT_R_OPTIONS, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, {"engine_impl", OPT_ENGINE_IMPL, '-', "Also use engine given by -engine for crypto operations"}, #endif + {"sign", OPT_SIGN, '-', "Sign input data with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, + {"derive", OPT_DERIVE, '-', "Derive shared secret"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, + {"pubin", OPT_PUBIN, '-', "Input is a public key"}, + {"inkey", OPT_INKEY, 's', "Input private key file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, + {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"}, + {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, + {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, + {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, + {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"}, + {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, + {"verifyrecover", OPT_VERIFYRECOVER, '-', + "Verify with public key, recover original data"}, + + OPT_SECTION("Signing/Derivation"), + {"digest", OPT_DIGEST, 's', + "Specify the digest algorithm when signing the raw input data"}, + {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, + {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', + "Public key option that is read as a passphrase argument opt:passphrase"}, + {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, + {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, + + OPT_R_OPTIONS, {NULL} }; diff --git a/apps/prime.c b/apps/prime.c index 55cdad81..5345e5b6 100644 --- a/apps/prime.c +++ b/apps/prime.c @@ -20,15 +20,20 @@ typedef enum OPTION_choice { const OPTIONS prime_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, - {OPT_HELP_STR, 1, '-', - " number Number to check for primality\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"bits", OPT_BITS, 'p', "Size of number in bits"}, + {"checks", OPT_CHECKS, 'p', "Number of checks"}, + + OPT_SECTION("Output"), {"hex", OPT_HEX, '-', "Hex output"}, {"generate", OPT_GENERATE, '-', "Generate a prime"}, - {"bits", OPT_BITS, 'p', "Size of number in bits"}, {"safe", OPT_SAFE, '-', "When used with -generate, generate a safe prime"}, - {"checks", OPT_CHECKS, 'p', "Number of checks"}, + + OPT_PARAMETERS(), + {"number", 0, 0, "Number(s) to check for primality if not generating"}, {NULL} }; diff --git a/apps/progs.c b/apps/progs.c index 721e8cbf..82cd19be 100644 --- a/apps/progs.c +++ b/apps/progs.c @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by apps/progs.pl * - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 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/apps/progs.h b/apps/progs.h index deb9549f..04e9c4e9 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by apps/progs.pl * - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 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/apps/provider.c b/apps/provider.c index 325a7424..87231cd2 100644 --- a/apps/provider.c +++ b/apps/provider.c @@ -26,14 +26,20 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS provider_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] provider...\n"}, - {OPT_HELP_STR, 1, '-', " provider... Providers to load\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [provider...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"v", OPT_V, '-', "List the algorithm names of specified provider"}, {"vv", OPT_VV, '-', "List the algorithm names of specified providers,"}, {OPT_MORE_STR, 0, '-', "categorised by operation type"}, {"vvv", OPT_VVV, '-', "List the algorithm names of specified provider"}, {OPT_MORE_STR, 0, '-', "one at a time, and list all known parameters"}, + + OPT_PARAMETERS(), + {"provider", 0, 0, "Provider(s) to load"}, {NULL} }; @@ -264,6 +270,7 @@ int provider_main(int argc, char **argv) argc = opt_num_rest(); argv = opt_rest(); for ( ; *argv; argv++) { + /* This isn't necessary since -- is supported. */ if (**argv == '-') { BIO_printf(bio_err, "%s: Cannot mix flags and provider names.\n", prog); diff --git a/apps/rand.c b/apps/rand.c index b35b84ae..421ebfc2 100644 --- a/apps/rand.c +++ b/apps/rand.c @@ -25,16 +25,23 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS rand_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] num\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file"}, - OPT_R_OPTIONS, - {"base64", OPT_BASE64, '-', "Base64 encode output"}, - {"hex", OPT_HEX, '-', "Hex encode output"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"base64", OPT_BASE64, '-', "Base64 encode output"}, + {"hex", OPT_HEX, '-', "Hex encode output"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"num", 0, 0, "Number of bytes to generate"}, {NULL} }; diff --git a/apps/rehash.c b/apps/rehash.c index a1fc3790..b7e6e7ec 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -451,14 +451,20 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS rehash_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert-directory...]\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [directory...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"h", OPT_HELP, '-', "Display this summary"}, {"compat", OPT_COMPAT, '-', "Create both new- and old-style hash links"}, {"old", OPT_OLD, '-', "Use old-style hash to generate links"}, {"n", OPT_N, '-', "Do not remove existing links"}, + + OPT_SECTION("Output"), {"v", OPT_VERBOSE, '-', "Verbose output"}, + + OPT_PARAMETERS(), + {"directory", 0, 0, "One or more directories to process (optional)"}, {NULL} }; diff --git a/apps/req.c b/apps/req.c index 70b4f0d6..87994ceb 100644 --- a/apps/req.c +++ b/apps/req.c @@ -95,37 +95,26 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS req_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"keygen_engine", OPT_KEYGEN_ENGINE, 's', + "Specify engine to be used for key generation operations"}, +#endif {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"key", OPT_KEY, 's', "Private key to use"}, - {"keyform", OPT_KEYFORM, 'f', "Key file format"}, - {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"verify", OPT_VERIFY, '-', "Verify signature on REQ"}, + + OPT_SECTION("Certificate"), {"new", OPT_NEW, '-', "New request"}, {"config", OPT_CONFIG, '<', "Request template file"}, - {"keyout", OPT_KEYOUT, '>', "File to send the key to"}, - {"passin", OPT_PASSIN, 's', "Private key password source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - OPT_R_OPTIONS, - {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, - {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"batch", OPT_BATCH, '-', - "Do not ask anything during request generation"}, - {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, - {"modulus", OPT_MODULUS, '-', "RSA modulus"}, - {"verify", OPT_VERIFY, '-', "Verify signature on REQ"}, - {"nodes", OPT_NODES, '-', "Don't encrypt the output key"}, - {"noout", OPT_NOOUT, '-', "Do not output REQ"}, - {"verbose", OPT_VERBOSE, '-', "Verbose output"}, {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, {"reqopt", OPT_REQOPT, 's', "Various request text options"}, {"text", OPT_TEXT, '-', "Text form of request"}, {"x509", OPT_X509, '-', - "Output a x509 structure instead of a cert request"}, + "Output an x509 structure instead of a cert request"}, {OPT_MORE_STR, 1, 1, "(Required by some CA's)"}, {"subj", OPT_SUBJ, 's', "Set or modify request subject"}, {"subject", OPT_SUBJECT, '-', "Output the request's subject"}, @@ -140,18 +129,37 @@ const OPTIONS req_options[] = { {"reqexts", OPT_REQEXTS, 's', "Request extension section (override value in config file)"}, {"precert", OPT_PRECERT, '-', "Add a poison extension (implies -new)"}, + + OPT_SECTION("Keys and Signing"), + {"key", OPT_KEY, 's', "Private key to use"}, + {"keyform", OPT_KEYFORM, 'f', "Key file format"}, + {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"keyout", OPT_KEYOUT, '>', "File to send the key to"}, + {"passin", OPT_PASSIN, 's', "Private key password source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, + {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"keygen_engine", OPT_KEYGEN_ENGINE, 's', - "Specify engine to be used for key generation operations"}, -#endif #ifndef OPENSSL_NO_SM2 {"sm2-id", OPT_SM2ID, 's', "Specify an ID string to verify an SM2 certificate request"}, {"sm2-hex-id", OPT_SM2HEXID, 's', "Specify a hex ID string to verify an SM2 certificate request"}, #endif + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"batch", OPT_BATCH, '-', + "Do not ask anything during request generation"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"nodes", OPT_NODES, '-', "Don't encrypt the output key"}, + {"noout", OPT_NOOUT, '-', "Do not output REQ"}, + {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, + {"modulus", OPT_MODULUS, '-', "RSA modulus"}, + + OPT_R_OPTIONS, {NULL} }; @@ -206,9 +214,12 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) *p = '\0'; /* Finally have a clean "key"; see if it's there [by attempt to add it]. */ - if ((p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv)) - != NULL || lh_OPENSSL_STRING_error(addexts)) { - OPENSSL_free(p != NULL ? p : kv); + p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv); + if (p != NULL) { + OPENSSL_free(p); + return 1; + } else if (lh_OPENSSL_STRING_error(addexts)) { + OPENSSL_free(kv); return -1; } @@ -468,12 +479,14 @@ int req_main(int argc, char **argv) if (verbose) BIO_printf(bio_err, "Using configuration from %s\n", template); - req_conf = app_load_config(template); + if ((req_conf = app_load_config(template)) == NULL) + goto end; if (addext_bio) { if (verbose) BIO_printf(bio_err, "Using additional configuration from command line\n"); - addext_conf = app_load_config_bio(addext_bio, NULL); + if ((addext_conf = app_load_config_bio(addext_bio, NULL)) == NULL) + goto end; } if (template != default_config_file && !app_load_modules(req_conf)) goto end; diff --git a/apps/rsa.c b/apps/rsa.c index 7c0620c6..82b34e7c 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -37,29 +37,36 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS rsa_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format, one of DER PEM"}, - {"outform", OPT_OUTFORM, 'f', "Output format, one of DER PEM PVK"}, + {"check", OPT_CHECK, '-', "Verify key consistency"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("Input"), {"in", OPT_IN, 's', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, + {"inform", OPT_INFORM, 'f', "Input format, one of DER PEM"}, {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, - {"pubout", OPT_PUBOUT, '-', "Output a public key"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"RSAPublicKey_in", OPT_RSAPUBKEY_IN, '-', "Input is an RSAPublicKey"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'f', "Output format, one of DER PEM PVK"}, + {"pubout", OPT_PUBOUT, '-', "Output a public key"}, {"RSAPublicKey_out", OPT_RSAPUBKEY_OUT, '-', "Output is an RSAPublicKey"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key in text"}, {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, - {"check", OPT_CHECK, '-', "Verify key consistency"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, + # if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) + OPT_SECTION("PVK"), {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, -# endif -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif {NULL} }; diff --git a/apps/rsautl.c b/apps/rsautl.c index 6939e42a..99f1c440 100644 --- a/apps/rsautl.c +++ b/apps/rsautl.c @@ -38,31 +38,37 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS rsautl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"sign", OPT_SIGN, '-', "Sign with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, {"inkey", OPT_INKEY, 's', "Input key"}, {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, {"pubin", OPT_PUBIN, '-', "Input is an RSA public"}, {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"}, + {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, {"ssl", OPT_SSL, '-', "Use SSL v2 padding"}, {"raw", OPT_RSA_RAW, '-', "Use no padding"}, {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"}, + {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"}, - {"sign", OPT_SIGN, '-', "Sign with private key"}, - {"verify", OPT_VERIFY, '-', "Verify with public key"}, {"asn1parse", OPT_ASN1PARSE, '-', "Run output through asn1parse; useful with -verify"}, {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, - {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, - {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif {NULL} }; diff --git a/apps/s_client.c b/apps/s_client.c index 392ab022..a0668bc9 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -581,9 +581,11 @@ typedef enum OPTION_choice { OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, - OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, - OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, - OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, + OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, + OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, + OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME, OPT_ASYNC, OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST, OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, @@ -603,7 +605,23 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS s_client_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [host:port]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', + "Specify engine to be used for client certificate operations"}, +#endif + {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"}, +#ifndef OPENSSL_NO_CT + {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, + {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, + {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, +#endif + + OPT_SECTION("Network"), {"host", OPT_HOST, 's', "Use -connect instead"}, {"port", OPT_PORT, 'p', "Use -connect instead"}, {"connect", OPT_CONNECT, 's', @@ -620,6 +638,18 @@ const OPTIONS s_client_options[] = { #ifdef AF_INET6 {"6", OPT_6, '-', "Use IPv6 only"}, #endif + {"maxfraglen", OPT_MAXFRAGLEN, 'p', + "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, + {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, + {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', + "Size used to split data for encrypt pipelines"}, + {"max_pipelines", OPT_MAX_PIPELINES, 'p', + "Maximum number of encrypt/decrypt pipelines to be used"}, + {"read_buf", OPT_READ_BUF, 'p', + "Default read buffer size to be used for connections"}, + {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, + + OPT_SECTION("Identity"), {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, {"certform", OPT_CERTFORM, 'F', @@ -630,10 +660,13 @@ const OPTIONS s_client_options[] = { {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CAstore", OPT_CAFILE, ':', "URI to store of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates store"}, {"requestCAfile", OPT_REQCAFILE, '<', "PEM format file of CA names to send to the server"}, {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"}, @@ -641,16 +674,19 @@ const OPTIONS s_client_options[] = { "DANE TLSA rrdata presentation form"}, {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-', "Disable name checks when matching DANE-EE(3) TLSA records"}, + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, + {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, + {"name", OPT_PROTOHOST, 's', + "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, + + OPT_SECTION("Session"), {"reconnect", OPT_RECONNECT, '-', "Drop and re-make the connection with the same Session-ID"}, - {"showcerts", OPT_SHOWCERTS, '-', - "Show all certificates sent by the server"}, - {"debug", OPT_DEBUG, '-', "Extra output"}, - {"msg", OPT_MSG, '-', "Show protocol messages"}, - {"msgfile", OPT_MSGFILE, '>', - "File to send output of -msg or -trace, instead of stdout"}, - {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, - {"state", OPT_STATE, '-', "Print the ssl states"}, + {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, + {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, + + OPT_SECTION("Input/Output"), {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, {"quiet", OPT_QUIET, '-', "No s_client output"}, {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"}, @@ -659,47 +695,35 @@ const OPTIONS s_client_options[] = { "Use the appropriate STARTTLS command before starting TLS"}, {"xmpphost", OPT_XMPPHOST, 's', "Alias of -name option for \"-starttls xmpp[-server]\""}, - OPT_R_OPTIONS, - {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, - {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, -#ifndef OPENSSL_NO_SRTP - {"use_srtp", OPT_USE_SRTP, 's', - "Offer SRTP key management with a colon-separated profile list"}, -#endif - {"keymatexport", OPT_KEYMATEXPORT, 's', - "Export keying material using label"}, - {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, - {"maxfraglen", OPT_MAXFRAGLEN, 'p', - "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, - {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, - {"name", OPT_PROTOHOST, 's', - "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, - {"CRL", OPT_CRL, '<', "CRL file to use"}, - {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, - {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, - {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', - "Close connection on verification error"}, - {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, {"brief", OPT_BRIEF, '-', "Restrict output to brief summary of connection parameters"}, {"prexit", OPT_PREXIT, '-', "Print session information when the program exits"}, + + OPT_SECTION("Debug"), + {"showcerts", OPT_SHOWCERTS, '-', + "Show all certificates sent by the server"}, + {"debug", OPT_DEBUG, '-', "Extra output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>', + "File to send output of -msg or -trace, instead of stdout"}, + {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, + {"state", OPT_STATE, '-', "Print the ssl states"}, + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, {"security_debug", OPT_SECURITY_DEBUG, '-', "Enable security debug messages"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', "Output more security debug output"}, - {"cert_chain", OPT_CERT_CHAIN, '<', - "Certificate chain file (in PEM format)"}, - {"chainCApath", OPT_CHAINCAPATH, '/', - "Use dir as certificate store path to build CA certificate chain"}, - {"verifyCApath", OPT_VERIFYCAPATH, '/', - "Use dir as certificate store path to verify CA certificate"}, - {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, - {"chainCAfile", OPT_CHAINCAFILE, '<', - "CA file for certificate chain (PEM format)"}, - {"verifyCAfile", OPT_VERIFYCAFILE, '<', - "CA file for certificate verification (PEM format)"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, +#endif +#ifdef WATT32 + {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, +#endif + {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, {"servername", OPT_SERVERNAME, 's', "Set TLS extension servername (SNI) in ClientHello (default)"}, @@ -715,17 +739,9 @@ const OPTIONS s_client_options[] = { {"alpn", OPT_ALPN, 's', "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, {"async", OPT_ASYNC, '-', "Support asynchronous operation"}, - {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"}, - {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, - {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', - "Size used to split data for encrypt pipelines"}, - {"max_pipelines", OPT_MAX_PIPELINES, 'p', - "Maximum number of encrypt/decrypt pipelines to be used"}, - {"read_buf", OPT_READ_BUF, 'p', - "Default read buffer size to be used for connections"}, - OPT_S_OPTIONS, - OPT_V_OPTIONS, - OPT_X_OPTIONS, + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + + OPT_SECTION("Protocol and version"), #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, #endif @@ -757,16 +773,16 @@ const OPTIONS s_client_options[] = { {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif -#ifndef OPENSSL_NO_SSL_TRACE - {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, +#ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Enable NPN extension, considering named protocols supported (comma-separated list)"}, #endif -#ifdef WATT32 - {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, + {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, + {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, +#ifndef OPENSSL_NO_SRTP + {"use_srtp", OPT_USE_SRTP, 's', + "Offer SRTP key management with a colon-separated profile list"}, #endif - {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, - {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, - {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, - {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, #ifndef OPENSSL_NO_SRP {"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"}, {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, @@ -776,24 +792,36 @@ const OPTIONS s_client_options[] = { "Tolerate other than the known g N values."}, {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal length in bits for N"}, #endif -#ifndef OPENSSL_NO_NEXTPROTONEG - {"nextprotoneg", OPT_NEXTPROTONEG, 's', - "Enable NPN extension, considering named protocols supported (comma-separated list)"}, -#endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', - "Specify engine to be used for client certificate operations"}, -#endif -#ifndef OPENSSL_NO_CT - {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, - {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, - {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, -#endif - {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, - {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, - {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, - {NULL, OPT_EOF, 0x00, NULL} + + OPT_R_OPTIONS, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + {"CRL", OPT_CRL, '<', "CRL file to use"}, + {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, + {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', + "Close connection on verification error"}, + {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, + {"cert_chain", OPT_CERT_CHAIN, '<', + "Certificate chain file (in PEM format)"}, + {"chainCApath", OPT_CHAINCAPATH, '/', + "Use dir as certificate store path to build CA certificate chain"}, + {"chainCAstore", OPT_CHAINCASTORE, ':', + "CA store URI for certificate chain"}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<', + "CA file for certificate verification (PEM format)"}, + {"verifyCApath", OPT_VERIFYCAPATH, '/', + "Use dir as certificate store path to verify CA certificate"}, + {"verifyCAstore", OPT_VERIFYCASTORE, ':', + "CA store URI for certificate verification"}, + {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, + {"chainCAfile", OPT_CHAINCAFILE, '<', + "CA file for certificate chain (PEM format)"}, + OPT_X_OPTIONS, + + OPT_PARAMETERS(), + {"host:port", 0, 0, "Where to connect; same as -connect option"}, + {NULL} }; typedef enum PROTOCOL_choice { @@ -899,22 +927,23 @@ int s_client_main(int argc, char **argv) int dane_ee_no_name = 0; STACK_OF(X509_CRL) *crls = NULL; const SSL_METHOD *meth = TLS_client_method(); - const char *CApath = NULL, *CAfile = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; char *proxystr = NULL, *proxyuser = NULL; char *proxypassarg = NULL, *proxypass = NULL; char *connectstr = NULL, *bindstr = NULL; char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; - char *chCApath = NULL, *chCAfile = NULL, *host = NULL; + char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL; char *port = OPENSSL_strdup(PORT); char *bindhost = NULL, *bindport = NULL; - char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *passarg = NULL, *pass = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL; char *ReqCAfile = NULL; char *sess_in = NULL, *crl_file = NULL, *p; const char *protohost = NULL; struct timeval timeout, *timeoutp; fd_set readfds, writefds; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; int prexit = 0; @@ -1416,6 +1445,18 @@ int s_client_main(int argc, char **argv) case OPT_VERIFYCAFILE: vfyCAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; + case OPT_CHAINCASTORE: + chCAstore = opt_arg(); + break; + case OPT_VERIFYCASTORE: + vfyCAstore = opt_arg(); + break; case OPT_DANE_TLSA_DOMAIN: dane_tlsa_domain = opt_arg(); break; @@ -1796,7 +1837,9 @@ int s_client_main(int argc, char **argv) goto end; } - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + if (!ssl_load_stores(ctx, + vfyCApath, vfyCAfile, vfyCAstore, + chCApath, chCAfile, chCAstore, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1925,7 +1968,8 @@ int s_client_main(int argc, char **argv) SSL_CTX_set_verify(ctx, verify, verify_callback); - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } diff --git a/apps/s_server.c b/apps/s_server.c index 28937bd8..c81e5722 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -182,9 +182,6 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, } #endif -#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01") -#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") - static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, size_t identity_len, SSL_SESSION **sess) { @@ -738,7 +735,9 @@ typedef enum OPTION_choice { OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, - OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, + OPT_VERIFYCAFILE, + OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, + OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, @@ -762,26 +761,50 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS s_server_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"ssl_config", OPT_SSL_CONFIG, 's', + "Configure SSL_CTX using the configuration 'val'"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-', "trace protocol messages"}, +#endif +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Network"), {"port", OPT_PORT, 'p', "TCP/IP port to listen on for connections (default is " PORT ")"}, {"accept", OPT_ACCEPT, 's', "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"}, #ifdef AF_UNIX {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, + {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, #endif {"4", OPT_4, '-', "Use IPv4 only"}, {"6", OPT_6, '-', "Use IPv6 only"}, -#ifdef AF_UNIX - {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, -#endif + + OPT_SECTION("Identity"), {"context", OPT_CONTEXT, 's', "Set session ID context"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store URI"}, + {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, {"Verify", OPT_UPPER_V_VERIFY, 'n', "Turn on peer certificate verification, must have a cert"}, {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, + {"cert2", OPT_CERT2, '<', + "Certificate file to use for servername; default is" TEST_CERT2}, + {"key2", OPT_KEY2, '<', + "-Private Key file to use for servername if not in -cert2"}, {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, {"serverinfo", OPT_SERVERINFO, 's', "PEM serverinfo file for certificate"}, {"certform", OPT_CERTFORM, 'F', @@ -801,39 +824,24 @@ const OPTIONS s_server_options[] = { {"dkeyform", OPT_DKEYFORM, 'F', "Second key format (PEM, DER or ENGINE) PEM default"}, {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, + {"servername", OPT_SERVERNAME, 's', + "Servername for HostName TLS extension"}, + {"servername_fatal", OPT_SERVERNAME_FATAL, '-', + "mismatch send fatal alert (default warning alert)"}, + {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, - {"debug", OPT_DEBUG, '-', "Print more output"}, - {"msg", OPT_MSG, '-', "Show protocol messages"}, - {"msgfile", OPT_MSGFILE, '>', - "File to send output of -msg or -trace, instead of stdout"}, - {"state", OPT_STATE, '-', "Print the SSL states"}, - {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, - {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, - {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, + {"quiet", OPT_QUIET, '-', "No server output"}, {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', "Disable caching and tickets if ephemeral (EC)DH is used"}, {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, - {"servername", OPT_SERVERNAME, 's', - "Servername for HostName TLS extension"}, - {"servername_fatal", OPT_SERVERNAME_FATAL, '-', - "mismatch send fatal alert (default warning alert)"}, - {"cert2", OPT_CERT2, '<', - "Certificate file to use for servername; default is" TEST_CERT2}, - {"key2", OPT_KEY2, '<', - "-Private Key file to use for servername if not in -cert2"}, {"tlsextdebug", OPT_TLSEXTDEBUG, '-', "Hex dump of all TLS extensions received"}, {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, {"id_prefix", OPT_ID_PREFIX, 's', "Generate SSL/TLS session IDs prefixed by arg"}, - OPT_R_OPTIONS, {"keymatexport", OPT_KEYMATEXPORT, 's', "Export keying material using label"}, {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', @@ -841,14 +849,14 @@ const OPTIONS s_server_options[] = { {"CRL", OPT_CRL, '<', "CRL file to use"}, {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, - {"cert_chain", OPT_CERT_CHAIN, '<', - "certificate chain file in PEM format"}, - {"dcert_chain", OPT_DCERT_CHAIN, '<', - "second certificate chain file in PEM format"}, {"chainCApath", OPT_CHAINCAPATH, '/', "use dir as certificate store path to build CA certificate chain"}, + {"chainCAstore", OPT_CHAINCASTORE, ':', + "use URI as certificate store to build CA certificate chain"}, {"verifyCApath", OPT_VERIFYCAPATH, '/', "use dir as certificate store path to verify CA certificate"}, + {"verifyCAstore", OPT_VERIFYCASTORE, ':', + "use URI as certificate store to verify CA certificate"}, {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"}, {"ext_cache", OPT_EXT_CACHE, '-', "Disable internal cache, setup and use external cache"}, @@ -857,14 +865,13 @@ const OPTIONS s_server_options[] = { "Close connection on verification error"}, {"verify_quiet", OPT_VERIFY_QUIET, '-', "No verify output except verify errors"}, - {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, - {"chainCAfile", OPT_CHAINCAFILE, '<', - "CA file for certificate chain (PEM format)"}, {"verifyCAfile", OPT_VERIFYCAFILE, '<', "CA file for certificate verification (PEM format)"}, {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"}, {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"}, + #ifndef OPENSSL_NO_OCSP + OPT_SECTION("OCSP"), {"status", OPT_STATUS, '-', "Request certificate status from server"}, {"status_verbose", OPT_STATUS_VERBOSE, '-', "Print more output in certificate status callback"}, @@ -874,9 +881,8 @@ const OPTIONS s_server_options[] = { {"status_file", OPT_STATUS_FILE, '<', "File containing DER encoded OCSP Response"}, #endif -#ifndef OPENSSL_NO_SSL_TRACE - {"trace", OPT_TRACE, '-', "trace protocol messages"}, -#endif + + OPT_SECTION("Debug"), {"security_debug", OPT_SECURITY_DEBUG, '-', "Print output from SSL/TLS security framework"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', @@ -885,20 +891,28 @@ const OPTIONS s_server_options[] = { "Restrict output to brief summary of connection parameters"}, {"rev", OPT_REV, '-', "act as a simple test server which just sends back with the received text reversed"}, + {"debug", OPT_DEBUG, '-', "Print more output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>', + "File to send output of -msg or -trace, instead of stdout"}, + {"state", OPT_STATE, '-', "Print the SSL states"}, {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"}, - {"ssl_config", OPT_SSL_CONFIG, 's', - "Configure SSL_CTX using the configuration 'val'"}, - {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, - {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', - "Size used to split data for encrypt pipelines"}, {"max_pipelines", OPT_MAX_PIPELINES, 'p', "Maximum number of encrypt/decrypt pipelines to be used"}, + {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, + {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, + + OPT_SECTION("Network"), + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, + {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, {"read_buf", OPT_READ_BUF, 'p', "Default read buffer size to be used for connections"}, - OPT_S_OPTIONS, - OPT_V_OPTIONS, - OPT_X_OPTIONS, - {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', + "Size used to split data for encrypt pipelines"}, + {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, + + OPT_SECTION("Server identity"), {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, #ifndef OPENSSL_NO_PSK {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, @@ -910,6 +924,19 @@ const OPTIONS s_server_options[] = { {"srpuserseed", OPT_SRPUSERSEED, 's', "A seed string for a default user salt"}, #endif + + OPT_SECTION("Protocol and version"), + {"max_early_data", OPT_MAX_EARLY, 'n', + "The maximum number of bytes of early data as advertised in tickets"}, + {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', + "The maximum number of bytes of early data (hard limit)"}, + {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, + {"num_tickets", OPT_S_NUM_TICKETS, 'n', + "The number of TLSv1.3 session tickets that a server will automatically issue" }, + {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, + {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, + {"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"}, + {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, #endif @@ -927,12 +954,9 @@ const OPTIONS s_server_options[] = { #endif #ifndef OPENSSL_NO_DTLS {"dtls", OPT_DTLS, '-', "Use any DTLS version"}, - {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, - {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, {"listen", OPT_LISTEN, '-', "Listen for a DTLS ClientHello with a cookie and then connect"}, #endif - {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, #ifndef OPENSSL_NO_DTLS1 {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, #endif @@ -943,34 +967,32 @@ const OPTIONS s_server_options[] = { {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif +#ifndef OPENSSL_NO_SRTP + {"use_srtp", OPT_SRTP_PROFILES, 's', + "Offer SRTP key management with a colon-separated profile list"}, +#endif #ifndef OPENSSL_NO_DH {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, #endif #ifndef OPENSSL_NO_NEXTPROTONEG {"nextprotoneg", OPT_NEXTPROTONEG, 's', "Set the advertised protocols for the NPN extension (comma-separated list)"}, -#endif -#ifndef OPENSSL_NO_SRTP - {"use_srtp", OPT_SRTP_PROFILES, 's', - "Offer SRTP key management with a colon-separated profile list"}, #endif {"alpn", OPT_ALPN, 's', "Set the advertised protocols for the ALPN extension (comma-separated list)"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif - {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, - {"max_early_data", OPT_MAX_EARLY, 'n', - "The maximum number of bytes of early data as advertised in tickets"}, - {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', - "The maximum number of bytes of early data (hard limit)"}, - {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, - {"num_tickets", OPT_S_NUM_TICKETS, 'n', - "The number of TLSv1.3 session tickets that a server will automatically issue" }, - {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, - {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, - {"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"}, - {NULL, OPT_EOF, 0, NULL} + + OPT_R_OPTIONS, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + {"cert_chain", OPT_CERT_CHAIN, '<', + "certificate chain file in PEM format"}, + {"dcert_chain", OPT_DCERT_CHAIN, '<', + "second certificate chain file in PEM format"}, + {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, + {"chainCAfile", OPT_CHAINCAFILE, '<', + "CA file for certificate chain (PEM format)"}, + OPT_X_OPTIONS, + {NULL} }; #define IS_PROT_FLAG(o) \ @@ -989,9 +1011,11 @@ int s_server_main(int argc, char *argv[]) STACK_OF(X509_CRL) *crls = NULL; X509 *s_cert = NULL, *s_dcert = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + const char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL; char *dpassarg = NULL, *dpass = NULL; - char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *passarg = NULL, *pass = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL; char *crl_file = NULL, *prog; #ifdef AF_UNIX int unlink_unix_path = 0; @@ -1003,14 +1027,14 @@ int s_server_main(int argc, char *argv[]) int no_dhe = 0; #endif int nocert = 0, ret = 1; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; int rev = 0, naccept = -1, sdebug = 0; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; int state = 0, crl_format = FORMAT_PEM, crl_download = 0; char *host = NULL; - char *port = BUF_strdup(PORT); + char *port = OPENSSL_strdup(PORT); unsigned char *context = NULL; OPTION_CHOICE o; EVP_PKEY *s_key2 = NULL; @@ -1159,7 +1183,7 @@ int s_server_main(int argc, char *argv[]) #ifdef AF_UNIX case OPT_UNIX: socket_family = AF_UNIX; - OPENSSL_free(host); host = BUF_strdup(opt_arg()); + OPENSSL_free(host); host = OPENSSL_strdup(opt_arg()); OPENSSL_free(port); port = NULL; break; case OPT_UNLINK: @@ -1261,6 +1285,18 @@ int s_server_main(int argc, char *argv[]) case OPT_VERIFYCAPATH: vfyCApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; + case OPT_CHAINCASTORE: + chCAstore = opt_arg(); + break; + case OPT_VERIFYCASTORE: + vfyCAstore = opt_arg(); + break; case OPT_NO_CACHE: no_cache = 1; break; @@ -1883,7 +1919,8 @@ int s_server_main(int argc, char *argv[]) } #endif - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -1895,7 +1932,9 @@ int s_server_main(int argc, char *argv[]) ssl_ctx_add_crls(ctx, crls, 0); - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + if (!ssl_load_stores(ctx, + vfyCApath, vfyCAfile, vfyCAstore, + chCApath, chCAfile, chCAstore, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1944,8 +1983,8 @@ int s_server_main(int argc, char *argv[]) if (async) SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC); - if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile, - noCApath)) { + if (!ctx_set_verify_locations(ctx2, CAfile, noCAfile, CApath, + noCApath, CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -2555,8 +2594,8 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) continue; } if (buf[0] == 'P') { - static const char *str = "Lets print some clear text\n"; - BIO_write(SSL_get_wbio(con), str, strlen(str)); + static const char str[] = "Lets print some clear text\n"; + BIO_write(SSL_get_wbio(con), str, sizeof(str) -1); } if (buf[0] == 'S') { print_stats(bio_s_out, SSL_get_SSL_CTX(con)); @@ -3214,6 +3253,12 @@ static int www_body(int s, int stype, int prot, unsigned char *context) if (e[0] == ' ') break; + if (e[0] == ':') { + /* Windows drive. We treat this the same way as ".." */ + dot = -1; + break; + } + switch (dot) { case 1: dot = (e[0] == '.') ? 2 : 0; @@ -3222,11 +3267,11 @@ static int www_body(int s, int stype, int prot, unsigned char *context) dot = (e[0] == '.') ? 3 : 0; break; case 3: - dot = (e[0] == '/') ? -1 : 0; + dot = (e[0] == '/' || e[0] == '\\') ? -1 : 0; break; } if (dot == 0) - dot = (e[0] == '/') ? 1 : 0; + dot = (e[0] == '/' || e[0] == '\\') ? 1 : 0; } dot = (dot == 3) || (dot == -1); /* filename contains ".." * component */ @@ -3240,11 +3285,11 @@ static int www_body(int s, int stype, int prot, unsigned char *context) if (dot) { BIO_puts(io, text); - BIO_printf(io, "'%s' contains '..' reference\r\n", p); + BIO_printf(io, "'%s' contains '..' or ':'\r\n", p); break; } - if (*p == '/') { + if (*p == '/' || *p == '\\') { BIO_puts(io, text); BIO_printf(io, "'%s' is an invalid path\r\n", p); break; @@ -3499,6 +3544,8 @@ static int generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int count = 0; + unsigned int session_id_prefix_len = strlen(session_id_prefix); + do { if (RAND_bytes(id, *id_len) <= 0) return 0; @@ -3510,8 +3557,8 @@ static int generate_session_id(SSL *ssl, unsigned char *id, * conflicts. */ memcpy(id, session_id_prefix, - (strlen(session_id_prefix) < *id_len) ? - strlen(session_id_prefix) : *id_len); + (session_id_prefix_len < *id_len) ? + session_id_prefix_len : *id_len); } while (SSL_has_matching_session_id(ssl, id, *id_len) && (++count < MAX_SESSION_ID_ATTEMPTS)); diff --git a/apps/s_time.c b/apps/s_time.c index f6dbfa04..d5816a1b 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -45,34 +45,25 @@ static const size_t fmt_http_get_cmd_size = sizeof(fmt_http_get_cmd) - 2; typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_CONNECT, OPT_CIPHER, OPT_CIPHERSUITES, OPT_CERT, OPT_NAMEOPT, OPT_KEY, - OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, - OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3, + OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, + OPT_NEW, OPT_REUSE, OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3, OPT_WWW, OPT_TLS1, OPT_TLS1_1, OPT_TLS1_2, OPT_TLS1_3 } OPTION_CHOICE; const OPTIONS s_time_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Connection"), {"connect", OPT_CONNECT, 's', "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"}, - {"cipher", OPT_CIPHER, 's', "TLSv1.2 and below cipher list to be used"}, - {"ciphersuites", OPT_CIPHERSUITES, 's', - "Specify TLSv1.3 ciphersuites to be used"}, - {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, - {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, - {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, {"new", OPT_NEW, '-', "Just time new connections"}, {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, - {"verify", OPT_VERIFY, 'p', - "Turn on peer certificate verification, set depth"}, - {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, - {"www", OPT_WWW, 's', "Fetch specified page from the site"}, + {"cipher", OPT_CIPHER, 's', "TLSv1.2 and below cipher list to be used"}, + {"ciphersuites", OPT_CIPHERSUITES, 's', + "Specify TLSv1.3 ciphersuites to be used"}, #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, #endif @@ -88,6 +79,25 @@ const OPTIONS s_time_options[] = { #ifndef OPENSSL_NO_TLS1_3 {"tls1_3", OPT_TLS1_3, '-', "Just use TLSv1.3"}, #endif + {"verify", OPT_VERIFY, 'p', + "Turn on peer certificate verification, set depth"}, + {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, + {"www", OPT_WWW, 's', "Fetch specified page from the site"}, + + OPT_SECTION("Certificate"), + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"}, + {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, + {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store URI"}, + {NULL} }; @@ -105,11 +115,12 @@ int s_time_main(int argc, char **argv) SSL *scon = NULL; SSL_CTX *ctx = NULL; const SSL_METHOD *meth = NULL; - char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL; + char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + char *cipher = NULL, *ciphersuites = NULL; char *www_path = NULL; char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; double totalTime = 0.0; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0; long bytes_read = 0, finishtime = 0; OPTION_CHOICE o; @@ -167,6 +178,12 @@ int s_time_main(int argc, char **argv) case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_CIPHER: cipher = opt_arg(); break; @@ -236,7 +253,8 @@ int s_time_main(int argc, char **argv) if (!set_cert_stuff(ctx, certfile, keyfile)) goto end; - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } diff --git a/apps/sess_id.c b/apps/sess_id.c index d8e18277..5183ea93 100644 --- a/apps/sess_id.c +++ b/apps/sess_id.c @@ -25,16 +25,21 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS sess_id_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"context", OPT_CONTEXT, 's', "Set the session ID context"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input file - default stdin"}, {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, {"outform", OPT_OUTFORM, 'f', "Output format - default PEM (PEM, DER or NSS)"}, - {"in", OPT_IN, 's', "Input file - default stdin"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, {"text", OPT_TEXT, '-', "Print ssl session id details"}, {"cert", OPT_CERT, '-', "Output certificate "}, {"noout", OPT_NOOUT, '-', "Don't output the encoded session info"}, - {"context", OPT_CONTEXT, 's', "Set the session ID context"}, {NULL} }; diff --git a/apps/smime.c b/apps/smime.c index 0f99e0a5..149d3151 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -41,71 +41,89 @@ typedef enum OPTION_choice { OPT_CRLFEOL, OPT_ENGINE, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD, OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE, + OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, OPT_NOCAPATH, OPT_NOCASTORE, OPT_R_ENUM, OPT_V_ENUM, - OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT, + OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTFORM, OPT_CONTENT } OPTION_CHOICE; const OPTIONS smime_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', - " cert.pem... recipient certs for encryption\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, - {"sign", OPT_SIGN, '-', "Sign message"}, - {"verify", OPT_VERIFY, '-', "Verify signed message"}, - {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, - {"nointern", OPT_NOINTERN, '-', - "Don't search certificates in message for signer"}, - {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, - {"nocerts", OPT_NOCERTS, '-', - "Don't include signers certificate when signing"}, - {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, - {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, - {"binary", OPT_BINARY, '-', "Don't translate message to text"}, - {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, - {"signer", OPT_SIGNER, 's', "Signer certificate file"}, - {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"}, {"in", OPT_IN, '<', "Input file"}, {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, - {"inkey", OPT_INKEY, 's', - "Input private key (if not signer or recipient)"}, - {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, {"out", OPT_OUT, '>', "Output file"}, {"outform", OPT_OUTFORM, 'c', "Output format SMIME (default), PEM or DER"}, + {"inkey", OPT_INKEY, 's', + "Input private key (if not signer or recipient)"}, + {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"stream", OPT_STREAM, '-', "Enable CMS streaming" }, + {"indef", OPT_INDEF, '-', "Same as -stream" }, + {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, + + OPT_SECTION("Action"), + {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, + {"sign", OPT_SIGN, '-', "Sign message"}, + {"resign", OPT_RESIGN, '-', "Resign a signed message"}, + {"verify", OPT_VERIFY, '-', "Verify signed message"}, + + OPT_SECTION("Signing/Encryption"), + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, + {"nointern", OPT_NOINTERN, '-', + "Don't search certificates in message for signer"}, + {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, + {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, + {"binary", OPT_BINARY, '-', "Don't translate message to text"}, + {"signer", OPT_SIGNER, 's', "Signer certificate file"}, {"content", OPT_CONTENT, '<', "Supply or override content for detached signature"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signers certificate when signing"}, + + OPT_SECTION("Verification/Decryption"), + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + + {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, + {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"}, + + OPT_SECTION("Email"), {"to", OPT_TO, 's', "To address"}, {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, + + OPT_SECTION("Certificate chain"), {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"}, {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"resign", OPT_RESIGN, '-', "Resign a signed message"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, {"nochain", OPT_NOCHAIN, '-', "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" }, - {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, - {"stream", OPT_STREAM, '-', "Enable CMS streaming" }, - {"indef", OPT_INDEF, '-', "Same as -stream" }, - {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"}, + OPT_R_OPTIONS, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, OPT_V_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PARAMETERS(), + {"cert", 0, 0, "Recipient certs, used when encrypting"}, {NULL} }; @@ -121,12 +139,12 @@ int smime_main(int argc, char **argv) X509_VERIFY_PARAM *vpm = NULL; const EVP_CIPHER *cipher = NULL; const EVP_MD *sign_md = NULL; - const char *CAfile = NULL, *CApath = NULL, *prog = NULL; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL; char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL; OPTION_CHOICE o; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform = FORMAT_PEM; @@ -302,12 +320,18 @@ int smime_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_CONTENT: contfile = opt_arg(); break; @@ -473,7 +497,8 @@ int smime_main(int argc, char **argv) goto end; if (operation == SMIME_VERIFY) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, smime_cb); if (vpmtouched) diff --git a/apps/speed.c b/apps/speed.c index 9d7bff0c..d741f315 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -17,6 +17,9 @@ #define EdDSA_SECONDS 10 #define SM2_SECONDS 10 +/* We need to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include @@ -41,7 +44,9 @@ #ifndef OPENSSL_NO_DES # include #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 #include +#endif #ifndef OPENSSL_NO_CAMELLIA # include #endif @@ -133,72 +138,9 @@ typedef struct openssl_speed_sec_st { static volatile int run = 0; -static int mr = 0; +static int mr = 0; /* machine-readeable output format to merge fork results */ static int usertime = 1; -#ifndef OPENSSL_NO_MD2 -static int EVP_Digest_MD2_loop(void *args); -#endif - -#ifndef OPENSSL_NO_MDC2 -static int EVP_Digest_MDC2_loop(void *args); -#endif -#ifndef OPENSSL_NO_MD4 -static int EVP_Digest_MD4_loop(void *args); -#endif -#ifndef OPENSSL_NO_MD5 -static int MD5_loop(void *args); -static int HMAC_loop(void *args); -#endif -static int SHA1_loop(void *args); -static int SHA256_loop(void *args); -static int SHA512_loop(void *args); -#ifndef OPENSSL_NO_WHIRLPOOL -static int WHIRLPOOL_loop(void *args); -#endif -#ifndef OPENSSL_NO_RMD160 -static int EVP_Digest_RMD160_loop(void *args); -#endif -#ifndef OPENSSL_NO_RC4 -static int RC4_loop(void *args); -#endif -#ifndef OPENSSL_NO_DES -static int DES_ncbc_encrypt_loop(void *args); -static int DES_ede3_cbc_encrypt_loop(void *args); -#endif -static int AES_cbc_128_encrypt_loop(void *args); -static int AES_cbc_192_encrypt_loop(void *args); -static int AES_cbc_256_encrypt_loop(void *args); -#if !OPENSSL_API_3 -static int AES_ige_128_encrypt_loop(void *args); -static int AES_ige_192_encrypt_loop(void *args); -static int AES_ige_256_encrypt_loop(void *args); -#endif -static int CRYPTO_gcm128_aad_loop(void *args); -static int RAND_bytes_loop(void *args); -static int EVP_Update_loop(void *args); -static int EVP_Update_loop_ccm(void *args); -static int EVP_Update_loop_aead(void *args); -static int EVP_Digest_loop(void *args); -#ifndef OPENSSL_NO_RSA -static int RSA_sign_loop(void *args); -static int RSA_verify_loop(void *args); -#endif -#ifndef OPENSSL_NO_DSA -static int DSA_sign_loop(void *args); -static int DSA_verify_loop(void *args); -#endif -#ifndef OPENSSL_NO_EC -static int ECDSA_sign_loop(void *args); -static int ECDSA_verify_loop(void *args); -static int EdDSA_sign_loop(void *args); -static int EdDSA_verify_loop(void *args); -# ifndef OPENSSL_NO_SM2 -static int SM2_sign_loop(void *args); -static int SM2_verify_loop(void *args); -# endif -#endif - static double Time_F(int s); static void print_message(const char *s, long num, int length, int tm); static void pkey_print_message(const char *str, const char *str2, @@ -211,6 +153,7 @@ static int do_multi(int multi, int size_num); static const int lengths_list[] = { 16, 64, 256, 1024, 8 * 1024, 16 * 1024 }; +#define SIZE_NUM OSSL_NELEM(lengths_list) static const int *lengths = lengths_list; static const int aead_lengths_list[] = { @@ -292,8 +235,6 @@ static double Time_F(int s) static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, const openssl_speed_sec_t *seconds); -#define found(value, pairs, result)\ - opt_found(value, result, pairs, OSSL_NELEM(pairs)) static int opt_found(const char *name, unsigned int *result, const OPT_PAIR pairs[], unsigned int nbelem) { @@ -306,6 +247,8 @@ static int opt_found(const char *name, unsigned int *result, } return 0; } +#define opt_found(value, pairs, result)\ + opt_found(value, result, pairs, OSSL_NELEM(pairs)) typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -315,18 +258,10 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS speed_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, - {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"}, -#ifndef OPENSSL_NO_CMAC - {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"}, -#endif - {"decrypt", OPT_DECRYPT, '-', - "Time decryption instead of encryption (only EVP)"}, - {"aead", OPT_AEAD, '-', - "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, {"mb", OPT_MB, '-', "Enable (tls1>=1) multi-block mode on EVP-named cipher"}, {"mr", OPT_MR, '-', "Produce machine readable output"}, @@ -337,58 +272,51 @@ const OPTIONS speed_options[] = { {"async_jobs", OPT_ASYNCJOBS, 'p', "Enable async mode and start specified number of jobs"}, #endif - OPT_R_OPTIONS, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"}, + + OPT_SECTION("Selection"), + {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, + {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"}, +#ifndef OPENSSL_NO_CMAC + {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"}, +#endif + {"decrypt", OPT_DECRYPT, '-', + "Time decryption instead of encryption (only EVP)"}, + {"aead", OPT_AEAD, '-', + "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, + + OPT_SECTION("Timing"), {"elapsed", OPT_ELAPSED, '-', "Use wall-clock time instead of CPU user time as divisor"}, - {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"}, {"seconds", OPT_SECONDS, 'p', "Run benchmarks for specified amount of seconds"}, {"bytes", OPT_BYTES, 'p', "Run [non-PKI] benchmarks on custom-sized buffer"}, {"misalign", OPT_MISALIGN, 'p', "Use specified offset to mis-align buffers"}, + + OPT_R_OPTIONS, + + OPT_PARAMETERS(), + {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"}, {NULL} }; -#define D_MD2 0 -#define D_MDC2 1 -#define D_MD4 2 -#define D_MD5 3 -#define D_HMAC 4 -#define D_SHA1 5 -#define D_RMD160 6 -#define D_RC4 7 -#define D_CBC_DES 8 -#define D_EDE3_DES 9 -#define D_CBC_IDEA 10 -#define D_CBC_SEED 11 -#define D_CBC_RC2 12 -#define D_CBC_RC5 13 -#define D_CBC_BF 14 -#define D_CBC_CAST 15 -#define D_CBC_128_AES 16 -#define D_CBC_192_AES 17 -#define D_CBC_256_AES 18 -#define D_CBC_128_CML 19 -#define D_CBC_192_CML 20 -#define D_CBC_256_CML 21 -#define D_EVP 22 -#define D_SHA256 23 -#define D_SHA512 24 -#define D_WHIRLPOOL 25 -#define D_IGE_128_AES 26 -#define D_IGE_192_AES 27 -#define D_IGE_256_AES 28 -#define D_GHASH 29 -#define D_RAND 30 -#define D_EVP_HMAC 31 -#define D_EVP_CMAC 32 - -/* name of algorithms to test */ -static const char *names[] = { +enum { + D_MD2, D_MDC2, D_MD4, D_MD5 , D_HMAC, D_SHA1, D_RMD160, D_RC4, + D_CBC_DES, D_EDE3_DES, D_CBC_IDEA, D_CBC_SEED, + D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST, + D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES, + D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML, + D_EVP, D_SHA256, D_SHA512, D_WHIRLPOOL, + D_IGE_128_AES, D_IGE_192_AES, D_IGE_256_AES, + D_GHASH, D_RAND, D_EVP_HMAC, D_EVP_CMAC, ALGOR_NUM +}; +/* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */ +static const char *names[ALGOR_NUM] = { "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4", "des cbc", "des ede3", "idea cbc", "seed cbc", "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc", @@ -398,17 +326,16 @@ static const char *names[] = { "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash", "rand", "hmac", "cmac" }; -#define ALGOR_NUM OSSL_NELEM(names) -/* list of configured algorithm (remaining) */ +/* list of configured algorithm (remaining), with some few alias */ static const OPT_PAIR doit_choices[] = { -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_MD2) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"md2", D_MD2}, #endif -#ifndef OPENSSL_NO_MDC2 +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"mdc2", D_MDC2}, #endif -#ifndef OPENSSL_NO_MD4 +#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"md4", D_MD4}, #endif #ifndef OPENSSL_NO_MD5 @@ -418,34 +345,34 @@ static const OPT_PAIR doit_choices[] = { {"sha1", D_SHA1}, {"sha256", D_SHA256}, {"sha512", D_SHA512}, -#ifndef OPENSSL_NO_WHIRLPOOL +#if !defined(OPENSSL_NO_WHIRLPOOL) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"whirlpool", D_WHIRLPOOL}, #endif -#ifndef OPENSSL_NO_RMD160 +#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"ripemd", D_RMD160}, {"rmd160", D_RMD160}, {"ripemd160", D_RMD160}, #endif -#ifndef OPENSSL_NO_RC4 +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"rc4", D_RC4}, #endif #ifndef OPENSSL_NO_DES {"des-cbc", D_CBC_DES}, {"des-ede3", D_EDE3_DES}, #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 {"aes-128-cbc", D_CBC_128_AES}, {"aes-192-cbc", D_CBC_192_AES}, {"aes-256-cbc", D_CBC_256_AES}, -#if !OPENSSL_API_3 {"aes-128-ige", D_IGE_128_AES}, {"aes-192-ige", D_IGE_192_AES}, {"aes-256-ige", D_IGE_256_AES}, #endif -#ifndef OPENSSL_NO_RC2 +#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"rc2-cbc", D_CBC_RC2}, {"rc2", D_CBC_RC2}, #endif -#ifndef OPENSSL_NO_RC5 +#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"rc5-cbc", D_CBC_RC5}, {"rc5", D_CBC_RC5}, #endif @@ -453,16 +380,16 @@ static const OPT_PAIR doit_choices[] = { {"idea-cbc", D_CBC_IDEA}, {"idea", D_CBC_IDEA}, #endif -#ifndef OPENSSL_NO_SEED +#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"seed-cbc", D_CBC_SEED}, {"seed", D_CBC_SEED}, #endif -#ifndef OPENSSL_NO_BF +#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"bf-cbc", D_CBC_BF}, {"blowfish", D_CBC_BF}, {"bf", D_CBC_BF}, #endif -#ifndef OPENSSL_NO_CAST +#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"cast-cbc", D_CBC_CAST}, {"cast", D_CBC_CAST}, {"cast5", D_CBC_CAST}, @@ -471,31 +398,24 @@ static const OPT_PAIR doit_choices[] = { {"rand", D_RAND} }; -static double results[ALGOR_NUM][OSSL_NELEM(lengths_list)]; +static double results[ALGOR_NUM][SIZE_NUM]; #ifndef OPENSSL_NO_DSA -# define R_DSA_512 0 -# define R_DSA_1024 1 -# define R_DSA_2048 2 -static const OPT_PAIR dsa_choices[] = { +enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM }; +static const OPT_PAIR dsa_choices[DSA_NUM] = { {"dsa512", R_DSA_512}, {"dsa1024", R_DSA_1024}, {"dsa2048", R_DSA_2048} }; -# define DSA_NUM OSSL_NELEM(dsa_choices) - static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */ #endif /* OPENSSL_NO_DSA */ -#define R_RSA_512 0 -#define R_RSA_1024 1 -#define R_RSA_2048 2 -#define R_RSA_3072 3 -#define R_RSA_4096 4 -#define R_RSA_7680 5 -#define R_RSA_15360 6 #ifndef OPENSSL_NO_RSA -static const OPT_PAIR rsa_choices[] = { +enum { + R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680, + R_RSA_15360, RSA_NUM +}; +static const OPT_PAIR rsa_choices[RSA_NUM] = { {"rsa512", R_RSA_512}, {"rsa1024", R_RSA_1024}, {"rsa2048", R_RSA_2048}, @@ -504,42 +424,22 @@ static const OPT_PAIR rsa_choices[] = { {"rsa7680", R_RSA_7680}, {"rsa15360", R_RSA_15360} }; -# define RSA_NUM OSSL_NELEM(rsa_choices) static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ #endif /* OPENSSL_NO_RSA */ -enum { - R_EC_P160, - R_EC_P192, - R_EC_P224, - R_EC_P256, - R_EC_P384, - R_EC_P521, -#ifndef OPENSSL_NO_EC2M - R_EC_K163, - R_EC_K233, - R_EC_K283, - R_EC_K409, - R_EC_K571, - R_EC_B163, - R_EC_B233, - R_EC_B283, - R_EC_B409, - R_EC_B571, -#endif - R_EC_BRP256R1, - R_EC_BRP256T1, - R_EC_BRP384R1, - R_EC_BRP384T1, - R_EC_BRP512R1, - R_EC_BRP512T1, - R_EC_X25519, - R_EC_X448 -}; - #ifndef OPENSSL_NO_EC -static OPT_PAIR ecdsa_choices[] = { +enum ec_curves_t { + R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521, +# ifndef OPENSSL_NO_EC2M + R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571, + R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571, +# endif + R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1, + R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM +}; +/* list of ecdsa curves */ +static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = { {"ecdsap160", R_EC_P160}, {"ecdsap192", R_EC_P192}, {"ecdsap224", R_EC_P224}, @@ -565,11 +465,9 @@ static OPT_PAIR ecdsa_choices[] = { {"ecdsabrp512r1", R_EC_BRP512R1}, {"ecdsabrp512t1", R_EC_BRP512T1} }; -# define ECDSA_NUM OSSL_NELEM(ecdsa_choices) - -static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ - -static const OPT_PAIR ecdh_choices[] = { +enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM }; +/* list of ecdh curves, extension of |ecdsa_choices| list above */ +static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhp160", R_EC_P160}, {"ecdhp192", R_EC_P192}, {"ecdhp224", R_EC_P224}, @@ -597,29 +495,25 @@ static const OPT_PAIR ecdh_choices[] = { {"ecdhx25519", R_EC_X25519}, {"ecdhx448", R_EC_X448} }; -# define EC_NUM OSSL_NELEM(ecdh_choices) -static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ +static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ +static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ -#define R_EC_Ed25519 0 -#define R_EC_Ed448 1 -static OPT_PAIR eddsa_choices[] = { +enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM }; +static const OPT_PAIR eddsa_choices[EdDSA_NUM] = { {"ed25519", R_EC_Ed25519}, {"ed448", R_EC_Ed448} -}; -# define EdDSA_NUM OSSL_NELEM(eddsa_choices) +}; static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */ # ifndef OPENSSL_NO_SM2 -# define R_EC_CURVESM2 0 -static OPT_PAIR sm2_choices[] = { +enum { R_EC_CURVESM2, SM2_NUM }; +static const OPT_PAIR sm2_choices[SM2_NUM] = { {"curveSM2", R_EC_CURVESM2} }; # define SM2_ID "TLSv1.3+GM+Cipher+Suite" # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1 -# define SM2_NUM OSSL_NELEM(sm2_choices) - static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */ # endif /* OPENSSL_NO_SM2 */ #endif /* OPENSSL_NO_EC */ @@ -674,9 +568,9 @@ static int run_benchmark(int async_jobs, int (*loop_function) (void *), static unsigned int testnum; /* Nb of iterations to do per algorithm and key-size */ -static long c[ALGOR_NUM][OSSL_NELEM(lengths_list)]; +static long c[ALGOR_NUM][SIZE_NUM]; -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_MD2) && !defined(OPENSSL_NO_DEPRECATED_3_0) static int EVP_Digest_MD2_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -693,7 +587,7 @@ static int EVP_Digest_MD2_loop(void *args) } #endif -#ifndef OPENSSL_NO_MDC2 +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) static int EVP_Digest_MDC2_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -710,7 +604,7 @@ static int EVP_Digest_MDC2_loop(void *args) } #endif -#ifndef OPENSSL_NO_MD4 +#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0) static int EVP_Digest_MD4_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -789,7 +683,7 @@ static int SHA512_loop(void *args) return count; } -#ifndef OPENSSL_NO_WHIRLPOOL +#if !defined(OPENSSL_NO_WHIRLPOOL) && !defined(OPENSSL_NO_DEPRECATED_3_0) static int WHIRLPOOL_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -802,7 +696,7 @@ static int WHIRLPOOL_loop(void *args) } #endif -#ifndef OPENSSL_NO_RMD160 +#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0) static int EVP_Digest_RMD160_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -818,7 +712,7 @@ static int EVP_Digest_RMD160_loop(void *args) } #endif -#ifndef OPENSSL_NO_RC4 +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) static RC4_KEY rc4_ks; static int RC4_loop(void *args) { @@ -833,16 +727,14 @@ static int RC4_loop(void *args) #ifndef OPENSSL_NO_DES static unsigned char DES_iv[8]; -static DES_key_schedule sch; -static DES_key_schedule sch2; -static DES_key_schedule sch3; +static DES_key_schedule sch[3]; static int DES_ncbc_encrypt_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; int count; for (count = 0; COND(c[D_CBC_DES][testnum]); count++) - DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch, + DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch[0], &DES_iv, DES_ENCRYPT); return count; } @@ -854,7 +746,7 @@ static int DES_ede3_cbc_encrypt_loop(void *args) int count; for (count = 0; COND(c[D_EDE3_DES][testnum]); count++) DES_ede3_cbc_encrypt(buf, buf, lengths[testnum], - &sch, &sch2, &sch3, &DES_iv, DES_ENCRYPT); + &sch[0], &sch[1], &sch[2], &DES_iv, DES_ENCRYPT); return count; } #endif @@ -862,6 +754,8 @@ static int DES_ede3_cbc_encrypt_loop(void *args) #define MAX_BLOCK_SIZE 128 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8]; + +#ifndef OPENSSL_NO_DEPRECATED_3_0 static AES_KEY aes_ks1, aes_ks2, aes_ks3; static int AES_cbc_128_encrypt_loop(void *args) { @@ -896,7 +790,6 @@ static int AES_cbc_256_encrypt_loop(void *args) return count; } -#if !OPENSSL_API_3 static int AES_ige_128_encrypt_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -932,7 +825,6 @@ static int AES_ige_256_encrypt_loop(void *args) (size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT); return count; } -#endif static int CRYPTO_gcm128_aad_loop(void *args) { @@ -944,6 +836,7 @@ static int CRYPTO_gcm128_aad_loop(void *args) CRYPTO_gcm128_aad(gcm_ctx, buf, lengths[testnum]); return count; } +#endif static int RAND_bytes_loop(void *args) { @@ -956,7 +849,6 @@ static int RAND_bytes_loop(void *args) return count; } -static long save_count = 0; static int decrypt = 0; static int EVP_Update_loop(void *args) { @@ -964,11 +856,9 @@ static int EVP_Update_loop(void *args) unsigned char *buf = tempargs->buf; EVP_CIPHER_CTX *ctx = tempargs->ctx; int outl, count, rc; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ @@ -976,7 +866,7 @@ static int EVP_Update_loop(void *args) } } } else { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ @@ -1003,11 +893,9 @@ static int EVP_Update_loop_ccm(void *args) EVP_CIPHER_CTX *ctx = tempargs->ctx; int outl, count; unsigned char tag[12]; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag); /* reset iv */ EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); @@ -1015,7 +903,7 @@ static int EVP_Update_loop_ccm(void *args) EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); } } else { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { /* restore iv length field */ EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); /* counter is reset on every update */ @@ -1042,11 +930,9 @@ static int EVP_Update_loop_aead(void *args) int outl, count; unsigned char aad[13] = { 0xcc }; unsigned char faketag[16] = { 0xcc }; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(faketag), faketag); @@ -1055,7 +941,7 @@ static int EVP_Update_loop_aead(void *args) EVP_DecryptFinal_ex(ctx, buf + outl, &outl); } } else { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); @@ -1072,11 +958,8 @@ static int EVP_Digest_loop(void *args) unsigned char *buf = tempargs->buf; unsigned char md[EVP_MAX_MD_SIZE]; int count; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { if (!EVP_Digest(buf, lengths[testnum], md, NULL, evp_md, NULL)) return -1; } @@ -1091,11 +974,8 @@ static int EVP_HMAC_loop(void *args) unsigned char *buf = tempargs->buf; unsigned char no_key[32]; int count; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP_HMAC][testnum]); count++) { if (HMAC(evp_hmac_md, no_key, sizeof(no_key), buf, lengths[testnum], NULL, NULL) == NULL) return -1; @@ -1116,11 +996,8 @@ static int EVP_CMAC_loop(void *args) unsigned char mac[16]; size_t len = sizeof(mac); int count; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP_CMAC][testnum]); count++) { if (!CMAC_Init(cmac_ctx, key, sizeof(key), evp_cmac_cipher, NULL) || !CMAC_Update(cmac_ctx, buf, lengths[testnum]) || !CMAC_Final(cmac_ctx, mac, &len)) @@ -1399,8 +1276,6 @@ static int run_benchmark(int async_jobs, OSSL_ASYNC_FD job_fd = 0; size_t num_job_fds = 0; - run = 1; - if (async_jobs == 0) { return loop_function((void *)&loopargs); } @@ -1542,6 +1417,9 @@ static int run_benchmark(int async_jobs, return error ? -1 : total_op_count; } +#define stop_it(do_it, test_num)\ + memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num); + int speed_main(int argc, char **argv) { ENGINE *e = NULL; @@ -1552,11 +1430,11 @@ int speed_main(int argc, char **argv) double d = 0.0; OPTION_CHOICE o; int async_init = 0, multiblock = 0, pr_header = 0; - int doit[ALGOR_NUM] = { 0 }; + uint8_t doit[ALGOR_NUM] = { 0 }; int ret = 1, misalign = 0, lengths_single = 0, aead = 0; long count = 0; - unsigned int size_num = OSSL_NELEM(lengths_list); - unsigned int i, k, loop, loopargs_len = 0, async_jobs = 0; + unsigned int size_num = SIZE_NUM; + unsigned int i, k, loopargs_len = 0, async_jobs = 0; int keylen; int buflen; #ifndef NO_FORK @@ -1571,28 +1449,29 @@ int speed_main(int argc, char **argv) EdDSA_SECONDS, SM2_SECONDS }; /* What follows are the buffers and key material. */ -#ifndef OPENSSL_NO_RC5 +#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) RC5_32_KEY rc5_ks; #endif -#ifndef OPENSSL_NO_RC2 +#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) RC2_KEY rc2_ks; #endif #ifndef OPENSSL_NO_IDEA IDEA_KEY_SCHEDULE idea_ks; #endif -#ifndef OPENSSL_NO_SEED +#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) SEED_KEY_SCHEDULE seed_ks; #endif -#ifndef OPENSSL_NO_BF +#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) BF_KEY bf_ks; #endif -#ifndef OPENSSL_NO_CAST +#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) CAST_KEY cast_ks; #endif static const unsigned char key16[16] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }; +#ifndef OPENSSL_NO_DEPRECATED_3_0 static const unsigned char key24[24] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, @@ -1604,62 +1483,45 @@ int speed_main(int argc, char **argv) 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 }; -#ifndef OPENSSL_NO_CAMELLIA - static const unsigned char ckey24[24] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; - static const unsigned char ckey32[32] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, - 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 - }; - CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3; #endif -#ifndef OPENSSL_NO_DES - static DES_cblock key = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 - }; - static DES_cblock key2 = { - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 - }; - static DES_cblock key3 = { - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; +#if !defined(OPENSSL_NO_CAMELLIA) && !defined(OPENSSL_NO_DEPRECATED_3_0) + CAMELLIA_KEY camellia_ks[3]; #endif #ifndef OPENSSL_NO_RSA - static const unsigned int rsa_bits[RSA_NUM] = { - 512, 1024, 2048, 3072, 4096, 7680, 15360 + static const struct { + const unsigned char *data; + unsigned int length; + unsigned int bits; + } rsa_keys[] = { + { test512, sizeof(test512), 512 }, + { test1024, sizeof(test1024), 1024 }, + { test2048, sizeof(test2048), 2048 }, + { test3072, sizeof(test3072), 3072 }, + { test4096, sizeof(test4096), 4092 }, + { test7680, sizeof(test7680), 7680 }, + { test15360, sizeof(test15360), 15360 } }; - static const unsigned char *rsa_data[RSA_NUM] = { - test512, test1024, test2048, test3072, test4096, test7680, test15360 - }; - static const int rsa_data_length[RSA_NUM] = { - sizeof(test512), sizeof(test1024), - sizeof(test2048), sizeof(test3072), - sizeof(test4096), sizeof(test7680), - sizeof(test15360) - }; - int rsa_doit[RSA_NUM] = { 0 }; + uint8_t rsa_doit[RSA_NUM] = { 0 }; int primes = RSA_DEFAULT_PRIME_NUM; #endif #ifndef OPENSSL_NO_DSA static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; - int dsa_doit[DSA_NUM] = { 0 }; + uint8_t dsa_doit[DSA_NUM] = { 0 }; #endif #ifndef OPENSSL_NO_EC - /* - * We only test over the following curves as they are representative, To - * add tests over more curves, simply add the curve NID and curve name to - * the following arrays and increase the |ecdh_choices| list accordingly. - */ - static const struct { + typedef struct ec_curve_st { const char *name; unsigned int nid; unsigned int bits; - } test_curves[] = { + size_t sigsize; /* only used for EdDSA curves */ + } EC_CURVE; + /* + * We only test over the following curves as they are representative, To + * add tests over more curves, simply add the curve NID and curve name to + * the following arrays and increase the |ecdh_choices| and |ecdsa_choices| + * lists accordingly. + */ + static const EC_CURVE ec_curves[EC_NUM] = { /* Prime Curves */ {"secp160r1", NID_secp160r1, 160}, {"nistp192", NID_X9_62_prime192v1, 192}, @@ -1690,33 +1552,36 @@ int speed_main(int argc, char **argv) {"X25519", NID_X25519, 253}, {"X448", NID_X448, 448} }; - static const struct { - const char *name; - unsigned int nid; - unsigned int bits; - size_t sigsize; - } test_ed_curves[] = { + static const EC_CURVE ed_curves[EdDSA_NUM] = { /* EdDSA */ {"Ed25519", NID_ED25519, 253, 64}, {"Ed448", NID_ED448, 456, 114} }; # ifndef OPENSSL_NO_SM2 - static const struct { - const char *name; - unsigned int nid; - unsigned int bits; - } test_sm2_curves[] = { + static const EC_CURVE sm2_curves[SM2_NUM] = { /* SM2 */ {"CurveSM2", NID_sm2, 256} }; + uint8_t sm2_doit[SM2_NUM] = { 0 }; +# endif + uint8_t ecdsa_doit[ECDSA_NUM] = { 0 }; + uint8_t ecdh_doit[EC_NUM] = { 0 }; + uint8_t eddsa_doit[EdDSA_NUM] = { 0 }; + + /* checks declarated curves against choices list. */ + OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448); + OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0); + + OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448); + OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0); + + OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1); + OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0); + +# ifndef OPENSSL_NO_SM2 + OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2); + OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0); # endif - int ecdsa_doit[ECDSA_NUM] = { 0 }; - int ecdh_doit[EC_NUM] = { 0 }; - int eddsa_doit[EdDSA_NUM] = { 0 }; - int sm2_doit[SM2_NUM] = { 0 }; - OPENSSL_assert(OSSL_NELEM(test_curves) >= EC_NUM); - OPENSSL_assert(OSSL_NELEM(test_ed_curves) >= EdDSA_NUM); - OPENSSL_assert(OSSL_NELEM(test_sm2_curves) >= SM2_NUM); #endif /* ndef OPENSSL_NO_EC */ prog = opt_init(argc, argv, speed_options); @@ -1847,95 +1712,101 @@ int speed_main(int argc, char **argv) /* Remaining arguments are algorithms. */ for (; *argv; argv++) { - if (found(*argv, doit_choices, &i)) { + const char *algo = *argv; + + if (opt_found(algo, doit_choices, &i)) { doit[i] = 1; continue; } #ifndef OPENSSL_NO_DES - if (strcmp(*argv, "des") == 0) { + if (strcmp(algo, "des") == 0) { doit[D_CBC_DES] = doit[D_EDE3_DES] = 1; continue; } #endif - if (strcmp(*argv, "sha") == 0) { + if (strcmp(algo, "sha") == 0) { doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1; continue; } #ifndef OPENSSL_NO_RSA - if (strcmp(*argv, "openssl") == 0) - continue; - if (strcmp(*argv, "rsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(rsa_doit); loop++) - rsa_doit[loop] = 1; - continue; - } - if (found(*argv, rsa_choices, &i)) { - rsa_doit[i] = 1; + if (strcmp(algo, "openssl") == 0) /* just for compatibility */ continue; + if (strncmp(algo, "rsa", 3) == 0) { + if (algo[3] == '\0') { + memset(rsa_doit, 1, sizeof(rsa_doit)); + continue; + } + if (opt_found(algo, rsa_choices, &i)) { + rsa_doit[i] = 1; + continue; + } } #endif #ifndef OPENSSL_NO_DSA - if (strcmp(*argv, "dsa") == 0) { - dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] = - dsa_doit[R_DSA_2048] = 1; - continue; - } - if (found(*argv, dsa_choices, &i)) { - dsa_doit[i] = 2; - continue; + if (strncmp(algo, "dsa", 3) == 0) { + if (algo[3] == '\0') { + memset(dsa_doit, 1, sizeof(dsa_doit)); + continue; + } + if (opt_found(algo, dsa_choices, &i)) { + dsa_doit[i] = 2; + continue; + } } #endif - if (strcmp(*argv, "aes") == 0) { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (strcmp(algo, "aes") == 0) { doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1; continue; } -#ifndef OPENSSL_NO_CAMELLIA - if (strcmp(*argv, "camellia") == 0) { +#endif +#if !defined(OPENSSL_NO_CAMELLIA) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (strcmp(algo, "camellia") == 0) { doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1; continue; } #endif #ifndef OPENSSL_NO_EC - if (strcmp(*argv, "ecdsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) - ecdsa_doit[loop] = 1; + if (strncmp(algo, "ecdsa", 5) == 0) { + if (algo[5] == '\0') { + memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); + continue; + } + if (opt_found(algo, ecdsa_choices, &i)) { + ecdsa_doit[i] = 2; + continue; + } + } + if (strncmp(algo, "ecdh", 4) == 0) { + if (algo[4] == '\0') { + memset(ecdh_doit, 1, sizeof(ecdh_doit)); + continue; + } + if (opt_found(algo, ecdh_choices, &i)) { + ecdh_doit[i] = 2; + continue; + } + } + if (strcmp(algo, "eddsa") == 0) { + memset(eddsa_doit, 1, sizeof(eddsa_doit)); continue; } - if (found(*argv, ecdsa_choices, &i)) { - ecdsa_doit[i] = 2; - continue; - } - if (strcmp(*argv, "ecdh") == 0) { - for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) - ecdh_doit[loop] = 1; - continue; - } - if (found(*argv, ecdh_choices, &i)) { - ecdh_doit[i] = 2; - continue; - } - if (strcmp(*argv, "eddsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) - eddsa_doit[loop] = 1; - continue; - } - if (found(*argv, eddsa_choices, &i)) { + if (opt_found(algo, eddsa_choices, &i)) { eddsa_doit[i] = 2; continue; } # ifndef OPENSSL_NO_SM2 - if (strcmp(*argv, "sm2") == 0) { - for (loop = 0; loop < OSSL_NELEM(sm2_doit); loop++) - sm2_doit[loop] = 1; + if (strcmp(algo, "sm2") == 0) { + memset(sm2_doit, 1, sizeof(sm2_doit)); continue; } - if (found(*argv, sm2_choices, &i)) { + if (opt_found(algo, sm2_choices, &i)) { sm2_doit[i] = 2; continue; } # endif -#endif - BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv); +#endif /* OPENSSL_NO_EC */ + BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo); goto end; } @@ -2018,27 +1889,20 @@ int speed_main(int argc, char **argv) /* No parameters; turn on everything. */ if (argc == 0 && !doit[D_EVP] && !doit[D_EVP_HMAC] && !doit[D_EVP_CMAC]) { - for (i = 0; i < ALGOR_NUM; i++) - if (i != D_EVP && i != D_EVP_HMAC && i != D_EVP_CMAC) - doit[i] = 1; + memset(doit, 1, sizeof(doit)); + doit[D_EVP] = doit[D_EVP_HMAC] = doit[D_EVP_CMAC] = 0; #ifndef OPENSSL_NO_RSA - for (i = 0; i < RSA_NUM; i++) - rsa_doit[i] = 1; + memset(rsa_doit, 1, sizeof(rsa_doit)); #endif #ifndef OPENSSL_NO_DSA - for (i = 0; i < DSA_NUM; i++) - dsa_doit[i] = 1; + memset(dsa_doit, 1, sizeof(dsa_doit)); #endif #ifndef OPENSSL_NO_EC - for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) - ecdsa_doit[loop] = 1; - for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) - ecdh_doit[loop] = 1; - for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) - eddsa_doit[loop] = 1; + memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); + memset(ecdh_doit, 1, sizeof(ecdh_doit)); + memset(eddsa_doit, 1, sizeof(eddsa_doit)); # ifndef OPENSSL_NO_SM2 - for (loop = 0; loop < OSSL_NELEM(sm2_doit); loop++) - sm2_doit[loop] = 1; + memset(sm2_doit, 1, sizeof(sm2_doit)); # endif #endif } @@ -2058,11 +1922,10 @@ int speed_main(int argc, char **argv) break; } for (k = 0; k < RSA_NUM; k++) { - const unsigned char *p; + const unsigned char *p = rsa_keys[k].data; - p = rsa_data[k]; loopargs[i].rsa_key[k] = - d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]); + d2i_RSAPrivateKey(NULL, &p, rsa_keys[k].length); if (loopargs[i].rsa_key[k] == NULL) { BIO_printf(bio_err, "internal error loading RSA key number %d\n", k); @@ -2079,41 +1942,59 @@ int speed_main(int argc, char **argv) } #endif #ifndef OPENSSL_NO_DES - DES_set_key_unchecked(&key, &sch); - DES_set_key_unchecked(&key2, &sch2); - DES_set_key_unchecked(&key3, &sch3); + if (doit[D_CBC_DES] || doit[D_EDE3_DES]) { + static DES_cblock keys[] = { + { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }, /* keys[0] */ + { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }, /* keys[1] */ + { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 } /* keys[3] */ + }; + DES_set_key_unchecked(&keys[0], &sch[0]); + DES_set_key_unchecked(&keys[1], &sch[1]); + DES_set_key_unchecked(&keys[2], &sch[2]); + } #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 AES_set_encrypt_key(key16, 128, &aes_ks1); AES_set_encrypt_key(key24, 192, &aes_ks2); AES_set_encrypt_key(key32, 256, &aes_ks3); -#ifndef OPENSSL_NO_CAMELLIA - Camellia_set_key(key16, 128, &camellia_ks1); - Camellia_set_key(ckey24, 192, &camellia_ks2); - Camellia_set_key(ckey32, 256, &camellia_ks3); #endif -#ifndef OPENSSL_NO_IDEA - IDEA_set_encrypt_key(key16, &idea_ks); -#endif -#ifndef OPENSSL_NO_SEED - SEED_set_key(key16, &seed_ks); -#endif -#ifndef OPENSSL_NO_RC4 - RC4_set_key(&rc4_ks, 16, key16); -#endif -#ifndef OPENSSL_NO_RC2 - RC2_set_key(&rc2_ks, 16, key16, 128); -#endif -#ifndef OPENSSL_NO_RC5 - if (!RC5_32_set_key(&rc5_ks, 16, key16, 12)) { - BIO_printf(bio_err, "Failed setting RC5 key\n"); - goto end; +#if !defined(OPENSSL_NO_CAMELLIA) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) { + Camellia_set_key(key16, 128, &camellia_ks[0]); + Camellia_set_key(key24, 192, &camellia_ks[1]); + Camellia_set_key(key32, 256, &camellia_ks[2]); } #endif -#ifndef OPENSSL_NO_BF - BF_set_key(&bf_ks, 16, key16); +#ifndef OPENSSL_NO_IDEA + if (doit[D_CBC_IDEA]) + IDEA_set_encrypt_key(key16, &idea_ks); #endif -#ifndef OPENSSL_NO_CAST - CAST_set_key(&cast_ks, 16, key16); +#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_SEED]) + SEED_set_key(key16, &seed_ks); +#endif +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_RC4]) + RC4_set_key(&rc4_ks, 16, key16); +#endif +#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_RC2]) + RC2_set_key(&rc2_ks, 16, key16, 128); +#endif +#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_RC5]) + if (!RC5_32_set_key(&rc5_ks, 16, key16, 12)) { + BIO_printf(bio_err, "Failed setting RC5 key\n"); + goto end; + } +#endif +#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_BF]) + BF_set_key(&bf_ks, 16, key16); +#endif +#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) + if (doit[D_CBC_CAST]) + CAST_set_key(&cast_ks, 16, key16); #endif #ifndef SIGALRM # ifndef OPENSSL_NO_DES @@ -2128,7 +2009,6 @@ int speed_main(int argc, char **argv) (DES_cblock *)loopargs[0].buf, &sch, DES_ENCRYPT); d = Time_F(STOP); } while (d < 3); - save_count = count; c[D_MD2][0] = count / 10; c[D_MDC2][0] = count / 10; c[D_MD4][0] = count; @@ -2151,6 +2031,7 @@ int speed_main(int argc, char **argv) c[D_CBC_128_CML][0] = count; c[D_CBC_192_CML][0] = count; c[D_CBC_256_CML][0] = count; + c[D_EVP][0] = count; c[D_SHA256][0] = count; c[D_SHA512][0] = count; c[D_WHIRLPOOL][0] = count; @@ -2159,12 +2040,12 @@ int speed_main(int argc, char **argv) c[D_IGE_256_AES][0] = count; c[D_GHASH][0] = count; c[D_RAND][0] = count; + c[D_EVP_HMAC][0] = count; + c[D_EVP_CMAC][0] = count; for (i = 1; i < size_num; i++) { - long l0, l1; - - l0 = (long)lengths[0]; - l1 = (long)lengths[i]; + long l0 = (long)lengths[0]; + long l1 = (long)lengths[i]; c[D_MD2][i] = c[D_MD2][0] * 4 * l0 / l1; c[D_MDC2][i] = c[D_MDC2][0] * 4 * l0 / l1; @@ -2173,11 +2054,14 @@ int speed_main(int argc, char **argv) c[D_HMAC][i] = c[D_HMAC][0] * 4 * l0 / l1; c[D_SHA1][i] = c[D_SHA1][0] * 4 * l0 / l1; c[D_RMD160][i] = c[D_RMD160][0] * 4 * l0 / l1; + c[D_EVP][i] = = c[D_EVP][0] * 4 * l0 / l1; c[D_SHA256][i] = c[D_SHA256][0] * 4 * l0 / l1; c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1; c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1; c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1; c[D_RAND][i] = c[D_RAND][0] * 4 * l0 / l1; + c[D_EVP_HMAC][i] = = c[D_EVP_HMAC][0] * 4 * l0 / l1; + c[D_EVP_CMAC][i] = = c[D_EVP_CMAC][0] * 4 * l0 / l1; l0 = (long)lengths[i - 1]; @@ -2349,7 +2233,7 @@ int speed_main(int argc, char **argv) # ifndef OPENSSL_NO_SM2 sm2_c[R_EC_SM2P256][0] = count / 1800; # endif -# endif +# endif /* OPENSSL_NO_EC */ # else /* not worth fixing */ @@ -2359,7 +2243,7 @@ int speed_main(int argc, char **argv) signal(SIGALRM, alarmed); #endif /* SIGALRM */ -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_MD2) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_MD2]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum], @@ -2371,7 +2255,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_MDC2 +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_MDC2]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum], @@ -2380,11 +2264,13 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs); d = Time_F(STOP); print_result(D_MDC2, testnum, count, d); + if (count < 0) + break; } } #endif -#ifndef OPENSSL_NO_MD4 +#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_MD4]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum], @@ -2393,6 +2279,8 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs); d = Time_F(STOP); print_result(D_MD4, testnum, count, d); + if (count < 0) + break; } } #endif @@ -2430,9 +2318,8 @@ int speed_main(int argc, char **argv) d = Time_F(STOP); print_result(D_HMAC, testnum, count, d); } - for (i = 0; i < loopargs_len; i++) { + for (i = 0; i < loopargs_len; i++) HMAC_CTX_free(loopargs[i].hctx); - } } #endif if (doit[D_SHA1]) { @@ -2465,7 +2352,7 @@ int speed_main(int argc, char **argv) print_result(D_SHA512, testnum, count, d); } } -#ifndef OPENSSL_NO_WHIRLPOOL +#if !defined(OPENSSL_NO_WHIRLPOOL) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_WHIRLPOOL]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], @@ -2478,7 +2365,7 @@ int speed_main(int argc, char **argv) } #endif -#ifndef OPENSSL_NO_RMD160 +#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_RMD160]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_RMD160], c[D_RMD160][testnum], @@ -2487,10 +2374,12 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs); d = Time_F(STOP); print_result(D_RMD160, testnum, count, d); + if (count < 0) + break; } } #endif -#ifndef OPENSSL_NO_RC4 +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_RC4]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum], @@ -2527,6 +2416,7 @@ int speed_main(int argc, char **argv) } #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 if (doit[D_CBC_128_AES]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum], @@ -2561,7 +2451,7 @@ int speed_main(int argc, char **argv) } } -#if !OPENSSL_API_3 + if (doit[D_IGE_128_AES]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum], @@ -2595,7 +2485,6 @@ int speed_main(int argc, char **argv) print_result(D_IGE_256_AES, testnum, count, d); } } -#endif if (doit[D_GHASH]) { for (i = 0; i < loopargs_len; i++) { loopargs[i].gcm_ctx = @@ -2615,7 +2504,8 @@ int speed_main(int argc, char **argv) for (i = 0; i < loopargs_len; i++) CRYPTO_gcm128_release(loopargs[i].gcm_ctx); } -#ifndef OPENSSL_NO_CAMELLIA +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ +#if !defined(OPENSSL_NO_CAMELLIA) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_128_CML]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2626,9 +2516,9 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_128_CML][testnum]); count++) + for (count = 0; COND(c[D_CBC_128_CML][testnum]); count++) Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks1, + (size_t)lengths[testnum], &camellia_ks[0], iv, CAMELLIA_ENCRYPT); d = Time_F(STOP); print_result(D_CBC_128_CML, testnum, count, d); @@ -2648,9 +2538,9 @@ int speed_main(int argc, char **argv) exit(1); } Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_192_CML][testnum]); count++) + for (count = 0; COND(c[D_CBC_192_CML][testnum]); count++) Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks2, + (size_t)lengths[testnum], &camellia_ks[1], iv, CAMELLIA_ENCRYPT); d = Time_F(STOP); print_result(D_CBC_192_CML, testnum, count, d); @@ -2666,9 +2556,9 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_256_CML][testnum]); count++) + for (count = 0; COND(c[D_CBC_256_CML][testnum]); count++) Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks3, + (size_t)lengths[testnum], &camellia_ks[2], iv, CAMELLIA_ENCRYPT); d = Time_F(STOP); print_result(D_CBC_256_CML, testnum, count, d); @@ -2686,7 +2576,7 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_IDEA][testnum]); count++) + for (count = 0; COND(c[D_CBC_IDEA][testnum]); count++) IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &idea_ks, iv, IDEA_ENCRYPT); @@ -2695,7 +2585,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_SEED +#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_SEED]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2706,7 +2596,7 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_SEED][testnum]); count++) + for (count = 0; COND(c[D_CBC_SEED][testnum]); count++) SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &seed_ks, iv, 1); d = Time_F(STOP); @@ -2714,7 +2604,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_RC2 +#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_RC2]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2729,7 +2619,7 @@ int speed_main(int argc, char **argv) exit(1); } Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_RC2][testnum]); count++) + for (count = 0; COND(c[D_CBC_RC2][testnum]); count++) RC2_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &rc2_ks, iv, RC2_ENCRYPT); @@ -2738,7 +2628,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_RC5 +#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_RC5]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2753,7 +2643,7 @@ int speed_main(int argc, char **argv) exit(1); } Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_RC5][testnum]); count++) + for (count = 0; COND(c[D_CBC_RC5][testnum]); count++) RC5_32_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &rc5_ks, iv, RC5_ENCRYPT); @@ -2762,7 +2652,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_BF +#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_BF]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2773,7 +2663,7 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_BF][testnum]); count++) + for (count = 0; COND(c[D_CBC_BF][testnum]); count++) BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &bf_ks, iv, BF_ENCRYPT); @@ -2782,7 +2672,7 @@ int speed_main(int argc, char **argv) } } #endif -#ifndef OPENSSL_NO_CAST +#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (doit[D_CBC_CAST]) { if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with %s\n", @@ -2793,7 +2683,7 @@ int speed_main(int argc, char **argv) print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], lengths[testnum], seconds.sym); Time_F(START); - for (count = 0, run = 1; COND(c[D_CBC_CAST][testnum]); count++) + for (count = 0; COND(c[D_CBC_CAST][testnum]); count++) CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, (size_t)lengths[testnum], &cast_ks, iv, CAST_ENCRYPT); @@ -2815,7 +2705,7 @@ int speed_main(int argc, char **argv) if (doit[D_EVP]) { if (evp_cipher != NULL) { - int (*loopfunc)(void *args) = EVP_Update_loop; + int (*loopfunc) (void *) = EVP_Update_loop; if (multiblock && (EVP_CIPHER_flags(evp_cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { @@ -2838,7 +2728,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], save_count, lengths[testnum], + print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], seconds.sym); for (k = 0; k < loopargs_len; k++) { @@ -2884,7 +2774,7 @@ int speed_main(int argc, char **argv) names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md)); for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], save_count, lengths[testnum], + print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs); @@ -2894,52 +2784,50 @@ int speed_main(int argc, char **argv) } } - if (doit[D_EVP_HMAC]) { - if (evp_hmac_md != NULL) { - const char *md_name = OBJ_nid2ln(EVP_MD_type(evp_hmac_md)); - evp_hmac_name = app_malloc(sizeof("HMAC()") + strlen(md_name), - "HMAC name"); - sprintf(evp_hmac_name, "HMAC(%s)", md_name); - names[D_EVP_HMAC] = evp_hmac_name; + if (doit[D_EVP_HMAC] && evp_hmac_md != NULL) { + const char *md_name = OBJ_nid2ln(EVP_MD_type(evp_hmac_md)); - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP_HMAC], save_count, lengths[testnum], - seconds.sym); - Time_F(START); - count = run_benchmark(async_jobs, EVP_HMAC_loop, loopargs); - d = Time_F(STOP); - print_result(D_EVP_HMAC, testnum, count, d); - } + evp_hmac_name = app_malloc(sizeof("HMAC()") + strlen(md_name), + "HMAC name"); + sprintf(evp_hmac_name, "HMAC(%s)", md_name); + names[D_EVP_HMAC] = evp_hmac_name; + + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_EVP_HMAC], c[D_EVP_HMAC][testnum], lengths[testnum], + seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, EVP_HMAC_loop, loopargs); + d = Time_F(STOP); + print_result(D_EVP_HMAC, testnum, count, d); } } #ifndef OPENSSL_NO_CMAC - if (doit[D_EVP_CMAC]) { - if (evp_cmac_cipher != NULL) { - const char *cipher_name = OBJ_nid2ln(EVP_CIPHER_type(evp_cmac_cipher)); - evp_cmac_name = app_malloc(sizeof("CMAC()") + strlen(cipher_name), - "CMAC name"); - sprintf(evp_cmac_name, "CMAC(%s)", cipher_name); - names[D_EVP_CMAC] = evp_cmac_name; + if (doit[D_EVP_CMAC] && evp_cmac_cipher != NULL) { + const char *cipher_name = OBJ_nid2ln(EVP_CIPHER_type(evp_cmac_cipher)); - for (i = 0; i < loopargs_len; i++) { - loopargs[i].cmac_ctx = CMAC_CTX_new(); - if (loopargs[i].cmac_ctx == NULL) { - BIO_printf(bio_err, "CMAC malloc failure, exiting..."); - exit(1); - } + evp_cmac_name = app_malloc(sizeof("CMAC()") + strlen(cipher_name), + "CMAC name"); + sprintf(evp_cmac_name, "CMAC(%s)", cipher_name); + names[D_EVP_CMAC] = evp_cmac_name; + + for (i = 0; i < loopargs_len; i++) { + loopargs[i].cmac_ctx = CMAC_CTX_new(); + if (loopargs[i].cmac_ctx == NULL) { + BIO_printf(bio_err, "CMAC malloc failure, exiting..."); + exit(1); } - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP_CMAC], save_count, lengths[testnum], - seconds.sym); - Time_F(START); - count = run_benchmark(async_jobs, EVP_CMAC_loop, loopargs); - d = Time_F(STOP); - print_result(D_EVP_CMAC, testnum, count, d); - } - for (i = 0; i < loopargs_len; i++) - CMAC_CTX_free(loopargs[i].cmac_ctx); } + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum], lengths[testnum], + seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, EVP_CMAC_loop, loopargs); + d = Time_F(STOP); + print_result(D_EVP_CMAC, testnum, count, d); + } + for (i = 0; i < loopargs_len; i++) + CMAC_CTX_free(loopargs[i].cmac_ctx); } #endif @@ -2953,7 +2841,7 @@ int speed_main(int argc, char **argv) if (!rsa_doit[testnum]) continue; for (i = 0; i < loopargs_len; i++) { - if (primes > 2) { + if (primes > RSA_DEFAULT_PRIME_NUM) { /* we haven't set keys yet, generate multi-prime RSA keys */ BIGNUM *bn = BN_new(); @@ -2974,7 +2862,7 @@ int speed_main(int argc, char **argv) } if (!RSA_generate_multi_prime_key(loopargs[i].rsa_key[testnum], - rsa_bits[testnum], + rsa_keys[testnum].bits, primes, bn, NULL)) { BN_free(bn); goto end; @@ -2993,7 +2881,7 @@ int speed_main(int argc, char **argv) rsa_count = 1; } else { pkey_print_message("private", "rsa", - rsa_c[testnum][0], rsa_bits[testnum], + rsa_c[testnum][0], rsa_keys[testnum].bits, seconds.rsa); /* RSA_blinding_on(rsa_key[testnum],NULL); */ Time_F(START); @@ -3002,7 +2890,7 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n" : "%ld %u bits private RSA's in %.2fs\n", - count, rsa_bits[testnum], d); + count, rsa_keys[testnum].bits, d); rsa_results[testnum][0] = (double)count / d; rsa_count = count; } @@ -3020,7 +2908,7 @@ int speed_main(int argc, char **argv) rsa_doit[testnum] = 0; } else { pkey_print_message("public", "rsa", - rsa_c[testnum][1], rsa_bits[testnum], + rsa_c[testnum][1], rsa_keys[testnum].bits, seconds.rsa); Time_F(START); count = run_benchmark(async_jobs, RSA_verify_loop, loopargs); @@ -3028,14 +2916,13 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n" : "%ld %u bits public RSA's in %.2fs\n", - count, rsa_bits[testnum], d); + count, rsa_keys[testnum].bits, d); rsa_results[testnum][1] = (double)count / d; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < RSA_NUM; testnum++) - rsa_doit[testnum] = 0; + stop_it(rsa_doit, testnum); } } #endif /* OPENSSL_NO_RSA */ @@ -3105,8 +2992,7 @@ int speed_main(int argc, char **argv) if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < DSA_NUM; testnum++) - dsa_doit[testnum] = 0; + stop_it(dsa_doit, testnum); } } #endif /* OPENSSL_NO_DSA */ @@ -3119,7 +3005,7 @@ int speed_main(int argc, char **argv) continue; /* Ignore Curve */ for (i = 0; i < loopargs_len; i++) { loopargs[i].ecdsa[testnum] = - EC_KEY_new_by_curve_name(test_curves[testnum].nid); + EC_KEY_new_by_curve_name(ec_curves[testnum].nid); if (loopargs[i].ecdsa[testnum] == NULL) { st = 0; break; @@ -3148,7 +3034,7 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("sign", "ecdsa", ecdsa_c[testnum][0], - test_curves[testnum].bits, seconds.ecdsa); + ec_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs); d = Time_F(STOP); @@ -3156,7 +3042,7 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R5:%ld:%u:%.2f\n" : "%ld %u bits ECDSA signs in %.2fs \n", - count, test_curves[testnum].bits, d); + count, ec_curves[testnum].bits, d); ecdsa_results[testnum][0] = (double)count / d; rsa_count = count; } @@ -3177,21 +3063,20 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("verify", "ecdsa", ecdsa_c[testnum][1], - test_curves[testnum].bits, seconds.ecdsa); + ec_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R6:%ld:%u:%.2f\n" : "%ld %u bits ECDSA verify in %.2fs\n", - count, test_curves[testnum].bits, d); + count, ec_curves[testnum].bits, d); ecdsa_results[testnum][1] = (double)count / d; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < ECDSA_NUM; testnum++) - ecdsa_doit[testnum] = 0; + stop_it(ecdsa_doit, testnum); } } } @@ -3224,7 +3109,7 @@ int speed_main(int argc, char **argv) * If this fails we try creating a EVP_PKEY_EC generic param ctx, * then we set the curve by NID before deriving the actual keygen * ctx for that specific curve. */ - kctx = EVP_PKEY_CTX_new_id(test_curves[testnum].nid, NULL); /* keygen ctx from NID */ + kctx = EVP_PKEY_CTX_new_id(ec_curves[testnum].nid, NULL); /* keygen ctx from NID */ if (!kctx) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *params = NULL; @@ -3247,13 +3132,13 @@ int speed_main(int argc, char **argv) break; } - if ( /* Create the context for parameter generation */ - !(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) || + /* Create the context for parameter generation */ + if (!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) || /* Initialise the parameter generation */ !EVP_PKEY_paramgen_init(pctx) || /* Set the curve by NID */ !EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, - test_curves + ec_curves [testnum].nid) || /* Create the parameter object params */ !EVP_PKEY_paramgen(pctx, ¶ms)) { @@ -3336,7 +3221,7 @@ int speed_main(int argc, char **argv) if (ecdh_checks != 0) { pkey_print_message("", "ecdh", ecdh_c[testnum][0], - test_curves[testnum].bits, seconds.ecdh); + ec_curves[testnum].bits, seconds.ecdh); Time_F(START); count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs); @@ -3344,15 +3229,14 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count, - test_curves[testnum].bits, d); + ec_curves[testnum].bits, d); ecdh_results[testnum][0] = (double)count / d; rsa_count = count; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < OSSL_NELEM(ecdh_doit); testnum++) - ecdh_doit[testnum] = 0; + stop_it(ecdh_doit, testnum); } } @@ -3370,7 +3254,7 @@ int speed_main(int argc, char **argv) break; } - if ((ed_pctx = EVP_PKEY_CTX_new_id(test_ed_curves[testnum].nid, NULL)) + if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid, NULL)) == NULL || EVP_PKEY_keygen_init(ed_pctx) <= 0 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) { @@ -3395,7 +3279,7 @@ int speed_main(int argc, char **argv) } else { for (i = 0; i < loopargs_len; i++) { /* Perform EdDSA signature test */ - loopargs[i].sigsize = test_ed_curves[testnum].sigsize; + loopargs[i].sigsize = ed_curves[testnum].sigsize; st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum], loopargs[i].buf2, &loopargs[i].sigsize, loopargs[i].buf, 20); @@ -3408,9 +3292,9 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); rsa_count = 1; } else { - pkey_print_message("sign", test_ed_curves[testnum].name, + pkey_print_message("sign", ed_curves[testnum].name, eddsa_c[testnum][0], - test_ed_curves[testnum].bits, seconds.eddsa); + ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs); d = Time_F(STOP); @@ -3418,8 +3302,8 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R8:%ld:%u:%s:%.2f\n" : "%ld %u bits %s signs in %.2fs \n", - count, test_ed_curves[testnum].bits, - test_ed_curves[testnum].name, d); + count, ed_curves[testnum].bits, + ed_curves[testnum].name, d); eddsa_results[testnum][0] = (double)count / d; rsa_count = count; } @@ -3438,24 +3322,23 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); eddsa_doit[testnum] = 0; } else { - pkey_print_message("verify", test_ed_curves[testnum].name, + pkey_print_message("verify", ed_curves[testnum].name, eddsa_c[testnum][1], - test_ed_curves[testnum].bits, seconds.eddsa); + ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R9:%ld:%u:%s:%.2f\n" : "%ld %u bits %s verify in %.2fs\n", - count, test_ed_curves[testnum].bits, - test_ed_curves[testnum].name, d); + count, ed_curves[testnum].bits, + ed_curves[testnum].name, d); eddsa_results[testnum][1] = (double)count / d; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < EdDSA_NUM; testnum++) - eddsa_doit[testnum] = 0; + stop_it(eddsa_doit, testnum); } } } @@ -3464,105 +3347,73 @@ int speed_main(int argc, char **argv) for (testnum = 0; testnum < SM2_NUM; testnum++) { int st = 1; EVP_PKEY *sm2_pkey = NULL; - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *sm2_pctx = NULL; - EVP_PKEY_CTX *sm2_vfy_pctx = NULL; - size_t sm2_sigsize = 0; if (!sm2_doit[testnum]) continue; /* Ignore Curve */ /* Init signing and verification */ 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(); - if (loopargs[i].sm2_ctx[testnum] == NULL) { - st = 0; - break; - } loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new(); - if (loopargs[i].sm2_vfy_ctx[testnum] == NULL) { - st = 0; + if (loopargs[i].sm2_ctx[testnum] == NULL + || loopargs[i].sm2_vfy_ctx[testnum] == NULL) break; - } /* SM2 keys are generated as normal EC keys with a special curve */ - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL + st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL || EVP_PKEY_keygen_init(pctx) <= 0 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, - test_sm2_curves[testnum].nid) <= 0 - || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0) { - st = 0; - EVP_PKEY_CTX_free(pctx); - break; - } - /* free previous one and alloc a new one */ + sm2_curves[testnum].nid) <= 0 + || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0); EVP_PKEY_CTX_free(pctx); - - loopargs[i].sigsize = sm2_sigsize - = ECDSA_size(EVP_PKEY_get0_EC_KEY(sm2_pkey)); - - if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2)) { - st = 0; - EVP_PKEY_free(sm2_pkey); + if (st == 0) + break; + + st = 0; /* set back to zero */ + /* attach it sooner to rely on main final cleanup */ + loopargs[i].sm2_pkey[testnum] = sm2_pkey; + loopargs[i].sigsize = ECDSA_size(EVP_PKEY_get0_EC_KEY(sm2_pkey)); + if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2)) break; - } sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); - if (sm2_pctx == NULL) { - st = 0; - EVP_PKEY_free(sm2_pkey); - break; - } sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); - if (sm2_vfy_pctx == NULL) { - st = 0; - EVP_PKEY_CTX_free(sm2_pctx); - EVP_PKEY_free(sm2_pkey); + if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) { + EVP_PKEY_CTX_free(sm2_vfy_pctx); break; } + /* attach them directly to respective ctx */ + EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx); + EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx); + /* * No need to allow user to set an explicit ID here, just use * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D. */ - if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1) { - st = 0; - EVP_PKEY_CTX_free(sm2_pctx); - EVP_PKEY_CTX_free(sm2_vfy_pctx); - EVP_PKEY_free(sm2_pkey); + if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1 + || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1) break; - } - - if (EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1) { - st = 0; - EVP_PKEY_CTX_free(sm2_pctx); - EVP_PKEY_CTX_free(sm2_vfy_pctx); - EVP_PKEY_free(sm2_pkey); - break; - } - - EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx); - EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx); if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL, - EVP_sm3(), NULL, sm2_pkey)) { - st = 0; - EVP_PKEY_free(sm2_pkey); + EVP_sm3(), NULL, sm2_pkey)) break; - } if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL, - EVP_sm3(), NULL, sm2_pkey)) { - st = 0; - EVP_PKEY_free(sm2_pkey); + EVP_sm3(), NULL, sm2_pkey)) break; - } - loopargs[i].sm2_pkey[testnum] = sm2_pkey; + st = 1; /* mark loop as succeeded */ } if (st == 0) { - BIO_printf(bio_err, "SM2 failure.\n"); + BIO_printf(bio_err, "SM2 init failure.\n"); ERR_print_errors(bio_err); rsa_count = 1; } else { for (i = 0; i < loopargs_len; i++) { - sm2_sigsize = loopargs[i].sigsize; + size_t sm2_sigsize = loopargs[i].sigsize; + /* Perform SM2 signature test */ st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum], loopargs[i].buf2, &sm2_sigsize, @@ -3576,9 +3427,9 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); rsa_count = 1; } else { - pkey_print_message("sign", test_sm2_curves[testnum].name, + pkey_print_message("sign", sm2_curves[testnum].name, sm2_c[testnum][0], - test_sm2_curves[testnum].bits, seconds.sm2); + sm2_curves[testnum].bits, seconds.sm2); Time_F(START); count = run_benchmark(async_jobs, SM2_sign_loop, loopargs); d = Time_F(STOP); @@ -3586,8 +3437,8 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R8:%ld:%u:%s:%.2f\n" : "%ld %u bits %s signs in %.2fs \n", - count, test_sm2_curves[testnum].bits, - test_sm2_curves[testnum].name, d); + count, sm2_curves[testnum].bits, + sm2_curves[testnum].name, d); sm2_results[testnum][0] = (double)count / d; rsa_count = count; } @@ -3606,17 +3457,17 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); sm2_doit[testnum] = 0; } else { - pkey_print_message("verify", test_sm2_curves[testnum].name, + pkey_print_message("verify", sm2_curves[testnum].name, sm2_c[testnum][1], - test_sm2_curves[testnum].bits, seconds.sm2); + sm2_curves[testnum].bits, seconds.sm2); Time_F(START); count = run_benchmark(async_jobs, SM2_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R9:%ld:%u:%s:%.2f\n" : "%ld %u bits %s verify in %.2fs\n", - count, test_sm2_curves[testnum].bits, - test_sm2_curves[testnum].name, d); + count, sm2_curves[testnum].bits, + sm2_curves[testnum].name, d); sm2_results[testnum][1] = (double)count / d; } @@ -3638,20 +3489,22 @@ int speed_main(int argc, char **argv) printf("built on: %s\n", OpenSSL_version(OPENSSL_BUILT_ON)); printf("options:"); printf("%s ", BN_options()); -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_MD2) && !defined(OPENSSL_NO_DEPRECATED_3_0) printf("%s ", MD2_options()); #endif -#ifndef OPENSSL_NO_RC4 +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) printf("%s ", RC4_options()); #endif #ifndef OPENSSL_NO_DES printf("%s ", DES_options()); #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 printf("%s ", AES_options()); +#endif #ifndef OPENSSL_NO_IDEA printf("%s ", IDEA_options()); #endif -#ifndef OPENSSL_NO_BF +#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) printf("%s ", BF_options()); #endif printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS)); @@ -3697,10 +3550,10 @@ int speed_main(int argc, char **argv) } if (mr) printf("+F2:%u:%u:%f:%f\n", - k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]); + k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]); else printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", - rsa_bits[k], 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1], + rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1], rsa_results[k][0], rsa_results[k][1]); } #endif @@ -3734,11 +3587,11 @@ int speed_main(int argc, char **argv) if (mr) printf("+F4:%u:%u:%f:%f\n", - k, test_curves[k].bits, + k, ec_curves[k].bits, ecdsa_results[k][0], ecdsa_results[k][1]); else printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_curves[k].bits, test_curves[k].name, + ec_curves[k].bits, ec_curves[k].name, 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1], ecdsa_results[k][0], ecdsa_results[k][1]); } @@ -3753,12 +3606,12 @@ int speed_main(int argc, char **argv) } if (mr) printf("+F5:%u:%u:%f:%f\n", - k, test_curves[k].bits, + k, ec_curves[k].bits, ecdh_results[k][0], 1.0 / ecdh_results[k][0]); else printf("%4u bits ecdh (%s) %8.4fs %8.1f\n", - test_curves[k].bits, test_curves[k].name, + ec_curves[k].bits, ec_curves[k].name, 1.0 / ecdh_results[k][0], ecdh_results[k][0]); } @@ -3773,11 +3626,11 @@ int speed_main(int argc, char **argv) if (mr) printf("+F6:%u:%u:%s:%f:%f\n", - k, test_ed_curves[k].bits, test_ed_curves[k].name, + k, ed_curves[k].bits, ed_curves[k].name, eddsa_results[k][0], eddsa_results[k][1]); else printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_ed_curves[k].bits, test_ed_curves[k].name, + ed_curves[k].bits, ed_curves[k].name, 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1], eddsa_results[k][0], eddsa_results[k][1]); } @@ -3794,16 +3647,16 @@ int speed_main(int argc, char **argv) if (mr) printf("+F6:%u:%u:%s:%f:%f\n", - k, test_sm2_curves[k].bits, test_sm2_curves[k].name, + k, sm2_curves[k].bits, sm2_curves[k].name, sm2_results[k][0], sm2_results[k][1]); else printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_sm2_curves[k].bits, test_sm2_curves[k].name, + sm2_curves[k].bits, sm2_curves[k].name, 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1], sm2_results[k][0], sm2_results[k][1]); } # endif -#endif +#endif /* OPENSSL_NO_EC */ ret = 0; @@ -3875,6 +3728,7 @@ static void print_message(const char *s, long num, int length, int tm) mr ? "+DT:%s:%d:%d\n" : "Doing %s for %ds on %d size blocks: ", s, tm, length); (void)BIO_flush(bio_err); + run = 1; alarm(tm); #else BIO_printf(bio_err, @@ -3892,6 +3746,7 @@ static void pkey_print_message(const char *str, const char *str2, long num, mr ? "+DTP:%d:%s:%s:%d\n" : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm); (void)BIO_flush(bio_err); + run = 1; alarm(tm); #else BIO_printf(bio_err, @@ -3904,8 +3759,10 @@ static void pkey_print_message(const char *str, const char *str2, long num, static void print_result(int alg, int run_no, int count, double time_used) { if (count == -1) { - BIO_puts(bio_err, "EVP error!\n"); - exit(1); + BIO_printf(bio_err, "%s error!\n", names[alg]); + ERR_print_errors(bio_err); + /* exit(1); disable exit until default provider enabled */ + return; } BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" @@ -4064,6 +3921,7 @@ static int do_multi(int multi, int size_num) p = buf + 4; k = atoi(sstrsep(&p, sep)); sstrsep(&p, sep); + sstrsep(&p, sep); d = atof(sstrsep(&p, sep)); eddsa_results[k][0] += d; @@ -4137,7 +3995,7 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, for (j = 0; j < num; j++) { print_message(alg_name, 0, mblengths[j], seconds->sym); Time_F(START); - for (count = 0, run = 1; run && count < 0x7fffffff; count++) { + for (count = 0; run && count < 0x7fffffff; count++) { unsigned char aad[EVP_AEAD_TLS1_AAD_LEN]; EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; size_t len = mblengths[j]; diff --git a/apps/spkac.c b/apps/spkac.c index 0ac644dd..75e246a1 100644 --- a/apps/spkac.c +++ b/apps/spkac.c @@ -28,22 +28,27 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS spkac_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"key", OPT_KEY, '<', "Create SPKAC using private key"}, - {"keyform", OPT_KEYFORM, 'f', "Private key file format - default PEM (PEM, DER, or ENGINE)"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"challenge", OPT_CHALLENGE, 's', "Challenge string"}, - {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"}, - {"noout", OPT_NOOUT, '-', "Don't print SPKAC"}, - {"pubkey", OPT_PUBKEY, '-', "Output public key"}, - {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"}, {"spksect", OPT_SPKSECT, 's', "Specify the name of an SPKAC-dedicated section of configuration"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"key", OPT_KEY, '<', "Create SPKAC using private key"}, + {"keyform", OPT_KEYFORM, 'f', "Private key file format - default PEM (PEM, DER, or ENGINE)"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"challenge", OPT_CHALLENGE, 's', "Challenge string"}, + {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"noout", OPT_NOOUT, '-', "Don't print SPKAC"}, + {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"}, {NULL} }; diff --git a/apps/srp.c b/apps/srp.c index e9d9b67b..e7a18d68 100644 --- a/apps/srp.c +++ b/apps/srp.c @@ -197,24 +197,34 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS srp_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [user...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"}, {"config", OPT_CONFIG, '<', "A config file"}, {"name", OPT_NAME, 's', "The particular srp definition to use"}, - {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + + OPT_SECTION("Action"), {"add", OPT_ADD, '-', "Add a user and srp verifier"}, - {"modify", OPT_MODIFY, '-', - "Modify the srp verifier of an existing user"}, + {"modify", OPT_MODIFY, '-', "Modify the srp verifier of an existing user"}, {"delete", OPT_DELETE, '-', "Delete user from verifier file"}, {"list", OPT_LIST, '-', "List users"}, + + OPT_SECTION("Configuration"), + {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"}, {"gn", OPT_GN, 's', "Set g and N values to be used for new verifier"}, {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif + + OPT_PARAMETERS(), + {"user", 0, 0, "Username(s) to process (optional)"}, {NULL} }; diff --git a/apps/storeutl.c b/apps/storeutl.c index f557f4d3..85fb1ed8 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -31,12 +31,16 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS storeutl_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\nValid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"text", OPT_TEXT, '-', "Print a text form of the objects"}, - {"noout", OPT_NOOUT, '-', "No PEM output, just status"}, + {"", OPT_MD, '-', "Any supported digest"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Search"), {"certs", OPT_SEARCHFOR_CERTS, '-', "Search for certificates only"}, {"keys", OPT_SEARCHFOR_KEYS, '-', "Search for keys only"}, {"crls", OPT_SEARCHFOR_CRLS, '-', "Search for CRLs only"}, @@ -45,11 +49,18 @@ const OPTIONS storeutl_options[] = { {"serial", OPT_CRITERION_SERIAL, 's', "Search by issuer and serial, serial number"}, {"fingerprint", OPT_CRITERION_FINGERPRINT, 's', "Search by public key fingerprint, given in hex"}, {"alias", OPT_CRITERION_ALIAS, 's', "Search by alias"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif {"r", OPT_RECURSIVE, '-', "Recurse through names"}, + + OPT_SECTION("Input"), + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"text", OPT_TEXT, '-', "Print a text form of the objects"}, + {"noout", OPT_NOOUT, '-', "No PEM output, just status"}, + + OPT_PARAMETERS(), + {"uri", 0, 0, "URI of the store object"}, {NULL} }; diff --git a/apps/ts.c b/apps/ts.c index b45c2627..c651c8e5 100644 --- a/apps/ts.c +++ b/apps/ts.c @@ -66,15 +66,17 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); /* Verify related functions. */ static int verify_command(const char *data, const char *digest, const char *queryfile, const char *in, int token_in, - const char *CApath, const char *CAfile, const char *untrusted, - X509_VERIFY_PARAM *vpm); + const char *CApath, const char *CAfile, + const char *CAstore, + const char *untrusted, X509_VERIFY_PARAM *vpm); static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, const char *queryfile, const char *CApath, const char *CAfile, + const char *CAstore, const char *untrusted, X509_VERIFY_PARAM *vpm); static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, - X509_VERIFY_PARAM *vpm); + const char *CAstore, X509_VERIFY_PARAM *vpm); static int verify_cb(int ok, X509_STORE_CTX *ctx); typedef enum OPTION_choice { @@ -83,43 +85,48 @@ typedef enum OPTION_choice { OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT, OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT, OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER, - OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED, + OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, OPT_UNTRUSTED, OPT_MD, OPT_V_ENUM, OPT_R_ENUM } OPTION_CHOICE; const OPTIONS ts_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"config", OPT_CONFIG, '<', "Configuration file"}, {"section", OPT_SECTION, 's', "Section to use within config file"}, - {"query", OPT_QUERY, '-', "Generate a TS query"}, - {"data", OPT_DATA, '<', "File to hash"}, - {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"}, - OPT_R_OPTIONS, - {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"}, - {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"}, - {"cert", OPT_CERT, '-', "Put cert request into query"}, - {"in", OPT_IN, '<', "Input file"}, - {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"}, - {"text", OPT_TEXT, '-', "Output text (not DER)"}, - {"reply", OPT_REPLY, '-', "Generate a TS reply"}, - {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"inkey", OPT_INKEY, 's', "File with private key for reply"}, - {"signer", OPT_SIGNER, 's', "Signer certificate file"}, - {"chain", OPT_CHAIN, '<', "File with signer CA chain"}, - {"verify", OPT_VERIFY, '-', "Verify a TS response"}, - {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"}, - {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, - {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"}, - {"", OPT_MD, '-', "Any supported digest"}, # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif - {OPT_HELP_STR, 1, '-', "\nOptions specific to 'ts -verify': \n"}, + {"inkey", OPT_INKEY, 's', "File with private key for reply"}, + {"signer", OPT_SIGNER, 's', "Signer certificate file"}, + {"chain", OPT_CHAIN, '<', "File with signer CA chain"}, + {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"}, + {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, + {"CAstore", OPT_CASTORE, ':', "URI to trusted CA store"}, + {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"}, + {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"}, + {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"", OPT_MD, '-', "Any supported digest"}, + + OPT_SECTION("Query"), + {"query", OPT_QUERY, '-', "Generate a TS query"}, + {"data", OPT_DATA, '<', "File to hash"}, + {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"}, + {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"}, + {"cert", OPT_CERT, '-', "Put cert request into query"}, + {"in", OPT_IN, '<', "Input file"}, + + OPT_SECTION("Verify"), + {"verify", OPT_VERIFY, '-', "Verify a TS response"}, + {"reply", OPT_REPLY, '-', "Generate a TS reply"}, + {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"}, + {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"}, + {"out", OPT_OUT, '>', "Output file"}, + {"text", OPT_TEXT, '-', "Output text (not DER)"}, + + OPT_R_OPTIONS, OPT_V_OPTIONS, - {OPT_HELP_STR, 1, '-', "\n"}, {NULL} }; @@ -127,26 +134,26 @@ const OPTIONS ts_options[] = { * This command is so complex, special help is needed. */ static char* opt_helplist[] = { + "", "Typical uses:", - "ts -query [-rand file...] [-config file] [-data file]", - " [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]", - " [-in file] [-out file] [-text]", - " or", - "ts -reply [-config file] [-section tsa_section]", - " [-queryfile file] [-passin password]", - " [-signer tsa_cert.pem] [-inkey private_key.pem]", - " [-chain certs_file.pem] [-tspolicy oid]", - " [-in file] [-token_in] [-out file] [-token_out]", + " openssl ts -query [-rand file...] [-config file] [-data file]", + " [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]", + " [-in file] [-out file] [-text]", + "", + " openssl ts -reply [-config file] [-section tsa_section]", + " [-queryfile file] [-passin password]", + " [-signer tsa_cert.pem] [-inkey private_key.pem]", + " [-chain certs_file.pem] [-tspolicy oid]", + " [-in file] [-token_in] [-out file] [-token_out]", # ifndef OPENSSL_NO_ENGINE - " [-text] [-engine id]", + " [-text] [-engine id]", # else - " [-text]", + " [-text]", # endif - " or", - "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem", - " [-data file] [-digest hexstring]", - " [-queryfile file] -in file [-token_in]", - " [[options specific to 'ts -verify']]", + "", + " openssl ts -verify -CApath dir -CAfile file.pem -CAstore uri", + " -untrusted file.pem [-data file] [-digest hexstring]", + " [-queryfile file] -in file [-token_in] ...", NULL, }; @@ -161,6 +168,7 @@ int ts_main(int argc, char **argv) char *data = NULL, *digest = NULL, *policy = NULL; char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL; char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL; + char *CAstore = NULL; const EVP_MD *md = NULL; OPTION_CHOICE o, mode = OPT_ERR; int ret = 1, no_nonce = 0, cert = 0, text = 0; @@ -256,6 +264,9 @@ int ts_main(int argc, char **argv) case OPT_CAFILE: CAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_UNTRUSTED: untrusted = opt_arg(); break; @@ -282,7 +293,8 @@ int ts_main(int argc, char **argv) goto end; } - conf = load_config_file(configfile); + if ((conf = load_config_file(configfile)) == NULL) + goto end; if (configfile != default_config_file && !app_load_modules(conf)) goto end; @@ -311,7 +323,7 @@ int ts_main(int argc, char **argv) if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest)) goto opthelp; ret = !verify_command(data, digest, queryfile, in, token_in, - CApath, CAfile, untrusted, + CApath, CAfile, CAstore, untrusted, vpmtouched ? vpm : NULL); } else { goto opthelp; @@ -820,7 +832,8 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) static int verify_command(const char *data, const char *digest, const char *queryfile, const char *in, int token_in, - const char *CApath, const char *CAfile, const char *untrusted, + const char *CApath, const char *CAfile, + const char *CAstore, const char *untrusted, X509_VERIFY_PARAM *vpm) { BIO *in_bio = NULL; @@ -840,7 +853,7 @@ static int verify_command(const char *data, const char *digest, const char *quer } if ((verify_ctx = create_verify_ctx(data, digest, queryfile, - CApath, CAfile, untrusted, + CApath, CAfile, CAstore, untrusted, vpm)) == NULL) goto end; @@ -867,6 +880,7 @@ static int verify_command(const char *data, const char *digest, const char *quer static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, const char *queryfile, const char *CApath, const char *CAfile, + const char *CAstore, const char *untrusted, X509_VERIFY_PARAM *vpm) { @@ -915,7 +929,8 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE); /* Initialising the X509_STORE object. */ - if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm)) + if (TS_VERIFY_CTX_set_store(ctx, + create_cert_store(CApath, CAfile, CAstore, vpm)) == NULL) goto err; @@ -936,11 +951,10 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, } static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, - X509_VERIFY_PARAM *vpm) + const char *CAstore, X509_VERIFY_PARAM *vpm) { X509_STORE *cert_ctx = NULL; X509_LOOKUP *lookup = NULL; - int i; cert_ctx = X509_STORE_new(); X509_STORE_set_verify_cb(cert_ctx, verify_cb); @@ -950,8 +964,7 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); - if (!i) { + if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto err; } @@ -963,13 +976,24 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM); - if (!i) { + if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto err; } } + if (CAstore != NULL) { + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_store()); + if (lookup == NULL) { + BIO_printf(bio_err, "memory allocation failure\n"); + goto err; + } + if (!X509_LOOKUP_load_store(lookup, CAstore)) { + BIO_printf(bio_err, "Error loading store URI %s\n", CAstore); + goto err; + } + } + if (vpm != NULL) X509_STORE_set1_param(cert_ctx, vpm); diff --git a/apps/verify.c b/apps/verify.c index fd407646..5c504211 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -27,24 +27,35 @@ static int v_verbose = 0, vflags = 0; typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, + OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN, OPT_V_ENUM, OPT_NAMEOPT, OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID } OPTION_CHOICE; const OPTIONS verify_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif {"verbose", OPT_VERBOSE, '-', "Print extra information about the operations being performed."}, + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + + OPT_SECTION("Certificate chain"), {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"}, {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"}, + {"CAstore", OPT_CASTORE, ':', "URI to a store of trusted certificates"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates store"}, {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"}, {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"}, {"CRLfile", OPT_CRLFILE, '<', @@ -53,17 +64,17 @@ const OPTIONS verify_options[] = { "Attempt to download CRL information for this certificate"}, {"show_chain", OPT_SHOW_CHAIN, '-', "Display information about the certificate chain"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + OPT_V_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif #ifndef OPENSSL_NO_SM2 {"sm2-id", OPT_SM2ID, 's', "Specify an ID string to verify an SM2 certificate"}, {"sm2-hex-id", OPT_SM2HEXID, 's', "Specify a hex ID string to verify an SM2 certificate"}, #endif + + OPT_PARAMETERS(), + {"cert", 0, 0, "Certificate(s) to verify (optional; stdin used otherwise)"}, {NULL} }; @@ -74,8 +85,8 @@ int verify_main(int argc, char **argv) STACK_OF(X509_CRL) *crls = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *prog, *CApath = NULL, *CAfile = NULL; - int noCApath = 0, noCAfile = 0; + const char *prog, *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; OPTION_CHOICE o; unsigned char *sm2_id = NULL; @@ -94,20 +105,20 @@ int verify_main(int argc, char **argv) goto end; case OPT_HELP: opt_help(verify_options); - BIO_printf(bio_err, "Recognized usages:\n"); + BIO_printf(bio_err, "\nRecognized certificate chain purposes:\n"); for (i = 0; i < X509_PURPOSE_get_count(); i++) { - X509_PURPOSE *ptmp; - ptmp = X509_PURPOSE_get0(i); - BIO_printf(bio_err, "\t%-10s\t%s\n", + X509_PURPOSE *ptmp = X509_PURPOSE_get0(i); + + BIO_printf(bio_err, " %-15s %s\n", X509_PURPOSE_get0_sname(ptmp), X509_PURPOSE_get0_name(ptmp)); } - BIO_printf(bio_err, "Recognized verify names:\n"); + BIO_printf(bio_err, "Recognized certificate policy names:\n"); for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) { - const X509_VERIFY_PARAM *vptmp; - vptmp = X509_VERIFY_PARAM_get0(i); - BIO_printf(bio_err, "\t%-10s\n", + const X509_VERIFY_PARAM *vptmp = X509_VERIFY_PARAM_get0(i); + + BIO_printf(bio_err, " %s\n", X509_VERIFY_PARAM_get0_name(vptmp)); } ret = 0; @@ -123,12 +134,18 @@ int verify_main(int argc, char **argv) case OPT_CAFILE: CAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_UNTRUSTED: /* Zero or more times */ if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL, @@ -139,6 +156,7 @@ int verify_main(int argc, char **argv) /* Zero or more times */ noCAfile = 1; noCApath = 1; + noCAstore = 1; if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL, "trusted certificates")) goto end; @@ -195,14 +213,16 @@ int verify_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); - if (trusted != NULL && (CAfile || CApath)) { + if (trusted != NULL + && (CAfile != NULL || CApath != NULL || CAstore != NULL)) { BIO_printf(bio_err, - "%s: Cannot use -trusted with -CAfile or -CApath\n", + "%s: Cannot use -trusted with -CAfile, -CApath or -CAstore\n", prog); goto end; } - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, cb); diff --git a/apps/version.c b/apps/version.c index 7350ccf7..deb91338 100644 --- a/apps/version.c +++ b/apps/version.c @@ -18,9 +18,6 @@ #ifndef OPENSSL_NO_MD2 # include #endif -#ifndef OPENSSL_NO_RC4 -# include -#endif #ifndef OPENSSL_NO_DES # include #endif @@ -37,7 +34,10 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS version_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"a", OPT_A, '-', "Show all data"}, {"b", OPT_B, '-', "Show build date"}, {"d", OPT_D, '-', "Show configuration directory"}, @@ -126,20 +126,11 @@ opthelp: if (options) { printf("options: "); printf(" %s", BN_options()); -#ifndef OPENSSL_NO_MD2 - printf(" %s", MD2_options()); -#endif -#ifndef OPENSSL_NO_RC4 - printf(" %s", RC4_options()); -#endif #ifndef OPENSSL_NO_DES printf(" %s", DES_options()); #endif #ifndef OPENSSL_NO_IDEA printf(" %s", IDEA_options()); -#endif -#ifndef OPENSSL_NO_BF - printf(" %s", BF_options()); #endif printf("\n"); } diff --git a/apps/x509.c b/apps/x509.c index 3a5d5612..c0075379 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -65,15 +65,23 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS x509_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"inform", OPT_INFORM, 'f', "Input format - default PEM (one of DER or PEM)"}, {"in", OPT_IN, '<', "Input file - default stdin"}, + {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"}, {"outform", OPT_OUTFORM, 'f', "Output format - default PEM (one of DER or PEM)"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, - {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"}, + {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, + {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, + + OPT_SECTION("Output"), {"serial", OPT_SERIAL, '-', "Print serial number value"}, {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, @@ -81,21 +89,37 @@ const OPTIONS x509_options[] = { {"subject", OPT_SUBJECT, '-', "Print subject DN"}, {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, {"email", OPT_EMAIL, '-', "Print email address(es)"}, - {"startdate", OPT_STARTDATE, '-', "Set notBefore field"}, - {"enddate", OPT_ENDDATE, '-', "Set notAfter field"}, {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"}, - {"dates", OPT_DATES, '-', "Both Before and After dates"}, {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, {"pubkey", OPT_PUBKEY, '-', "Output the public key"}, - {"fingerprint", OPT_FINGERPRINT, '-', - "Print the certificate fingerprint"}, + {"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"}, {"alias", OPT_ALIAS, '-', "Output certificate alias"}, {"noout", OPT_NOOUT, '-', "No output, just status"}, - {"nocert", OPT_NOCERT, '-', "No certificate output"}, {"ocspid", OPT_OCSPID, '-', "Print OCSP hash values for the subject name and public key"}, {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"}, + {"nocert", OPT_NOCERT, '-', "No certificate output"}, {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"}, + {"x509toreq", OPT_X509TOREQ, '-', + "Output a certification request object"}, + {"checkend", OPT_CHECKEND, 'M', + "Check whether the cert expires in the next arg seconds"}, + {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, + {"text", OPT_TEXT, '-', "Print the certificate in text form"}, + {"ext", OPT_EXT, 's', "Print various X509V3 extensions"}, + {"C", OPT_C, '-', "Print out C code forms"}, +#ifndef OPENSSL_NO_MD5 + {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', + "Print old-style (MD5) issuer hash value"}, + {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', + "Print old-style (MD5) subject hash value"}, +#endif + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + + OPT_SECTION("Certificate"), + {"startdate", OPT_STARTDATE, '-', "Set notBefore field"}, + {"enddate", OPT_ENDDATE, '-', "Set notAfter field"}, + {"dates", OPT_DATES, '-', "Both Before and After dates"}, {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"}, {"clrext", OPT_CLREXT, '-', "Clear all certificate extensions"}, {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"}, @@ -104,51 +128,34 @@ const OPTIONS x509_options[] = { {"setalias", OPT_SETALIAS, 's', "Set certificate alias"}, {"days", OPT_DAYS, 'n', "How long till expiry of a signed certificate - def 30 days"}, - {"checkend", OPT_CHECKEND, 'M', - "Check whether the cert expires in the next arg seconds"}, - {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"}, - {"x509toreq", OPT_X509TOREQ, '-', - "Output a certification request object"}, - {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, - {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, - {"CAkey", OPT_CAKEY, 's', - "The CA key, must be PEM format; if not in CAfile"}, - {"CAcreateserial", OPT_CACREATESERIAL, '-', - "Create serial number file if it does not exist"}, - {"CAserial", OPT_CASERIAL, 's', "Serial file"}, {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, - {"text", OPT_TEXT, '-', "Print the certificate in text form"}, - {"ext", OPT_EXT, 's', "Print various X509V3 extensions"}, - {"C", OPT_C, '-', "Print out C code forms"}, - {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"}, - OPT_R_OPTIONS, {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, {"certopt", OPT_CERTOPT, 's', "Various certificate text options"}, {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"}, {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"}, {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"}, + {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the key to put inside certificate"}, + {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, + + OPT_SECTION("CA"), + {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, + {"CAkey", OPT_CAKEY, 's', + "The CA key, must be PEM format; if not in CAfile"}, + {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"}, + OPT_R_OPTIONS, {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, {"CAkeyform", OPT_CAKEYFORM, 'f', "CA key format - default PEM"}, {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"CAcreateserial", OPT_CACREATESERIAL, '-', + "Create serial number file if it does not exist"}, + {"CAserial", OPT_CASERIAL, 's', "Serial file"}, {"new", OPT_NEW, '-', "Generate a certificate from scratch"}, - {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the key to put inside certificate"}, - {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"}, {"clrreject", OPT_CLRREJECT, '-', "Clears all the prohibited or rejected uses of the certificate"}, {"badsig", OPT_BADSIG, '-', "Corrupt last byte of certificate signature (for test)"}, {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_MD5 - {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', - "Print old-style (MD5) issuer hash value"}, - {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', - "Print old-style (MD5) subject hash value"}, -#endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif {"preserve_dates", OPT_PRESERVE_DATES, '-', "preserve existing dates when signing"}, {NULL} }; @@ -224,7 +231,7 @@ int x509_main(int argc, char **argv) goto opthelp; break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyformat)) goto opthelp; break; case OPT_CAFORM: diff --git a/appveyor.yml b/appveyor.yml index ab4444d6..cca4a9a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ before_build: - ps: >- If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" - $env:TARGET="VC-WIN32 no-asm" + $env:TARGET="VC-WIN32 no-asm --strict-warnings" } Else { $env:VCVARS_PLATFORM="amd64" $env:TARGET="VC-WIN64A-masm" diff --git a/build.info b/build.info index 5e63b440..6cfa2017 100644 --- a/build.info +++ b/build.info @@ -1,6 +1,6 @@ # Note that some of these directories are filtered in Configure. Look for # %skipdir there for further explanations. -SUBDIRS=crypto ssl apps test util tools fuzz engines providers +SUBDIRS=crypto ssl apps test util tools fuzz engines providers doc LIBS=libcrypto libssl INCLUDE[libcrypto]=. include @@ -9,9 +9,12 @@ DEPEND[libssl]=libcrypto # Empty DEPEND "indices" means the dependencies are expected to be built # unconditionally before anything else. -DEPEND[]=include/openssl/opensslconf.h include/crypto/bn_conf.h \ - include/crypto/dso_conf.h doc/man7/openssl_user_macros.pod -GENERATE[include/openssl/opensslconf.h]=include/openssl/opensslconf.h.in +DEPEND[]=include/openssl/configuration.h include/openssl/opensslv.h \ + include/crypto/bn_conf.h include/crypto/dso_conf.h \ + doc/man7/openssl_user_macros.pod + +GENERATE[include/openssl/configuration.h]=include/openssl/configuration.h.in +GENERATE[include/openssl/opensslv.h]=include/openssl/opensslv.h.in GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in GENERATE[doc/man7/openssl_user_macros.pod]=doc/man7/openssl_user_macros.pod.in diff --git a/configdata.pm.in b/configdata.pm.in index 6e5c1ad4..71627b48 100644 --- a/configdata.pm.in +++ b/configdata.pm.in @@ -124,8 +124,6 @@ unless (caller) { my $prepend = <<"_____"; use File::Spec::Functions; use lib '{- sourcedir('util', 'perl') -}'; -_____ - $prepend .= <<"_____" if defined $target{perl_platform}; use lib '{- sourcedir('Configurations') -}'; use lib '{- $config{builddir} -}'; use platform; @@ -247,7 +245,13 @@ _____ foreach (sort keys %target) { next if $_ =~ m|^_| || $_ eq 'template'; my $quotify = sub { - map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; + map { + if (defined $_) { + (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\"" + } else { + "undef"; + } + } @_; }; print ' ', $_, ' => '; if (ref($target{$_}) eq "ARRAY") { diff --git a/crypto/LPdir_unix.c b/crypto/LPdir_unix.c index f2c86191..ddf68b57 100644 --- a/crypto/LPdir_unix.c +++ b/crypto/LPdir_unix.c @@ -131,9 +131,8 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) return 0; } - strncpy((*ctx)->entry_name, direntry->d_name, - sizeof((*ctx)->entry_name) - 1); - (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; + OPENSSL_strlcpy((*ctx)->entry_name, direntry->d_name, + sizeof((*ctx)->entry_name)); #ifdef __VMS if ((*ctx)->expect_file_generations) { char *p = (*ctx)->entry_name + strlen((*ctx)->entry_name); diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c index d4e30919..9017cc13 100644 --- a/crypto/aes/aes_cbc.c +++ b/crypto/aes/aes_cbc.c @@ -7,6 +7,13 @@ * https://www.openssl.org/source/license.html */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/aes/aes_cfb.c b/crypto/aes/aes_cfb.c index 09628017..f0442f61 100644 --- a/crypto/aes/aes_cfb.c +++ b/crypto/aes/aes_cfb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * AES_encrypt is deprecated - but we need to use it to implement these other + * deprecated APIs. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/aes/aes_core.c b/crypto/aes/aes_core.c index a094a9ad..d7e4bf16 100644 --- a/crypto/aes/aes_core.c +++ b/crypto/aes/aes_core.c @@ -36,6 +36,13 @@ /* Note: rewritten a little bit to provide error control and an OpenSSL- compatible API */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/aes/aes_ecb.c b/crypto/aes/aes_ecb.c index f4a75f13..7270fc31 100644 --- a/crypto/aes/aes_ecb.c +++ b/crypto/aes/aes_ecb.c @@ -9,6 +9,12 @@ #include +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * AES_ecb_encrypt + */ +#include "internal/deprecated.h" + #include #include "aes_local.h" diff --git a/crypto/aes/aes_ige.c b/crypto/aes/aes_ige.c index b95d3d4b..b40f4e53 100644 --- a/crypto/aes/aes_ige.c +++ b/crypto/aes/aes_ige.c @@ -7,9 +7,15 @@ * https://www.openssl.org/source/license.html */ +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * these functions + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" -#if OPENSSL_API_3 +#ifdef OPENSSL_NO_DEPRECATED_3_0 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/aes/aes_misc.c b/crypto/aes/aes_misc.c index 35be71d1..e706f513 100644 --- a/crypto/aes/aes_misc.c +++ b/crypto/aes/aes_misc.c @@ -11,11 +11,13 @@ #include #include "aes_local.h" +#ifndef OPENSSL_NO_DEPRECATED_3_0 const char *AES_options(void) { -#ifdef FULL_UNROLL +# ifdef FULL_UNROLL return "aes(full)"; -#else +# else return "aes(partial)"; -#endif +# endif } +#endif diff --git a/crypto/aes/aes_ofb.c b/crypto/aes/aes_ofb.c index e77546c8..20f9814f 100644 --- a/crypto/aes/aes_ofb.c +++ b/crypto/aes/aes_ofb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * AES_encrypt is deprecated - but we need to use it to implement + * AES_ofb128_encrypt + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/aes/aes_wrap.c b/crypto/aes/aes_wrap.c index b869b265..82bf6dbf 100644 --- a/crypto/aes/aes_wrap.c +++ b/crypto/aes/aes_wrap.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * these functions + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include #include diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl index 6ab747d9..a657e362 100755 --- a/crypto/aes/asm/aes-x86_64.pl +++ b/crypto/aes/asm/aes-x86_64.pl @@ -328,6 +328,7 @@ $code.=<<___; .type _x86_64_AES_encrypt,\@abi-omnipotent .align 16 _x86_64_AES_encrypt: +.cfi_startproc xor 0($key),$s0 # xor with key xor 4($key),$s1 xor 8($key),$s2 @@ -363,6 +364,7 @@ ___ } $code.=<<___; .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt ___ @@ -912,6 +914,7 @@ $code.=<<___; .type _x86_64_AES_decrypt,\@abi-omnipotent .align 16 _x86_64_AES_decrypt: +.cfi_startproc xor 0($key),$s0 # xor with key xor 4($key),$s1 xor 8($key),$s2 @@ -954,6 +957,7 @@ ___ } $code.=<<___; .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt ___ diff --git a/crypto/aes/asm/aesni-mb-x86_64.pl b/crypto/aes/asm/aesni-mb-x86_64.pl index 72f55dbd..e531137e 100644 --- a/crypto/aes/asm/aesni-mb-x86_64.pl +++ b/crypto/aes/asm/aesni-mb-x86_64.pl @@ -71,7 +71,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/aes/asm/aesni-sha1-x86_64.pl b/crypto/aes/asm/aesni-sha1-x86_64.pl index 800bd5ff..6bf29556 100644 --- a/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -109,7 +109,7 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && `ml64 2>&1` =~ /Version ([0-9]+)\./ && $1>=10); -$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/ && $2>=3.0); +$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); $shaext=1; ### set to zero if compiling for 1.0.1 @@ -135,6 +135,7 @@ $code.=<<___; .type aesni_cbc_sha1_enc,\@abi-omnipotent .align 32 aesni_cbc_sha1_enc: +.cfi_startproc # caller should check for SSSE3 and AES-NI bits mov OPENSSL_ia32cap_P+0(%rip),%r10d mov OPENSSL_ia32cap_P+4(%rip),%r11 @@ -153,6 +154,7 @@ ___ $code.=<<___; jmp aesni_cbc_sha1_enc_ssse3 ret +.cfi_endproc .size aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc ___ @@ -842,6 +844,7 @@ $code.=<<___; .type aesni256_cbc_sha1_dec,\@abi-omnipotent .align 32 aesni256_cbc_sha1_dec: +.cfi_startproc # caller should check for SSSE3 and AES-NI bits mov OPENSSL_ia32cap_P+0(%rip),%r10d mov OPENSSL_ia32cap_P+4(%rip),%r11d @@ -856,6 +859,7 @@ ___ $code.=<<___; jmp aesni256_cbc_sha1_dec_ssse3 ret +.cfi_endproc .size aesni256_cbc_sha1_dec,.-aesni256_cbc_sha1_dec .type aesni256_cbc_sha1_dec_ssse3,\@function,6 @@ -1762,6 +1766,7 @@ $code.=<<___; .type aesni_cbc_sha1_enc_shaext,\@function,6 .align 32 aesni_cbc_sha1_enc_shaext: +.cfi_startproc mov `($win64?56:8)`(%rsp),$inp # load 7th argument ___ $code.=<<___ if ($win64); @@ -1913,6 +1918,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size aesni_cbc_sha1_enc_shaext,.-aesni_cbc_sha1_enc_shaext ___ }}} diff --git a/crypto/aes/asm/aesni-sha256-x86_64.pl b/crypto/aes/asm/aesni-sha256-x86_64.pl index 0a1dec77..8f230855 100644 --- a/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -71,7 +71,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=12); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } @@ -125,6 +125,7 @@ $code=<<___; .type $func,\@abi-omnipotent .align 16 $func: +.cfi_startproc ___ if ($avx) { $code.=<<___; @@ -164,6 +165,7 @@ $code.=<<___; ud2 .Lprobe: ret +.cfi_endproc .size $func,.-$func .align 64 @@ -1086,7 +1088,23 @@ $code.=<<___; vmovdqa $t0,0x00(%rsp) xor $a1,$a1 vmovdqa $t1,0x20(%rsp) +___ +$code.=<<___ if (!$win64); +# temporarily use %rsi as frame pointer + mov $_rsp,%rsi +.cfi_def_cfa %rsi,8 +___ +$code.=<<___; lea -$PUSH8(%rsp),%rsp +___ +$code.=<<___ if (!$win64); +# the frame info is at $_rsp, but the stack is moving... +# so a second frame pointer is saved at -8(%rsp) +# that is in the red zone + mov %rsi,-8(%rsp) +.cfi_cfa_expression %rsp-8,deref,+8 +___ +$code.=<<___; mov $B,$a3 vmovdqa $t2,0x00(%rsp) xor $C,$a3 # magic @@ -1108,7 +1126,17 @@ my @X = @_; my @insns = (&$body,&$body,&$body,&$body); # 96 instructions my $base = "+2*$PUSH8(%rsp)"; - &lea ("%rsp","-$PUSH8(%rsp)") if (($j%2)==0); + if (($j%2)==0) { + &lea ("%rsp","-$PUSH8(%rsp)"); +$code.=<<___ if (!$win64); +.cfi_cfa_expression %rsp+`$PUSH8-8`,deref,+8 +# copy secondary frame pointer to new location again at -8(%rsp) + pushq $PUSH8-8(%rsp) +.cfi_cfa_expression %rsp,deref,+8 + lea 8(%rsp),%rsp +.cfi_cfa_expression %rsp-8,deref,+8 +___ + } foreach (Xupdate_256_AVX()) { # 29 instructions eval; eval(shift(@insns)); @@ -1234,26 +1262,28 @@ $code.=<<___; jbe .Loop_avx2 lea (%rsp),$Tbl +# temporarily use $Tbl as index to $_rsp +# this avoids the need to save a secondary frame pointer at -8(%rsp) +.cfi_cfa_expression $Tbl+`16*$SZ+7*8`,deref,+8 .Ldone_avx2: - lea ($Tbl),%rsp - mov $_ivp,$ivp - mov $_rsp,%rsi + mov 16*$SZ+4*8($Tbl),$ivp + mov 16*$SZ+7*8($Tbl),%rsi .cfi_def_cfa %rsi,8 vmovdqu $iv,($ivp) # output IV vzeroall ___ $code.=<<___ if ($win64); - movaps `$framesz+16*0`(%rsp),%xmm6 - movaps `$framesz+16*1`(%rsp),%xmm7 - movaps `$framesz+16*2`(%rsp),%xmm8 - movaps `$framesz+16*3`(%rsp),%xmm9 - movaps `$framesz+16*4`(%rsp),%xmm10 - movaps `$framesz+16*5`(%rsp),%xmm11 - movaps `$framesz+16*6`(%rsp),%xmm12 - movaps `$framesz+16*7`(%rsp),%xmm13 - movaps `$framesz+16*8`(%rsp),%xmm14 - movaps `$framesz+16*9`(%rsp),%xmm15 + movaps `$framesz+16*0`($Tbl),%xmm6 + movaps `$framesz+16*1`($Tbl),%xmm7 + movaps `$framesz+16*2`($Tbl),%xmm8 + movaps `$framesz+16*3`($Tbl),%xmm9 + movaps `$framesz+16*4`($Tbl),%xmm10 + movaps `$framesz+16*5`($Tbl),%xmm11 + movaps `$framesz+16*6`($Tbl),%xmm12 + movaps `$framesz+16*7`($Tbl),%xmm13 + movaps `$framesz+16*8`($Tbl),%xmm14 + movaps `$framesz+16*9`($Tbl),%xmm15 ___ $code.=<<___; mov -48(%rsi),%r15 @@ -1341,6 +1371,7 @@ $code.=<<___; .type ${func}_shaext,\@function,6 .align 32 ${func}_shaext: +.cfi_startproc mov `($win64?56:8)`(%rsp),$inp # load 7th argument ___ $code.=<<___ if ($win64); @@ -1557,6 +1588,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size ${func}_shaext,.-${func}_shaext ___ } diff --git a/crypto/aes/asm/aesni-x86_64.pl b/crypto/aes/asm/aesni-x86_64.pl index 486ebc8d..2c164d45 100644 --- a/crypto/aes/asm/aesni-x86_64.pl +++ b/crypto/aes/asm/aesni-x86_64.pl @@ -59,7 +59,7 @@ # nothing one can do and the result appears optimal. CCM result is # identical to CBC, because CBC-MAC is essentially CBC encrypt without # saving output. CCM CTR "stays invisible," because it's neatly -# interleaved wih CBC-MAC. This provides ~30% improvement over +# interleaved with CBC-MAC. This provides ~30% improvement over # "straightforward" CCM implementation with CTR and CBC-MAC performed # disjointly. Parallelizable modes practically achieve the theoretical # limit. @@ -986,6 +986,7 @@ $code.=<<___; .type aesni_ccm64_encrypt_blocks,\@function,6 .align 16 aesni_ccm64_encrypt_blocks: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -1068,6 +1069,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks ___ ###################################################################### @@ -1076,6 +1078,7 @@ $code.=<<___; .type aesni_ccm64_decrypt_blocks,\@function,6 .align 16 aesni_ccm64_decrypt_blocks: +.cfi_startproc ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -1175,6 +1178,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks ___ } @@ -3033,6 +3037,7 @@ $code.=<<___; .type __ocb_encrypt6,\@abi-omnipotent .align 32 __ocb_encrypt6: +.cfi_startproc pxor $rndkey0l,@offset[5] # offset_i ^ round[0] movdqu ($L_p,$i1),@offset[1] movdqa @offset[0],@offset[2] @@ -3130,11 +3135,13 @@ __ocb_encrypt6: aesenclast @offset[4],$inout4 aesenclast @offset[5],$inout5 ret +.cfi_endproc .size __ocb_encrypt6,.-__ocb_encrypt6 .type __ocb_encrypt4,\@abi-omnipotent .align 32 __ocb_encrypt4: +.cfi_startproc pxor $rndkey0l,@offset[5] # offset_i ^ round[0] movdqu ($L_p,$i1),@offset[1] movdqa @offset[0],@offset[2] @@ -3199,11 +3206,13 @@ __ocb_encrypt4: aesenclast @offset[2],$inout2 aesenclast @offset[3],$inout3 ret +.cfi_endproc .size __ocb_encrypt4,.-__ocb_encrypt4 .type __ocb_encrypt1,\@abi-omnipotent .align 32 __ocb_encrypt1: +.cfi_startproc pxor @offset[5],$inout5 # offset_i pxor $rndkey0l,$inout5 # offset_i ^ round[0] pxor $inout0,$checksum # accumulate checksum @@ -3234,6 +3243,7 @@ __ocb_encrypt1: aesenclast $inout5,$inout0 ret +.cfi_endproc .size __ocb_encrypt1,.-__ocb_encrypt1 .globl aesni_ocb_decrypt @@ -3515,6 +3525,7 @@ $code.=<<___; .type __ocb_decrypt6,\@abi-omnipotent .align 32 __ocb_decrypt6: +.cfi_startproc pxor $rndkey0l,@offset[5] # offset_i ^ round[0] movdqu ($L_p,$i1),@offset[1] movdqa @offset[0],@offset[2] @@ -3606,11 +3617,13 @@ __ocb_decrypt6: aesdeclast @offset[4],$inout4 aesdeclast @offset[5],$inout5 ret +.cfi_endproc .size __ocb_decrypt6,.-__ocb_decrypt6 .type __ocb_decrypt4,\@abi-omnipotent .align 32 __ocb_decrypt4: +.cfi_startproc pxor $rndkey0l,@offset[5] # offset_i ^ round[0] movdqu ($L_p,$i1),@offset[1] movdqa @offset[0],@offset[2] @@ -3671,11 +3684,13 @@ __ocb_decrypt4: aesdeclast @offset[2],$inout2 aesdeclast @offset[3],$inout3 ret +.cfi_endproc .size __ocb_decrypt4,.-__ocb_decrypt4 .type __ocb_decrypt1,\@abi-omnipotent .align 32 __ocb_decrypt1: +.cfi_startproc pxor @offset[5],$inout5 # offset_i pxor $rndkey0l,$inout5 # offset_i ^ round[0] pxor $inout5,$inout0 # input ^ round[0] ^ offset_i @@ -3705,6 +3720,7 @@ __ocb_decrypt1: aesdeclast $inout5,$inout0 ret +.cfi_endproc .size __ocb_decrypt1,.-__ocb_decrypt1 ___ } }} @@ -4639,7 +4655,6 @@ __aesni_set_encrypt_key: add \$8,%rsp .cfi_adjust_cfa_offset -8 ret -.cfi_endproc .LSEH_end_set_encrypt_key: .align 16 @@ -4710,6 +4725,7 @@ __aesni_set_encrypt_key: shufps \$0b10101010,%xmm1,%xmm1 # critical path xorps %xmm1,%xmm2 ret +.cfi_endproc .size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key .size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key ___ diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl index c132d1d7..d0ae34bc 100755 --- a/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/aes/asm/aesv8-armx.pl @@ -384,6 +384,836 @@ ___ &gen_block("en"); &gen_block("de"); }}} + +# Performance in cycles per byte. +# Processed with AES-ECB different key size. +# It shows the value before and after optimization as below: +# (before/after): +# +# AES-128-ECB AES-192-ECB AES-256-ECB +# Cortex-A57 1.85/0.82 2.16/0.96 2.47/1.10 +# Cortex-A72 1.64/0.85 1.82/0.99 2.13/1.14 + +# Optimization is implemented by loop unrolling and interleaving. +# Commonly, we choose the unrolling factor as 5, if the input +# data size smaller than 5 blocks, but not smaller than 3 blocks, +# choose 3 as the unrolling factor. +# If the input data size dsize >= 5*16 bytes, then take 5 blocks +# as one iteration, every loop the left size lsize -= 5*16. +# If 5*16 > lsize >= 3*16 bytes, take 3 blocks as one iteration, +# every loop lsize -=3*16. +# If lsize < 3*16 bytes, treat them as the tail, interleave the +# two blocks AES instructions. +# There is one special case, if the original input data size dsize +# = 16 bytes, we will treat it seperately to improve the +# performance: one independent code block without LR, FP load and +# store, just looks like what the original ECB implementation does. + +{{{ +my ($inp,$out,$len,$key)=map("x$_",(0..3)); +my ($enc,$rounds,$cnt,$key_,$step)=("w4","w5","w6","x7","x8"); +my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$tmp2,$rndlast)=map("q$_",(0..7)); + +my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1); + +### q7 last round key +### q10-q15 q7 Last 7 round keys +### q8-q9 preloaded round keys except last 7 keys for big size +### q5, q6, q8-q9 preloaded round keys except last 7 keys for only 16 byte + +{ +my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); + +my ($dat3,$in3,$tmp3); # used only in 64-bit mode +my ($dat4,$in4,$tmp4); +if ($flavour =~ /64/) { + ($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23)); +} + +$code.=<<___; +.globl ${prefix}_ecb_encrypt +.type ${prefix}_ecb_encrypt,%function +.align 5 +${prefix}_ecb_encrypt: +___ +$code.=<<___ if ($flavour =~ /64/); + subs $len,$len,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lecb_big_size + vld1.8 {$dat0},[$inp] + cmp $enc,#0 // en- or decrypting? + ldr $rounds,[$key,#240] + vld1.32 {q5-q6},[$key],#32 // load key schedule... + + b.eq .Lecb_small_dec + aese $dat0,q5 + aesmc $dat0,$dat0 + vld1.32 {q8-q9},[$key],#32 // load key schedule... + aese $dat0,q6 + aesmc $dat0,$dat0 + subs $rounds,$rounds,#10 // if rounds==10, jump to aes-128-ecb processing + b.eq .Lecb_128_enc +.Lecb_round_loop: + aese $dat0,q8 + aesmc $dat0,$dat0 + vld1.32 {q8},[$key],#16 // load key schedule... + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q9},[$key],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lecb_round_loop +.Lecb_128_enc: + vld1.32 {q10-q11},[$key],#32 // load key schedule... + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q12-q13},[$key],#32 // load key schedule... + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat0,q11 + aesmc $dat0,$dat0 + vld1.32 {q14-q15},[$key],#32 // load key schedule... + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat0,q13 + aesmc $dat0,$dat0 + vld1.32 {$rndlast},[$key] + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat0,q15 + veor $dat0,$dat0,$rndlast + vst1.8 {$dat0},[$out] + b .Lecb_Final_abort +.Lecb_small_dec: + aesd $dat0,q5 + aesimc $dat0,$dat0 + vld1.32 {q8-q9},[$key],#32 // load key schedule... + aesd $dat0,q6 + aesimc $dat0,$dat0 + subs $rounds,$rounds,#10 // bias + b.eq .Lecb_128_dec +.Lecb_dec_round_loop: + aesd $dat0,q8 + aesimc $dat0,$dat0 + vld1.32 {q8},[$key],#16 // load key schedule... + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q9},[$key],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lecb_dec_round_loop +.Lecb_128_dec: + vld1.32 {q10-q11},[$key],#32 // load key schedule... + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q12-q13},[$key],#32 // load key schedule... + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat0,q11 + aesimc $dat0,$dat0 + vld1.32 {q14-q15},[$key],#32 // load key schedule... + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat0,q13 + aesimc $dat0,$dat0 + vld1.32 {$rndlast},[$key] + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat0,q15 + veor $dat0,$dat0,$rndlast + vst1.8 {$dat0},[$out] + b .Lecb_Final_abort +.Lecb_big_size: +___ +$code.=<<___ if ($flavour =~ /64/); + stp x29,x30,[sp,#-16]! + add x29,sp,#0 +___ +$code.=<<___ if ($flavour !~ /64/); + mov ip,sp + stmdb sp!,{r4-r8,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so + ldmia ip,{r4-r5} @ load remaining args + subs $len,$len,#16 +___ +$code.=<<___; + mov $step,#16 + b.lo .Lecb_done + cclr $step,eq + + cmp $enc,#0 // en- or decrypting? + ldr $rounds,[$key,#240] + and $len,$len,#-16 + vld1.8 {$dat},[$inp],$step + + vld1.32 {q8-q9},[$key] // load key schedule... + sub $rounds,$rounds,#6 + add $key_,$key,x5,lsl#4 // pointer to last 7 round keys + sub $rounds,$rounds,#2 + vld1.32 {q10-q11},[$key_],#32 + vld1.32 {q12-q13},[$key_],#32 + vld1.32 {q14-q15},[$key_],#32 + vld1.32 {$rndlast},[$key_] + + add $key_,$key,#32 + mov $cnt,$rounds + b.eq .Lecb_dec + + vld1.8 {$dat1},[$inp],#16 + subs $len,$len,#32 // bias + add $cnt,$rounds,#2 + vorr $in1,$dat1,$dat1 + vorr $dat2,$dat1,$dat1 + vorr $dat1,$dat,$dat + b.lo .Lecb_enc_tail + + vorr $dat1,$in1,$in1 + vld1.8 {$dat2},[$inp],#16 +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_ecb_enc + + vld1.8 {$dat3},[$inp],#16 + vld1.8 {$dat4},[$inp],#16 + sub $len,$len,#32 // bias + mov $cnt,$rounds + +.Loop5x_ecb_enc: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_ecb_enc + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + cmp $len,#0x40 // because .Lecb_enc_tail4x + sub $len,$len,#0x50 + + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo + mov $key_,$key + + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat1,q10 + aesmc $dat1,$dat1 + aese $dat2,q10 + aesmc $dat2,$dat2 + aese $dat3,q10 + aesmc $dat3,$dat3 + aese $dat4,q10 + aesmc $dat4,$dat4 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat4 + // are loaded with last "words" + add x6,$len,#0x60 // because .Lecb_enc_tail4x + + aese $dat0,q11 + aesmc $dat0,$dat0 + aese $dat1,q11 + aesmc $dat1,$dat1 + aese $dat2,q11 + aesmc $dat2,$dat2 + aese $dat3,q11 + aesmc $dat3,$dat3 + aese $dat4,q11 + aesmc $dat4,$dat4 + + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + aese $dat3,q12 + aesmc $dat3,$dat3 + aese $dat4,q12 + aesmc $dat4,$dat4 + + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat3,q13 + aesmc $dat3,$dat3 + aese $dat4,q13 + aesmc $dat4,$dat4 + + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat3,q14 + aesmc $dat3,$dat3 + aese $dat4,q14 + aesmc $dat4,$dat4 + + aese $dat0,q15 + vld1.8 {$in0},[$inp],#16 + aese $dat1,q15 + vld1.8 {$in1},[$inp],#16 + aese $dat2,q15 + vld1.8 {$in2},[$inp],#16 + aese $dat3,q15 + vld1.8 {$in3},[$inp],#16 + aese $dat4,q15 + vld1.8 {$in4},[$inp],#16 + cbz x6,.Lecb_enc_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$rndlast,$dat0 + vorr $dat0,$in0,$in0 + veor $tmp1,$rndlast,$dat1 + vorr $dat1,$in1,$in1 + veor $tmp2,$rndlast,$dat2 + vorr $dat2,$in2,$in2 + veor $tmp3,$rndlast,$dat3 + vorr $dat3,$in3,$in3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp0},[$out],#16 + vorr $dat4,$in4,$in4 + vst1.8 {$tmp1},[$out],#16 + mov $cnt,$rounds + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_ecb_enc + + add $len,$len,#0x50 + cbz $len,.Lecb_done + + add $cnt,$rounds,#2 + subs $len,$len,#0x30 + vorr $dat0,$in2,$in2 + vorr $dat1,$in3,$in3 + vorr $dat2,$in4,$in4 + b.lo .Lecb_enc_tail + + b .Loop3x_ecb_enc + +.align 4 +.Lecb_enc_tail4x: + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + veor $tmp3,$rndlast,$dat3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + + b .Lecb_done +.align 4 +___ +$code.=<<___; +.Loop3x_ecb_enc: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Loop3x_ecb_enc + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + subs $len,$len,#0x30 + mov.lo x6,$len // x6, $cnt, is zero at this point + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat2 + // are loaded with last "words" + mov $key_,$key + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + vld1.8 {$in0},[$inp],#16 + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aese $dat0,q15 + aese $dat1,q15 + aese $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $cnt,$rounds,#2 + veor $tmp0,$rndlast,$dat0 + veor $tmp1,$rndlast,$dat1 + veor $dat2,$dat2,$rndlast + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vorr $dat0,$in0,$in0 + vst1.8 {$tmp1},[$out],#16 + vorr $dat1,$in1,$in1 + vst1.8 {$dat2},[$out],#16 + vorr $dat2,$in2,$in2 + b.hs .Loop3x_ecb_enc + + cmn $len,#0x30 + b.eq .Lecb_done + nop + +.Lecb_enc_tail: + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lecb_enc_tail + + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + cmn $len,#0x20 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat1,q15 + aese $dat2,q15 + b.eq .Lecb_enc_one + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + b .Lecb_done + +.Lecb_enc_one: + veor $tmp1,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + b .Lecb_done +___ + +$code.=<<___; +.align 5 +.Lecb_dec: + vld1.8 {$dat1},[$inp],#16 + subs $len,$len,#32 // bias + add $cnt,$rounds,#2 + vorr $in1,$dat1,$dat1 + vorr $dat2,$dat1,$dat1 + vorr $dat1,$dat,$dat + b.lo .Lecb_dec_tail + + vorr $dat1,$in1,$in1 + vld1.8 {$dat2},[$inp],#16 +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_ecb_dec + + vld1.8 {$dat3},[$inp],#16 + vld1.8 {$dat4},[$inp],#16 + sub $len,$len,#32 // bias + mov $cnt,$rounds + +.Loop5x_ecb_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_ecb_dec + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + cmp $len,#0x40 // because .Lecb_tail4x + sub $len,$len,#0x50 + + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo + mov $key_,$key + + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat1,q10 + aesimc $dat1,$dat1 + aesd $dat2,q10 + aesimc $dat2,$dat2 + aesd $dat3,q10 + aesimc $dat3,$dat3 + aesd $dat4,q10 + aesimc $dat4,$dat4 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat4 + // are loaded with last "words" + add x6,$len,#0x60 // because .Lecb_tail4x + + aesd $dat0,q11 + aesimc $dat0,$dat0 + aesd $dat1,q11 + aesimc $dat1,$dat1 + aesd $dat2,q11 + aesimc $dat2,$dat2 + aesd $dat3,q11 + aesimc $dat3,$dat3 + aesd $dat4,q11 + aesimc $dat4,$dat4 + + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + aesd $dat3,q12 + aesimc $dat3,$dat3 + aesd $dat4,q12 + aesimc $dat4,$dat4 + + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat3,q13 + aesimc $dat3,$dat3 + aesd $dat4,q13 + aesimc $dat4,$dat4 + + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + aesd $dat3,q14 + aesimc $dat3,$dat3 + aesd $dat4,q14 + aesimc $dat4,$dat4 + + aesd $dat0,q15 + vld1.8 {$in0},[$inp],#16 + aesd $dat1,q15 + vld1.8 {$in1},[$inp],#16 + aesd $dat2,q15 + vld1.8 {$in2},[$inp],#16 + aesd $dat3,q15 + vld1.8 {$in3},[$inp],#16 + aesd $dat4,q15 + vld1.8 {$in4},[$inp],#16 + cbz x6,.Lecb_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$rndlast,$dat0 + vorr $dat0,$in0,$in0 + veor $tmp1,$rndlast,$dat1 + vorr $dat1,$in1,$in1 + veor $tmp2,$rndlast,$dat2 + vorr $dat2,$in2,$in2 + veor $tmp3,$rndlast,$dat3 + vorr $dat3,$in3,$in3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp0},[$out],#16 + vorr $dat4,$in4,$in4 + vst1.8 {$tmp1},[$out],#16 + mov $cnt,$rounds + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_ecb_dec + + add $len,$len,#0x50 + cbz $len,.Lecb_done + + add $cnt,$rounds,#2 + subs $len,$len,#0x30 + vorr $dat0,$in2,$in2 + vorr $dat1,$in3,$in3 + vorr $dat2,$in4,$in4 + b.lo .Lecb_dec_tail + + b .Loop3x_ecb_dec + +.align 4 +.Lecb_tail4x: + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + veor $tmp3,$rndlast,$dat3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + + b .Lecb_done +.align 4 +___ +$code.=<<___; +.Loop3x_ecb_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Loop3x_ecb_dec + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + subs $len,$len,#0x30 + mov.lo x6,$len // x6, $cnt, is zero at this point + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat2 + // are loaded with last "words" + mov $key_,$key + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + vld1.8 {$in0},[$inp],#16 + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aesd $dat0,q15 + aesd $dat1,q15 + aesd $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $cnt,$rounds,#2 + veor $tmp0,$rndlast,$dat0 + veor $tmp1,$rndlast,$dat1 + veor $dat2,$dat2,$rndlast + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vorr $dat0,$in0,$in0 + vst1.8 {$tmp1},[$out],#16 + vorr $dat1,$in1,$in1 + vst1.8 {$dat2},[$out],#16 + vorr $dat2,$in2,$in2 + b.hs .Loop3x_ecb_dec + + cmn $len,#0x30 + b.eq .Lecb_done + nop + +.Lecb_dec_tail: + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lecb_dec_tail + + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + cmn $len,#0x20 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + aesd $dat1,q15 + aesd $dat2,q15 + b.eq .Lecb_dec_one + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + b .Lecb_done + +.Lecb_dec_one: + veor $tmp1,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + +.Lecb_done: +___ +} +$code.=<<___ if ($flavour !~ /64/); + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r8,pc} +___ +$code.=<<___ if ($flavour =~ /64/); + ldr x29,[sp],#16 +___ +$code.=<<___ if ($flavour =~ /64/); +.Lecb_Final_abort: + ret +___ +$code.=<<___; +.size ${prefix}_ecb_encrypt,.-${prefix}_ecb_encrypt +___ +}}} {{{ my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5"; my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12"); diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl index 6593f7a2..1f9f261c 100644 --- a/crypto/aes/asm/bsaes-x86_64.pl +++ b/crypto/aes/asm/bsaes-x86_64.pl @@ -27,7 +27,7 @@ # - code was made position-independent; # - rounds were folded into a loop resulting in >5x size reduction # from 12.5KB to 2.2KB; -# - above was possibile thanks to mixcolumns() modification that +# - above was possible thanks to mixcolumns() modification that # allowed to feed its output back to aesenc[last], this was # achieved at cost of two additional inter-registers moves; # - some instruction reordering and interleaving; diff --git a/crypto/aes/build.info b/crypto/aes/build.info index 291bf2af..dc00df0c 100644 --- a/crypto/aes/build.info +++ b/crypto/aes/build.info @@ -68,8 +68,6 @@ SOURCE[../../providers/libfips.a]=$COMMON DEFINE[../../libcrypto]=$AESDEF DEFINE[../../providers/libfips.a]=$AESDEF DEFINE[../../providers/libimplementations.a]=$AESDEF -# fipsprov.c needs access to AESNI. -DEFINE[../../providers/fips]=$AESDEF GENERATE[aes-ia64.s]=asm/aes-ia64.S diff --git a/crypto/asn1/a_gentm.c b/crypto/asn1/a_gentm.c index d82126b0..4d31fef8 100644 --- a/crypto/asn1/a_gentm.c +++ b/crypto/asn1/a_gentm.c @@ -16,6 +16,9 @@ #include "internal/cryptlib.h" #include #include "asn1_local.h" +#include + +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_GENERALIZEDTIME) /* This is the primary function used to parse ASN1_GENERALIZEDTIME */ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index c978248d..4c9bf0c4 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -24,6 +24,7 @@ IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_TIME) static int is_utc(const int year) { diff --git a/crypto/asn1/a_utctm.c b/crypto/asn1/a_utctm.c index 47eb93fe..59659935 100644 --- a/crypto/asn1/a_utctm.c +++ b/crypto/asn1/a_utctm.c @@ -12,6 +12,9 @@ #include "internal/cryptlib.h" #include #include "asn1_local.h" +#include + +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_UTCTIME) /* This is the primary function used to parse ASN1_UTCTIME */ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) diff --git a/crypto/asn1/asn1_item_list.h b/crypto/asn1/asn1_item_list.h index b0b607a0..c8727e57 100644 --- a/crypto/asn1/asn1_item_list.h +++ b/crypto/asn1/asn1_item_list.h @@ -78,7 +78,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(IPAddressRange), #endif ASN1_ITEM_ref(ISSUING_DIST_POINT), -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(LONG), #endif ASN1_ITEM_ref(NAME_CONSTRAINTS), @@ -164,7 +164,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(X509_SIG), ASN1_ITEM_ref(X509_VAL), ASN1_ITEM_ref(X509), -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(ZLONG), #endif ASN1_ITEM_ref(INT32), diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 6399de7c..52eb16ba 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -383,7 +383,7 @@ const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) return x->data; } -# if !OPENSSL_API_1_1_0 +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 unsigned char *ASN1_STRING_data(ASN1_STRING *x) { return x->data; diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c index f722bed0..a26c4239 100644 --- a/crypto/asn1/asn1_par.c +++ b/crypto/asn1/asn1_par.c @@ -17,25 +17,44 @@ #define ASN1_PARSE_MAXDEPTH 128 #endif -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent); static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump); -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent) +static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len, + int tag, int xclass, int constructed, int indent) { - static const char fmt[] = "%-18s"; char str[128]; const char *p; + int pop_f_prefix = 0; + long saved_indent = -1; + int i = 0; if (constructed & V_ASN1_CONSTRUCTED) p = "cons: "; else p = "prim: "; - if (BIO_write(bp, p, 6) < 6) + if (constructed != (V_ASN1_CONSTRUCTED | 1)) { + if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=%4ld %s", + offset, depth, (long)hl, len, p) <= 0) + goto err; + } else { + if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=inf %s", + offset, depth, (long)hl, p) <= 0) + goto err; + } + if (BIO_set_prefix(bp, str) <= 0) { + if ((bp = BIO_push(BIO_new(BIO_f_prefix()), bp)) == NULL) + goto err; + pop_f_prefix = 1; + } + saved_indent = BIO_get_indent(bp); + if (BIO_set_prefix(bp, str) <= 0 + || BIO_set_indent(bp, indent) < 0) goto err; - BIO_indent(bp, indent, 128); + /* + * BIO_set_prefix made a copy of |str|, so we can safely use it for + * something else, ASN.1 tag printout. + */ p = str; if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag); @@ -48,11 +67,17 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, else p = ASN1_tag2str(tag); - if (BIO_printf(bp, fmt, p) <= 0) - goto err; - return 1; + i = (BIO_printf(bp, "%-18s", p) > 0); err: - return 0; + if (saved_indent >= 0) + BIO_set_indent(bp, saved_indent); + if (pop_f_prefix) { + BIO *next = BIO_pop(bp); + + BIO_free(bp); + bp = next; + } + return i; } int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) @@ -75,6 +100,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int nl, hl, j, r; ASN1_OBJECT *o = NULL; ASN1_OCTET_STRING *os = NULL; + ASN1_INTEGER *ai = NULL; + ASN1_ENUMERATED *ae = NULL; /* ASN1_BMPSTRING *bmp=NULL; */ int dump_indent, dump_cont = 0; @@ -100,19 +127,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, /* * if j == 0x21 it is a constructed indefinite length object */ - if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) - <= 0) - goto end; - - if (j != (V_ASN1_CONSTRUCTED | 1)) { - if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", - depth, (long)hl, len) <= 0) - goto end; - } else { - if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) - goto end; - } - if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) + if (!asn1_print_info(bp, (long)offset + (long)(op - *pp), depth, + hl, len, tag, xclass, j, (indent) ? depth : 0)) goto end; if (j & V_ASN1_CONSTRUCTED) { const unsigned char *sp = p; @@ -250,22 +266,21 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, ASN1_OCTET_STRING_free(os); os = NULL; } else if (tag == V_ASN1_INTEGER) { - ASN1_INTEGER *bs; int i; opp = op; - bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); - if (bs != NULL) { + ai = d2i_ASN1_INTEGER(NULL, &opp, len + hl); + if (ai != NULL) { if (BIO_write(bp, ":", 1) <= 0) goto end; - if (bs->type == V_ASN1_NEG_INTEGER) + if (ai->type == V_ASN1_NEG_INTEGER) if (BIO_write(bp, "-", 1) <= 0) goto end; - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + for (i = 0; i < ai->length; i++) { + if (BIO_printf(bp, "%02X", ai->data[i]) <= 0) goto end; } - if (bs->length == 0) { + if (ai->length == 0) { if (BIO_write(bp, "00", 2) <= 0) goto end; } @@ -274,24 +289,24 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, goto end; dump_cont = 1; } - ASN1_INTEGER_free(bs); + ASN1_INTEGER_free(ai); + ai = NULL; } else if (tag == V_ASN1_ENUMERATED) { - ASN1_ENUMERATED *bs; int i; opp = op; - bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); - if (bs != NULL) { + ae = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); + if (ae != NULL) { if (BIO_write(bp, ":", 1) <= 0) goto end; - if (bs->type == V_ASN1_NEG_ENUMERATED) + if (ae->type == V_ASN1_NEG_ENUMERATED) if (BIO_write(bp, "-", 1) <= 0) goto end; - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + for (i = 0; i < ae->length; i++) { + if (BIO_printf(bp, "%02X", ae->data[i]) <= 0) goto end; } - if (bs->length == 0) { + if (ae->length == 0) { if (BIO_write(bp, "00", 2) <= 0) goto end; } @@ -300,7 +315,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, goto end; dump_cont = 1; } - ASN1_ENUMERATED_free(bs); + ASN1_ENUMERATED_free(ae); + ae = NULL; } else if (len > 0 && dump) { if (!nl) { if (BIO_write(bp, "\n", 1) <= 0) @@ -341,6 +357,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, end: ASN1_OBJECT_free(o); ASN1_OCTET_STRING_free(os); + ASN1_INTEGER_free(ai); + ASN1_ENUMERATED_free(ae); *pp = p; return ret; } diff --git a/crypto/asn1/charmap.h b/crypto/asn1/charmap.h index 0374b643..e855b159 100644 --- a/crypto/asn1/charmap.h +++ b/crypto/asn1/charmap.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/asn1/charmap.pl * - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 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/crypto/asn1/charmap.pl b/crypto/asn1/charmap.pl index d29a21b3..8130c826 100644 --- a/crypto/asn1/charmap.pl +++ b/crypto/asn1/charmap.pl @@ -82,8 +82,8 @@ $arr[ord("?")] |= $PSTRING_CHAR; # Now generate the C code -# Output year depends on the year of the script. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; +# Year the file was generated. +my $YEAR = [localtime()]->[5] + 1900; print < -#if OPENSSL_API_3 +#ifdef OPENSSL_NO_DEPRECATED_3_0 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/asn1_dsa.c b/crypto/asn1_dsa.c index 972a9eb9..34835a52 100644 --- a/crypto/asn1_dsa.c +++ b/crypto/asn1_dsa.c @@ -99,7 +99,7 @@ int encode_der_integer(WPACKET *pkt, const BIGNUM *n) /* * Outputs the DER encoding of a DSA-Sig-Value or ECDSA-Sig-Value to pkt. pkt * may be initialised with a NULL buffer which enables pkt to be used to - * calulate how many bytes would be needed. + * calculate how many bytes would be needed. * * Returns 1 on success or 0 on error. */ diff --git a/crypto/bf/bf_cfb64.c b/crypto/bf/bf_cfb64.c index 6f4fe33e..2660270f 100644 --- a/crypto/bf/bf_cfb64.c +++ b/crypto/bf/bf_cfb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/bf/bf_ecb.c b/crypto/bf/bf_ecb.c index 512d7176..e0fd3911 100644 --- a/crypto/bf/bf_ecb.c +++ b/crypto/bf/bf_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" #include diff --git a/crypto/bf/bf_enc.c b/crypto/bf/bf_enc.c index 3f0c5b4e..7a8f8db7 100644 --- a/crypto/bf/bf_enc.c +++ b/crypto/bf/bf_enc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/bf/bf_ofb64.c b/crypto/bf/bf_ofb64.c index 8df34aa1..f0863ee9 100644 --- a/crypto/bf/bf_ofb64.c +++ b/crypto/bf/bf_ofb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/bf/bf_skey.c b/crypto/bf/bf_skey.c index e358b1de..08189442 100644 --- a/crypto/bf/bf_skey.c +++ b/crypto/bf/bf_skey.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index 8e40d864..78bcffdb 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -24,7 +24,7 @@ static int wsa_init_done = 0; # endif -# if !OPENSSL_API_1_1_0 +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 int BIO_get_host_ip(const char *str, unsigned char *ip) { BIO_ADDRINFO *res = NULL; @@ -103,7 +103,7 @@ int BIO_sock_error(int sock) return j; } -# if !OPENSSL_API_1_1_0 +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 struct hostent *BIO_gethostbyname(const char *name) { /* @@ -195,7 +195,7 @@ int BIO_socket_ioctl(int fd, long type, void *arg) return i; } -# if !OPENSSL_API_1_1_0 +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 int BIO_get_accept_socket(char *host, int bind_mode) { int s = INVALID_SOCKET; diff --git a/apps/lib/bf_prefix.c b/crypto/bio/bf_prefix.c similarity index 61% rename from apps/lib/bf_prefix.c rename to crypto/bio/bf_prefix.c index 8cedca90..5727c149 100644 --- a/apps/lib/bf_prefix.c +++ b/crypto/bio/bf_prefix.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2019 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 @@ -10,8 +10,7 @@ #include #include #include -#include -#include "apps.h" +#include "bio_local.h" static int prefix_write(BIO *b, const char *out, size_t outl, size_t *numwritten); @@ -23,31 +22,31 @@ static int prefix_create(BIO *b); static int prefix_destroy(BIO *b); static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); -static BIO_METHOD *prefix_meth = NULL; +static const BIO_METHOD prefix_meth = { + BIO_TYPE_BUFFER, + "prefix", + prefix_write, + NULL, + prefix_read, + NULL, + prefix_puts, + prefix_gets, + prefix_ctrl, + prefix_create, + prefix_destroy, + prefix_callback_ctrl, +}; -BIO_METHOD *apps_bf_prefix(void) +const BIO_METHOD *BIO_f_prefix(void) { - if (prefix_meth == NULL) { - if ((prefix_meth = - BIO_meth_new(BIO_TYPE_FILTER, "Prefix filter")) == NULL - || !BIO_meth_set_create(prefix_meth, prefix_create) - || !BIO_meth_set_destroy(prefix_meth, prefix_destroy) - || !BIO_meth_set_write_ex(prefix_meth, prefix_write) - || !BIO_meth_set_read_ex(prefix_meth, prefix_read) - || !BIO_meth_set_puts(prefix_meth, prefix_puts) - || !BIO_meth_set_gets(prefix_meth, prefix_gets) - || !BIO_meth_set_ctrl(prefix_meth, prefix_ctrl) - || !BIO_meth_set_callback_ctrl(prefix_meth, prefix_callback_ctrl)) { - BIO_meth_free(prefix_meth); - prefix_meth = NULL; - } - } - return prefix_meth; + return &prefix_meth; } typedef struct prefix_ctx_st { - char *prefix; - int linestart; /* flag to indicate we're at the line start */ + char *prefix; /* Text prefix, given by user */ + unsigned int indent; /* Indentation amount, given by user */ + + int linestart; /* flag to indicate we're at the line start */ } PREFIX_CTX; static int prefix_create(BIO *b) @@ -58,6 +57,7 @@ static int prefix_create(BIO *b) return 0; ctx->prefix = NULL; + ctx->indent = 0; ctx->linestart = 1; BIO_set_data(b, ctx); BIO_set_init(b, 1); @@ -86,9 +86,16 @@ static int prefix_write(BIO *b, const char *out, size_t outl, if (ctx == NULL) return 0; - /* If no prefix is set or if it's empty, we've got nothing to do here */ - if (ctx->prefix == NULL || *ctx->prefix == '\0') { - /* We do note if what comes next will be a new line, though */ + /* + * If no prefix is set or if it's empty, and no indentation amount is set, + * we've got nothing to do here + */ + if ((ctx->prefix == NULL || *ctx->prefix == '\0') + && ctx->indent == 0) { + /* + * We do note if what comes next will be a new line, though, so we're + * prepared to handle prefix and indentation the next time around. + */ if (outl > 0) ctx->linestart = (out[outl-1] == '\n'); return BIO_write_ex(BIO_next(b), out, outl, numwritten); @@ -100,13 +107,18 @@ static int prefix_write(BIO *b, const char *out, size_t outl, size_t i; char c; - /* If we know that we're at the start of the line, output the prefix */ + /* + * If we know that we're at the start of the line, output prefix and + * indentation. + */ if (ctx->linestart) { size_t dontcare; - if (!BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix), - &dontcare)) + if (ctx->prefix != NULL + && !BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix), + &dontcare)) return 0; + BIO_printf(BIO_next(b), "%*s", ctx->indent, ""); ctx->linestart = 0; } @@ -139,21 +151,39 @@ static int prefix_write(BIO *b, const char *out, size_t outl, static long prefix_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 0; + PREFIX_CTX *ctx = BIO_get_data(b); + + if (ctx == NULL) + return -1; switch (cmd) { - case PREFIX_CTRL_SET_PREFIX: - { - PREFIX_CTX *ctx = BIO_get_data(b); - - if (ctx == NULL) - break; - - OPENSSL_free(ctx->prefix); + case BIO_CTRL_SET_PREFIX: + OPENSSL_free(ctx->prefix); + if (ptr == NULL) { + ctx->prefix = NULL; + ret = 1; + } else { ctx->prefix = OPENSSL_strdup((const char *)ptr); ret = ctx->prefix != NULL; } break; + case BIO_CTRL_SET_INDENT: + if (num >= 0) { + ctx->indent = (unsigned int)num; + ret = 1; + } + break; + case BIO_CTRL_GET_INDENT: + ret = (long)ctx->indent; + break; default: + /* Commands that we intercept before passing them along */ + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + ctx->linestart = 1; + break; + } if (BIO_next(b) != NULL) ret = BIO_ctrl(BIO_next(b), cmd, num, ptr); break; diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c index 3c2b279b..3d293759 100644 --- a/crypto/bio/bss_acpt.c +++ b/crypto/bio/bss_acpt.c @@ -432,7 +432,7 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) b->init = 1; } else if (num == 1) { OPENSSL_free(data->param_serv); - data->param_serv = BUF_strdup(ptr); + data->param_serv = OPENSSL_strdup(ptr); b->init = 1; } else if (num == 2) { data->bind_mode |= BIO_SOCK_NONBLOCK; diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index afcf4367..3abf2354 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -54,6 +54,7 @@ void BIO_CONNECT_free(BIO_CONNECT *a); #define BIO_CONN_S_CONNECT 4 #define BIO_CONN_S_OK 5 #define BIO_CONN_S_BLOCKED_CONNECT 6 +#define BIO_CONN_S_CONNECT_ERROR 7 static const BIO_METHOD methods_connectp = { BIO_TYPE_CONNECT, @@ -172,7 +173,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c) ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), "calling connect(%s, %s)", c->param_hostname, c->param_service); - BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); + c->state = BIO_CONN_S_CONNECT_ERROR; + break; } goto exit_loop; } else { @@ -194,6 +196,11 @@ static int conn_state(BIO *b, BIO_CONNECT *c) c->state = BIO_CONN_S_OK; break; + case BIO_CONN_S_CONNECT_ERROR: + BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); + ret = 0; + goto exit_loop; + case BIO_CONN_S_OK: ret = 1; goto exit_loop; @@ -411,7 +418,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) OPENSSL_free(hold_service); } else if (num == 1) { OPENSSL_free(data->param_service); - data->param_service = BUF_strdup(ptr); + data->param_service = OPENSSL_strdup(ptr); } else if (num == 2) { const BIO_ADDR *addr = (const BIO_ADDR *)ptr; if (ret) { diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index ff961450..fc17c9ed 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -1009,7 +1009,6 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) int ret = 0, n = 0, i, optval; socklen_t optlen; bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - union sctp_notification *snp; struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; @@ -1075,8 +1074,10 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) } if (msg.msg_flags & MSG_NOTIFICATION) { - snp = (union sctp_notification *)out; - if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { + union sctp_notification snp; + + memcpy(&snp, out, sizeof(snp)); + if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { # ifdef SCTP_EVENT struct sctp_event event; # else @@ -1116,17 +1117,19 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) # endif } # ifdef SCTP_AUTHENTICATION_EVENT - if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) - dgram_sctp_handle_auth_free_key_event(b, snp); + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); # endif if (data->handle_notifications != NULL) data->handle_notifications(b, data->notification_context, (void *)out); + memset(&snp, 0, sizeof(snp)); memset(out, 0, outl); - } else + } else { ret += n; + } } while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl)); diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index ed513495..09cc4e30 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -152,7 +152,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; int *ip; # ifndef OPENSSL_NO_KTLS +# ifdef __FreeBSD__ + struct tls_enable *crypto_info; +# else struct tls12_crypto_info_aes_gcm_128 *crypto_info; +# endif # endif switch (cmd) { @@ -183,7 +187,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) break; # ifndef OPENSSL_NO_KTLS case BIO_CTRL_SET_KTLS: +# ifdef __FreeBSD__ + crypto_info = (struct tls_enable *)ptr; +# else crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; +# endif ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); if (ret) BIO_set_ktls_flag(b, num); diff --git a/crypto/bio/build.info b/crypto/bio/build.info index d1e7d73c..8e3f530f 100644 --- a/crypto/bio/build.info +++ b/crypto/bio/build.info @@ -1,8 +1,18 @@ LIBS=../../libcrypto + +# Base library SOURCE[../../libcrypto]=\ bio_lib.c bio_cb.c bio_err.c \ - bss_mem.c bss_null.c bss_fd.c \ - bss_file.c bss_sock.c bss_conn.c \ - bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \ - b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \ - bss_dgram.c bio_meth.c bf_lbuf.c + b_print.c b_dump.c b_addr.c \ + b_sock.c b_sock2.c \ + bio_meth.c + +# Source / sink implementations +SOURCE[../../libcrypto]=\ + bss_null.c bss_mem.c bss_bio.c bss_fd.c bss_file.c \ + bss_sock.c bss_conn.c bss_acpt.c bss_dgram.c \ + bss_log.c + +# Filters +SOURCE[../../libcrypto]=\ + bf_null.c bf_buff.c bf_lbuf.c bf_nbio.c bf_prefix.c diff --git a/crypto/blake2/build.info b/crypto/blake2/build.info deleted file mode 100644 index 8b5ebcec..00000000 --- a/crypto/blake2/build.info +++ /dev/null @@ -1,2 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=m_blake2b.c m_blake2s.c diff --git a/crypto/blake2/m_blake2b.c b/crypto/blake2/m_blake2b.c deleted file mode 100644 index bb3f145a..00000000 --- a/crypto/blake2/m_blake2b.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2019 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 - */ - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include -# include "crypto/evp.h" -# include "prov/blake2.h" - -static int init(EVP_MD_CTX *ctx) -{ - return blake2b512_init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return blake2b_update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return blake2b_final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD blake2b_md = { - NID_blake2b512, - 0, - BLAKE2B_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - BLAKE2B_BLOCKBYTES, - sizeof(BLAKE2B_CTX), -}; - -const EVP_MD *EVP_blake2b512(void) -{ - return &blake2b_md; -} -#endif /* OPENSSL_NO_BLAKE2 */ diff --git a/crypto/blake2/m_blake2s.c b/crypto/blake2/m_blake2s.c deleted file mode 100644 index b04d63ec..00000000 --- a/crypto/blake2/m_blake2s.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2019 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 - */ - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include -# include "crypto/evp.h" -# include "prov/blake2.h" - -static int init(EVP_MD_CTX *ctx) -{ - return blake2s256_init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return blake2s_update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return blake2s_final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD blake2s_md = { - NID_blake2s256, - 0, - BLAKE2S_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - BLAKE2S_BLOCKBYTES, - sizeof(BLAKE2S_CTX), -}; - -const EVP_MD *EVP_blake2s256(void) -{ - return &blake2s_md; -} -#endif /* OPENSSL_NO_BLAKE2 */ diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl index 66822abe..b68a8d61 100755 --- a/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/bn/asm/rsaz-avx2.pl @@ -67,7 +67,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $avx = ($ver>=3.0) + ($ver>=3.01); $addx = ($ver>=3.03); diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl index c41d8e52..e9ff9834 100755 --- a/crypto/bn/asm/rsaz-x86_64.pl +++ b/crypto/bn/asm/rsaz-x86_64.pl @@ -83,7 +83,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } @@ -118,7 +118,7 @@ rsaz_512_sqr: # 25-29% faster than rsaz_512_mul subq \$128+24, %rsp .cfi_adjust_cfa_offset 128+24 .Lsqr_body: - movq $mod, %rbp # common argument + movq $mod, %xmm1 # common off-load movq ($inp), %rdx movq 8($inp), %rax movq $n0, 128(%rsp) @@ -136,7 +136,8 @@ $code.=<<___; .Loop_sqr: movl $times,128+8(%rsp) #first iteration - movq %rdx, %rbx + movq %rdx, %rbx # 0($inp) + mov %rax, %rbp # 8($inp) mulq %rdx movq %rax, %r8 movq 16($inp), %rax @@ -175,31 +176,29 @@ $code.=<<___; mulq %rbx addq %rax, %r14 movq %rbx, %rax - movq %rdx, %r15 - adcq \$0, %r15 + adcq \$0, %rdx - addq %r8, %r8 #shlq \$1, %r8 - movq %r9, %rcx - adcq %r9, %r9 #shld \$1, %r8, %r9 + xorq %rcx,%rcx # rcx:r8 = r8 << 1 + addq %r8, %r8 + movq %rdx, %r15 + adcq \$0, %rcx mulq %rax - movq %rax, (%rsp) - addq %rdx, %r8 - adcq \$0, %r9 + addq %r8, %rdx + adcq \$0, %rcx - movq %r8, 8(%rsp) - shrq \$63, %rcx + movq %rax, (%rsp) + movq %rdx, 8(%rsp) #second iteration - movq 8($inp), %r8 movq 16($inp), %rax - mulq %r8 + mulq %rbp addq %rax, %r10 movq 24($inp), %rax movq %rdx, %rbx adcq \$0, %rbx - mulq %r8 + mulq %rbp addq %rax, %r11 movq 32($inp), %rax adcq \$0, %rdx @@ -207,7 +206,7 @@ $code.=<<___; movq %rdx, %rbx adcq \$0, %rbx - mulq %r8 + mulq %rbp addq %rax, %r12 movq 40($inp), %rax adcq \$0, %rdx @@ -215,7 +214,7 @@ $code.=<<___; movq %rdx, %rbx adcq \$0, %rbx - mulq %r8 + mulq %rbp addq %rax, %r13 movq 48($inp), %rax adcq \$0, %rdx @@ -223,7 +222,7 @@ $code.=<<___; movq %rdx, %rbx adcq \$0, %rbx - mulq %r8 + mulq %rbp addq %rax, %r14 movq 56($inp), %rax adcq \$0, %rdx @@ -231,39 +230,39 @@ $code.=<<___; movq %rdx, %rbx adcq \$0, %rbx - mulq %r8 + mulq %rbp addq %rax, %r15 - movq %r8, %rax + movq %rbp, %rax adcq \$0, %rdx addq %rbx, %r15 - movq %rdx, %r8 - movq %r10, %rdx - adcq \$0, %r8 + adcq \$0, %rdx - add %rdx, %rdx - lea (%rcx,%r10,2), %r10 #shld \$1, %rcx, %r10 - movq %r11, %rbx - adcq %r11, %r11 #shld \$1, %r10, %r11 + xorq %rbx, %rbx # rbx:r10:r9 = r10:r9 << 1 + addq %r9, %r9 + movq %rdx, %r8 + adcq %r10, %r10 + adcq \$0, %rbx mulq %rax + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rcx, %rax + movq 16($inp), %rbp addq %rax, %r9 + movq 24($inp), %rax adcq %rdx, %r10 - adcq \$0, %r11 + adcq \$0, %rbx movq %r9, 16(%rsp) movq %r10, 24(%rsp) - shrq \$63, %rbx #third iteration - movq 16($inp), %r9 - movq 24($inp), %rax - mulq %r9 + mulq %rbp addq %rax, %r12 movq 32($inp), %rax movq %rdx, %rcx adcq \$0, %rcx - mulq %r9 + mulq %rbp addq %rax, %r13 movq 40($inp), %rax adcq \$0, %rdx @@ -271,7 +270,7 @@ $code.=<<___; movq %rdx, %rcx adcq \$0, %rcx - mulq %r9 + mulq %rbp addq %rax, %r14 movq 48($inp), %rax adcq \$0, %rdx @@ -279,9 +278,7 @@ $code.=<<___; movq %rdx, %rcx adcq \$0, %rcx - mulq %r9 - movq %r12, %r10 - lea (%rbx,%r12,2), %r12 #shld \$1, %rbx, %r12 + mulq %rbp addq %rax, %r15 movq 56($inp), %rax adcq \$0, %rdx @@ -289,36 +286,40 @@ $code.=<<___; movq %rdx, %rcx adcq \$0, %rcx - mulq %r9 - shrq \$63, %r10 + mulq %rbp addq %rax, %r8 - movq %r9, %rax + movq %rbp, %rax adcq \$0, %rdx addq %rcx, %r8 - movq %rdx, %r9 - adcq \$0, %r9 + adcq \$0, %rdx - movq %r13, %rcx - leaq (%r10,%r13,2), %r13 #shld \$1, %r12, %r13 + xorq %rcx, %rcx # rcx:r12:r11 = r12:r11 << 1 + addq %r11, %r11 + movq %rdx, %r9 + adcq %r12, %r12 + adcq \$0, %rcx mulq %rax + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rbx, %rax + movq 24($inp), %r10 addq %rax, %r11 + movq 32($inp), %rax adcq %rdx, %r12 - adcq \$0, %r13 + adcq \$0, %rcx movq %r11, 32(%rsp) movq %r12, 40(%rsp) - shrq \$63, %rcx #fourth iteration - movq 24($inp), %r10 - movq 32($inp), %rax + mov %rax, %r11 # 32($inp) mulq %r10 addq %rax, %r14 movq 40($inp), %rax movq %rdx, %rbx adcq \$0, %rbx + mov %rax, %r12 # 40($inp) mulq %r10 addq %rax, %r15 movq 48($inp), %rax @@ -327,9 +328,8 @@ $code.=<<___; movq %rdx, %rbx adcq \$0, %rbx + mov %rax, %rbp # 48($inp) mulq %r10 - movq %r14, %r12 - leaq (%rcx,%r14,2), %r14 #shld \$1, %rcx, %r14 addq %rax, %r8 movq 56($inp), %rax adcq \$0, %rdx @@ -338,32 +338,33 @@ $code.=<<___; adcq \$0, %rbx mulq %r10 - shrq \$63, %r12 addq %rax, %r9 movq %r10, %rax adcq \$0, %rdx addq %rbx, %r9 - movq %rdx, %r10 - adcq \$0, %r10 + adcq \$0, %rdx - movq %r15, %rbx - leaq (%r12,%r15,2),%r15 #shld \$1, %r14, %r15 + xorq %rbx, %rbx # rbx:r13:r14 = r13:r14 << 1 + addq %r13, %r13 + movq %rdx, %r10 + adcq %r14, %r14 + adcq \$0, %rbx mulq %rax + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rcx, %rax addq %rax, %r13 + movq %r12, %rax # 40($inp) adcq %rdx, %r14 - adcq \$0, %r15 + adcq \$0, %rbx movq %r13, 48(%rsp) movq %r14, 56(%rsp) - shrq \$63, %rbx #fifth iteration - movq 32($inp), %r11 - movq 40($inp), %rax mulq %r11 addq %rax, %r8 - movq 48($inp), %rax + movq %rbp, %rax # 48($inp) movq %rdx, %rcx adcq \$0, %rcx @@ -371,97 +372,99 @@ $code.=<<___; addq %rax, %r9 movq 56($inp), %rax adcq \$0, %rdx - movq %r8, %r12 - leaq (%rbx,%r8,2), %r8 #shld \$1, %rbx, %r8 addq %rcx, %r9 movq %rdx, %rcx adcq \$0, %rcx + mov %rax, %r14 # 56($inp) mulq %r11 - shrq \$63, %r12 addq %rax, %r10 movq %r11, %rax adcq \$0, %rdx addq %rcx, %r10 - movq %rdx, %r11 - adcq \$0, %r11 + adcq \$0, %rdx - movq %r9, %rcx - leaq (%r12,%r9,2), %r9 #shld \$1, %r8, %r9 + xorq %rcx, %rcx # rcx:r8:r15 = r8:r15 << 1 + addq %r15, %r15 + movq %rdx, %r11 + adcq %r8, %r8 + adcq \$0, %rcx mulq %rax + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rbx, %rax addq %rax, %r15 + movq %rbp, %rax # 48($inp) adcq %rdx, %r8 - adcq \$0, %r9 + adcq \$0, %rcx movq %r15, 64(%rsp) movq %r8, 72(%rsp) - shrq \$63, %rcx #sixth iteration - movq 40($inp), %r12 - movq 48($inp), %rax mulq %r12 addq %rax, %r10 - movq 56($inp), %rax + movq %r14, %rax # 56($inp) movq %rdx, %rbx adcq \$0, %rbx mulq %r12 addq %rax, %r11 movq %r12, %rax - movq %r10, %r15 - leaq (%rcx,%r10,2), %r10 #shld \$1, %rcx, %r10 adcq \$0, %rdx - shrq \$63, %r15 addq %rbx, %r11 - movq %rdx, %r12 - adcq \$0, %r12 + adcq \$0, %rdx - movq %r11, %rbx - leaq (%r15,%r11,2), %r11 #shld \$1, %r10, %r11 + xorq %rbx, %rbx # rbx:r10:r9 = r10:r9 << 1 + addq %r9, %r9 + movq %rdx, %r12 + adcq %r10, %r10 + adcq \$0, %rbx mulq %rax + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rcx, %rax addq %rax, %r9 + movq %r14, %rax # 56($inp) adcq %rdx, %r10 - adcq \$0, %r11 + adcq \$0, %rbx movq %r9, 80(%rsp) movq %r10, 88(%rsp) #seventh iteration - movq 48($inp), %r13 - movq 56($inp), %rax - mulq %r13 + mulq %rbp addq %rax, %r12 - movq %r13, %rax - movq %rdx, %r13 - adcq \$0, %r13 + movq %rbp, %rax + adcq \$0, %rdx - xorq %r14, %r14 - shlq \$1, %rbx - adcq %r12, %r12 #shld \$1, %rbx, %r12 - adcq %r13, %r13 #shld \$1, %r12, %r13 - adcq %r14, %r14 #shld \$1, %r13, %r14 + xorq %rcx, %rcx # rcx:r12:r11 = r12:r11 << 1 + addq %r11, %r11 + movq %rdx, %r13 + adcq %r12, %r12 + adcq \$0, %rcx mulq %rax + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rbx, %rax addq %rax, %r11 + movq %r14, %rax # 56($inp) adcq %rdx, %r12 - adcq \$0, %r13 + adcq \$0, %rcx movq %r11, 96(%rsp) movq %r12, 104(%rsp) #eighth iteration - movq 56($inp), %rax + xorq %rbx, %rbx # rbx:r13 = r13 << 1 + addq %r13, %r13 + adcq \$0, %rbx + mulq %rax - addq %rax, %r13 - adcq \$0, %rdx - - addq %rdx, %r14 - - movq %r13, 112(%rsp) - movq %r14, 120(%rsp) + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + addq %rcx, %rax + addq %r13, %rax + adcq %rbx, %rdx movq (%rsp), %r8 movq 8(%rsp), %r9 @@ -471,6 +474,10 @@ $code.=<<___; movq 40(%rsp), %r13 movq 48(%rsp), %r14 movq 56(%rsp), %r15 + movq %xmm1, %rbp + + movq %rax, 112(%rsp) + movq %rdx, 120(%rsp) call __rsaz_512_reduce @@ -502,9 +509,9 @@ $code.=<<___; .Loop_sqrx: movl $times,128+8(%rsp) movq $out, %xmm0 # off-load - movq %rbp, %xmm1 # off-load #first iteration mulx %rax, %r8, %r9 + mov %rax, %rbx mulx 16($inp), %rcx, %r10 xor %rbp, %rbp # cf=0, of=0 @@ -512,40 +519,39 @@ $code.=<<___; mulx 24($inp), %rax, %r11 adcx %rcx, %r9 - mulx 32($inp), %rcx, %r12 + .byte 0xc4,0x62,0xf3,0xf6,0xa6,0x20,0x00,0x00,0x00 # mulx 32($inp), %rcx, %r12 adcx %rax, %r10 - mulx 40($inp), %rax, %r13 + .byte 0xc4,0x62,0xfb,0xf6,0xae,0x28,0x00,0x00,0x00 # mulx 40($inp), %rax, %r13 adcx %rcx, %r11 - .byte 0xc4,0x62,0xf3,0xf6,0xb6,0x30,0x00,0x00,0x00 # mulx 48($inp), %rcx, %r14 + mulx 48($inp), %rcx, %r14 adcx %rax, %r12 adcx %rcx, %r13 - .byte 0xc4,0x62,0xfb,0xf6,0xbe,0x38,0x00,0x00,0x00 # mulx 56($inp), %rax, %r15 + mulx 56($inp), %rax, %r15 adcx %rax, %r14 adcx %rbp, %r15 # %rbp is 0 - mov %r9, %rcx - shld \$1, %r8, %r9 - shl \$1, %r8 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx - adcx %rdx, %r8 - mov 8($inp), %rdx - adcx %rbp, %r9 + mulx %rdx, %rax, $out + mov %rbx, %rdx # 8($inp) + xor %rcx, %rcx + adox %r8, %r8 + adcx $out, %r8 + adox %rbp, %rcx + adcx %rbp, %rcx mov %rax, (%rsp) mov %r8, 8(%rsp) #second iteration - mulx 16($inp), %rax, %rbx + .byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x10,0x00,0x00,0x00 # mulx 16($inp), %rax, %rbx adox %rax, %r10 adcx %rbx, %r11 - .byte 0xc4,0x62,0xc3,0xf6,0x86,0x18,0x00,0x00,0x00 # mulx 24($inp), $out, %r8 + mulx 24($inp), $out, %r8 adox $out, %r11 + .byte 0x66 adcx %r8, %r12 mulx 32($inp), %rax, %rbx @@ -563,24 +569,25 @@ $code.=<<___; .byte 0xc4,0x62,0xc3,0xf6,0x86,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r8 adox $out, %r15 adcx %rbp, %r8 + mulx %rdx, %rax, $out adox %rbp, %r8 + .byte 0x48,0x8b,0x96,0x10,0x00,0x00,0x00 # mov 16($inp), %rdx - mov %r11, %rbx - shld \$1, %r10, %r11 - shld \$1, %rcx, %r10 - - xor %ebp,%ebp - mulx %rdx, %rax, %rcx - mov 16($inp), %rdx + xor %rbx, %rbx + adox %r9, %r9 + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rcx, %rax + adox %r10, %r10 adcx %rax, %r9 - adcx %rcx, %r10 - adcx %rbp, %r11 + adox %rbp, %rbx + adcx $out, %r10 + adcx %rbp, %rbx mov %r9, 16(%rsp) .byte 0x4c,0x89,0x94,0x24,0x18,0x00,0x00,0x00 # mov %r10, 24(%rsp) #third iteration - .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x18,0x00,0x00,0x00 # mulx 24($inp), $out, %r9 + mulx 24($inp), $out, %r9 adox $out, %r12 adcx %r9, %r13 @@ -588,7 +595,7 @@ $code.=<<___; adox %rax, %r13 adcx %rcx, %r14 - mulx 40($inp), $out, %r9 + .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x28,0x00,0x00,0x00 # mulx 40($inp), $out, %r9 adox $out, %r14 adcx %r9, %r15 @@ -596,27 +603,28 @@ $code.=<<___; adox %rax, %r15 adcx %rcx, %r8 - .byte 0xc4,0x62,0xc3,0xf6,0x8e,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r9 + mulx 56($inp), $out, %r9 adox $out, %r8 adcx %rbp, %r9 + mulx %rdx, %rax, $out adox %rbp, %r9 - - mov %r13, %rcx - shld \$1, %r12, %r13 - shld \$1, %rbx, %r12 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx - adcx %rax, %r11 - adcx %rdx, %r12 mov 24($inp), %rdx - adcx %rbp, %r13 + + xor %rcx, %rcx + adox %r11, %r11 + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rbx, %rax + adox %r12, %r12 + adcx %rax, %r11 + adox %rbp, %rcx + adcx $out, %r12 + adcx %rbp, %rcx mov %r11, 32(%rsp) - .byte 0x4c,0x89,0xa4,0x24,0x28,0x00,0x00,0x00 # mov %r12, 40(%rsp) + mov %r12, 40(%rsp) #fourth iteration - .byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x20,0x00,0x00,0x00 # mulx 32($inp), %rax, %rbx + mulx 32($inp), %rax, %rbx adox %rax, %r14 adcx %rbx, %r15 @@ -631,25 +639,25 @@ $code.=<<___; mulx 56($inp), $out, %r10 adox $out, %r9 adcx %rbp, %r10 + mulx %rdx, %rax, $out adox %rbp, %r10 - - .byte 0x66 - mov %r15, %rbx - shld \$1, %r14, %r15 - shld \$1, %rcx, %r14 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx - adcx %rax, %r13 - adcx %rdx, %r14 mov 32($inp), %rdx - adcx %rbp, %r15 + + xor %rbx, %rbx + adox %r13, %r13 + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rcx, %rax + adox %r14, %r14 + adcx %rax, %r13 + adox %rbp, %rbx + adcx $out, %r14 + adcx %rbp, %rbx mov %r13, 48(%rsp) mov %r14, 56(%rsp) #fifth iteration - .byte 0xc4,0x62,0xc3,0xf6,0x9e,0x28,0x00,0x00,0x00 # mulx 40($inp), $out, %r11 + mulx 40($inp), $out, %r11 adox $out, %r8 adcx %r11, %r9 @@ -660,18 +668,19 @@ $code.=<<___; mulx 56($inp), $out, %r11 adox $out, %r10 adcx %rbp, %r11 + mulx %rdx, %rax, $out + mov 40($inp), %rdx adox %rbp, %r11 - mov %r9, %rcx - shld \$1, %r8, %r9 - shld \$1, %rbx, %r8 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx + xor %rcx, %rcx + adox %r15, %r15 + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rbx, %rax + adox %r8, %r8 adcx %rax, %r15 - adcx %rdx, %r8 - mov 40($inp), %rdx - adcx %rbp, %r9 + adox %rbp, %rcx + adcx $out, %r8 + adcx %rbp, %rcx mov %r15, 64(%rsp) mov %r8, 72(%rsp) @@ -684,18 +693,19 @@ $code.=<<___; .byte 0xc4,0x62,0xc3,0xf6,0xa6,0x38,0x00,0x00,0x00 # mulx 56($inp), $out, %r12 adox $out, %r11 adcx %rbp, %r12 + mulx %rdx, %rax, $out adox %rbp, %r12 - - mov %r11, %rbx - shld \$1, %r10, %r11 - shld \$1, %rcx, %r10 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx - adcx %rax, %r9 - adcx %rdx, %r10 mov 48($inp), %rdx - adcx %rbp, %r11 + + xor %rbx, %rbx + adox %r9, %r9 + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rcx, %rax + adox %r10, %r10 + adcx %rax, %r9 + adcx $out, %r10 + adox %rbp, %rbx + adcx %rbp, %rbx mov %r9, 80(%rsp) mov %r10, 88(%rsp) @@ -705,31 +715,31 @@ $code.=<<___; adox %rax, %r12 adox %rbp, %r13 - xor %r14, %r14 - shld \$1, %r13, %r14 - shld \$1, %r12, %r13 - shld \$1, %rbx, %r12 - - xor %ebp, %ebp - mulx %rdx, %rax, %rdx - adcx %rax, %r11 - adcx %rdx, %r12 + mulx %rdx, %rax, $out + xor %rcx, %rcx mov 56($inp), %rdx - adcx %rbp, %r13 + adox %r11, %r11 + # rbx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rbx, %rax + adox %r12, %r12 + adcx %rax, %r11 + adox %rbp, %rcx + adcx $out, %r12 + adcx %rbp, %rcx .byte 0x4c,0x89,0x9c,0x24,0x60,0x00,0x00,0x00 # mov %r11, 96(%rsp) .byte 0x4c,0x89,0xa4,0x24,0x68,0x00,0x00,0x00 # mov %r12, 104(%rsp) #eighth iteration mulx %rdx, %rax, %rdx - adox %rax, %r13 - adox %rbp, %rdx + xor %rbx, %rbx + adox %r13, %r13 + # rcx <= 2 and rax <= 0xFFFF..F9, so carry must be zero here + adcx %rcx, %rax + adox %rbp, %rbx + adcx %r13, %rax + adcx %rdx, %rbx - .byte 0x66 - add %rdx, %r14 - - movq %r13, 112(%rsp) - movq %r14, 120(%rsp) movq %xmm0, $out movq %xmm1, %rbp @@ -743,6 +753,9 @@ $code.=<<___; movq 48(%rsp), %r14 movq 56(%rsp), %r15 + movq %rax, 112(%rsp) + movq %rbx, 120(%rsp) + call __rsaz_512_reducex addq 64(%rsp), %r8 @@ -1608,6 +1621,7 @@ $code.=<<___; .type __rsaz_512_reduce,\@abi-omnipotent .align 32 __rsaz_512_reduce: +.cfi_startproc movq %r8, %rbx imulq 128+8(%rsp), %rbx movq 0(%rbp), %rax @@ -1687,6 +1701,7 @@ __rsaz_512_reduce: jne .Lreduction_loop ret +.cfi_endproc .size __rsaz_512_reduce,.-__rsaz_512_reduce ___ } @@ -1700,6 +1715,7 @@ $code.=<<___; .type __rsaz_512_reducex,\@abi-omnipotent .align 32 __rsaz_512_reducex: +.cfi_startproc #movq 128+8(%rsp), %rdx # pull $n0 imulq %r8, %rdx xorq %rsi, %rsi # cf=0,of=0 @@ -1752,6 +1768,7 @@ __rsaz_512_reducex: jne .Lreduction_loopx ret +.cfi_endproc .size __rsaz_512_reducex,.-__rsaz_512_reducex ___ } @@ -1763,6 +1780,7 @@ $code.=<<___; .type __rsaz_512_subtract,\@abi-omnipotent .align 32 __rsaz_512_subtract: +.cfi_startproc movq %r8, ($out) movq %r9, 8($out) movq %r10, 16($out) @@ -1816,6 +1834,7 @@ __rsaz_512_subtract: movq %r15, 56($out) ret +.cfi_endproc .size __rsaz_512_subtract,.-__rsaz_512_subtract ___ } @@ -1829,6 +1848,7 @@ $code.=<<___; .type __rsaz_512_mul,\@abi-omnipotent .align 32 __rsaz_512_mul: +.cfi_startproc leaq 8(%rsp), %rdi movq ($ap), %rax @@ -1967,6 +1987,7 @@ __rsaz_512_mul: movq %r15, 56(%rdi) ret +.cfi_endproc .size __rsaz_512_mul,.-__rsaz_512_mul ___ } @@ -1981,6 +2002,7 @@ $code.=<<___; .type __rsaz_512_mulx,\@abi-omnipotent .align 32 __rsaz_512_mulx: +.cfi_startproc mulx ($ap), %rbx, %r8 # initial %rdx preloaded by caller mov \$-6, %rcx @@ -2097,6 +2119,7 @@ __rsaz_512_mulx: mov %r15, 8+64+56(%rsp) ret +.cfi_endproc .size __rsaz_512_mulx,.-__rsaz_512_mulx ___ } @@ -2107,6 +2130,7 @@ $code.=<<___; .type rsaz_512_scatter4,\@abi-omnipotent .align 16 rsaz_512_scatter4: +.cfi_startproc leaq ($out,$power,8), $out movl \$8, %r9d jmp .Loop_scatter @@ -2119,12 +2143,14 @@ rsaz_512_scatter4: decl %r9d jnz .Loop_scatter ret +.cfi_endproc .size rsaz_512_scatter4,.-rsaz_512_scatter4 .globl rsaz_512_gather4 .type rsaz_512_gather4,\@abi-omnipotent .align 16 rsaz_512_gather4: +.cfi_startproc ___ $code.=<<___ if ($win64); .LSEH_begin_rsaz_512_gather4: @@ -2219,6 +2245,7 @@ ___ $code.=<<___; ret .LSEH_end_rsaz_512_gather4: +.cfi_endproc .size rsaz_512_gather4,.-rsaz_512_gather4 .align 64 diff --git a/crypto/bn/asm/s390x-mont.pl b/crypto/bn/asm/s390x-mont.pl index 00b2d467..6ca0c437 100644 --- a/crypto/bn/asm/s390x-mont.pl +++ b/crypto/bn/asm/s390x-mont.pl @@ -147,7 +147,7 @@ $code.=<<___; lghi $NHI,0 alcgr $NHI,$nhi - la $j,8(%r0) # j=1 + la $j,8 # j=1 lr $count,$num .align 16 @@ -199,7 +199,7 @@ $code.=<<___; lghi $NHI,0 alcgr $NHI,$nhi - la $j,8(%r0) # j=1 + la $j,8 # j=1 lr $count,$num .align 16 @@ -243,7 +243,7 @@ $code.=<<___; la $ap,$stdframe($sp) ahi $num,1 # restore $num, incidentally clears "borrow" - la $j,0(%r0) + la $j,0 lr $count,$num .Lsub: lg $alo,0($j,$ap) lg $nlo,0($j,$np) @@ -257,7 +257,7 @@ $code.=<<___; lghi $NHI,-1 xgr $NHI,$AHI - la $j,0(%r0) + la $j,0 lgr $count,$num .Lcopy: lg $ahi,$stdframe($j,$sp) # conditional copy lg $alo,0($j,$rp) diff --git a/crypto/bn/asm/s390x.S b/crypto/bn/asm/s390x.S index d369a8c4..65a08987 100644 --- a/crypto/bn/asm/s390x.S +++ b/crypto/bn/asm/s390x.S @@ -511,7 +511,7 @@ bn_mul_comba4: lghi zero,0 mul_add_c(0,0,c1,c2,c3); - stg c1,0*8(%r3) + stg c1,0*8(%r2) lghi c1,0 mul_add_c(0,1,c2,c3,c1); diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl index aa06345f..9e425b22 100755 --- a/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/bn/asm/x86_64-mont.pl @@ -77,7 +77,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index d6d2764e..5e705477 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -62,7 +62,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } @@ -582,6 +582,7 @@ $code.=<<___; .type mul4x_internal,\@abi-omnipotent .align 32 mul4x_internal: +.cfi_startproc shl \$5,$num # $num was in bytes movd `($win64?56:8)`(%rax),%xmm5 # load 7th argument, index lea .Linc(%rip),%rax @@ -1076,6 +1077,7 @@ $code.=<<___ ___ } $code.=<<___; +.cfi_endproc .size mul4x_internal,.-mul4x_internal ___ }}} @@ -1241,6 +1243,7 @@ $code.=<<___; .align 32 bn_sqr8x_internal: __bn_sqr8x_internal: +.cfi_startproc ############################################################## # Squaring part: # @@ -2032,6 +2035,7 @@ __bn_sqr8x_reduction: cmp %rdx,$tptr # end of t[]? jb .L8x_reduction_loop ret +.cfi_endproc .size bn_sqr8x_internal,.-bn_sqr8x_internal ___ } @@ -2044,6 +2048,7 @@ $code.=<<___; .type __bn_post4x_internal,\@abi-omnipotent .align 32 __bn_post4x_internal: +.cfi_startproc mov 8*0($nptr),%r12 lea (%rdi,$num),$tptr # %rdi was $tptr above mov $num,%rcx @@ -2094,6 +2099,7 @@ __bn_post4x_internal: mov $num,%r10 # prepare for back-to-back call neg $num # restore $num ret +.cfi_endproc .size __bn_post4x_internal,.-__bn_post4x_internal ___ } @@ -2103,10 +2109,12 @@ $code.=<<___; .type bn_from_montgomery,\@abi-omnipotent .align 32 bn_from_montgomery: +.cfi_startproc testl \$7,`($win64?"48(%rsp)":"%r9d")` jz bn_from_mont8x xor %eax,%eax ret +.cfi_endproc .size bn_from_montgomery,.-bn_from_montgomery .type bn_from_mont8x,\@function,6 @@ -2402,6 +2410,7 @@ bn_mulx4x_mont_gather5: .type mulx4x_internal,\@abi-omnipotent .align 32 mulx4x_internal: +.cfi_startproc mov $num,8(%rsp) # save -$num (it was in bytes) mov $num,%r10 neg $num # restore $num @@ -2752,6 +2761,7 @@ $code.=<<___; mov 8*2(%rbp),%r14 mov 8*3(%rbp),%r15 jmp .Lsqrx4x_sub_entry # common post-condition +.cfi_endproc .size mulx4x_internal,.-mulx4x_internal ___ } { @@ -3557,6 +3567,7 @@ my ($rptr,$nptr)=("%rdx","%rbp"); $code.=<<___; .align 32 __bn_postx4x_internal: +.cfi_startproc mov 8*0($nptr),%r12 mov %rcx,%r10 # -$num mov %rcx,%r9 # -$num @@ -3604,6 +3615,7 @@ __bn_postx4x_internal: neg %r9 # restore $num ret +.cfi_endproc .size __bn_postx4x_internal,.-__bn_postx4x_internal ___ } @@ -3620,6 +3632,7 @@ $code.=<<___; .type bn_get_bits5,\@abi-omnipotent .align 16 bn_get_bits5: +.cfi_startproc lea 0($inp),%r10 lea 1($inp),%r11 mov $num,%ecx @@ -3633,12 +3646,14 @@ bn_get_bits5: shrl %cl,%eax and \$31,%eax ret +.cfi_endproc .size bn_get_bits5,.-bn_get_bits5 .globl bn_scatter5 .type bn_scatter5,\@abi-omnipotent .align 16 bn_scatter5: +.cfi_startproc cmp \$0, $num jz .Lscatter_epilogue lea ($tbl,$idx,8),$tbl @@ -3651,6 +3666,7 @@ bn_scatter5: jnz .Lscatter .Lscatter_epilogue: ret +.cfi_endproc .size bn_scatter5,.-bn_scatter5 .globl bn_gather5 @@ -3658,6 +3674,7 @@ bn_scatter5: .align 32 bn_gather5: .LSEH_begin_bn_gather5: # Win64 thing, but harmless in other cases +.cfi_startproc # I can't trust assembler to use specific encoding:-( .byte 0x4c,0x8d,0x14,0x24 #lea (%rsp),%r10 .byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 #sub $0x108,%rsp @@ -3742,6 +3759,7 @@ $code.=<<___; lea (%r10),%rsp ret .LSEH_end_bn_gather5: +.cfi_endproc .size bn_gather5,.-bn_gather5 ___ } diff --git a/crypto/bn/bn_depr.c b/crypto/bn/bn_depr.c index 4dbbdc38..9c1c3d57 100644 --- a/crypto/bn/bn_depr.c +++ b/crypto/bn/bn_depr.c @@ -13,7 +13,7 @@ */ #include -#if OPENSSL_API_0_9_8 +#ifdef OPENSSL_NO_DEPRECATED_0_9_8 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c index fbefe4ab..bed9fca4 100644 --- a/crypto/bn/bn_gcd.c +++ b/crypto/bn/bn_gcd.c @@ -593,7 +593,9 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) for (i = 0; i < m; i++) { /* conditionally flip signs if delta is positive and g is odd */ - cond = (-delta >> (8 * sizeof(delta) - 1)) & g->d[0] & 1; + cond = (-delta >> (8 * sizeof(delta) - 1)) & g->d[0] & 1 + /* make sure g->top > 0 (i.e. if top == 0 then g == 0 always) */ + & (~((g->top - 1) >> (sizeof(g->top) * 8 - 1))); delta = (-cond & -delta) | ((cond - 1) & delta); r->neg ^= cond; /* swap */ @@ -603,7 +605,10 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) delta++; if (!BN_add(temp, g, r)) goto err; - BN_consttime_swap(g->d[0] & 1, g, temp, top); + BN_consttime_swap(g->d[0] & 1 /* g is odd */ + /* make sure g->top > 0 (i.e. if top == 0 then g == 0 always) */ + & (~((g->top - 1) >> (sizeof(g->top) * 8 - 1))), + g, temp, top); if (!BN_rshift1(g, g)) goto err; } diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index bdd4caa2..1e62b968 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -15,7 +15,7 @@ #include "internal/constant_time.h" /* This stuff appears to be completely unused, so is deprecated */ -#if !OPENSSL_API_0_9_8 +#ifndef OPENSSL_NO_DEPRECATED_0_9_8 /*- * For a 32 bit machine * 2 - 4 == 128 diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index fd1c3c30..ce5789ea 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -224,7 +224,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, } #endif -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) { diff --git a/crypto/bn/bn_prime.h b/crypto/bn/bn_prime.h index e99433cd..ef16bb43 100644 --- a/crypto/bn/bn_prime.h +++ b/crypto/bn/bn_prime.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/bn/bn_prime.pl * - * Copyright 1998-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2020 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/crypto/bn/bn_prime.pl b/crypto/bn/bn_prime.pl index 76df3fc5..b6b546b9 100644 --- a/crypto/bn/bn_prime.pl +++ b/crypto/bn/bn_prime.pl @@ -6,8 +6,8 @@ # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html -# Output year depends on the year of the script. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; +# The year the output file is generated. +my $YEAR = [localtime()]->[5] + 1900; print <<"EOF"; /* * WARNING: do not edit! diff --git a/crypto/bn/bn_rsa_fips186_4.c b/crypto/bn/bn_rsa_fips186_4.c index c31b43ba..492eb297 100644 --- a/crypto/bn/bn_rsa_fips186_4.c +++ b/crypto/bn/bn_rsa_fips186_4.c @@ -31,6 +31,27 @@ #include #include "bn_local.h" #include "crypto/bn.h" +#include "internal/nelem.h" + +#if BN_BITS2 == 64 +# define BN_DEF(lo, hi) (BN_ULONG)hi<<32|lo +#else +# define BN_DEF(lo, hi) lo, hi +#endif + +/* 1 / sqrt(2) * 2^256, rounded up */ +static const BN_ULONG inv_sqrt_2_val[] = { + BN_DEF(0x83339916UL, 0xED17AC85UL), BN_DEF(0x893BA84CUL, 0x1D6F60BAUL), + BN_DEF(0x754ABE9FUL, 0x597D89B3UL), BN_DEF(0xF9DE6484UL, 0xB504F333UL) +}; + +const BIGNUM bn_inv_sqrt_2 = { + (BN_ULONG *)inv_sqrt_2_val, + OSSL_NELEM(inv_sqrt_2_val), + OSSL_NELEM(inv_sqrt_2_val), + 0, + BN_FLG_STATIC_DATA +}; /* * FIPS 186-4 Table B.1. "Min length of auxiliary primes p1, p2, q1, q2". @@ -221,9 +242,12 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, int i, imax; int bits = nlen >> 1; BIGNUM *tmp, *R, *r1r2x2, *y1, *r1x2; + BIGNUM *base, *range; BN_CTX_start(ctx); + base = BN_CTX_get(ctx); + range = BN_CTX_get(ctx); R = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); r1r2x2 = BN_CTX_get(ctx); @@ -235,6 +259,24 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, if (Xin != NULL && BN_copy(X, Xin) == NULL) goto err; + /* + * We need to generate a random number X in the range + * 1/sqrt(2) * 2^(nlen/2) <= X < 2^(nlen/2). + * We can rewrite that as: + * base = 1/sqrt(2) * 2^(nlen/2) + * range = ((2^(nlen/2))) - (1/sqrt(2) * 2^(nlen/2)) + * X = base + random(range) + * We only have the first 256 bit of 1/sqrt(2) + */ + if (Xin == NULL) { + if (bits < BN_num_bits(&bn_inv_sqrt_2)) + goto err; + if (!BN_lshift(base, &bn_inv_sqrt_2, bits - BN_num_bits(&bn_inv_sqrt_2)) + || !BN_lshift(range, BN_value_one(), bits) + || !BN_sub(range, range, base)) + goto err; + } + if (!(BN_lshift1(r1x2, r1) /* (Step 1) GCD(2r1, r2) = 1 */ && BN_gcd(tmp, r1x2, r2, ctx) @@ -257,16 +299,9 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, if (Xin == NULL) { /* * (Step 3) Choose Random X such that - * sqrt(2) * 2^(nlen/2-1) < Random X < (2^(nlen/2)) - 1. - * - * For the lower bound: - * sqrt(2) * 2^(nlen/2 - 1) == sqrt(2)/2 * 2^(nlen/2) - * where sqrt(2)/2 = 0.70710678.. = 0.B504FC33F9DE... - * so largest number will have B5... as the top byte - * Setting the top 2 bits gives 0xC0. + * sqrt(2) * 2^(nlen/2-1) <= Random X <= (2^(nlen/2)) - 1. */ - if (!BN_priv_rand_ex(X, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, - ctx)) + if (!BN_priv_rand_range_ex(X, range, ctx) || !BN_add(X, X, base)) goto end; } /* (Step 4) Y = X + ((R - X) mod 2r1r2) */ diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c index cdf66933..5481609d 100644 --- a/crypto/bn/bn_shift.c +++ b/crypto/bn/bn_shift.c @@ -34,12 +34,10 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a) for (i = 0; i < a->top; i++) { t = *(ap++); *(rp++) = ((t << 1) | c) & BN_MASK2; - c = (t & BN_TBIT) ? 1 : 0; - } - if (c) { - *rp = 1; - r->top++; + c = t >> (BN_BITS2 - 1); } + *rp = c; + r->top += c; bn_check_top(r); return 1; } @@ -47,7 +45,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a) int BN_rshift1(BIGNUM *r, const BIGNUM *a) { BN_ULONG *ap, *rp, t, c; - int i, j; + int i; bn_check_top(r); bn_check_top(a); @@ -58,23 +56,22 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a) } i = a->top; ap = a->d; - j = i - (ap[i - 1] == 1); if (a != r) { - if (bn_wexpand(r, j) == NULL) + if (bn_wexpand(r, i) == NULL) return 0; r->neg = a->neg; } rp = r->d; + r->top = i; t = ap[--i]; - c = (t & 1) ? BN_TBIT : 0; - if (t >>= 1) - rp[i] = t; + rp[i] = t >> 1; + c = t << (BN_BITS2 - 1); + r->top -= (t == 1); while (i > 0) { t = ap[--i]; rp[i] = ((t >> 1) & BN_MASK2) | c; - c = (t & 1) ? BN_TBIT : 0; + c = t << (BN_BITS2 - 1); } - r->top = j; if (!r->top) r->neg = 0; /* don't allow negative zero */ bn_check_top(r); diff --git a/crypto/build.info b/crypto/build.info index 7d3eb295..daa26b8e 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -1,11 +1,11 @@ # Note that these directories are filtered in Configure. Look for %skipdir # there for further explanations. SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ - txt_db pkcs7 pkcs12 ui store property \ - md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 blake2 \ + txt_db pkcs7 pkcs12 ui kdf store property \ + md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ - err comp ocsp cms ts srp cmac ct async ess crmf cmp + err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer LIBS=../libcrypto @@ -62,7 +62,7 @@ ENDIF $CORE_COMMON=provider_core.c provider_predefined.c \ core_fetch.c core_algorithm.c core_namemap.c -SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c +SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c self_test_core.c SOURCE[../providers/libfips.a]=$CORE_COMMON # Central utilities @@ -73,7 +73,7 @@ $UTIL_COMMON=\ $UTIL_DEFINE=$CPUIDDEF SOURCE[../libcrypto]=$UTIL_COMMON \ - mem.c mem_sec.c mem_dbg.c \ + 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 o_fips.c init.c trace.c provider.c \ $UPLINKSRC @@ -85,6 +85,7 @@ DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF DEFINE[../providers/libfips.a]=$UTIL_DEFINE DEFINE[../providers/fips]=$UTIL_DEFINE DEFINE[../providers/libimplementations.a]=$UTIL_DEFINE +DEFINE[../providers/libcommon.a]=$UTIL_DEFINE DEPEND[info.o]=buildinf.h DEPEND[cversion.o]=buildinf.h diff --git a/crypto/camellia/asm/cmll-x86_64.pl b/crypto/camellia/asm/cmll-x86_64.pl index bd1e4c06..d0a45f27 100644 --- a/crypto/camellia/asm/cmll-x86_64.pl +++ b/crypto/camellia/asm/cmll-x86_64.pl @@ -127,11 +127,13 @@ $code=<<___; .type Camellia_EncryptBlock,\@abi-omnipotent .align 16 Camellia_EncryptBlock: +.cfi_startproc movl \$128,%eax subl $arg0d,%eax movl \$3,$arg0d adcl \$0,$arg0d # keyBitLength==128?3:4 jmp .Lenc_rounds +.cfi_endproc .size Camellia_EncryptBlock,.-Camellia_EncryptBlock # V2 .globl Camellia_EncryptBlock_Rounds @@ -200,6 +202,7 @@ Camellia_EncryptBlock_Rounds: .type _x86_64_Camellia_encrypt,\@abi-omnipotent .align 16 _x86_64_Camellia_encrypt: +.cfi_startproc xor 0($key),@S[1] xor 4($key),@S[0] # ^=key[0-3] xor 8($key),@S[3] @@ -243,6 +246,7 @@ $code.=<<___; mov $t3,@S[3] .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt # V1.x API @@ -250,11 +254,13 @@ $code.=<<___; .type Camellia_DecryptBlock,\@abi-omnipotent .align 16 Camellia_DecryptBlock: +.cfi_startproc movl \$128,%eax subl $arg0d,%eax movl \$3,$arg0d adcl \$0,$arg0d # keyBitLength==128?3:4 jmp .Ldec_rounds +.cfi_endproc .size Camellia_DecryptBlock,.-Camellia_DecryptBlock # V2 .globl Camellia_DecryptBlock_Rounds @@ -323,6 +329,7 @@ Camellia_DecryptBlock_Rounds: .type _x86_64_Camellia_decrypt,\@abi-omnipotent .align 16 _x86_64_Camellia_decrypt: +.cfi_startproc xor 0($key),@S[1] xor 4($key),@S[0] # ^=key[0-3] xor 8($key),@S[3] @@ -367,6 +374,7 @@ $code.=<<___; mov $t1,@S[3] .byte 0xf3,0xc3 # rep ret +.cfi_endproc .size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt ___ diff --git a/crypto/camellia/build.info b/crypto/camellia/build.info index c10babc7..02f9afeb 100644 --- a/crypto/camellia/build.info +++ b/crypto/camellia/build.info @@ -10,10 +10,12 @@ IF[{- !$disabled{asm} -}] # appropriate one IF[$CMLLASM_{- $target{asm_arch} -}] $CMLLASM=$CMLLASM_{- $target{asm_arch} -} + $CMLLDEF=CMLL_ASM ENDIF ENDIF SOURCE[../../libcrypto]=cmll_ecb.c cmll_ofb.c cmll_cfb.c cmll_ctr.c $CMLLASM +DEFINE[../../libcrypto]=$CMLLDEF GENERATE[cmll-x86.s]=asm/cmll-x86.pl DEPEND[cmll-x86.s]=../perlasm/x86asm.pl diff --git a/crypto/camellia/camellia.c b/crypto/camellia/camellia.c index cb285d05..fd493a8a 100644 --- a/crypto/camellia/camellia.c +++ b/crypto/camellia/camellia.c @@ -39,6 +39,12 @@ * words reasonable performance even with not so modern compilers. */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cmll_local.h" #include diff --git a/crypto/camellia/cmll_cbc.c b/crypto/camellia/cmll_cbc.c index 14724bf2..92b729e0 100644 --- a/crypto/camellia/cmll_cbc.c +++ b/crypto/camellia/cmll_cbc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/camellia/cmll_cfb.c b/crypto/camellia/cmll_cfb.c index 054f79c0..5b169a4f 100644 --- a/crypto/camellia/cmll_cfb.c +++ b/crypto/camellia/cmll_cfb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/camellia/cmll_ctr.c b/crypto/camellia/cmll_ctr.c index bb36560c..fa00150e 100644 --- a/crypto/camellia/cmll_ctr.c +++ b/crypto/camellia/cmll_ctr.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/camellia/cmll_ecb.c b/crypto/camellia/cmll_ecb.c index 6a2c7775..bb3e519d 100644 --- a/crypto/camellia/cmll_ecb.c +++ b/crypto/camellia/cmll_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cmll_local.h" diff --git a/crypto/camellia/cmll_misc.c b/crypto/camellia/cmll_misc.c index b38fcc04..3cc10c99 100644 --- a/crypto/camellia/cmll_misc.c +++ b/crypto/camellia/cmll_misc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "cmll_local.h" diff --git a/crypto/camellia/cmll_ofb.c b/crypto/camellia/cmll_ofb.c index 9ef51299..0073a77c 100644 --- a/crypto/camellia/cmll_ofb.c +++ b/crypto/camellia/cmll_ofb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/cast/c_cfb64.c b/crypto/cast/c_cfb64.c index 1ae13bc3..805a51d4 100644 --- a/crypto/cast/c_cfb64.c +++ b/crypto/cast/c_cfb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/cast/c_ecb.c b/crypto/cast/c_ecb.c index 2b841ac9..cbd04436 100644 --- a/crypto/cast/c_ecb.c +++ b/crypto/cast/c_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" #include diff --git a/crypto/cast/c_enc.c b/crypto/cast/c_enc.c index 7e2461df..ede9f2e8 100644 --- a/crypto/cast/c_enc.c +++ b/crypto/cast/c_enc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/cast/c_ofb64.c b/crypto/cast/c_ofb64.c index bc598d4d..6aaa7edf 100644 --- a/crypto/cast/c_ofb64.c +++ b/crypto/cast/c_ofb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/cast/c_skey.c b/crypto/cast/c_skey.c index c21ecdf8..d516e10e 100644 --- a/crypto/cast/c_skey.c +++ b/crypto/cast/c_skey.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" #include "cast_s.h" diff --git a/crypto/chacha/asm/chacha-armv8.pl b/crypto/chacha/asm/chacha-armv8.pl index aed873d5..7868389f 100755 --- a/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/chacha/asm/chacha-armv8.pl @@ -1232,8 +1232,7 @@ $code.=<<___; adds $len,$len,#512 ushr $ONE,$ONE,#1 // 4 -> 2 - ldp d8,d9,[sp,#128+0] // meet ABI requirements - ldp d10,d11,[sp,#128+16] + ldp d10,d11,[sp,#128+16] // meet ABI requirements ldp d12,d13,[sp,#128+32] ldp d14,d15,[sp,#128+48] @@ -1250,6 +1249,7 @@ $code.=<<___; ld1 {$CTR,$ROT24},[$key] b.hs .Loop_outer_neon + ldp d8,d9,[sp,#0] // meet ABI requirements eor @K[1],@K[1],@K[1] eor @K[2],@K[2],@K[2] eor @K[3],@K[3],@K[3] @@ -1259,6 +1259,7 @@ $code.=<<___; b .Loop_outer .Ldone_512_neon: + ldp d8,d9,[sp,#128+0] // meet ABI requirements ldp x19,x20,[x29,#16] add sp,sp,#128+64 ldp x21,x22,[x29,#32] diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl index 1f577b86..9e29ebcc 100755 --- a/crypto/chacha/asm/chacha-s390x.pl +++ b/crypto/chacha/asm/chacha-s390x.pl @@ -40,7 +40,7 @@ use strict; use FindBin qw($Bin); use lib "$Bin/../.."; -use perlasm::s390x qw(:DEFAULT :VX :LD AUTOLOAD LABEL INCLUDE); +use perlasm::s390x qw(:DEFAULT :VX :EI AUTOLOAD LABEL INCLUDE); # $output is the last argument if it looks like a file (it has an extension) # $flavour is the first argument if it doesn't look like a file diff --git a/crypto/chacha/asm/chacha-x86.pl b/crypto/chacha/asm/chacha-x86.pl index bcd8eb4b..566a8b79 100755 --- a/crypto/chacha/asm/chacha-x86.pl +++ b/crypto/chacha/asm/chacha-x86.pl @@ -61,7 +61,7 @@ $ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" && $1>=10); # first version supporting AVX $ymm=1 if ($xmm && !$ymm && - `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9]\.[0-9]+)/ && + `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); # first version supporting AVX $a="eax"; diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl index b854e2e3..fee0a963 100755 --- a/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/chacha/asm/chacha-x86_64.pl @@ -86,7 +86,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/chacha/chacha_enc.c b/crypto/chacha/chacha_enc.c index 05a716b5..3cf5facd 100644 --- a/crypto/chacha/chacha_enc.c +++ b/crypto/chacha/chacha_enc.c @@ -12,6 +12,7 @@ #include #include "crypto/chacha.h" +#include "crypto/ctype.h" typedef unsigned int u32; typedef unsigned char u8; @@ -78,10 +79,18 @@ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t todo, i; /* sigma constant "expand 32-byte k" in little-endian encoding */ - input[0] = ((u32)'e') | ((u32)'x'<<8) | ((u32)'p'<<16) | ((u32)'a'<<24); - input[1] = ((u32)'n') | ((u32)'d'<<8) | ((u32)' '<<16) | ((u32)'3'<<24); - input[2] = ((u32)'2') | ((u32)'-'<<8) | ((u32)'b'<<16) | ((u32)'y'<<24); - input[3] = ((u32)'t') | ((u32)'e'<<8) | ((u32)' '<<16) | ((u32)'k'<<24); + input[0] = ((u32)ossl_toascii('e')) | ((u32)ossl_toascii('x') << 8) + | ((u32)ossl_toascii('p') << 16) + | ((u32)ossl_toascii('a') << 24); + input[1] = ((u32)ossl_toascii('n')) | ((u32)ossl_toascii('d') << 8) + | ((u32)ossl_toascii(' ') << 16) + | ((u32)ossl_toascii('3') << 24); + input[2] = ((u32)ossl_toascii('2')) | ((u32)ossl_toascii('-') << 8) + | ((u32)ossl_toascii('b') << 16) + | ((u32)ossl_toascii('y') << 24); + input[3] = ((u32)ossl_toascii('t')) | ((u32)ossl_toascii('e') << 8) + | ((u32)ossl_toascii(' ') << 16) + | ((u32)ossl_toascii('k') << 24); input[4] = key[0]; input[5] = key[1]; diff --git a/crypto/cmp/build.info b/crypto/cmp/build.info index d5ce60e0..760c3423 100644 --- a/crypto/cmp/build.info +++ b/crypto/cmp/build.info @@ -1,2 +1,3 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c +SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \ + cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index fa7c26d7..ca121b06 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -164,7 +164,7 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, { int created = 0; - if (itav_sk_p == NULL) { + if (itav_sk_p == NULL || itav == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); goto err; } @@ -174,11 +174,10 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, goto err; created = 1; } - if (itav != NULL) { - if (!sk_OSSL_CMP_ITAV_push(*itav_sk_p, itav)) - goto err; - } + if (!sk_OSSL_CMP_ITAV_push(*itav_sk_p, itav)) + goto err; return 1; + err: if (created != 0) { sk_OSSL_CMP_ITAV_free(*itav_sk_p); diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index 6ec23ad8..0bd12f47 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -68,14 +68,21 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx) */ int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) { + STACK_OF(X509) *untrusted_certs; if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return 0; } - sk_X509_pop_free(ctx->untrusted_certs, X509_free); - if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL) + if ((untrusted_certs = sk_X509_new_null()) == NULL) return 0; - return ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, certs, 0, 1, 0); + if (ossl_cmp_sk_X509_add1_certs(untrusted_certs, certs, 0, 1, 0) != 1) + goto err; + sk_X509_pop_free(ctx->untrusted_certs, X509_free); + ctx->untrusted_certs = untrusted_certs; + return 1; +err: + sk_X509_pop_free(untrusted_certs, X509_free); + return 0; } /* @@ -195,7 +202,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status) { if (!ossl_assert(ctx != NULL)) - return 0; + return 0; ctx->status = status; return 1; } @@ -373,13 +380,19 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, const int len) { + ASN1_OCTET_STRING *secretValue = NULL; if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return 0; } - if (ctx->secretValue != NULL) + if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1) + return 0; + if (ctx->secretValue != NULL) { OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length); - return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->secretValue, sec, len); + ASN1_OCTET_STRING_free(ctx->secretValue); + } + ctx->secretValue = secretValue; + return 1; } /* @@ -933,7 +946,8 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx) * Sets a Boolean or integer option of the context to the "val" arg. * Returns 1 on success, 0 on error */ -int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) { +int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) +{ int min_val; if (ctx == NULL) { @@ -1036,7 +1050,8 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) { * Reads a Boolean or integer option value from the context. * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON) */ -int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) { +int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) +{ if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return -1; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 4086d522..8b4a6ca7 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -1,7 +1,6 @@ /* - * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Nokia 2007-2019 - * Copyright Siemens AG 2015-2019 + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 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 @@ -15,11 +14,69 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA CMP_str_reasons[] = { + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND), + "certificate not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND), + "certresponse not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH), + "cert and key do not match"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION), + "error calculating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF), + "error creating certconf"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP), + "error creating certrep"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR), + "error creating error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM), + "error creating genm"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP), + "error creating genp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_P10CR), + "error creating p10cr"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF), + "error creating pkiconf"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREP), + "error creating pollrep"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREQ), + "error creating pollreq"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RP), "error creating rp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS), + "error parsing pkistatus"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE), + "error protecting message"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH), + "error setting certhash"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM), + "failure obtaining random"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE), + "fail info out of range"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION), + "missing key input for creating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY), + "missing private key"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SENDER_IDENTIFICATION), + "missing sender identification"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES), "multiple san sources"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND), + "pkistatusinfo not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID), + "unknown algorithm id"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM), + "unsupported algorithm"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE), + "unsupported key type"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID), + "wrong algorithm oid"}, {0, NULL} }; diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c new file mode 100644 index 00000000..29f477f1 --- /dev/null +++ b/crypto/cmp/cmp_hdr.c @@ -0,0 +1,377 @@ +/* + * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * 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 + */ + +/* CMP functions for PKIHeader handling */ + +#include "cmp_local.h" + +#include + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include + +int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return ASN1_INTEGER_set(hdr->pvno, pvno); +} + +int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr) +{ + int64_t pvno; + + if (!ossl_assert(hdr != NULL)) + return -1; + if (!ASN1_INTEGER_get_int64(&pvno, hdr->pvno) || pvno < 0 || pvno > INT_MAX) + return -1; + return (int)pvno; +} + +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr) +{ + if (hdr == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return NULL; + } + return hdr->transactionID; +} + +ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL)) + return NULL; + return hdr->senderNonce; +} + +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr) +{ + if (hdr == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return NULL; + } + return hdr->recipNonce; +} + +/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */ +static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src) +{ + GENERAL_NAME *gen; + + if (!ossl_assert(tgt != NULL)) + return 0; + if ((gen = GENERAL_NAME_new()) == NULL) + goto err; + gen->type = GEN_DIRNAME; + + if (src == NULL) { /* NULL-DN */ + if ((gen->d.directoryName = X509_NAME_new()) == NULL) + goto err; + } else if (!X509_NAME_set(&gen->d.directoryName, src)) { + goto err; + } + + GENERAL_NAME_free(*tgt); + *tgt = gen; + + return 1; + + err: + GENERAL_NAME_free(gen); + return 0; +} + +/* + * Set the sender name in PKIHeader. + * when nm is NULL, sender is set to an empty string + * returns 1 on success, 0 on error + */ +int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return set1_general_name(&hdr->sender, nm); +} + +int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return set1_general_name(&hdr->recipient, nm); +} + +int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + if (hdr->messageTime == NULL + && (hdr->messageTime = ASN1_GENERALIZEDTIME_new()) == NULL) + return 0; + return ASN1_GENERALIZEDTIME_set(hdr->messageTime, time(NULL)) != NULL; +} + +/* assign to *tgt a copy of src (or if NULL a random byte array of given len) */ +static int set1_aostr_else_random(ASN1_OCTET_STRING **tgt, + const ASN1_OCTET_STRING *src, size_t len) +{ + unsigned char *bytes = NULL; + int res = 0; + + if (src == NULL) { /* generate a random value if src == NULL */ + if ((bytes = OPENSSL_malloc(len)) == NULL) + goto err; + if (RAND_bytes(bytes, len) <= 0) { + CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM); + goto err; + } + res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len); + } else { + res = ossl_cmp_asn1_octet_string_set1(tgt, src); + } + + err: + OPENSSL_free(bytes); + return res; +} + +int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return ossl_cmp_asn1_octet_string_set1(&hdr->senderKID, senderKID); +} + +/* push the given text string to the given PKIFREETEXT ft */ +int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text) +{ + ASN1_UTF8STRING *utf8string; + + if (!ossl_assert(ft != NULL && text != NULL)) + return 0; + if ((utf8string = ASN1_UTF8STRING_new()) == NULL) + return 0; + if (!ASN1_STRING_set(utf8string, text, -1)) + goto err; + if (!sk_ASN1_UTF8STRING_push(ft, utf8string)) + goto err; + return 1; + + err: + ASN1_UTF8STRING_free(utf8string); + return 0; +} + +int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text) +{ + if (!ossl_assert(hdr != NULL && text != NULL)) + return 0; + + if (hdr->freeText == NULL + && (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL) + return 0; + + return sk_ASN1_UTF8STRING_push(hdr->freeText, text); +} + +int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text) +{ + if (!ossl_assert(hdr != NULL && text != NULL)) + return 0; + + if (hdr->freeText == NULL + && (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL) + return 0; + + return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data); +} + +int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav) +{ + if (!ossl_assert(hdr != NULL && itav != NULL)) + return 0; + return OSSL_CMP_ITAV_push0_stack_item(&hdr->generalInfo, itav); +} + +int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr, + STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + int i; + OSSL_CMP_ITAV *itav; + + if (!ossl_assert(hdr != NULL)) + return 0; + + for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { + itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i)); + if (itav == NULL) + return 0; + + if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav)) { + OSSL_CMP_ITAV_free(itav); + return 0; + } + } + return 1; +} + +int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr) +{ + OSSL_CMP_ITAV *itav; + ASN1_TYPE *asn1null; + + if (!ossl_assert(hdr != NULL)) + return 0; + asn1null = (ASN1_TYPE *)ASN1_NULL_new(); + if (asn1null == NULL) + return 0; + if ((itav = OSSL_CMP_ITAV_create(OBJ_nid2obj(NID_id_it_implicitConfirm), + asn1null)) == NULL) + goto err; + if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav)) + goto err; + return 1; + + err: + ASN1_TYPE_free(asn1null); + OSSL_CMP_ITAV_free(itav); + return 0; +} + +/* return 1 if implicitConfirm in the generalInfo field of the header is set */ +int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr) +{ + int itavCount; + int i; + OSSL_CMP_ITAV *itav; + + if (!ossl_assert(hdr != NULL)) + return 0; + + itavCount = sk_OSSL_CMP_ITAV_num(hdr->generalInfo); + for (i = 0; i < itavCount; i++) { + itav = sk_OSSL_CMP_ITAV_value(hdr->generalInfo, i); + if (itav != NULL + && OBJ_obj2nid(itav->infoType) == NID_id_it_implicitConfirm) + return 1; + } + + return 0; +} + +/* fill in all fields of the hdr according to the info given in ctx */ +int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) +{ + X509_NAME *sender; + X509_NAME *rcp = NULL; + + if (!ossl_assert(ctx != NULL && hdr != NULL)) + return 0; + + /* set the CMP version */ + if (!ossl_cmp_hdr_set_pvno(hdr, OSSL_CMP_PVNO)) + return 0; + + sender = ctx->clCert != NULL ? + X509_get_subject_name(ctx->clCert) : ctx->subjectName; + /* + * The sender name is copied from the subject of the client cert, if any, + * or else from the the subject name provided for certification requests. + * As required by RFC 4210 section 5.1.1., if the sender name is not known + * to the client it set to NULL-DN. In this case for identification at least + * the senderKID must be set, which we take from any referenceValue given. + */ + if (sender == NULL && ctx->referenceValue == NULL) { + CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION); + return 0; + } + if (!ossl_cmp_hdr_set1_sender(hdr, sender)) + return 0; + + /* determine recipient entry in PKIHeader */ + if (ctx->srvCert != NULL) { + rcp = X509_get_subject_name(ctx->srvCert); + /* set also as expected_sender of responses unless set explicitly */ + if (ctx->expected_sender == NULL && rcp != NULL + && !OSSL_CMP_CTX_set1_expected_sender(ctx, rcp)) + return 0; + } else if (ctx->recipient != NULL) { + rcp = ctx->recipient; + } else if (ctx->issuer != NULL) { + rcp = ctx->issuer; + } else if (ctx->oldCert != NULL) { + rcp = X509_get_issuer_name(ctx->oldCert); + } else if (ctx->clCert != NULL) { + rcp = X509_get_issuer_name(ctx->clCert); + } + if (!ossl_cmp_hdr_set1_recipient(hdr, rcp)) + return 0; + + /* set current time as message time */ + if (!ossl_cmp_hdr_update_messageTime(hdr)) + return 0; + + if (ctx->recipNonce != NULL + && !ossl_cmp_asn1_octet_string_set1(&hdr->recipNonce, + ctx->recipNonce)) + return 0; + + /* + * set ctx->transactionID in CMP header + * if ctx->transactionID is NULL, a random one is created with 128 bit + * according to section 5.1.1: + * + * It is RECOMMENDED that the clients fill the transactionID field with + * 128 bits of (pseudo-) random data for the start of a transaction to + * reduce the probability of having the transactionID in use at the server. + */ + if (ctx->transactionID == NULL + && !set1_aostr_else_random(&ctx->transactionID, NULL, + OSSL_CMP_TRANSACTIONID_LENGTH)) + return 0; + if (!ossl_cmp_asn1_octet_string_set1(&hdr->transactionID, + ctx->transactionID)) + return 0; + + /*- + * set random senderNonce + * according to section 5.1.1: + * + * senderNonce present + * -- 128 (pseudo-)random bits + * The senderNonce and recipNonce fields protect the PKIMessage against + * replay attacks. The senderNonce will typically be 128 bits of + * (pseudo-) random data generated by the sender, whereas the recipNonce + * is copied from the senderNonce of the previous message in the + * transaction. + */ + if (!set1_aostr_else_random(&hdr->senderNonce, NULL, + OSSL_CMP_SENDERNONCE_LENGTH)) + return 0; + + /* store senderNonce - for cmp with recipNonce in next outgoing msg */ + if (!OSSL_CMP_CTX_set1_senderNonce(ctx, hdr->senderNonce)) + return 0; + + /*- + * freeText [7] PKIFreeText OPTIONAL, + * -- this may be used to indicate context-specific instructions + * -- (this field is intended for human consumption) + */ + if (ctx->freeText != NULL + && !ossl_cmp_hdr_push1_freeText(hdr, ctx->freeText)) + return 0; + + return 1; +} diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index 1a7dcca3..b7ab6454 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -42,7 +42,7 @@ struct ossl_cmp_ctx_st { int proxyPort; int msgtimeout; /* max seconds to wait for each CMP message round trip */ int totaltimeout; /* maximum number seconds an enrollment may take, incl. */ - /* attempts polling for a response if a 'waiting' PKIStatus is received */ + /* attempts polling for a response if a 'waiting' PKIStatus is received */ time_t end_time; /* session start time + totaltimeout */ OSSL_cmp_http_cb_t http_cb; void *http_cb_arg; /* allows to store optional argument to cb */ @@ -77,6 +77,7 @@ struct ossl_cmp_ctx_st { ASN1_OCTET_STRING *transactionID; /* the current transaction ID */ ASN1_OCTET_STRING *senderNonce; /* last nonce sent */ ASN1_OCTET_STRING *recipNonce; /* last nonce received */ + ASN1_UTF8STRING *freeText; /* optional string to include each msg */ STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs; int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */ int disableConfirm; /* disable certConf in IR/KUR/CR for broken servers */ @@ -278,6 +279,7 @@ struct ossl_cmp_pkisi_st { } /* OSSL_CMP_PKISI */; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI) DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) /*- * RevReqContent ::= SEQUENCE OF RevDetails @@ -525,6 +527,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_GENREPCONTENT) * certConf [24] CertConfirmContent, --Certificate confirm * pollReq [25] PollReqContent, --Polling request * pollRep [26] PollRepContent --Polling response + * } */ typedef struct ossl_cmp_pkibody_st { int type; @@ -678,6 +681,13 @@ DECLARE_ASN1_FUNCTIONS(CMP_PROTECTEDPART) * } */ +/* + * constants + */ +/* certReqId for the first - and so far only - certificate request */ +# define OSSL_CMP_CERTREQID 0 +/* sequence id for the first - and so far only - revocation request */ +# define OSSL_CMP_REVREQSID 0 /* * functions */ @@ -720,6 +730,122 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *nonce); -# define OSSL_CMP_TRANSACTIONID_LENGTH 16 +/* from cmp_status.c */ +OSSL_CMP_PKISI * +ossl_cmp_statusinfo_new(int status, int fail_info, const char *text); +int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo); +const char *ossl_cmp_PKIStatus_to_string(int status); +OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si); +int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si); +int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index); + +/* from cmp_hdr.c */ +int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); +int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); +ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); +int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); +int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID); +int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text); +int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text); +int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text); +int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav); +int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr, + STACK_OF(OSSL_CMP_ITAV) *itavs); +int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr); +# define OSSL_CMP_TRANSACTIONID_LENGTH 16 +# define OSSL_CMP_SENDERNONCE_LENGTH 16 +int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); + +/* from cmp_msg.c */ +/* OSSL_CMP_MSG bodytype ASN.1 choice IDs */ +# define OSSL_CMP_PKIBODY_IR 0 +# define OSSL_CMP_PKIBODY_IP 1 +# define OSSL_CMP_PKIBODY_CR 2 +# define OSSL_CMP_PKIBODY_CP 3 +# define OSSL_CMP_PKIBODY_P10CR 4 +# define OSSL_CMP_PKIBODY_POPDECC 5 +# define OSSL_CMP_PKIBODY_POPDECR 6 +# define OSSL_CMP_PKIBODY_KUR 7 +# define OSSL_CMP_PKIBODY_KUP 8 +# define OSSL_CMP_PKIBODY_KRR 9 +# define OSSL_CMP_PKIBODY_KRP 10 +# define OSSL_CMP_PKIBODY_RR 11 +# define OSSL_CMP_PKIBODY_RP 12 +# define OSSL_CMP_PKIBODY_CCR 13 +# define OSSL_CMP_PKIBODY_CCP 14 +# define OSSL_CMP_PKIBODY_CKUANN 15 +# define OSSL_CMP_PKIBODY_CANN 16 +# define OSSL_CMP_PKIBODY_RANN 17 +# define OSSL_CMP_PKIBODY_CRLANN 18 +# define OSSL_CMP_PKIBODY_PKICONF 19 +# define OSSL_CMP_PKIBODY_NESTED 20 +# define OSSL_CMP_PKIBODY_GENM 21 +# define OSSL_CMP_PKIBODY_GENP 22 +# define OSSL_CMP_PKIBODY_ERROR 23 +# define OSSL_CMP_PKIBODY_CERTCONF 24 +# define OSSL_CMP_PKIBODY_POLLREQ 25 +# define OSSL_CMP_PKIBODY_POLLREP 26 +# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP +const char *ossl_cmp_bodytype_to_string(int type); +int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type); +int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg); +OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype); +OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int bodytype, + int err_code); +OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype, + int certReqId, OSSL_CMP_PKISI *si, + X509 *cert, STACK_OF(X509) *chain, + STACK_OF(X509) *caPubs, int encrypted, + int unprotectedErrors); +OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, + OSSL_CRMF_CERTID *certId, int unprot_err); +OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx); +int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav); +int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, + STACK_OF(OSSL_CMP_ITAV) *itavs); +OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, + int errorCode, + OSSL_CMP_PKIFREETEXT *errorDetails, + int unprotected); +int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus, + const X509 *cert); +OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, + const char *text); +OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid); +OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, + int64_t poll_after); +OSSL_CMP_PKISI * +ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid); +OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, + int rsid); +OSSL_CMP_POLLREP * +ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, + int rid); +OSSL_CMP_CERTRESPONSE * +ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg, + int rid); +X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, + const OSSL_CMP_CERTRESPONSE *crep); +OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file); +/* BIO definitions */ +# define OSSL_d2i_CMP_MSG_bio(bp, p) \ + ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new, d2i_OSSL_CMP_MSG, bp, p) +# define OSSL_i2d_CMP_MSG_bio(bp, o) \ + ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bp, o) + +/* from cmp_protect.c */ +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, + const ASN1_OCTET_STRING *secret, + EVP_PKEY *pkey); +int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); +int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); #endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */ diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c new file mode 100644 index 00000000..00381932 --- /dev/null +++ b/crypto/cmp/cmp_msg.c @@ -0,0 +1,996 @@ +/* + * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * 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 + */ + +/* CMP functions for PKIMessage construction */ + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include + +OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg) +{ + if (msg == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return NULL; + } + return msg->header; +} + +const char *ossl_cmp_bodytype_to_string(int type) +{ + static const char *type_names[] = { + "IR", "IP", "CR", "CP", "P10CR", + "POPDECC", "POPDECR", "KUR", "KUP", + "KRR", "KRP", "RR", "RP", "CCR", "CCP", + "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED", + "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP", + }; + + if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX) + return "illegal body type"; + return type_names[type]; +} + +int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type) +{ + if (!ossl_assert(msg != NULL && msg->body != NULL)) + return 0; + + msg->body->type = type; + return 1; +} + +int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(msg != NULL && msg->body != NULL)) + return -1; + + return msg->body->type; +} + +/* Add an extension to the referenced extension stack, which may be NULL */ +static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) +{ + X509_EXTENSION *ext; + int res; + + if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */ + return 0; + + if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL) + return 0; + + res = X509v3_add_ext(pexts, ext, 0) != NULL; + X509_EXTENSION_free(ext); + return res; +} + +/* Add a CRL revocation reason code to extension stack, which may be NULL */ +static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code) +{ + ASN1_ENUMERATED *val = ASN1_ENUMERATED_new(); + int res = 0; + + if (val != NULL && ASN1_ENUMERATED_set(val, reason_code)) + res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val); + ASN1_ENUMERATED_free(val); + return res; +} + +OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype) +{ + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = OSSL_CMP_MSG_new()) == NULL) + return NULL; + if (!ossl_cmp_hdr_init(ctx, msg->header) + || !ossl_cmp_msg_set_bodytype(msg, bodytype)) + goto err; + if (ctx->geninfo_ITAVs != NULL + && !ossl_cmp_hdr_generalInfo_push1_items(msg->header, + ctx->geninfo_ITAVs)) + goto err; + + switch (bodytype) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_KUR: + if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_P10CR: + if (ctx->p10CSR == NULL) { + CMPerr(0, CMP_R_ERROR_CREATING_P10CR); + goto err; + } + if ((msg->body->value.p10cr = X509_REQ_dup(ctx->p10CSR)) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + if ((msg->body->value.ip = OSSL_CMP_CERTREPMESSAGE_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_RR: + if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_RP: + if ((msg->body->value.rp = OSSL_CMP_REVREPCONTENT_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_CERTCONF: + if ((msg->body->value.certConf = + sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_PKICONF: + if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL) + goto err; + ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL); + return msg; + + case OSSL_CMP_PKIBODY_POLLREQ: + if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_POLLREP: + if ((msg->body->value.pollRep = sk_OSSL_CMP_POLLREP_new_null()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_GENM: + case OSSL_CMP_PKIBODY_GENP: + if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_ERROR: + if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL) + goto err; + return msg; + + default: + CMPerr(0, CMP_R_UNEXPECTED_PKIBODY); + goto err; + } + + err: + OSSL_CMP_MSG_free(msg); + return NULL; +} + +#define HAS_SAN(ctx) \ + (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \ + || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) + +static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert, + int bodytype) +{ + if (ctx->subjectName != NULL) + return ctx->subjectName; + + if (refcert != NULL + && (bodytype == OSSL_CMP_PKIBODY_KUR || !HAS_SAN(ctx))) + /* + * For KUR, copy subjectName from reference certificate. + * For IR or CR, do the same only if there is no subjectAltName. + */ + return X509_get_subject_name(refcert); + return NULL; +} + +/* + * Create CRMF certificate request message for IR/CR/KUR + * returns a pointer to the OSSL_CRMF_MSG on success, NULL on error + */ +static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, + int rid, EVP_PKEY *rkey) +{ + OSSL_CRMF_MSG *crm = NULL; + X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert; + /* refcert defaults to current client cert */ + STACK_OF(GENERAL_NAME) *default_sans = NULL; + X509_NAME *subject = determine_subj(ctx, refcert, bodytype); + int crit = ctx->setSubjectAltNameCritical || subject == NULL; + /* RFC5280: subjectAltName MUST be critical if subject is null */ + X509_EXTENSIONS *exts = NULL; + + if (rkey == NULL + || (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) { + CMPerr(0, CMP_R_INVALID_ARGS); + return NULL; + } + if ((crm = OSSL_CRMF_MSG_new()) == NULL) + return NULL; + if (!OSSL_CRMF_MSG_set_certReqId(crm, rid) + /* + * fill certTemplate, corresponding to CertificationRequestInfo + * of PKCS#10. The rkey param cannot be NULL so far - + * it could be NULL if centralized key creation was supported + */ + || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey, + subject, ctx->issuer, + NULL/* serial */)) + goto err; + if (ctx->days != 0) { + time_t notBefore, notAfter; + + notBefore = time(NULL); + notAfter = notBefore + 60 * 60 * 24 * ctx->days; + if (!OSSL_CRMF_MSG_set_validity(crm, notBefore, notAfter)) + goto err; + } + + /* extensions */ + if (refcert != NULL && !ctx->SubjectAltName_nodefault) + default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), + NID_subject_alt_name, NULL, NULL); + /* exts are copied from ctx to allow reuse */ + if (ctx->reqExtensions != NULL) { + exts = sk_X509_EXTENSION_deep_copy(ctx->reqExtensions, + X509_EXTENSION_dup, + X509_EXTENSION_free); + if (exts == NULL) + goto err; + } + if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 + && !add1_extension(&exts, NID_subject_alt_name, + crit, ctx->subjectAltNames)) + goto err; + if (!HAS_SAN(ctx) && default_sans != NULL + && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans)) + goto err; + if (ctx->policies != NULL + && !add1_extension(&exts, NID_certificate_policies, + ctx->setPoliciesCritical, ctx->policies)) + goto err; + if (!OSSL_CRMF_MSG_set0_extensions(crm, exts)) + goto err; + exts = NULL; + /* end fill certTemplate, now set any controls */ + + /* for KUR, set OldCertId according to D.6 */ + if (bodytype == OSSL_CMP_PKIBODY_KUR) { + OSSL_CRMF_CERTID *cid = + OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert), + X509_get_serialNumber(refcert)); + int ret; + + if (cid == NULL) + goto err; + ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid); + OSSL_CRMF_CERTID_free(cid); + if (ret == 0) + goto err; + } + + goto end; + + err: + OSSL_CRMF_MSG_free(crm); + crm = NULL; + + end: + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free); + return crm; +} + +OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code) +{ + EVP_PKEY *rkey; + EVP_PKEY *privkey; + OSSL_CMP_MSG *msg; + OSSL_CRMF_MSG *crm = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0); + if (rkey == NULL) + return NULL; + privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + + if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR + && type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) { + CMPerr(0, CMP_R_INVALID_ARGS); + return NULL; + } + + if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL) + goto err; + + /* header */ + if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) + goto err; + + /* body */ + /* For P10CR the content has already been set in OSSL_CMP_MSG_create */ + if (type != OSSL_CMP_PKIBODY_P10CR) { + if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) { + CMPerr(0, CMP_R_MISSING_PRIVATE_KEY); + goto err; + } + if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID, rkey)) == NULL + || !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest, + ctx->popoMethod) + /* value.ir is same for cr and kur */ + || !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm)) + goto err; + crm = NULL; + /* TODO: here optional 2nd certreqmsg could be pushed to the stack */ + } + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, err_code); + OSSL_CRMF_MSG_free(crm); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype, + int certReqId, OSSL_CMP_PKISI *si, + X509 *cert, STACK_OF(X509) *chain, + STACK_OF(X509) *caPubs, int encrypted, + int unprotectedErrors) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_CERTREPMESSAGE *repMsg = NULL; + OSSL_CMP_CERTRESPONSE *resp = NULL; + int status = -1; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, bodytype)) == NULL) + goto err; + repMsg = msg->body->value.ip; /* value.ip is same for cp and kup */ + + /* header */ + if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) + goto err; + + /* body */ + if ((resp = OSSL_CMP_CERTRESPONSE_new()) == NULL) + goto err; + OSSL_CMP_PKISI_free(resp->status); + if ((resp->status = OSSL_CMP_PKISI_dup(si)) == NULL + || !ASN1_INTEGER_set(resp->certReqId, certReqId)) + goto err; + + status = ossl_cmp_pkisi_get_pkistatus(resp->status); + if (status != OSSL_CMP_PKISTATUS_rejection + && status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) { + if (encrypted) { + CMPerr(0, CMP_R_INVALID_ARGS); + goto err; + } + + if ((resp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new()) + == NULL) + goto err; + resp->certifiedKeyPair->certOrEncCert->type = + OSSL_CMP_CERTORENCCERT_CERTIFICATE; + if (!X509_up_ref(cert)) + goto err; + resp->certifiedKeyPair->certOrEncCert->value.certificate = cert; + } + + if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp)) + goto err; + resp = NULL; + /* TODO: here optional 2nd certrep could be pushed to the stack */ + + if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL + && (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL) + goto err; + if (chain != NULL + && !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0)) + goto err; + + if (!unprotectedErrors + || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection) + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_CERTREP); + OSSL_CMP_CERTRESPONSE_free(resp); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_REVDETAILS *rd; + + if (!ossl_assert(ctx != NULL && ctx->oldCert != NULL)) + return NULL; + + if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL) + goto err; + + /* Fill the template from the contents of the certificate to be revoked */ + if (!OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, + NULL/* pubkey would be redundant */, + NULL/* subject would be redundant */, + X509_get_issuer_name(ctx->oldCert), + X509_get_serialNumber(ctx->oldCert))) + goto err; + + /* revocation reason code is optional */ + if (ctx->revocationReason != CRL_REASON_NONE + && !add_crl_reason_extension(&rd->crlEntryDetails, + ctx->revocationReason)) + goto err; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL) + goto err; + + if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd)) + goto err; + rd = NULL; + + /* + * TODO: the Revocation Passphrase according to section 5.3.19.9 could be + * set here if set in ctx + */ + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_RR); + OSSL_CMP_MSG_free(msg); + OSSL_CMP_REVDETAILS_free(rd); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, + OSSL_CRMF_CERTID *cid, int unprot_err) +{ + OSSL_CMP_REVREPCONTENT *rep = NULL; + OSSL_CMP_PKISI *si1 = NULL; + OSSL_CRMF_CERTID *cid_copy = NULL; + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL && si != NULL && cid != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL) + goto err; + rep = msg->body->value.rp; + + if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL) + goto err; + + if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) { + OSSL_CMP_PKISI_free(si1); + goto err; + } + + if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL) + goto err; + if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL) + goto err; + if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) { + OSSL_CRMF_CERTID_free(cid_copy); + goto err; + } + + if (!unprot_err + || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection) + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_RP); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *msg; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL) + goto err; + if (ossl_cmp_msg_protect(ctx, msg)) + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_PKICONF); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav) +{ + int bodytype; + + if (!ossl_assert(msg != NULL && itav != NULL)) + return 0; + + bodytype = ossl_cmp_msg_get_bodytype(msg); + if (bodytype != OSSL_CMP_PKIBODY_GENM + && bodytype != OSSL_CMP_PKIBODY_GENP) { + CMPerr(0, CMP_R_INVALID_ARGS); + return 0; + } + + /* value.genp has the same structure, so this works for genp as well */ + return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav); +} + +int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, + STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + int i; + OSSL_CMP_ITAV *itav = NULL; + + if (!ossl_assert(msg != NULL)) + return 0; + + for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { + if ((itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs,i))) == NULL) + return 0; + if (!ossl_cmp_msg_gen_push0_ITAV(msg, itav)) { + OSSL_CMP_ITAV_free(itav); + return 0; + } + } + return 1; +} + +/* + * Creates a new General Message/Response with an empty itav stack + * returns a pointer to the PKIMessage on success, NULL on error + */ +static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code) +{ + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL) + return NULL; + + if (ctx->genm_ITAVs != NULL + && !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs)) + goto err; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, err_code); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx) +{ + return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM); +} + +OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx) +{ + return gen_new(ctx, OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP); +} + +OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, + int errorCode, + OSSL_CMP_PKIFREETEXT *errorDetails, + int unprotected) +{ + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL) + goto err; + + OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo); + if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si)) + == NULL) + goto err; + if (errorCode >= 0) { + if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(msg->body->value.error->errorCode, errorCode)) + goto err; + } + if (errorDetails != NULL) + if ((msg->body->value.error->errorDetails = + sk_ASN1_UTF8STRING_deep_copy(errorDetails, ASN1_STRING_dup, + ASN1_STRING_free)) == NULL) + goto err; + + if (!unprotected && !ossl_cmp_msg_protect(ctx, msg)) + goto err; + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_ERROR); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +/* + * OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate, + * using the same hash algorithm as is used to create and verify the + * certificate signature, and places the hash into the certHash field of a + * OSSL_CMP_CERTSTATUS structure. This is used in the certConf message, + * for example, to confirm that the certificate was received successfully. + */ +int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus, + const X509 *cert) +{ + unsigned int len; + unsigned char hash[EVP_MAX_MD_SIZE]; + int md_NID; + const EVP_MD *md = NULL; + + if (!ossl_assert(certStatus != NULL && cert != NULL)) + return 0; + + /*- + * select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs: + * the hash of the certificate, using the same hash algorithm + * as is used to create and verify the certificate signature + */ + if (OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL) + && (md = EVP_get_digestbynid(md_NID)) != NULL) { + if (!X509_digest(cert, md, hash, &len)) + goto err; + if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus->certHash, hash, + len)) + goto err; + } else { + CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return 1; + err: + CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH); + return 0; +} + +/* + * TODO: handle potential 2nd certificate when signing and encrypting + * certificates have been requested/received + */ +OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, + const char *text) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_CERTSTATUS *certStatus = NULL; + OSSL_CMP_PKISI *sinfo; + + if (!ossl_assert(ctx != NULL && ctx->newCert != NULL)) + return NULL; + + if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) { + CMPerr(0, CMP_R_FAIL_INFO_OUT_OF_RANGE); + return NULL; + } + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL) + goto err; + + if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL) + goto err; + /* consume certStatus into msg right away so it gets deallocated with msg */ + if (!sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus)) + goto err; + /* set the ID of the certReq */ + if (!ASN1_INTEGER_set(certStatus->certReqId, OSSL_CMP_CERTREQID)) + goto err; + /* + * the hash of the certificate, using the same hash algorithm + * as is used to create and verify the certificate signature + */ + if (!ossl_cmp_certstatus_set_certHash(certStatus, ctx->newCert)) + goto err; + /* + * For any particular CertStatus, omission of the statusInfo field + * indicates ACCEPTANCE of the specified certificate. Alternatively, + * explicit status details (with respect to acceptance or rejection) MAY + * be provided in the statusInfo field, perhaps for auditing purposes at + * the CA/RA. + */ + sinfo = fail_info != 0 ? + ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) : + ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted, 0, text); + if (sinfo == NULL) + goto err; + certStatus->statusInfo = sinfo; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_POLLREQ *preq = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL) + goto err; + + /* TODO: support multiple cert request IDs to poll */ + if ((preq = OSSL_CMP_POLLREQ_new()) == NULL + || !ASN1_INTEGER_set(preq->certReqId, crid) + || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq)) + goto err; + + preq = NULL; + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_POLLREQ); + OSSL_CMP_POLLREQ_free(preq); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, + int64_t poll_after) +{ + OSSL_CMP_MSG *msg; + OSSL_CMP_POLLREP *prep; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL) + goto err; + if ((prep = OSSL_CMP_POLLREP_new()) == NULL) + goto err; + if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep)) + goto err; + if (!ASN1_INTEGER_set(prep->certReqId, crid)) + goto err; + if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after)) + goto err; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + return msg; + + err: + CMPerr(0, CMP_R_ERROR_CREATING_POLLREP); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +/*- + * returns the status field of the RevRepContent with the given + * request/sequence id inside a revocation response. + * RevRepContent has the revocation statuses in same order as they were sent in + * RevReqContent. + * returns NULL on error + */ +OSSL_CMP_PKISI * +ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid) +{ + OSSL_CMP_PKISI *status; + + if (!ossl_assert(rrep != NULL)) + return NULL; + + if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL) + return status; + + CMPerr(0, CMP_R_PKISTATUSINFO_NOT_FOUND); + return NULL; +} + +/* + * returns the CertId field in the revCerts part of the RevRepContent + * with the given request/sequence id inside a revocation response. + * RevRepContent has the CertIds in same order as they were sent in + * RevReqContent. + * returns NULL on error + */ +OSSL_CRMF_CERTID * +ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid) +{ + OSSL_CRMF_CERTID *cid = NULL; + + if (!ossl_assert(rrep != NULL)) + return NULL; + + if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL) + return cid; + + CMPerr(0, CMP_R_CERTID_NOT_FOUND); + return NULL; +} + +static int suitable_rid(const ASN1_INTEGER *certReqId, int rid) +{ + int trid; + + if (rid == -1) + return 1; + + trid = ossl_cmp_asn1_get_int(certReqId); + + if (trid == -1) { + CMPerr(0, CMP_R_BAD_REQUEST_ID); + return 0; + } + return rid == trid; +} + +static void add_expected_rid(int rid) +{ + char str[DECIMAL_SIZE(rid) + 1]; + + BIO_snprintf(str, sizeof(str), "%d", rid); + ERR_add_error_data(2, "expected certReqId = ", str); +} + +/* + * returns a pointer to the PollResponse with the given CertReqId + * (or the first one in case -1) inside a PollRepContent + * returns NULL on error or if no suitable PollResponse available + */ +OSSL_CMP_POLLREP * +ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, + int rid) +{ + OSSL_CMP_POLLREP *pollRep = NULL; + int i; + + if (!ossl_assert(prc != NULL)) + return NULL; + + for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) { + pollRep = sk_OSSL_CMP_POLLREP_value(prc, i); + if (suitable_rid(pollRep->certReqId, rid)) + return pollRep; + } + + CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND); + add_expected_rid(rid); + return NULL; +} + +/* + * returns a pointer to the CertResponse with the given CertReqId + * (or the first one in case -1) inside a CertRepMessage + * returns NULL on error or if no suitable CertResponse available + */ +OSSL_CMP_CERTRESPONSE * +ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, + int rid) +{ + OSSL_CMP_CERTRESPONSE *crep = NULL; + int i; + + if (!ossl_assert(crm != NULL && crm->response != NULL)) + return NULL; + + for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) { + crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i); + if (suitable_rid(crep->certReqId, rid)) + return crep; + } + + CMPerr(0, CMP_R_CERTRESPONSE_NOT_FOUND); + add_expected_rid(rid); + return NULL; +} + +/* + * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned + * certificate from the given certResponse B. + * Uses the privkey in case of indirect POP from B. + * Returns a pointer to a copy of the found certificate, or NULL if not found. + */ +X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, + const OSSL_CMP_CERTRESPONSE *crep) +{ + OSSL_CMP_CERTORENCCERT *coec; + X509 *crt = NULL; + + if (!ossl_assert(crep != NULL)) + return NULL; + + if (crep->certifiedKeyPair + && (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) { + switch (coec->type) { + case OSSL_CMP_CERTORENCCERT_CERTIFICATE: + crt = X509_dup(coec->value.certificate); + break; + case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT: + /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */ + if (privkey == NULL) { + CMPerr(0, CMP_R_MISSING_PRIVATE_KEY); + return NULL; + } + crt = + OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert, + privkey); + break; + default: + CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE); + return NULL; + } + } + if (crt == NULL) + CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND); + return crt; +} + +OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file) +{ + OSSL_CMP_MSG *msg = NULL; + BIO *bio = NULL; + + if (!ossl_assert(file != NULL)) + return NULL; + + if ((bio = BIO_new_file(file, "rb")) == NULL) + return NULL; + msg = OSSL_d2i_CMP_MSG_bio(bio, NULL); + BIO_free(bio); + return msg; +} diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c new file mode 100644 index 00000000..7db3440f --- /dev/null +++ b/crypto/cmp/cmp_protect.c @@ -0,0 +1,313 @@ +/* + * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * 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 + */ + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include + +/* + * This function is also used for verification from cmp_vfy. + * + * Calculate protection for given PKImessage utilizing the given credentials + * and the algorithm parameters set inside the message header's protectionAlg. + * + * Either secret or pkey must be set, the other must be NULL. Attempts doing + * PBMAC in case 'secret' is set and signature if 'pkey' is set - but will only + * do the protection already marked in msg->header->protectionAlg. + * + * returns ptr to ASN1_BIT_STRING containing protection on success, else NULL + */ +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, + const ASN1_OCTET_STRING *secret, + EVP_PKEY *pkey) +{ + ASN1_BIT_STRING *prot = NULL; + CMP_PROTECTEDPART prot_part; + const ASN1_OBJECT *algorOID = NULL; + int len; + size_t prot_part_der_len; + unsigned char *prot_part_der = NULL; + size_t sig_len; + unsigned char *protection = NULL; + const void *ppval = NULL; + int pptype = 0; + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + ASN1_STRING *pbm_str = NULL; + const unsigned char *pbm_str_uc = NULL; + EVP_MD_CTX *evp_ctx = NULL; + int md_NID; + const EVP_MD *md = NULL; + + if (!ossl_assert(msg != NULL)) + return NULL; + + /* construct data to be signed */ + prot_part.header = msg->header; + prot_part.body = msg->body; + + len = i2d_CMP_PROTECTEDPART(&prot_part, &prot_part_der); + if (len < 0 || prot_part_der == NULL) { + CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); + goto end; + } + prot_part_der_len = (size_t) len; + + if (msg->header->protectionAlg == NULL) { + CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); + goto end; + } + X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg); + + if (secret != NULL && pkey == NULL) { + if (ppval == NULL) { + CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); + goto end; + } + if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) { + CMPerr(0, CMP_R_WRONG_ALGORITHM_OID); + goto end; + } + pbm_str = (ASN1_STRING *)ppval; + pbm_str_uc = pbm_str->data; + pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length); + if (pbm == NULL) { + CMPerr(0, CMP_R_WRONG_ALGORITHM_OID); + goto end; + } + + if (!OSSL_CRMF_pbm_new(pbm, prot_part_der, prot_part_der_len, + secret->data, secret->length, + &protection, &sig_len)) + goto end; + } else if (secret == NULL && pkey != NULL) { + /* TODO combine this with large parts of CRMF_poposigningkey_init() */ + /* EVP_DigestSignInit() checks that pkey type is correct for the alg */ + + if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_NID, NULL) + || (md = EVP_get_digestbynid(md_NID)) == NULL + || (evp_ctx = EVP_MD_CTX_new()) == NULL) { + CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); + goto end; + } + if (EVP_DigestSignInit(evp_ctx, NULL, md, NULL, pkey) <= 0 + || EVP_DigestSignUpdate(evp_ctx, prot_part_der, + prot_part_der_len) <= 0 + || EVP_DigestSignFinal(evp_ctx, NULL, &sig_len) <= 0 + || (protection = OPENSSL_malloc(sig_len)) == NULL + || EVP_DigestSignFinal(evp_ctx, protection, &sig_len) <= 0) { + CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); + goto end; + } + } else { + CMPerr(0, CMP_R_INVALID_ARGS); + goto end; + } + + if ((prot = ASN1_BIT_STRING_new()) == NULL) + goto end; + /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ + prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { + ASN1_BIT_STRING_free(prot); + prot = NULL; + } + + end: + OSSL_CRMF_PBMPARAMETER_free(pbm); + EVP_MD_CTX_free(evp_ctx); + OPENSSL_free(protection); + OPENSSL_free(prot_part_der); + return prot; +} + +int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(ctx != NULL && msg != NULL)) + return 0; + + if (msg->extraCerts == NULL + && (msg->extraCerts = sk_X509_new_null()) == NULL) + return 0; + + if (ctx->clCert != NULL) { + /* Make sure that our own cert gets sent, in the first position */ + if (!X509_up_ref(ctx->clCert)) + return 0; + if (!sk_X509_push(msg->extraCerts, ctx->clCert)) { + X509_free(ctx->clCert); + return 0; + } + /* if we have untrusted store, try to add intermediate certs */ + if (ctx->untrusted_certs != NULL) { + STACK_OF(X509) *chain = + ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->clCert); + int res = ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, + 1 /* no self-signed */, + 1 /* no duplicates */, 0); + sk_X509_pop_free(chain, X509_free); + if (res == 0) + return 0; + } + } + + /* add any additional certificates from ctx->extraCertsOut */ + if (!ossl_cmp_sk_X509_add1_certs(msg->extraCerts, ctx->extraCertsOut, 0, + 1 /* no duplicates */, 0)) + return 0; + + /* if none was found avoid empty ASN.1 sequence */ + if (sk_X509_num(msg->extraCerts) == 0) { + sk_X509_free(msg->extraCerts); + msg->extraCerts = NULL; + } + return 1; +} + +/* + * Create an X509_ALGOR structure for PasswordBasedMAC protection based on + * the pbm settings in the context + * returns pointer to X509_ALGOR on success, NULL on error + */ +static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx) +{ + X509_ALGOR *alg = NULL; + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + unsigned char *pbm_der = NULL; + int pbm_der_len; + ASN1_STRING *pbm_str = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + alg = X509_ALGOR_new(); + pbm = OSSL_CRMF_pbmp_new(ctx->pbm_slen, ctx->pbm_owf, ctx->pbm_itercnt, + ctx->pbm_mac); + pbm_str = ASN1_STRING_new(); + if (alg == NULL || pbm == NULL || pbm_str == NULL) + goto err; + + if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) + goto err; + + if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) + goto err; + OPENSSL_free(pbm_der); + + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), + V_ASN1_SEQUENCE, pbm_str); + OSSL_CRMF_PBMPARAMETER_free(pbm); + return alg; + + err: + ASN1_STRING_free(pbm_str); + X509_ALGOR_free(alg); + OPENSSL_free(pbm_der); + OSSL_CRMF_PBMPARAMETER_free(pbm); + return NULL; +} + +int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(ctx != NULL && msg != NULL)) + return 0; + + if (ctx->unprotectedSend) + return 1; + + /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ + if (ctx->secretValue != NULL) { + if ((msg->header->protectionAlg = create_pbmac_algor(ctx)) == NULL) + goto err; + if (ctx->referenceValue != NULL + && !ossl_cmp_hdr_set1_senderKID(msg->header, + ctx->referenceValue)) + goto err; + + /* + * add any additional certificates from ctx->extraCertsOut + * while not needed to validate the signing cert, the option to do + * this might be handy for certain use cases + */ + if (!ossl_cmp_msg_add_extraCerts(ctx, msg)) + goto err; + + if ((msg->protection = + ossl_cmp_calc_protection(msg, ctx->secretValue, NULL)) == NULL) + goto err; + } else { + /* + * use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and + * private key is given + */ + if (ctx->clCert != NULL && ctx->pkey != NULL) { + const ASN1_OCTET_STRING *subjKeyIDStr = NULL; + int algNID = 0; + ASN1_OBJECT *alg = NULL; + + /* make sure that key and certificate match */ + if (!X509_check_private_key(ctx->clCert, ctx->pkey)) { + CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH); + goto err; + } + + if (msg->header->protectionAlg == NULL) + if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) + goto err; + + if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest, + EVP_PKEY_id(ctx->pkey))) { + CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE); + goto err; + } + if ((alg = OBJ_nid2obj(algNID)) == NULL) + goto err; + if (!X509_ALGOR_set0(msg->header->protectionAlg, + alg, V_ASN1_UNDEF, NULL)) { + ASN1_OBJECT_free(alg); + goto err; + } + + /* + * set senderKID to keyIdentifier of the used certificate according + * to section 5.1.1 + */ + subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert); + if (subjKeyIDStr != NULL + && !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr)) + goto err; + + /* + * Add ctx->clCert followed, if possible, by its chain built + * from ctx->untrusted_certs, and then ctx->extraCertsOut + */ + if (!ossl_cmp_msg_add_extraCerts(ctx, msg)) + goto err; + + if ((msg->protection = + ossl_cmp_calc_protection(msg, NULL, ctx->pkey)) == NULL) + goto err; + } else { + CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); + goto err; + } + } + + return 1; + err: + CMPerr(0, CMP_R_ERROR_PROTECTING_MESSAGE); + return 0; +} diff --git a/crypto/cmp/cmp_status.c b/crypto/cmp/cmp_status.c new file mode 100644 index 00000000..a5f6b294 --- /dev/null +++ b/crypto/cmp/cmp_status.c @@ -0,0 +1,301 @@ +/* + * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * 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 + */ + +/* CMP functions for PKIStatusInfo handling and PKIMessage decomposition */ + +#include + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include /* needed in case config no-deprecated */ +#include +#include +#include +#include +#include /* for ASN1_R_TOO_SMALL and ASN1_R_TOO_LARGE */ + +/* CMP functions related to PKIStatus */ + +int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *si) +{ + if (!ossl_assert(si != NULL && si->status != NULL)) + return -1; + return ossl_cmp_asn1_get_int(si->status); +} + +/* + * return the declared identifier and a short explanation for the PKIStatus + * value as specified in RFC4210, Appendix F. + */ +const char *ossl_cmp_PKIStatus_to_string(int status) +{ + switch (status) { + case OSSL_CMP_PKISTATUS_accepted: + return "PKIStatus: accepted"; + case OSSL_CMP_PKISTATUS_grantedWithMods: + return "PKIStatus: granted with modifications"; + case OSSL_CMP_PKISTATUS_rejection: + return "PKIStatus: rejection"; + case OSSL_CMP_PKISTATUS_waiting: + return "PKIStatus: waiting"; + case OSSL_CMP_PKISTATUS_revocationWarning: + return "PKIStatus: revocation warning - a revocation of the cert is imminent"; + case OSSL_CMP_PKISTATUS_revocationNotification: + return "PKIStatus: revocation notification - a revocation of the cert has occurred"; + case OSSL_CMP_PKISTATUS_keyUpdateWarning: + return "PKIStatus: key update warning - update already done for the cert"; + default: + { + char buf[40]; + BIO_snprintf(buf, sizeof(buf), "PKIStatus: invalid=%d", status); + CMPerr(0, CMP_R_ERROR_PARSING_PKISTATUS); + ossl_cmp_add_error_data(buf); + return NULL; + } + } +} + +/* + * returns a pointer to the statusString contained in a PKIStatusInfo + * returns NULL on error + */ +OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si) +{ + if (!ossl_assert(si != NULL)) + return NULL; + return si->statusString; +} + +/* + * returns the FailureInfo bits of the given PKIStatusInfo + * returns -1 on error + */ +int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si) +{ + int i; + int res = 0; + + if (!ossl_assert(si != NULL && si->failInfo != NULL)) + return -1; + for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++) + if (ASN1_BIT_STRING_get_bit(si->failInfo, i)) + res |= 1 << i; + return res; +} + +/* + * internal function + * convert PKIFailureInfo number to human-readable string + * + * returns pointer to static string + * returns NULL on error + */ +static const char *CMP_PKIFAILUREINFO_to_string(int number) +{ + switch (number) { + case OSSL_CMP_PKIFAILUREINFO_badAlg: + return "badAlg"; + case OSSL_CMP_PKIFAILUREINFO_badMessageCheck: + return "badMessageCheck"; + case OSSL_CMP_PKIFAILUREINFO_badRequest: + return "badRequest"; + case OSSL_CMP_PKIFAILUREINFO_badTime: + return "badTime"; + case OSSL_CMP_PKIFAILUREINFO_badCertId: + return "badCertId"; + case OSSL_CMP_PKIFAILUREINFO_badDataFormat: + return "badDataFormat"; + case OSSL_CMP_PKIFAILUREINFO_wrongAuthority: + return "wrongAuthority"; + case OSSL_CMP_PKIFAILUREINFO_incorrectData: + return "incorrectData"; + case OSSL_CMP_PKIFAILUREINFO_missingTimeStamp: + return "missingTimeStamp"; + case OSSL_CMP_PKIFAILUREINFO_badPOP: + return "badPOP"; + case OSSL_CMP_PKIFAILUREINFO_certRevoked: + return "certRevoked"; + case OSSL_CMP_PKIFAILUREINFO_certConfirmed: + return "certConfirmed"; + case OSSL_CMP_PKIFAILUREINFO_wrongIntegrity: + return "wrongIntegrity"; + case OSSL_CMP_PKIFAILUREINFO_badRecipientNonce: + return "badRecipientNonce"; + case OSSL_CMP_PKIFAILUREINFO_timeNotAvailable: + return "timeNotAvailable"; + case OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy: + return "unacceptedPolicy"; + case OSSL_CMP_PKIFAILUREINFO_unacceptedExtension: + return "unacceptedExtension"; + case OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable: + return "addInfoNotAvailable"; + case OSSL_CMP_PKIFAILUREINFO_badSenderNonce: + return "badSenderNonce"; + case OSSL_CMP_PKIFAILUREINFO_badCertTemplate: + return "badCertTemplate"; + case OSSL_CMP_PKIFAILUREINFO_signerNotTrusted: + return "signerNotTrusted"; + case OSSL_CMP_PKIFAILUREINFO_transactionIdInUse: + return "transactionIdInUse"; + case OSSL_CMP_PKIFAILUREINFO_unsupportedVersion: + return "unsupportedVersion"; + case OSSL_CMP_PKIFAILUREINFO_notAuthorized: + return "notAuthorized"; + case OSSL_CMP_PKIFAILUREINFO_systemUnavail: + return "systemUnavail"; + case OSSL_CMP_PKIFAILUREINFO_systemFailure: + return "systemFailure"; + case OSSL_CMP_PKIFAILUREINFO_duplicateCertReq: + return "duplicateCertReq"; + default: + return NULL; /* illegal failure number */ + } +} + +/* + * checks PKIFailureInfo bits in a given PKIStatusInfo + * returns 1 if a given bit is set, 0 if not, -1 on error + */ +int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index) +{ + if (!ossl_assert(si != NULL && si->failInfo != NULL)) + return -1; + if (bit_index < 0 || bit_index > OSSL_CMP_PKIFAILUREINFO_MAX) { + CMPerr(0, CMP_R_INVALID_ARGS); + return -1; + } + + return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index); +} + +/* + * place human-readable error string created from PKIStatusInfo in given buffer + * returns pointer to the same buffer containing the string, or NULL on error + */ +char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf, + size_t bufsize) +{ + int status, failure, fail_info; + const char *status_string, *failure_string; + OSSL_CMP_PKIFREETEXT *status_strings; + ASN1_UTF8STRING *text; + int i; + int printed_chars; + int failinfo_found = 0; + int n_status_strings; + char* write_ptr = buf; + +#define ADVANCE_BUFFER \ + if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \ + return NULL; \ + write_ptr += printed_chars; \ + bufsize -= printed_chars; + + if (ctx == NULL + || buf == NULL + || (status = OSSL_CMP_CTX_get_status(ctx)) < 0 + || (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL) + return NULL; + printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string); + ADVANCE_BUFFER; + + /* failInfo is optional and may be empty */ + if ((fail_info = OSSL_CMP_CTX_get_failInfoCode(ctx)) > 0) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: "); + ADVANCE_BUFFER; + for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) { + if ((fail_info & (1 << failure)) != 0) { + failure_string = CMP_PKIFAILUREINFO_to_string(failure); + if (failure_string != NULL) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s", + failure > 0 ? ", " : "", + failure_string); + ADVANCE_BUFFER; + failinfo_found = 1; + } + } + } + } + if (!failinfo_found && status != OSSL_CMP_PKISTATUS_accepted + && status != OSSL_CMP_PKISTATUS_grantedWithMods) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; "); + ADVANCE_BUFFER; + } + + /* statusString sequence is optional and may be empty */ + status_strings = OSSL_CMP_CTX_get0_statusString(ctx); + n_status_strings = sk_ASN1_UTF8STRING_num(status_strings); + if (n_status_strings > 0) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ", + n_status_strings > 1 ? "s" : ""); + ADVANCE_BUFFER; + for (i = 0; i < n_status_strings; i++) { + text = sk_ASN1_UTF8STRING_value(status_strings, i); + printed_chars = BIO_snprintf(write_ptr, bufsize, "\"%s\"%s", + ASN1_STRING_get0_data(text), + i < n_status_strings - 1 ? ", " : ""); + ADVANCE_BUFFER; + } + } +#undef ADVANCE_BUFFER + return buf; +} + +/* + * Creates a new PKIStatusInfo structure and fills it in + * returns a pointer to the structure on success, NULL on error + * note: strongly overlaps with TS_RESP_CTX_set_status_info() + * and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c + */ +OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info, + const char *text) +{ + OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new(); + ASN1_UTF8STRING *utf8_text = NULL; + int failure; + + if (si == NULL) + goto err; + if (!ASN1_INTEGER_set(si->status, status)) + goto err; + + if (text != NULL) { + if ((utf8_text = ASN1_UTF8STRING_new()) == NULL + || !ASN1_STRING_set(utf8_text, text, -1)) + goto err; + if ((si->statusString = sk_ASN1_UTF8STRING_new_null()) == NULL) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->statusString, utf8_text)) + goto err; + /* Ownership is lost. */ + utf8_text = NULL; + } + + for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) { + if ((fail_info & (1 << failure)) != 0) { + if (si->failInfo == NULL + && (si->failInfo = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failInfo, failure, 1)) + goto err; + } + } + return si; + + err: + OSSL_CMP_PKISI_free(si); + ASN1_UTF8STRING_free(utf8_text); + return NULL; +} diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c index 9490496c..0390c23e 100644 --- a/crypto/cmp/cmp_util.c +++ b/crypto/cmp/cmp_util.c @@ -408,21 +408,23 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert) int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, const ASN1_OCTET_STRING *src) { + ASN1_OCTET_STRING *new; if (tgt == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return 0; } if (*tgt == src) /* self-assignment */ return 1; - ASN1_OCTET_STRING_free(*tgt); if (src != NULL) { - if ((*tgt = ASN1_OCTET_STRING_dup(src)) == NULL) + if ((new = ASN1_OCTET_STRING_dup(src)) == NULL) return 0; } else { - *tgt = NULL; + new = NULL; } + ASN1_OCTET_STRING_free(*tgt); + *tgt = new; return 1; } diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index ecece987..ac34f3ef 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "cms_local.h" #include "crypto/asn1.h" #include "crypto/evp.h" @@ -625,6 +625,23 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, return 1; } +static const EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen) +{ + switch(keylen) { + case 16: + return EVP_aes_128_wrap(); + + case 24: + return EVP_aes_192_wrap(); + + case 32: + return EVP_aes_256_wrap(); + } + + return NULL; +} + + /* Encrypt content key in KEK recipient info */ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, @@ -632,36 +649,50 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *wkey = NULL; int wkeylen; int r = 0; + const EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; ec = cms->d.envelopedData->encryptedContentInfo; kekri = ri->d.kekri; - if (!kekri->key) { + if (kekri->key == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); return 0; } - if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen); + if (cipher == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; } + /* 8 byte prefix for AES wrap ciphers */ wkey = OPENSSL_malloc(ec->keylen + 8); - if (wkey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } - wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } - if (wkeylen <= 0) { + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, ec->keylen) + || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); + goto err; + } + wkeylen += outlen; + if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); goto err; } @@ -671,10 +702,9 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, r = 1; err: - if (!r) OPENSSL_free(wkey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r; @@ -687,10 +717,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *ukey = NULL; int ukeylen; int r = 0, wrap_nid; + const EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; ec = cms->d.envelopedData->encryptedContentInfo; @@ -716,27 +748,33 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, goto err; } - if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen); + if (cipher == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; } ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - if (ukey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } - ukeylen = AES_unwrap_key(&actx, NULL, ukey, - kekri->encryptedKey->data, - kekri->encryptedKey->length); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } - if (ukeylen <= 0) { + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_DecryptUpdate(ctx, ukey, &ukeylen, + kekri->encryptedKey->data, + kekri->encryptedKey->length) + || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); goto err; } + ukeylen += outlen; ec->key = ukey; ec->keylen = ukeylen; @@ -744,10 +782,9 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, r = 1; err: - if (!r) OPENSSL_free(ukey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r; diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c index 06c5a1bb..ef721641 100644 --- a/crypto/cms/cms_io.c +++ b/crypto/cms/cms_io.c @@ -43,7 +43,7 @@ int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); } -IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) +IMPLEMENT_PEM_rw(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) { diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index a43225ec..9718b73a 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -54,7 +54,7 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx); static CONF *def_create(CONF_METHOD *meth); static int def_init_default(CONF *conf); -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 static int def_init_WIN32(CONF *conf); #endif static int def_destroy(CONF *conf); @@ -83,7 +83,7 @@ CONF_METHOD *NCONF_default(void) return &default_method; } -#if ! OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 static CONF_METHOD WIN32_method = { "WIN32", def_create, @@ -121,22 +121,22 @@ static int def_init_default(CONF *conf) if (conf == NULL) return 0; + memset(conf, 0, sizeof(*conf)); conf->meth = &default_method; conf->meth_data = (void *)CONF_type_default; - conf->data = NULL; return 1; } -#if ! OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 static int def_init_WIN32(CONF *conf) { if (conf == NULL) return 0; + memset(conf, 0, sizeof(*conf)); conf->meth = &WIN32_method; conf->meth_data = (void *)CONF_type_win32; - conf->data = NULL; return 1; } @@ -354,7 +354,49 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) psection = section; } p = eat_ws(conf, end); - if (strncmp(pname, ".include", 8) == 0 + if (strncmp(pname, ".pragma", 7) == 0 + && (p != pname + 7 || *p == '=')) { + char *pval; + + if (*p == '=') { + p++; + p = eat_ws(conf, p); + } + trim_ws(conf, p); + + /* Pragma values take the form keyword:value */ + pval = strchr(p, ':'); + if (pval == NULL || pval == p || pval[1] == '\0') { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_INVALID_PRAGMA); + goto err; + } + + *pval++ = '\0'; + trim_ws(conf, p); + pval = eat_ws(conf, pval); + + /* + * Known pragmas: + * + * dollarid takes "on", "true or "off", "false" + */ + if (strcmp(p, "dollarid") == 0) { + if (strcmp(pval, "on") == 0 + || strcmp(pval, "true") == 0) { + conf->flag_dollarid = 1; + } else if (strcmp(pval, "off") == 0 + || strcmp(pval, "false") == 0) { + conf->flag_dollarid = 0; + } else { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_INVALID_PRAGMA); + goto err; + } + } + /* + * We *ignore* any unknown pragma. + */ + continue; + } else if (strncmp(pname, ".include", 8) == 0 && (p != pname + 8 || *p == '=')) { char *include = NULL; BIO *next; @@ -414,6 +456,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) continue; } else if (*p != '=') { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); + ERR_add_error_data(2, "HERE-->", p); goto err; } *end = '\0'; @@ -590,7 +633,10 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) buf->data[to++] = v; } else if (IS_EOF(conf, *from)) break; - else if (*from == '$') { + else if (*from == '$' + && (!conf->flag_dollarid + || from[1] == '{' + || from[1] == '(')) { size_t newsize; /* try to expand it */ @@ -607,7 +653,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) s++; cp = section; e = np = s; - while (IS_ALNUM(conf, *e)) + while (IS_ALNUM(conf, *e) + || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) e++; if ((e[0] == ':') && (e[1] == ':')) { cp = np; @@ -616,7 +663,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) *rrp = '\0'; e += 2; np = e; - while (IS_ALNUM(conf, *e)) + while (IS_ALNUM(conf, *e) + || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) e++; } r = *e; @@ -729,7 +777,9 @@ static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) { const char *filename; + size_t pathlen; + pathlen = strlen(path); while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) { size_t namelen; @@ -742,7 +792,7 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) char *newpath; BIO *bio; - newlen = strlen(path) + namelen + 2; + newlen = pathlen + namelen + 2; newpath = OPENSSL_zalloc(newlen); if (newpath == NULL) { CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE); @@ -753,14 +803,11 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) * If the given path isn't clear VMS syntax, * we treat it as on Unix. */ - { - size_t pathlen = strlen(path); - - if (path[pathlen - 1] == ']' || path[pathlen - 1] == '>' - || path[pathlen - 1] == ':') { - /* Clear VMS directory syntax, just copy as is */ - OPENSSL_strlcpy(newpath, path, newlen); - } + if (path[pathlen - 1] == ']' + || path[pathlen - 1] == '>' + || path[pathlen - 1] == ':') { + /* Clear VMS directory syntax, just copy as is */ + OPENSSL_strlcpy(newpath, path, newlen); } #endif if (newpath[0] == '\0') { @@ -833,7 +880,8 @@ static char *eat_alpha_numeric(CONF *conf, char *p) p = scan_esc(conf, p); continue; } - if (!IS_ALNUM_PUNCT(conf, *p)) + if (!(IS_ALNUM_PUNCT(conf, *p) + || (conf->flag_dollarid && IS_DOLLAR(conf, *p)))) return p; p++; } diff --git a/crypto/conf/conf_def.h b/crypto/conf/conf_def.h index 725c430c..3fdb6a9b 100644 --- a/crypto/conf/conf_def.h +++ b/crypto/conf/conf_def.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/conf/keysets.pl * - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 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 @@ -20,6 +20,7 @@ #define CONF_DQUOTE 1024 #define CONF_COMMENT 128 #define CONF_FCOMMENT 2048 +#define CONF_DOLLAR 4096 #define CONF_EOF 8 #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) #define CONF_ALNUM (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) @@ -36,13 +37,14 @@ #define IS_ALNUM_PUNCT(conf,c) is_keytype(conf, c, CONF_ALNUM_PUNCT) #define IS_QUOTE(conf,c) is_keytype(conf, c, CONF_QUOTE) #define IS_DQUOTE(conf,c) is_keytype(conf, c, CONF_DQUOTE) +#define IS_DOLLAR(conf,c) is_keytype(conf, c, CONF_DOLLAR) static const unsigned short CONF_type_default[128] = { 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, + 0x0010, 0x0200, 0x0040, 0x0080, 0x1000, 0x0200, 0x0200, 0x0040, 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, @@ -56,13 +58,13 @@ static const unsigned short CONF_type_default[128] = { 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, }; -#if ! OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 static const unsigned short CONF_type_win32[128] = { 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, + 0x0010, 0x0200, 0x0400, 0x0000, 0x1000, 0x0200, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c index 96d2cd99..daf2320a 100644 --- a/crypto/conf/conf_err.c +++ b/crypto/conf/conf_err.c @@ -15,8 +15,11 @@ static const ERR_STRING_DATA CONF_str_reasons[] = { {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_ERROR_LOADING_DSO), "error loading dso"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_INVALID_PRAGMA), "invalid pragma"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION), + "mandatory braces in variable expansion"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_CLOSE_SQUARE_BRACKET), "missing close square bracket"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_EQUAL_SIGN), diff --git a/crypto/conf/conf_sap.c b/crypto/conf/conf_sap.c index 921ff770..2c5ee2a1 100644 --- a/crypto/conf/conf_sap.c +++ b/crypto/conf/conf_sap.c @@ -27,7 +27,7 @@ static int openssl_configured = 0; -#if !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 void OPENSSL_config(const char *appname) { OPENSSL_INIT_SETTINGS settings; diff --git a/crypto/conf/keysets.pl b/crypto/conf/keysets.pl index 05b086f7..42c19883 100644 --- a/crypto/conf/keysets.pl +++ b/crypto/conf/keysets.pl @@ -20,6 +20,7 @@ my $QUOTE = 0x0040; my $DQUOTE = 0x0400; my $COMMENT = 0x0080; my $FCOMMENT = 0x0800; +my $DOLLAR = 0x1000; my $EOF = 0x0008; my @V_def; my @V_w32; @@ -38,6 +39,7 @@ foreach (0 .. 127) { $v |= $ESC if $c =~ /\\/; $v |= $QUOTE if $c =~ /['`"]/; # for emacs: "`' $v |= $COMMENT if $c =~ /\#/; + $v |= $DOLLAR if $c eq '$'; $v |= $EOF if $c =~ /\0/; push(@V_def, $v); @@ -50,13 +52,13 @@ foreach (0 .. 127) { $v |= $WS if $c =~ /[ \t\r\n]/; $v |= $DQUOTE if $c =~ /["]/; # for emacs: " $v |= $FCOMMENT if $c =~ /;/; + $v |= $DOLLAR if $c eq '$'; $v |= $EOF if $c =~ /\0/; push(@V_w32, $v); } -# Output year depends on the year of the script. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; - +# The year the output file is generated. +my $YEAR = [localtime()]->[5] + 1900; print <<"EOF"; /* * WARNING: do not edit! @@ -80,6 +82,7 @@ print <<"EOF"; #define CONF_DQUOTE $DQUOTE #define CONF_COMMENT $COMMENT #define CONF_FCOMMENT $FCOMMENT +#define CONF_DOLLAR $DOLLAR #define CONF_EOF $EOF #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) #define CONF_ALNUM (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) @@ -96,6 +99,7 @@ print <<"EOF"; #define IS_ALNUM_PUNCT(conf,c) is_keytype(conf, c, CONF_ALNUM_PUNCT) #define IS_QUOTE(conf,c) is_keytype(conf, c, CONF_QUOTE) #define IS_DQUOTE(conf,c) is_keytype(conf, c, CONF_DQUOTE) +#define IS_DOLLAR(conf,c) is_keytype(conf, c, CONF_DOLLAR) EOF @@ -108,7 +112,7 @@ for ($i = 0; $i < 128; $i++) { } print "\n};\n\n"; -print "#if ! OPENSSL_API_3\n"; +print "#ifndef OPENSSL_NO_DEPRECATED_3_0\n"; print "static const unsigned short CONF_type_win32[128] = {"; for ($i = 0; $i < 128; $i++) { print "\n " if ($i % 8) == 0; diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index ed50bb87..7f815a50 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -31,9 +31,8 @@ static void ossl_method_construct_this(OSSL_PROVIDER *provider, struct construct_data_st *data = cbdata; void *method = NULL; - if ((method = data->mcm->construct(algo->algorithm_names, - algo->implementation, provider, - data->mcm_data)) == NULL) + if ((method = data->mcm->construct(algo, provider, data->mcm_data)) + == NULL) return; /* diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index 71b70ff5..4723604e 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -72,9 +72,11 @@ static void stored_namemap_free(void *vnamemap) { OSSL_NAMEMAP *namemap = vnamemap; - /* Pretend it isn't stored, or ossl_namemap_free() will do nothing */ - namemap->stored = 0; - ossl_namemap_free(namemap); + if (namemap != NULL) { + /* Pretend it isn't stored, or ossl_namemap_free() will do nothing */ + namemap->stored = 0; + ossl_namemap_free(namemap); + } } static const OPENSSL_CTX_METHOD stored_namemap_method = { @@ -87,36 +89,16 @@ static const OPENSSL_CTX_METHOD stored_namemap_method = { * ============= */ -OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx) +int ossl_namemap_empty(OSSL_NAMEMAP *namemap) { - return openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX, - &stored_namemap_method); -} + int rv = 0; -OSSL_NAMEMAP *ossl_namemap_new(void) -{ - OSSL_NAMEMAP *namemap; + CRYPTO_THREAD_read_lock(namemap->lock); + if (namemap->max_number == 0) + rv = 1; + CRYPTO_THREAD_unlock(namemap->lock); - if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL - && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL - && (namemap->namenum = - lh_NAMENUM_ENTRY_new(namenum_hash, namenum_cmp)) != NULL) - return namemap; - - ossl_namemap_free(namemap); - return NULL; -} - -void ossl_namemap_free(OSSL_NAMEMAP *namemap) -{ - if (namemap == NULL || namemap->stored) - return; - - lh_NAMENUM_ENTRY_doall(namemap->namenum, namenum_free); - lh_NAMENUM_ENTRY_free(namemap->namenum); - - CRYPTO_THREAD_lock_free(namemap->lock); - OPENSSL_free(namemap); + return rv; } typedef struct doall_names_data_st { @@ -210,8 +192,8 @@ const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number, return data.name; } -int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number, - const char *name, size_t name_len) +int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number, + const char *name, size_t name_len) { NAMENUM_ENTRY *namenum = NULL; int tmp_number; @@ -251,10 +233,177 @@ int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number, return 0; } -int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name) +int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name) { if (name == NULL) return 0; - return ossl_namemap_add_n(namemap, number, name, strlen(name)); + return ossl_namemap_add_name_n(namemap, number, name, strlen(name)); +} + +int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number, + const char *names, const char separator) +{ + const char *p, *q; + size_t l; + + /* Check that we have a namemap */ + if (!ossl_assert(namemap != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * Check that no name is an empty string, and that all names have at + * most one numeric identity together. + */ + for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { + int this_number; + + if ((q = strchr(p, separator)) == NULL) + l = strlen(p); /* offset to \0 */ + else + l = q - p; /* offset to the next separator */ + + this_number = ossl_namemap_name2num_n(namemap, p, l); + + if (*p == '\0' || *p == separator) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_BAD_ALGORITHM_NAME); + return 0; + } + if (number == 0) { + number = this_number; + } else if (this_number != 0 && this_number != number) { + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_CONFLICTING_NAMES, + "\"%.*s\" has an existing different identity %d (from \"%s\")", + l, p, this_number, names); + return 0; + } + } + + /* Now that we have checked, register all names */ + for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { + int this_number; + + if ((q = strchr(p, separator)) == NULL) + l = strlen(p); /* offset to \0 */ + else + l = q - p; /* offset to the next separator */ + + this_number = ossl_namemap_add_name_n(namemap, number, p, l); + if (number == 0) { + number = this_number; + } else if (this_number != number) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR, + "Got number %d when expecting %d", + this_number, number); + return 0; + } + } + + return number; +} + +/*- + * Pre-population + * ============== + */ + +#ifndef FIPS_MODE +#include + +/* Creates an initial namemap with names found in the legacy method db */ +static void get_legacy_evp_names(const char *main_name, const char *alias, + void *arg) +{ + int main_id = ossl_namemap_add_name(arg, 0, main_name); + + /* + * We could check that the returned value is the same as main_id, + * but since this is a void function, there's no sane way to report + * the error. The best we can do is trust ourselve to keep the legacy + * method database conflict free. + * + * This registers any alias with the same number as the main name. + * Should it be that the current |on| *has* the main name, this is + * simply a no-op. + */ + if (alias != NULL) { + (void)ossl_namemap_add_name(arg, main_id, alias); + } +} + +static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg) +{ + const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type); + + get_legacy_evp_names(EVP_CIPHER_name(cipher), on->name, arg); +} + +static void get_legacy_md_names(const OBJ_NAME *on, void *arg) +{ + const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type); + /* We don't want the pkey_type names, so we need some extra care */ + int snid, lnid; + + snid = OBJ_sn2nid(on->name); + lnid = OBJ_ln2nid(on->name); + if (snid != EVP_MD_pkey_type(md) && lnid != EVP_MD_pkey_type(md)) + get_legacy_evp_names(EVP_MD_name(md), on->name, arg); + else + get_legacy_evp_names(EVP_MD_name(md), NULL, arg); +} +#endif + +/*- + * Constructors / destructors + * ========================== + */ + +OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx) +{ + OSSL_NAMEMAP *namemap = + openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX, + &stored_namemap_method); + +#ifndef FIPS_MODE + if (namemap != NULL && ossl_namemap_empty(namemap)) { + /* Before pilfering, we make sure the legacy database is populated */ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); + + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, + get_legacy_cipher_names, namemap); + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, + get_legacy_md_names, namemap); + } +#endif + + return namemap; +} + +OSSL_NAMEMAP *ossl_namemap_new(void) +{ + OSSL_NAMEMAP *namemap; + + if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL + && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL + && (namemap->namenum = + lh_NAMENUM_ENTRY_new(namenum_hash, namenum_cmp)) != NULL) + return namemap; + + ossl_namemap_free(namemap); + return NULL; +} + +void ossl_namemap_free(OSSL_NAMEMAP *namemap) +{ + if (namemap == NULL || namemap->stored) + return; + + lh_NAMENUM_ENTRY_doall(namemap->namenum, namenum_free); + lh_NAMENUM_ENTRY_free(namemap->namenum); + + CRYPTO_THREAD_lock_free(namemap->lock); + OPENSSL_free(namemap); } diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c index 0028b329..0201f31e 100644 --- a/crypto/cpt_err.c +++ b/crypto/cpt_err.c @@ -14,6 +14,10 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA CRYPTO_str_reasons[] = { + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_BAD_ALGORITHM_NAME), + "bad algorithm name"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_CONFLICTING_NAMES), + "conflicting names"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT), diff --git a/crypto/crmf/crmf_asn.c b/crypto/crmf/crmf_asn.c index 43801567..8b6657f9 100644 --- a/crypto/crmf/crmf_asn.c +++ b/crypto/crmf/crmf_asn.c @@ -235,6 +235,5 @@ IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSG) ASN1_ITEM_TEMPLATE(OSSL_CRMF_MSGS) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CRMF_MSGS, OSSL_CRMF_MSG) - ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS) +ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSGS) - diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 6ba3f7ab..64dbf809 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -97,10 +97,10 @@ static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm, return 0; } - /* id-regCtrl-regToken Control (section 6.1) */ +/* id-regCtrl-regToken Control (section 6.1) */ IMPLEMENT_CRMF_CTRL_FUNC(regToken, ASN1_STRING, regCtrl) - /* id-regCtrl-authenticator Control (section 6.2) */ +/* id-regCtrl-authenticator Control (section 6.2) */ #define ASN1_UTF8STRING_dup ASN1_STRING_dup IMPLEMENT_CRMF_CTRL_FUNC(authenticator, ASN1_UTF8STRING, regCtrl) @@ -153,11 +153,11 @@ int OSSL_CRMF_MSG_set_PKIPublicationInfo_action( return ASN1_INTEGER_set(pi->action, action); } - /* id-regCtrl-pkiPublicationInfo Control (section 6.3) */ +/* id-regCtrl-pkiPublicationInfo Control (section 6.3) */ IMPLEMENT_CRMF_CTRL_FUNC(pkiPublicationInfo, OSSL_CRMF_PKIPUBLICATIONINFO, regCtrl) - /* id-regCtrl-oldCertID Control (section 6.5) from the given */ +/* id-regCtrl-oldCertID Control (section 6.5) from the given */ IMPLEMENT_CRMF_CTRL_FUNC(oldCertID, OSSL_CRMF_CERTID, regCtrl) OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, @@ -188,10 +188,9 @@ OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, return NULL; } - /* - * id-regCtrl-protocolEncrKey Control (section 6.6) - * - */ +/* + * id-regCtrl-protocolEncrKey Control (section 6.6) + */ IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl) /*- @@ -567,7 +566,7 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, * return 1 if the type of req->popo->value.keyEncipherment * is OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE and * its value.subsequentMessage == OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT - */ + */ case OSSL_CRMF_POPO_KEYAGREE: default: CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, @@ -702,7 +701,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL) goto end; if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, - EVP_CIPHER_iv_length(cipher)) + EVP_CIPHER_iv_length(cipher)) != EVP_CIPHER_iv_length(cipher)) { CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, CRMF_R_MALFORMED_IV); diff --git a/crypto/crmf/crmf_local.h b/crypto/crmf/crmf_local.h index 577187f5..06b32b53 100644 --- a/crypto/crmf/crmf_local.h +++ b/crypto/crmf/crmf_local.h @@ -217,7 +217,7 @@ struct ossl_crmf_pbmparameter_st { ASN1_INTEGER *iterationCount; X509_ALGOR *mac; } /* OSSL_CRMF_PBMPARAMETER */; -#define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */ +# define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */ /*- * POPOSigningKeyInput ::= SEQUENCE { @@ -232,7 +232,7 @@ struct ossl_crmf_pbmparameter_st { * -- on the DER-encoded value of publicKey * publicKey SubjectPublicKeyInfo -- from CertTemplate * } -*/ + */ typedef struct ossl_crmf_poposigningkeyinput_authinfo_st { int type; union { diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c index c5e08c47..2dfa84e4 100644 --- a/crypto/crmf/crmf_pbm.c +++ b/crypto/crmf/crmf_pbm.c @@ -133,8 +133,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, int ok = 0; EVP_MAC *mac = NULL; EVP_MAC_CTX *mctx = NULL; - OSSL_PARAM macparams[3] = - { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + OSSL_PARAM macparams[3] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; if (out == NULL || pbmp == NULL || pbmp->mac == NULL || pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) { @@ -193,16 +192,15 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, mac_nid = OBJ_obj2nid(pbmp->mac->algorithm); if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL) - || ((mdname = OBJ_nid2sn(hmac_md_nid)) == NULL)) { + || (mdname = OBJ_nid2sn(hmac_md_nid)) == NULL) { CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM); goto err; } - macparams[0] = - OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, - (char *)mdname, 0); - macparams[1] = - OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen); + macparams[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + (char *)mdname, 0); + macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + basekey, bklen); if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL || (mctx = EVP_MAC_CTX_new(mac)) == NULL || !EVP_MAC_CTX_set_params(mctx, macparams) diff --git a/crypto/ct/ct_oct.c b/crypto/ct/ct_oct.c index cdab02fd..bd8d1bb1 100644 --- a/crypto/ct/ct_oct.c +++ b/crypto/ct/ct_oct.c @@ -101,7 +101,7 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) } len -= 43; p++; - sct->log_id = BUF_memdup(p, CT_V1_HASHLEN); + sct->log_id = OPENSSL_memdup(p, CT_V1_HASHLEN); if (sct->log_id == NULL) goto err; sct->log_id_len = CT_V1_HASHLEN; @@ -115,7 +115,7 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) goto err; } if (len2 > 0) { - sct->ext = BUF_memdup(p, len2); + sct->ext = OPENSSL_memdup(p, len2); if (sct->ext == NULL) goto err; } @@ -132,7 +132,7 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) *in = p + len; } else { /* If not V1 just cache encoding */ - sct->sct = BUF_memdup(p, len); + sct->sct = OPENSSL_memdup(p, len); if (sct->sct == NULL) goto err; sct->sct_len = len; diff --git a/crypto/cversion.c b/crypto/cversion.c index c81f56f4..530b0e80 100644 --- a/crypto/cversion.c +++ b/crypto/cversion.c @@ -33,12 +33,12 @@ unsigned int OPENSSL_version_patch(void) const char *OPENSSL_version_pre_release(void) { - return OPENSSL_VERSION_PRE_RELEASE_STR; + return OPENSSL_VERSION_PRE_RELEASE; } const char *OPENSSL_version_build_metadata(void) { - return OPENSSL_VERSION_BUILD_METADATA_STR; + return OPENSSL_VERSION_BUILD_METADATA; } extern char ossl_cpu_info_str[]; diff --git a/crypto/des/asm/des_enc.m4 b/crypto/des/asm/des_enc.m4 index c6661fe7..c00ac618 100644 --- a/crypto/des/asm/des_enc.m4 +++ b/crypto/des/asm/des_enc.m4 @@ -104,15 +104,15 @@ changequote({,}) ! technique. ! ! The macro also loads address sbox 1 to 5 to global 1 to 5, address -! sbox 6 to local6, and addres sbox 8 to out3. +! sbox 6 to local6, and address sbox 8 to out3. ! -! Rotates the halfs 3 left to bring the sbox bits in convenient positions. +! Rotates the halves 3 left to bring the sbox bits in convenient positions. ! ! Loads key first round from address in parameter 5 to out0, out1. ! ! After the original LibDES initial permutation, the resulting left ! is in the variable initially used for right and vice versa. The macro -! implements the possibility to keep the halfs in the original registers. +! implements the possibility to keep the halves in the original registers. ! ! parameter 1 left ! parameter 2 right @@ -1182,7 +1182,7 @@ DES_encrypt2: add %o7,global1,global1 sub global1,.PIC.DES_SPtrans-.des_and,out2 - ! Set sbox address 1 to 6 and rotate halfs 3 left + ! Set sbox address 1 to 6 and rotate halves 3 left ! Errors caught by destest? Yes. Still? *NO* !sethi %hi(DES_SPtrans), global1 ! address sbox 1 diff --git a/crypto/des/build.info b/crypto/des/build.info index b1c1e624..40e87482 100644 --- a/crypto/des/build.info +++ b/crypto/des/build.info @@ -9,6 +9,7 @@ IF[{- !$disabled{asm} -}] # appropriate one IF[$DESASM_{- $target{asm_arch} -}] $DESASM=$DESASM_{- $target{asm_arch} -} + $DESDEF=DES_ASM ENDIF ENDIF @@ -21,6 +22,8 @@ SOURCE[../../libcrypto]=$COMMON\ str2key.c pcbc_enc.c qud_cksm.c rand_key.c \ fcrypt.c xcbc_enc.c cbc_cksm.c SOURCE[../../providers/libfips.a]=$COMMON +DEFINE[../../libcrypto]=$DESDEF +DEFINE[../../providers/libfips.a]=$DESDEF GENERATE[des_enc-sparc.S]=asm/des_enc.m4 GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index abb9bfdc..174bd04c 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -295,8 +295,8 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) else ktype = "DH Parameters"; - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) goto err; indent += 4; @@ -315,8 +315,10 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) goto err; if (x->seed) { int i; - BIO_indent(bp, indent, 128); - BIO_puts(bp, "seed:"); + + if (!BIO_indent(bp, indent, 128) + || BIO_puts(bp, "seed:") <= 0) + goto err; for (i = 0; i < x->seedlen; i++) { if ((i % 15) == 0) { if (BIO_puts(bp, "\n") <= 0 @@ -333,9 +335,9 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent)) goto err; if (x->length != 0) { - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "recommended-private-length: %d bits\n", - (int)x->length) <= 0) + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "recommended-private-length: %d bits\n", + (int)x->length) <= 0) goto err; } @@ -976,6 +978,7 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) err: OPENSSL_free(penc); X509_ALGOR_free(wrap_alg); + OPENSSL_free(dukm); return rv; } diff --git a/crypto/dh/dh_depr.c b/crypto/dh/dh_depr.c index f0903ca2..09403f6a 100644 --- a/crypto/dh/dh_depr.c +++ b/crypto/dh/dh_depr.c @@ -10,7 +10,7 @@ /* This file contains deprecated functions as wrappers to the new ones */ #include -#if OPENSSL_API_0_9_8 +#ifdef OPENSSL_NO_DEPRECATED_0_9_8 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 670ba1f7..65c2154c 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -78,8 +78,10 @@ DH *DH_new_method(ENGINE *engine) ret->flags = ret->meth->flags; +#ifndef FIPS_MODE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data)) goto err; +#endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL); @@ -112,7 +114,9 @@ void DH_free(DH *r) ENGINE_finish(r->engine); #endif +#ifndef FIPS_MODE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); @@ -139,6 +143,7 @@ int DH_up_ref(DH *r) return ((i > 1) ? 1 : 0); } +#ifndef FIPS_MODE int DH_set_ex_data(DH *d, int idx, void *arg) { return CRYPTO_set_ex_data(&d->ex_data, idx, arg); @@ -148,6 +153,7 @@ void *DH_get_ex_data(DH *d, int idx) { return CRYPTO_get_ex_data(&d->ex_data, idx); } +#endif int DH_bits(const DH *dh) { diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index a9041e94..378cf5c9 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -33,7 +33,9 @@ struct dh_st { int seedlen; BIGNUM *counter; CRYPTO_REF_COUNT references; +#ifndef FIPS_MODE CRYPTO_EX_DATA ex_data; +#endif const DH_METHOD *meth; ENGINE *engine; CRYPTO_RWLOCK *lock; diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info index 2e759853..309fda32 100644 --- a/crypto/dsa/build.info +++ b/crypto/dsa/build.info @@ -1,5 +1,9 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \ - dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \ + +$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c + +SOURCE[../../libcrypto]=$COMMON\ + dsa_gen.c dsa_key.c dsa_asn1.c \ + dsa_err.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \ dsa_meth.c +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c index bf16e282..20bf2518 100644 --- a/crypto/dsa/dsa_asn1.c +++ b/crypto/dsa/dsa_asn1.c @@ -15,110 +15,6 @@ #include #include "crypto/asn1_dsa.h" -DSA_SIG *DSA_SIG_new(void) -{ - DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); - if (sig == NULL) - DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); - return sig; -} - -void DSA_SIG_free(DSA_SIG *sig) -{ - if (sig == NULL) - return; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - OPENSSL_free(sig); -} - -DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) -{ - DSA_SIG *sig; - - if (len < 0) - return NULL; - if (psig != NULL && *psig != NULL) { - sig = *psig; - } else { - sig = DSA_SIG_new(); - if (sig == NULL) - return NULL; - } - if (sig->r == NULL) - sig->r = BN_new(); - if (sig->s == NULL) - sig->s = BN_new(); - if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { - if (psig == NULL || *psig == NULL) - DSA_SIG_free(sig); - return NULL; - } - if (psig != NULL && *psig == NULL) - *psig = sig; - return sig; -} - -int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) -{ - BUF_MEM *buf = NULL; - size_t encoded_len; - WPACKET pkt; - - if (ppout == NULL) { - if (!WPACKET_init_null(&pkt, 0)) - return -1; - } else if (*ppout == NULL) { - if ((buf = BUF_MEM_new()) == NULL - || !WPACKET_init_len(&pkt, buf, 0)) { - BUF_MEM_free(buf); - return -1; - } - } else { - if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) - return -1; - } - - if (!encode_der_dsa_sig(&pkt, sig->r, sig->s) - || !WPACKET_get_total_written(&pkt, &encoded_len) - || !WPACKET_finish(&pkt)) { - BUF_MEM_free(buf); - WPACKET_cleanup(&pkt); - return -1; - } - - if (ppout != NULL) { - if (*ppout == NULL) { - *ppout = (unsigned char *)buf->data; - buf->data = NULL; - BUF_MEM_free(buf); - } else { - *ppout += encoded_len; - } - } - - return (int)encoded_len; -} - -void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) - *pr = sig->r; - if (ps != NULL) - *ps = sig->s; -} - -int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} - /* Override the default free and new methods */ static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) @@ -168,50 +64,3 @@ DSA *DSAparams_dup(const DSA *dsa) { return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); } - -int DSA_sign(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa) -{ - DSA_SIG *s; - - s = DSA_do_sign(dgst, dlen, dsa); - if (s == NULL) { - *siglen = 0; - return 0; - } - *siglen = i2d_DSA_SIG(s, &sig); - DSA_SIG_free(s); - return 1; -} - -/* data has already been hashed (probably with SHA or SHA-1). */ -/*- - * returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa) -{ - DSA_SIG *s; - const unsigned char *p = sigbuf; - unsigned char *der = NULL; - int derlen = -1; - int ret = -1; - - s = DSA_SIG_new(); - if (s == NULL) - return ret; - if (d2i_DSA_SIG(&s, &p, siglen) == NULL) - goto err; - /* Ensure signature uses DER and doesn't have trailing garbage */ - derlen = i2d_DSA_SIG(s, &der); - if (derlen != siglen || memcmp(sigbuf, der, derlen)) - goto err; - ret = DSA_do_verify(dgst, dgst_len, s, dsa); - err: - OPENSSL_clear_free(der, derlen); - DSA_SIG_free(s); - return ret; -} diff --git a/crypto/dsa/dsa_depr.c b/crypto/dsa/dsa_depr.c index e97eaf12..2b363e26 100644 --- a/crypto/dsa/dsa_depr.c +++ b/crypto/dsa/dsa_depr.c @@ -20,7 +20,7 @@ #define xxxHASH EVP_sha1() #include -#if OPENSSL_API_0_9_8 +#ifdef OPENSSL_NO_DEPRECATED_0_9_8 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 4670c433..976eb622 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -15,155 +15,9 @@ #include #include #include +#include "crypto/dsa.h" -DSA *DSA_new(void) -{ - return DSA_new_method(NULL); -} - -int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) -{ - /* - * NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. - */ - const DSA_METHOD *mtmp; - mtmp = dsa->meth; - if (mtmp->finish) - mtmp->finish(dsa); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(dsa->engine); - dsa->engine = NULL; -#endif - dsa->meth = meth; - if (meth->init) - meth->init(dsa); - return 1; -} - -const DSA_METHOD *DSA_get_method(DSA *d) -{ - return d->meth; -} - -DSA *DSA_new_method(ENGINE *engine) -{ - DSA *ret = OPENSSL_zalloc(sizeof(*ret)); - - if (ret == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; - } - - ret->meth = DSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ - if (engine) { - if (!ENGINE_init(engine)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); - goto err; - } - ret->engine = engine; - } else - ret->engine = ENGINE_get_default_DSA(); - if (ret->engine) { - ret->meth = ENGINE_get_DSA(ret->engine); - if (ret->meth == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); - goto err; - } - } -#endif - - ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; - - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data)) - goto err; - - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); - goto err; - } - - return ret; - - err: - DSA_free(ret); - return NULL; -} - -void DSA_free(DSA *r) -{ - int i; - - if (r == NULL) - return; - - CRYPTO_DOWN_REF(&r->references, &i, r->lock); - REF_PRINT_COUNT("DSA", r); - if (i > 0) - return; - REF_ASSERT_ISNT(i < 0); - - if (r->meth != NULL && r->meth->finish != NULL) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); - - CRYPTO_THREAD_lock_free(r->lock); - - BN_clear_free(r->p); - BN_clear_free(r->q); - BN_clear_free(r->g); - BN_clear_free(r->pub_key); - BN_clear_free(r->priv_key); - OPENSSL_free(r); -} - -int DSA_up_ref(DSA *r) -{ - int i; - - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) - return 0; - - REF_PRINT_COUNT("DSA", r); - REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); -} - -int DSA_size(const DSA *r) -{ - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. However, - * i2d_ASN1_INTEGER() will not look beyond - * the first byte, as long as the second - * parameter is NULL. */ - - i = BN_num_bits(r->q); - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - return ret; -} +#ifndef FIPS_MODE int DSA_set_ex_data(DSA *d, int idx, void *arg) { @@ -175,13 +29,6 @@ void *DSA_get_ex_data(DSA *d, int idx) return CRYPTO_get_ex_data(&d->ex_data, idx); } -int DSA_security_bits(const DSA *d) -{ - if (d->p && d->q) - return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); - return -1; -} - #ifndef OPENSSL_NO_DH DH *DSA_dup_DH(const DSA *r) { @@ -240,6 +87,189 @@ DH *DSA_dup_DH(const DSA *r) } #endif +const BIGNUM *DSA_get0_p(const DSA *d) +{ + return d->p; +} + +const BIGNUM *DSA_get0_q(const DSA *d) +{ + return d->q; +} + +const BIGNUM *DSA_get0_g(const DSA *d) +{ + return d->g; +} + +const BIGNUM *DSA_get0_pub_key(const DSA *d) +{ + return d->pub_key; +} + +const BIGNUM *DSA_get0_priv_key(const DSA *d) +{ + return d->priv_key; +} + +void DSA_clear_flags(DSA *d, int flags) +{ + d->flags &= ~flags; +} + +int DSA_test_flags(const DSA *d, int flags) +{ + return d->flags & flags; +} + +void DSA_set_flags(DSA *d, int flags) +{ + d->flags |= flags; +} + +ENGINE *DSA_get0_engine(DSA *d) +{ + return d->engine; +} + +int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DSA_METHOD *mtmp; + mtmp = dsa->meth; + if (mtmp->finish) + mtmp->finish(dsa); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(dsa->engine); + dsa->engine = NULL; +#endif + dsa->meth = meth; + if (meth->init) + meth->init(dsa); + return 1; +} +#endif /* FIPS_MODE */ + + +const DSA_METHOD *DSA_get_method(DSA *d) +{ + return d->meth; +} + +static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine) +{ + DSA *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->references = 1; + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + + ret->meth = DSA_get_default_method(); +#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE) + ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ + if (engine) { + if (!ENGINE_init(engine)) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + goto err; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_DSA(); + if (ret->engine) { + ret->meth = ENGINE_get_DSA(ret->engine); + if (ret->meth == NULL) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + goto err; + } + } +#endif + + ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + +#ifndef FIPS_MODE + if (!crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data)) + goto err; +#endif + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); + goto err; + } + + return ret; + + err: + DSA_free(ret); + return NULL; +} + +DSA *DSA_new_method(ENGINE *engine) +{ + return dsa_new_method(NULL, engine); +} + +DSA *DSA_new(void) +{ + return DSA_new_method(NULL); +} + +void DSA_free(DSA *r) +{ + int i; + + if (r == NULL) + return; + + CRYPTO_DOWN_REF(&r->references, &i, r->lock); + REF_PRINT_COUNT("DSA", r); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + + if (r->meth != NULL && r->meth->finish != NULL) + r->meth->finish(r); +#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE) + ENGINE_finish(r->engine); +#endif + +#ifndef FIPS_MODE + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); +#endif + + CRYPTO_THREAD_lock_free(r->lock); + + BN_clear_free(r->p); + BN_clear_free(r->q); + BN_clear_free(r->g); + BN_clear_free(r->pub_key); + BN_clear_free(r->priv_key); + OPENSSL_free(r); +} + +int DSA_up_ref(DSA *r) +{ + int i; + + if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + return 0; + + REF_PRINT_COUNT("DSA", r); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { @@ -309,49 +339,11 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) return 1; } -const BIGNUM *DSA_get0_p(const DSA *d) +int DSA_security_bits(const DSA *d) { - return d->p; -} - -const BIGNUM *DSA_get0_q(const DSA *d) -{ - return d->q; -} - -const BIGNUM *DSA_get0_g(const DSA *d) -{ - return d->g; -} - -const BIGNUM *DSA_get0_pub_key(const DSA *d) -{ - return d->pub_key; -} - -const BIGNUM *DSA_get0_priv_key(const DSA *d) -{ - return d->priv_key; -} - -void DSA_clear_flags(DSA *d, int flags) -{ - d->flags &= ~flags; -} - -int DSA_test_flags(const DSA *d, int flags) -{ - return d->flags & flags; -} - -void DSA_set_flags(DSA *d, int flags) -{ - d->flags |= flags; -} - -ENGINE *DSA_get0_engine(DSA *d) -{ - return d->engine; + if (d->p && d->q) + return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); + return -1; } int DSA_bits(const DSA *dsa) diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h index e56ff069..f0ec7341 100644 --- a/crypto/dsa/dsa_local.h +++ b/crypto/dsa/dsa_local.h @@ -26,7 +26,9 @@ struct dsa_st { /* Normally used to cache montgomery values */ BN_MONT_CTX *method_mont_p; CRYPTO_REF_COUNT references; +#ifndef FIPS_MODE CRYPTO_EX_DATA ex_data; +#endif const DSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; @@ -78,3 +80,6 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, size_t seed_len, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, + int dlen, DSA *dsa); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 5e34fc55..af0fa6b5 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -44,10 +44,12 @@ static DSA_METHOD openssl_dsa_meth = { static const DSA_METHOD *default_DSA_method = &openssl_dsa_meth; +#ifndef FIPS_MODE void DSA_set_default_method(const DSA_METHOD *meth) { default_DSA_method = meth; } +#endif /* FIPS_MODE */ const DSA_METHOD *DSA_get_default_method(void) { @@ -59,7 +61,8 @@ const DSA_METHOD *DSA_OpenSSL(void) return &openssl_dsa_meth; } -static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst, + int dlen, DSA *dsa) { BIGNUM *kinv = NULL; BIGNUM *m, *blind, *blindm, *tmp; @@ -85,7 +88,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) if (ret->r == NULL || ret->s == NULL) goto err; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (ctx == NULL) goto err; m = BN_CTX_get(ctx); @@ -121,8 +124,8 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) /* Generate a blinding value */ do { - if (!BN_priv_rand(blind, BN_num_bits(dsa->q) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->q) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) goto err; } while (BN_is_zero(blind)); BN_set_flags(blind, BN_FLG_CONSTTIME); @@ -164,7 +167,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) err: if (rv == 0) { - DSAerr(DSA_F_DSA_DO_SIGN, reason); + DSAerr(0, reason); DSA_SIG_free(ret); ret = NULL; } @@ -173,6 +176,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) return ret; } +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + return dsa_do_sign_int(NULL, dgst, dlen, dsa); +} + static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { @@ -210,7 +218,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, goto err; if (ctx_in == NULL) { - if ((ctx = BN_CTX_new()) == NULL) + /* if you don't pass in ctx_in you get a default libctx */ + if ((ctx = BN_CTX_new_ex(NULL)) == NULL) goto err; } else ctx = ctx_in; @@ -232,7 +241,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst, dlen, ctx)) goto err; - } else if (!BN_priv_rand_range(k, dsa->q)) + } else if (!BN_priv_rand_range_ex(k, dsa->q, ctx)) goto err; } while (BN_is_zero(k)); @@ -323,7 +332,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, u1 = BN_new(); u2 = BN_new(); t1 = BN_new(); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(NULL); /* verify does not need a libctx */ if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL) goto err; diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index 68501efa..d09aaea6 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -7,18 +7,195 @@ * https://www.openssl.org/source/license.html */ +#include #include "internal/cryptlib.h" #include "dsa_local.h" -#include +#include "crypto/asn1_dsa.h" +#include "crypto/dsa.h" DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { return dsa->meth->dsa_do_sign(dgst, dlen, dsa); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } #endif + +DSA_SIG *DSA_SIG_new(void) +{ + DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); + if (sig == NULL) + DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); + return sig; +} + +void DSA_SIG_free(DSA_SIG *sig) +{ + if (sig == NULL) + return; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + OPENSSL_free(sig); +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) +{ + DSA_SIG *sig; + + if (len < 0) + return NULL; + if (psig != NULL && *psig != NULL) { + sig = *psig; + } else { + sig = DSA_SIG_new(); + if (sig == NULL) + return NULL; + } + if (sig->r == NULL) + sig->r = BN_new(); + if (sig->s == NULL) + sig->s = BN_new(); + if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (psig == NULL || *psig == NULL) + DSA_SIG_free(sig); + return NULL; + } + if (psig != NULL && *psig == NULL) + *psig = sig; + return sig; +} + +int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) +{ + BUF_MEM *buf = NULL; + size_t encoded_len; + WPACKET pkt; + + if (ppout == NULL) { + if (!WPACKET_init_null(&pkt, 0)) + return -1; + } else if (*ppout == NULL) { + if ((buf = BUF_MEM_new()) == NULL + || !WPACKET_init_len(&pkt, buf, 0)) { + BUF_MEM_free(buf); + return -1; + } + } else { + if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) + return -1; + } + + if (!encode_der_dsa_sig(&pkt, sig->r, sig->s) + || !WPACKET_get_total_written(&pkt, &encoded_len) + || !WPACKET_finish(&pkt)) { + BUF_MEM_free(buf); + WPACKET_cleanup(&pkt); + return -1; + } + + if (ppout != NULL) { + if (*ppout == NULL) { + *ppout = (unsigned char *)buf->data; + buf->data = NULL; + BUF_MEM_free(buf); + } else { + *ppout += encoded_len; + } + } + + return (int)encoded_len; +} + +int DSA_size(const DSA *dsa) +{ + int ret; + DSA_SIG sig; + + sig.r = sig.s = dsa->q; + ret = i2d_DSA_SIG(&sig, NULL); + + if (ret < 0) + ret = 0; + return ret; +} + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst, + int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + DSA_SIG *s; + + /* legacy case uses the method table */ + if (libctx == NULL || dsa->meth != DSA_get_default_method()) + s = DSA_do_sign(dgst, dlen, dsa); + else + s = dsa_do_sign_int(libctx, dgst, dlen, dsa); + if (s == NULL) { + *siglen = 0; + return 0; + } + *siglen = i2d_DSA_SIG(s, &sig); + DSA_SIG_free(s); + return 1; +} + +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + return dsa_sign_int(NULL, type, dgst, dlen, sig, siglen, dsa); +} + +/* data has already been hashed (probably with SHA or SHA-1). */ +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = DSA_SIG_new(); + if (s == NULL) + return ret; + if (d2i_DSA_SIG(&s, &p, siglen) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_DSA_SIG(s, &der); + if (derlen != siglen || memcmp(sigbuf, der, derlen)) + goto err; + ret = DSA_do_verify(dgst, dgst_len, s, dsa); + err: + OPENSSL_clear_free(der, derlen); + DSA_SIG_free(s); + return ret; +} + diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl index 4e6bfef4..4809360a 100755 --- a/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -1398,7 +1398,7 @@ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); # 256-bit vectors on top. Then note that we push # starting from r0, which means that we have copy of # input arguments just below these temporary vectors. -# We use three of them for !in1infty, !in2intfy and +# We use three of them for ~in1infty, ~in2infty and # result of check for zero. $code.=<<___; @@ -1428,7 +1428,7 @@ ecp_nistz256_point_add: #endif movne r12,#-1 stmia r3,{r4-r11} - str r12,[sp,#32*18+8] @ !in2infty + str r12,[sp,#32*18+8] @ ~in2infty ldmia $a_ptr!,{r4-r11} @ copy in1_x add r3,sp,#$in1_x @@ -1449,7 +1449,7 @@ ecp_nistz256_point_add: #endif movne r12,#-1 stmia r3,{r4-r11} - str r12,[sp,#32*18+4] @ !in1infty + str r12,[sp,#32*18+4] @ ~in1infty add $a_ptr,sp,#$in2_z add $b_ptr,sp,#$in2_z @@ -1514,33 +1514,20 @@ ecp_nistz256_point_add: orr $a0,$a0,$a2 orr $a4,$a4,$a6 orr $a0,$a0,$a7 - orrs $a0,$a0,$a4 + orr $a0,$a0,$a4 @ ~is_equal(U1,U2) - bne .Ladd_proceed @ is_equal(U1,U2)? + ldr $t0,[sp,#32*18+4] @ ~in1infty + ldr $t1,[sp,#32*18+8] @ ~in2infty + ldr $t2,[sp,#32*18+12] @ ~is_equal(S1,S2) + mvn $t0,$t0 @ -1/0 -> 0/-1 + mvn $t1,$t1 @ -1/0 -> 0/-1 + orr $a0,$t0 + orr $a0,$t1 + orrs $a0,$t2 @ set flags - ldr $t0,[sp,#32*18+4] - ldr $t1,[sp,#32*18+8] - ldr $t2,[sp,#32*18+12] - tst $t0,$t1 - beq .Ladd_proceed @ (in1infty || in2infty)? - tst $t2,$t2 - beq .Ladd_double @ is_equal(S1,S2)? + @ if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + bne .Ladd_proceed - ldr $r_ptr,[sp,#32*18+16] - eor r4,r4,r4 - eor r5,r5,r5 - eor r6,r6,r6 - eor r7,r7,r7 - eor r8,r8,r8 - eor r9,r9,r9 - eor r10,r10,r10 - eor r11,r11,r11 - stmia $r_ptr!,{r4-r11} - stmia $r_ptr!,{r4-r11} - stmia $r_ptr!,{r4-r11} - b .Ladd_done - -.align 4 .Ladd_double: ldr $a_ptr,[sp,#32*18+20] add sp,sp,#32*(18-5)+16 @ difference in frame sizes @@ -1605,15 +1592,15 @@ ecp_nistz256_point_add: add $b_ptr,sp,#$S2 bl __ecp_nistz256_sub_from @ p256_sub(res_y, res_y, S2); - ldr r11,[sp,#32*18+4] @ !in1intfy - ldr r12,[sp,#32*18+8] @ !in2intfy + ldr r11,[sp,#32*18+4] @ ~in1infty + ldr r12,[sp,#32*18+8] @ ~in2infty add r1,sp,#$res_x add r2,sp,#$in2_x - and r10,r11,r12 + and r10,r11,r12 @ ~in1infty & ~in2infty mvn r11,r11 add r3,sp,#$in1_x - and r11,r11,r12 - mvn r12,r12 + and r11,r11,r12 @ in1infty & ~in2infty + mvn r12,r12 @ in2infty ldr $r_ptr,[sp,#32*18+16] ___ for($i=0;$i<96;$i+=8) { # conditional moves @@ -1621,11 +1608,11 @@ $code.=<<___; ldmia r1!,{r4-r5} @ res_x ldmia r2!,{r6-r7} @ in2_x ldmia r3!,{r8-r9} @ in1_x - and r4,r4,r10 + and r4,r4,r10 @ ~in1infty & ~in2infty and r5,r5,r10 - and r6,r6,r11 + and r6,r6,r11 @ in1infty & ~in2infty and r7,r7,r11 - and r8,r8,r12 + and r8,r8,r12 @ in2infty and r9,r9,r12 orr r4,r4,r6 orr r5,r5,r7 @@ -1660,7 +1647,7 @@ my $Z1sqr = $S2; # 256-bit vectors on top. Then note that we push # starting from r0, which means that we have copy of # input arguments just below these temporary vectors. -# We use two of them for !in1infty, !in2intfy. +# We use two of them for ~in1infty, ~in2infty. my @ONE_mont=(1,0,0,-1,-1,-1,-2,0); @@ -1691,7 +1678,7 @@ ecp_nistz256_point_add_affine: #endif movne r12,#-1 stmia r3,{r4-r11} - str r12,[sp,#32*15+4] @ !in1infty + str r12,[sp,#32*15+4] @ ~in1infty ldmia $b_ptr!,{r4-r11} @ copy in2_x add r3,sp,#$in2_x @@ -1718,7 +1705,7 @@ ecp_nistz256_point_add_affine: it ne #endif movne r12,#-1 - str r12,[sp,#32*15+8] @ !in2infty + str r12,[sp,#32*15+8] @ ~in2infty add $a_ptr,sp,#$in1_z add $b_ptr,sp,#$in1_z @@ -1800,15 +1787,15 @@ ecp_nistz256_point_add_affine: add $b_ptr,sp,#$S2 bl __ecp_nistz256_sub_from @ p256_sub(res_y, res_y, S2); - ldr r11,[sp,#32*15+4] @ !in1intfy - ldr r12,[sp,#32*15+8] @ !in2intfy + ldr r11,[sp,#32*15+4] @ ~in1infty + ldr r12,[sp,#32*15+8] @ ~in2infty add r1,sp,#$res_x add r2,sp,#$in2_x - and r10,r11,r12 + and r10,r11,r12 @ ~in1infty & ~in2infty mvn r11,r11 add r3,sp,#$in1_x - and r11,r11,r12 - mvn r12,r12 + and r11,r11,r12 @ in1infty & ~in2infty + mvn r12,r12 @ in2infty ldr $r_ptr,[sp,#32*15] ___ for($i=0;$i<64;$i+=8) { # conditional moves @@ -1816,11 +1803,11 @@ $code.=<<___; ldmia r1!,{r4-r5} @ res_x ldmia r2!,{r6-r7} @ in2_x ldmia r3!,{r8-r9} @ in1_x - and r4,r4,r10 + and r4,r4,r10 @ ~in1infty & ~in2infty and r5,r5,r10 - and r6,r6,r11 + and r6,r6,r11 @ in1infty & ~in2infty and r7,r7,r11 - and r8,r8,r12 + and r8,r8,r12 @ in2infty and r9,r9,r12 orr r4,r4,r6 orr r5,r5,r7 diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl index 2bcf130b..3be0c1c0 100644 --- a/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -725,7 +725,7 @@ $code.=<<___; .align 5 ecp_nistz256_point_double: .inst 0xd503233f // paciasp - stp x29,x30,[sp,#-80]! + stp x29,x30,[sp,#-96]! add x29,sp,#0 stp x19,x20,[sp,#16] stp x21,x22,[sp,#32] @@ -858,7 +858,7 @@ ecp_nistz256_point_double: add sp,x29,#0 // destroy frame ldp x19,x20,[x29,#16] ldp x21,x22,[x29,#32] - ldp x29,x30,[sp],#80 + ldp x29,x30,[sp],#96 .inst 0xd50323bf // autiasp ret .size ecp_nistz256_point_double,.-ecp_nistz256_point_double @@ -875,7 +875,7 @@ my ($res_x,$res_y,$res_z, my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); # above map() describes stack layout with 12 temporary # 256-bit vectors on top. -my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26)); +my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp0,$temp1,$temp2)=map("x$_",(21..28)); $code.=<<___; .globl ecp_nistz256_point_add @@ -883,12 +883,13 @@ $code.=<<___; .align 5 ecp_nistz256_point_add: .inst 0xd503233f // paciasp - stp x29,x30,[sp,#-80]! + stp x29,x30,[sp,#-96]! add x29,sp,#0 stp x19,x20,[sp,#16] stp x21,x22,[sp,#32] stp x23,x24,[sp,#48] stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] sub sp,sp,#32*12 ldp $a0,$a1,[$bp,#64] // in2_z @@ -902,7 +903,7 @@ ecp_nistz256_point_add: orr $t2,$a2,$a3 orr $in2infty,$t0,$t2 cmp $in2infty,#0 - csetm $in2infty,ne // !in2infty + csetm $in2infty,ne // ~in2infty add $rp,sp,#$Z2sqr bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); @@ -912,7 +913,7 @@ ecp_nistz256_point_add: orr $t2,$a2,$a3 orr $in1infty,$t0,$t2 cmp $in1infty,#0 - csetm $in1infty,ne // !in1infty + csetm $in1infty,ne // ~in1infty add $rp,sp,#$Z1sqr bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); @@ -953,7 +954,7 @@ ecp_nistz256_point_add: orr $acc0,$acc0,$acc1 // see if result is zero orr $acc2,$acc2,$acc3 - orr $temp,$acc0,$acc2 + orr $temp0,$acc0,$acc2 // ~is_equal(S1,S2) add $bp,sp,#$Z2sqr add $rp,sp,#$U1 @@ -974,32 +975,21 @@ ecp_nistz256_point_add: orr $acc0,$acc0,$acc1 // see if result is zero orr $acc2,$acc2,$acc3 - orr $acc0,$acc0,$acc2 - tst $acc0,$acc0 - b.ne .Ladd_proceed // is_equal(U1,U2)? + orr $acc0,$acc0,$acc2 // ~is_equal(U1,U2) - tst $in1infty,$in2infty - b.eq .Ladd_proceed // (in1infty || in2infty)? + mvn $temp1,$in1infty // -1/0 -> 0/-1 + mvn $temp2,$in2infty // -1/0 -> 0/-1 + orr $acc0,$acc0,$temp1 + orr $acc0,$acc0,$temp2 + orr $acc0,$acc0,$temp0 + cbnz $acc0,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) - tst $temp,$temp - b.eq .Ladd_double // is_equal(S1,S2)? - - eor $a0,$a0,$a0 - eor $a1,$a1,$a1 - stp $a0,$a1,[$rp_real] - stp $a0,$a1,[$rp_real,#16] - stp $a0,$a1,[$rp_real,#32] - stp $a0,$a1,[$rp_real,#48] - stp $a0,$a1,[$rp_real,#64] - stp $a0,$a1,[$rp_real,#80] - b .Ladd_done - -.align 4 .Ladd_double: mov $ap,$ap_real mov $rp,$rp_real ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] add sp,sp,#32*(12-4) // difference in stack frames b .Ldouble_shortcut @@ -1084,14 +1074,14 @@ ___ for($i=0;$i<64;$i+=32) { # conditional moves $code.=<<___; ldp $acc0,$acc1,[$ap_real,#$i] // in1 - cmp $in1infty,#0 // !$in1intfy, remember? + cmp $in1infty,#0 // ~$in1intfy, remember? ldp $acc2,$acc3,[$ap_real,#$i+16] csel $t0,$a0,$t0,ne csel $t1,$a1,$t1,ne ldp $a0,$a1,[sp,#$res_x+$i+32] // res csel $t2,$a2,$t2,ne csel $t3,$a3,$t3,ne - cmp $in2infty,#0 // !$in2intfy, remember? + cmp $in2infty,#0 // ~$in2intfy, remember? ldp $a2,$a3,[sp,#$res_x+$i+48] csel $acc0,$t0,$acc0,ne csel $acc1,$t1,$acc1,ne @@ -1105,13 +1095,13 @@ ___ } $code.=<<___; ldp $acc0,$acc1,[$ap_real,#$i] // in1 - cmp $in1infty,#0 // !$in1intfy, remember? + cmp $in1infty,#0 // ~$in1intfy, remember? ldp $acc2,$acc3,[$ap_real,#$i+16] csel $t0,$a0,$t0,ne csel $t1,$a1,$t1,ne csel $t2,$a2,$t2,ne csel $t3,$a3,$t3,ne - cmp $in2infty,#0 // !$in2intfy, remember? + cmp $in2infty,#0 // ~$in2intfy, remember? csel $acc0,$t0,$acc0,ne csel $acc1,$t1,$acc1,ne csel $acc2,$t2,$acc2,ne @@ -1125,7 +1115,8 @@ $code.=<<___; ldp x21,x22,[x29,#32] ldp x23,x24,[x29,#48] ldp x25,x26,[x29,#64] - ldp x29,x30,[sp],#80 + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 .inst 0xd50323bf // autiasp ret .size ecp_nistz256_point_add,.-ecp_nistz256_point_add @@ -1169,7 +1160,7 @@ ecp_nistz256_point_add_affine: orr $t2,$a2,$a3 orr $in1infty,$t0,$t2 cmp $in1infty,#0 - csetm $in1infty,ne // !in1infty + csetm $in1infty,ne // ~in1infty ldp $acc0,$acc1,[$bp] // in2_x ldp $acc2,$acc3,[$bp,#16] @@ -1183,7 +1174,7 @@ ecp_nistz256_point_add_affine: orr $t0,$t0,$t2 orr $in2infty,$acc0,$t0 cmp $in2infty,#0 - csetm $in2infty,ne // !in2infty + csetm $in2infty,ne // ~in2infty add $rp,sp,#$Z1sqr bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); @@ -1293,14 +1284,14 @@ ___ for($i=0;$i<64;$i+=32) { # conditional moves $code.=<<___; ldp $acc0,$acc1,[$ap_real,#$i] // in1 - cmp $in1infty,#0 // !$in1intfy, remember? + cmp $in1infty,#0 // ~$in1intfy, remember? ldp $acc2,$acc3,[$ap_real,#$i+16] csel $t0,$a0,$t0,ne csel $t1,$a1,$t1,ne ldp $a0,$a1,[sp,#$res_x+$i+32] // res csel $t2,$a2,$t2,ne csel $t3,$a3,$t3,ne - cmp $in2infty,#0 // !$in2intfy, remember? + cmp $in2infty,#0 // ~$in2intfy, remember? ldp $a2,$a3,[sp,#$res_x+$i+48] csel $acc0,$t0,$acc0,ne csel $acc1,$t1,$acc1,ne @@ -1317,13 +1308,13 @@ ___ } $code.=<<___; ldp $acc0,$acc1,[$ap_real,#$i] // in1 - cmp $in1infty,#0 // !$in1intfy, remember? + cmp $in1infty,#0 // ~$in1intfy, remember? ldp $acc2,$acc3,[$ap_real,#$i+16] csel $t0,$a0,$t0,ne csel $t1,$a1,$t1,ne csel $t2,$a2,$t2,ne csel $t3,$a3,$t3,ne - cmp $in2infty,#0 // !$in2intfy, remember? + cmp $in2infty,#0 // ~$in2intfy, remember? csel $acc0,$t0,$acc0,ne csel $acc1,$t1,$acc1,ne csel $acc2,$t2,$acc2,ne diff --git a/crypto/ec/asm/ecp_nistz256-avx2.pl b/crypto/ec/asm/ecp_nistz256-avx2.pl index 275aabb4..669eb560 100755 --- a/crypto/ec/asm/ecp_nistz256-avx2.pl +++ b/crypto/ec/asm/ecp_nistz256-avx2.pl @@ -49,7 +49,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $avx = ($ver>=3.0) + ($ver>=3.01); $addx = ($ver>=3.03); diff --git a/crypto/ec/asm/ecp_nistz256-x86.pl b/crypto/ec/asm/ecp_nistz256-x86.pl index b1b0b6bc..bf8c4db5 100755 --- a/crypto/ec/asm/ecp_nistz256-x86.pl +++ b/crypto/ec/asm/ecp_nistz256-x86.pl @@ -1387,7 +1387,7 @@ for ($i=0;$i<7;$i++) { # above map() describes stack layout with 18 temporary # 256-bit vectors on top, then we take extra words for - # !in1infty, !in2infty, result of check for zero and + # ~in1infty, ~in2infty, result of check for zero and # OPENSSL_ia32cap_P copy. [one unused word for padding] &stack_push(8*18+5); if ($sse2) { @@ -1418,7 +1418,7 @@ for ($i=0;$i<7;$i++) { &sub ("eax","ebp"); &or ("ebp","eax"); &sar ("ebp",31); - &mov (&DWP(32*18+4,"esp"),"ebp"); # !in2infty + &mov (&DWP(32*18+4,"esp"),"ebp"); # ~in2infty &lea ("edi",&DWP($in1_x,"esp")); for($i=0;$i<96;$i+=16) { @@ -1440,7 +1440,7 @@ for ($i=0;$i<7;$i++) { &sub ("eax","ebp"); &or ("ebp","eax"); &sar ("ebp",31); - &mov (&DWP(32*18+0,"esp"),"ebp"); # !in1infty + &mov (&DWP(32*18+0,"esp"),"ebp"); # ~in1infty &mov ("eax",&DWP(32*18+12,"esp")); # OPENSSL_ia32cap_P copy &lea ("esi",&DWP($in2_z,"esp")); @@ -1515,23 +1515,19 @@ for ($i=0;$i<7;$i++) { &or ("eax",&DWP(0,"edi")); &or ("eax",&DWP(4,"edi")); &or ("eax",&DWP(8,"edi")); - &or ("eax",&DWP(12,"edi")); + &or ("eax",&DWP(12,"edi")); # ~is_equal(U1,U2) + &mov ("ebx",&DWP(32*18+0,"esp")); # ~in1infty + ¬ ("ebx"); # -1/0 -> 0/-1 + &or ("eax","ebx"); + &mov ("ebx",&DWP(32*18+4,"esp")); # ~in2infty + ¬ ("ebx"); # -1/0 -> 0/-1 + &or ("eax","ebx"); + &or ("eax",&DWP(32*18+8,"esp")); # ~is_equal(S1,S2) + + # if (~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) &data_byte(0x3e); # predict taken - &jnz (&label("add_proceed")); # is_equal(U1,U2)? - - &mov ("eax",&DWP(32*18+0,"esp")); - &and ("eax",&DWP(32*18+4,"esp")); - &mov ("ebx",&DWP(32*18+8,"esp")); - &jz (&label("add_proceed")); # (in1infty || in2infty)? - &test ("ebx","ebx"); - &jz (&label("add_double")); # is_equal(S1,S2)? - - &mov ("edi",&wparam(0)); - &xor ("eax","eax"); - &mov ("ecx",96/4); - &data_byte(0xfc,0xf3,0xab); # cld; stosd - &jmp (&label("add_done")); + &jnz (&label("add_proceed")); &set_label("add_double",16); &mov ("esi",&wparam(1)); @@ -1613,34 +1609,34 @@ for ($i=0;$i<7;$i++) { &lea ("edi",&DWP($res_y,"esp")); &call ("_ecp_nistz256_sub"); # p256_sub(res_y, res_y, S2); - &mov ("ebp",&DWP(32*18+0,"esp")); # !in1infty - &mov ("esi",&DWP(32*18+4,"esp")); # !in2infty + &mov ("ebp",&DWP(32*18+0,"esp")); # ~in1infty + &mov ("esi",&DWP(32*18+4,"esp")); # ~in2infty &mov ("edi",&wparam(0)); &mov ("edx","ebp"); ¬ ("ebp"); - &and ("edx","esi"); - &and ("ebp","esi"); - ¬ ("esi"); + &and ("edx","esi"); # ~in1infty & ~in2infty + &and ("ebp","esi"); # in1infty & ~in2infty + ¬ ("esi"); # in2infty ######################################## # conditional moves for($i=64;$i<96;$i+=4) { - &mov ("eax","edx"); + &mov ("eax","edx"); # ~in1infty & ~in2infty &and ("eax",&DWP($res_x+$i,"esp")); - &mov ("ebx","ebp"); + &mov ("ebx","ebp"); # in1infty & ~in2infty &and ("ebx",&DWP($in2_x+$i,"esp")); - &mov ("ecx","esi"); + &mov ("ecx","esi"); # in2infty &and ("ecx",&DWP($in1_x+$i,"esp")); &or ("eax","ebx"); &or ("eax","ecx"); &mov (&DWP($i,"edi"),"eax"); } for($i=0;$i<64;$i+=4) { - &mov ("eax","edx"); + &mov ("eax","edx"); # ~in1infty & ~in2infty &and ("eax",&DWP($res_x+$i,"esp")); - &mov ("ebx","ebp"); + &mov ("ebx","ebp"); # in1infty & ~in2infty &and ("ebx",&DWP($in2_x+$i,"esp")); - &mov ("ecx","esi"); + &mov ("ecx","esi"); # in2infty &and ("ecx",&DWP($in1_x+$i,"esp")); &or ("eax","ebx"); &or ("eax","ecx"); @@ -1667,7 +1663,7 @@ for ($i=0;$i<7;$i++) { # above map() describes stack layout with 15 temporary # 256-bit vectors on top, then we take extra words for - # !in1infty, !in2infty, and OPENSSL_ia32cap_P copy. + # ~in1infty, ~in2infty, and OPENSSL_ia32cap_P copy. &stack_push(8*15+3); if ($sse2) { &call ("_picup_eax"); @@ -1697,7 +1693,7 @@ for ($i=0;$i<7;$i++) { &sub ("eax","ebp"); &or ("ebp","eax"); &sar ("ebp",31); - &mov (&DWP(32*15+0,"esp"),"ebp"); # !in1infty + &mov (&DWP(32*15+0,"esp"),"ebp"); # ~in1infty &lea ("edi",&DWP($in2_x,"esp")); for($i=0;$i<64;$i+=16) { @@ -1723,7 +1719,7 @@ for ($i=0;$i<7;$i++) { &lea ("ebp",&DWP($in1_z,"esp")); &sar ("ebx",31); &lea ("edi",&DWP($Z1sqr,"esp")); - &mov (&DWP(32*15+4,"esp"),"ebx"); # !in2infty + &mov (&DWP(32*15+4,"esp"),"ebx"); # ~in2infty &call ("_ecp_nistz256_mul_mont"); # p256_sqr_mont(Z1sqr, in1_z); @@ -1822,14 +1818,14 @@ for ($i=0;$i<7;$i++) { &lea ("edi",&DWP($res_y,"esp")); &call ("_ecp_nistz256_sub"); # p256_sub(res_y, res_y, S2); - &mov ("ebp",&DWP(32*15+0,"esp")); # !in1infty - &mov ("esi",&DWP(32*15+4,"esp")); # !in2infty + &mov ("ebp",&DWP(32*15+0,"esp")); # ~in1infty + &mov ("esi",&DWP(32*15+4,"esp")); # ~in2infty &mov ("edi",&wparam(0)); &mov ("edx","ebp"); ¬ ("ebp"); - &and ("edx","esi"); - &and ("ebp","esi"); - ¬ ("esi"); + &and ("edx","esi"); # ~in1infty & ~in2infty + &and ("ebp","esi"); # in1infty & ~in2infty + ¬ ("esi"); # in2infty ######################################## # conditional moves @@ -1847,11 +1843,11 @@ for ($i=0;$i<7;$i++) { &mov (&DWP($i,"edi"),"eax"); } for($i=0;$i<64;$i+=4) { - &mov ("eax","edx"); + &mov ("eax","edx"); # ~in1infty & ~in2infty &and ("eax",&DWP($res_x+$i,"esp")); - &mov ("ebx","ebp"); + &mov ("ebx","ebp"); # in1infty & ~in2infty &and ("ebx",&DWP($in2_x+$i,"esp")); - &mov ("ecx","esi"); + &mov ("ecx","esi"); # in2infty &and ("ecx",&DWP($in1_x+$i,"esp")); &or ("eax","ebx"); &or ("eax","ecx"); diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl index 53b60ddb..2fb0a2a6 100755 --- a/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -74,7 +74,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $avx = ($ver>=3.0) + ($ver>=3.01); $addx = ($ver>=3.03); @@ -1581,6 +1581,7 @@ $code.=<<___; .type ecp_nistz256_to_mont,\@function,2 .align 32 ecp_nistz256_to_mont: +.cfi_startproc ___ $code.=<<___ if ($addx); mov \$0x80100, %ecx @@ -1589,6 +1590,7 @@ ___ $code.=<<___; lea .LRR(%rip), $b_org jmp .Lmul_mont +.cfi_endproc .size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont ################################################################################ @@ -2564,6 +2566,7 @@ $code.=<<___; .type ecp_nistz256_scatter_w5,\@abi-omnipotent .align 32 ecp_nistz256_scatter_w5: +.cfi_startproc lea -3($index,$index,2), $index movdqa 0x00($in_t), %xmm0 shl \$5, $index @@ -2580,6 +2583,7 @@ ecp_nistz256_scatter_w5: movdqa %xmm5, 0x50($val,$index) ret +.cfi_endproc .size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5 ################################################################################ @@ -2687,6 +2691,7 @@ $code.=<<___; .type ecp_nistz256_scatter_w7,\@abi-omnipotent .align 32 ecp_nistz256_scatter_w7: +.cfi_startproc movdqu 0x00($in_t), %xmm0 shl \$6, $index movdqu 0x10($in_t), %xmm1 @@ -2698,6 +2703,7 @@ ecp_nistz256_scatter_w7: movdqa %xmm3, 0x30($val,$index) ret +.cfi_endproc .size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7 ################################################################################ @@ -3022,8 +3028,10 @@ $code.=<<___; .type ecp_nistz256_avx2_gather_w7,\@function,3 .align 32 ecp_nistz256_avx2_gather_w7: +.cfi_startproc .byte 0x0f,0x0b # ud2 ret +.cfi_endproc .size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7 ___ } @@ -3619,29 +3627,19 @@ $code.=<<___; call __ecp_nistz256_sub_from$x # p256_sub(H, U2, U1); or $acc5, $acc4 # see if result is zero + or $acc0, $acc4 + or $acc1, $acc4 # !is_equal(U1, U2) + + movq %xmm2, $acc0 # in1infty | in2infty + movq %xmm3, $acc1 # !is_equal(S1, S2) + or $acc0, $acc4 or $acc1, $acc4 + # if (!is_equal(U1, U2) | in1infty | in2infty | !is_equal(S1, S2)) .byte 0x3e # predict taken - jnz .Ladd_proceed$x # is_equal(U1,U2)? - movq %xmm2, $acc0 - movq %xmm3, $acc1 - test $acc0, $acc0 - jnz .Ladd_proceed$x # (in1infty || in2infty)? - test $acc1, $acc1 - jz .Ladd_double$x # is_equal(S1,S2)? + jnz .Ladd_proceed$x - movq %xmm0, $r_ptr # restore $r_ptr - pxor %xmm0, %xmm0 - movdqu %xmm0, 0x00($r_ptr) - movdqu %xmm0, 0x10($r_ptr) - movdqu %xmm0, 0x20($r_ptr) - movdqu %xmm0, 0x30($r_ptr) - movdqu %xmm0, 0x40($r_ptr) - movdqu %xmm0, 0x50($r_ptr) - jmp .Ladd_done$x - -.align 32 .Ladd_double$x: movq %xmm1, $a_ptr # restore $a_ptr movq %xmm0, $r_ptr # restore $r_ptr diff --git a/crypto/ec/asm/x25519-x86_64.pl b/crypto/ec/asm/x25519-x86_64.pl index 14583bd7..e5f5f759 100755 --- a/crypto/ec/asm/x25519-x86_64.pl +++ b/crypto/ec/asm/x25519-x86_64.pl @@ -92,7 +92,7 @@ if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } @@ -490,12 +490,14 @@ $code.=<<___; .type x25519_fe64_eligible,\@abi-omnipotent .align 32 x25519_fe64_eligible: +.cfi_startproc mov OPENSSL_ia32cap_P+8(%rip),%ecx xor %eax,%eax and \$0x80100,%ecx cmp \$0x80100,%ecx cmove %ecx,%eax ret +.cfi_endproc .size x25519_fe64_eligible,.-x25519_fe64_eligible .globl x25519_fe64_mul @@ -724,6 +726,7 @@ x25519_fe64_sqr: .align 32 x25519_fe64_mul121666: .Lfe64_mul121666_body: +.cfi_startproc mov \$121666,%edx mulx 8*0(%rsi),$acc0,%rcx mulx 8*1(%rsi),$acc1,%rax @@ -752,6 +755,7 @@ x25519_fe64_mul121666: .Lfe64_mul121666_epilogue: ret +.cfi_endproc .size x25519_fe64_mul121666,.-x25519_fe64_mul121666 .globl x25519_fe64_add @@ -759,6 +763,7 @@ x25519_fe64_mul121666: .align 32 x25519_fe64_add: .Lfe64_add_body: +.cfi_startproc mov 8*0(%rsi),$acc0 mov 8*1(%rsi),$acc1 mov 8*2(%rsi),$acc2 @@ -787,6 +792,7 @@ x25519_fe64_add: .Lfe64_add_epilogue: ret +.cfi_endproc .size x25519_fe64_add,.-x25519_fe64_add .globl x25519_fe64_sub @@ -794,6 +800,7 @@ x25519_fe64_add: .align 32 x25519_fe64_sub: .Lfe64_sub_body: +.cfi_startproc mov 8*0(%rsi),$acc0 mov 8*1(%rsi),$acc1 mov 8*2(%rsi),$acc2 @@ -822,6 +829,7 @@ x25519_fe64_sub: .Lfe64_sub_epilogue: ret +.cfi_endproc .size x25519_fe64_sub,.-x25519_fe64_sub .globl x25519_fe64_tobytes @@ -829,6 +837,7 @@ x25519_fe64_sub: .align 32 x25519_fe64_tobytes: .Lfe64_to_body: +.cfi_startproc mov 8*0(%rsi),$acc0 mov 8*1(%rsi),$acc1 mov 8*2(%rsi),$acc2 @@ -864,6 +873,7 @@ x25519_fe64_tobytes: .Lfe64_to_epilogue: ret +.cfi_endproc .size x25519_fe64_tobytes,.-x25519_fe64_tobytes ___ } else { @@ -872,8 +882,10 @@ $code.=<<___; .type x25519_fe64_eligible,\@abi-omnipotent .align 32 x25519_fe64_eligible: +.cfi_startproc xor %eax,%eax ret +.cfi_endproc .size x25519_fe64_eligible,.-x25519_fe64_eligible .globl x25519_fe64_mul @@ -889,8 +901,10 @@ x25519_fe64_mul121666: x25519_fe64_add: x25519_fe64_sub: x25519_fe64_tobytes: +.cfi_startproc .byte 0x0f,0x0b # ud2 ret +.cfi_endproc .size x25519_fe64_mul,.-x25519_fe64_mul ___ } diff --git a/crypto/ec/build.info b/crypto/ec/build.info index 90aea66a..ba16e088 100644 --- a/crypto/ec/build.info +++ b/crypto/ec/build.info @@ -73,6 +73,9 @@ GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl INCLUDE[ecp_nistz256-sparcv9.o]=.. +INCLUDE[ecp_s390x_nistp.o]=.. +INCLUDE[ecx_meth.o]=.. + GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl INCLUDE[ecp_nistz256-armv4.o]=.. GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index c993821b..0567f2ab 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -1342,32 +1342,27 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) return 1; } -#ifndef FIPS_MODE -int ECDSA_size(const EC_KEY *r) +int ECDSA_size(const EC_KEY *ec) { - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; + int ret; + ECDSA_SIG sig; const EC_GROUP *group; + const BIGNUM *bn; - if (r == NULL) + if (ec == NULL) return 0; - group = EC_KEY_get0_group(r); + group = EC_KEY_get0_group(ec); if (group == NULL) return 0; - i = EC_GROUP_order_bits(group); - if (i == 0) + bn = EC_GROUP_get0_order(group); + if (bn == NULL) return 0; - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + sig.r = sig.s = (BIGNUM *)bn; + ret = i2d_ECDSA_SIG(&sig, NULL); + + if (ret < 0) + ret = 0; return ret; } -#endif diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index ec8989f6..0fdd5f67 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -53,7 +53,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, return NULL; if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); + EC_GROUP_free(ret); return NULL; } @@ -74,7 +74,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, return NULL; if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); + EC_GROUP_free(ret); return NULL; } diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 69b3c7fc..168cf729 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -116,6 +116,7 @@ void EC_GROUP_free(EC_GROUP *group) OPENSSL_free(group); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 void EC_GROUP_clear_free(EC_GROUP *group) { if (!group) @@ -134,6 +135,7 @@ void EC_GROUP_clear_free(EC_GROUP *group) OPENSSL_clear_free(group->seed, group->seed_len); OPENSSL_clear_free(group, sizeof(*group)); } +#endif int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) { @@ -538,7 +540,7 @@ int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, return group->meth->group_get_curve(group, p, a, b, ctx); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { @@ -847,7 +849,7 @@ int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, return 1; } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) @@ -885,7 +887,7 @@ int EC_POINT_get_affine_coordinates(const EC_GROUP *group, return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) diff --git a/crypto/ec/ec_oct.c b/crypto/ec/ec_oct.c index e9b1b87a..041c442b 100644 --- a/crypto/ec/ec_oct.c +++ b/crypto/ec/ec_oct.c @@ -49,7 +49,7 @@ int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, y_bit, ctx); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, BN_CTX *ctx) diff --git a/crypto/ec/ec_print.c b/crypto/ec/ec_print.c index bb372d86..c76d7034 100644 --- a/crypto/ec/ec_print.c +++ b/crypto/ec/ec_print.c @@ -39,13 +39,13 @@ EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, EC_POINT *ret; if ((buf_len = BN_num_bytes(bn)) == 0) - return NULL; + buf_len = 1; if ((buf = OPENSSL_malloc(buf_len)) == NULL) { ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE); return NULL; } - if (!BN_bn2bin(bn, buf)) { + if (!BN_bn2binpad(bn, buf, buf_len)) { OPENSSL_free(buf); return NULL; } diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c index 8c4d530b..000b12a5 100644 --- a/crypto/ec/ecdh_kdf.c +++ b/crypto/ec/ecdh_kdf.c @@ -48,7 +48,7 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, * The old name for ecdh_KDF_X9_63 * Retained for ABI compatibility */ -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c index 5593d5d6..8de22ba9 100644 --- a/crypto/ec/ecdsa_ossl.c +++ b/crypto/ec/ecdsa_ossl.c @@ -344,7 +344,7 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, goto err; ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); err: - OPENSSL_clear_free(der, derlen); + OPENSSL_free(der); ECDSA_SIG_free(s); return ret; } diff --git a/crypto/ec/ecdsa_vrf.c b/crypto/ec/ecdsa_vrf.c index 75dfe5b9..60f4af04 100644 --- a/crypto/ec/ecdsa_vrf.c +++ b/crypto/ec/ecdsa_vrf.c @@ -23,7 +23,7 @@ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, if (eckey->meth->verify_sig != NULL) return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey); ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED); - return 0; + return -1; } /*- @@ -39,5 +39,5 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len, eckey); ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED); - return 0; + return -1; } diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index a726f8e2..6777d322 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -912,6 +912,7 @@ static void point_add(felem x3, felem y3, felem z3, felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; widefelem tmp, tmp2; limb z1_is_zero, z2_is_zero, x_equal, y_equal; + limb points_equal; if (!mixed) { /* ftmp2 = z2^2 */ @@ -968,15 +969,41 @@ static void point_add(felem x3, felem y3, felem z3, felem_reduce(ftmp, tmp); /* - * the formulae are incorrect if the points are equal so we check for - * this and do doubling if this happens + * The formulae are incorrect if the points are equal, in affine coordinates + * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this + * happens. + * + * We use bitwise operations to avoid potential side-channels introduced by + * the short-circuiting behaviour of boolean operators. */ x_equal = felem_is_zero(ftmp); y_equal = felem_is_zero(ftmp3); + /* + * The special case of either point being the point at infinity (z1 and/or + * z2 are zero), is handled separately later on in this function, so we + * avoid jumping to point_double here in those special cases. + */ z1_is_zero = felem_is_zero(z1); z2_is_zero = felem_is_zero(z2); - /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */ - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + + /* + * Compared to `ecp_nistp256.c` and `ecp_nistp521.c`, in this + * specific implementation `felem_is_zero()` returns truth as `0x1` + * (rather than `0xff..ff`). + * + * This implies that `~true` in this implementation becomes + * `0xff..fe` (rather than `0x0`): for this reason, to be used in + * the if expression, we mask out only the last bit in the next + * line. + */ + points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)) & 1; + + if (points_equal) { + /* + * This is obviously not constant-time but, as mentioned before, this + * case never happens during single point multiplication, so there is no + * timing leak for ECDH or ECDSA signing. + */ point_double(x3, y3, z3, x1, y1, z1); return; } diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index 4cbac522..954263c9 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -1241,6 +1241,7 @@ static void point_add(felem x3, felem y3, felem z3, longfelem tmp, tmp2; smallfelem small1, small2, small3, small4, small5; limb x_equal, y_equal, z1_is_zero, z2_is_zero; + limb points_equal; felem_shrink(small3, z1); @@ -1340,7 +1341,26 @@ static void point_add(felem x3, felem y3, felem z3, felem_shrink(small1, ftmp5); y_equal = smallfelem_is_zero(small1); - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + /* + * The formulae are incorrect if the points are equal, in affine coordinates + * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this + * happens. + * + * We use bitwise operations to avoid potential side-channels introduced by + * the short-circuiting behaviour of boolean operators. + * + * The special case of either point being the point at infinity (z1 and/or + * z2 are zero), is handled separately later on in this function, so we + * avoid jumping to point_double here in those special cases. + */ + points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)); + + if (points_equal) { + /* + * This is obviously not constant-time but, as mentioned before, this + * case never happens during single point multiplication, so there is no + * timing leak for ECDH or ECDSA signing. + */ point_double(x3, y3, z3, x1, y1, z1); return; } diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 6b5dc8eb..78a98c71 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -1158,6 +1158,7 @@ static void point_add(felem x3, felem y3, felem z3, felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; largefelem tmp, tmp2; limb x_equal, y_equal, z1_is_zero, z2_is_zero; + limb points_equal; z1_is_zero = felem_is_zero(z1); z2_is_zero = felem_is_zero(z2); @@ -1242,7 +1243,24 @@ static void point_add(felem x3, felem y3, felem z3, felem_scalar64(ftmp5, 2); /* ftmp5[i] < 2^61 */ - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + /* + * The formulae are incorrect if the points are equal, in affine coordinates + * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this + * happens. + * + * We use bitwise operations to avoid potential side-channels introduced by + * the short-circuiting behaviour of boolean operators. + * + * The special case of either point being the point at infinity (z1 and/or + * z2 are zero), is handled separately later on in this function, so we + * avoid jumping to point_double here in those special cases. + * + * Notice the comment below on the implications of this branching for timing + * leaks and why it is considered practically irrelevant. + */ + points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)); + + if (points_equal) { /* * This is obviously not constant-time but it will almost-never happen * for ECDH / ECDSA. The case where it can happen is during scalar-mult diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 603557ce..1609c4bb 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -358,16 +358,47 @@ static void ecp_nistz256_point_add(P256_POINT *r, ecp_nistz256_sub(H, U2, U1); /* H = U2 - U1 */ /* - * This should not happen during sign/ecdh, so no constant time violation + * The formulae are incorrect if the points are equal so we check for + * this and do doubling if this happens. + * + * Points here are in Jacobian projective coordinates (Xi, Yi, Zi) + * that are bound to the affine coordinates (xi, yi) by the following + * equations: + * - xi = Xi / (Zi)^2 + * - y1 = Yi / (Zi)^3 + * + * For the sake of optimization, the algorithm operates over + * intermediate variables U1, U2 and S1, S2 that are derived from + * the projective coordinates: + * - U1 = X1 * (Z2)^2 ; U2 = X2 * (Z1)^2 + * - S1 = Y1 * (Z2)^3 ; S2 = Y2 * (Z1)^3 + * + * It is easy to prove that is_equal(U1, U2) implies that the affine + * x-coordinates are equal, or either point is at infinity. + * Likewise is_equal(S1, S2) implies that the affine y-coordinates are + * equal, or either point is at infinity. + * + * The special case of either point being the point at infinity (Z1 or Z2 + * is zero), is handled separately later on in this function, so we avoid + * jumping to point_double here in those special cases. + * + * When both points are inverse of each other, we know that the affine + * x-coordinates are equal, and the y-coordinates have different sign. + * Therefore since U1 = U2, we know H = 0, and therefore Z3 = H*Z1*Z2 + * will equal 0, thus the result is infinity, if we simply let this + * function continue normally. + * + * We use bitwise operations to avoid potential side-channels introduced by + * the short-circuiting behaviour of boolean operators. */ - if (is_equal(U1, U2) && !in1infty && !in2infty) { - if (is_equal(S1, S2)) { - ecp_nistz256_point_double(r, a); - return; - } else { - memset(r, 0, sizeof(*r)); - return; - } + if (is_equal(U1, U2) & ~in1infty & ~in2infty & is_equal(S1, S2)) { + /* + * This is obviously not constant-time but it should never happen during + * single point multiplication, so there is no timing leak for ECDH or + * ECDSA signing. + */ + ecp_nistz256_point_double(r, a); + return; } ecp_nistz256_sqr_mont(Rsqr, R); /* R^2 */ diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index eace1a88..d141fe7b 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -854,6 +854,7 @@ static const EVP_PKEY_METHOD ed448_pkey_meth = { #ifdef S390X_EC_ASM # include "s390x_arch.h" +# include "internal/constant_time.h" static void s390x_x25519_mod_p(unsigned char u[32]) { @@ -867,16 +868,16 @@ static void s390x_x25519_mod_p(unsigned char u[32]) u_red[31] = (unsigned char)c; c >>= 8; - for (i = 30; c > 0 && i >= 0; i--) { + for (i = 30; i >= 0; i--) { c += (unsigned int)u_red[i]; u_red[i] = (unsigned char)c; c >>= 8; } - if (u_red[0] & 0x80) { - u_red[0] &= 0x7f; - memcpy(u, u_red, sizeof(u_red)); - } + c = (u_red[0] & 0x80) >> 7; + u_red[0] &= 0x7f; + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); } static void s390x_x448_mod_p(unsigned char u[56]) @@ -901,16 +902,14 @@ static void s390x_x448_mod_p(unsigned char u[56]) u_red[27] = (unsigned char)c; c >>= 8; - for (i = 26; c > 0 && i >= 0; i--) { + for (i = 26; i >= 0; i--) { c += (unsigned int)u_red[i]; u_red[i] = (unsigned char)c; c >>= 8; } - if (u_red[0] & 0x80) { - u_red[0] &= 0x7f; - memcpy(u, u_red, sizeof(u_red)); - } + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); } static int s390x_x25519_mul(unsigned char u_dst[32], @@ -966,7 +965,7 @@ static int s390x_x448_mul(unsigned char u_dst[56], memcpy(param.x448.d_src, d_src, 56); s390x_flip_endian64(param.x448.u_src, param.x448.u_src); - s390x_x448_mod_p(param.x448.u_src); + s390x_x448_mod_p(param.x448.u_src + 8); s390x_flip_endian64(param.x448.d_src, param.x448.d_src); param.x448.d_src[63] &= 252; diff --git a/crypto/engine/eng_all.c b/crypto/engine/eng_all.c index 0c5e4bdf..2f83b2ec 100644 --- a/crypto/engine/eng_all.c +++ b/crypto/engine/eng_all.c @@ -15,9 +15,10 @@ void ENGINE_load_builtin_engines(void) OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); } -#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) \ - && !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) void ENGINE_setup_bsd_cryptodev(void) { } +# endif #endif diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index b5c08783..704268ad 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -8,6 +8,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include "internal/cryptlib.h" diff --git a/crypto/engine/tb_asnmth.c b/crypto/engine/tb_asnmth.c index 5e356312..6289c225 100644 --- a/crypto/engine/tb_asnmth.c +++ b/crypto/engine/tb_asnmth.c @@ -147,7 +147,8 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); for (i = 0; i < nidcount; i++) { e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); - if (((int)strlen(ameth->pem_str) == len) + if (ameth != NULL + && ((int)strlen(ameth->pem_str) == len) && strncasecmp(ameth->pem_str, str, len) == 0) return ameth; } diff --git a/crypto/err/err.c b/crypto/err/err.c index b636473b..e77cfe83 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -70,10 +70,12 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, {ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"}, {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"}, + {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, 0), "STORE routines"}, {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"}, {ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"}, {ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"}, + {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"}, {0, NULL}, }; @@ -110,6 +112,8 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_DISABLED, "called a function that was disabled at compile-time"}, {ERR_R_INIT_FAIL, "init fail"}, {ERR_R_OPERATION_FAIL, "operation fail"}, + {ERR_R_INVALID_PROVIDER_FUNCTIONS, "invalid provider functions"}, + {ERR_R_INTERRUPTED_OR_CANCELLED, "interrupted or cancelled"}, {0, NULL}, }; @@ -407,7 +411,7 @@ unsigned long ERR_get_error_all(const char **file, int *line, return get_error_values(EV_POP, file, line, func, data, flags); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags) { @@ -442,7 +446,7 @@ unsigned long ERR_peek_error_all(const char **file, int *line, return get_error_values(EV_PEEK, file, line, func, data, flags); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_peek_error_line_data(const char **file, int *line, const char **data, int *flags) { @@ -477,7 +481,7 @@ unsigned long ERR_peek_last_error_all(const char **file, int *line, return get_error_values(EV_PEEK_LAST, file, line, func, data, flags); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_peek_last_error_line_data(const char **file, int *line, const char **data, int *flags) { @@ -621,7 +625,7 @@ const char *ERR_lib_error_string(unsigned long e) return ((p == NULL) ? NULL : p->string); } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 const char *ERR_func_error_string(unsigned long e) { return NULL; @@ -659,13 +663,13 @@ static void err_delete_thread_state(void *arg) ERR_STATE_free(state); } -#if !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 void ERR_remove_thread_state(void *dummy) { } #endif -#if !OPENSSL_API_1_0_0 +#ifndef OPENSSL_NO_DEPRECATED_1_0_0 void ERR_remove_state(unsigned long pid) { } @@ -716,7 +720,7 @@ ERR_STATE *err_get_state_int(void) return state; } -#if !OPENSSL_API_3 +#ifndef OPENSSL_NO_DEPRECATED_3_0 ERR_STATE *ERR_get_state(void) { return err_get_state_int(); diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index 27e987e0..e0184b07 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -36,7 +36,8 @@ void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), data = ""; hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); BIO_snprintf(buf, sizeof(buf), "%s:error:%s:%s:%s:%s:%d:%s\n", - hex, lib, func, reason, file, line, data); + hex == NULL ? "" : hex, lib, func, reason, file, + line, data); OPENSSL_free(hex); if (cb(buf, strlen(buf), u) <= 0) break; /* abort outputting the error report */ diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 65633717..485c0c89 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -34,12 +34,13 @@ L CRMF include/openssl/crmf.h crypto/crmf/crmf_err.c L CMP include/openssl/cmp.h crypto/cmp/cmp_err.c L CT include/openssl/ct.h crypto/ct/ct_err.c L ASYNC include/openssl/async.h crypto/async/async_err.c -L KDF include/openssl/kdf.h crypto/kdf/kdf_err.c +L KDF NONE crypto/kdf/kdf_err.c L SM2 include/crypto/sm2.h crypto/sm2/sm2_err.c L OSSL_STORE include/openssl/store.h crypto/store/store_err.c L ESS include/openssl/ess.h crypto/ess/ess_err.c L PROP include/internal/property.h crypto/property/property_err.c L PROV providers/common/include/prov/providercommon.h providers/common/provider_err.c +L OSSL_SERIALIZER include/openssl/serializer.h crypto/serializer/serializer_err.c # additional header files to be scanned for function names L NONE include/openssl/x509_vfy.h NONE diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 004bc7f2..de8c8cbe 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2020 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 @@ -1150,6 +1150,8 @@ RAND_F_RAND_POOL_ATTACH:124:rand_pool_attach RAND_F_RAND_POOL_BYTES_NEEDED:115:rand_pool_bytes_needed RAND_F_RAND_POOL_GROW:127: RAND_F_RAND_POOL_NEW:116:rand_pool_new +RAND_F_RAND_PRIV_BYTES_EX:128: +RAND_F_RAND_PSEUDO_BYTES:129: RAND_F_RAND_WRITE_FILE:112:RAND_write_file RSA_F_CHECK_PADDING_MD:140:check_padding_md RSA_F_ENCODE_PKCS1:146:encode_pkcs1 @@ -1822,6 +1824,7 @@ X509V3_F_X509_PURPOSE_SET:141:X509_PURPOSE_set X509_F_ADD_CERT_DIR:100:add_cert_dir X509_F_BUILD_CHAIN:106:build_chain X509_F_BY_FILE_CTRL:101:by_file_ctrl +X509_F_CACHE_OBJECTS:163:cache_objects X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints X509_F_CHECK_POLICY:145:check_policy X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2 @@ -2063,10 +2066,43 @@ BN_R_PRIVATE_KEY_TOO_LARGE:117:private key too large BN_R_P_IS_NOT_PRIME:112:p is not prime BN_R_TOO_MANY_ITERATIONS:113:too many iterations BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables +CMP_R_BAD_REQUEST_ID:108:bad request id +CMP_R_CERTID_NOT_FOUND:109:certid not found +CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found +CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found +CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match +CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection +CMP_R_ERROR_CREATING_CERTCONF:116:error creating certconf +CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep +CMP_R_ERROR_CREATING_ERROR:118:error creating error +CMP_R_ERROR_CREATING_GENM:119:error creating genm +CMP_R_ERROR_CREATING_GENP:120:error creating genp +CMP_R_ERROR_CREATING_P10CR:121:error creating p10cr +CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf +CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep +CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq +CMP_R_ERROR_CREATING_RP:125:error creating rp +CMP_R_ERROR_CREATING_RR:126:error creating rr +CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus +CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message +CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash +CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random +CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range CMP_R_INVALID_ARGS:100:invalid args +CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\ + missing key input for creating protection +CMP_R_MISSING_PRIVATE_KEY:131:missing private key +CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources CMP_R_NO_STDIO:194:no stdio CMP_R_NULL_ARGUMENT:103:null argument +CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found +CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody +CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id +CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type +CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm +CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type +CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid CMS_R_ADD_SIGNER_ERROR:99:add signer error CMS_R_ATTRIBUTE_ERROR:161:attribute error CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present @@ -2159,7 +2195,10 @@ COMP_R_ZLIB_DEFLATE_ERROR:99:zlib deflate error COMP_R_ZLIB_INFLATE_ERROR:100:zlib inflate error COMP_R_ZLIB_NOT_SUPPORTED:101:zlib not supported CONF_R_ERROR_LOADING_DSO:110:error loading dso +CONF_R_INVALID_PRAGMA:122:invalid pragma CONF_R_LIST_CANNOT_BE_NULL:115:list cannot be null +CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION:123:\ + mandatory braces in variable expansion CONF_R_MISSING_CLOSE_SQUARE_BRACKET:100:missing close square bracket CONF_R_MISSING_EQUAL_SIGN:101:missing equal sign CONF_R_MISSING_INIT_FUNCTION:112:missing init function @@ -2199,6 +2238,8 @@ CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\ unsupported method for creating popo CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted +CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name +CRYPTO_R_CONFLICTING_NAMES:118:conflicting names CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space @@ -2541,6 +2582,7 @@ OCSP_R_STATUS_TOO_OLD:127:status too old OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest OCSP_R_UNKNOWN_NID:120:unknown nid OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type +OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac @@ -2665,7 +2707,7 @@ PROP_R_NOT_AN_HEXADECIMAL_DIGIT:102:not an hexadecimal digit PROP_R_NOT_AN_IDENTIFIER:103:not an identifier PROP_R_NOT_AN_OCTAL_DIGIT:104:not an octal digit PROP_R_NOT_A_DECIMAL_DIGIT:105:not a decimal digit -PROP_R_NO_MATCHING_STRING_DELIMETER:106:no matching string delimeter +PROP_R_NO_MATCHING_STRING_DELIMITER:106:no matching string delimiter PROP_R_NO_VALUE:107:no value PROP_R_PARSE_FAILED:108:parse failed PROP_R_STRING_TOO_LONG:109:string too long @@ -2674,19 +2716,24 @@ PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed PROV_R_BAD_DECRYPT:100:bad decrypt PROV_R_BAD_ENCODING:141:bad encoding PROV_R_BAD_LENGTH:142:bad length +PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version +PROV_R_BN_ERROR:160:bn error PROV_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length PROV_R_INVALID_AAD:108:invalid aad +PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length PROV_R_INVALID_DATA:115:invalid data PROV_R_INVALID_DIGEST:122:invalid digest PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count PROV_R_INVALID_IVLEN:116:invalid ivlen PROV_R_INVALID_IV_LENGTH:109:invalid iv length +PROV_R_INVALID_KEY:158:invalid key PROV_R_INVALID_KEYLEN:117:invalid keylen PROV_R_INVALID_KEY_LEN:124:invalid key len PROV_R_INVALID_KEY_LENGTH:105:invalid key length @@ -2698,6 +2745,8 @@ PROV_R_INVALID_SEED_LENGTH:154:invalid seed length PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAGLEN:118:invalid taglen PROV_R_MISSING_CEK_ALG:144:missing cek alg +PROV_R_MISSING_CIPHER:155:missing cipher +PROV_R_MISSING_CONSTANT:156:missing constant PROV_R_MISSING_KEY:128:missing key PROV_R_MISSING_MAC:150:missing mac PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest @@ -2712,6 +2761,7 @@ PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_READ_KEY:159:read key PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1 diff --git a/crypto/err/openssl.txt.old b/crypto/err/openssl.txt.old index 46d2eaa2..70dca149 100644 --- a/crypto/err/openssl.txt.old +++ b/crypto/err/openssl.txt.old @@ -1150,6 +1150,8 @@ RAND_F_RAND_POOL_ATTACH:124:rand_pool_attach RAND_F_RAND_POOL_BYTES_NEEDED:115:rand_pool_bytes_needed RAND_F_RAND_POOL_GROW:127: RAND_F_RAND_POOL_NEW:116:rand_pool_new +RAND_F_RAND_PRIV_BYTES_EX:128: +RAND_F_RAND_PSEUDO_BYTES:129: RAND_F_RAND_WRITE_FILE:112:RAND_write_file RSA_F_CHECK_PADDING_MD:140:check_padding_md RSA_F_ENCODE_PKCS1:146:encode_pkcs1 @@ -1828,6 +1830,7 @@ X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2 X509_F_DANE_I2D:107:dane_i2d X509_F_DIR_CTRL:102:dir_ctrl X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject +X509_F_CACHE_OBJECTS:163:cache_objects X509_F_I2D_X509_AUX:151:i2d_X509_AUX X509_F_LOOKUP_CERTS_SK:152:lookup_certs_sk X509_F_NETSCAPE_SPKI_B64_DECODE:129:NETSCAPE_SPKI_b64_decode @@ -2063,10 +2066,43 @@ BN_R_PRIVATE_KEY_TOO_LARGE:117:private key too large BN_R_P_IS_NOT_PRIME:112:p is not prime BN_R_TOO_MANY_ITERATIONS:113:too many iterations BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables +CMP_R_BAD_REQUEST_ID:108:bad request id +CMP_R_CERTID_NOT_FOUND:109:certid not found +CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found +CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found +CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match +CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection +CMP_R_ERROR_CREATING_CERTCONF:116:error creating certconf +CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep +CMP_R_ERROR_CREATING_ERROR:118:error creating error +CMP_R_ERROR_CREATING_GENM:119:error creating genm +CMP_R_ERROR_CREATING_GENP:120:error creating genp +CMP_R_ERROR_CREATING_P10CR:121:error creating p10cr +CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf +CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep +CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq +CMP_R_ERROR_CREATING_RP:125:error creating rp +CMP_R_ERROR_CREATING_RR:126:error creating rr +CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus +CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message +CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash +CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random +CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range CMP_R_INVALID_ARGS:100:invalid args +CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\ + missing key input for creating protection +CMP_R_MISSING_PRIVATE_KEY:131:missing private key +CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources CMP_R_NO_STDIO:194:no stdio CMP_R_NULL_ARGUMENT:103:null argument +CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found +CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody +CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id +CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type +CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm +CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type +CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid CMS_R_ADD_SIGNER_ERROR:99:add signer error CMS_R_ATTRIBUTE_ERROR:161:attribute error CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present @@ -2159,7 +2195,10 @@ COMP_R_ZLIB_DEFLATE_ERROR:99:zlib deflate error COMP_R_ZLIB_INFLATE_ERROR:100:zlib inflate error COMP_R_ZLIB_NOT_SUPPORTED:101:zlib not supported CONF_R_ERROR_LOADING_DSO:110:error loading dso +CONF_R_INVALID_PRAGMA:122:invalid pragma CONF_R_LIST_CANNOT_BE_NULL:115:list cannot be null +CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION:123:\ + mandatory braces in variable expansion CONF_R_MISSING_CLOSE_SQUARE_BRACKET:100:missing close square bracket CONF_R_MISSING_EQUAL_SIGN:101:missing equal sign CONF_R_MISSING_INIT_FUNCTION:112:missing init function @@ -2199,6 +2238,8 @@ CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\ unsupported method for creating popo CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted +CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name +CRYPTO_R_CONFLICTING_NAMES:118:conflicting names CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space @@ -2541,6 +2582,7 @@ OCSP_R_STATUS_TOO_OLD:127:status too old OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest OCSP_R_UNKNOWN_NID:120:unknown nid OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type +OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac @@ -2665,7 +2707,7 @@ PROP_R_NOT_AN_HEXADECIMAL_DIGIT:102:not an hexadecimal digit PROP_R_NOT_AN_IDENTIFIER:103:not an identifier PROP_R_NOT_AN_OCTAL_DIGIT:104:not an octal digit PROP_R_NOT_A_DECIMAL_DIGIT:105:not a decimal digit -PROP_R_NO_MATCHING_STRING_DELIMETER:106:no matching string delimeter +PROP_R_NO_MATCHING_STRING_DELIMITER:106:no matching string delimiter PROP_R_NO_VALUE:107:no value PROP_R_PARSE_FAILED:108:parse failed PROP_R_STRING_TOO_LONG:109:string too long @@ -2674,19 +2716,24 @@ PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed PROV_R_BAD_DECRYPT:100:bad decrypt PROV_R_BAD_ENCODING:141:bad encoding PROV_R_BAD_LENGTH:142:bad length +PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version +PROV_R_BN_ERROR:160:bn error PROV_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length PROV_R_INVALID_AAD:108:invalid aad +PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length PROV_R_INVALID_DATA:115:invalid data PROV_R_INVALID_DIGEST:122:invalid digest PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count PROV_R_INVALID_IVLEN:116:invalid ivlen PROV_R_INVALID_IV_LENGTH:109:invalid iv length +PROV_R_INVALID_KEY:158:invalid key PROV_R_INVALID_KEYLEN:117:invalid keylen PROV_R_INVALID_KEY_LEN:124:invalid key len PROV_R_INVALID_KEY_LENGTH:105:invalid key length @@ -2698,6 +2745,8 @@ PROV_R_INVALID_SEED_LENGTH:154:invalid seed length PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAGLEN:118:invalid taglen PROV_R_MISSING_CEK_ALG:144:missing cek alg +PROV_R_MISSING_CIPHER:155:missing cipher +PROV_R_MISSING_CONSTANT:156:missing constant PROV_R_MISSING_KEY:128:missing key PROV_R_MISSING_MAC:150:missing mac PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest @@ -2712,6 +2761,7 @@ PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_READ_KEY:159:read key PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1 diff --git a/crypto/evp/build.info b/crypto/evp/build.info index f2c798b7..71e0ebaf 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -1,23 +1,22 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ - m_sigver.c + m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c + SOURCE[../../libcrypto]=$COMMON\ encode.c evp_key.c evp_cnf.c \ e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\ e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \ - e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \ - m_null.c m_wp.c m_ripemd.c \ - p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \ + e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c m_null.c \ + p_open.c p_seal.c p_sign.c p_verify.c p_enc.c p_dec.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_allc.c c_alld.c bio_ok.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ - pkey_kdf.c \ - e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c \ + pkey_kdf.c e_old.c pmeth_fn.c\ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ pkey_mac.c exchange.c \ - legacy_sha.c legacy_md5_sha1.c + legacy_sha.c IF[{- !$disabled{md2} -}] SOURCE[../../libcrypto]=legacy_md2.c @@ -26,11 +25,20 @@ IF[{- !$disabled{md4} -}] SOURCE[../../libcrypto]=legacy_md4.c ENDIF IF[{- !$disabled{md5} -}] - SOURCE[../../libcrypto]=legacy_md5.c + SOURCE[../../libcrypto]=legacy_md5.c legacy_md5_sha1.c ENDIF IF[{- !$disabled{mdc2} -}] SOURCE[../../libcrypto]=legacy_mdc2.c ENDIF +IF[{- !$disabled{blake2} -}] + SOURCE[../../libcrypto]=legacy_blake2.c +ENDIF +IF[{- !$disabled{whirlpool} -}] + SOURCE[../../libcrypto]=legacy_wp.c +ENDIF +IF[{- !$disabled{rmd160} -}] + SOURCE[../../libcrypto]=legacy_ripemd.c +ENDIF SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 11c334cc..adde3e13 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -165,7 +165,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) if (type->prov == NULL) { #ifdef FIPS_MODE - /* We only do explict fetches inside the FIPS module */ + /* We only do explicit fetches inside the FIPS module */ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); return 0; #else @@ -303,7 +303,9 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) return 0; } - if (ctx->digest == NULL || ctx->digest->prov == NULL) + if (ctx->digest == NULL + || ctx->digest->prov == NULL + || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) goto legacy; if (ctx->digest->dupdate == NULL) { @@ -422,7 +424,8 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) return 0; } - if (in->digest->prov == NULL) + if (in->digest->prov == NULL + || (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) goto legacy; if (in->digest->dupctx == NULL) { @@ -730,12 +733,19 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid) { int nid; int *legacy_nid = vlegacy_nid; + /* + * We use lowest level function to get the associated method, because + * higher level functions such as EVP_get_digestbyname() have changed + * to look at providers too. + */ + const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); if (*legacy_nid == -1) /* We found a clash already */ return; - if ((nid = OBJ_sn2nid(name)) == NID_undef - && (nid = OBJ_ln2nid(name)) == NID_undef) + + if (legacy_method == NULL) return; + nid = EVP_MD_nid(legacy_method); if (*legacy_nid != NID_undef && *legacy_nid != nid) { *legacy_nid = -1; return; @@ -746,7 +756,7 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid) static void *evp_md_from_dispatch(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, void *unused) + OSSL_PROVIDER *prov) { EVP_MD *md = NULL; int fncnt = 0; @@ -873,8 +883,7 @@ EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, { EVP_MD *md = evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties, - evp_md_from_dispatch, NULL, evp_md_up_ref, - evp_md_free); + evp_md_from_dispatch, evp_md_up_ref, evp_md_free); return md; } @@ -908,5 +917,5 @@ void EVP_MD_do_all_provided(OPENSSL_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_DIGEST, (void (*)(void *, void *))fn, arg, - evp_md_from_dispatch, NULL, evp_md_free); + evp_md_from_dispatch, evp_md_free); } diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 42c2e5eb..0d5418b0 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * This file uses the low level AES functions (which are deprecated for + * non-internal use) in order to implement the EVP AES ciphers. + */ +#include "internal/deprecated.h" + #include #include #include @@ -20,7 +26,7 @@ #include "internal/cryptlib.h" #include "crypto/modes.h" #include "crypto/siv.h" -#include "crypto/ciphermode_platform.h" +#include "crypto/aes_platform.h" #include "evp_local.h" typedef struct { @@ -130,8 +136,6 @@ static void ctr64_inc(unsigned char *counter) #if defined(AESNI_CAPABLE) # if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -# define AES_gcm_encrypt aesni_gcm_encrypt -# define AES_gcm_decrypt aesni_gcm_decrypt # define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \ gctx->gcm.ghash==gcm_ghash_avx) # undef AES_GCM_ASM2 /* minor size optimization */ @@ -915,7 +919,7 @@ typedef struct { } icv; unsigned char k[32]; } kmac_param; - /* KMAC-AES paramater block - end */ + /* KMAC-AES parameter block - end */ union { unsigned long long g[2]; @@ -3228,7 +3232,7 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; /* - * Impose a limit of 2^20 blocks per data unit as specifed by + * Impose a limit of 2^20 blocks per data unit as specified by * IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007 * indicated that this was a SHOULD NOT rather than a MUST NOT. * NIST SP 800-38E mandates the same limit. diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c index 6b9362a1..35b16463 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -7,6 +7,13 @@ * https://www.openssl.org/source/license.html */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/evp/e_aes_cbc_hmac_sha256.c index 771ef1d6..27cc59bd 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -7,6 +7,13 @@ * https://www.openssl.org/source/license.html */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index a8c4fc32..9720fcb7 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -695,8 +695,6 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!cctx->iv_set) return -1; - if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set) - return -1; if (!out) { if (!in) { if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), @@ -711,6 +709,11 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, CRYPTO_ccm128_aad(ccm, in, len); return len; } + + /* The tag must be set before actually decrypting data */ + if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set) + return -1; + /* If not set length yet do it */ if (!cctx->len_set) { if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), diff --git a/crypto/evp/e_bf.c b/crypto/evp/e_bf.c index 0ac49fe1..57976b8b 100644 --- a/crypto/evp/e_bf.c +++ b/crypto/evp/e_bf.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #ifndef OPENSSL_NO_BF diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c index 50febca9..b0638219 100644 --- a/crypto/evp/e_camellia.c +++ b/crypto/evp/e_camellia.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #ifdef OPENSSL_NO_CAMELLIA NON_EMPTY_TRANSLATION_UNIT @@ -19,7 +25,7 @@ NON_EMPTY_TRANSLATION_UNIT # include # include "crypto/evp.h" # include "crypto/modes.h" -# include "crypto/ciphermode_platform.h" +# include "crypto/cmll_platform.h" static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/crypto/evp/e_cast.c b/crypto/evp/e_cast.c index 4b06717b..5703f7fa 100644 --- a/crypto/evp/e_cast.c +++ b/crypto/evp/e_cast.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" diff --git a/crypto/evp/e_old.c b/crypto/evp/e_old.c index 02b16d0f..82e0c128 100644 --- a/crypto/evp/e_old.c +++ b/crypto/evp/e_old.c @@ -8,7 +8,7 @@ */ #include -#if OPENSSL_API_0_9_8 +#ifdef OPENSSL_NO_DEPRECATED_0_9_8 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c index d2201b00..a3c09c86 100644 --- a/crypto/evp/e_rc2.c +++ b/crypto/evp/e_rc2.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" diff --git a/crypto/evp/e_rc4.c b/crypto/evp/e_rc4.c index 092d6cf1..f75e2d71 100644 --- a/crypto/evp/e_rc4.c +++ b/crypto/evp/e_rc4.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" diff --git a/crypto/evp/e_rc4_hmac_md5.c b/crypto/evp/e_rc4_hmac_md5.c index fc519d90..fa838bf4 100644 --- a/crypto/evp/e_rc4_hmac_md5.c +++ b/crypto/evp/e_rc4_hmac_md5.c @@ -7,6 +7,13 @@ * https://www.openssl.org/source/license.html */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + +#include #include #include diff --git a/crypto/evp/e_rc5.c b/crypto/evp/e_rc5.c index 4783cc31..96066e85 100644 --- a/crypto/evp/e_rc5.c +++ b/crypto/evp/e_rc5.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" diff --git a/crypto/evp/e_seed.c b/crypto/evp/e_seed.c index 9a9938de..224003d9 100644 --- a/crypto/evp/e_seed.c +++ b/crypto/evp/e_seed.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #ifdef OPENSSL_NO_SEED NON_EMPTY_TRANSLATION_UNIT diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index efcb7e50..35feec17 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -171,6 +171,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, case NID_aes_256_gcm: case NID_aes_192_gcm: case NID_aes_128_gcm: + case NID_aes_256_siv: + case NID_aes_192_siv: + case NID_aes_128_siv: + case NID_aes_256_cbc_hmac_sha256: + case NID_aes_128_cbc_hmac_sha256: + case NID_aes_256_cbc_hmac_sha1: + case NID_aes_128_cbc_hmac_sha1: case NID_id_aes256_wrap: case NID_id_aes256_wrap_pad: case NID_id_aes192_wrap: @@ -280,6 +287,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, case NID_rc2_ofb64: case NID_chacha20: case NID_chacha20_poly1305: + case NID_rc4_hmac_md5: break; default: goto legacy; @@ -313,7 +321,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, if (cipher->prov == NULL) { #ifdef FIPS_MODE - /* We only do explict fetches inside the FIPS module */ + /* We only do explicit fetches inside the FIPS module */ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); return 0; #else @@ -1022,17 +1030,31 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) { - int ok; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - size_t len = keylen; + if (c->cipher->prov != NULL) { + int ok; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t len = keylen; - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len); - ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params); + if (EVP_CIPHER_CTX_key_length(c) == keylen) + return 1; - if (ok != EVP_CTRL_RET_UNSUPPORTED) - return ok; + /* Check the cipher actually understands this parameter */ + if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher), + OSSL_CIPHER_PARAM_KEYLEN) == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len); + ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params); + + return ok > 0 ? 1 : 0; + } /* TODO(3.0) legacy code follows */ + + /* + * Note there have never been any built-in ciphers that define this flag + * since it was first introduced. + */ if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); if (EVP_CIPHER_CTX_key_length(c) == keylen) @@ -1068,7 +1090,9 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) int set_params = 1; size_t sz = arg; unsigned int i; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + OSSL_PARAM params[4] = { + OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END + }; if (ctx == NULL || ctx->cipher == NULL) { EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); @@ -1111,10 +1135,22 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) return 0; params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz); break; - case EVP_CTRL_GCM_SET_IV_FIXED: - params[0] = - OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, - ptr, sz); + case EVP_CTRL_AEAD_SET_IV_FIXED: + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz); + break; + case EVP_CTRL_GCM_IV_GEN: + set_params = 0; + if (arg < 0) + sz = 0; /* special case that uses the iv length */ + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, ptr, sz); + break; + case EVP_CTRL_GCM_SET_IV_INV: + if (arg < 0) + return 0; + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, ptr, sz); break; case EVP_CTRL_GET_RC5_ROUNDS: set_params = 0; /* Fall thru */ @@ -1124,19 +1160,20 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) i = (unsigned int)arg; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i); break; + case EVP_CTRL_SET_SPEED: + if (arg < 0) + return 0; + i = (unsigned int)arg; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_SPEED, &i); + break; case EVP_CTRL_AEAD_GET_TAG: set_params = 0; /* Fall thru */ case EVP_CTRL_AEAD_SET_TAG: params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, ptr, sz); break; - case EVP_CTRL_AEAD_SET_MAC_KEY: - params[0] = - OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY, - ptr, sz); - break; case EVP_CTRL_AEAD_TLS1_AAD: - /* This one does a set and a get - since it returns a padding size */ + /* This one does a set and a get - since it returns a size */ params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, ptr, sz); @@ -1156,6 +1193,76 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, &sz); break; #endif /* OPENSSL_NO_RC2 */ +#if !defined(OPENSSL_NO_MULTIBLOCK) + case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, &sz); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return 0; + + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, &sz); + params[1] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return 0; + return sz; + case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; + + if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) + return 0; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, (void*)p->inp, p->len); + params[1] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return ret; + /* Retrieve the return values changed by the set */ + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, &sz); + params[1] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + params[2] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return 0; + return sz; + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, p->out, p->len); + + params[1] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, (void*)p->inp, + p->len); + params[2] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return ret; + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, &sz); + params[1] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return 0; + return sz; + } +#endif /* OPENSSL_NO_MULTIBLOCK */ + case EVP_CTRL_AEAD_SET_MAC_KEY: + if (arg < 0) + return -1; + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_MAC_KEY, ptr, sz); + break; } if (set_params) @@ -1335,12 +1442,18 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid) { int nid; int *legacy_nid = vlegacy_nid; + /* + * We use lowest level function to get the associated method, because + * higher level functions such as EVP_get_cipherbyname() have changed + * to look at providers too. + */ + const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); if (*legacy_nid == -1) /* We found a clash already */ return; - if ((nid = OBJ_sn2nid(name)) == NID_undef - && (nid = OBJ_ln2nid(name)) == NID_undef) + if (legacy_method == NULL) return; + nid = EVP_CIPHER_nid(legacy_method); if (*legacy_nid != NID_undef && *legacy_nid != nid) { *legacy_nid = -1; return; @@ -1351,8 +1464,7 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid) static void *evp_cipher_from_dispatch(const int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *unused) + OSSL_PROVIDER *prov) { EVP_CIPHER *cipher = NULL; int fnciphcnt = 0, fnctxcnt = 0; @@ -1492,9 +1604,13 @@ EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, { EVP_CIPHER *cipher = evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties, - evp_cipher_from_dispatch, NULL, evp_cipher_up_ref, + evp_cipher_from_dispatch, evp_cipher_up_ref, evp_cipher_free); + if (cipher != NULL && !evp_cipher_cache_constants(cipher)) { + EVP_CIPHER_free(cipher); + cipher = NULL; + } return cipher; } @@ -1527,5 +1643,5 @@ void EVP_CIPHER_do_all_provided(OPENSSL_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_CIPHER, (void (*)(void *, void *))fn, arg, - evp_cipher_from_dispatch, NULL, evp_cipher_free); + evp_cipher_from_dispatch, evp_cipher_free); } diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 907091fc..5bf825d6 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -22,124 +22,60 @@ #define NAME_SEPARATOR ':' -static void default_method_store_free(void *vstore) +static void evp_method_store_free(void *vstore) { ossl_method_store_free(vstore); } -static void *default_method_store_new(OPENSSL_CTX *ctx) +static void *evp_method_store_new(OPENSSL_CTX *ctx) { return ossl_method_store_new(ctx); } -static const OPENSSL_CTX_METHOD default_method_store_method = { - default_method_store_new, - default_method_store_free, +static const OPENSSL_CTX_METHOD evp_method_store_method = { + evp_method_store_new, + evp_method_store_free, }; /* Data to be passed through ossl_method_construct() */ -struct method_data_st { +struct evp_method_data_st { OPENSSL_CTX *libctx; OSSL_METHOD_CONSTRUCT_METHOD *mcm; - int operation_id; /* For get_method_from_store() */ - int name_id; /* For get_method_from_store() */ - const char *names; /* For get_method_from_store() */ - const char *propquery; /* For get_method_from_store() */ + int operation_id; /* For get_evp_method_from_store() */ + int name_id; /* For get_evp_method_from_store() */ + const char *names; /* For get_evp_method_from_store() */ + const char *propquery; /* For get_evp_method_from_store() */ void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *, - OSSL_PROVIDER *, void *); - void *method_data; + OSSL_PROVIDER *); int (*refcnt_up_method)(void *method); void (*destruct_method)(void *method); }; -static int add_names_to_namemap(OSSL_NAMEMAP *namemap, - const char *names) -{ - const char *p, *q; - size_t l; - int id = 0; - - /* Check that we have a namemap and that there is at least one name */ - if (namemap == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - /* - * Check that no name is an empty string, and that all names have at - * most one numeric identity together. - */ - for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { - int this_id; - - if ((q = strchr(p, NAME_SEPARATOR)) == NULL) - l = strlen(p); /* offset to \0 */ - else - l = q - p; /* offset to the next separator */ - - this_id = ossl_namemap_name2num_n(namemap, p, l); - - if (*p == '\0' || *p == NAME_SEPARATOR) { - ERR_raise(ERR_LIB_EVP, EVP_R_BAD_ALGORITHM_NAME); - return 0; - } - if (id == 0) - id = this_id; - else if (this_id != 0 && this_id != id) { - ERR_raise_data(ERR_LIB_EVP, EVP_R_CONFLICTING_ALGORITHM_NAME, - "\"%.*s\" has an existing different identity %d (from \"%s\")", - l, p, this_id, names); - return 0; - } - } - - /* Now that we have checked, register all names */ - for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { - int this_id; - - if ((q = strchr(p, NAME_SEPARATOR)) == NULL) - l = strlen(p); /* offset to \0 */ - else - l = q - p; /* offset to the next separator */ - - this_id = ossl_namemap_add_n(namemap, id, p, l); - if (id == 0) - id = this_id; - else if (this_id != id) { - ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR, - "Got id %d when expecting %d", this_id, id); - return 0; - } - } - - return id; -} - /* * Generic routines to fetch / create EVP methods with ossl_method_construct() */ -static void *alloc_tmp_method_store(OPENSSL_CTX *ctx) +static void *alloc_tmp_evp_method_store(OPENSSL_CTX *ctx) { return ossl_method_store_new(ctx); } - static void dealloc_tmp_method_store(void *store) + static void dealloc_tmp_evp_method_store(void *store) { if (store != NULL) ossl_method_store_free(store); } -static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx) +static OSSL_METHOD_STORE *get_evp_method_store(OPENSSL_CTX *libctx) { - return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX, - &default_method_store_method); + return openssl_ctx_get_data(libctx, OPENSSL_CTX_EVP_METHOD_STORE_INDEX, + &evp_method_store_method); } /* - * To identity the method in the method store, we mix the name identity - * with the operation identity, with the assumption that we don't have - * more than 2^24 names or more than 2^8 operation types. + * To identity the method in the EVP method store, we mix the name identity + * with the operation identity, with the assumption that we don't have more + * than 2^24 names or more than 2^8 operation types. * * The resulting identity is a 32-bit integer, composed like this: * @@ -147,7 +83,7 @@ static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx) * | name identity | op id | * +------------------------+--------+ */ -static uint32_t method_id(unsigned int operation_id, int name_id) +static uint32_t evp_method_id(unsigned int operation_id, int name_id) { if (!ossl_assert(name_id < (1 << 24) || operation_id < (1 << 8)) || !ossl_assert(name_id > 0 && operation_id > 0)) @@ -155,18 +91,18 @@ static uint32_t method_id(unsigned int operation_id, int name_id) return ((name_id << 8) & 0xFFFFFF00) | (operation_id & 0x000000FF); } -static void *get_method_from_store(OPENSSL_CTX *libctx, void *store, - void *data) +static void *get_evp_method_from_store(OPENSSL_CTX *libctx, void *store, + void *data) { - struct method_data_st *methdata = data; + struct evp_method_data_st *methdata = data; void *method = NULL; int name_id; uint32_t meth_id; /* - * get_method_from_store() is only called to try and get the method - * that evp_generic_fetch() is asking for, and the operation id as - * well as the name or name id are passed via methdata. + * get_evp_method_from_store() is only called to try and get the method + * that evp_generic_fetch() is asking for, and the operation id as well + * as the name or name id are passed via methdata. */ if ((name_id = methdata->name_id) == 0) { OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); @@ -180,40 +116,35 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store, } if (name_id == 0 - || (meth_id = method_id(methdata->operation_id, name_id)) == 0) + || (meth_id = evp_method_id(methdata->operation_id, name_id)) == 0) return NULL; if (store == NULL - && (store = get_default_method_store(libctx)) == NULL) + && (store = get_evp_method_store(libctx)) == NULL) return NULL; - (void)ossl_method_store_fetch(store, meth_id, methdata->propquery, - &method); - - if (method != NULL - && !methdata->refcnt_up_method(method)) { - method = NULL; - } + if (!ossl_method_store_fetch(store, meth_id, methdata->propquery, + &method)) + return NULL; return method; } -static int put_method_in_store(OPENSSL_CTX *libctx, void *store, - void *method, const OSSL_PROVIDER *prov, - int operation_id, const char *names, - const char *propdef, void *data) +static int put_evp_method_in_store(OPENSSL_CTX *libctx, void *store, + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *names, + const char *propdef, void *data) { - struct method_data_st *methdata = data; + struct evp_method_data_st *methdata = data; OSSL_NAMEMAP *namemap; int name_id; uint32_t meth_id; size_t l = 0; /* - * put_method_in_store() is only called with a method that was - * successfully created by construct_method() below, which means - * that all the names should already be stored in the namemap with - * the same numeric identity, so just use the first to get that - * identity. + * put_evp_method_in_store() is only called with an EVP method that was + * successfully created by construct_method() below, which means that + * all the names should already be stored in the namemap with the same + * numeric identity, so just use the first to get that identity. */ if (names != NULL) { const char *q = strchr(names, NAME_SEPARATOR); @@ -223,11 +154,11 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store, if ((namemap = ossl_namemap_stored(libctx)) == NULL || (name_id = ossl_namemap_name2num_n(namemap, names, l)) == 0 - || (meth_id = method_id(operation_id, name_id)) == 0) + || (meth_id = evp_method_id(operation_id, name_id)) == 0) return 0; if (store == NULL - && (store = get_default_method_store(libctx)) == NULL) + && (store = get_evp_method_store(libctx)) == NULL) return 0; return ossl_method_store_add(store, prov, meth_id, propdef, method, @@ -239,45 +170,46 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store, * The core fetching functionality passes the name of the implementation. * This function is responsible to getting an identity number for it. */ -static void *construct_method(const char *names, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, void *data) +static void *construct_evp_method(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *data) { /* - * This function is only called if get_method_from_store() returned + * This function is only called if get_evp_method_from_store() returned * NULL, so it's safe to say that of all the spots to create a new * namemap entry, this is it. Should the name already exist there, we - * know that ossl_namemap_add() will return its corresponding number. + * know that ossl_namemap_add_name() will return its corresponding + * number. */ - struct method_data_st *methdata = data; + struct evp_method_data_st *methdata = data; OPENSSL_CTX *libctx = ossl_provider_library_context(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - int name_id = add_names_to_namemap(namemap, names); + const char *names = algodef->algorithm_names; + int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); if (name_id == 0) return NULL; - return methdata->method_from_dispatch(name_id, fns, prov, - methdata->method_data); + return methdata->method_from_dispatch(name_id, algodef->implementation, + prov); } -static void destruct_method(void *method, void *data) +static void destruct_evp_method(void *method, void *data) { - struct method_data_st *methdata = data; + struct evp_method_data_st *methdata = data; methdata->destruct_method(method); } -static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id, - int name_id, const char *name, - const char *properties, - void *(*new_method)(int name_id, - const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, - int (*up_ref_method)(void *), - void (*free_method)(void *)) +static void * +inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, + int name_id, const char *name, + const char *properties, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) { - OSSL_METHOD_STORE *store = get_default_method_store(libctx); + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); uint32_t meth_id = 0; void *method = NULL; @@ -304,26 +236,26 @@ static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id, name_id = ossl_namemap_name2num(namemap, name); /* - * If we have a name id, calculate a method id with method_id(). + * If we have a name id, calculate a method id with evp_method_id(). * - * method_id returns 0 if we have too many operations (more than - * about 2^8) or too many names (more than about 2^24). In that - * case, we can't create any new method. + * evp_method_id returns 0 if we have too many operations (more than + * about 2^8) or too many names (more than about 2^24). In that case, + * we can't create any new method. */ - if (name_id != 0 && (meth_id = method_id(operation_id, name_id)) == 0) + if (name_id != 0 && (meth_id = evp_method_id(operation_id, name_id)) == 0) return NULL; if (meth_id == 0 || !ossl_method_store_cache_get(store, meth_id, properties, &method)) { OSSL_METHOD_CONSTRUCT_METHOD mcm = { - alloc_tmp_method_store, - dealloc_tmp_method_store, - get_method_from_store, - put_method_in_store, - construct_method, - destruct_method + alloc_tmp_evp_method_store, + dealloc_tmp_evp_method_store, + get_evp_method_from_store, + put_evp_method_in_store, + construct_evp_method, + destruct_evp_method }; - struct method_data_st mcmdata; + struct evp_method_data_st mcmdata; mcmdata.mcm = &mcm; mcmdata.libctx = libctx; @@ -332,26 +264,23 @@ static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id, mcmdata.names = name; mcmdata.propquery = properties; mcmdata.method_from_dispatch = new_method; - mcmdata.destruct_method = free_method; mcmdata.refcnt_up_method = up_ref_method; mcmdata.destruct_method = free_method; - mcmdata.method_data = method_data; if ((method = ossl_method_construct(libctx, operation_id, 0 /* !force_cache */, &mcm, &mcmdata)) != NULL) { /* * If construction did create a method for us, we know that - * there is a correct name_id and methodid, since those have - * already been calculated in get_method_from_store() and - * put_method_in_store() above. + * there is a correct name_id and meth_id, since those have + * already been calculated in get_evp_method_from_store() and + * put_evp_method_in_store() above. */ if (name_id == 0) name_id = ossl_namemap_name2num(namemap, name); - meth_id = method_id(operation_id, name_id); - ossl_method_store_cache_set(store, meth_id, properties, method); + meth_id = evp_method_id(operation_id, name_id); + ossl_method_store_cache_set(store, meth_id, properties, method, + up_ref_method, free_method); } - } else { - up_ref_method(method); } return method; @@ -361,16 +290,13 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, const char *name, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)) { - return inner_generic_fetch(libctx, - operation_id, 0, name, properties, - new_method, method_data, - up_ref_method, free_method); + return inner_evp_generic_fetch(libctx, + operation_id, 0, name, properties, + new_method, up_ref_method, free_method); } /* @@ -384,21 +310,18 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id, int name_id, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)) { - return inner_generic_fetch(libctx, - operation_id, name_id, NULL, properties, - new_method, method_data, - up_ref_method, free_method); + return inner_evp_generic_fetch(libctx, + operation_id, name_id, NULL, properties, + new_method, up_ref_method, free_method); } int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) { - OSSL_METHOD_STORE *store = get_default_method_store(libctx); + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); if (store != NULL) return ossl_method_store_set_global_properties(store, propq); @@ -410,8 +333,7 @@ struct do_all_data_st { void (*user_fn)(void *method, void *arg); void *user_arg; void *(*new_method)(const int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, void *method_data); - void *method_data; + OSSL_PROVIDER *prov); void (*free_method)(void *); }; @@ -421,12 +343,12 @@ static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, struct do_all_data_st *data = vdata; OPENSSL_CTX *libctx = ossl_provider_library_context(provider); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - int name_id = add_names_to_namemap(namemap, algo->algorithm_names); + int name_id = ossl_namemap_add_names(namemap, 0, algo->algorithm_names, + NAME_SEPARATOR); void *method = NULL; if (name_id != 0) - method = data->new_method(name_id, algo->implementation, provider, - data->method_data); + method = data->new_method(name_id, algo->implementation, provider); if (method != NULL) { data->user_fn(method, data->user_arg); @@ -439,15 +361,12 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, void *user_arg, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), void (*free_method)(void *)) { struct do_all_data_st data; data.new_method = new_method; - data.method_data = method_data; data.free_method = free_method; data.user_fn = user_fn; data.user_arg = user_arg; @@ -462,11 +381,17 @@ const char *evp_first_name(OSSL_PROVIDER *prov, int name_id) return ossl_namemap_num2name(namemap, name_id, 0); } -int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name) +int evp_is_a(OSSL_PROVIDER *prov, int number, + const char *legacy_name, const char *name) { + /* + * For a |prov| that is NULL, the library context will be NULL + */ OPENSSL_CTX *libctx = ossl_provider_library_context(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + if (prov == NULL) + number = ossl_namemap_name2num(namemap, legacy_name); return ossl_namemap_name2num(namemap, name) == number; } diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index c25c40dd..2b512671 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -272,16 +272,38 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) } } -int EVP_CIPHER_block_size(const EVP_CIPHER *cipher) +int evp_cipher_cache_constants(EVP_CIPHER *cipher) { int ok; - size_t v = cipher->block_size; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t ivlen = 0; + size_t blksz = 0; + size_t keylen = 0; + unsigned int mode = 0; + unsigned long flags = 0; + OSSL_PARAM params[6]; - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &v); + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &blksz); + params[1] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &ivlen); + params[2] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &keylen); + params[3] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &mode); + params[4] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &flags); + params[5] = OSSL_PARAM_construct_end(); ok = evp_do_ciph_getparams(cipher, params); + if (ok) { + /* Provided implementations may have a custom cipher_cipher */ + if (cipher->prov != NULL && cipher->ccipher != NULL) + flags |= EVP_CIPH_FLAG_CUSTOM_CIPHER; + cipher->block_size = blksz; + cipher->iv_len = ivlen; + cipher->key_len = keylen; + cipher->flags = flags | mode; + } + return ok; +} - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher) +{ + return cipher->block_size; } int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) @@ -340,18 +362,7 @@ int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) { - int ok; - unsigned long v = cipher->flags; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &v); - ok = evp_do_ciph_getparams(cipher, params); - - /* Provided implementations may have a custom cipher_cipher */ - if (cipher->prov != NULL && cipher->ccipher != NULL) - v |= EVP_CIPH_FLAG_CUSTOM_CIPHER; - - return ok != 0 ? v : 0; + return cipher->flags; } void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) @@ -381,14 +392,7 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { - int ok; - size_t v = cipher->iv_len; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; + return cipher->iv_len; } int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) @@ -501,14 +505,7 @@ int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num) int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { - int ok; - size_t v = cipher->key_len; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; + return cipher->key_len; } int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) @@ -535,14 +532,9 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name) { -#ifndef FIPS_MODE - if (cipher->prov == NULL) { - int nid = EVP_CIPHER_nid(cipher); - - return nid == OBJ_sn2nid(name) || nid == OBJ_ln2nid(name); - } -#endif - return evp_is_a(cipher->prov, cipher->name_id, name); + if (cipher->prov != NULL) + return evp_is_a(cipher->prov, cipher->name_id, NULL, name); + return evp_is_a(NULL, 0, EVP_CIPHER_name(cipher), name); } int EVP_CIPHER_number(const EVP_CIPHER *cipher) @@ -576,19 +568,14 @@ const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher) int EVP_CIPHER_mode(const EVP_CIPHER *cipher) { - int ok; - unsigned int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : 0; + return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE; } int EVP_MD_is_a(const EVP_MD *md, const char *name) { - return evp_is_a(md->prov, md->name_id, name); + if (md->prov != NULL) + return evp_is_a(md->prov, md->name_id, NULL, name); + return evp_is_a(NULL, 0, EVP_MD_name(md), name); } int EVP_MD_number(const EVP_MD *md) diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 9b208190..0feace2a 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -80,6 +80,8 @@ struct evp_keymgmt_st { OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams; OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types; OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types; + OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params; + OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params; /* Key routines */ OSSL_OP_keymgmt_importkey_fn *importkey; @@ -89,6 +91,10 @@ struct evp_keymgmt_st { OSSL_OP_keymgmt_exportkey_fn *exportkey; OSSL_OP_keymgmt_importkey_types_fn *importkey_types; OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types; + OSSL_OP_keymgmt_get_key_params_fn *get_key_params; + OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params; + + OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name; } /* EVP_KEYMGMT */ ; struct keymgmt_data_st { @@ -102,8 +108,6 @@ struct evp_keyexch_st { CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; - EVP_KEYMGMT *keymgmt; - OSSL_OP_keyexch_newctx_fn *newctx; OSSL_OP_keyexch_init_fn *init; OSSL_OP_keyexch_set_peer_fn *set_peer; @@ -120,8 +124,6 @@ struct evp_signature_st { CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; - EVP_KEYMGMT *keymgmt; - OSSL_OP_signature_newctx_fn *newctx; OSSL_OP_signature_sign_init_fn *sign_init; OSSL_OP_signature_sign_fn *sign; @@ -147,6 +149,25 @@ struct evp_signature_st { OSSL_OP_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } /* EVP_SIGNATURE */; +struct evp_asym_cipher_st { + int name_id; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_asym_cipher_newctx_fn *newctx; + OSSL_OP_asym_cipher_encrypt_init_fn *encrypt_init; + OSSL_OP_asym_cipher_encrypt_fn *encrypt; + OSSL_OP_asym_cipher_decrypt_init_fn *decrypt_init; + OSSL_OP_asym_cipher_decrypt_fn *decrypt; + OSSL_OP_asym_cipher_freectx_fn *freectx; + OSSL_OP_asym_cipher_dupctx_fn *dupctx; + OSSL_OP_asym_cipher_get_ctx_params_fn *get_ctx_params; + OSSL_OP_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_asym_cipher_set_ctx_params_fn *set_ctx_params; + OSSL_OP_asym_cipher_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_ASYM_CIPHER */; + int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, @@ -180,18 +201,14 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, const char *name, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); void *evp_generic_fetch_by_number(OPENSSL_CTX *ctx, int operation_id, int name_id, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, @@ -199,9 +216,7 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, void *user_arg, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data), - void *method_data, + OSSL_PROVIDER *prov), void (*free_method)(void *)); /* Internal fetchers for method types that are to be combined with others */ @@ -260,7 +275,9 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx); /* OSSL_PROVIDER * is only used to get the library context */ const char *evp_first_name(OSSL_PROVIDER *prov, int name_id); -int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name); +int evp_is_a(OSSL_PROVIDER *prov, int number, + const char *legacy_name, const char *name); void evp_names_do_all(OSSL_PROVIDER *prov, int number, void (*fn)(const char *name, void *data), void *data); +int evp_cipher_cache_constants(EVP_CIPHER *cipher); diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index dfc309ec..56896390 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -20,8 +20,14 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) { EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH)); + if (exchange == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + exchange->lock = CRYPTO_THREAD_lock_new(); if (exchange->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); OPENSSL_free(exchange); return NULL; } @@ -34,38 +40,17 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) static void *evp_keyexch_from_dispatch(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *vkeymgmt_data) + OSSL_PROVIDER *prov) { - /* - * Key exchange cannot work without a key, and key management - * from the same provider to manage its keys. We therefore fetch - * a key management method using the same algorithm and properties - * and pass that down to evp_generic_fetch to be passed on to our - * evp_keyexch_from_dispatch, which will attach the key management - * method to the newly created key exchange method as long as the - * provider matches. - */ - struct keymgmt_data_st *keymgmt_data = vkeymgmt_data; - EVP_KEYMGMT *keymgmt = - evp_keymgmt_fetch_by_number(keymgmt_data->ctx, name_id, - keymgmt_data->properties); EVP_KEYEXCH *exchange = NULL; int fncnt = 0, paramfncnt = 0; - if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) { - ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE); - goto err; - } - if ((exchange = evp_keyexch_new(prov)) == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; } exchange->name_id = name_id; - exchange->keymgmt = keymgmt; - keymgmt = NULL; /* avoid double free on failure below */ for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -135,7 +120,6 @@ static void *evp_keyexch_from_dispatch(int name_id, err: EVP_KEYEXCH_free(exchange); - EVP_KEYMGMT_free(keymgmt); return NULL; } @@ -147,7 +131,6 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange) CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock); if (i > 0) return; - EVP_KEYMGMT_free(exchange->keymgmt); ossl_provider_free(exchange->prov); CRYPTO_THREAD_lock_free(exchange->lock); OPENSSL_free(exchange); @@ -170,71 +153,81 @@ OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange) EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm, const char *properties) { - EVP_KEYEXCH *keyexch = NULL; - struct keymgmt_data_st keymgmt_data; - - keymgmt_data.ctx = ctx; - keymgmt_data.properties = properties; - keyexch = evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties, - evp_keyexch_from_dispatch, &keymgmt_data, - (int (*)(void *))EVP_KEYEXCH_up_ref, - (void (*)(void *))EVP_KEYEXCH_free); - - return keyexch; + return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties, + evp_keyexch_from_dispatch, + (int (*)(void *))EVP_KEYEXCH_up_ref, + (void (*)(void *))EVP_KEYEXCH_free); } -int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange) +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { int ret; void *provkey = NULL; + EVP_KEYEXCH *exchange = NULL; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } evp_pkey_ctx_free_old_ops(ctx); ctx->operation = EVP_PKEY_OP_DERIVE; - if (ctx->engine != NULL) + if (ctx->engine != NULL || ctx->keytype == NULL) goto legacy; - if (exchange != NULL) { - if (!EVP_KEYEXCH_up_ref(exchange)) - goto err; - } else { - int nid = ctx->pkey != NULL ? ctx->pkey->type : ctx->pmeth->pkey_id; + if (ctx->keymgmt == NULL) + ctx->keymgmt = + EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery); + if (ctx->keymgmt != NULL) { + const char *supported_exch = NULL; + + if (ctx->keymgmt->query_operation_name != NULL) + supported_exch = + ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH); /* - * TODO(3.0): Check for legacy handling. Remove this once all all - * algorithms are moved to providers. + * If we didn't get a supported exch, assume there is one with the + * same name as the key type. */ - if (ctx->pkey != NULL) { - switch (ctx->pkey->type) { - case EVP_PKEY_DH: - break; - default: - goto legacy; - } - exchange = EVP_KEYEXCH_fetch(NULL, OBJ_nid2sn(nid), NULL); - } else { - goto legacy; - } + if (supported_exch == NULL) + supported_exch = ctx->keytype; - if (exchange == NULL) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR); - goto err; - } + /* + * Because we cleared out old ops, we shouldn't need to worry about + * checking if exchange is already there. + */ + exchange = + EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery); } + if (ctx->keymgmt == NULL + || exchange == NULL + || (EVP_KEYMGMT_provider(ctx->keymgmt) + != EVP_KEYEXCH_provider(exchange))) { + /* + * We don't have the full support we need with provided methods, + * let's go see if legacy does. Also, we don't need to free + * ctx->keymgmt here, as it's not necessarily tied to this + * operation. It will be freed by EVP_PKEY_CTX_free(). + */ + EVP_KEYEXCH_free(exchange); + goto legacy; + } + + ctx->op.kex.exchange = exchange; + if (ctx->pkey != NULL) { - provkey = - evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt, 0); - if (provkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR); - goto err; - } + provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; } ctx->op.kex.exchprovctx = exchange->newctx(ossl_provider_ctx(exchange->prov)); if (ctx->op.kex.exchprovctx == NULL) { /* The provider key can stay in the cache */ - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR); + EVPerr(0, EVP_R_INITIALIZATION_ERROR); goto err; } ret = exchange->init(ctx->op.kex.exchprovctx, provkey); @@ -245,9 +238,8 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange) return 0; legacy: - if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } @@ -259,11 +251,6 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange) return ret; } -int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) -{ - return EVP_PKEY_derive_init_ex(ctx, NULL); -} - int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { int ret; @@ -284,12 +271,10 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) return -2; } - provkey = - evp_keymgmt_export_to_provider(peer, ctx->op.kex.exchange->keymgmt, 0); - if (provkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR); - return 0; - } + provkey = evp_keymgmt_export_to_provider(peer, ctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey); legacy: @@ -395,20 +380,16 @@ int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch) int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name) { - return evp_is_a(keyexch->prov, keyexch->name_id, name); + return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name); } void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx, void (*fn)(EVP_KEYEXCH *keyexch, void *arg), void *arg) { - struct keymgmt_data_st keymgmt_data; - - keymgmt_data.ctx = libctx; - keymgmt_data.properties = NULL; evp_generic_do_all(libctx, OSSL_OP_KEYEXCH, (void (*)(void *, void *))fn, arg, - evp_keyexch_from_dispatch, &keymgmt_data, + evp_keyexch_from_dispatch, (void (*)(void *))EVP_KEYEXCH_free); } diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 5ddf8560..84dc9108 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -90,7 +90,7 @@ int EVP_KDF_number(const EVP_KDF *kdf) int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name) { - return evp_is_a(kdf->prov, kdf->name_id, name); + return evp_is_a(kdf->prov, kdf->name_id, NULL, name); } const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf) diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c index 576dde68..219dbdfa 100644 --- a/crypto/evp/kdf_meth.c +++ b/crypto/evp/kdf_meth.c @@ -54,8 +54,7 @@ static void *evp_kdf_new(void) static void *evp_kdf_from_dispatch(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *method_data) + OSSL_PROVIDER *prov) { EVP_KDF *kdf = NULL; int fnkdfcnt = 0, fnctxcnt = 0; @@ -152,7 +151,7 @@ EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, - evp_kdf_from_dispatch, NULL, evp_kdf_up_ref, + evp_kdf_from_dispatch, evp_kdf_up_ref, evp_kdf_free); } @@ -193,5 +192,5 @@ void EVP_KDF_do_all_provided(OPENSSL_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_KDF, (void (*)(void *, void *))fn, arg, - evp_kdf_from_dispatch, NULL, evp_kdf_free); + evp_kdf_from_dispatch, evp_kdf_free); } diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 87629157..53610d3e 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -7,62 +7,29 @@ * https://www.openssl.org/source/license.html */ +#include #include "internal/cryptlib.h" #include "internal/nelem.h" #include "crypto/evp.h" #include "crypto/asn1.h" +#include "internal/core.h" #include "internal/provider.h" #include "evp_local.h" -static OSSL_PARAM *paramdefs_to_params(const OSSL_PARAM *paramdefs) +struct import_data_st { + void *provctx; + void *(*importfn)(void *provctx, const OSSL_PARAM params[]); + + /* Result */ + void *provdata; +}; + +static int try_import(const OSSL_PARAM params[], void *arg) { - size_t cnt; - const OSSL_PARAM *p; - OSSL_PARAM *params, *q; + struct import_data_st *data = arg; - for (cnt = 1, p = paramdefs; p->key != NULL; p++, cnt++) - continue; - - params = OPENSSL_zalloc(cnt * sizeof(*params)); - - for (p = paramdefs, q = params; ; p++, q++) { - *q = *p; - if (p->key == NULL) - break; - - q->data = NULL; /* In case the provider used it */ - q->return_size = 0; - } - - return params; -} - -typedef union align_block_un { - OSSL_UNION_ALIGN; -} ALIGN_BLOCK; - -#define ALIGN_SIZE sizeof(ALIGN_BLOCK) - -static void *allocate_params_space(OSSL_PARAM *params) -{ - unsigned char *data = NULL; - size_t space; - OSSL_PARAM *p; - - for (space = 0, p = params; p->key != NULL; p++) - space += ((p->return_size + ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE; - - if (space == 0) - return NULL; - - data = OPENSSL_zalloc(space); - - for (space = 0, p = params; p->key != NULL; p++) { - p->data = data + space; - space += ((p->return_size + ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE; - } - - return data; + data->provdata = data->importfn(data->provctx, params); + return data->provdata != NULL; } void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, @@ -121,68 +88,39 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, * the new provider. */ - void *(*importfn)(void *provctx, const OSSL_PARAM params[]) = + /* Setup for the export callback */ + struct import_data_st import_data; + + import_data.importfn = want_domainparams ? keymgmt->importdomparams : keymgmt->importkey; + import_data.provdata = NULL; /* * If the given keymgmt doesn't have an import function, give up */ - if (importfn == NULL) + if (import_data.importfn == NULL) return NULL; for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) { - if (pk->pkeys[j].keymgmt->exportkey != NULL) { - const OSSL_PARAM *paramdefs = NULL; - OSSL_PARAM *params = NULL; - void *data = NULL; - void *provctx = + int (*exportfn)(void *provctx, OSSL_CALLBACK *cb, void *cbarg) = + want_domainparams + ? pk->pkeys[j].keymgmt->exportdomparams + : pk->pkeys[j].keymgmt->exportkey; + + if (exportfn != NULL) { + import_data.provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); - int (*exportfn)(void *provctx, OSSL_PARAM params[]) = NULL; - - if (pk->pkeys[j].domainparams != want_domainparams) - continue; - - exportfn = want_domainparams - ? pk->pkeys[j].keymgmt->exportdomparams - : pk->pkeys[j].keymgmt->exportkey; - - paramdefs = pk->pkeys[j].keymgmt->exportkey_types(); - /* - * All params have 'data' set to NULL. In that case, - * the exportkey call should just fill in 'return_size' - * in all applicable params. - */ - params = paramdefs_to_params(paramdefs); - /* Get 'return_size' filled */ - exportfn(pk->pkeys[j].provdata, params); /* - * Allocate space and assign 'data' to point into the - * data block. - * If something goes wrong, go to the next cached key. + * The export function calls the callback (try_import), which + * does the import for us. + * Even though we got a success return, we double check that + * we actually got something, just in case some implementation + * forgets to check the return value. + */ - if ((data = allocate_params_space(params)) == NULL) - goto cont; - - /* - * Call the exportkey function a second time, to get - * the data filled. - * If something goes wrong, go to the next cached key. - */ - if (!exportfn(pk->pkeys[j].provdata, params)) - goto cont; - - /* - * We should have all the data at this point, so import - * into the new provider and hope to get a key back. - */ - provdata = importfn(provctx, params); - - cont: - OPENSSL_free(params); - OPENSSL_free(data); - - if (provdata != NULL) + if (exportfn(pk->pkeys[j].provdata, &try_import, &import_data) + && (provdata = import_data.provdata) != NULL) break; } } @@ -195,12 +133,7 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, */ j = ossl_assert(i < OSSL_NELEM(pk->pkeys)); - if (provdata != NULL) { - EVP_KEYMGMT_up_ref(keymgmt); - pk->pkeys[i].keymgmt = keymgmt; - pk->pkeys[i].provdata = provdata; - pk->pkeys[i].domainparams = want_domainparams; - } + evp_keymgmt_cache_pkey(pk, i, keymgmt, provdata, want_domainparams); return provdata; } @@ -224,9 +157,65 @@ void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk) keymgmt->freekey(provdata); EVP_KEYMGMT_free(keymgmt); } + + pk->cache.size = 0; + pk->cache.bits = 0; + pk->cache.security_bits = 0; } } +void evp_keymgmt_cache_pkey(EVP_PKEY *pk, size_t index, EVP_KEYMGMT *keymgmt, + void *provdata, int domainparams) +{ + if (provdata != NULL) { + EVP_KEYMGMT_up_ref(keymgmt); + pk->pkeys[index].keymgmt = keymgmt; + pk->pkeys[index].provdata = provdata; + pk->pkeys[index].domainparams = domainparams; + + /* + * Cache information about the domain parameters or key. Only needed + * for the "original" provider side key. + * + * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc + */ + if (index == 0) { + int ok; + int bits = 0; + int security_bits = 0; + int size = 0; + OSSL_PARAM params[4]; + + params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits); + params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS, + &security_bits); + params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size); + params[3] = OSSL_PARAM_construct_end(); + ok = domainparams + ? evp_keymgmt_get_domparam_params(keymgmt, provdata, params) + : evp_keymgmt_get_key_params(keymgmt, provdata, params); + if (ok) { + pk->cache.size = size; + pk->cache.bits = bits; + pk->cache.security_bits = security_bits; + } + } + } +} + +void *evp_keymgmt_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[], int domainparams) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + void *provdata = domainparams + ? keymgmt->importdomparams(provctx, params) + : keymgmt->importkey(provctx, params); + + evp_keymgmt_clear_pkey_cache(target); + evp_keymgmt_cache_pkey(target, 0, keymgmt, provdata, domainparams); + + return provdata; +} /* internal functions */ /* TODO(3.0) decide if these should be public or internal */ @@ -253,9 +242,10 @@ void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, } int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt, - void *provdomparams, OSSL_PARAM params[]) + void *provdomparams, + OSSL_CALLBACK *param_cb, void *cbarg) { - return keymgmt->exportdomparams(provdomparams, params); + return keymgmt->exportdomparams(provdomparams, param_cb, cbarg); } const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt) @@ -263,11 +253,31 @@ const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt) return keymgmt->importdomparam_types(); } +/* + * TODO(v3.0) investigate if we need this function. 'openssl provider' may + * be a caller... + */ const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt) { return keymgmt->exportdomparam_types(); } +int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt, + void *provdomparams, OSSL_PARAM params[]) +{ + if (keymgmt->get_domparam_params == NULL) + return 1; + return keymgmt->get_domparam_params(provdomparams, params); +} + +const OSSL_PARAM * +evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt) +{ + if (keymgmt->gettable_domparam_params == NULL) + return NULL; + return keymgmt->gettable_domparam_params(); +} + void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]) @@ -299,9 +309,9 @@ void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey) } int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey, - OSSL_PARAM params[]) + OSSL_CALLBACK *param_cb, void *cbarg) { - return keymgmt->exportkey(provkey, params); + return keymgmt->exportkey(provkey, param_cb, cbarg); } const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt) @@ -309,7 +319,26 @@ const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt) return keymgmt->importkey_types(); } +/* + * TODO(v3.0) investigate if we need this function. 'openssl provider' may + * be a caller... + */ const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt) { return keymgmt->exportkey_types(); } + +int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt, + void *provkey, OSSL_PARAM params[]) +{ + if (keymgmt->get_key_params == NULL) + return 1; + return keymgmt->get_key_params(provkey, params); +} + +const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt) +{ + if (keymgmt->gettable_key_params == NULL) + return NULL; + return keymgmt->gettable_key_params(); +} diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index 9c8d482b..ae1f10e6 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -35,8 +35,7 @@ static void *keymgmt_new(void) static void *keymgmt_from_dispatch(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *unused) + OSSL_PROVIDER *prov) { EVP_KEYMGMT *keymgmt = NULL; @@ -82,6 +81,16 @@ static void *keymgmt_from_dispatch(int name_id, keymgmt->exportdomparam_types = OSSL_get_OP_keymgmt_exportdomparam_types(fns); break; + case OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS: + if (keymgmt->get_domparam_params == NULL) + keymgmt->get_domparam_params = + OSSL_get_OP_keymgmt_get_domparam_params(fns); + break; + case OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS: + if (keymgmt->gettable_domparam_params == NULL) + keymgmt->gettable_domparam_params = + OSSL_get_OP_keymgmt_gettable_domparam_params(fns); + break; case OSSL_FUNC_KEYMGMT_IMPORTKEY: if (keymgmt->importkey != NULL) break; @@ -119,6 +128,22 @@ static void *keymgmt_from_dispatch(int name_id, keymgmt->exportkey_types = OSSL_get_OP_keymgmt_exportkey_types(fns); break; + case OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS: + if (keymgmt->get_key_params == NULL) + keymgmt->get_key_params = + OSSL_get_OP_keymgmt_get_key_params(fns); + break; + case OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS: + if (keymgmt->gettable_key_params == NULL) + keymgmt->gettable_key_params = + OSSL_get_OP_keymgmt_gettable_key_params(fns); + break; + case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: + if (keymgmt->query_operation_name != NULL) + break; + keymgmt->query_operation_name = + OSSL_get_OP_keymgmt_query_operation_name(fns); + break; } } /* @@ -138,10 +163,14 @@ static void *keymgmt_from_dispatch(int name_id, && keymgmt->importdomparams == NULL) || (keymgmt->exportdomparam_types != NULL && keymgmt->exportdomparams == NULL) + || (keymgmt->gettable_domparam_params != NULL + && keymgmt->get_domparam_params == NULL) || (keymgmt->importkey_types != NULL && keymgmt->importkey == NULL) || (keymgmt->exportkey_types != NULL - && keymgmt->exportkey == NULL)) { + && keymgmt->exportkey == NULL) + || (keymgmt->gettable_key_params != NULL + && keymgmt->get_key_params == NULL)) { EVP_KEYMGMT_free(keymgmt); EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS); return NULL; @@ -158,7 +187,7 @@ EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, { return evp_generic_fetch_by_number(ctx, OSSL_OP_KEYMGMT, name_id, properties, - keymgmt_from_dispatch, NULL, + keymgmt_from_dispatch, (int (*)(void *))EVP_KEYMGMT_up_ref, (void (*)(void *))EVP_KEYMGMT_free); } @@ -167,7 +196,7 @@ EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties, - keymgmt_from_dispatch, NULL, + keymgmt_from_dispatch, (int (*)(void *))EVP_KEYMGMT_up_ref, (void (*)(void *))EVP_KEYMGMT_free); } @@ -207,7 +236,7 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt) int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name) { - return evp_is_a(keymgmt->prov, keymgmt->name_id, name); + return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name); } void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx, @@ -216,7 +245,7 @@ void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_KEYMGMT, (void (*)(void *, void *))fn, arg, - keymgmt_from_dispatch, NULL, + keymgmt_from_dispatch, (void (*)(void *))EVP_KEYMGMT_free); } diff --git a/crypto/evp/legacy_blake2.c b/crypto/evp/legacy_blake2.c new file mode 100644 index 00000000..e0340340 --- /dev/null +++ b/crypto/evp/legacy_blake2.c @@ -0,0 +1,46 @@ +/* + * Copyright 2019 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 + */ + +#include "crypto/evp.h" +#include "prov/blake2.h" /* diverse BLAKE2 macros */ +#include "legacy_meth.h" + +#define blake2b_init blake2b512_init +#define blake2s_init blake2s256_init + +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, blake2s) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, blake2b) + +static const EVP_MD blake2b_md = { + NID_blake2b512, + 0, + BLAKE2B_DIGEST_LENGTH, + 0, + LEGACY_EVP_MD_METH_TABLE(blake2b_int_init, blake2b_int_update, + blake2b_int_final, NULL, BLAKE2B_BLOCKBYTES), +}; + +const EVP_MD *EVP_blake2b512(void) +{ + return &blake2b_md; +} + +static const EVP_MD blake2s_md = { + NID_blake2s256, + 0, + BLAKE2S_DIGEST_LENGTH, + 0, + LEGACY_EVP_MD_METH_TABLE(blake2s_int_init, blake2s_int_update, + blake2s_int_final, NULL, BLAKE2S_BLOCKBYTES), +}; + +const EVP_MD *EVP_blake2s256(void) +{ + return &blake2s_md; +} diff --git a/crypto/evp/legacy_md2.c b/crypto/evp/legacy_md2.c index d399095f..ec6e0a5f 100644 --- a/crypto/evp/legacy_md2.c +++ b/crypto/evp/legacy_md2.c @@ -7,29 +7,27 @@ * https://www.openssl.org/source/license.html */ -#include +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#ifndef OPENSSL_NO_MD2 +#include +#include "crypto/evp.h" +#include "legacy_meth.h" -# include -# include "crypto/evp.h" +IMPLEMENT_LEGACY_EVP_MD_METH(md2, MD2) static const EVP_MD md2_md = { NID_md2, NID_md2WithRSAEncryption, MD2_DIGEST_LENGTH, 0, - NULL, - NULL, - NULL, - NULL, - NULL, - MD2_BLOCK, + LEGACY_EVP_MD_METH_TABLE(md2_init, md2_update, md2_final, NULL, MD2_BLOCK) }; const EVP_MD *EVP_md2(void) { return &md2_md; } - -#endif /* OPENSSL_NO_MD2 */ diff --git a/crypto/evp/legacy_md4.c b/crypto/evp/legacy_md4.c index fa57e98b..4f91a9b2 100644 --- a/crypto/evp/legacy_md4.c +++ b/crypto/evp/legacy_md4.c @@ -7,29 +7,27 @@ * https://www.openssl.org/source/license.html */ -#include +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#ifndef OPENSSL_NO_MD4 +#include +#include "crypto/evp.h" +#include "legacy_meth.h" -# include -# include "crypto/evp.h" +IMPLEMENT_LEGACY_EVP_MD_METH(md4, MD4) static const EVP_MD md4_md = { NID_md4, NID_md4WithRSAEncryption, MD4_DIGEST_LENGTH, 0, - NULL, - NULL, - NULL, - NULL, - NULL, - MD4_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(md4_init, md4_update, md4_final, NULL, MD4_CBLOCK), }; const EVP_MD *EVP_md4(void) { return &md4_md; } - -#endif /* OPENSSL_NO_MD4 */ diff --git a/crypto/evp/legacy_md5.c b/crypto/evp/legacy_md5.c index f125b33f..9bb1258e 100644 --- a/crypto/evp/legacy_md5.c +++ b/crypto/evp/legacy_md5.c @@ -7,29 +7,21 @@ * https://www.openssl.org/source/license.html */ -#include +#include +#include "crypto/evp.h" +#include "legacy_meth.h" -#ifndef OPENSSL_NO_MD5 - -# include -# include "crypto/evp.h" +IMPLEMENT_LEGACY_EVP_MD_METH(md5, MD5) static const EVP_MD md5_md = { NID_md5, NID_md5WithRSAEncryption, MD5_DIGEST_LENGTH, 0, - NULL, - NULL, - NULL, - NULL, - NULL, - MD5_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(md5_init, md5_update, md5_final, NULL, MD5_CBLOCK) }; const EVP_MD *EVP_md5(void) { return &md5_md; } - -#endif /* OPENSSL_NO_MD5 */ diff --git a/crypto/evp/legacy_md5_sha1.c b/crypto/evp/legacy_md5_sha1.c index a23febfd..6da6b4fd 100644 --- a/crypto/evp/legacy_md5_sha1.c +++ b/crypto/evp/legacy_md5_sha1.c @@ -7,31 +7,27 @@ * https://www.openssl.org/source/license.html */ -#include - +#include "crypto/evp.h" #include "prov/md5_sha1.h" /* diverse MD5_SHA1 macros */ +#include "legacy_meth.h" -#ifndef OPENSSL_NO_MD5 - -# include -# include "crypto/evp.h" +IMPLEMENT_LEGACY_EVP_MD_METH_LC(md5_sha1_int, md5_sha1) +static int md5_sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) +{ + return md5_sha1_ctrl(EVP_MD_CTX_md_data(ctx), cmd, mslen, ms); +} static const EVP_MD md5_sha1_md = { NID_md5_sha1, NID_md5_sha1, MD5_SHA1_DIGEST_LENGTH, 0, - NULL, - NULL, - NULL, - NULL, - NULL, - MD5_SHA1_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(md5_sha1_int_init, md5_sha1_int_update, + md5_sha1_int_final, md5_sha1_int_ctrl, + MD5_SHA1_CBLOCK), }; const EVP_MD *EVP_md5_sha1(void) { return &md5_sha1_md; } - -#endif /* OPENSSL_NO_MD5 */ diff --git a/crypto/evp/legacy_mdc2.c b/crypto/evp/legacy_mdc2.c index 5b51b015..9499db78 100644 --- a/crypto/evp/legacy_mdc2.c +++ b/crypto/evp/legacy_mdc2.c @@ -7,29 +7,28 @@ * https://www.openssl.org/source/license.html */ -#include +/* + * MDC2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#ifndef OPENSSL_NO_MDC2 +#include +#include "crypto/evp.h" +#include "legacy_meth.h" -# include -# include "crypto/evp.h" +IMPLEMENT_LEGACY_EVP_MD_METH(mdc2, MDC2) static const EVP_MD mdc2_md = { NID_mdc2, NID_mdc2WithRSA, MDC2_DIGEST_LENGTH, 0, - NULL, - NULL, - NULL, - NULL, - NULL, - MDC2_BLOCK, + LEGACY_EVP_MD_METH_TABLE(mdc2_init, mdc2_update, mdc2_final, NULL, + MDC2_BLOCK), }; const EVP_MD *EVP_mdc2(void) { return &mdc2_md; } - -#endif /* OPENSSL_NO_MDC2 */ diff --git a/crypto/evp/legacy_meth.h b/crypto/evp/legacy_meth.h new file mode 100644 index 00000000..0a23efd0 --- /dev/null +++ b/crypto/evp/legacy_meth.h @@ -0,0 +1,40 @@ +/* + * Copyright 2019 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 + */ + +#define IMPLEMENT_LEGACY_EVP_MD_METH(nm, fn) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_Init(EVP_MD_CTX_md_data(ctx)); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_Update(EVP_MD_CTX_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_Final(md, EVP_MD_CTX_md_data(ctx)); \ +} + +#define IMPLEMENT_LEGACY_EVP_MD_METH_LC(nm, fn) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_md_data(ctx)); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_update(EVP_MD_CTX_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_final(md, EVP_MD_CTX_md_data(ctx)); \ +} + + +#define LEGACY_EVP_MD_METH_TABLE(init, update, final, ctrl, blksz) \ + init, update, final, NULL, NULL, blksz, 0, ctrl diff --git a/crypto/evp/legacy_ripemd.c b/crypto/evp/legacy_ripemd.c new file mode 100644 index 00000000..fd1739c7 --- /dev/null +++ b/crypto/evp/legacy_ripemd.c @@ -0,0 +1,34 @@ +/* + * Copyright 1995-2016 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 + */ + +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(ripe, RIPEMD160) + +static const EVP_MD ripemd160_md = { + NID_ripemd160, + NID_ripemd160WithRSA, + RIPEMD160_DIGEST_LENGTH, + 0, + LEGACY_EVP_MD_METH_TABLE(ripe_init, ripe_update, ripe_final, NULL, + RIPEMD160_CBLOCK), +}; + +const EVP_MD *EVP_ripemd160(void) +{ + return &ripemd160_md; +} diff --git a/crypto/evp/legacy_sha.c b/crypto/evp/legacy_sha.c index 859c129a..db289bf2 100644 --- a/crypto/evp/legacy_sha.c +++ b/crypto/evp/legacy_sha.c @@ -7,24 +7,83 @@ * https://www.openssl.org/source/license.html */ -#include - -#include #include /* diverse SHA macros */ #include "internal/sha3.h" /* KECCAK1600_WIDTH */ #include "crypto/evp.h" +/* Used by legacy methods */ +#include "crypto/sha.h" +#include "legacy_meth.h" +#include "evp_local.h" + +/*- + * LEGACY methods for SHA. + * These only remain to support engines that can get these methods. + * Hardware support for SHA3 has been removed from these legacy cases. + */ +#define IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(nm, fn, tag) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_md_data(ctx), tag, ctx->digest->md_size * 8); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_update(EVP_MD_CTX_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_final(md, EVP_MD_CTX_md_data(ctx)); \ +} +#define IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(nm, fn, tag) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_md_data(ctx), tag, ctx->digest->md_size * 8); \ +} \ + +#define sha512_224_Init sha512_224_init +#define sha512_256_Init sha512_256_init + +#define sha512_224_Update SHA512_Update +#define sha512_224_Final SHA512_Final +#define sha512_256_Update SHA512_Update +#define sha512_256_Final SHA512_Final + +IMPLEMENT_LEGACY_EVP_MD_METH(sha1, SHA1) +IMPLEMENT_LEGACY_EVP_MD_METH(sha224, SHA224) +IMPLEMENT_LEGACY_EVP_MD_METH(sha256, SHA256) +IMPLEMENT_LEGACY_EVP_MD_METH(sha384, SHA384) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512, SHA512) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512_224_int, sha512_224) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512_256_int, sha512_256) +IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(sha3_int, sha3, '\x06') +IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(shake, sha3, '\x1f') + +static int sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) +{ + return sha1_ctrl(ctx != NULL ? EVP_MD_CTX_md_data(ctx) : NULL, cmd, p1, p2); +} + +static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) +{ + KECCAK1600_CTX *ctx = evp_ctx->md_data; + + switch (cmd) { + case EVP_MD_CTRL_XOF_LEN: + ctx->md_size = p1; + return 1; + default: + return 0; + } +} + + static const EVP_MD sha1_md = { NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha1_init, sha1_update, sha1_final, sha1_int_ctrl, + SHA_CBLOCK), }; const EVP_MD *EVP_sha1(void) @@ -37,12 +96,8 @@ static const EVP_MD sha224_md = { NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA256_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha224_init, sha224_update, sha224_final, NULL, + SHA256_CBLOCK), }; const EVP_MD *EVP_sha224(void) @@ -55,12 +110,8 @@ static const EVP_MD sha256_md = { NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA256_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha256_init, sha256_update, sha256_final, NULL, + SHA256_CBLOCK), }; const EVP_MD *EVP_sha256(void) @@ -73,12 +124,8 @@ static const EVP_MD sha512_224_md = { NID_sha512_224WithRSAEncryption, SHA224_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA512_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha512_224_int_init, sha512_224_int_update, + sha512_224_int_final, NULL, SHA512_CBLOCK), }; const EVP_MD *EVP_sha512_224(void) @@ -91,12 +138,8 @@ static const EVP_MD sha512_256_md = { NID_sha512_256WithRSAEncryption, SHA256_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA512_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha512_256_int_init, sha512_256_int_update, + sha512_256_int_final, NULL, SHA512_CBLOCK), }; const EVP_MD *EVP_sha512_256(void) @@ -109,12 +152,8 @@ static const EVP_MD sha384_md = { NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA512_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha384_init, sha384_update, sha384_final, NULL, + SHA512_CBLOCK), }; const EVP_MD *EVP_sha384(void) @@ -127,12 +166,8 @@ static const EVP_MD sha512_md = { NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, - NULL, - NULL, - NULL, - NULL, - NULL, - SHA512_CBLOCK, + LEGACY_EVP_MD_METH_TABLE(sha512_init, sha512_update, sha512_final, NULL, + SHA512_CBLOCK), }; const EVP_MD *EVP_sha512(void) @@ -140,40 +175,33 @@ const EVP_MD *EVP_sha512(void) return &sha512_md; } -# define EVP_MD_SHA3(bitlen) \ - const EVP_MD *EVP_sha3_##bitlen(void) \ - { \ - static const EVP_MD sha3_##bitlen##_md = { \ - NID_sha3_##bitlen, \ - NID_RSA_SHA3_##bitlen, \ - bitlen / 8, \ - EVP_MD_FLAG_DIGALGID_ABSENT, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - }; \ - return &sha3_##bitlen##_md; \ - } -# define EVP_MD_SHAKE(bitlen) \ - const EVP_MD *EVP_shake##bitlen(void) \ - { \ - static const EVP_MD shake##bitlen##_md = { \ - NID_shake##bitlen, \ - 0, \ - bitlen / 8, \ - EVP_MD_FLAG_XOF, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - }; \ - return &shake##bitlen##_md; \ - } +#define EVP_MD_SHA3(bitlen) \ +const EVP_MD *EVP_sha3_##bitlen(void) \ +{ \ + static const EVP_MD sha3_##bitlen##_md = { \ + NID_sha3_##bitlen, \ + NID_RSA_SHA3_##bitlen, \ + bitlen / 8, \ + EVP_MD_FLAG_DIGALGID_ABSENT, \ + LEGACY_EVP_MD_METH_TABLE(sha3_int_init, sha3_int_update, \ + sha3_int_final, NULL, \ + (KECCAK1600_WIDTH - bitlen * 2) / 8), \ + }; \ + return &sha3_##bitlen##_md; \ +} +#define EVP_MD_SHAKE(bitlen) \ +const EVP_MD *EVP_shake##bitlen(void) \ +{ \ + static const EVP_MD shake##bitlen##_md = { \ + NID_shake##bitlen, \ + 0, \ + bitlen / 8, \ + EVP_MD_FLAG_XOF, \ + LEGACY_EVP_MD_METH_TABLE(shake_init, sha3_int_update, sha3_int_final, \ + shake_ctrl, (KECCAK1600_WIDTH - bitlen * 2) / 8), \ + }; \ + return &shake##bitlen##_md; \ +} EVP_MD_SHA3(224) EVP_MD_SHA3(256) diff --git a/crypto/evp/legacy_wp.c b/crypto/evp/legacy_wp.c new file mode 100644 index 00000000..38f82a76 --- /dev/null +++ b/crypto/evp/legacy_wp.c @@ -0,0 +1,34 @@ +/* + * Copyright 2005-2016 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 + */ + +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(wp, WHIRLPOOL) + +static const EVP_MD whirlpool_md = { + NID_whirlpool, + 0, + WHIRLPOOL_DIGEST_LENGTH, + 0, + LEGACY_EVP_MD_METH_TABLE(wp_init, wp_update, wp_final, NULL, + WHIRLPOOL_BBLOCK / 8), +}; + +const EVP_MD *EVP_whirlpool(void) +{ + return &whirlpool_md; +} diff --git a/crypto/evp/m_ripemd.c b/crypto/evp/m_ripemd.c deleted file mode 100644 index 4e05d18b..00000000 --- a/crypto/evp/m_ripemd.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1995-2016 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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_RMD160 - -# include -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD ripemd160_md = { - NID_ripemd160, - NID_ripemd160WithRSA, - RIPEMD160_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - RIPEMD160_CBLOCK, - sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), -}; - -const EVP_MD *EVP_ripemd160(void) -{ - return &ripemd160_md; -} -#endif diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index c02325cf..dbfa01b3 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -27,9 +27,10 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen) static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, const char *mdname, const char *props, ENGINE *e, EVP_PKEY *pkey, - EVP_SIGNATURE *signature, int ver) + int ver) { EVP_PKEY_CTX *locpctx = NULL; + EVP_SIGNATURE *signature = NULL; void *provkey = NULL; int ret; @@ -43,66 +44,92 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, ctx->provctx = NULL; } - if (ctx->pctx == NULL) { + if (ctx->pctx == NULL) ctx->pctx = EVP_PKEY_CTX_new(pkey, e); - if (ctx->pctx == NULL) - return 0; - } else if (pkey != NULL) { - if (!EVP_PKEY_up_ref(pkey)) - return 0; - EVP_PKEY_free(ctx->pctx->pkey); - ctx->pctx->pkey = pkey; - } + if (ctx->pctx == NULL) + return 0; + locpctx = ctx->pctx; evp_pkey_ctx_free_old_ops(locpctx); - if (locpctx->pkey == NULL) + + if (locpctx->keytype == NULL) goto legacy; - if (e != NULL || locpctx->engine != NULL) - goto legacy; - - if (signature != NULL) { - if (!EVP_SIGNATURE_up_ref(signature)) - goto err; - } else { - /* - * TODO(3.0): Check for legacy handling. Remove this once all all - * algorithms are moved to providers. - */ - switch (locpctx->pkey->type) { - case NID_dsa: - break; - default: - goto legacy; - } - signature - = EVP_SIGNATURE_fetch(NULL, OBJ_nid2sn(locpctx->pkey->type), NULL); - - if (signature == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); - goto err; + if (mdname == NULL) { + if (type != NULL) { + mdname = EVP_MD_name(type); + } else if (pkey != NULL) { + /* + * TODO(v3.0) work out a better way for EVP_PKEYs with no legacy + * component. + */ + if (pkey->pkey.ptr != NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + mdname = OBJ_nid2sn(def_nid); + } } } - locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX - : EVP_PKEY_OP_SIGNCTX; + + if (locpctx->keymgmt == NULL) + locpctx->keymgmt = EVP_KEYMGMT_fetch(locpctx->libctx, locpctx->keytype, + locpctx->propquery); + if (locpctx->keymgmt != NULL) { + const char *supported_sig = NULL; + + if (locpctx->keymgmt->query_operation_name != NULL) + supported_sig = + locpctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE); + + /* + * If we didn't get a supported sig, assume there is one with the + * same name as the key type. + */ + if (supported_sig == NULL) + supported_sig = locpctx->keytype; + + /* + * Because we cleared out old ops, we shouldn't need to worry about + * checking if signature is already there. + */ + signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig, + locpctx->propquery); + } + + if (locpctx->keymgmt == NULL + || signature == NULL + || (EVP_KEYMGMT_provider(locpctx->keymgmt) + != EVP_SIGNATURE_provider(signature))) { + /* + * We don't have the full support we need with provided methods, + * let's go see if legacy does. Also, we don't need to free + * ctx->keymgmt here, as it's not necessarily tied to this + * operation. It will be freed by EVP_PKEY_CTX_free(). + */ + EVP_SIGNATURE_free(signature); + goto legacy; + } + + /* No more legacy from here down to legacy: */ locpctx->op.sig.signature = signature; + provkey = + evp_keymgmt_export_to_provider(locpctx->pkey, locpctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; + + locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX + : EVP_PKEY_OP_SIGNCTX; + locpctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov)); if (locpctx->op.sig.sigprovctx == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; } - provkey = - evp_keymgmt_export_to_provider(locpctx->pkey, signature->keymgmt, 0); - if (provkey == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); - goto err; - } - - if (mdname == NULL) { - mdname = EVP_MD_name(type); + if (type != NULL) { ctx->reqdigest = type; } else { /* @@ -111,11 +138,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, * man pages), i.e. the ref count is not updated so the EVP_MD should * not be used beyound the lifetime of the EVP_MD_CTX. */ - ctx->reqdigest - = ctx->fetched_digest - = EVP_MD_fetch( - ossl_provider_library_context(EVP_SIGNATURE_provider(signature)), - mdname, props); + ctx->reqdigest = ctx->fetched_digest = + EVP_MD_fetch(locpctx->libctx, mdname, props); } if (ver) { @@ -123,15 +147,15 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; } - ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx, mdname, - props, provkey); + ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx, + mdname, props, provkey); } else { if (signature->digest_sign_init == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; } - ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx, mdname, - props, provkey); + ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx, + mdname, props, provkey); } return ret ? 1 : 0; @@ -141,6 +165,11 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, return 0; legacy: + if (ctx->pctx->pmeth == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { if (type == NULL) { @@ -197,31 +226,28 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, } int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, EVP_PKEY *pkey, - EVP_SIGNATURE *signature) + const char *mdname, const char *props, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, signature, - 0); + return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 0); } int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 0); + return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 0); } int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, const char *props, - EVP_PKEY *pkey, EVP_SIGNATURE *signature) + EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, signature, - 1); + return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 1); } int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1); + return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 1); } #endif /* FIPS_MDOE */ @@ -276,34 +302,42 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, sigret, siglen, SIZE_MAX); legacy: + if (pctx == NULL || pctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { - if (!sigret) + if (sigret == NULL) return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); else { - EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx); - if (!dctx) + EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(pctx); + + if (dctx == NULL) return 0; r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); EVP_PKEY_CTX_free(dctx); } return r; } - if (pctx->pmeth->signctx) + if (pctx->pmeth->signctx != NULL) sctx = 1; else sctx = 0; - if (sigret) { + if (sigret != NULL) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen = 0; + if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { if (sctx) - r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx); + r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); else r = EVP_DigestFinal_ex(ctx, md, &mdlen); } else { EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) return 0; if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { @@ -319,7 +353,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, } if (sctx || !r) return r; - if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0) return 0; } else { if (sctx) { @@ -327,6 +361,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, return 0; } else { int s = EVP_MD_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) return 0; } @@ -337,7 +372,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - if (ctx->pctx->pmeth->digestsign != NULL) + if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL) return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) return 0; @@ -363,13 +398,18 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, sig, siglen); legacy: - if (ctx->pctx->pmeth->verifyctx) + if (pctx == NULL || pctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + if (pctx->pmeth->verifyctx != NULL) vctx = 1; else vctx = 0; if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { if (vctx) - r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx); + r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx); else r = EVP_DigestFinal_ex(ctx, md, &mdlen); } else { @@ -389,13 +429,13 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, } if (vctx || !r) return r; - return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); + return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen); } int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) { - if (ctx->pctx->pmeth->digestverify != NULL) + if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL) return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) return -1; diff --git a/crypto/evp/m_wp.c b/crypto/evp/m_wp.c deleted file mode 100644 index ee69df56..00000000 --- a/crypto/evp/m_wp.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2005-2016 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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_WHIRLPOOL - -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD whirlpool_md = { - NID_whirlpool, - 0, - WHIRLPOOL_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - WHIRLPOOL_BBLOCK / 8, - sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), -}; - -const EVP_MD *EVP_whirlpool(void) -{ - return &whirlpool_md; -} -#endif diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index 07ed1c87..bf52aaff 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -165,7 +165,7 @@ int EVP_MAC_number(const EVP_MAC *mac) int EVP_MAC_is_a(const EVP_MAC *mac, const char *name) { - return evp_is_a(mac->prov, mac->name_id, name); + return evp_is_a(mac->prov, mac->name_id, NULL, name); } void EVP_MAC_names_do_all(const EVP_MAC *mac, diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c index 2c124aef..b1fadb6c 100644 --- a/crypto/evp/mac_meth.c +++ b/crypto/evp/mac_meth.c @@ -48,8 +48,7 @@ static void *evp_mac_new(void) static void *evp_mac_from_dispatch(int name_id, const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *unused) + OSSL_PROVIDER *prov) { EVP_MAC *mac = NULL; int fnmaccnt = 0, fnctxcnt = 0; @@ -154,7 +153,7 @@ EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties, - evp_mac_from_dispatch, NULL, evp_mac_up_ref, + evp_mac_from_dispatch, evp_mac_up_ref, evp_mac_free); } @@ -200,5 +199,5 @@ void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx, { evp_generic_do_all(libctx, OSSL_OP_MAC, (void (*)(void *, void *))fn, arg, - evp_mac_from_dispatch, NULL, evp_mac_free); + evp_mac_from_dispatch, evp_mac_free); } diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 901899ad..5eb7a39a 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -8,11 +8,12 @@ */ #include -#include "internal/cryptlib.h" #include #include -#include "crypto/objects.h" #include +#include "internal/cryptlib.h" +#include "internal/namemap.h" +#include "crypto/objects.h" #include "crypto/evp.h" int EVP_add_cipher(const EVP_CIPHER *c) @@ -56,26 +57,94 @@ int EVP_add_digest(const EVP_MD *md) return r; } +static void cipher_from_name(const char *name, void *data) +{ + const EVP_CIPHER **cipher = data; + + if (*cipher != NULL) + return; + + *cipher = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); +} + const EVP_CIPHER *EVP_get_cipherbyname(const char *name) +{ + return evp_get_cipherbyname_ex(NULL, name); +} + +const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name) { const EVP_CIPHER *cp; + OSSL_NAMEMAP *namemap; + int id; if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL)) return NULL; cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + + if (cp != NULL) + return cp; + + /* + * It's not in the method database, but it might be there under a different + * name. So we check for aliases in the EVP namemap and try all of those + * in turn. + */ + + namemap = ossl_namemap_stored(libctx); + id = ossl_namemap_name2num(namemap, name); + if (id == 0) + return NULL; + + ossl_namemap_doall_names(namemap, id, cipher_from_name, &cp); + return cp; } +static void digest_from_name(const char *name, void *data) +{ + const EVP_MD **md = data; + + if (*md != NULL) + return; + + *md = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); +} + const EVP_MD *EVP_get_digestbyname(const char *name) { - const EVP_MD *cp; + return evp_get_digestbyname_ex(NULL, name); +} + +const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name) +{ + const EVP_MD *dp; + OSSL_NAMEMAP *namemap; + int id; if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) return NULL; - cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); - return cp; + dp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + + if (dp != NULL) + return dp; + + /* + * It's not in the method database, but it might be there under a different + * name. So we check for aliases in the EVP namemap and try all of those + * in turn. + */ + + namemap = ossl_namemap_stored(libctx); + id = ossl_namemap_name2num(namemap, name); + if (id == 0) + return NULL; + + ossl_namemap_doall_names(namemap, id, digest_from_name, &dp); + + return dp; } void evp_cleanup_int(void) diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 04530063..2e0890ca 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -21,18 +21,25 @@ #include #include #include +#include #include #include "crypto/asn1.h" #include "crypto/evp.h" #include "internal/provider.h" -static void EVP_PKEY_free_it(EVP_PKEY *x); +static void evp_pkey_free_it(EVP_PKEY *key); + +#ifndef FIPS_MODE int EVP_PKEY_bits(const EVP_PKEY *pkey) { - if (pkey && pkey->ameth && pkey->ameth->pkey_bits) - return pkey->ameth->pkey_bits(pkey); + if (pkey != NULL) { + if (pkey->ameth == NULL) + return pkey->cache.bits; + else if (pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + } return 0; } @@ -40,21 +47,16 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey) { if (pkey == NULL) return 0; - if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL) + if (pkey->ameth == NULL) + return pkey->cache.security_bits; + if (pkey->ameth->pkey_security_bits == NULL) return -2; return pkey->ameth->pkey_security_bits(pkey); } -int EVP_PKEY_size(const EVP_PKEY *pkey) -{ - if (pkey && pkey->ameth && pkey->ameth->pkey_size) - return pkey->ameth->pkey_size(pkey); - return 0; -} - int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) { -#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) { int ret = pkey->save_parameters; @@ -62,8 +64,8 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) pkey->save_parameters = mode; return ret; } -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC if (pkey->type == EVP_PKEY_EC) { int ret = pkey->save_parameters; @@ -71,7 +73,7 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) pkey->save_parameters = mode; return ret; } -#endif +# endif return 0; } @@ -105,7 +107,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { - if (pkey->ameth && pkey->ameth->param_missing) + if (pkey != NULL && pkey->ameth && pkey->ameth->param_missing) return pkey->ameth->param_missing(pkey); return 0; } @@ -140,38 +142,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } -EVP_PKEY *EVP_PKEY_new(void) -{ - EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); - - if (ret == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - ret->type = EVP_PKEY_NONE; - ret->save_type = EVP_PKEY_NONE; - ret->references = 1; - ret->save_parameters = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; - } - return ret; -} - -int EVP_PKEY_up_ref(EVP_PKEY *pkey) -{ - int i; - - if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0) - return 0; - - REF_PRINT_COUNT("EVP_PKEY", pkey); - REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); -} /* * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey @@ -186,29 +156,29 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, if (pkey) { if (pkey->pkey.ptr) - EVP_PKEY_free_it(pkey); + evp_pkey_free_it(pkey); /* * If key type matches and a method exists then this lookup has * succeeded once so just indicate success. */ if ((type == pkey->save_type) && pkey->ameth) return 1; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE /* If we have ENGINEs release them */ ENGINE_finish(pkey->engine); pkey->engine = NULL; ENGINE_finish(pkey->pmeth_engine); pkey->pmeth_engine = NULL; -#endif +# endif } if (str) ameth = EVP_PKEY_asn1_find_str(eptr, str, len); else ameth = EVP_PKEY_asn1_find(eptr, type); -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE if (pkey == NULL && eptr != NULL) ENGINE_finish(e); -#endif +# endif if (ameth == NULL) { EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); return 0; @@ -320,10 +290,10 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher) { -#ifndef OPENSSL_NO_CMAC -# ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_CMAC +# ifndef OPENSSL_NO_ENGINE const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL; -# endif +# endif const char *cipher_name = EVP_CIPHER_name(cipher); const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher); OPENSSL_CTX *libctx = @@ -341,11 +311,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, goto err; } -# ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE if (engine_id != NULL) params[paramsn++] = OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0); -# endif +# endif params[paramsn++] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, @@ -368,11 +338,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, EVP_MAC_CTX_free(cmctx); EVP_MAC_free(cmac); return NULL; -#else +# else EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return NULL; -#endif +# endif } int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) @@ -404,7 +374,7 @@ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) return 1; } -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e) { if (e != NULL) { @@ -427,7 +397,7 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey) { return pkey->engine; } -#endif +# endif int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) @@ -453,7 +423,7 @@ const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len) return os->data; } -#ifndef OPENSSL_NO_POLY1305 +# ifndef OPENSSL_NO_POLY1305 const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len) { ASN1_OCTET_STRING *os = NULL; @@ -465,9 +435,9 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len) *len = os->length; return os->data; } -#endif +# endif -#ifndef OPENSSL_NO_SIPHASH +# ifndef OPENSSL_NO_SIPHASH const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len) { ASN1_OCTET_STRING *os = NULL; @@ -480,9 +450,9 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len) *len = os->length; return os->data; } -#endif +# endif -#ifndef OPENSSL_NO_RSA +# ifndef OPENSSL_NO_RSA int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { int ret = EVP_PKEY_assign_RSA(pkey, key); @@ -493,7 +463,7 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_RSA) { + if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) { EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } @@ -507,9 +477,9 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) RSA_up_ref(ret); return ret; } -#endif +# endif -#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_DSA int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { int ret = EVP_PKEY_assign_DSA(pkey, key); @@ -534,9 +504,9 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) DSA_up_ref(ret); return ret; } -#endif +# endif -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { @@ -562,13 +532,15 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) EC_KEY_up_ref(ret); return ret; } -#endif +# endif -#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_DH int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { - int ret = EVP_PKEY_assign_DH(pkey, key); + int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX; + int ret = EVP_PKEY_assign(pkey, type, key); + if (ret) DH_up_ref(key); return ret; @@ -590,7 +562,7 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) DH_up_ref(ret); return ret; } -#endif +# endif int EVP_PKEY_type(int type) { @@ -602,9 +574,9 @@ int EVP_PKEY_type(int type) ret = ameth->pkey_id; else ret = NID_undef; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE ENGINE_finish(e); -#endif +# endif return ret; } @@ -618,75 +590,104 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey) return EVP_PKEY_type(pkey->type); } -void EVP_PKEY_free(EVP_PKEY *x) + +static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent) { - int i; + BIO_set_indent(*out, saved_indent); + if (pop_f_prefix) { + BIO *next = BIO_pop(*out); - if (x == NULL) - return; - - CRYPTO_DOWN_REF(&x->references, &i, x->lock); - REF_PRINT_COUNT("EVP_PKEY", x); - if (i > 0) - return; - REF_ASSERT_ISNT(i < 0); - EVP_PKEY_free_it(x); - CRYPTO_THREAD_lock_free(x->lock); - sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); - OPENSSL_free(x); + BIO_free(*out); + *out = next; + } + return 1; } -static void EVP_PKEY_free_it(EVP_PKEY *x) +static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent, + long indent) { - /* internal function; x is never NULL */ + *pop_f_prefix = 0; + *saved_indent = 0; + if (indent > 0) { + long i = BIO_get_indent(*out); - evp_keymgmt_clear_pkey_cache(x); - - if (x->ameth && x->ameth->pkey_free) { - x->ameth->pkey_free(x); - x->pkey.ptr = NULL; + *saved_indent = (i < 0 ? 0 : i); + if (BIO_set_indent(*out, indent) <= 0) { + if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL) + return 0; + *pop_f_prefix = 1; + } + if (BIO_set_indent(*out, indent) <= 0) { + print_reset_indent(out, *pop_f_prefix, *saved_indent); + return 0; + } } -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(x->engine); - x->engine = NULL; - ENGINE_finish(x->pmeth_engine); - x->pmeth_engine = NULL; -#endif + return 1; } static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr) { - BIO_indent(out, indent, 128); - BIO_printf(out, "%s algorithm \"%s\" unsupported\n", - kstr, OBJ_nid2ln(pkey->type)); - return 1; + return BIO_indent(out, indent, 128) + && BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)) > 0; +} + +static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent, + const char *propquery /* For provided serialization */, + int (*legacy_print)(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + ASN1_PCTX *legacy_pctx /* For legacy print */) +{ + int pop_f_prefix; + long saved_indent; + OSSL_SERIALIZER_CTX *ctx = NULL; + int ret = -2; /* default to unsupported */ + + if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent)) + return 0; + + ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery); + if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) + ret = OSSL_SERIALIZER_to_bio(ctx, out); + OSSL_SERIALIZER_CTX_free(ctx); + + if (ret != -2) + goto end; + + /* legacy fallback */ + if (legacy_print != NULL) + ret = legacy_print(out, pkey, 0, legacy_pctx); + else + ret = unsup_alg(out, pkey, 0, "Public Key"); + + end: + print_reset_indent(&out, pop_f_prefix, saved_indent); + return ret; } int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->pub_print) - return pkey->ameth->pub_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Public Key"); + return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ, + (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL), + pctx); } int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->priv_print) - return pkey->ameth->priv_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Private Key"); + return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ, + (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL), + pctx); } int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->param_print) - return pkey->ameth->param_print(out, pkey, indent, pctx); - return unsup_alg(out, pkey, indent, "Parameters"); + return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ, + (pkey->ameth != NULL ? pkey->ameth->param_print : NULL), + pctx); } static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2) @@ -740,3 +741,89 @@ size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) return 0; return rv; } + +#endif /* FIPS_MODE */ + +/*- All methods below can also be used in FIPS_MODE */ + +EVP_PKEY *EVP_PKEY_new(void) +{ + EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) { + EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->type = EVP_PKEY_NONE; + ret->save_type = EVP_PKEY_NONE; + ret->references = 1; + ret->save_parameters = 1; + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + return ret; +} + +int EVP_PKEY_up_ref(EVP_PKEY *pkey) +{ + int i; + + if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0) + return 0; + + REF_PRINT_COUNT("EVP_PKEY", pkey); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + +static void evp_pkey_free_it(EVP_PKEY *x) +{ + /* internal function; x is never NULL */ + + evp_keymgmt_clear_pkey_cache(x); + + if (x->ameth && x->ameth->pkey_free) { + x->ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) + ENGINE_finish(x->engine); + x->engine = NULL; + ENGINE_finish(x->pmeth_engine); + x->pmeth_engine = NULL; +#endif +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + CRYPTO_DOWN_REF(&x->references, &i, x->lock); + REF_PRINT_COUNT("EVP_PKEY", x); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + evp_pkey_free_it(x); + CRYPTO_THREAD_lock_free(x->lock); +#ifndef FIPS_MODE + sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); +#endif + OPENSSL_free(x); +} + +int EVP_PKEY_size(const EVP_PKEY *pkey) +{ + if (pkey != NULL) { + if (pkey->ameth == NULL) + return pkey->cache.size; + else if (pkey->ameth->pkey_size != NULL) + return pkey->ameth->pkey_size(pkey); + } + return 0; +} diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c index d06edb21..aa226fcc 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/pmeth_fn.c @@ -16,341 +16,11 @@ #include "internal/provider.h" #include "evp_local.h" -static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov) -{ - EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE)); - - signature->lock = CRYPTO_THREAD_lock_new(); - if (signature->lock == NULL) { - OPENSSL_free(signature); - return NULL; - } - signature->prov = prov; - ossl_provider_up_ref(prov); - signature->refcnt = 1; - - return signature; -} - -static void *evp_signature_from_dispatch(int name_id, - const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov, - void *vkeymgmt_data) -{ - /* - * Signature functions cannot work without a key, and key management - * from the same provider to manage its keys. We therefore fetch - * a key management method using the same algorithm and properties - * and pass that down to evp_generic_fetch to be passed on to our - * evp_signature_from_dispatch, which will attach the key management - * method to the newly created key exchange method as long as the - * provider matches. - */ - struct keymgmt_data_st *keymgmt_data = vkeymgmt_data; - EVP_KEYMGMT *keymgmt = - evp_keymgmt_fetch_by_number(keymgmt_data->ctx, name_id, - keymgmt_data->properties); - EVP_SIGNATURE *signature = NULL; - int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0; - int digsignfncnt = 0, digverifyfncnt = 0; - int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0; - - if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) { - ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE); - goto err; - } - - if ((signature = evp_signature_new(prov)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - goto err; - } - - signature->name_id = name_id; - signature->keymgmt = keymgmt; - keymgmt = NULL; /* avoid double free on failure below */ - - for (; fns->function_id != 0; fns++) { - switch (fns->function_id) { - case OSSL_FUNC_SIGNATURE_NEWCTX: - if (signature->newctx != NULL) - break; - signature->newctx = OSSL_get_OP_signature_newctx(fns); - ctxfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SIGN_INIT: - if (signature->sign_init != NULL) - break; - signature->sign_init = OSSL_get_OP_signature_sign_init(fns); - signfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SIGN: - if (signature->sign != NULL) - break; - signature->sign = OSSL_get_OP_signature_sign(fns); - signfncnt++; - break; - case OSSL_FUNC_SIGNATURE_VERIFY_INIT: - if (signature->verify_init != NULL) - break; - signature->verify_init = OSSL_get_OP_signature_verify_init(fns); - verifyfncnt++; - break; - case OSSL_FUNC_SIGNATURE_VERIFY: - if (signature->verify != NULL) - break; - signature->verify = OSSL_get_OP_signature_verify(fns); - verifyfncnt++; - break; - case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT: - if (signature->verify_recover_init != NULL) - break; - signature->verify_recover_init - = OSSL_get_OP_signature_verify_recover_init(fns); - verifyrecfncnt++; - break; - case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER: - if (signature->verify_recover != NULL) - break; - signature->verify_recover - = OSSL_get_OP_signature_verify_recover(fns); - verifyrecfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT: - if (signature->digest_sign_init != NULL) - break; - signature->digest_sign_init - = OSSL_get_OP_signature_digest_sign_init(fns); - digsignfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE: - if (signature->digest_sign_update != NULL) - break; - signature->digest_sign_update - = OSSL_get_OP_signature_digest_sign_update(fns); - digsignfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL: - if (signature->digest_sign_final != NULL) - break; - signature->digest_sign_final - = OSSL_get_OP_signature_digest_sign_final(fns); - digsignfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT: - if (signature->digest_verify_init != NULL) - break; - signature->digest_verify_init - = OSSL_get_OP_signature_digest_verify_init(fns); - digverifyfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE: - if (signature->digest_verify_update != NULL) - break; - signature->digest_verify_update - = OSSL_get_OP_signature_digest_verify_update(fns); - digverifyfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL: - if (signature->digest_verify_final != NULL) - break; - signature->digest_verify_final - = OSSL_get_OP_signature_digest_verify_final(fns); - digverifyfncnt++; - break; - case OSSL_FUNC_SIGNATURE_FREECTX: - if (signature->freectx != NULL) - break; - signature->freectx = OSSL_get_OP_signature_freectx(fns); - ctxfncnt++; - break; - case OSSL_FUNC_SIGNATURE_DUPCTX: - if (signature->dupctx != NULL) - break; - signature->dupctx = OSSL_get_OP_signature_dupctx(fns); - break; - case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS: - if (signature->get_ctx_params != NULL) - break; - signature->get_ctx_params - = OSSL_get_OP_signature_get_ctx_params(fns); - gparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS: - if (signature->gettable_ctx_params != NULL) - break; - signature->gettable_ctx_params - = OSSL_get_OP_signature_gettable_ctx_params(fns); - gparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS: - if (signature->set_ctx_params != NULL) - break; - signature->set_ctx_params - = OSSL_get_OP_signature_set_ctx_params(fns); - sparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS: - if (signature->settable_ctx_params != NULL) - break; - signature->settable_ctx_params - = OSSL_get_OP_signature_settable_ctx_params(fns); - sparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS: - if (signature->get_ctx_md_params != NULL) - break; - signature->get_ctx_md_params - = OSSL_get_OP_signature_get_ctx_md_params(fns); - gmdparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS: - if (signature->gettable_ctx_md_params != NULL) - break; - signature->gettable_ctx_md_params - = OSSL_get_OP_signature_gettable_ctx_md_params(fns); - gmdparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS: - if (signature->set_ctx_md_params != NULL) - break; - signature->set_ctx_md_params - = OSSL_get_OP_signature_set_ctx_md_params(fns); - smdparamfncnt++; - break; - case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS: - if (signature->settable_ctx_md_params != NULL) - break; - signature->settable_ctx_md_params - = OSSL_get_OP_signature_settable_ctx_md_params(fns); - smdparamfncnt++; - break; - } - } - if (ctxfncnt != 2 - || (signfncnt == 0 - && verifyfncnt == 0 - && verifyrecfncnt == 0 - && digsignfncnt == 0 - && digverifyfncnt == 0) - || (signfncnt != 0 && signfncnt != 2) - || (verifyfncnt != 0 && verifyfncnt != 2) - || (verifyrecfncnt != 0 && verifyrecfncnt != 2) - || (digsignfncnt != 0 && digsignfncnt != 3) - || (digverifyfncnt != 0 && digverifyfncnt != 3) - || (gparamfncnt != 0 && gparamfncnt != 2) - || (sparamfncnt != 0 && sparamfncnt != 2) - || (gmdparamfncnt != 0 && gmdparamfncnt != 2) - || (smdparamfncnt != 0 && smdparamfncnt != 2)) { - /* - * In order to be a consistent set of functions we must have at least - * a set of context functions (newctx and freectx) as well as a set of - * "signature" functions: - * (sign_init, sign) or - * (verify_init verify) or - * (verify_recover_init, verify_recover) or - * (digest_sign_init, digest_sign_update, digest_sign_final) or - * (digest_verify_init, digest_verify_update, digest_verify_final). - * - * set_ctx_params and settable_ctx_params are optional, but if one of - * them is present then the other one must also be present. The same - * applies to get_ctx_params and gettable_ctx_params. The same rules - * apply to the "md_params" functions. The dupctx function is optional. - */ - ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); - goto err; - } - - return signature; - err: - EVP_SIGNATURE_free(signature); - EVP_KEYMGMT_free(keymgmt); - return NULL; -} - -void EVP_SIGNATURE_free(EVP_SIGNATURE *signature) -{ - if (signature != NULL) { - int i; - - CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock); - if (i > 0) - return; - EVP_KEYMGMT_free(signature->keymgmt); - ossl_provider_free(signature->prov); - CRYPTO_THREAD_lock_free(signature->lock); - OPENSSL_free(signature); - } -} - -int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature) -{ - int ref = 0; - - CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock); - return 1; -} - -OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature) -{ - return signature->prov; -} - -EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm, - const char *properties) -{ - struct keymgmt_data_st keymgmt_data; - - /* - * A signature operation cannot work without a key, so we need key - * management from the same provider to manage its keys. - */ - keymgmt_data.ctx = ctx; - keymgmt_data.properties = properties; - return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties, - evp_signature_from_dispatch, &keymgmt_data, - (int (*)(void *))EVP_SIGNATURE_up_ref, - (void (*)(void *))EVP_SIGNATURE_free); -} - -int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name) -{ - return evp_is_a(signature->prov, signature->name_id, name); -} - -int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature) -{ - return signature->name_id; -} - -void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(EVP_SIGNATURE *signature, - void *arg), - void *arg) -{ - struct keymgmt_data_st keymgmt_data; - - keymgmt_data.ctx = libctx; - keymgmt_data.properties = NULL; - evp_generic_do_all(libctx, OSSL_OP_SIGNATURE, - (void (*)(void *, void *))fn, arg, - evp_signature_from_dispatch, &keymgmt_data, - (void (*)(void *))EVP_SIGNATURE_free); -} - - -void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature, - void (*fn)(const char *name, void *data), - void *data) -{ - if (signature->prov != NULL) - evp_names_do_all(signature->prov, signature->name_id, fn, data); -} - -static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature, - int operation) +static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation) { int ret = 0; void *provkey = NULL; + EVP_ASYM_CIPHER *cipher = NULL; if (ctx == NULL) { EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -360,77 +30,79 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature, evp_pkey_ctx_free_old_ops(ctx); ctx->operation = operation; - if (ctx->engine != NULL) + if (ctx->keytype == NULL || ctx->engine != NULL) goto legacy; - if (signature != NULL) { - if (!EVP_SIGNATURE_up_ref(signature)) - goto err; - } else { - int nid = ctx->pkey != NULL ? ctx->pkey->type : ctx->pmeth->pkey_id; + if (ctx->keymgmt == NULL) + ctx->keymgmt = + EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery); + if (ctx->keymgmt != NULL) { + const char *supported_ciph = NULL; + + if (ctx->keymgmt->query_operation_name != NULL) + supported_ciph = + ctx->keymgmt->query_operation_name(OSSL_OP_ASYM_CIPHER); /* - * TODO(3.0): Check for legacy handling. Remove this once all all - * algorithms are moved to providers. + * If we didn't get a supported ciph, assume there is one with the + * same name as the key type. */ - if (ctx->pkey != NULL) { - switch (ctx->pkey->type) { - case NID_dsa: - break; - default: - goto legacy; - } - signature = EVP_SIGNATURE_fetch(NULL, OBJ_nid2sn(nid), NULL); - } else { - goto legacy; - } + if (supported_ciph == NULL) + supported_ciph = ctx->keytype; - if (signature == NULL) { - EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; - } + /* + * Because we cleared out old ops, we shouldn't need to worry about + * checking if cipher is already there. + */ + cipher = + EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, ctx->propquery); } - ctx->op.sig.signature = signature; + if (ctx->keymgmt == NULL + || cipher == NULL + || (EVP_KEYMGMT_provider(ctx->keymgmt) + != EVP_ASYM_CIPHER_provider(cipher))) { + /* + * We don't have the full support we need with provided methods, + * let's go see if legacy does. Also, we don't need to free + * ctx->keymgmt here, as it's not necessarily tied to this + * operation. It will be freed by EVP_PKEY_CTX_free(). + */ + EVP_ASYM_CIPHER_free(cipher); + goto legacy; + } + + ctx->op.ciph.cipher = cipher; + if (ctx->pkey != NULL) { - provkey = - evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt, 0); - if (provkey == NULL) { - EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; - } + provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; } - ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov)); - if (ctx->op.sig.sigprovctx == NULL) { + ctx->op.ciph.ciphprovctx = cipher->newctx(ossl_provider_ctx(cipher->prov)); + if (ctx->op.ciph.ciphprovctx == NULL) { /* The provider key can stay in the cache */ EVPerr(0, EVP_R_INITIALIZATION_ERROR); goto err; } switch (operation) { - case EVP_PKEY_OP_SIGN: - if (signature->sign_init == NULL) { + case EVP_PKEY_OP_ENCRYPT: + if (cipher->encrypt_init == NULL) { EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = signature->sign_init(ctx->op.sig.sigprovctx, provkey); + ret = cipher->encrypt_init(ctx->op.ciph.ciphprovctx, provkey); break; - case EVP_PKEY_OP_VERIFY: - if (signature->verify_init == NULL) { + case EVP_PKEY_OP_DECRYPT: + if (cipher->decrypt_init == NULL) { EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = signature->verify_init(ctx->op.sig.sigprovctx, provkey); - break; - case EVP_PKEY_OP_VERIFYRECOVER: - if (signature->verify_recover_init == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - ret = -2; - goto err; - } - ret = signature->verify_recover_init(ctx->op.sig.sigprovctx, provkey); + ret = cipher->decrypt_init(ctx->op.ciph.ciphprovctx, provkey); break; default: EVPerr(0, EVP_R_INITIALIZATION_ERROR); @@ -438,244 +110,314 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature, } if (ret <= 0) { - signature->freectx(ctx->op.sig.sigprovctx); - ctx->op.sig.sigprovctx = NULL; + cipher->freectx(ctx->op.ciph.ciphprovctx); + ctx->op.ciph.ciphprovctx = NULL; goto err; } return 1; legacy: - if (ctx->pmeth == NULL - || (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL) - || (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL) - || (operation == EVP_PKEY_OP_VERIFYRECOVER - && ctx->pmeth->verify_recover == NULL)) { + if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } - - switch (operation) { - case EVP_PKEY_OP_SIGN: - if (ctx->pmeth->sign_init == NULL) + switch(ctx->operation) { + case EVP_PKEY_OP_ENCRYPT: + if (ctx->pmeth->encrypt_init == NULL) return 1; - ret = ctx->pmeth->sign_init(ctx); + ret = ctx->pmeth->encrypt_init(ctx); break; - case EVP_PKEY_OP_VERIFY: - if (ctx->pmeth->verify_init == NULL) + case EVP_PKEY_OP_DECRYPT: + if (ctx->pmeth->decrypt_init == NULL) return 1; - ret = ctx->pmeth->verify_init(ctx); - break; - case EVP_PKEY_OP_VERIFYRECOVER: - if (ctx->pmeth->verify_recover_init == NULL) - return 1; - ret = ctx->pmeth->verify_recover_init(ctx); + ret = ctx->pmeth->decrypt_init(ctx); break; default: EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; + ret = -1; } - if (ret <= 0) - goto err; - return ret; err: - ctx->operation = EVP_PKEY_OP_UNDEFINED; + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; return ret; } -int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature) -{ - return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_SIGN); -} - -int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) -{ - return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_SIGN); -} - -int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret; - - if (ctx == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - if (ctx->operation != EVP_PKEY_OP_SIGN) { - EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - if (ctx->op.sig.sigprovctx == NULL) - goto legacy; - - ret = ctx->op.sig.signature->sign(ctx->op.sig.sigprovctx, sig, siglen, - SIZE_MAX, tbs, tbslen); - - return ret; - legacy: - - if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) - return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature) -{ - return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_VERIFY); -} - -int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) -{ - return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_VERIFY); -} - -int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret; - - if (ctx == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - if (ctx->operation != EVP_PKEY_OP_VERIFY) { - EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - if (ctx->op.sig.sigprovctx == NULL) - goto legacy; - - ret = ctx->op.sig.signature->verify(ctx->op.sig.sigprovctx, sig, siglen, - tbs, tbslen); - - return ret; - legacy: - if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature) -{ - return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_VERIFYRECOVER); -} - -int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) -{ - return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_VERIFYRECOVER); -} - -int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen) -{ - int ret; - - if (ctx == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { - EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - if (ctx->op.sig.sigprovctx == NULL) - goto legacy; - - ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.sigprovctx, rout, - routlen, - (rout == NULL ? 0 : *routlen), - sig, siglen); - return ret; - legacy: - if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) { - EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) - return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); -} - int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_ENCRYPT; - if (!ctx->pmeth->encrypt_init) - return 1; - ret = ctx->pmeth->encrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT); } int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + int ret; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.ciph.ciphprovctx == NULL) + goto legacy; + + ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.ciphprovctx, out, outlen, + (out == NULL ? 0 : *outlen), in, inlen); + return ret; + + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } - if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); } int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DECRYPT; - if (!ctx->pmeth->decrypt_init) - return 1; - ret = ctx->pmeth->decrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT); } int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + int ret; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.ciph.ciphprovctx == NULL) + goto legacy; + + ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.ciphprovctx, out, outlen, + (out == NULL ? 0 : *outlen), in, inlen); + return ret; + + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) { EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } - if (ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); } + + +static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) +{ + EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER)); + + if (cipher == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + cipher->lock = CRYPTO_THREAD_lock_new(); + if (cipher->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(cipher); + return NULL; + } + cipher->prov = prov; + ossl_provider_up_ref(prov); + cipher->refcnt = 1; + + return cipher; +} + +static void *evp_asym_cipher_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) +{ + EVP_ASYM_CIPHER *cipher = NULL; + int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0; + + if ((cipher = evp_asym_cipher_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + cipher->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_ASYM_CIPHER_NEWCTX: + if (cipher->newctx != NULL) + break; + cipher->newctx = OSSL_get_OP_asym_cipher_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT: + if (cipher->encrypt_init != NULL) + break; + cipher->encrypt_init = OSSL_get_OP_asym_cipher_encrypt_init(fns); + encfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_ENCRYPT: + if (cipher->encrypt != NULL) + break; + cipher->encrypt = OSSL_get_OP_asym_cipher_encrypt(fns); + encfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT: + if (cipher->decrypt_init != NULL) + break; + cipher->decrypt_init = OSSL_get_OP_asym_cipher_decrypt_init(fns); + decfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DECRYPT: + if (cipher->decrypt != NULL) + break; + cipher->decrypt = OSSL_get_OP_asym_cipher_decrypt(fns); + decfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_FREECTX: + if (cipher->freectx != NULL) + break; + cipher->freectx = OSSL_get_OP_asym_cipher_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DUPCTX: + if (cipher->dupctx != NULL) + break; + cipher->dupctx = OSSL_get_OP_asym_cipher_dupctx(fns); + break; + case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS: + if (cipher->get_ctx_params != NULL) + break; + cipher->get_ctx_params + = OSSL_get_OP_asym_cipher_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS: + if (cipher->gettable_ctx_params != NULL) + break; + cipher->gettable_ctx_params + = OSSL_get_OP_asym_cipher_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS: + if (cipher->set_ctx_params != NULL) + break; + cipher->set_ctx_params + = OSSL_get_OP_asym_cipher_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS: + if (cipher->settable_ctx_params != NULL) + break; + cipher->settable_ctx_params + = OSSL_get_OP_asym_cipher_settable_ctx_params(fns); + sparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (encfncnt != 0 && encfncnt != 2) + || (decfncnt != 0 && decfncnt != 2) + || (encfncnt != 2 && decfncnt != 2) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a pair of + * "cipher" functions: (encrypt_init, encrypt) or + * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are + * optional, but if one of them is present then the other one must also + * be present. The same applies to get_ctx_params and + * gettable_ctx_params. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return cipher; + err: + EVP_ASYM_CIPHER_free(cipher); + return NULL; +} + +void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher) +{ + if (cipher != NULL) { + int i; + + CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + if (i > 0) + return; + ossl_provider_free(cipher->prov); + CRYPTO_THREAD_lock_free(cipher->lock); + OPENSSL_free(cipher); + } +} + +int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher) +{ + int ref = 0; + + CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + return 1; +} + +OSSL_PROVIDER *EVP_ASYM_CIPHER_provider(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->prov; +} + +EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties, + evp_asym_cipher_from_dispatch, + (int (*)(void *))EVP_ASYM_CIPHER_up_ref, + (void (*)(void *))EVP_ASYM_CIPHER_free); +} + +int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name) +{ + return evp_is_a(cipher->prov, cipher->name_id, NULL, name); +} + +int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->name_id; +} + +void EVP_ASYM_CIPHER_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(EVP_ASYM_CIPHER *cipher, + void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER, + (void (*)(void *, void *))fn, arg, + evp_asym_cipher_from_dispatch, + (void (*)(void *))EVP_ASYM_CIPHER_free); +} + + +void EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, + void (*fn)(const char *name, void *data), + void *data) +{ + if (cipher->prov != NULL) + evp_names_do_all(cipher->prov, cipher->name_id, fn, data); +} + diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 2564bbd0..14c5fd4b 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -15,7 +15,9 @@ #include "crypto/bn.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "evp_local.h" +#ifndef FIPS_MODE int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { int ret; @@ -237,3 +239,93 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) return pkey->ameth->pkey_param_check(pkey); } + +#endif /* FIPS_MODE */ + +/*- All methods below can also be used in FIPS_MODE */ + +static int fromdata_init(EVP_PKEY_CTX *ctx, int operation) +{ + if (ctx == NULL || ctx->keytype == NULL) + goto not_supported; + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + if (ctx->keymgmt == NULL) + ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, + ctx->propquery); + if (ctx->keymgmt == NULL) + goto not_supported; + + return 1; + + not_supported: + ctx->operation = EVP_PKEY_OP_UNDEFINED; + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} + +int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx) +{ + return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA); +} + +int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx) +{ + return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA); +} + +int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]) +{ + void *provdata = NULL; + + if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ppkey == NULL) + return -1; + + if (*ppkey == NULL) + *ppkey = EVP_PKEY_new(); + + if (*ppkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return -1; + } + + provdata = + evp_keymgmt_fromdata(*ppkey, ctx->keymgmt, params, + ctx->operation == EVP_PKEY_OP_PARAMFROMDATA); + + if (provdata == NULL) + return 0; + /* provdata is cached in *ppkey, so we need not bother with it further */ + return 1; +} + +/* + * TODO(3.0) Re-evaluate the names, it's possible that we find these to be + * better: + * + * EVP_PKEY_param_settable() + * EVP_PKEY_param_gettable() + */ +const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx) +{ + /* We call fromdata_init to get ctx->keymgmt populated */ + if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) + return evp_keymgmt_importdomparam_types(ctx->keymgmt); + return NULL; +} + +const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx) +{ + /* We call fromdata_init to get ctx->keymgmt populated */ + if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) + return evp_keymgmt_importdomparam_types(ctx->keymgmt); + return NULL; +} + + diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index c840a12b..24e2fdc9 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "internal/cryptlib.h" #include "crypto/asn1.h" #include "crypto/evp.h" @@ -22,6 +23,8 @@ #include "internal/provider.h" #include "evp_local.h" +#ifndef FIPS_MODE + typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void); typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); @@ -29,50 +32,50 @@ static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; /* This array needs to be in order of NIDs */ static pmeth_fn standard_methods[] = { -#ifndef OPENSSL_NO_RSA +# ifndef OPENSSL_NO_RSA rsa_pkey_method, -#endif -#ifndef OPENSSL_NO_DH +# endif +# ifndef OPENSSL_NO_DH dh_pkey_method, -#endif -#ifndef OPENSSL_NO_DSA +# endif +# ifndef OPENSSL_NO_DSA dsa_pkey_method, -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC ec_pkey_method, -#endif +# endif hmac_pkey_method, -#ifndef OPENSSL_NO_CMAC +# ifndef OPENSSL_NO_CMAC cmac_pkey_method, -#endif -#ifndef OPENSSL_NO_RSA +# endif +# ifndef OPENSSL_NO_RSA rsa_pss_pkey_method, -#endif -#ifndef OPENSSL_NO_DH +# endif +# ifndef OPENSSL_NO_DH dhx_pkey_method, -#endif -#ifndef OPENSSL_NO_SCRYPT +# endif +# ifndef OPENSSL_NO_SCRYPT scrypt_pkey_method, -#endif +# endif tls1_prf_pkey_method, -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC ecx25519_pkey_method, ecx448_pkey_method, -#endif +# endif hkdf_pkey_method, -#ifndef OPENSSL_NO_POLY1305 +# ifndef OPENSSL_NO_POLY1305 poly1305_pkey_method, -#endif -#ifndef OPENSSL_NO_SIPHASH +# endif +# ifndef OPENSSL_NO_SIPHASH siphash_pkey_method, -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC ed25519_pkey_method, ed448_pkey_method, -#endif -#ifndef OPENSSL_NO_SM2 +# endif +# ifndef OPENSSL_NO_SM2 sm2_pkey_method, -#endif +# endif }; DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func); @@ -111,9 +114,27 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) return (**ret)(); } -static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + + pmeth = OPENSSL_zalloc(sizeof(*pmeth)); + if (pmeth == NULL) { + EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + return pmeth; +} +#endif /* FIPS_MODE */ + +static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, + EVP_PKEY *pkey, ENGINE *e, const char *name, const char *propquery, int id) + { EVP_PKEY_CTX *ret; const EVP_PKEY_METHOD *pmeth = NULL; @@ -125,16 +146,59 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, if (pkey == NULL && e == NULL && id == -1) goto common; + /* + * If the key doesn't contain anything legacy, then it must be provided, + * so we extract the necessary information and use that. + */ + if (pkey != NULL && pkey->ameth == NULL) { + /* If we have an engine, something went wrong somewhere... */ + if (!ossl_assert(e == NULL)) + return NULL; + name = evp_first_name(pkey->pkeys[0].keymgmt->prov, + pkey->pkeys[0].keymgmt->name_id); + /* + * TODO: I wonder if the EVP_PKEY should have the name and propquery + * that were used when building it.... /RL + */ + goto common; + } +#ifndef FIPS_MODE /* TODO(3.0) Legacy code should be removed when all is provider based */ /* BEGIN legacy */ if (id == -1) { if (pkey == NULL) - return 0; + return NULL; id = pkey->type; } - name = OBJ_nid2sn(id); + + /* + * Here, we extract what information we can for the purpose of + * supporting usage with implementations from providers, to make + * for a smooth transition from legacy stuff to provider based stuff. + * + * If an engine is given, this is entirely legacy, and we should not + * pretend anything else, so we only set the name when no engine is + * given. If both are already given, someone made a mistake, and + * since that can only happen internally, it's safe to make an + * assertion. + */ + if (!ossl_assert(e == NULL || name == NULL)) + return NULL; + if (e == NULL) + name = OBJ_nid2sn(id); propquery = NULL; -#ifndef OPENSSL_NO_ENGINE + /* + * We were called using legacy data, or an EVP_PKEY, but an EVP_PKEY + * isn't tied to a specific library context, so we fall back to the + * default library context. + * TODO(v3.0): an EVP_PKEY that doesn't originate from a leagacy key + * structure only has the pkeys[] cache, where the first element is + * considered the "origin". Investigate if that could be a suitable + * way to find a library context. + */ + libctx = NULL; + +# ifndef OPENSSL_NO_ENGINE if (e == NULL && pkey != NULL) e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine; /* Try to find an ENGINE which implements this method */ @@ -154,28 +218,29 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, if (e) pmeth = ENGINE_get_pkey_meth(e, id); else -#endif +# endif pmeth = EVP_PKEY_meth_find(id); if (pmeth == NULL) { -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE ENGINE_finish(e); -#endif +# endif EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); return NULL; } /* END legacy */ - +#endif /* FIPS_MODE */ common: ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ENGINE_finish(e); #endif EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } - ret->algorithm = name; + ret->libctx = libctx; + ret->keytype = name; ret->propquery = propquery; ret->engine = e; ret->pmeth = pmeth; @@ -195,34 +260,67 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, return ret; } +/*- All methods below can also be used in FIPS_MODE */ + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx, + const char *name, + const char *propquery) +{ + return int_ctx_new(libctx, NULL, NULL, name, propquery, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey) +{ + return int_ctx_new(libctx, pkey, NULL, NULL, NULL, -1); +} + void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) { - if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { - if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL) - ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx); - EVP_KEYEXCH_free(ctx->op.kex.exchange); - } else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { if (ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL) ctx->op.sig.signature->freectx(ctx->op.sig.sigprovctx); EVP_SIGNATURE_free(ctx->op.sig.signature); + ctx->op.sig.sigprovctx = NULL; + ctx->op.sig.signature = NULL; } +/* TODO(3.0): add dependancies and uncomment this when available for fips mode */ +#ifndef FIPS_MODE + else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL) + ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx); + EVP_KEYEXCH_free(ctx->op.kex.exchange); + ctx->op.kex.exchprovctx = NULL; + ctx->op.kex.exchange = NULL; + } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL) + ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx); + EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher); + ctx->op.ciph.ciphprovctx = NULL; + ctx->op.ciph.cipher = NULL; + } +#endif } -EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { - EVP_PKEY_METHOD *pmeth; + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); - pmeth = OPENSSL_zalloc(sizeof(*pmeth)); - if (pmeth == NULL) { - EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } + evp_pkey_ctx_free_old_ops(ctx); + EVP_KEYMGMT_free(ctx->keymgmt); - pmeth->pkey_id = id; - pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; - return pmeth; + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) + ENGINE_finish(ctx->engine); +#endif + OPENSSL_free(ctx); } +#ifndef FIPS_MODE + void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth) { @@ -283,19 +381,14 @@ void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { - return int_ctx_new(pkey, e, NULL, NULL, -1); + return int_ctx_new(NULL, pkey, e, NULL, NULL, -1); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - return int_ctx_new(NULL, e, NULL, NULL, id); + return int_ctx_new(NULL, NULL, e, NULL, NULL, id); } -EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name, - const char *propquery) -{ - return int_ctx_new(NULL, NULL, name, propquery, -1); -} EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) { @@ -307,13 +400,13 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) || (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx) && pctx->op.sig.sigprovctx == NULL))) return NULL; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a pkey context using an ENGINE */ if (pctx->engine && !ENGINE_init(pctx->engine)) { EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); return 0; } -#endif +# endif rctx = OPENSSL_zalloc(sizeof(*rctx)); if (rctx == NULL) { EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE); @@ -324,7 +417,8 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) EVP_PKEY_up_ref(pctx->pkey); rctx->pkey = pctx->pkey; rctx->operation = pctx->operation; - rctx->algorithm = pctx->algorithm; + rctx->libctx = pctx->libctx; + rctx->keytype = pctx->keytype; rctx->propquery = pctx->propquery; if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) { @@ -367,12 +461,32 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) } return rctx; } + } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(pctx)) { + if (pctx->op.ciph.cipher != NULL) { + rctx->op.ciph.cipher = pctx->op.ciph.cipher; + if (!EVP_ASYM_CIPHER_up_ref(rctx->op.ciph.cipher)) { + OPENSSL_free(rctx); + return NULL; + } + } + if (pctx->op.ciph.ciphprovctx != NULL) { + if (!ossl_assert(pctx->op.ciph.cipher != NULL)) + return NULL; + rctx->op.ciph.ciphprovctx + = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.ciphprovctx); + if (rctx->op.ciph.ciphprovctx == NULL) { + EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher); + OPENSSL_free(rctx); + return NULL; + } + return rctx; + } } rctx->pmeth = pctx->pmeth; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE rctx->engine = pctx->engine; -#endif +# endif if (pctx->peerkey) EVP_PKEY_up_ref(pctx->peerkey); @@ -439,44 +553,7 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx) return NULL; return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); } - -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) -{ - if (ctx == NULL) - return; - if (ctx->pmeth && ctx->pmeth->cleanup) - ctx->pmeth->cleanup(ctx); - - evp_pkey_ctx_free_old_ops(ctx); - - EVP_PKEY_free(ctx->pkey); - EVP_PKEY_free(ctx->peerkey); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(ctx->engine); #endif - OPENSSL_free(ctx); -} - -int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) -{ - if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL - && ctx->op.sig.signature != NULL - && ctx->op.sig.signature->get_ctx_params != NULL) - return ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx, - params); - return 0; -} - -const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx) -{ - if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.signature != NULL - && ctx->op.sig.signature->gettable_ctx_params != NULL) - return ctx->op.sig.signature->gettable_ctx_params(); - - return NULL; -} int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) { @@ -492,9 +569,48 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) && ctx->op.sig.signature->set_ctx_params != NULL) return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx, params); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->set_ctx_params != NULL) + return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx, + params); return 0; } +#ifndef FIPS_MODE +int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx != NULL + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->get_ctx_params != NULL) + return ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx, + params); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->get_ctx_params != NULL) + return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx, + params); + return 0; +} + +const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx) +{ + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->gettable_ctx_params != NULL) + return ctx->op.sig.signature->gettable_ctx_params(); + + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->gettable_ctx_params != NULL) + return ctx->op.ciph.cipher->gettable_ctx_params(); + + return NULL; +} + const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) { if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) @@ -505,11 +621,15 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) && ctx->op.sig.signature != NULL && ctx->op.sig.signature->settable_ctx_params != NULL) return ctx->op.sig.signature->settable_ctx_params(); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->settable_ctx_params != NULL) + return ctx->op.ciph.cipher->settable_ctx_params(); return NULL; } -#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_DH int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) { OSSL_PARAM dh_pad_params[2]; @@ -531,7 +651,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) return EVP_PKEY_CTX_set_params(ctx, dh_pad_params); } -#endif +# endif int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) { @@ -559,7 +679,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params)) return 0; - tmp = EVP_get_digestbyname(name); + tmp = evp_get_digestbyname_ex(ctx->libctx, name); if (tmp == NULL) return 0; @@ -611,14 +731,41 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { switch (cmd) { -#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_DH case EVP_PKEY_CTRL_DH_PAD: return EVP_PKEY_CTX_set_dh_pad(ctx, p1); -#endif +# endif case EVP_PKEY_CTRL_MD: return EVP_PKEY_CTX_set_signature_md(ctx, p2); case EVP_PKEY_CTRL_GET_MD: return EVP_PKEY_CTX_get_signature_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_PADDING: + return EVP_PKEY_CTX_set_rsa_padding(ctx, p1); + case EVP_PKEY_CTRL_GET_RSA_PADDING: + return EVP_PKEY_CTX_get_rsa_padding(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_MGF1_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1); + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2); + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: +# ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: +# endif + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 1; + ERR_raise(ERR_LIB_EVP, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; } return 0; } @@ -634,8 +781,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, } if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL) - || (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL)) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx != NULL) + || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL)) return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2); if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) { @@ -677,14 +826,14 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, const char *value) { -#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_DH if (strcmp(name, "dh_pad") == 0) { int pad; pad = atoi(value); return EVP_PKEY_CTX_set_dh_pad(ctx, pad); } -#endif +# endif if (strcmp(name, "digest") == 0) { int ret; EVP_MD *md; @@ -700,6 +849,52 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, return ret; } + if (strcmp(name, "rsa_padding_mode") == 0) { + int pm; + + if (strcmp(value, "pkcs1") == 0) { + pm = RSA_PKCS1_PADDING; + } else if (strcmp(value, "sslv23") == 0) { + pm = RSA_SSLV23_PADDING; + } else if (strcmp(value, "none") == 0) { + pm = RSA_NO_PADDING; + } else if (strcmp(value, "oeap") == 0) { + pm = RSA_PKCS1_OAEP_PADDING; + } else if (strcmp(value, "oaep") == 0) { + pm = RSA_PKCS1_OAEP_PADDING; + } else if (strcmp(value, "x931") == 0) { + pm = RSA_X931_PADDING; + } else if (strcmp(value, "pss") == 0) { + pm = RSA_PKCS1_PSS_PADDING; + } else { + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (strcmp(name, "rsa_mgf1_md") == 0) + return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, value, NULL); + + if (strcmp(name, "rsa_oaep_md") == 0) + return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, value, NULL); + + if (strcmp(name, "rsa_oaep_label") == 0) { + unsigned char *lab; + long lablen; + int ret; + + lab = OPENSSL_hexstr2buf(value, &lablen); + if (lab == NULL) + return 0; + ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); + if (ret <= 0) + OPENSSL_free(lab); + return ret; + } + + + return 0; } @@ -713,7 +908,9 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL) || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL)) + && ctx->op.sig.sigprovctx != NULL) + || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL)) return legacy_ctrl_str_to_param(ctx, name, value); if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { @@ -951,6 +1148,21 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl_str = ctrl_str; } +void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth, + int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)) +{ + pmeth->digestsign = digestsign; +} + +void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth, + int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen)) +{ + pmeth->digestverify = digestverify; +} + void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, int (*check) (EVP_PKEY *pkey)) { @@ -1143,6 +1355,23 @@ void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, *pctrl_str = pmeth->ctrl_str; } +void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, + int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)) +{ + if (digestsign) + *digestsign = pmeth->digestsign; +} + +void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth, + int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen)) +{ + if (digestverify) + *digestverify = pmeth->digestverify; +} + void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey)) { @@ -1171,3 +1400,5 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, if (pdigest_custom != NULL) *pdigest_custom = pmeth->digest_custom; } + +#endif /* FIPS_MODE */ diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c new file mode 100644 index 00000000..1cef4649 --- /dev/null +++ b/crypto/evp/signature.c @@ -0,0 +1,580 @@ +/* + * Copyright 2006-2016 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 + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "crypto/evp.h" +#include "internal/provider.h" +#include "evp_local.h" + +static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov) +{ + EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE)); + + if (signature == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + signature->lock = CRYPTO_THREAD_lock_new(); + if (signature->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(signature); + return NULL; + } + signature->prov = prov; + ossl_provider_up_ref(prov); + signature->refcnt = 1; + + return signature; +} + +static void *evp_signature_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) +{ + EVP_SIGNATURE *signature = NULL; + int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0; + int digsignfncnt = 0, digverifyfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0; + + if ((signature = evp_signature_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + signature->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_SIGNATURE_NEWCTX: + if (signature->newctx != NULL) + break; + signature->newctx = OSSL_get_OP_signature_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SIGN_INIT: + if (signature->sign_init != NULL) + break; + signature->sign_init = OSSL_get_OP_signature_sign_init(fns); + signfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SIGN: + if (signature->sign != NULL) + break; + signature->sign = OSSL_get_OP_signature_sign(fns); + signfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_INIT: + if (signature->verify_init != NULL) + break; + signature->verify_init = OSSL_get_OP_signature_verify_init(fns); + verifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY: + if (signature->verify != NULL) + break; + signature->verify = OSSL_get_OP_signature_verify(fns); + verifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT: + if (signature->verify_recover_init != NULL) + break; + signature->verify_recover_init + = OSSL_get_OP_signature_verify_recover_init(fns); + verifyrecfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER: + if (signature->verify_recover != NULL) + break; + signature->verify_recover + = OSSL_get_OP_signature_verify_recover(fns); + verifyrecfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT: + if (signature->digest_sign_init != NULL) + break; + signature->digest_sign_init + = OSSL_get_OP_signature_digest_sign_init(fns); + digsignfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE: + if (signature->digest_sign_update != NULL) + break; + signature->digest_sign_update + = OSSL_get_OP_signature_digest_sign_update(fns); + digsignfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL: + if (signature->digest_sign_final != NULL) + break; + signature->digest_sign_final + = OSSL_get_OP_signature_digest_sign_final(fns); + digsignfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT: + if (signature->digest_verify_init != NULL) + break; + signature->digest_verify_init + = OSSL_get_OP_signature_digest_verify_init(fns); + digverifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE: + if (signature->digest_verify_update != NULL) + break; + signature->digest_verify_update + = OSSL_get_OP_signature_digest_verify_update(fns); + digverifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL: + if (signature->digest_verify_final != NULL) + break; + signature->digest_verify_final + = OSSL_get_OP_signature_digest_verify_final(fns); + digverifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_FREECTX: + if (signature->freectx != NULL) + break; + signature->freectx = OSSL_get_OP_signature_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DUPCTX: + if (signature->dupctx != NULL) + break; + signature->dupctx = OSSL_get_OP_signature_dupctx(fns); + break; + case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS: + if (signature->get_ctx_params != NULL) + break; + signature->get_ctx_params + = OSSL_get_OP_signature_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS: + if (signature->gettable_ctx_params != NULL) + break; + signature->gettable_ctx_params + = OSSL_get_OP_signature_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS: + if (signature->set_ctx_params != NULL) + break; + signature->set_ctx_params + = OSSL_get_OP_signature_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS: + if (signature->settable_ctx_params != NULL) + break; + signature->settable_ctx_params + = OSSL_get_OP_signature_settable_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS: + if (signature->get_ctx_md_params != NULL) + break; + signature->get_ctx_md_params + = OSSL_get_OP_signature_get_ctx_md_params(fns); + gmdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS: + if (signature->gettable_ctx_md_params != NULL) + break; + signature->gettable_ctx_md_params + = OSSL_get_OP_signature_gettable_ctx_md_params(fns); + gmdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS: + if (signature->set_ctx_md_params != NULL) + break; + signature->set_ctx_md_params + = OSSL_get_OP_signature_set_ctx_md_params(fns); + smdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS: + if (signature->settable_ctx_md_params != NULL) + break; + signature->settable_ctx_md_params + = OSSL_get_OP_signature_settable_ctx_md_params(fns); + smdparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (signfncnt == 0 + && verifyfncnt == 0 + && verifyrecfncnt == 0 + && digsignfncnt == 0 + && digverifyfncnt == 0) + || (signfncnt != 0 && signfncnt != 2) + || (verifyfncnt != 0 && verifyfncnt != 2) + || (verifyrecfncnt != 0 && verifyrecfncnt != 2) + || (digsignfncnt != 0 && digsignfncnt != 3) + || (digverifyfncnt != 0 && digverifyfncnt != 3) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2) + || (gmdparamfncnt != 0 && gmdparamfncnt != 2) + || (smdparamfncnt != 0 && smdparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a set of + * "signature" functions: + * (sign_init, sign) or + * (verify_init verify) or + * (verify_recover_init, verify_recover) or + * (digest_sign_init, digest_sign_update, digest_sign_final) or + * (digest_verify_init, digest_verify_update, digest_verify_final). + * + * set_ctx_params and settable_ctx_params are optional, but if one of + * them is present then the other one must also be present. The same + * applies to get_ctx_params and gettable_ctx_params. The same rules + * apply to the "md_params" functions. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return signature; + err: + EVP_SIGNATURE_free(signature); + return NULL; +} + +void EVP_SIGNATURE_free(EVP_SIGNATURE *signature) +{ + if (signature != NULL) { + int i; + + CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock); + if (i > 0) + return; + ossl_provider_free(signature->prov); + CRYPTO_THREAD_lock_free(signature->lock); + OPENSSL_free(signature); + } +} + +int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature) +{ + int ref = 0; + + CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock); + return 1; +} + +OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature) +{ + return signature->prov; +} + +EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties, + evp_signature_from_dispatch, + (int (*)(void *))EVP_SIGNATURE_up_ref, + (void (*)(void *))EVP_SIGNATURE_free); +} + +int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name) +{ + return evp_is_a(signature->prov, signature->name_id, NULL, name); +} + +int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature) +{ + return signature->name_id; +} + +void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(EVP_SIGNATURE *signature, + void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_SIGNATURE, + (void (*)(void *, void *))fn, arg, + evp_signature_from_dispatch, + (void (*)(void *))EVP_SIGNATURE_free); +} + + +void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature, + void (*fn)(const char *name, void *data), + void *data) +{ + if (signature->prov != NULL) + evp_names_do_all(signature->prov, signature->name_id, fn, data); +} + +static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) +{ + int ret = 0; + void *provkey = NULL; + EVP_SIGNATURE *signature = NULL; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + if (ctx->keytype == NULL) + goto legacy; + + if (ctx->keymgmt == NULL) + ctx->keymgmt = + EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery); + if (ctx->keymgmt != NULL) { + const char *supported_sig = NULL; + + if (ctx->keymgmt->query_operation_name != NULL) + supported_sig = + ctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE); + + /* + * If we didn't get a supported sig, assume there is one with the + * same name as the key type. + */ + if (supported_sig == NULL) + supported_sig = ctx->keytype; + + /* + * Because we cleared out old ops, we shouldn't need to worry about + * checking if signature is already there. + */ + signature = + EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery); + } + + if (ctx->keymgmt == NULL + || signature == NULL + || (EVP_KEYMGMT_provider(ctx->keymgmt) + != EVP_SIGNATURE_provider(signature))) { + /* + * We don't have the full support we need with provided methods, + * let's go see if legacy does. Also, we don't need to free + * ctx->keymgmt here, as it's not necessarily tied to this + * operation. It will be freed by EVP_PKEY_CTX_free(). + */ + EVP_SIGNATURE_free(signature); + goto legacy; + } + + ctx->op.sig.signature = signature; + + if (ctx->pkey != NULL) { + provkey = + evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; + } + ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov)); + if (ctx->op.sig.sigprovctx == NULL) { + /* The provider key can stay in the cache */ + EVPerr(0, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + switch (operation) { + case EVP_PKEY_OP_SIGN: + if (signature->sign_init == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->sign_init(ctx->op.sig.sigprovctx, provkey); + break; + case EVP_PKEY_OP_VERIFY: + if (signature->verify_init == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->verify_init(ctx->op.sig.sigprovctx, provkey); + break; + case EVP_PKEY_OP_VERIFYRECOVER: + if (signature->verify_recover_init == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->verify_recover_init(ctx->op.sig.sigprovctx, provkey); + break; + default: + EVPerr(0, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + if (ret <= 0) { + signature->freectx(ctx->op.sig.sigprovctx); + ctx->op.sig.sigprovctx = NULL; + goto err; + } + return 1; + + legacy: + if (ctx->pmeth == NULL + || (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL) + || (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL) + || (operation == EVP_PKEY_OP_VERIFYRECOVER + && ctx->pmeth->verify_recover == NULL)) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + switch (operation) { + case EVP_PKEY_OP_SIGN: + if (ctx->pmeth->sign_init == NULL) + return 1; + ret = ctx->pmeth->sign_init(ctx); + break; + case EVP_PKEY_OP_VERIFY: + if (ctx->pmeth->verify_init == NULL) + return 1; + ret = ctx->pmeth->verify_init(ctx); + break; + case EVP_PKEY_OP_VERIFYRECOVER: + if (ctx->pmeth->verify_recover_init == NULL) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + break; + default: + EVPerr(0, EVP_R_INITIALIZATION_ERROR); + goto err; + } + if (ret <= 0) + goto err; + return ret; + + err: + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_SIGN); +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_SIGN) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.sigprovctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->sign(ctx->op.sig.sigprovctx, sig, siglen, + SIZE_MAX, tbs, tbslen); + + return ret; + legacy: + + if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFY); +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.sigprovctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->verify(ctx->op.sig.sigprovctx, sig, siglen, + tbs, tbslen); + + return ret; + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFYRECOVER); +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + int ret; + + if (ctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.sigprovctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.sigprovctx, rout, + routlen, + (rout == NULL ? 0 : *routlen), + sig, siglen); + return ret; + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); +} diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 9f08606d..3cffef89 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -38,13 +38,8 @@ static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index) global = openssl_ctx_get_ex_data_global(ctx); if (global == NULL || global->ex_data_lock == NULL) { /* - * This can happen in normal operation when using CRYPTO_mem_leaks(). - * The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans - * up the locks. Subsequently the BIO that CRYPTO_mem_leaks() uses gets - * freed, which also attempts to free the ex_data. However - * CRYPTO_mem_leaks() ensures that the ex_data is freed early (i.e. - * before OPENSSL_cleanup() is called), so if we get here we can safely - * ignore this operation. We just treat it as an error. + * If we get here, someone (who?) cleaned up the lock, so just + * treat it as an error. */ return NULL; } @@ -108,7 +103,7 @@ static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx) { - EX_CALLBACKS *ip = get_and_lock(ctx, class_index); + EX_CALLBACKS *ip; EX_CALLBACK *a; int toret = 0; OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index 17cc5871..a94550a3 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -18,16 +18,17 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { - int rv = 0; - int i, j, reset = 0; + int rv = 0, reset = 0; + int i, j; unsigned char pad[HMAC_MAX_MD_CBLOCK_SIZE]; + unsigned int keytmp_length; + unsigned char keytmp[HMAC_MAX_MD_CBLOCK_SIZE]; /* If we are changing MD then we must have a key */ if (md != NULL && md != ctx->md && (key == NULL || len < 0)) return 0; if (md != NULL) { - reset = 1; ctx->md = md; } else if (ctx->md) { md = ctx->md; @@ -44,35 +45,34 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, if (key != NULL) { reset = 1; + j = EVP_MD_block_size(md); - if (!ossl_assert(j <= (int)sizeof(ctx->key))) + if (!ossl_assert(j <= (int)sizeof(keytmp))) return 0; if (j < len) { if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl) || !EVP_DigestUpdate(ctx->md_ctx, key, len) - || !EVP_DigestFinal_ex(ctx->md_ctx, ctx->key, - &ctx->key_length)) + || !EVP_DigestFinal_ex(ctx->md_ctx, keytmp, + &keytmp_length)) return 0; } else { - if (len < 0 || len > (int)sizeof(ctx->key)) + if (len < 0 || len > (int)sizeof(keytmp)) return 0; - memcpy(ctx->key, key, len); - ctx->key_length = len; + memcpy(keytmp, key, len); + keytmp_length = len; } - if (ctx->key_length != HMAC_MAX_MD_CBLOCK_SIZE) - memset(&ctx->key[ctx->key_length], 0, - HMAC_MAX_MD_CBLOCK_SIZE - ctx->key_length); - } + if (keytmp_length != HMAC_MAX_MD_CBLOCK_SIZE) + memset(&keytmp[keytmp_length], 0, + HMAC_MAX_MD_CBLOCK_SIZE - keytmp_length); - if (reset) { for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) - pad[i] = 0x36 ^ ctx->key[i]; + pad[i] = 0x36 ^ keytmp[i]; if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl) || !EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md))) goto err; for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) - pad[i] = 0x5c ^ ctx->key[i]; + pad[i] = 0x5c ^ keytmp[i]; if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl) || !EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md))) goto err; @@ -81,12 +81,14 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, goto err; rv = 1; err: - if (reset) + if (reset) { + OPENSSL_cleanse(keytmp, sizeof(keytmp)); OPENSSL_cleanse(pad, sizeof(pad)); + } return rv; } -#if !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) { if (key && md) @@ -149,8 +151,6 @@ static void hmac_ctx_cleanup(HMAC_CTX *ctx) EVP_MD_CTX_reset(ctx->o_ctx); EVP_MD_CTX_reset(ctx->md_ctx); ctx->md = NULL; - ctx->key_length = 0; - OPENSSL_cleanse(ctx->key, sizeof(ctx->key)); } void HMAC_CTX_free(HMAC_CTX *ctx) @@ -201,8 +201,6 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) goto err; if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx)) goto err; - memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK_SIZE); - dctx->key_length = sctx->key_length; dctx->md = sctx->md; return 1; err: diff --git a/crypto/hmac/hmac_local.h b/crypto/hmac/hmac_local.h index 788721ef..d6fd4f39 100644 --- a/crypto/hmac/hmac_local.h +++ b/crypto/hmac/hmac_local.h @@ -18,8 +18,6 @@ struct hmac_ctx_st { EVP_MD_CTX *md_ctx; EVP_MD_CTX *i_ctx; EVP_MD_CTX *o_ctx; - unsigned int key_length; - unsigned char key[HMAC_MAX_MD_CBLOCK_SIZE]; }; #endif diff --git a/crypto/info.c b/crypto/info.c index 613ddc7d..abba5437 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -8,6 +8,7 @@ */ #include +#include "crypto/rand.h" #include "crypto/dso_conf.h" #include "internal/thread_once.h" #include "internal/cryptlib.h" @@ -71,14 +72,15 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings) do { \ add_seeds_string(label "("); \ { \ - const char *dev[] = strlist; \ + const char *dev[] = { strlist, NULL }; \ + const char **p; \ int first = 1; \ \ - for (; *dev != NULL; dev++) { \ + for (p = dev; *p != NULL; p++) { \ if (!first) \ OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ first = 0; \ - OPENSSL_strlcat(seeds, *dev, sizeof(seeds)); \ + OPENSSL_strlcat(seeds, *p, sizeof(seeds)); \ } \ } \ OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \ @@ -100,10 +102,10 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings) add_seeds_string("getrandom-syscall"); #endif #ifdef OPENSSL_RAND_SEED_DEVRANDOM - add_seeds_stringlist("random-device", { DEVRANDOM, NULL }); + add_seeds_stringlist("random-device", DEVRANDOM); #endif #ifdef OPENSSL_RAND_SEED_EGD - add_seeds_stringlist("EGD", { DEVRANDOM_EGD, NULL }); + add_seeds_stringlist("EGD", DEVRANDOM_EGD); #endif #ifdef OPENSSL_RAND_SEED_OS add_seeds_string("os-specific"); diff --git a/crypto/initthread.c b/crypto/initthread.c index da30d59f..a5f770e2 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -380,6 +380,8 @@ static int init_thread_deregister(void *index, int all) int i; gtr = get_global_tevent_register(); + if (gtr == NULL) + return 0; if (!all) CRYPTO_THREAD_write_lock(gtr->lock); for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) { diff --git a/crypto/kdf/build.info b/crypto/kdf/build.info new file mode 100644 index 00000000..7707c009 --- /dev/null +++ b/crypto/kdf/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=kdf_err.c diff --git a/crypto/kdf/kdf_err.c b/crypto/kdf/kdf_err.c new file mode 100644 index 00000000..5b794285 --- /dev/null +++ b/crypto/kdf/kdf_err.c @@ -0,0 +1,19 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 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 + */ + +#include +#include + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int ERR_load_KDF_strings(void) +{ + return 1; +} +#endif diff --git a/crypto/md2/build.info b/crypto/md2/build.info index e31948c2..d682cfa6 100644 --- a/crypto/md2/build.info +++ b/crypto/md2/build.info @@ -1,3 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - md2_dgst.c md2_one.c + +SOURCE[../../libcrypto]=md2_dgst.c md2_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MD2 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{"deprecated"} + && (defined $config{"api"} && $config{"api"} >= 30000) -}] + SOURCE[../../providers/liblegacy.a]=md2_dgst.c md2_one.c +ENDIF diff --git a/crypto/md2/md2_dgst.c b/crypto/md2/md2_dgst.c index 405600fb..d8524891 100644 --- a/crypto/md2/md2_dgst.c +++ b/crypto/md2/md2_dgst.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/md2/md2_one.c b/crypto/md2/md2_one.c index a6008024..9b152ef7 100644 --- a/crypto/md2/md2_one.c +++ b/crypto/md2/md2_one.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include diff --git a/crypto/md4/build.info b/crypto/md4/build.info index 20846e0d..7b36a042 100644 --- a/crypto/md4/build.info +++ b/crypto/md4/build.info @@ -1,3 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - md4_dgst.c md4_one.c + +SOURCE[../../libcrypto]=md4_dgst.c md4_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MD4 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{"deprecated"} + && (defined $config{"api"} && $config{"api"} >= 30000) -}] + SOURCE[../../providers/liblegacy.a]=md4_dgst.c md4_one.c +ENDIF diff --git a/crypto/md4/md4_dgst.c b/crypto/md4/md4_dgst.c index cf95fbe6..531676a2 100644 --- a/crypto/md4/md4_dgst.c +++ b/crypto/md4/md4_dgst.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "md4_local.h" diff --git a/crypto/md4/md4_local.h b/crypto/md4/md4_local.h index 58c23e1a..66aa5e40 100644 --- a/crypto/md4/md4_local.h +++ b/crypto/md4/md4_local.h @@ -53,7 +53,7 @@ void md4_block_data_order(MD4_CTX *c, const void *p, size_t num); #define R1(a,b,c,d,k,s,t) { \ a+=((k)+(t)+G((b),(c),(d))); \ - a=ROTATE(a,s); };\ + a=ROTATE(a,s); }; #define R2(a,b,c,d,k,s,t) { \ a+=((k)+(t)+H((b),(c),(d))); \ diff --git a/crypto/md4/md4_one.c b/crypto/md4/md4_one.c index 0383f9bc..25f8eb8b 100644 --- a/crypto/md4/md4_one.c +++ b/crypto/md4/md4_one.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/md5/md5_local.h b/crypto/md5/md5_local.h index 8571e484..629fccdc 100644 --- a/crypto/md5/md5_local.h +++ b/crypto/md5/md5_local.h @@ -62,7 +62,7 @@ void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); #define R0(a,b,c,d,k,s,t) { \ a+=((k)+(t)+F((b),(c),(d))); \ a=ROTATE(a,s); \ - a+=b; };\ + a+=b; }; #define R1(a,b,c,d,k,s,t) { \ a+=((k)+(t)+G((b),(c),(d))); \ diff --git a/crypto/mdc2/build.info b/crypto/mdc2/build.info index 8fe6878d..54df2625 100644 --- a/crypto/mdc2/build.info +++ b/crypto/mdc2/build.info @@ -1,3 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - mdc2dgst.c mdc2_one.c + +SOURCE[../../libcrypto]=mdc2dgst.c mdc2_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MDC2 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{"deprecated"} + && (defined $config{"api"} && $config{"api"} >= 30000) -}] + SOURCE[../../providers/liblegacy.a]=mdc2dgst.c mdc2_one.c +ENDIF diff --git a/crypto/mdc2/mdc2_one.c b/crypto/mdc2/mdc2_one.c index 7b80bac5..c8bfdcc9 100644 --- a/crypto/mdc2/mdc2_one.c +++ b/crypto/mdc2/mdc2_one.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include diff --git a/crypto/mdc2/mdc2dgst.c b/crypto/mdc2/mdc2dgst.c index 46142f11..8893be16 100644 --- a/crypto/mdc2/mdc2dgst.c +++ b/crypto/mdc2/mdc2dgst.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/mem.c b/crypto/mem.c index d3cac29b..640107be 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -14,9 +14,6 @@ #include #include #include -#if !defined(OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE) && !defined(FIPS_MODE) -# include -#endif /* * the following pointers may be changed as long as 'allow_customize' is set @@ -43,7 +40,6 @@ static char *md_failstring; static long md_count; static int md_fail_percent = 0; static int md_tracefd = -1; -static int call_malloc_debug = 1; static void parseit(void); static int shouldfail(void); @@ -51,7 +47,6 @@ static int shouldfail(void); # define FAILTEST() if (shouldfail()) return NULL #else -static int call_malloc_debug = 0; # define INCREMENT(x) /* empty */ # define FAILTEST() /* empty */ @@ -73,14 +68,6 @@ int CRYPTO_set_mem_functions( return 1; } -int CRYPTO_set_mem_debug(int flag) -{ - if (!allow_customize) - return 0; - call_malloc_debug = flag; - return 1; -} - void CRYPTO_get_mem_functions( void *(**m)(size_t, const char *, int), void *(**r)(void *, size_t, const char *, int), @@ -158,14 +145,6 @@ static int shouldfail(void) len = strlen(buff); if (write(md_tracefd, buff, len) != len) perror("shouldfail write failed"); -# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - if (shoulditfail) { - void *addrs[30]; - int num = backtrace(addrs, OSSL_NELEM(addrs)); - - backtrace_symbols_fd(addrs, num, md_tracefd); - } -# endif } # endif @@ -209,18 +188,8 @@ void *CRYPTO_malloc(size_t num, const char *file, int line) */ allow_customize = 0; } -#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE) - if (call_malloc_debug) { - CRYPTO_mem_debug_malloc(NULL, num, 0, file, line); - ret = malloc(num); - CRYPTO_mem_debug_malloc(ret, num, 1, file, line); - } else { - ret = malloc(num); - } -#else (void)(file); (void)(line); ret = malloc(num); -#endif return ret; } @@ -250,17 +219,7 @@ void *CRYPTO_realloc(void *str, size_t num, const char *file, int line) return NULL; } -#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE) - if (call_malloc_debug) { - void *ret; - CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line); - ret = realloc(str, num); - CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line); - return ret; - } -#else (void)(file); (void)(line); -#endif return realloc(str, num); } @@ -300,17 +259,7 @@ void CRYPTO_free(void *str, const char *file, int line) return; } -#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE) - if (call_malloc_debug) { - CRYPTO_mem_debug_free(str, 0, file, line); - free(str); - CRYPTO_mem_debug_free(str, 1, file, line); - } else { - free(str); - } -#else free(str); -#endif } void CRYPTO_clear_free(void *str, size_t num, const char *file, int line) @@ -321,3 +270,72 @@ void CRYPTO_clear_free(void *str, size_t num, const char *file, int line) OPENSSL_cleanse(str, num); CRYPTO_free(str, file, line); } + +#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +int CRYPTO_mem_ctrl(int mode) +{ + (void)mode; + return -1; +} + +int CRYPTO_set_mem_debug(int flag) +{ + (void)flag; + return -1; +} + +int CRYPTO_mem_debug_push(const char *info, const char *file, int line) +{ + (void)info; (void)file; (void)line; + return -1; +} + +int CRYPTO_mem_debug_pop(void) +{ + return -1; +} + +void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag, + const char *file, int line) +{ + (void)addr; (void)num; (void)flag; (void)file; (void)line; +} + +void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag, + const char *file, int line) +{ + (void)addr1; (void)addr2; (void)num; (void)flag; (void)file; (void)line; +} + +void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line) +{ + (void)addr; (void)flag; (void)file; (void)line; +} + +int CRYPTO_mem_leaks(BIO *b) +{ + (void)b; + return -1; +} + +# ifndef OPENSSL_NO_STDIO +int CRYPTO_mem_leaks_fp(FILE *fp) +{ + (void)fp; + return -1; +} +# endif + +int CRYPTO_mem_leaks_cb(int (*cb)(const char *str, size_t len, void *u), + void *u) +{ + (void)cb; (void)u; + return -1; +} + +# endif + +#endif diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c deleted file mode 100644 index 1a08b2bb..00000000 --- a/crypto/mem_dbg.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright 1995-2019 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 - */ - -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/thread_once.h" -#include -#include -#include "internal/bio.h" -#include - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE -# include -#endif - -/* - * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when - * the application asks for it (usually after library initialisation for - * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only - * temporarily when the library thinks that certain allocations should not be - * checked (e.g. the data structures used for memory checking). It is not - * suitable as an initial state: the library will unexpectedly enable memory - * checking when it executes one of those sections that want to disable - * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes - * no sense whatsoever. - */ -#ifndef OPENSSL_NO_CRYPTO_MDEBUG -static int mh_mode = CRYPTO_MEM_CHECK_OFF; -#endif - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG -static unsigned long order = 0; /* number of memory requests */ - -static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT; -CRYPTO_RWLOCK *memdbg_lock; -static CRYPTO_RWLOCK *long_memdbg_lock; - -/* memory-block description */ -struct mem_st { - void *addr; - int num; - const char *file; - int line; - CRYPTO_THREAD_ID threadid; - unsigned long order; - time_t time; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - void *array[30]; - size_t array_siz; -#endif -}; - -/* - * hash-table of memory requests (address as * key); access requires - * long_memdbg_lock lock - */ -static LHASH_OF(MEM) *mh = NULL; - -/* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ -static unsigned int num_disable = 0; - -/* - * Valid iff num_disable > 0. long_memdbg_lock is locked exactly in this - * case (by the thread named in disabling_thread). - */ -static CRYPTO_THREAD_ID disabling_threadid; - -DEFINE_RUN_ONCE_STATIC(do_memdbg_init) -{ - memdbg_lock = CRYPTO_THREAD_lock_new(); - long_memdbg_lock = CRYPTO_THREAD_lock_new(); - if (memdbg_lock == NULL || long_memdbg_lock == NULL) { - CRYPTO_THREAD_lock_free(memdbg_lock); - memdbg_lock = NULL; - CRYPTO_THREAD_lock_free(long_memdbg_lock); - long_memdbg_lock = NULL; - return 0; - } - return 1; -} - -#endif - -int CRYPTO_mem_ctrl(int mode) -{ -#ifdef OPENSSL_NO_CRYPTO_MDEBUG - return mode - mode; -#else - int ret = mh_mode; - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return -1; - - CRYPTO_THREAD_write_lock(memdbg_lock); - switch (mode) { - default: - break; - - case CRYPTO_MEM_CHECK_ON: - mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE; - num_disable = 0; - break; - - case CRYPTO_MEM_CHECK_OFF: - mh_mode = 0; - num_disable = 0; - break; - - /* switch off temporarily (for library-internal use): */ - case CRYPTO_MEM_CHECK_DISABLE: - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id(); - /* see if we don't have long_memdbg_lock already */ - if (!num_disable - || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) { - /* - * Long-time lock long_memdbg_lock must not be claimed - * while we're holding memdbg_lock, or we'll deadlock - * if somebody else holds long_memdbg_lock (and cannot - * release it because we block entry to this function). Give - * them a chance, first, and then claim the locks in - * appropriate order (long-time lock first). - */ - CRYPTO_THREAD_unlock(memdbg_lock); - /* - * Note that after we have waited for long_memdbg_lock and - * memdbg_lock, we'll still be in the right "case" and - * "if" branch because MemCheck_start and MemCheck_stop may - * never be used while there are multiple OpenSSL threads. - */ - CRYPTO_THREAD_write_lock(long_memdbg_lock); - CRYPTO_THREAD_write_lock(memdbg_lock); - mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; - disabling_threadid = cur; - } - num_disable++; - } - break; - - case CRYPTO_MEM_CHECK_ENABLE: - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (num_disable) { /* always true, or something is going wrong */ - num_disable--; - if (num_disable == 0) { - mh_mode |= CRYPTO_MEM_CHECK_ENABLE; - CRYPTO_THREAD_unlock(long_memdbg_lock); - } - } - } - break; - } - CRYPTO_THREAD_unlock(memdbg_lock); - return ret; -#endif -} - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - -static int mem_check_on(void) -{ - int ret = 0; - CRYPTO_THREAD_ID cur; - - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return 0; - - cur = CRYPTO_THREAD_get_current_id(); - CRYPTO_THREAD_read_lock(memdbg_lock); - - ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) - || !CRYPTO_THREAD_compare_id(disabling_threadid, cur); - - CRYPTO_THREAD_unlock(memdbg_lock); - } - return ret; -} - -static int mem_cmp(const MEM *a, const MEM *b) -{ -#ifdef _WIN64 - const char *ap = (const char *)a->addr, *bp = (const char *)b->addr; - if (ap == bp) - return 0; - else if (ap > bp) - return 1; - else - return -1; -#else - return (const char *)a->addr - (const char *)b->addr; -#endif -} - -static unsigned long mem_hash(const MEM *a) -{ - size_t ret; - - ret = (size_t)a->addr; - - ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; - return ret; -} - -#if !OPENSSL_API_3 -int CRYPTO_mem_debug_push(const char *info, const char *file, int line) -{ - return 0; -} - -int CRYPTO_mem_debug_pop(void) -{ - return 0; -} -#endif - -static unsigned long break_order_num = 0; - -void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p, - const char *file, int line) -{ - MEM *m, *mm; - - switch (before_p & 127) { - case 0: - break; - case 1: - if (addr == NULL) - break; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init) - || (m = OPENSSL_malloc(sizeof(*m))) == NULL) { - OPENSSL_free(addr); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - return; - } - if (mh == NULL) { - if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) { - OPENSSL_free(addr); - OPENSSL_free(m); - addr = NULL; - goto err; - } - } - - m->addr = addr; - m->file = file; - m->line = line; - m->num = num; - m->threadid = CRYPTO_THREAD_get_current_id(); - - if (order == break_order_num) { - /* BREAK HERE */ - m->order = order; - } - m->order = order++; -# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - m->array_siz = backtrace(m->array, OSSL_NELEM(m->array)); -# endif - m->time = time(NULL); - - if ((mm = lh_MEM_insert(mh, m)) != NULL) - OPENSSL_free(mm); - err: - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - } - return; -} - -void CRYPTO_mem_debug_free(void *addr, int before_p, - const char *file, int line) -{ - MEM m, *mp; - - switch (before_p) { - case 0: - if (addr == NULL) - break; - - if (mem_check_on() && (mh != NULL)) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - m.addr = addr; - mp = lh_MEM_delete(mh, &m); - OPENSSL_free(mp); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - case 1: - break; - } -} - -void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, - int before_p, const char *file, int line) -{ - MEM m, *mp; - - switch (before_p) { - case 0: - break; - case 1: - if (addr2 == NULL) - break; - - if (addr1 == NULL) { - CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line); - break; - } - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - m.addr = addr1; - mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { - mp->addr = addr2; - mp->num = num; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array)); -#endif - (void)lh_MEM_insert(mh, mp); - } - - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - } - return; -} - -typedef struct mem_leak_st { - int (*print_cb) (const char *str, size_t len, void *u); - void *print_cb_arg; - int chunks; - long bytes; -} MEM_LEAK; - -static void print_leak(const MEM *m, MEM_LEAK *l) -{ - char buf[1024]; - char *bufp = buf, *hex; - size_t len = sizeof(buf); - int n; - struct tm *lcl = NULL; - - lcl = localtime(&m->time); - n = BIO_snprintf(bufp, len, "[%02d:%02d:%02d] ", - lcl->tm_hour, lcl->tm_min, lcl->tm_sec); - if (n <= 0) { - bufp[0] = '\0'; - return; - } - bufp += n; - len -= n; - - n = BIO_snprintf(bufp, len, "%5lu file=%s, line=%d, ", - m->order, m->file, m->line); - if (n <= 0) - return; - bufp += n; - len -= n; - - hex = OPENSSL_buf2hexstr((const unsigned char *)&m->threadid, - sizeof(m->threadid)); - n = BIO_snprintf(bufp, len, "thread=%s, number=%d, address=%p\n", hex, - m->num, m->addr); - OPENSSL_free(hex); - if (n <= 0) - return; - bufp += n; - len -= n; - - l->print_cb(buf, (size_t)(bufp - buf), l->print_cb_arg); - l->chunks++; - l->bytes += m->num; - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - { - size_t i; - char **strings = backtrace_symbols(m->array, m->array_siz); - - for (i = 0; i < m->array_siz; i++) - fprintf(stderr, "##> %s\n", strings[i]); - free(strings); - } -#endif -} - -IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK); - -int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), - void *u) -{ - MEM_LEAK ml; - - /* Ensure all resources are released */ - OPENSSL_cleanup(); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return -1; - - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - ml.print_cb = cb; - ml.print_cb_arg = u; - ml.bytes = 0; - ml.chunks = 0; - if (mh != NULL) - lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml); - - if (ml.chunks != 0) { - char buf[256]; - - BIO_snprintf(buf, sizeof(buf), "%ld bytes leaked in %d chunks\n", - ml.bytes, ml.chunks); - cb(buf, strlen(buf), u); - } else { - /* - * Make sure that, if we found no leaks, memory-leak debugging itself - * does not introduce memory leaks (which might irritate external - * debugging tools). (When someone enables leak checking, but does not - * call this function, we declare it to be their fault.) - */ - int old_mh_mode; - - CRYPTO_THREAD_write_lock(memdbg_lock); - - /* - * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses - * mem_check_on - */ - old_mh_mode = mh_mode; - mh_mode = CRYPTO_MEM_CHECK_OFF; - - lh_MEM_free(mh); - mh = NULL; - - mh_mode = old_mh_mode; - CRYPTO_THREAD_unlock(memdbg_lock); - } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF); - - /* Clean up locks etc */ - CRYPTO_THREAD_lock_free(memdbg_lock); - CRYPTO_THREAD_lock_free(long_memdbg_lock); - memdbg_lock = NULL; - long_memdbg_lock = NULL; - - return ml.chunks == 0 ? 1 : 0; -} - -static int print_bio(const char *str, size_t len, void *b) -{ - return BIO_write((BIO *)b, str, len); -} - -int CRYPTO_mem_leaks(BIO *b) -{ - /* - * OPENSSL_cleanup() will free the ex_data locks so we can't have any - * ex_data hanging around - */ - bio_free_ex_data(b); - - return CRYPTO_mem_leaks_cb(print_bio, b); -} - -# ifndef OPENSSL_NO_STDIO -int CRYPTO_mem_leaks_fp(FILE *fp) -{ - BIO *b; - int ret; - - /* - * Need to turn off memory checking when allocated BIOs ... especially as - * we're creating them at a time when we're trying to check we've not - * left anything un-free()'d!! - */ - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - b = BIO_new(BIO_s_file()); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - if (b == NULL) - return -1; - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = CRYPTO_mem_leaks_cb(print_bio, b); - BIO_free(b); - return ret; -} -# endif - -#endif diff --git a/crypto/modes/asm/aes-gcm-armv8_64.pl b/crypto/modes/asm/aes-gcm-armv8_64.pl new file mode 100755 index 00000000..ee88906d --- /dev/null +++ b/crypto/modes/asm/aes-gcm-armv8_64.pl @@ -0,0 +1,5722 @@ +#! /usr/bin/env perl +# Copyright 2019 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 + +# +#======================================================================== +# Written by Fangming Fang for the OpenSSL project, +# derived from https://github.com/ARM-software/AArch64cryptolib, original +# author Samuel Lee . The module is, however, dual +# licensed under OpenSSL and CRYPTOGAMS licenses depending on where you +# obtain it. For further details see http://www.openssl.org/~appro/cryptogams/. +#======================================================================== +# +# Approach - assume we don't want to reload constants, so reserve ~half of vector register file for constants +# +# main loop to act on 4 16B blocks per iteration, and then do modulo of the accumulated intermediate hashes from the 4 blocks +# +# ____________________________________________________ +# | | +# | PRE | +# |____________________________________________________| +# | | | | +# | CTR block 4k+8 | AES block 4k+4 | GHASH block 4k+0 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+9 | AES block 4k+5 | GHASH block 4k+1 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+10| AES block 4k+6 | GHASH block 4k+2 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+11| AES block 4k+7 | GHASH block 4k+3 | +# |________________|____(mostly)____|__________________| +# | | +# | MODULO | +# |____________________________________________________| +# +# PRE: +# Ensure previous generated intermediate hash is aligned and merged with result for GHASH 4k+0 +# EXT low_acc, low_acc, low_acc, #8 +# EOR res_curr (4k+0), res_curr (4k+0), low_acc +# +# CTR block: +# Increment and byte reverse counter in scalar registers and transfer to SIMD registers +# REV ctr32, rev_ctr32 +# ORR ctr64, constctr96_top32, ctr32, LSL #32 +# INS ctr_next.d[0], constctr96_bottom64 // Keeping this in scalar registers to free up space in SIMD RF +# INS ctr_next.d[1], ctr64X +# ADD rev_ctr32, #1 +# +# AES block: +# Do AES encryption/decryption on CTR block X and EOR it with input block X. Take 256 bytes key below for example. +# Doing small trick here of loading input in scalar registers, EORing with last key and then transferring +# Given we are very constrained in our ASIMD registers this is quite important +# +# Encrypt: +# LDR input_low, [ input_ptr ], #8 +# LDR input_high, [ input_ptr ], #8 +# EOR input_low, k14_low +# EOR input_high, k14_high +# INS res_curr.d[0], input_low +# INS res_curr.d[1], input_high +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# EOR res_curr, res_curr, ctr_curr +# ST1 { res_curr.16b }, [ output_ptr ], #16 +# +# Decrypt: +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# LDR res_curr, [ input_ptr ], #16 +# EOR res_curr, res_curr, ctr_curr +# MOV output_low, res_curr.d[0] +# MOV output_high, res_curr.d[1] +# EOR output_low, k14_low +# EOR output_high, k14_high +# STP output_low, output_high, [ output_ptr ], #16 +# +# GHASH block X: +# do 128b karatsuba polynomial multiplication on block +# We only have 64b->128b polynomial multipliers, naively that means we need to do 4 64b multiplies to generate a 128b +# +# multiplication: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ (Pmull(Ah,Bl) ^ Pmull(Al,Bh))<<64 +# +# The idea behind Karatsuba multiplication is that we can do just 3 64b multiplies: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ (Pmull(Ah^Al,Bh^Bl) ^ Pmull(Ah,Bh) ^ Pmull(Al,Bl))<<64 +# +# There is some complication here because the bit order of GHASH's PMULL is reversed compared to elsewhere, so we are +# multiplying with "twisted" powers of H +# +# Note: We can PMULL directly into the acc_x in first GHASH of the loop +# Note: For scheduling big cores we want to split the processing to happen over two loop iterations - otherwise the critical +# path latency dominates the performance +# +# This has a knock on effect on register pressure, so we have to be a bit more clever with our temporary registers +# than indicated here +# REV64 res_curr, res_curr +# INS t_m.d[0], res_curr.d[1] +# EOR t_m.8B, t_m.8B, res_curr.8B +# PMULL2 t_h, res_curr, HX +# PMULL t_l, res_curr, HX +# PMULL t_m, t_m, HX_k +# EOR acc_h, acc_h, t_h +# EOR acc_l, acc_l, t_l +# EOR acc_m, acc_m, t_m +# +# MODULO: take the partial accumulators (~representing sum of 256b multiplication results), from GHASH and do modulo reduction on them +# There is some complication here because the bit order of GHASH's PMULL is reversed compared to elsewhere, so we are doing modulo +# with a reversed constant +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, acc_l // Finish off karatsuba processing +# PMULL t_mod, acc_h, mod_constant +# EXT acc_h, acc_h, acc_h, #8 +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, t_mod +# PMULL acc_h, acc_m, mod_constant +# EXT acc_m, acc_m, acc_m, #8 +# EOR acc_l, acc_l, acc_h +# EOR acc_l, acc_l, acc_m + +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate ) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$input_ptr="x0"; #argument block +$bit_length="x1"; +$output_ptr="x2"; +$current_tag="x3"; +$counter="x16"; +$cc="x8"; + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk10_l,$rk10_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; + +my ($t1,$t2,$t3)=map("v$_",(28..30)); +my ($t1d,$t2d,$t3d)=map("d$_",(28..30)); + +my $t4="v8"; +my $t4d="d8"; +my $t5="v28"; +my $t5d="d28"; +my $t6="v31"; +my $t6d="d31"; + +my $t7="v4"; +my $t7d="d4"; +my $t8="v29"; +my $t8d="d29"; +my $t9="v30"; +my $t9d="d30"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v31"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9)=map("v$_.16b",(18..27)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q)=map("q$_",(18..27)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +$code=<<___; +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=8 +___ +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); +$code.=<<___ if ($flavour !~ /64/); +.fpu neon +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,0xef,a,b +#else +.code 32 +# define INST(a,b,c,d) $_byte a,b,c,0xf2 +#endif + +.text +___ + +######################################################################################### +# size_t aes_gcm_enc_128_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_128_kernel +.type aes_gcm_enc_128_kernel,%function +.align 4 +aes_gcm_enc_128_kernel: + cbz x1, .L128_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + ldp $rk10_l, $rk10_h, [$cc, #160] @ load rk10 + + ld1 {$acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + + ldr $rk9q, [$cc, #144] @ load rk9 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + ldr $rk0q, [$cc, #0] @ load rk0 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk1q, [$cc, #16] @ load rk1 + + add $rctr32w, $rctr32w, #1 @ CTR block 3 + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr2b, $rk9 @ AES block 2 - round 9 + + aese $ctr0b, $rk9 @ AES block 0 - round 9 + + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr1b, $rk9 @ AES block 1 - round 9 + + aese $ctr3b, $rk9 @ AES block 3 - round 9 + b.ge .L128_enc_tail @ handle tail + + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + eor $input_l0, $input_l0, $rk10_l @ AES block 0 - round 10 low + eor $input_h0, $input_h0, $rk10_h @ AES block 0 - round 10 high + + eor $input_l2, $input_l2, $rk10_l @ AES block 2 - round 10 low + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + eor $input_l1, $input_l1, $rk10_l @ AES block 1 - round 10 low + eor $input_h2, $input_h2, $rk10_h @ AES block 2 - round 10 high + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_h1, $input_h1, $rk10_h @ AES block 1 - round 10 high + + eor $input_l3, $input_l3, $rk10_l @ AES block 3 - round 10 low + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + eor $input_h3, $input_h3, $rk10_h @ AES block 3 - round 10 high + rev $ctr32w, $rctr32w @ CTR block 4 + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + add $rctr32w, $rctr32w, #1 @ CTR block 5 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + rev $ctr32w, $rctr32w @ CTR block 6 + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + rev $ctr32w, $rctr32w @ CTR block 7 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge .L128_enc_prepretail @ do prepretail + + .L128_enc_main_loop: @ main loop start + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+3 - load plaintext + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_h3, $input_h3, $rk10_h @ AES block 4k+3 - round 10 high + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $input_h0, $input_h0, $rk10_h @ AES block 4k+4 - round 10 high + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $input_l0, $input_l0, $rk10_l @ AES block 4k+4 - round 10 low + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $input_l1, $input_l1, $rk10_l @ AES block 4k+5 - round 10 low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $input_l3, $input_l3, $rk10_l @ AES block 4k+3 - round 10 low + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + fmov $ctr_t3d, $input_l3 @ AES block 4k+3 - mov low + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $input_h1, $input_h1, $rk10_h @ AES block 4k+5 - round 10 high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+3 - mov high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + eor $input_l2, $input_l2, $rk10_l @ AES block 4k+6 - round 10 low + eor $input_h2, $input_h2, $rk10_h @ AES block 4k+6 - round 10 high + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+3 - result + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+3 - store result + b.lt .L128_enc_main_loop + + .L128_enc_prepretail: @ PREPRETAIL + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + eor $res0b, $res0b, $acc_lb @ PRE 1 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + eor $acc_lb, $acc_lb, $acc_mb + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + .L128_enc_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + cmp $main_end_input_ptr, #48 + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + eor $input_l0, $input_l0, $rk10_l @ AES block 4k+4 - round 10 low + eor $input_h0, $input_h0, $rk10_h @ AES block 4k+4 - round 10 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + b.gt .L128_enc_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + movi $acc_l.8b, #0 + mov $ctr3b, $ctr2b + + cmp $main_end_input_ptr, #32 + mov $ctr2b, $ctr1b + movi $acc_h.8b, #0 + + movi $acc_m.8b, #0 + b.gt .L128_enc_blocks_more_than_2 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + + sub $rctr32w, $rctr32w, #1 + b.gt .L128_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L128_enc_blocks_less_than_1 + .L128_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + eor $input_h0, $input_h0, $rk10_h @ AES final-2 block - round 10 high + eor $input_l0, $input_l0, $rk10_l @ AES final-2 block - round 10 low + + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + movi $t0.8b, #0 @ suppress further partial tag feed in + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + .L128_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + rev64 $res0b, $res1b @ GHASH final-2 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_l0, $input_l0, $rk10_l @ AES final-1 block - round 10 low + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + eor $input_h0, $input_h0, $rk10_h @ AES final-1 block - round 10 high + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L128_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + rev64 $res0b, $res1b @ GHASH final-1 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk10_h @ AES final block - round 10 high + eor $input_l0, $input_l0, $rk10_l @ AES final block - round 10 low + + fmov $res1d, $input_l0 @ AES final block - mov low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $res1b, $res1b, $ctr3b @ AES final block - result + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + .L128_enc_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk10_l, xzr @ rk10_l = 0xffffffffffffffff + + mvn $rk10_h, xzr @ rk10_h = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk10_h, $rk10_h, $bit_length @ rk10_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk10_l, $rk10_h, lt + csel $input_h0, $rk10_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + rev $ctr32w, $rctr32w + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + st1 { $res1b}, [$output_ptr] @ store all 16B + + str $ctr32w, [$counter, #12] @ store the updated counter + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_128_kernel,.-aes_gcm_enc_128_kernel +___ + +######################################################################################### +# size_t aes_gcm_dec_128_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_128_kernel +.type aes_gcm_dec_128_kernel,%function +.align 4 +aes_gcm_dec_128_kernel: + cbz x1, .L128_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + ldr $rk0q, [$cc, #0] @ load rk0 + + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + lsr $rctr32x, $ctr96_t32x, #32 + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + + ldr $rk1q, [$cc, #16] @ load rk1 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + rev $rctr32w, $rctr32w @ rev_ctr32 + + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + rev $ctr32w, $rctr32w @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ldr $rk2q, [$cc, #32] @ load rk2 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldp $rk10_l, $rk10_h, [$cc, #160] @ load rk10 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr2b, $rk9 @ AES block 2 - round 9 + + aese $ctr3b, $rk9 @ AES block 3 - round 9 + + aese $ctr0b, $rk9 @ AES block 0 - round 9 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr1b, $rk9 @ AES block 1 - round 9 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + b.ge .L128_dec_tail @ handle tail + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + rev64 $res0b, $res0b @ GHASH block 0 + rev $ctr32w, $rctr32w @ CTR block 4 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + rev64 $res1b, $res1b @ GHASH block 1 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + eor $output_l1, $output_l1, $rk10_l @ AES block 1 - round 10 low + + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + add $rctr32w, $rctr32w, #1 @ CTR block 6 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + eor $output_h1, $output_h1, $rk10_h @ AES block 1 - round 10 high + eor $output_l0, $output_l0, $rk10_l @ AES block 0 - round 10 low + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + + eor $output_h0, $output_h0, $rk10_h @ AES block 0 - round 10 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + b.ge .L128_dec_prepretail @ do prepretail + + .L128_dec_main_loop: @ main loop start + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + rev64 $res2b, $res2b @ GHASH block 4k+2 + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + eor $res0b, $res0b, $acc_lb @ PRE 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $output_l3, $output_l3, $rk10_l @ AES block 4k+3 - round 10 low + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $output_h2, $output_h2, $rk10_h @ AES block 4k+2 - round 10 high + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $output_h3, $output_h3, $rk10_h @ AES block 4k+3 - round 10 high + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + eor $output_l2, $output_l2, $rk10_l @ AES block 4k+2 - round 10 low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ldr $res3q, [$input_ptr, #48] @ AES block 4k+3 - load ciphertext + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + rev64 $res1b, $res1b @ GHASH block 4k+5 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $output_h0, $output_h0, $rk10_h @ AES block 4k+4 - round 10 high + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + eor $output_l0, $output_l0, $rk10_l @ AES block 4k+4 - round 10 low + + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + rev64 $res0b, $res0b @ GHASH block 4k+4 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + + rev $ctr32w, $rctr32w @ CTR block 4k+10 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + eor $output_h1, $output_h1, $rk10_h @ AES block 4k+5 - round 10 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + + eor $output_l1, $output_l1, $rk10_l @ AES block 4k+5 - round 10 low + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + b.lt L128_dec_main_loop + + .L128_dec_prepretail: @ PREPRETAIL + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + eor $res0b, $res0b, $acc_lb @ PRE 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + + rev $ctr32w, $rctr32w @ CTR block 4k+7 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $output_l3, $output_l3, $rk10_l @ AES block 4k+3 - round 10 low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $output_l2, $output_l2, $rk10_l @ AES block 4k+2 - round 10 low + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $output_h3, $output_h3, $rk10_h @ AES block 4k+3 - round 10 high + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $output_h2, $output_h2, $rk10_h @ AES block 4k+2 - round 10 high + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L128_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + cmp $main_end_input_ptr, #48 + + eor $output_h0, $output_h0, $rk10_h @ AES block 4k+4 - round 10 high + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + eor $output_l0, $output_l0, $rk10_l @ AES block 4k+4 - round 10 low + b.gt .L128_dec_blocks_more_than_3 + + mov $ctr3b, $ctr2b + sub $rctr32w, $rctr32w, #1 + movi $acc_l.8b, #0 + + movi $acc_h.8b, #0 + mov $ctr2b, $ctr1b + + movi $acc_m.8b, #0 + cmp $main_end_input_ptr, #32 + b.gt .L128_dec_blocks_more_than_2 + + cmp $main_end_input_ptr, #16 + + mov $ctr3b, $ctr1b + sub $rctr32w, $rctr32w, #1 + b.gt .L128_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L128_dec_blocks_less_than_1 + .L128_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + eor $output_h0, $output_h0, $rk10_h @ AES final-2 block - round 10 high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_l0, $output_l0, $rk10_l @ AES final-2 block - round 10 low + .L128_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $output_l0, $output_l0, $rk10_l @ AES final-1 block - round 10 low + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + eor $output_h0, $output_h0, $rk10_h @ AES final-1 block - round 10 high + .L128_dec_blocks_more_than_1: @ blocks left > 1 + + rev64 $res0b, $res1b @ GHASH final-1 block + + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + eor $output_h0, $output_h0, $rk10_h @ AES final block - round 10 high + + eor $output_l0, $output_l0, $rk10_l @ AES final block - round 10 low + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L128_dec_blocks_less_than_1: @ blocks left <= 1 + + mvn $rk10_h, xzr @ rk10_h = 0xffffffffffffffff + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + mvn $rk10_l, xzr @ rk10_l = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk10_h, $rk10_h, $bit_length @ rk10_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr96_b64x, $rk10_h, xzr, lt + csel $ctr32x, $rk10_l, $rk10_h, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + + mov $ctr0.d[1], $ctr96_b64x + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + + and $output_h0, $output_h0, $ctr96_b64x + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + and $output_l0, $output_l0, $ctr32x + + rev $ctr32w, $rctr32w + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + orr $output_l0, $output_l0, $end_input_ptr + str $ctr32w, [$counter, #12] @ store the updated counter + + orr $output_h0, $output_h0, $main_end_input_ptr + stp $output_l0, $output_h0, [$output_ptr] + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + + .L128_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_128_kernel,.-aes_gcm_dec_128_kernel +___ +} + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk12_l,$rk12_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; +my $t3="v4"; +my $t3d="d4"; + +my ($t1,$t2)=map("v$_",(30..31)); +my ($t1d,$t2d)=map("d$_",(30..31)); + +my $t4="v30"; +my $t4d="d30"; +my $t5="v8"; +my $t5d="d8"; +my $t6="v31"; +my $t6d="d31"; + +my $t7="v5"; +my $t7d="d5"; +my $t8="v6"; +my $t8d="d6"; +my $t9="v30"; +my $t9d="d30"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v31"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9,$rk10,$rk11)=map("v$_.16b",(18..29)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q,$rk10q,$rk11q)=map("q$_",(18..29)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +######################################################################################### +# size_t aes_gcm_enc_192_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_192_kernel +.type aes_gcm_enc_192_kernel,%function +.align 4 +aes_gcm_enc_192_kernel: + cbz x1, .L192_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ldr $rk5q, [$cc, #80] @ load rk5 + + ldr $rk4q, [$cc, #64] @ load rk4 + + ldr $rk8q, [$cc, #128] @ load rk8 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $rk6q, [$cc, #96] @ load rk6 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + ldr $rk7q, [$cc, #112] @ load rk7 + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk0q, [$cc, #0] @ load rk0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $rk3q, [$cc, #48] @ load rk3 + + ldp $rk12_l, $rk12_h, [$cc, #192] @ load rk12 + + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr2b, $rk11 @ AES block 2 - round 11 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk11 @ AES block 1 - round 11 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk11 @ AES block 0 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr3b, $rk11 @ AES block 3 - round 11 + b.ge .L192_enc_tail @ handle tail + + rev $ctr32w, $rctr32w @ CTR block 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + eor $input_l0, $input_l0, $rk12_l @ AES block 0 - round 12 low + + eor $input_h0, $input_h0, $rk12_h @ AES block 0 - round 12 high + eor $input_h2, $input_h2, $rk12_h @ AES block 2 - round 12 high + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + eor $input_h3, $input_h3, $rk12_h @ AES block 3 - round 12 high + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + + eor $input_l2, $input_l2, $rk12_l @ AES block 2 - round 12 low + eor $input_l1, $input_l1, $rk12_l @ AES block 1 - round 12 low + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_h1, $input_h1, $rk12_h @ AES block 1 - round 12 high + + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + eor $input_l3, $input_l3, $rk12_l @ AES block 3 - round 12 low + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + + add $rctr32w, $rctr32w, #1 @ CTR block 4 + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + rev $ctr32w, $rctr32w @ CTR block 7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge .L192_enc_prepretail @ do prepretail + + .L192_enc_main_loop: @ main loop start + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+3 - load plaintext + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_h3, $input_h3, $rk12_h @ AES block 4k+3 - round 12 high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $input_l2, $input_l2, $rk12_l @ AES block 4k+6 - round 12 low + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $input_l1, $input_l1, $rk12_l @ AES block 4k+5 - round 12 low + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $input_h1, $input_h1, $rk12_h @ AES block 4k+5 - round 12 high + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $input_h2, $input_h2, $rk12_h @ AES block 4k+6 - round 12 high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $input_l3, $input_l3, $rk12_l @ AES block 4k+3 - round 12 low + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + movi $mod_constant.8b, #0xc2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + eor $input_h0, $input_h0, $rk12_h @ AES block 4k+4 - round 12 high + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $input_l0, $input_l0, $rk12_l @ AES block 4k+4 - round 12 low + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + fmov $ctr_t3d, $input_l3 @ AES block 4k+3 - mov low + + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+3 - mov high + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+3 - store result + b.lt .L192_enc_main_loop + + .L192_enc_prepretail: @ PREPRETAIL + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + eor $res0b, $res0b, $acc_lb @ PRE 1 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + eor $acc_lb, $acc_lb, $acc_mb + .L192_enc_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + eor $input_l0, $input_l0, $rk12_l @ AES block 4k+4 - round 12 low + eor $input_h0, $input_h0, $rk12_h @ AES block 4k+4 - round 12 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + cmp $main_end_input_ptr, #48 + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + b.gt .L192_enc_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + movi $acc_m.8b, #0 + + mov $ctr3b, $ctr2b + movi $acc_h.8b, #0 + cmp $main_end_input_ptr, #32 + + mov $ctr2b, $ctr1b + movi $acc_l.8b, #0 + b.gt .L192_enc_blocks_more_than_2 + + sub $rctr32w, $rctr32w, #1 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + b.gt .L192_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L192_enc_blocks_less_than_1 + .L192_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $input_l0, $input_l0, $rk12_l @ AES final-2 block - round 12 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk12_h @ AES final-2 block - round 12 high + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + .L192_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + rev64 $res0b, $res1b @ GHASH final-2 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk12_h @ AES final-1 block - round 12 high + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + eor $input_l0, $input_l0, $rk12_l @ AES final-1 block - round 12 low + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L192_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-1 block + + eor $input_l0, $input_l0, $rk12_l @ AES final block - round 12 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + eor $input_h0, $input_h0, $rk12_h @ AES final block - round 12 high + fmov $res1d, $input_l0 @ AES final block - mov low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + eor $res1b, $res1b, $ctr3b @ AES final block - result + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L192_enc_blocks_less_than_1: @ blocks left <= 1 + + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + rev $ctr32w, $rctr32w + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + mvn $rk12_h, xzr @ rk12_h = 0xffffffffffffffff + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + mvn $rk12_l, xzr @ rk12_l = 0xffffffffffffffff + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk12_h, $rk12_h, $bit_length @ rk12_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk12_l, $rk12_h, lt + csel $input_h0, $rk12_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + str $ctr32w, [$counter, #12] @ store the updated counter + + st1 { $res1b}, [$output_ptr] @ store all 16B + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_192_kernel,.-aes_gcm_enc_192_kernel +___ + +######################################################################################### +# size_t aes_gcm_dec_192_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_192_kernel +.type aes_gcm_dec_192_kernel,%function +.align 4 +aes_gcm_dec_192_kernel: + cbz x1, .L192_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + ldr $rk0q, [$cc, #0] @ load rk0 + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldr $rk2q, [$cc, #32] @ load rk2 + + lsr $rctr32x, $ctr96_t32x, #32 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $rctr32w, $rctr32w @ rev_ctr32 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + rev $ctr32w, $rctr32w @ CTR block 1 + + add $rctr32w, $rctr32w, #1 @ CTR block 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ldr $rk3q, [$cc, #48] @ load rk3 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldp $rk12_l, $rk12_h, [$cc, #192] @ load rk12 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr3b, $rk11 @ AES block 3 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr2b, $rk11 @ AES block 2 - round 11 + + aese $ctr1b, $rk11 @ AES block 1 - round 11 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr0b, $rk11 @ AES block 0 - round 11 + b.ge .L192_dec_tail @ handle tail + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + rev $ctr32w, $rctr32w @ CTR block 4 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + rev64 $res0b, $res0b @ GHASH block 0 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + rev64 $res1b, $res1b @ GHASH block 1 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + eor $output_l1, $output_l1, $rk12_l @ AES block 1 - round 12 low + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + eor $output_h1, $output_h1, $rk12_h @ AES block 1 - round 12 high + + add $rctr32w, $rctr32w, #1 @ CTR block 5 + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + eor $output_l0, $output_l0, $rk12_l @ AES block 0 - round 12 low + + rev $ctr32w, $rctr32w @ CTR block 6 + eor $output_h0, $output_h0, $rk12_h @ AES block 0 - round 12 high + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + b.ge .L192_dec_prepretail @ do prepretail + + .L192_dec_main_loop: @ main loop start + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $output_h2, $output_h2, $rk12_h @ AES block 4k+2 - round 12 high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + eor $output_l2, $output_l2, $rk12_l @ AES block 4k+2 - round 12 low + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + movi $mod_constant.8b, #0xc2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ldr $res3q, [$input_ptr, #48] @ AES block 4k+7 - load ciphertext + eor $output_l3, $output_l3, $rk12_l @ AES block 4k+3 - round 12 low + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + eor $output_h3, $output_h3, $rk12_h @ AES block 4k+3 - round 12 high + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + rev64 $res1b, $res1b @ GHASH block 4k+5 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + eor $output_l0, $output_l0, $rk12_l @ AES block 4k+4 - round 12 low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + eor $output_l1, $output_l1, $rk12_l @ AES block 4k+5 - round 12 low + + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + eor $output_h1, $output_h1, $rk12_h @ AES block 4k+5 - round 12 high + + eor $output_h0, $output_h0, $rk12_h @ AES block 4k+4 - round 12 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + rev64 $res0b, $res0b @ GHASH block 4k+4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + b.lt .L192_dec_main_loop + + .L192_dec_prepretail: @ PREPRETAIL + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + eor $res0b, $res0b, $acc_lb @ PRE 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $output_h3, $output_h3, $rk12_h @ AES block 4k+3 - round 12 high + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $output_l2, $output_l2, $rk12_l @ AES block 4k+2 - round 12 low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + eor $output_h2, $output_h2, $rk12_h @ AES block 4k+2 - round 12 high + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $output_l3, $output_l3, $rk12_l @ AES block 4k+3 - round 12 low + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + rev64 $res3b, $res3b @ GHASH block 4k+3 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr0b, $rk11 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr2b, $rk11 + + aese $ctr1b, $rk11 + + aese $ctr3b, $rk11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L192_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + + cmp $main_end_input_ptr, #48 + + eor $output_h0, $output_h0, $rk12_h @ AES block 4k+4 - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES block 4k+4 - round 12 low + b.gt .L192_dec_blocks_more_than_3 + + movi $acc_l.8b, #0 + movi $acc_h.8b, #0 + + mov $ctr3b, $ctr2b + mov $ctr2b, $ctr1b + sub $rctr32w, $rctr32w, #1 + + movi $acc_m.8b, #0 + cmp $main_end_input_ptr, #32 + b.gt .L192_dec_blocks_more_than_2 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + sub $rctr32w, $rctr32w, #1 + + b.gt .L192_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L192_dec_blocks_less_than_1 + .L192_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + eor $output_l0, $output_l0, $rk12_l @ AES final-2 block - round 12 low + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_h0, $output_h0, $rk12_h @ AES final-2 block - round 12 high + .L192_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $output_h0, $output_h0, $rk12_h @ AES final-1 block - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES final-1 block - round 12 low + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L192_dec_blocks_more_than_1: @ blocks left > 1 + + rev64 $res0b, $res1b @ GHASH final-1 block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + eor $output_h0, $output_h0, $rk12_h @ AES final block - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES final block - round 12 low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L192_dec_blocks_less_than_1: @ blocks left <= 1 + + mvn $rk12_l, xzr @ rk12_l = 0xffffffffffffffff + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk12_h, xzr @ rk12_h = 0xffffffffffffffff + + lsr $rk12_h, $rk12_h, $bit_length @ rk12_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr32x, $rk12_l, $rk12_h, lt + csel $ctr96_b64x, $rk12_h, xzr, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + and $output_l0, $output_l0, $ctr32x + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + + orr $output_l0, $output_l0, $end_input_ptr + mov $ctr0.d[1], $ctr96_b64x + + rev $ctr32w, $rctr32w + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + str $ctr32w, [$counter, #12] @ store the updated counter + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + + and $output_h0, $output_h0, $ctr96_b64x + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + orr $output_h0, $output_h0, $main_end_input_ptr + stp $output_l0, $output_h0, [$output_ptr] + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_192_kernel,.-aes_gcm_dec_192_kernel +___ +} + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk14_l,$rk14_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; +my $t1="v4"; +my $t1d="d4"; +my $t2="v8"; +my $t2d="d8"; +my $t3="v4"; +my $t3d="d4"; +my $t4="v4"; +my $t4d="d4"; +my $t5="v5"; +my $t5d="d5"; +my $t6="v8"; +my $t6d="d8"; +my $t7="v5"; +my $t7d="d5"; +my $t8="v6"; +my $t8d="d6"; +my $t9="v4"; +my $t9d="d4"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v7"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9,$rk10,$rk11,$rk12,$rk13)=map("v$_.16b",(18..31)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q,$rk10q,$rk11q,$rk12q,$rk13q)=map("q$_",(18..31)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +######################################################################################### +# size_t aes_gcm_enc_256_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_256_kernel +.type aes_gcm_enc_256_kernel,%function +.align 4 +aes_gcm_enc_256_kernel: + cbz x1, .L256_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + ldr $rk0q, [$cc, #0] @ load rk0 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + ldr $rk7q, [$cc, #112] @ load rk7 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + lsr $rctr32x, $ctr96_t32x, #32 + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + rev $rctr32w, $rctr32w @ rev_ctr32 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + + rev $ctr32w, $rctr32w @ CTR block 1 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + ldr $rk1q, [$cc, #16] @ load rk1 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + ldr $rk2q, [$cc, #32] @ load rk2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk13q, [$cc, #208] @ load rk13 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $rk12q, [$cc, #192] @ load rk12 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldp $rk14_l, $rk14_h, [$cc, #224] @ load rk14 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 11 + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 11 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 12 + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 12 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 11 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 11 + + aese $ctr2b, $rk13 @ AES block 2 - round 13 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 12 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 12 + + aese $ctr1b, $rk13 @ AES block 1 - round 13 + + aese $ctr0b, $rk13 @ AES block 0 - round 13 + + aese $ctr3b, $rk13 @ AES block 3 - round 13 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + b.ge .L256_enc_tail @ handle tail + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + + rev $ctr32w, $rctr32w @ CTR block 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + eor $input_l1, $input_l1, $rk14_l @ AES block 1 - round 14 low + eor $input_h1, $input_h1, $rk14_h @ AES block 1 - round 14 high + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_l0, $input_l0, $rk14_l @ AES block 0 - round 14 low + + eor $input_h0, $input_h0, $rk14_h @ AES block 0 - round 14 high + eor $input_h3, $input_h3, $rk14_h @ AES block 3 - round 14 high + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + eor $input_l3, $input_l3, $rk14_l @ AES block 3 - round 14 low + + eor $input_l2, $input_l2, $rk14_l @ AES block 2 - round 14 low + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + eor $input_h2, $input_h2, $rk14_h @ AES block 2 - round 14 high + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + rev $ctr32w, $rctr32w @ CTR block 7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge L256_enc_prepretail @ do prepretail + + .L256_enc_main_loop: @ main loop start + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+7 - load plaintext + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_l3, $input_l3, $rk14_l @ AES block 4k+7 - round 14 low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $input_h2, $input_h2, $rk14_h @ AES block 4k+6 - round 14 high + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $input_l1, $input_l1, $rk14_l @ AES block 4k+5 - round 14 low + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $input_l2, $input_l2, $rk14_l @ AES block 4k+6 - round 14 low + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + eor $input_l0, $input_l0, $rk14_l @ AES block 4k+4 - round 14 low + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + eor $input_h0, $input_h0, $rk14_h @ AES block 4k+4 - round 14 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + eor $mod_t.16b, $acc_hb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + eor $input_h1, $input_h1, $rk14_h @ AES block 4k+5 - round 14 high + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + eor $input_h3, $input_h3, $rk14_h @ AES block 4k+7 - round 14 high + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + fmov $ctr_t3d, $input_l3 @ AES block 4k+7 - mov low + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+7 - mov high + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+7 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+7 - store result + b.lt L256_enc_main_loop + + .L256_enc_prepretail: @ PREPRETAIL + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + + eor $res0b, $res0b, $acc_lb @ PRE 1 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + eor $acc_lb, $acc_lb, $acc_mb + .L256_enc_tail: @ TAIL + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + eor $input_l0, $input_l0, $rk14_l @ AES block 4k+4 - round 14 low + eor $input_h0, $input_h0, $rk14_h @ AES block 4k+4 - round 14 high + + cmp $main_end_input_ptr, #48 + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + b.gt .L256_enc_blocks_more_than_3 + + cmp $main_end_input_ptr, #32 + mov $ctr3b, $ctr2b + movi $acc_l.8b, #0 + + movi $acc_h.8b, #0 + sub $rctr32w, $rctr32w, #1 + + mov $ctr2b, $ctr1b + movi $acc_m.8b, #0 + b.gt .L256_enc_blocks_more_than_2 + + mov $ctr3b, $ctr1b + sub $rctr32w, $rctr32w, #1 + cmp $main_end_input_ptr, #16 + + b.gt .L256_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L256_enc_blocks_less_than_1 + .L256_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $input_l0, $input_l0, $rk14_l @ AES final-2 block - round 14 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk14_h @ AES final-2 block - round 14 high + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + .L256_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-2 block + + eor $input_l0, $input_l0, $rk14_l @ AES final-1 block - round 14 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + eor $input_h0, $input_h0, $rk14_h @ AES final-1 block - round 14 high + + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L256_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + rev64 $res0b, $res1b @ GHASH final-1 block + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $input_l0, $input_l0, $rk14_l @ AES final block - round 14 low + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + eor $input_h0, $input_h0, $rk14_h @ AES final block - round 14 high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + fmov $res1d, $input_l0 @ AES final block - mov low + + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + eor $res1b, $res1b, $ctr3b @ AES final block - result + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + .L256_enc_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + mvn $rk14_l, xzr @ rk14_l = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + + mvn $rk14_h, xzr @ rk14_h = 0xffffffffffffffff + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk14_h, $rk14_h, $bit_length @ rk14_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk14_l, $rk14_h, lt + csel $input_h0, $rk14_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + rev $ctr32w, $rctr32w + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + str $ctr32w, [$counter, #12] @ store the updated counter + + st1 { $res1b}, [$output_ptr] @ store all 16B + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_256_kernel,.-aes_gcm_enc_256_kernel +___ + +{ +my $t8="v4"; +my $t8d="d4"; +my $t9="v6"; +my $t9d="d6"; +######################################################################################### +# size_t aes_gcm_dec_256_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_256_kernel +.type aes_gcm_dec_256_kernel,%function +.align 4 +aes_gcm_dec_256_kernel: + cbz x1, .L256_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ldr $rk8q, [$cc, #128] @ load rk8 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + ldr $rk7q, [$cc, #112] @ load rk7 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + ldr $rk6q, [$cc, #96] @ load rk6 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $rk5q, [$cc, #80] @ load rk5 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + ldr $rk3q, [$cc, #48] @ load rk3 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk0q, [$cc, #0] @ load rk0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + ldr $rk4q, [$cc, #64] @ load rk4 + + ldr $rk13q, [$cc, #208] @ load rk13 + + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldp $rk14_l, $rk14_h, [$cc, #224] @ load rk14 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $rk12q, [$cc, #192] @ load rk12 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 11 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 11 + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 11 + + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 12 + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 12 + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 12 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 12 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr1b, $rk13 @ AES block 1 - round 13 + + aese $ctr2b, $rk13 @ AES block 2 - round 13 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr3b, $rk13 @ AES block 3 - round 13 + + aese $ctr0b, $rk13 @ AES block 0 - round 13 + b.ge .L256_dec_tail @ handle tail + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + rev $ctr32w, $rctr32w @ CTR block 4 + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + rev64 $res1b, $res1b @ GHASH block 1 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + rev64 $res0b, $res0b @ GHASH block 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + eor $output_h0, $output_h0, $rk14_h @ AES block 0 - round 14 high + + eor $output_l0, $output_l0, $rk14_l @ AES block 0 - round 14 low + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + add $rctr32w, $rctr32w, #1 @ CTR block 6 + + eor $output_l1, $output_l1, $rk14_l @ AES block 1 - round 14 low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + eor $output_h1, $output_h1, $rk14_h @ AES block 1 - round 14 high + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + b.ge .L256_dec_prepretail @ do prepretail + + .L256_dec_main_loop: @ main loop start + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + eor $res0b, $res0b, $acc_lb @ PRE 1 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $output_h2, $output_h2, $rk14_h @ AES block 4k+2 - round 14 high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $output_l2, $output_l2, $rk14_l @ AES block 4k+2 - round 14 low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $output_l3, $output_l3, $rk14_l @ AES block 4k+3 - round 14 low + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $output_h3, $output_h3, $rk14_h @ AES block 4k+3 - round 14 high + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + ldr $res3q, [$input_ptr, #48] @ AES block 4k+7 - load ciphertext + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + eor $output_l0, $output_l0, $rk14_l @ AES block 4k+4 - round 14 low + eor $output_h0, $output_h0, $rk14_h @ AES block 4k+4 - round 14 high + + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + rev64 $res1b, $res1b @ GHASH block 4k+5 + eor $output_h1, $output_h1, $rk14_h @ AES block 4k+5 - round 14 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + + eor $output_l1, $output_l1, $rk14_l @ AES block 4k+5 - round 14 low + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + + rev64 $res0b, $res0b @ GHASH block 4k+4 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + b.lt .L256_dec_main_loop + + + .L256_dec_prepretail: @ PREPRETAIL + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + rev64 $res2b, $res2b @ GHASH block 4k+2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + eor $output_h2, $output_h2, $rk14_h @ AES block 4k+2 - round 14 high + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $output_l3, $output_l3, $rk14_l @ AES block 4k+3 - round 14 low + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + eor $output_l2, $output_l2, $rk14_l @ AES block 4k+2 - round 14 low + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $output_h3, $output_h3, $rk14_h @ AES block 4k+3 - round 14 high + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L256_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + + cmp $main_end_input_ptr, #48 + + eor $output_l0, $output_l0, $rk14_l @ AES block 4k+4 - round 14 low + + eor $output_h0, $output_h0, $rk14_h @ AES block 4k+4 - round 14 high + b.gt .L256_dec_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + mov $ctr3b, $ctr2b + movi $acc_m.8b, #0 + + movi $acc_l.8b, #0 + cmp $main_end_input_ptr, #32 + + movi $acc_h.8b, #0 + mov $ctr2b, $ctr1b + b.gt .L256_dec_blocks_more_than_2 + + sub $rctr32w, $rctr32w, #1 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + b.gt .L256_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L256_dec_blocks_less_than_1 + .L256_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_l0, $output_l0, $rk14_l @ AES final-2 block - round 14 low + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + eor $output_h0, $output_h0, $rk14_h @ AES final-2 block - round 14 high + .L256_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $output_l0, $output_l0, $rk14_l @ AES final-1 block - round 14 low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + eor $output_h0, $output_h0, $rk14_h @ AES final-1 block - round 14 high + .L256_dec_blocks_more_than_1: @ blocks left > 1 + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + rev64 $res0b, $res1b @ GHASH final-1 block + + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + eor $output_l0, $output_l0, $rk14_l @ AES final block - round 14 low + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + eor $output_h0, $output_h0, $rk14_h @ AES final block - round 14 high + .L256_dec_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk14_h, xzr @ rk14_h = 0xffffffffffffffff + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + mvn $rk14_l, xzr @ rk14_l = 0xffffffffffffffff + + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk14_h, $rk14_h, $bit_length @ rk14_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr32x, $rk14_l, $rk14_h, lt + csel $ctr96_b64x, $rk14_h, xzr, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + and $output_l0, $output_l0, $ctr32x + + mov $ctr0.d[1], $ctr96_b64x + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + + rev $ctr32w, $rctr32w + + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + + orr $output_l0, $output_l0, $end_input_ptr + + and $output_h0, $output_h0, $ctr96_b64x + + orr $output_h0, $output_h0, $main_end_input_ptr + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + stp $output_l0, $output_h0, [$output_ptr] + + str $ctr32w, [$counter, #12] @ store the updated counter + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_256_kernel,.-aes_gcm_dec_256_kernel +___ +} +} + +$code.=<<___; +.asciz "GHASH for ARMv8, CRYPTOGAMS by " +.align 2 +#endif +___ + +if ($flavour =~ /64/) { ######## 64-bit code + sub unvmov { + my $arg=shift; + + $arg =~ m/q([0-9]+)#(lo|hi),\s*q([0-9]+)#(lo|hi)/o && + sprintf "ins v%d.d[%d],v%d.d[%d]",$1<8?$1:$1+8,($2 eq "lo")?0:1, + $3<8?$3:$3+8,($4 eq "lo")?0:1; + } + foreach(split("\n",$code)) { + s/@\s/\/\//o; # old->new style commentary + print $_,"\n"; + } +} else { ######## 32-bit code + sub unvdup32 { + my $arg=shift; + + $arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o && + sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1; + } + sub unvpmullp64 { + my ($mnemonic,$arg)=@_; + + if ($arg =~ m/q([0-9]+),\s*q([0-9]+),\s*q([0-9]+)/o) { + my $word = 0xf2a00e00|(($1&7)<<13)|(($1&8)<<19) + |(($2&7)<<17)|(($2&8)<<4) + |(($3&7)<<1) |(($3&8)<<2); + $word |= 0x00010001 if ($mnemonic =~ "2"); + # since ARMv7 instructions are always encoded little-endian. + # correct solution is to use .inst directive, but older%%%% + # assemblers don't implement it:-( + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", + $word&0xff,($word>>8)&0xff, + ($word>>16)&0xff,($word>>24)&0xff, + $mnemonic,$arg; + } + } + + foreach(split("\n",$code)) { + s/\b[wx]([0-9]+)\b/r$1/go; # new->old registers + s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go; # new->old registers + s/\/\/\s?/@ /o; # new->old style commentary + + # fix up remaining new-style suffixes + s/\],#[0-9]+/]!/o; + + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or + s/vdup\.32\s+(.*)/unvdup32($1)/geo or + s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or + s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or + s/^(\s+)b\./$1b/o or + s/^(\s+)ret/$1bx\tlr/o; + + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + + print $_,"\n"; + } +} + +close STDOUT; # enforce flush diff --git a/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/modes/asm/aesni-gcm-x86_64.pl index d5ab0457..c3facaa1 100644 --- a/crypto/modes/asm/aesni-gcm-x86_64.pl +++ b/crypto/modes/asm/aesni-gcm-x86_64.pl @@ -67,7 +67,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } @@ -92,6 +92,7 @@ $code=<<___; .type _aesni_ctr32_ghash_6x,\@abi-omnipotent .align 32 _aesni_ctr32_ghash_6x: +.cfi_startproc vmovdqu 0x20($const),$T2 # borrow $T2, .Lone_msb sub \$6,$len vpxor $Z0,$Z0,$Z0 # $Z0 = 0 @@ -399,6 +400,7 @@ _aesni_ctr32_ghash_6x: vpxor $Z0,$Xi,$Xi # modulo-scheduled ret +.cfi_endproc .size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x ___ ###################################################################### @@ -545,6 +547,7 @@ $code.=<<___; .type _aesni_ctr32_6x,\@abi-omnipotent .align 32 _aesni_ctr32_6x: +.cfi_startproc vmovdqu 0x00-0x80($key),$Z0 # borrow $Z0 for $rndkey vmovdqu 0x20($const),$T2 # borrow $T2, .Lone_msb lea -1($rounds),%r13 @@ -631,6 +634,7 @@ _aesni_ctr32_6x: vpshufb $Ii,$T1,$T1 # next counter value vpxor $Z0,$inout5,$inout5 jmp .Loop_ctr32 +.cfi_endproc .size _aesni_ctr32_6x,.-_aesni_ctr32_6x .globl aesni_gcm_encrypt @@ -1081,15 +1085,19 @@ $code=<<___; # assembler is too old .globl aesni_gcm_encrypt .type aesni_gcm_encrypt,\@abi-omnipotent aesni_gcm_encrypt: +.cfi_startproc xor %eax,%eax ret +.cfi_endproc .size aesni_gcm_encrypt,.-aesni_gcm_encrypt .globl aesni_gcm_decrypt .type aesni_gcm_decrypt,\@abi-omnipotent aesni_gcm_decrypt: +.cfi_startproc xor %eax,%eax ret +.cfi_endproc .size aesni_gcm_decrypt,.-aesni_gcm_decrypt ___ }}} diff --git a/crypto/modes/asm/ghash-x86_64.pl b/crypto/modes/asm/ghash-x86_64.pl index 7a3412c0..f9d425ce 100644 --- a/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/modes/asm/ghash-x86_64.pl @@ -117,7 +117,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/modes/build.info b/crypto/modes/build.info index b741be82..fb54b46e 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -24,7 +24,7 @@ IF[{- !$disabled{asm} -}] $MODESASM_armv4=ghash-armv4.S ghashv8-armx.S $MODESDEF_armv4=GHASH_ASM - $MODESASM_aarch64=ghashv8-armx.S + $MODESASM_aarch64=ghashv8-armx.S aes-gcm-armv8_64.S $MODESDEF_aarch64= $MODESASM_parisc11=ghash-parisc.s @@ -76,6 +76,8 @@ GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl INCLUDE[ghash-armv4.o]=.. GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl INCLUDE[ghashv8-armx.o]=.. +GENERATE[aes-gcm-armv8_64.S]=asm/aes-gcm-armv8_64.pl +INCLUDE[aes-gcm-armv8_64.o]=.. GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl INCLUDE[ghash-s390x.o]=.. GENERATE[ghash-c64xplus.S]=asm/ghash-c64xplus.pl diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c index 52956ebc..5835ab6f 100644 --- a/crypto/objects/o_names.c +++ b/crypto/objects/o_names.c @@ -66,10 +66,8 @@ static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b); static CRYPTO_ONCE init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(o_names_init) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); names_lh = lh_OBJ_NAME_new(obj_name_hash, obj_name_cmp); obj_lock = CRYPTO_THREAD_lock_new(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); return names_lh != NULL && obj_lock != NULL; } @@ -90,11 +88,8 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), CRYPTO_THREAD_write_lock(obj_lock); - if (name_funcs_stack == NULL) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); + if (name_funcs_stack == NULL) name_funcs_stack = sk_NAME_FUNCS_new_null(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } if (name_funcs_stack == NULL) { /* ERROR */ goto out; @@ -102,9 +97,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), ret = names_type_num; names_type_num++; for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); name_funcs = OPENSSL_zalloc(sizeof(*name_funcs)); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); if (name_funcs == NULL) { OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); ret = 0; @@ -112,10 +105,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), } name_funcs->hash_func = openssl_lh_strcasehash; name_funcs->cmp_func = obj_strcasecmp; - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); if (!push) { OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index fa1690cc..c7cab61f 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/obj_dat.pl * - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 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 @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[7837] = { +static const unsigned char so[7845] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1085,9 +1085,10 @@ static const unsigned char so[7837] = { 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x09, /* [ 7812] OBJ_id_on_SmtpUTF8Mailbox */ 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x05, /* [ 7820] OBJ_XmppAddr */ 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x07, /* [ 7828] OBJ_SRVName */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ }; -#define NUM_NID 1212 +#define NUM_NID 1213 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2300,10 +2301,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"id-on-SmtpUTF8Mailbox", "Smtp UTF8 Mailbox", NID_id_on_SmtpUTF8Mailbox, 8, &so[7812]}, {"id-on-xmppAddr", "XmppAddr", NID_XmppAddr, 8, &so[7820]}, {"id-on-dnsSRV", "SRVName", NID_SRVName, 8, &so[7828]}, + {"id-on-NAIRealm", "NAIRealm", NID_NAIRealm, 8, &so[7836]}, {"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft}, }; -#define NUM_SN 1203 +#define NUM_SN 1204 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2426,7 +2428,7 @@ static const unsigned int sn_objs[NUM_SN] = { 417, /* "CSPName" */ 1019, /* "ChaCha20" */ 1018, /* "ChaCha20-Poly1305" */ - 1211, /* "ChaCha20-Poly1305-D" */ + 1212, /* "ChaCha20-Poly1305-D" */ 367, /* "CrlID" */ 391, /* "DC" */ 31, /* "DES-CBC" */ @@ -2959,6 +2961,7 @@ static const unsigned int sn_objs[NUM_SN] = { 279, /* "id-mod-qualified-cert-93" */ 281, /* "id-mod-timestamp-protocol" */ 264, /* "id-on" */ + 1211, /* "id-on-NAIRealm" */ 1208, /* "id-on-SmtpUTF8Mailbox" */ 1210, /* "id-on-dnsSRV" */ 858, /* "id-on-permanentIdentifier" */ @@ -3510,7 +3513,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1203 +#define NUM_LN 1204 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3624,6 +3627,7 @@ static const unsigned int ln_objs[NUM_LN] = { 648, /* "Microsoft Smartcard Login" */ 136, /* "Microsoft Trust List Signing" */ 649, /* "Microsoft User Principal Name" */ + 1211, /* "NAIRealm" */ 393, /* "NULL" */ 404, /* "NULL" */ 72, /* "Netscape Base Url" */ @@ -3898,7 +3902,7 @@ static const unsigned int ln_objs[NUM_LN] = { 883, /* "certificateRevocationList" */ 1019, /* "chacha20" */ 1018, /* "chacha20-poly1305" */ - 1211, /* "chacha20-poly1305-draft" */ + 1212, /* "chacha20-poly1305-draft" */ 54, /* "challengePassword" */ 407, /* "characteristic-two-field" */ 395, /* "clearance" */ @@ -4717,7 +4721,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1080 +#define NUM_OBJ 1081 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -5369,6 +5373,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ 1209, /* OBJ_XmppAddr 1 3 6 1 5 5 7 8 5 */ 1210, /* OBJ_SRVName 1 3 6 1 5 5 7 8 7 */ + 1211, /* OBJ_NAIRealm 1 3 6 1 5 5 7 8 8 */ 1208, /* OBJ_id_on_SmtpUTF8Mailbox 1 3 6 1 5 5 7 8 9 */ 348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ 349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ diff --git a/crypto/objects/obj_dat.pl b/crypto/objects/obj_dat.pl index 24f09b49..2cee3e19 100644 --- a/crypto/objects/obj_dat.pl +++ b/crypto/objects/obj_dat.pl @@ -36,10 +36,8 @@ sub der_it return $ret; } -# Output year depends on the year of the script and the input file. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; -my $iYEAR = [localtime([stat($ARGV[0])]->[9])]->[5] + 1900; -$YEAR = $iYEAR if $iYEAR > $YEAR; +# The year the output file is generated. +my $YEAR = [localtime()]->[5] + 1900; # Read input, parse all #define's into OID name and value. # Populate %ln and %sn with long and short names (%dupln and %dupsn) diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 4e801247..86e1fe2e 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1208,4 +1208,5 @@ x942kdf 1207 id_on_SmtpUTF8Mailbox 1208 XmppAddr 1209 SRVName 1210 -chacha20_poly1305_draft 1211 +NAIRealm 1211 +chacha20_poly1305_draft 1212 diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h index 2a02a934..ba290cc6 100644 --- a/crypto/objects/obj_xref.h +++ b/crypto/objects/obj_xref.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by objxref.pl * - * Copyright 1998-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2020 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/crypto/objects/objects.pl b/crypto/objects/objects.pl index 62d6b44b..f4f11fa4 100644 --- a/crypto/objects/objects.pl +++ b/crypto/objects/objects.pl @@ -11,12 +11,8 @@ use Getopt::Std; our($opt_n); getopts('n'); -# Output year depends on the year of the script and the input file. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; -my $iYEAR = [localtime([stat($ARGV[0])]->[9])]->[5] + 1900; -$YEAR = $iYEAR if $iYEAR > $YEAR; -$iYEAR = [localtime([stat($ARGV[1])]->[9])]->[5] + 1900; -$YEAR = $iYEAR if $iYEAR > $YEAR; +# The year the output file is generated. +my $YEAR = [localtime()]->[5] + 1900; open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]"; $max_nid=0; diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 340c0e67..99b3b396 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -611,6 +611,7 @@ id-on 1 : id-on-personalData id-on 3 : id-on-permanentIdentifier : Permanent Identifier id-on 5 : id-on-xmppAddr : XmppAddr id-on 7 : id-on-dnsSRV : SRVName +id-on 8 : id-on-NAIRealm : NAIRealm id-on 9 : id-on-SmtpUTF8Mailbox : Smtp UTF8 Mailbox # personal data attributes diff --git a/crypto/objects/objects.txt.orig b/crypto/objects/objects.txt.orig index 8833acd5..693852aa 100644 --- a/crypto/objects/objects.txt.orig +++ b/crypto/objects/objects.txt.orig @@ -611,6 +611,7 @@ id-on 1 : id-on-personalData id-on 3 : id-on-permanentIdentifier : Permanent Identifier id-on 5 : id-on-xmppAddr : XmppAddr id-on 7 : id-on-dnsSRV : SRVName +id-on 8 : id-on-NAIRealm : NAIRealm id-on 9 : id-on-SmtpUTF8Mailbox : Smtp UTF8 Mailbox # personal data attributes diff --git a/crypto/objects/objxref.pl b/crypto/objects/objxref.pl index e6b69a83..01ecf438 100644 --- a/crypto/objects/objxref.pl +++ b/crypto/objects/objxref.pl @@ -14,12 +14,8 @@ my %oid_tbl; my ($mac_file, $xref_file) = @ARGV; -# Output year depends on the year of the script and the input file. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; -my $iYEAR = [localtime([stat($mac_file)]->[9])]->[5] + 1900; -$YEAR = $iYEAR if $iYEAR > $YEAR; -$iYEAR = [localtime([stat($xref_file)]->[9])]->[5] + 1900; -$YEAR = $iYEAR if $iYEAR > $YEAR; +# The year the output file is generated. +my $YEAR = [localtime()]->[5] + 1900; open(IN, $mac_file) || die "Can't open $mac_file, $!\n"; diff --git a/crypto/params.c b/crypto/params.c index b2ceb132..5d1fc6a6 100644 --- a/crypto/params.c +++ b/crypto/params.c @@ -640,8 +640,11 @@ int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) p->return_size = bytes; if (p->data == NULL) return 1; - return p->data_size >= bytes - && BN_bn2nativepad(val, p->data, bytes) >= 0; + if (p->data_size >= bytes) { + p->return_size = p->data_size; + return BN_bn2nativepad(val, p->data, p->data_size) >= 0; + } + return 0; } OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, @@ -773,6 +776,9 @@ static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len, if (used_len != NULL) *used_len = sz; + if (sz == 0) + return 1; + if (*val == NULL) { char *const q = OPENSSL_malloc(sz); @@ -889,9 +895,8 @@ int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val) if (p == NULL) return 0; p->return_size = 0; - if (val == NULL) - return 0; - return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1); + return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, + val == NULL ? 0 : strlen(val) + 1); } int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, @@ -900,8 +905,6 @@ int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, if (p == NULL) return 0; p->return_size = 0; - if (val == NULL) - return 0; return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len); } diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index 4c3f5f0d..ba98371d 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -17,6 +17,7 @@ #include #include #include +#include "pem_local.h" #ifndef OPENSSL_NO_RSA static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); @@ -33,6 +34,7 @@ IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, @@ -79,14 +81,9 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) # endif -IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, - RSAPrivateKey) - - -IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, - RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, - PEM_STRING_PUBLIC, - RSA_PUBKEY) +IMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) +IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) +IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) #endif #ifndef OPENSSL_NO_DSA static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) @@ -113,9 +110,8 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ } -IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, - DSAPrivateKey) - IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) +IMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) +IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) # ifndef OPENSSL_NO_STDIO DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) { @@ -126,7 +122,7 @@ DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) # endif -IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) +IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) #endif #ifndef OPENSSL_NO_EC static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) @@ -153,8 +149,8 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, return pkey_get_eckey(pktmp, key); /* will free pktmp */ } -IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, - ECPKParameters) +IMPLEMENT_PEM_rw(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, + ECPKParameters) IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, @@ -175,7 +171,8 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, #ifndef OPENSSL_NO_DH -IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) - IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) +IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) +IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) #endif -IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) +IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) +IMPLEMENT_PEM_read(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index ad1dba3f..919769ae 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -244,15 +244,15 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, } /* A TJH addition */ -int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - unsigned char *kstr, int klen, +int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { int i, ret = 0; unsigned char *data = NULL; const char *objstr = NULL; char buf[PEM_BUFSIZE]; - unsigned char *iv = NULL; + const unsigned char *iv = NULL; if (enc != NULL) { objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); @@ -301,7 +301,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), - (char *)iv); + (const char *)iv); /* use the normal code to write things out */ i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index eb07c884..e059328a 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -80,7 +80,7 @@ void PEM_proc_type(char *buf, int type) BIO_snprintf(p, PEM_BUFSIZE - (size_t)(p - buf), "Proc-Type: 4,%s\n", str); } -void PEM_dek_info(char *buf, const char *type, int len, char *str) +void PEM_dek_info(char *buf, const char *type, int len, const char *str) { long i; char *p = buf + strlen(buf); @@ -288,8 +288,9 @@ int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, #ifndef OPENSSL_NO_STDIO int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { BIO *b; int ret; @@ -306,8 +307,9 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, #endif int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; @@ -680,9 +682,20 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, #endif /* Some helpers for PEM_read_bio_ex(). */ -static int sanitize_line(char *linebuf, int len, unsigned int flags) +static int sanitize_line(char *linebuf, int len, unsigned int flags, int first_call) { int i; + if (first_call) { + /* Other BOMs imply unsupported multibyte encoding, + * so don't strip them and let the error raise */ + const unsigned char utf8_bom[3] = {0xEF, 0xBB, 0xBF}; + + if (len > 3 && memcmp(linebuf, utf8_bom, 3) == 0) { + memmove(linebuf, linebuf + 3, len - 3); + linebuf[len - 3] = 0; + len -= 3; + } + } if (flags & PEM_FLAG_EAY_COMPATIBLE) { /* Strip trailing whitespace */ @@ -727,6 +740,7 @@ static int get_name(BIO *bp, char **name, unsigned int flags) char *linebuf; int ret = 0; int len; + int first_call = 1; /* * Need to hold trailing NUL (accounted for by BIO_gets() and the newline @@ -747,7 +761,8 @@ static int get_name(BIO *bp, char **name, unsigned int flags) } /* Strip trailing garbage and standardize ending. */ - len = sanitize_line(linebuf, len, flags & ~PEM_FLAG_ONLY_B64); + len = sanitize_line(linebuf, len, flags & ~PEM_FLAG_ONLY_B64, first_call); + first_call = 0; /* Allow leading empty or non-matching lines. */ } while (strncmp(linebuf, beginstr, BEGINLEN) != 0 @@ -819,7 +834,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, } if (!strncmp(linebuf, endstr, ENDLEN) || got_header == IN_HEADER) flags_mask &= ~PEM_FLAG_ONLY_B64; - len = sanitize_line(linebuf, len, flags & flags_mask); + len = sanitize_line(linebuf, len, flags & flags_mask, 0); /* Check for end of header. */ if (linebuf[0] == '\n') { diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h new file mode 100644 index 00000000..3b501abd --- /dev/null +++ b/crypto/pem/pem_local.h @@ -0,0 +1,128 @@ +/* + * Copyright 2019 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 + */ + +/* + * TODO(v3.0): the IMPLEMENT macros in include/openssl/pem.h should be + * moved here. + */ + +#include +#include + +/* Alternative IMPLEMENT macros for provided serializers */ + +# define IMPLEMENT_PEM_provided_write_body_vars(type, asn1) \ + int ret = 0; \ + const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ; \ + OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \ + \ + if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \ + OSSL_SERIALIZER_CTX_free(ctx); \ + goto legacy; \ + } +# define IMPLEMENT_PEM_provided_write_body_pass() \ + ret = 1; \ + if (kstr == NULL && cb == NULL) { \ + if (u != NULL) { \ + kstr = u; \ + klen = strlen(u); \ + } else { \ + cb = PEM_def_callback; \ + } \ + } \ + if (enc != NULL) { \ + ret = 0; \ + if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \ + NULL)) { \ + ret = 1; \ + if (kstr != NULL \ + && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \ + ret = 0; \ + else if (cb != NULL \ + && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, 1, \ + cb, u)) \ + ret = 0; \ + } \ + } \ + if (!ret) { \ + OSSL_SERIALIZER_CTX_free(ctx); \ + return 0; \ + } +# define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \ + ret = OSSL_SERIALIZER_to_##outtype(ctx, out); \ + OSSL_SERIALIZER_CTX_free(ctx); \ + return ret +# define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename) \ + legacy: \ + return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ + x, NULL, NULL, 0, NULL, NULL) +# define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ + writename) \ + legacy: \ + return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ + x, enc, kstr, klen, cb, u) + +# define IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, \ + OUTTYPE, outtype, writename) \ + PEM_write_fnsig(name, type, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename); \ + } + + +# define IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, \ + OUTTYPE, outtype, writename) \ + PEM_write_cb_fnsig(name, type, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \ + IMPLEMENT_PEM_provided_write_body_pass(); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ + writename); \ + } + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) +# define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) + +# else + +# define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, FILE, fp, write) +# define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, FILE, fp, write) + +# endif + +# define IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, BIO, bio, write_bio) +# define IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, BIO, bio, write_bio) + +# define IMPLEMENT_PEM_provided_write(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) + diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c index 642d4f6e..6b784050 100644 --- a/crypto/pem/pem_pk8.c +++ b/crypto/pem/pem_pk8.c @@ -18,12 +18,14 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); + const char *kstr, int klen, + pem_password_cb *cb, void *u); #ifndef OPENSSL_NO_STDIO static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); + const char *kstr, int klen, + pem_password_cb *cb, void *u); #endif /* * These functions write a private key in PKCS#8 format: it is a "drop in" @@ -33,35 +35,35 @@ static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, */ int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); } int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); } int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); } int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); } static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, + const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { X509_SIG *p8; @@ -149,34 +151,35 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, #ifndef OPENSSL_NO_STDIO int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u) + const char *kstr, int klen, + pem_password_cb *cb, void *u) { return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); } int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); } int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, - char *kstr, int klen, + const char *kstr, int klen, pem_password_cb *cb, void *u) { return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); } int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, - void *u) + const char *kstr, int klen, + pem_password_cb *cb, void *u) { return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); } static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, + const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { BIO *bp; diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 7132a7ad..c619cc11 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -17,94 +17,72 @@ #include #include #include +#include +#include +#include +#include "crypto/store.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "pem_local.h" int pem_check_suffix(const char *pem_str, const char *suffix); EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; EVP_PKEY *ret = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; + UI_METHOD *ui_method = NULL; - if (!PEM_bytes_read_bio_secmem(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, - cb, u)) + if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - p = data; - if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); - if (p8inf == NULL) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x != NULL) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - X509_SIG *p8; - int klen; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if (p8 == NULL) - goto p8err; - if (cb) - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - else - klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (klen < 0) { - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); + if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u)) == NULL) + goto err; +#ifndef OPENSSL_NO_SECURE_HEAP + { + int on = 1; + if (!OSSL_STORE_ctrl(ctx, OSSL_STORE_C_USE_SECMEM, &on)) goto err; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (p8inf == NULL) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { - const EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); - if (!ameth || !ameth->old_priv_decode) - goto p8err; - ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); } - p8err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); +#endif + + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { + ret = OSSL_STORE_INFO_get1_PKEY(info); + break; + } + OSSL_STORE_INFO_free(info); + } + + if (ret != NULL && x != NULL) + *x = ret; + err: - OPENSSL_secure_free(nm); - OPENSSL_secure_clear_free(data, len); + ossl_store_detach_pem_bio(ctx); + UI_destroy_method(ui_method); + OSSL_STORE_INFO_free(info); return ret; } -int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) +PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio) { + IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, PrivateKey); + + IMPLEMENT_PEM_provided_write_body_pass(); + IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio); + + legacy: if (x->ameth == NULL || x->ameth->priv_encode != NULL) - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, - (char *)kstr, klen, cb, u); - return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u); + return PEM_write_bio_PKCS8PrivateKey(out, x, enc, + (const char *)kstr, klen, cb, u); + return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u); } -int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, +int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { char pem_str[80]; @@ -115,51 +93,44 @@ int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; EVP_PKEY *ret = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, - bp, 0, NULL)) - return NULL; - p = data; + if ((ctx = ossl_store_attach_pem_bio(bp, UI_null(), NULL)) == NULL) + goto err; - if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { - ret = EVP_PKEY_new(); - if (ret == NULL) - goto err; - if (!EVP_PKEY_set_type_str(ret, nm, slen) - || !ret->ameth->param_decode - || !ret->ameth->param_decode(ret, &p, len)) { - EVP_PKEY_free(ret); - ret = NULL; - goto err; - } - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PARAMS) { + ret = OSSL_STORE_INFO_get1_PARAMS(info); + break; } + OSSL_STORE_INFO_free(info); } + + if (ret != NULL && x != NULL) + *x = ret; + err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); + ossl_store_detach_pem_bio(ctx); + OSSL_STORE_INFO_free(info); return ret; } -int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) { char pem_str[80]; + IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, Parameters); + + IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio); + + legacy: if (!x->ameth || !x->ameth->param_encode) return 0; BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, - pem_str, bp, x, NULL, NULL, 0, 0, NULL); + pem_str, out, x, NULL, NULL, 0, 0, NULL); } #ifndef OPENSSL_NO_STDIO @@ -179,8 +150,8 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, return ret; } -int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, +int PEM_write_PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { BIO *b; @@ -203,25 +174,37 @@ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; DH *ret = NULL; + EVP_PKEY *pkey = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info = NULL; + UI_METHOD *ui_method = NULL; - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) + if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - p = data; - if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) - ret = d2i_DHxparams(x, &p, len); - else - ret = d2i_DHparams(x, &p, len); + if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u)) == NULL) + goto err; - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); + while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PARAMS) { + pkey = OSSL_STORE_INFO_get0_PARAMS(info); + if (EVP_PKEY_id(pkey) == EVP_PKEY_DHX + || EVP_PKEY_id(pkey) == EVP_PKEY_DH) { + ret = EVP_PKEY_get1_DH(pkey); + break; + } + } + OSSL_STORE_INFO_free(info); + } + + if (ret != NULL && x != NULL) + *x = ret; + + err: + ossl_store_detach_pem_bio(ctx); + UI_destroy_method(ui_method); + OSSL_STORE_INFO_free(info); return ret; } diff --git a/crypto/pem/pem_sign.c b/crypto/pem/pem_sign.c index 4be03a47..c12afd5c 100644 --- a/crypto/pem/pem_sign.c +++ b/crypto/pem/pem_sign.c @@ -19,7 +19,8 @@ int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } -int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +int PEM_SignUpdate(EVP_MD_CTX *ctx, + const unsigned char *data, unsigned int count) { return EVP_DigestUpdate(ctx, data, count); } diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 6bcde93d..95bd4da3 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -424,7 +424,7 @@ static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); static void write_rsa(unsigned char **out, RSA *rsa, int ispub); static void write_dsa(unsigned char **out, DSA *dsa, int ispub); -static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) +static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) { unsigned char *p; unsigned int bitlen, magic = 0, keyalg; @@ -473,7 +473,7 @@ static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) return outlen; } -static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) +static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub) { unsigned char *tmp = NULL; int outlen, wrlen; @@ -599,12 +599,12 @@ static void write_dsa(unsigned char **out, DSA *dsa, int ispub) return; } -int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) +int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk) { return do_i2b_bio(out, pk, 0); } -int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) +int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk) { return do_i2b_bio(out, pk, 1); } @@ -780,7 +780,7 @@ EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) return ret; } -static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, +static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u) { int outlen = 24, pklen; @@ -865,7 +865,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, return -1; } -int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, +int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u) { unsigned char *tmp = NULL; diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl index e52f2f6e..5fcd0526 100755 --- a/crypto/perlasm/ppc-xlate.pl +++ b/crypto/perlasm/ppc-xlate.pl @@ -49,7 +49,7 @@ my $globl = sub { /osx/ && do { $name = "_$name"; last; }; - /linux.*(32|64le)/ + /linux.*(32|64(le|v2))/ && do { $ret .= ".globl $name"; if (!$$type) { $ret .= "\n.type $name,\@function"; @@ -80,7 +80,7 @@ my $globl = sub { }; my $text = sub { my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; - $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); + $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/); $ret; }; my $machine = sub { @@ -186,7 +186,7 @@ my $vmr = sub { # Some ABIs specify vrsave, special-purpose register #256, as reserved # for system use. -my $no_vrsave = ($flavour =~ /aix|linux64le/); +my $no_vrsave = ($flavour =~ /aix|linux64(le|v2)/); my $mtspr = sub { my ($f,$idx,$ra) = @_; if ($idx == 256 && $no_vrsave) { @@ -320,7 +320,7 @@ while($line=<>) { if ($label) { my $xlated = ($GLOBALS{$label} or $label); print "$xlated:"; - if ($flavour =~ /linux.*64le/) { + if ($flavour =~ /linux.*64(le|v2)/) { if ($TYPES{$label} =~ /function/) { printf "\n.localentry %s,0\n",$xlated; } diff --git a/crypto/perlasm/s390x.pm b/crypto/perlasm/s390x.pm index 7fb55c78..b2fea801 100644 --- a/crypto/perlasm/s390x.pm +++ b/crypto/perlasm/s390x.pm @@ -18,14 +18,14 @@ use Carp qw(confess); use Exporter qw(import); our @EXPORT=qw(PERLASM_BEGIN PERLASM_END); -our @EXPORT_OK=qw(AUTOLOAD LABEL INCLUDE stfle); +our @EXPORT_OK=qw(AUTOLOAD LABEL INCLUDE stfle stck); our %EXPORT_TAGS=( - # long-displacement facility - LD => [qw(clgfi)], + # store-clock-fast facility + SCF => [qw(stckf)], # general-instruction-extension facility GE => [qw(risbg)], # extended-immediate facility - EI => [qw(lt)], + EI => [qw(clfi clgfi lt)], # miscellaneous-instruction-extensions facility 1 MI1 => [qw(risbgn)], # message-security assist @@ -36,6 +36,8 @@ our %EXPORT_TAGS=( MSA5 => [qw(ppno prno)], # message-security-assist extension 8 MSA8 => [qw(kma)], + # message-security-assist extension 9 + MSA9 => [qw(kdsa)], # vector facility VX => [qw(vgef vgeg vgbm vzero vone vgm vgmb vgmh vgmf vgmg vl vlr vlrep vlrepb vlreph vlrepf vlrepg vleb vleh vlef vleg vleib @@ -102,7 +104,7 @@ our %EXPORT_TAGS=( VXD => [qw(vlrlr vlrl vstrlr vstrl vap vcp vcvb vcvbg vcvd vcvdg vdp vlip vmp vmsp vpkz vpsop vrp vsdp vsrp vsp vtp vupkz)], ); -Exporter::export_ok_tags(qw(LD GE EI MI1 MSA MSA4 MSA5 MSA8 VX VXE VXD)); +Exporter::export_ok_tags(qw(SCF GE EI MI1 MSA MSA4 MSA5 MSA8 MSA9 VX VXE VXD)); our $AUTOLOAD; @@ -130,7 +132,7 @@ sub AUTOLOAD { confess(err("PARSE")) if (grep(!defined($_),@_)); my $token; for ($AUTOLOAD) { - $token=".$1" if (/^.*::([A-Z_]+)$/); # uppercase: directive + $token=lc(".$1") if (/^.*::([A-Z_]+)$/);# uppercase: directive $token="\t$1" if (/^.*::([a-z]+)$/); # lowercase: mnemonic confess(err("PARSE")) if (!defined($token)); } @@ -159,7 +161,24 @@ sub stfle { S(0xb2b0,@_); } -# MISC +sub stck { + confess(err("ARGNUM")) if ($#_!=0); + S(0xb205,@_); +} + +# store-clock-fast facility + +sub stckf { + confess(err("ARGNUM")) if ($#_!=0); + S(0xb27c,@_); +} + +# extended-immediate facility + +sub clfi { + confess(err("ARGNUM")) if ($#_!=1); + RILa(0xc2f,@_); +} sub clgfi { confess(err("ARGNUM")) if ($#_!=1); @@ -171,11 +190,15 @@ sub lt { RXYa(0xe312,@_); } +# general-instruction-extension facility + sub risbg { confess(err("ARGNUM")) if ($#_<3||$#_>4); RIEf(0xec55,@_); } +# miscellaneous-instruction-extensions facility 1 + sub risbgn { confess(err("ARGNUM")) if ($#_<3||$#_>4); RIEf(0xec59,@_); @@ -248,6 +271,13 @@ sub kma { RRFb(0xb929,@_); } +# MSA9 + +sub kdsa { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb93a,@_); +} + # VX - Support Instructions sub vgef { @@ -2537,7 +2567,7 @@ sub RIEf { $out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$r2)).","; $out.=sprintf("%#06x",($i3<<8)|$i4).","; $out.=sprintf("%#06x",($i5<<8)|($opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub RILa { @@ -2551,7 +2581,7 @@ sub RILa { $out.=sprintf("%#06x",(($opcode>>4)<<8|$r1<<4|($opcode&0xf))).","; $out.=sprintf("%#06x",($i2>>16)).","; $out.=sprintf("%#06x",($i2&0xffff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub RRE { @@ -2562,7 +2592,10 @@ sub RRE { my ($opcode,$r1,$r2)=(shift,get_R(shift),get_R(shift)); $out.="\t.long\t".sprintf("%#010x",($opcode<<16|$r1<<4|$r2)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn"; + # RRE can have 0 ops e.g., pcc. + $out.="\t$ops" if ((defined($ops))&&($ops ne '')); + $out.="\n"; } sub RRFb { @@ -2575,7 +2608,7 @@ sub RRFb { $out.="\t.long\t" .sprintf("%#010x",($opcode<<16|$r3<<12|$m4<<8|$r1<<4|$r2)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub RXYa { @@ -2589,7 +2622,7 @@ sub RXYa { $out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$x2)).","; $out.=sprintf("%#06x",($b2<<12|($d2&0xfff))).","; $out.=sprintf("%#06x",(($d2>>12)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub S { @@ -2600,7 +2633,7 @@ sub S { my ($opcode,$d2,$b2)=(shift,get_DB(shift)); $out.="\t.long\t".sprintf("%#010x",($opcode<<16|$b2<<12|$d2)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIa { @@ -2615,7 +2648,7 @@ sub VRIa { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; $out.=sprintf("%#06x",$i2).","; $out.=sprintf("%#06x",($m3<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIb { @@ -2630,7 +2663,7 @@ sub VRIb { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; $out.=sprintf("%#06x",($i2<<8|$i3)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIc { @@ -2645,7 +2678,7 @@ sub VRIc { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v3&0xf)).","; $out.=sprintf("%#06x",$i2).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRId { @@ -2660,7 +2693,7 @@ sub VRId { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$i4)).","; $out.=sprintf("%#06x",($m5<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIe { @@ -2675,7 +2708,7 @@ sub VRIe { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; $out.=sprintf("%#06x",($i3<<4|$m5)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIf { @@ -2690,7 +2723,7 @@ sub VRIf { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<4)|$i4>>4).","; $out.=sprintf("%#06x",(($i4&0xf)<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIg { @@ -2705,7 +2738,7 @@ sub VRIg { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; $out.=sprintf("%#06x",($i4<<8|$m5<<4|$i3>>4)).","; $out.=sprintf("%#06x",(($i3&0xf)<<12|RXB($v1,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIh { @@ -2720,7 +2753,7 @@ sub VRIh { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; $out.=sprintf("%#06x",$i2).","; $out.=sprintf("%#06x",($i3<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRIi { @@ -2735,7 +2768,7 @@ sub VRIi { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|$r2).","; $out.=sprintf("%#06x",($m4<<4|$i3>>4)).","; $out.=sprintf("%#06x",(($i3&0xf)<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRa { @@ -2750,7 +2783,7 @@ sub VRRa { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",($m5<<4|$m4)).","; $out.=sprintf("%#06x",($m3<<12|RXB($v1,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRb { @@ -2765,7 +2798,7 @@ sub VRRb { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<4)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRc { @@ -2780,7 +2813,7 @@ sub VRRc { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$m6<<4|$m5)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRd { @@ -2795,7 +2828,7 @@ sub VRRd { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<8|$m6<<4)).","; $out.=sprintf("%#06x",(($v4&0xf)<<12|RXB($v1,$v2,$v3,$v4)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRe { @@ -2810,7 +2843,7 @@ sub VRRe { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",(($v3&0xf)<<12|$m6<<8|$m5)).","; $out.=sprintf("%#06x",(($v4&0xf)<<12|RXB($v1,$v2,$v3,$v4)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRf { @@ -2825,7 +2858,7 @@ sub VRRf { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|$r2)).","; $out.=sprintf("%#06x",($r3<<12)).","; $out.=sprintf("%#06x",(RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRg { @@ -2839,7 +2872,7 @@ sub VRRg { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf))).","; $out.=sprintf("%#06x",0x0000).","; $out.=sprintf("%#06x",(RXB(0,$v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRh { @@ -2854,7 +2887,7 @@ sub VRRh { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf))).","; $out.=sprintf("%#06x",(($v2&0xf)<<12|$m3<<4)).","; $out.=sprintf("%#06x",(RXB(0,$v1,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRRi { @@ -2869,7 +2902,7 @@ sub VRRi { $out.=sprintf("%#06x",($opcode&0xff00|$r1<<4|($v2&0xf))).","; $out.=sprintf("%#06x",($m3<<4))."\,"; $out.=sprintf("%#06x",(RXB(0,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRSa { @@ -2884,7 +2917,7 @@ sub VRSa { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v3&0xf))).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRSb { @@ -2899,7 +2932,7 @@ sub VRSb { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|$r3)).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",($m4<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRSc { @@ -2914,7 +2947,7 @@ sub VRSc { $out.=sprintf("%#06x",($opcode&0xff00|$r1<<4|($v3&0xf))).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",($m4<<12|RXB(0,$v3)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRSd { @@ -2929,7 +2962,7 @@ sub VRSd { $out.=sprintf("%#06x",($opcode&0xff00|$r3)).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",(($v1&0xf)<<12|RXB(0,0,0,$v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRV { @@ -2944,7 +2977,7 @@ sub VRV { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",($m3<<12|RXB($v1,$v2)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VRX { @@ -2959,7 +2992,7 @@ sub VRX { $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($x2))).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",($m3<<12|RXB($v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } sub VSI { @@ -2974,7 +3007,7 @@ sub VSI { $out.=sprintf("%#06x",($opcode&0xff00|$i3)).","; $out.=sprintf("%#06x",($b2<<12|$d2)).","; $out.=sprintf("%#06x",(($v1&0xf)<<12|RXB(0,0,0,$v1)<<8|$opcode&0xff)); - $out.="\t# $memn\t$ops\n" + $out.="\t# $memn\t$ops\n"; } # diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c index 2b4ca653..ccb9acb1 100644 --- a/crypto/pkcs12/p12_sbag.c +++ b/crypto/pkcs12/p12_sbag.c @@ -12,7 +12,7 @@ #include #include "p12_local.h" -#if !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid) { return PKCS12_get_attr_gen(bag->attrib, attr_nid); diff --git a/crypto/poly1305/asm/poly1305-s390x.pl b/crypto/poly1305/asm/poly1305-s390x.pl index 7f1f8347..4a93064f 100755 --- a/crypto/poly1305/asm/poly1305-s390x.pl +++ b/crypto/poly1305/asm/poly1305-s390x.pl @@ -45,7 +45,7 @@ use strict; use FindBin qw($Bin); use lib "$Bin/../.."; -use perlasm::s390x qw(:DEFAULT :LD :GE :EI :MI1 :VX AUTOLOAD LABEL INCLUDE); +use perlasm::s390x qw(:DEFAULT :GE :EI :MI1 :VX AUTOLOAD LABEL INCLUDE); # $output is the last argument if it looks like a file (it has an extension) # $flavour is the first argument if it doesn't look like a file diff --git a/crypto/poly1305/asm/poly1305-x86.pl b/crypto/poly1305/asm/poly1305-x86.pl index 9aa1bc16..08b0da1a 100755 --- a/crypto/poly1305/asm/poly1305-x86.pl +++ b/crypto/poly1305/asm/poly1305-x86.pl @@ -70,7 +70,7 @@ if ($sse2) { $avx = ($1>=2.09) + ($1>=2.10); } - if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9]\.[0-9]+)/) { + if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } } diff --git a/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/poly1305/asm/poly1305-x86_64.pl index c27d8779..8a469219 100755 --- a/crypto/poly1305/asm/poly1305-x86_64.pl +++ b/crypto/poly1305/asm/poly1305-x86_64.pl @@ -91,7 +91,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=12); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } @@ -170,6 +170,7 @@ $code.=<<___; .type poly1305_init,\@function,3 .align 32 poly1305_init: +.cfi_startproc xor %rax,%rax mov %rax,0($ctx) # initialize hash value mov %rax,8($ctx) @@ -221,6 +222,7 @@ $code.=<<___; mov \$1,%eax .Lno_key: ret +.cfi_endproc .size poly1305_init,.-poly1305_init .type poly1305_blocks,\@function,4 @@ -300,6 +302,7 @@ $code.=<<___; .type poly1305_emit,\@function,3 .align 32 poly1305_emit: +.cfi_startproc .Lemit: mov 0($ctx),%r8 # load hash value mov 8($ctx),%r9 @@ -320,6 +323,7 @@ poly1305_emit: mov %rcx,8($mac) ret +.cfi_endproc .size poly1305_emit,.-poly1305_emit ___ if ($avx) { @@ -344,15 +348,18 @@ $code.=<<___; .type __poly1305_block,\@abi-omnipotent .align 32 __poly1305_block: +.cfi_startproc ___ &poly1305_iteration(); $code.=<<___; ret +.cfi_endproc .size __poly1305_block,.-__poly1305_block .type __poly1305_init_avx,\@abi-omnipotent .align 32 __poly1305_init_avx: +.cfi_startproc mov $r0,$h0 mov $r1,$h1 xor $h2,$h2 @@ -510,6 +517,7 @@ __poly1305_init_avx: lea -48-64($ctx),$ctx # size [de-]optimization ret +.cfi_endproc .size __poly1305_init_avx,.-__poly1305_init_avx .type poly1305_blocks_avx,\@function,4 @@ -1375,6 +1383,7 @@ $code.=<<___; .type poly1305_emit_avx,\@function,3 .align 32 poly1305_emit_avx: +.cfi_startproc cmpl \$0,20($ctx) # is_base2_26? je .Lemit @@ -1425,6 +1434,7 @@ poly1305_emit_avx: mov %rcx,8($mac) ret +.cfi_endproc .size poly1305_emit_avx,.-poly1305_emit_avx ___ @@ -2743,6 +2753,7 @@ $code.=<<___; .type poly1305_init_base2_44,\@function,3 .align 32 poly1305_init_base2_44: +.cfi_startproc xor %rax,%rax mov %rax,0($ctx) # initialize hash value mov %rax,8($ctx) @@ -2784,6 +2795,7 @@ ___ $code.=<<___; mov \$1,%eax ret +.cfi_endproc .size poly1305_init_base2_44,.-poly1305_init_base2_44 ___ { @@ -2795,6 +2807,7 @@ $code.=<<___; .type poly1305_blocks_vpmadd52,\@function,4 .align 32 poly1305_blocks_vpmadd52: +.cfi_startproc shr \$4,$len jz .Lno_data_vpmadd52 # too short @@ -2901,6 +2914,7 @@ poly1305_blocks_vpmadd52: .Lno_data_vpmadd52: ret +.cfi_endproc .size poly1305_blocks_vpmadd52,.-poly1305_blocks_vpmadd52 ___ } @@ -2918,6 +2932,7 @@ $code.=<<___; .type poly1305_blocks_vpmadd52_4x,\@function,4 .align 32 poly1305_blocks_vpmadd52_4x: +.cfi_startproc shr \$4,$len jz .Lno_data_vpmadd52_4x # too short @@ -3342,6 +3357,7 @@ poly1305_blocks_vpmadd52_4x: .Lno_data_vpmadd52_4x: ret +.cfi_endproc .size poly1305_blocks_vpmadd52_4x,.-poly1305_blocks_vpmadd52_4x ___ } @@ -3360,6 +3376,7 @@ $code.=<<___; .type poly1305_blocks_vpmadd52_8x,\@function,4 .align 32 poly1305_blocks_vpmadd52_8x: +.cfi_startproc shr \$4,$len jz .Lno_data_vpmadd52_8x # too short @@ -3715,6 +3732,7 @@ $code.=<<___; .Lno_data_vpmadd52_8x: ret +.cfi_endproc .size poly1305_blocks_vpmadd52_8x,.-poly1305_blocks_vpmadd52_8x ___ } @@ -3722,6 +3740,7 @@ $code.=<<___; .type poly1305_emit_base2_44,\@function,3 .align 32 poly1305_emit_base2_44: +.cfi_startproc mov 0($ctx),%r8 # load hash value mov 8($ctx),%r9 mov 16($ctx),%r10 @@ -3752,6 +3771,7 @@ poly1305_emit_base2_44: mov %rcx,8($mac) ret +.cfi_endproc .size poly1305_emit_base2_44,.-poly1305_emit_base2_44 ___ } } } @@ -3802,6 +3822,7 @@ $code.=<<___; .type xor128_encrypt_n_pad,\@abi-omnipotent .align 16 xor128_encrypt_n_pad: +.cfi_startproc sub $otp,$inp sub $otp,$out mov $len,%r10 # put len aside @@ -3843,12 +3864,14 @@ xor128_encrypt_n_pad: .Ldone_enc: mov $otp,%rax ret +.cfi_endproc .size xor128_encrypt_n_pad,.-xor128_encrypt_n_pad .globl xor128_decrypt_n_pad .type xor128_decrypt_n_pad,\@abi-omnipotent .align 16 xor128_decrypt_n_pad: +.cfi_startproc sub $otp,$inp sub $otp,$out mov $len,%r10 # put len aside @@ -3894,6 +3917,7 @@ xor128_decrypt_n_pad: .Ldone_dec: mov $otp,%rax ret +.cfi_endproc .size xor128_decrypt_n_pad,.-xor128_decrypt_n_pad ___ } diff --git a/crypto/property/property.c b/crypto/property/property.c index 2089e21d..0e31b8fa 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -21,21 +21,30 @@ #include "crypto/sparse_array.h" #include "property_local.h" -/* The number of elements in the query cache before we initiate a flush */ +/* + * The number of elements in the query cache before we initiate a flush. + * If reducing this, also ensure the stochastic test in test/property_test.c + * isn't likely to fail. + */ #define IMPL_CACHE_FLUSH_THRESHOLD 500 +typedef struct { + void *method; + int (*up_ref)(void *); + void (*free)(void *); +} METHOD; + typedef struct { const OSSL_PROVIDER *provider; OSSL_PROPERTY_LIST *properties; - void *method; - void (*method_destruct)(void *); + METHOD method; } IMPLEMENTATION; DEFINE_STACK_OF(IMPLEMENTATION) typedef struct { const char *query; - void *method; + METHOD method; char body[1]; } QUERY; @@ -67,6 +76,16 @@ DEFINE_SPARSE_ARRAY_OF(ALGORITHM); static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid); static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *c); +static int ossl_method_up_ref(METHOD *method) +{ + return (*method->up_ref)(method->method); +} + +static void ossl_method_free(METHOD *method) +{ + (*method->free)(method->method); +} + int ossl_property_read_lock(OSSL_METHOD_STORE *p) { return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0; @@ -95,15 +114,17 @@ static int query_cmp(const QUERY *a, const QUERY *b) static void impl_free(IMPLEMENTATION *impl) { if (impl != NULL) { - if (impl->method_destruct) - impl->method_destruct(impl->method); + ossl_method_free(&impl->method); OPENSSL_free(impl); } } static void impl_cache_free(QUERY *elem) { - OPENSSL_free(elem); + if (elem != NULL) { + ossl_method_free(&elem->method); + OPENSSL_free(elem); + } } static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a) @@ -132,7 +153,7 @@ OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx) return NULL; } if ((res->lock = CRYPTO_THREAD_lock_new()) == NULL) { - OPENSSL_free(res->algs); + ossl_sa_ALGORITHM_free(res->algs); OPENSSL_free(res); return NULL; } @@ -180,13 +201,14 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, impl = OPENSSL_malloc(sizeof(*impl)); if (impl == NULL) return 0; - if (method_up_ref != NULL && !method_up_ref(method)) { + impl->method.method = method; + impl->method.up_ref = method_up_ref; + impl->method.free = method_destruct; + if (!ossl_method_up_ref(&impl->method)) { OPENSSL_free(impl); return 0; } impl->provider = prov; - impl->method = method; - impl->method_destruct = method_destruct; /* * Insert into the hash table if required. @@ -262,10 +284,10 @@ int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) { IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i); - if (impl->method == method) { + if (impl->method.method == method) { + impl_free(impl); sk_IMPLEMENTATION_delete(alg->impls, i); ossl_property_unlock(store); - impl_free(impl); return 1; } } @@ -279,6 +301,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, ALGORITHM *alg; IMPLEMENTATION *impl; OSSL_PROPERTY_LIST *pq = NULL, *p2; + METHOD *best_method = NULL; int ret = 0; int j, best = -1, score, optional; @@ -302,7 +325,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, if (prop_query == NULL) { if ((impl = sk_IMPLEMENTATION_value(alg->impls, 0)) != NULL) { - *method = impl->method; + best_method = &impl->method; ret = 1; } goto fin; @@ -322,14 +345,18 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, impl = sk_IMPLEMENTATION_value(alg->impls, j); score = ossl_property_match_count(pq, impl->properties); if (score > best) { - *method = impl->method; + best_method = &impl->method; + best = score; ret = 1; if (!optional) goto fin; - best = score; } } fin: + if (ret && ossl_method_up_ref(best_method)) + *method = best_method->method; + else + ret = 0; ossl_property_unlock(store); ossl_property_free(pq); return ret; @@ -414,7 +441,7 @@ static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state) state->seed = n; if ((n & 1) != 0) - OPENSSL_free(lh_QUERY_delete(state->cache, c)); + impl_cache_free(lh_QUERY_delete(state->cache, c)); else state->nelem++; } @@ -446,34 +473,38 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, { ALGORITHM *alg; QUERY elem, *r; + int res = 0; if (nid <= 0 || store == NULL) return 0; ossl_property_read_lock(store); alg = ossl_method_store_retrieve(store, nid); - if (alg == NULL) { - ossl_property_unlock(store); - return 0; - } + if (alg == NULL) + goto err; elem.query = prop_query != NULL ? prop_query : ""; r = lh_QUERY_retrieve(alg->cache, &elem); - if (r == NULL) { - ossl_property_unlock(store); - return 0; + if (r == NULL) + goto err; + if (ossl_method_up_ref(&r->method)) { + *method = r->method.method; + res = 1; } - *method = r->method; +err: ossl_property_unlock(store); - return 1; + return res; } int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, - const char *prop_query, void *method) + const char *prop_query, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)) { QUERY elem, *old, *p = NULL; ALGORITHM *alg; size_t len; + int res = 1; if (nid <= 0 || store == NULL) return 0; @@ -484,36 +515,41 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, if (store->need_flush) ossl_method_cache_flush_some(store); alg = ossl_method_store_retrieve(store, nid); - if (alg == NULL) { - ossl_property_unlock(store); - return 0; - } + if (alg == NULL) + goto err; if (method == NULL) { elem.query = prop_query; - if (lh_QUERY_delete(alg->cache, &elem) != NULL) + if ((old = lh_QUERY_delete(alg->cache, &elem)) != NULL) { + impl_cache_free(old); store->nelem--; - ossl_property_unlock(store); - return 1; + } + goto end; } p = OPENSSL_malloc(sizeof(*p) + (len = strlen(prop_query))); if (p != NULL) { p->query = p->body; - p->method = method; + p->method.method = method; + p->method.up_ref = method_up_ref; + p->method.free = method_destruct; + if (!ossl_method_up_ref(&p->method)) + goto err; memcpy((char *)p->query, prop_query, len + 1); if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) { - OPENSSL_free(old); - ossl_property_unlock(store); - return 1; + impl_cache_free(old); + goto end; } if (!lh_QUERY_error(alg->cache)) { if (++store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD) store->need_flush = 1; - ossl_property_unlock(store); - return 1; + goto end; } + ossl_method_free(&p->method); } - ossl_property_unlock(store); +err: + res = 0; OPENSSL_free(p); - return 0; +end: + ossl_property_unlock(store); + return res; } diff --git a/crypto/property/property_err.c b/crypto/property/property_err.c index 477dedfd..5f819301 100644 --- a/crypto/property/property_err.c +++ b/crypto/property/property_err.c @@ -24,8 +24,8 @@ static const ERR_STRING_DATA PROP_str_reasons[] = { "not an octal digit"}, {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT), "not a decimal digit"}, - {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMETER), - "no matching string delimeter"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMITER), + "no matching string delimiter"}, {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value"}, {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed"}, {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long"}, diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h index 25cfde46..950a0c6c 100644 --- a/crypto/property/property_local.h +++ b/crypto/property/property_local.h @@ -11,7 +11,6 @@ #include #include "internal/property.h" -typedef struct ossl_property_list_st OSSL_PROPERTY_LIST; typedef int OSSL_PROPERTY_IDX; /* Property string functions */ @@ -23,17 +22,9 @@ OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, /* Property list functions */ void ossl_property_free(OSSL_PROPERTY_LIST *p); int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query); -int ossl_property_match_count(const OSSL_PROPERTY_LIST *query, - const OSSL_PROPERTY_LIST *defn); OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, const OSSL_PROPERTY_LIST *b); -/* Property definition functions */ -OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s); - -/* Property query functions */ -OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s); - /* Property definition cache functions */ OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop); int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop, diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index a16bcd6d..6476f65b 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -203,7 +203,7 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, s++; } if (*s == '\0') { - ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER, + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMITER, "HERE-->%c%s", delim, *t); return 0; } @@ -492,7 +492,7 @@ int ossl_property_match_count(const OSSL_PROPERTY_LIST *query, /* * Handle the cases of a missing value and a query with no corresponding - * definition. The former fails for any comparision except inequality, + * definition. The former fails for any comparison except inequality, * the latter is treated as a comparison against the Boolean false. */ if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) { @@ -568,6 +568,8 @@ int ossl_property_parse_init(OPENSSL_CTX *ctx) "version", /* Version number of this provider */ "fips", /* FIPS supporting provider */ "engine", /* An old style engine masquerading as a provider */ + "format", /* output format for serializers */ + "type", /* output type for serializers */ }; size_t i; diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 4f3123d6..2f2d69a0 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -18,6 +18,9 @@ #include "internal/provider.h" #include "internal/refcount.h" #include "provider_local.h" +#ifndef FIPS_MODE +# include +#endif static OSSL_PROVIDER *provider_new(const char *name, OSSL_provider_init_fn *init_function); @@ -873,8 +876,9 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf }, { OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex }, { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free }, + { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, + { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))OSSL_SELF_TEST_get_callback }, #endif - { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, { OSSL_FUNC_CRYPTO_FREE, (void (*)(void))CRYPTO_free }, diff --git a/crypto/rand/drbg_hash.c b/crypto/rand/drbg_hash.c index 72068c67..f087d889 100644 --- a/crypto/rand/drbg_hash.c +++ b/crypto/rand/drbg_hash.c @@ -309,37 +309,16 @@ int drbg_hash_init(RAND_DRBG *drbg) RAND_DRBG_HASH *hash = &drbg->data.hash; /* - * Confirm digest is allowed. Outside FIPS_MODE we allow all non-legacy - * digests. Inside FIPS_MODE we only allow approved digests. Also no XOF - * digests (such as SHAKE). + * Confirm digest is allowed. We allow all digests that are not XOF + * (such as SHAKE). In FIPS mode, the fetch will fail for non-approved + * digests. */ - switch (drbg->type) { - default: - return 0; - - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - case NID_sha512_224: - case NID_sha512_256: - case NID_sha3_224: - case NID_sha3_256: - case NID_sha3_384: - case NID_sha3_512: -#ifndef FIPS_MODE - case NID_blake2b512: - case NID_blake2s256: - case NID_sm3: -#endif - break; - } - md = EVP_MD_fetch(drbg->libctx, ossl_prov_util_nid_to_name(drbg->type), ""); if (md == NULL) return 0; + if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0) + return 0; drbg->meth = &drbg_hash_meth; diff --git a/crypto/rand/drbg_hmac.c b/crypto/rand/drbg_hmac.c index 0289070f..3bda6c0d 100644 --- a/crypto/rand/drbg_hmac.c +++ b/crypto/rand/drbg_hmac.c @@ -203,37 +203,17 @@ int drbg_hmac_init(RAND_DRBG *drbg) RAND_DRBG_HMAC *hmac = &drbg->data.hmac; /* - * Confirm digest is allowed. Outside FIPS_MODE we allow all non-legacy - * digests. Inside FIPS_MODE we only allow approved digests. Also no XOF - * digests (such as SHAKE). + * Confirm digest is allowed. We allow all digests that are not XOF + * (such as SHAKE). In FIPS mode, the fetch will fail for non-approved + * digests. */ - switch (drbg->type) { - default: - return 0; - - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - case NID_sha512_224: - case NID_sha512_256: - case NID_sha3_224: - case NID_sha3_256: - case NID_sha3_384: - case NID_sha3_512: -#ifndef FIPS_MODE - case NID_blake2b512: - case NID_blake2s256: - case NID_sm3: -#endif - break; - } - md = EVP_MD_fetch(drbg->libctx, ossl_prov_util_nid_to_name(drbg->type), ""); if (md == NULL) return 0; + if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0) + return 0; + drbg->meth = &drbg_hmac_meth; if (hmac->ctx == NULL) { diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 90e37786..2c9ed3fb 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -503,7 +503,9 @@ void RAND_DRBG_free(RAND_DRBG *drbg) drbg->meth->uninstantiate(drbg); rand_pool_free(drbg->adin_pool); CRYPTO_THREAD_lock_free(drbg->lock); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data); +#ifndef FIPS_MODE + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data); +#endif if (drbg->secure) OPENSSL_secure_clear_free(drbg, sizeof(*drbg)); @@ -1098,6 +1100,7 @@ int rand_drbg_enable_locking(RAND_DRBG *drbg) return 1; } +#ifndef FIPS_MODE /* * Get and set the EXDATA */ @@ -1110,7 +1113,7 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) { return CRYPTO_get_ex_data(&drbg->ex_data, idx); } - +#endif /* * The following functions provide a RAND_METHOD that works on the diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 3508cfb2..0be9db1c 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -311,6 +311,9 @@ int RAND_poll(void) const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth == NULL) + return 0; + if (meth == RAND_OpenSSL()) { /* fill random pool and seed the master DRBG */ RAND_DRBG *drbg = RAND_DRBG_get0_master(); @@ -831,7 +834,7 @@ void RAND_seed(const void *buf, int num) { const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth->seed != NULL) + if (meth != NULL && meth->seed != NULL) meth->seed(buf, num); } @@ -839,7 +842,7 @@ void RAND_add(const void *buf, int num, double randomness) { const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth->add != NULL) + if (meth != NULL && meth->add != NULL) meth->add(buf, num, randomness); } @@ -851,18 +854,20 @@ void RAND_add(const void *buf, int num, double randomness) int rand_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) { RAND_DRBG *drbg; - int ret; const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth != RAND_OpenSSL()) - return meth->bytes(buf, num); + if (meth != NULL && meth != RAND_OpenSSL()) { + if (meth->bytes != NULL) + return meth->bytes(buf, num); + RANDerr(RAND_F_RAND_PRIV_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED); + return -1; + } drbg = OPENSSL_CTX_get0_private_drbg(ctx); - if (drbg == NULL) - return 0; + if (drbg != NULL) + return RAND_DRBG_bytes(drbg, buf, num); - ret = RAND_DRBG_bytes(drbg, buf, num); - return ret; + return 0; } int RAND_priv_bytes(unsigned char *buf, int num) @@ -873,10 +878,9 @@ int RAND_priv_bytes(unsigned char *buf, int num) int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) { RAND_DRBG *drbg; - int ret; const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth != RAND_OpenSSL()) { + if (meth != NULL && meth != RAND_OpenSSL()) { if (meth->bytes != NULL) return meth->bytes(buf, num); RANDerr(RAND_F_RAND_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED); @@ -884,11 +888,10 @@ int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) } drbg = OPENSSL_CTX_get0_public_drbg(ctx); - if (drbg == NULL) - return 0; + if (drbg != NULL) + return RAND_DRBG_bytes(drbg, buf, num); - ret = RAND_DRBG_bytes(drbg, buf, num); - return ret; + return 0; } int RAND_bytes(unsigned char *buf, int num) @@ -896,13 +899,14 @@ int RAND_bytes(unsigned char *buf, int num) return rand_bytes_ex(NULL, buf, num); } -#if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE) +#if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODE) int RAND_pseudo_bytes(unsigned char *buf, int num) { const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth->pseudorand != NULL) + if (meth != NULL && meth->pseudorand != NULL) return meth->pseudorand(buf, num); + RANDerr(RAND_F_RAND_PSEUDO_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED); return -1; } #endif @@ -911,7 +915,7 @@ int RAND_status(void) { const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth->status != NULL) + if (meth != NULL && meth->status != NULL) return meth->status(); return 0; } diff --git a/crypto/rand/rand_local.h b/crypto/rand/rand_local.h index 7817df80..310f03fc 100644 --- a/crypto/rand/rand_local.h +++ b/crypto/rand/rand_local.h @@ -308,8 +308,10 @@ struct rand_drbg_st { size_t seedlen; DRBG_STATUS state; +#ifndef FIPS_MODE /* Application data, mainly used in the KATs. */ CRYPTO_EX_DATA ex_data; +#endif /* Implementation specific data */ union { diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index 7f3ea30e..a733f041 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -19,6 +19,7 @@ #include "crypto/rand.h" #include #include "internal/dso.h" + #ifdef __linux # include # ifdef DEVRANDOM_WAIT @@ -81,7 +82,8 @@ static uint64_t get_timer_bits(void); # define OSSL_POSIX_TIMER_OKAY # endif # endif -#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */ +#endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) + || defined(__DJGPP__) */ #if defined(OPENSSL_RAND_SEED_NONE) /* none means none. this simplifies the following logic */ @@ -851,4 +853,5 @@ static uint64_t get_timer_bits(void) # endif return time(NULL); } -#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */ +#endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) + || defined(__DJGPP__) */ diff --git a/crypto/rand/rand_vms.c b/crypto/rand/rand_vms.c index fa74e744..13d913bc 100644 --- a/crypto/rand/rand_vms.c +++ b/crypto/rand/rand_vms.c @@ -32,10 +32,21 @@ # pragma message disable DOLLARID # endif +# include /* SYS$GET_ENTROPY presence */ + # ifndef OPENSSL_RAND_SEED_OS # error "Unsupported seeding method configured; must be os" # endif +/* + * DATA COLLECTION METHOD + * ====================== + * + * This is a method to get low quality entropy. + * It works by collecting all kinds of statistical data that + * VMS offers and using them as random seed. + */ + /* We need to make sure we have the right size pointer in some cases */ # if __INITIAL_POINTER_SIZE == 64 # pragma pointer_size save @@ -330,7 +341,7 @@ static void massage_JPI(ILE3 *items) */ #define ENTROPY_FACTOR 20 -size_t rand_pool_acquire_entropy(RAND_POOL *pool) +size_t data_collect_method(RAND_POOL *pool) { ILE3 JPI_items_64bit[OSSL_NELEM(JPI_item_data_64bit) + 1]; ILE3 RMI_items_64bit[OSSL_NELEM(RMI_item_data_64bit) + 1]; @@ -445,15 +456,9 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) * If we can't feed the requirements from the caller, we're in deep trouble. */ if (!ossl_assert(total_length >= bytes_needed)) { - char neededstr[20]; - char availablestr[20]; - - BIO_snprintf(neededstr, sizeof(neededstr), "%zu", bytes_needed); - BIO_snprintf(availablestr, sizeof(availablestr), "%zu", total_length); - RANDerr(RAND_F_RAND_POOL_ACQUIRE_ENTROPY, - RAND_R_RANDOM_POOL_UNDERFLOW); - ERR_add_error_data(4, "Needed: ", neededstr, ", Available: ", - availablestr); + ERR_raise_data(ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW, + "Needed: %zu, Available: %zu", + bytes_needed, total_length); return 0; } @@ -483,7 +488,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) /* * Add process id, thread id, and a high resolution timestamp * (where available, which is OpenVMS v8.4 and up) to ensure that - * the nonce is unique whith high probability for different process + * the nonce is unique with high probability for different process * instances. */ data.pid = getpid(); @@ -497,6 +502,80 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); } +/* + * SYS$GET_ENTROPY METHOD + * ====================== + * + * This is a high entropy method based on a new system service that is + * based on getentropy() from FreeBSD 12. It's only used if available, + * and its availability is detected at run-time. + * + * We assume that this function provides full entropy random output. + */ +#define PUBLIC_VECTORS "SYS$LIBRARY:SYS$PUBLIC_VECTORS.EXE" +#define GET_ENTROPY "SYS$GET_ENTROPY" + +static int get_entropy_address_flag = 0; +static int (*get_entropy_address)(void *buffer, size_t buffer_size) = NULL; +static int init_get_entropy_address(void) +{ + if (get_entropy_address_flag == 0) + get_entropy_address = dlsym(dlopen(PUBLIC_VECTORS, 0), GET_ENTROPY); + get_entropy_address_flag = 1; + return get_entropy_address != NULL; +} + +size_t get_entropy_method(RAND_POOL *pool) +{ + /* + * The documentation says that SYS$GET_ENTROPY will give a maximum of + * 256 bytes of data. + */ + unsigned char buffer[256]; + size_t bytes_needed; + size_t bytes_to_get = 0; + uint32_t status; + + for (bytes_needed = rand_pool_bytes_needed(pool, 1); + bytes_needed > 0; + bytes_needed -= bytes_to_get) { + bytes_to_get = + bytes_needed > sizeof(buffer) ? sizeof(buffer) : bytes_needed; + + status = get_entropy_address(buffer, bytes_to_get); + if (status == SS$_RETRY) { + /* Set to zero so the loop doesn't diminish |bytes_needed| */ + bytes_to_get = 0; + /* Should sleep some amount of time */ + continue; + } + + if (status != SS$_NORMAL) { + lib$signal(status); + return 0; + } + + rand_pool_add(pool, buffer, bytes_to_get, 8 * bytes_to_get); + } + + return rand_pool_entropy_available(pool); +} + +/* + * MAIN ENTROPY ACQUISITION FUNCTIONS + * ================================== + * + * These functions are called by the RAND / DRBG functions + */ + +size_t rand_pool_acquire_entropy(RAND_POOL *pool) +{ + if (init_get_entropy_address()) + return get_entropy_method(pool); + return data_collect_method(pool); +} + + int rand_pool_add_additional_data(RAND_POOL *pool) { struct { diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c index 5f67c87c..213a7425 100644 --- a/crypto/rand/rand_win.c +++ b/crypto/rand/rand_win.c @@ -133,7 +133,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) /* * Add process id, thread id, and a high resolution timestamp to - * ensure that the nonce is unique whith high probability for + * ensure that the nonce is unique with high probability for * different process instances. */ data.pid = GetCurrentProcessId(); @@ -163,7 +163,7 @@ int rand_pool_add_additional_data(RAND_POOL *pool) return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); } -# if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE) +# if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODE) int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) { RAND_poll(); diff --git a/crypto/rc2/rc2_cbc.c b/crypto/rc2/rc2_cbc.c index 58a4b3e6..acfd4fde 100644 --- a/crypto/rc2/rc2_cbc.c +++ b/crypto/rc2/rc2_cbc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/rc2/rc2_ecb.c b/crypto/rc2/rc2_ecb.c index fec2c101..da086e65 100644 --- a/crypto/rc2/rc2_ecb.c +++ b/crypto/rc2/rc2_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" #include diff --git a/crypto/rc2/rc2_skey.c b/crypto/rc2/rc2_skey.c index 33068d48..542ce0f6 100644 --- a/crypto/rc2/rc2_skey.c +++ b/crypto/rc2/rc2_skey.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/rc2/rc2cfb64.c b/crypto/rc2/rc2cfb64.c index 9b85368d..298be79d 100644 --- a/crypto/rc2/rc2cfb64.c +++ b/crypto/rc2/rc2cfb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/rc2/rc2ofb64.c b/crypto/rc2/rc2ofb64.c index 4270009e..097f8bef 100644 --- a/crypto/rc2/rc2ofb64.c +++ b/crypto/rc2/rc2ofb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/rc4/asm/rc4-md5-x86_64.pl b/crypto/rc4/asm/rc4-md5-x86_64.pl index c9381ca9..560eb4c4 100644 --- a/crypto/rc4/asm/rc4-md5-x86_64.pl +++ b/crypto/rc4/asm/rc4-md5-x86_64.pl @@ -486,6 +486,7 @@ $code.=<<___; .type RC4_set_key,\@function,3 .align 16 RC4_set_key: +.cfi_startproc lea 8($dat),$dat lea ($inp,$len),$inp neg $len @@ -521,6 +522,7 @@ RC4_set_key: mov %eax,-8($dat) mov %eax,-4($dat) ret +.cfi_endproc .size RC4_set_key,.-RC4_set_key .globl RC4_options diff --git a/crypto/rc4/asm/rc4-s390x.pl b/crypto/rc4/asm/rc4-s390x.pl index c90013cf..8214b488 100644 --- a/crypto/rc4/asm/rc4-s390x.pl +++ b/crypto/rc4/asm/rc4-s390x.pl @@ -186,7 +186,7 @@ $code.=<<___; RC4_set_key: stm${g} %r6,%r8,6*$SIZE_T($sp) lhi $cnt,256 - la $idx,0(%r0) + la $idx,0 sth $idx,0($key) .align 4 .L1stloop: @@ -196,8 +196,8 @@ RC4_set_key: lghi $ikey,-256 lr $cnt,$len - la $iinp,0(%r0) - la $idx,0(%r0) + la $iinp,0 + la $idx,0 .align 16 .L2ndloop: llgc $acc,2+256($ikey,$key) @@ -214,7 +214,7 @@ RC4_set_key: jz .Ldone brct $cnt,.L2ndloop lr $cnt,$len - la $iinp,0(%r0) + la $iinp,0 j .L2ndloop .Ldone: lm${g} %r6,%r8,6*$SIZE_T($sp) diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl index ebca0473..7c0f1a4c 100755 --- a/crypto/rc4/asm/rc4-x86_64.pl +++ b/crypto/rc4/asm/rc4-x86_64.pl @@ -455,6 +455,7 @@ $code.=<<___; .type RC4_set_key,\@function,3 .align 16 RC4_set_key: +.cfi_startproc lea 8($dat),$dat lea ($inp,$len),$inp neg $len @@ -521,6 +522,7 @@ RC4_set_key: mov %eax,-8($dat) mov %eax,-4($dat) ret +.cfi_endproc .size RC4_set_key,.-RC4_set_key .globl RC4_options diff --git a/crypto/rc4/rc4_enc.c b/crypto/rc4/rc4_enc.c index c4753d93..8479091c 100644 --- a/crypto/rc4/rc4_enc.c +++ b/crypto/rc4/rc4_enc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc4_local.h" diff --git a/crypto/rc4/rc4_skey.c b/crypto/rc4/rc4_skey.c index 42c4a208..e9d60ca0 100644 --- a/crypto/rc4/rc4_skey.c +++ b/crypto/rc4/rc4_skey.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc4_local.h" #include diff --git a/crypto/rc5/rc5_ecb.c b/crypto/rc5/rc5_ecb.c index 51c14fd5..39c36b61 100644 --- a/crypto/rc5/rc5_ecb.c +++ b/crypto/rc5/rc5_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" #include diff --git a/crypto/rc5/rc5_enc.c b/crypto/rc5/rc5_enc.c index c91fa99c..0fa80a50 100644 --- a/crypto/rc5/rc5_enc.c +++ b/crypto/rc5/rc5_enc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include "rc5_local.h" diff --git a/crypto/rc5/rc5_skey.c b/crypto/rc5/rc5_skey.c index 22a5df14..dc8617f6 100644 --- a/crypto/rc5/rc5_skey.c +++ b/crypto/rc5/rc5_skey.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" diff --git a/crypto/rc5/rc5cfb64.c b/crypto/rc5/rc5cfb64.c index 001e1240..99b1753a 100644 --- a/crypto/rc5/rc5cfb64.c +++ b/crypto/rc5/rc5cfb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" diff --git a/crypto/rc5/rc5ofb64.c b/crypto/rc5/rc5ofb64.c index c3ae5d8c..7fc19fd1 100644 --- a/crypto/rc5/rc5ofb64.c +++ b/crypto/rc5/rc5ofb64.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" diff --git a/crypto/ripemd/build.info b/crypto/ripemd/build.info index a0a45b0e..055da5da 100644 --- a/crypto/ripemd/build.info +++ b/crypto/ripemd/build.info @@ -12,12 +12,20 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -SOURCE[../../libcrypto]=rmd_dgst.c rmd_one.c $RMD160ASM - # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules -DEFINE[../../libcrypto]=$RMD160DEF DEFINE[../providers/libimplementations.a]=$RMD160DEF +SOURCE[../../libcrypto]=rmd_dgst.c rmd_one.c $RMD160ASM +DEFINE[../../libcrypto]=$RMD160DEF + +# When all deprecated symbols are removed, libcrypto doesn't export the +# RIPEMD160 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{"deprecated"} + && (defined $config{"api"} && $config{"api"} >= 30000) -}] + SOURCE[../../providers/liblegacy.a]=rmd_dgst.c rmd_one.c $RMD160ASM + DEFINE[../../providers/liblegacy.a]=$RMD160DEF +ENDIF + GENERATE[rmd-586.s]=asm/rmd-586.pl DEPEND[rmd-586.s]=../perlasm/x86asm.pl diff --git a/crypto/ripemd/rmd_dgst.c b/crypto/ripemd/rmd_dgst.c index f4a69c88..d815f173 100644 --- a/crypto/ripemd/rmd_dgst.c +++ b/crypto/ripemd/rmd_dgst.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "rmd_local.h" #include diff --git a/crypto/ripemd/rmd_one.c b/crypto/ripemd/rmd_one.c index 5efb36b8..30a83da8 100644 --- a/crypto/ripemd/rmd_one.c +++ b/crypto/ripemd/rmd_one.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 69e7c5ea..ade3fe25 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -13,8 +13,11 @@ #include #include #include +#include +#include "internal/param_build.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/rsa.h" #include "rsa_local.h" #ifndef OPENSSL_NO_CMS @@ -1045,6 +1048,111 @@ static int rsa_pkey_check(const EVP_PKEY *pkey) return RSA_check_key_ex(pkey->pkey.rsa, NULL); } +static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.rsa->dirty_cnt; +} + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + int want_domainparams) +{ + RSA *rsa = pk->pkey.rsa; + OSSL_PARAM_BLD tmpl; + const BIGNUM *n = RSA_get0_n(rsa), *e = RSA_get0_e(rsa); + const BIGNUM *d = RSA_get0_d(rsa); + STACK_OF(BIGNUM_const) *primes = NULL, *exps = NULL, *coeffs = NULL; + int numprimes = 0, numexps = 0, numcoeffs = 0; + OSSL_PARAM *params = NULL; + void *provkey = NULL; + + /* + * There are no domain parameters for RSA keys, or rather, they are + * included in the key data itself. + */ + if (want_domainparams) + goto err; + + /* Get all the primes and CRT params */ + if ((primes = sk_BIGNUM_const_new_null()) == NULL + || (exps = sk_BIGNUM_const_new_null()) == NULL + || (coeffs = sk_BIGNUM_const_new_null()) == NULL) + goto err; + + if (!rsa_get0_all_params(rsa, primes, exps, coeffs)) + goto err; + + /* Public parameters must always be present */ + if (n == NULL || e == NULL) + goto err; + + if (d != NULL) { + /* It's a private key, so we should have everything else too */ + numprimes = sk_BIGNUM_const_num(primes); + numexps = sk_BIGNUM_const_num(exps); + numcoeffs = sk_BIGNUM_const_num(coeffs); + + if (numprimes < 2 || numexps < 2 || numcoeffs < 1) + goto err; + + /* assert that an OSSL_PARAM_BLD has enough space. */ + if (!ossl_assert(/* n, e */ 2 + /* d */ 1 + /* numprimes */ 1 + + numprimes + numexps + numcoeffs + <= OSSL_PARAM_BLD_MAX)) + goto err; + } + + ossl_param_bld_init(&tmpl); + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_N, n) + || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, e)) + goto err; + + if (d != NULL) { + int i; + + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_D, d)) + goto err; + + for (i = 0; i < numprimes; i++) { + const BIGNUM *num = sk_BIGNUM_const_value(primes, i); + + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_FACTOR, + num)) + goto err; + } + + for (i = 0; i < numexps; i++) { + const BIGNUM *num = sk_BIGNUM_const_value(exps, i); + + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT, + num)) + goto err; + } + + for (i = 0; i < numcoeffs; i++) { + const BIGNUM *num = sk_BIGNUM_const_value(coeffs, i); + + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT, + num)) + goto err; + } + } + + if ((params = ossl_param_bld_to_param(&tmpl)) == NULL) + goto err; + + /* We export, the provider imports */ + provkey = evp_keymgmt_importkey(keymgmt, params); + + err: + sk_BIGNUM_const_free(primes); + sk_BIGNUM_const_free(exps); + sk_BIGNUM_const_free(coeffs); + ossl_param_bld_free(params); + return provkey; +} + const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { { EVP_PKEY_RSA, @@ -1077,7 +1185,13 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { rsa_item_verify, rsa_item_sign, rsa_sig_info_set, - rsa_pkey_check + rsa_pkey_check, + + 0, 0, + 0, 0, 0, 0, + + rsa_pkey_dirty_cnt, + rsa_pkey_export_to }, { @@ -1116,5 +1230,11 @@ const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { rsa_item_verify, rsa_item_sign, 0, - rsa_pkey_check + rsa_pkey_check, + + 0, 0, + 0, 0, 0, 0, + + rsa_pkey_dirty_cnt, + rsa_pkey_export_to }; diff --git a/crypto/rsa/rsa_depr.c b/crypto/rsa/rsa_depr.c index c34c6058..ed632626 100644 --- a/crypto/rsa/rsa_depr.c +++ b/crypto/rsa/rsa_depr.c @@ -13,7 +13,7 @@ */ #include -#if OPENSSL_API_0_9_8 +#ifdef OPENSSL_NO_DEPRECATED_0_9_8 NON_EMPTY_TRANSLATION_UNIT #else diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index c87b7097..cb2abff6 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -108,6 +108,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, for (i = 0; i < primes; i++) bitsr[i] = (i < rmd) ? quo + 1 : quo; + rsa->dirty_cnt++; + /* We need the RSA components non-NULL */ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) goto err; diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index abdabfb4..f538f72d 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -9,12 +9,14 @@ #include #include +#include +#include +#include #include "internal/cryptlib.h" #include "internal/refcount.h" #include "crypto/bn.h" -#include -#include #include "crypto/evp.h" +#include "crypto/rsa.h" #include "rsa_local.h" RSA *RSA_new(void) @@ -86,9 +88,11 @@ RSA *RSA_new_method(ENGINE *engine) #endif ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; +#ifndef FIPS_MODE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { goto err; } +#endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); @@ -121,7 +125,9 @@ void RSA_free(RSA *r) ENGINE_finish(r->engine); #endif +#ifndef FIPS_MODE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); @@ -153,6 +159,7 @@ int RSA_up_ref(RSA *r) return i > 1 ? 1 : 0; } +#ifndef FIPS_MODE int RSA_set_ex_data(RSA *r, int idx, void *arg) { return CRYPTO_set_ex_data(&r->ex_data, idx, arg); @@ -162,6 +169,7 @@ void *RSA_get_ex_data(const RSA *r, int idx) { return CRYPTO_get_ex_data(&r->ex_data, idx); } +#endif /* * Define a scaling constant for our fixed point arithmetic. @@ -327,6 +335,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) r->d = d; BN_set_flags(r->d, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } @@ -350,6 +359,7 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) r->q = q; BN_set_flags(r->q, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } @@ -379,6 +389,7 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) r->iqmp = iqmp; BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } @@ -443,6 +454,7 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], } r->version = RSA_ASN1_VERSION_MULTI; + r->dirty_cnt++; return 1; err: @@ -578,6 +590,11 @@ const BIGNUM *RSA_get0_iqmp(const RSA *r) return r->iqmp; } +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) +{ + return r->pss; +} + void RSA_clear_flags(RSA *r, int flags) { r->flags &= ~flags; @@ -613,3 +630,506 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) return -1; return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); } + +DEFINE_STACK_OF(BIGNUM) + +int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs) +{ + STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL; + int pnum; + + if (primes == NULL || exps == NULL || coeffs == NULL) + return 0; + + pnum = sk_BIGNUM_num(primes); + if (pnum < 2 + || pnum != sk_BIGNUM_num(exps) + || pnum != sk_BIGNUM_num(coeffs) + 1) + return 0; + + if (!RSA_set0_factors(r, sk_BIGNUM_value(primes, 0), + sk_BIGNUM_value(primes, 1)) + || !RSA_set0_crt_params(r, sk_BIGNUM_value(exps, 0), + sk_BIGNUM_value(exps, 1), + sk_BIGNUM_value(coeffs, 0))) + return 0; + + old_infos = r->prime_infos; + + if (pnum > 2) { + int i; + + prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); + if (prime_infos == NULL) + return 0; + + for (i = 2; i < pnum; i++) { + BIGNUM *prime = sk_BIGNUM_value(primes, i); + BIGNUM *exp = sk_BIGNUM_value(exps, i); + BIGNUM *coeff = sk_BIGNUM_value(coeffs, i - 1); + RSA_PRIME_INFO *pinfo = NULL; + + if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL)) + goto err; + + /* Using rsa_multip_info_new() is wasteful, so allocate directly */ + if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + pinfo->r = prime; + pinfo->d = exp; + pinfo->t = coeff; + BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); + (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); + } + + r->prime_infos = prime_infos; + + if (!rsa_multip_calc_product(r)) { + r->prime_infos = old_infos; + goto err; + } + } + + if (old_infos != NULL) { + /* + * This is hard to deal with, since the old infos could + * also be set by this function and r, d, t should not + * be freed in that case. So currently, stay consistent + * with other *set0* functions: just free it... + */ + sk_RSA_PRIME_INFO_pop_free(old_infos, rsa_multip_info_free); + } + + r->version = pnum > 2 ? RSA_ASN1_VERSION_MULTI : RSA_ASN1_VERSION_DEFAULT; + r->dirty_cnt++; + + return 1; + err: + /* r, d, t should not be freed */ + sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); + return 0; +} + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs) +{ + RSA_PRIME_INFO *pinfo; + int i, pnum; + + if (r == NULL) + return 0; + + pnum = RSA_get_multi_prime_extra_count(r); + + sk_BIGNUM_const_push(primes, RSA_get0_p(r)); + sk_BIGNUM_const_push(primes, RSA_get0_q(r)); + sk_BIGNUM_const_push(exps, RSA_get0_dmp1(r)); + sk_BIGNUM_const_push(exps, RSA_get0_dmq1(r)); + sk_BIGNUM_const_push(coeffs, RSA_get0_iqmp(r)); + for (i = 0; i < pnum; i++) { + pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); + sk_BIGNUM_const_push(primes, pinfo->r); + sk_BIGNUM_const_push(exps, pinfo->d); + sk_BIGNUM_const_push(coeffs, pinfo->t); + } + + return 1; +} + +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) +{ + OSSL_PARAM pad_params[2], *p = pad_params; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + || ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING, + pad_mode, NULL); + + *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, &pad_mode); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, pad_params); +} + +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode) +{ + OSSL_PARAM pad_params[2], *p = pad_params; + + if (ctx == NULL || pad_mode == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + || ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, + pad_mode); + + *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, pad_mode); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, pad_params)) + return 0; + + return 1; + +} + +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + const char *name; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); + + name = (md == NULL) ? "" : EVP_MD_name(md); + + return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, name, NULL); +} + +int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops) +{ + OSSL_PARAM rsa_params[3], *p = rsa_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)mdname, + strlen(mdname) + 1); + if (mdprops != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string( + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)mdprops, + strlen(mdprops) + 1); + } + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, rsa_params); +} + +int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namelen) +{ + OSSL_PARAM rsa_params[2], *p = rsa_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, + name, namelen); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, rsa_params)) + return -1; + + return 1; +} + +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + /* 80 should be big enough */ + char name[80] = ""; + + if (ctx == NULL || md == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md); + + if (EVP_PKEY_CTX_get_rsa_oaep_md_name(ctx, name, sizeof(name)) <= 0) + return -1; + + /* May be NULL meaning "unknown" */ + *md = EVP_get_digestbyname(name); + + return 1; +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + const char *name; + + if (ctx == NULL + || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if ((EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx == NULL) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx == NULL)) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); + + name = (md == NULL) ? "" : EVP_MD_name(md); + + return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, name, NULL); +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops) +{ + OSSL_PARAM rsa_params[3], *p = rsa_params; + + if (ctx == NULL + || mdname == NULL + || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)mdname, + strlen(mdname) + 1); + if (mdprops != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string( + OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)mdprops, + strlen(mdprops) + 1); + } + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, rsa_params); +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namelen) +{ + OSSL_PARAM rsa_params[2], *p = rsa_params; + + if (ctx == NULL + || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, + name, namelen); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, rsa_params)) + return -1; + + return 1; +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + /* 80 should be big enough */ + char name[80] = ""; + + if (ctx == NULL + || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if ((EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx == NULL) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx == NULL)) + return EVP_PKEY_CTX_ctrl(ctx, -1, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)md); + + if (EVP_PKEY_CTX_get_rsa_mgf1_md_name(ctx, name, sizeof(name)) <= 0) + return -1; + + /* May be NULL meaning "unknown" */ + *md = EVP_get_digestbyname(name); + + return 1; +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen) +{ + OSSL_PARAM rsa_params[2], *p = rsa_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, + (void *)label); + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, + /* + * Cast away the const. This is read + * only so should be safe + */ + (void *)label, + (size_t)llen); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_set_params(ctx, rsa_params)) + return 0; + + OPENSSL_free(label); + return 1; +} + +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) +{ + OSSL_PARAM rsa_params[3], *p = rsa_params; + size_t labellen; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.ciph.ciphprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, + (void *)label); + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, + (void **)label, 0); + *p++ = OSSL_PARAM_construct_size_t(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN, + &labellen); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, rsa_params)) + return -1; + + if (labellen > INT_MAX) + return -1; + + return (int)labellen; +} diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index 204fde29..9b55115e 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -50,8 +50,10 @@ struct rsa_st { STACK_OF(RSA_PRIME_INFO) *prime_infos; /* If a PSS only key this contains the parameter restrictions */ RSA_PSS_PARAMS *pss; +#ifndef FIPS_MODE /* be careful using this if the RSA structure is shared */ CRYPTO_EX_DATA ex_data; +#endif CRYPTO_REF_COUNT references; int flags; /* Used to cache montgomery values */ @@ -66,6 +68,8 @@ struct rsa_st { BN_BLINDING *blinding; BN_BLINDING *mt_blinding; CRYPTO_RWLOCK *lock; + + int dirty_cnt; }; struct rsa_meth_st { diff --git a/crypto/rsa/rsa_pk1.c b/crypto/rsa/rsa_pk1.c index 0c774224..007e9b8c 100644 --- a/crypto/rsa/rsa_pk1.c +++ b/crypto/rsa/rsa_pk1.c @@ -10,10 +10,13 @@ #include "internal/constant_time.h" #include -#include "internal/cryptlib.h" #include #include #include +/* Just for the SSL_MAX_MASTER_KEY_LENGTH value */ +#include +#include "internal/cryptlib.h" +#include "crypto/rsa.h" int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, const unsigned char *from, int flen) @@ -253,3 +256,123 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, return constant_time_select_int(good, mlen, -1); } + +/* + * rsa_padding_check_PKCS1_type_2_TLS() checks and removes the PKCS1 type 2 + * padding from a decrypted RSA message in a TLS signature. The result is stored + * in the buffer pointed to by |to| which should be |tlen| bytes long. |tlen| + * must be at least SSL_MAX_MASTER_KEY_LENGTH. The original decrypted message + * should be stored in |from| which must be |flen| bytes in length and padded + * such that |flen == RSA_size()|. The TLS protocol version that the client + * originally requested should be passed in |client_version|. Some buggy clients + * can exist which use the negotiated version instead of the originally + * requested protocol version. If it is necessary to work around this bug then + * the negotiated protocol version can be passed in |alt_version|, otherwise 0 + * should be passed. + * + * If the passed message is publicly invalid or some other error that can be + * treated in non-constant time occurs then -1 is returned. On success the + * length of the decrypted data is returned. This will always be + * SSL_MAX_MASTER_KEY_LENGTH. If an error occurs that should be treated in + * constant time then this function will appear to return successfully, but the + * decrypted data will be randomly generated (as per + * https://tools.ietf.org/html/rfc5246#section-7.4.7.1). + */ +int rsa_padding_check_PKCS1_type_2_TLS(unsigned char *to, size_t tlen, + const unsigned char *from, size_t flen, + int client_version, int alt_version) +{ + unsigned int i, good, version_good; + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + + /* + * If these checks fail then either the message in publicly invalid, or + * we've been called incorrectly. We can fail immediately. + */ + if (flen < RSA_PKCS1_PADDING_SIZE + SSL_MAX_MASTER_KEY_LENGTH + || tlen < SSL_MAX_MASTER_KEY_LENGTH) { + ERR_raise(ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR); + return -1; + } + + /* + * Generate a random premaster secret to use in the event that we fail + * to decrypt. + */ + if (RAND_priv_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + return -1; + } + + good = constant_time_is_zero(from[0]); + good &= constant_time_eq(from[1], 2); + + /* Check we have the expected padding data */ + for (i = 2; i < flen - SSL_MAX_MASTER_KEY_LENGTH - 1; i++) + good &= ~constant_time_is_zero_8(from[i]); + good &= constant_time_is_zero_8(from[flen - SSL_MAX_MASTER_KEY_LENGTH - 1]); + + + /* + * If the version in the decrypted pre-master secret is correct then + * version_good will be 0xff, otherwise it'll be zero. The + * Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version number + * check as a "bad version oracle". Thus version checks are done in + * constant time and are treated like any other decryption error. + */ + version_good = + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], + (client_version >> 8) & 0xff); + version_good &= + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], + client_version & 0xff); + + /* + * The premaster secret must contain the same version number as the + * ClientHello to detect version rollback attacks (strangely, the + * protocol does not offer such protection for DH ciphersuites). + * However, buggy clients exist that send the negotiated protocol + * version instead if the server does not support the requested + * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set then we tolerate + * such clients. In that case alt_version will be non-zero and set to + * the negotiated version. + */ + if (alt_version > 0) { + unsigned int workaround_good; + + workaround_good = + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], + (alt_version >> 8) & 0xff); + workaround_good &= + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], + alt_version & 0xff); + version_good |= workaround_good; + } + + good &= version_good; + + + /* + * Now copy the result over to the to buffer if good, or random data if + * not good. + */ + for (i = 0; i < SSL_MAX_MASTER_KEY_LENGTH; i++) { + to[i] = + constant_time_select_8(good, + from[flen - SSL_MAX_MASTER_KEY_LENGTH + i], + rand_premaster_secret[i]); + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + * So, whether we actually succeeded or not, return success. + */ + + return SSL_MAX_MASTER_KEY_LENGTH; +} diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 0ed9acf4..6479d126 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 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 @@ -14,68 +14,199 @@ #include #include #include "crypto/x509.h" +#ifndef OPENSSL_NO_MD2 +# include /* uses MD2_DIGEST_LENGTH */ +#endif +#ifndef OPENSSL_NO_MD5 +# include /* uses MD5_DIGEST_LENGTH */ +#endif +#ifndef OPENSSL_NO_MDC2 +# include /* uses MDC2_DIGEST_LENGTH */ +#endif +#include /* uses SHA???_DIGEST_LENGTH */ #include "rsa_local.h" +/* + * The general purpose ASN1 code is not available inside the FIPS provider. + * To remove the dependency RSASSA-PKCS1-v1_5 DigestInfo encodings can be + * treated as a special case by pregenerating the required ASN1 encoding. + * This encoding will also be shared by the default provider. + * + * The EMSA-PKCS1-v1_5 encoding method includes an ASN.1 value of type + * DigestInfo, where the type DigestInfo has the syntax + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithm, + * digest OCTET STRING + * } + * + * DigestAlgorithm ::= AlgorithmIdentifier { + * {PKCS1-v1-5DigestAlgorithms} + * } + * + * The AlgorithmIdentifier is a sequence containing the digest OID and + * parameters (a value of type NULL). + * + * The ENCODE_DIGESTINFO_SHA() and ENCODE_DIGESTINFO_MD() macros define an + * initialized array containing the DER encoded DigestInfo for the specified + * SHA or MD digest. The content of the OCTET STRING is not included. + * |name| is the digest name. + * |n| is last byte in the encoded OID for the digest. + * |sz| is the digest length in bytes. It must not be greater than 110. + */ + +#define ASN1_SEQUENCE 0x30 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OID 0x06 + +/* SHA OIDs are of the form: (2 16 840 1 101 3 4 2 |n|) */ +#define ENCODE_DIGESTINFO_SHA(name, n, sz) \ +static const unsigned char digestinfo_##name##_der[] = { \ + ASN1_SEQUENCE, 0x11 + sz, \ + ASN1_SEQUENCE, 0x0d, \ + ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 2, n, \ + ASN1_NULL, 0x00, \ + ASN1_OCTET_STRING, sz \ +}; + +/* MD2 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */ +#define ENCODE_DIGESTINFO_MD(name, n, sz) \ +static const unsigned char digestinfo_##name##_der[] = { \ + ASN1_SEQUENCE, 0x10 + sz, \ + ASN1_SEQUENCE, 0x0c, \ + ASN1_OID, 0x08, 1 * 40 + 2, 0x86, 0x48, 0x86, 0xf7, 0x0d, 2, n, \ + ASN1_NULL, 0x00, \ + ASN1_OCTET_STRING, sz \ +}; + +#ifndef FIPS_MODE +# ifndef OPENSSL_NO_MD2 +ENCODE_DIGESTINFO_MD(md2, 0x02, MD2_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD5 +ENCODE_DIGESTINFO_MD(md5, 0x05, MD5_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MDC2 +/* MDC-2 (2 5 8 3 101) */ +static const unsigned char digestinfo_mdc2_der[] = { + ASN1_SEQUENCE, 0x0c + MDC2_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x08, + ASN1_OID, 0x04, 2 * 40 + 5, 8, 3, 101, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, MDC2_DIGEST_LENGTH +}; +# endif +/* SHA-1 (1 3 14 3 2 26) */ +static const unsigned char digestinfo_sha1_der[] = { + ASN1_SEQUENCE, 0x0d + SHA_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x09, + ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, 26, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, SHA_DIGEST_LENGTH +}; + +#endif /* FIPS_MODE */ + +ENCODE_DIGESTINFO_SHA(sha256, 0x01, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha384, 0x02, SHA384_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512, 0x03, SHA512_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha224, 0x04, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512_224, 0x05, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512_256, 0x06, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_224, 0x07, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_256, 0x08, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_384, 0x09, SHA384_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH) + +#define MD_CASE(name) \ + case NID_##name: \ + *len = sizeof(digestinfo_##name##_der); \ + return digestinfo_##name##_der; + +static const unsigned char *digestinfo_encoding(int nid, size_t *len) +{ + switch (nid) { +#ifndef FIPS_MODE +# ifndef OPENSSL_NO_MDC2 + MD_CASE(mdc2) +# endif +# ifndef OPENSSL_NO_MD2 + MD_CASE(md2) +# endif +# ifndef OPENSSL_NO_MD5 + MD_CASE(md5) +# endif + MD_CASE(sha1) +#endif /* FIPS_MODE */ + MD_CASE(sha224) + MD_CASE(sha256) + MD_CASE(sha384) + MD_CASE(sha512) + MD_CASE(sha512_224) + MD_CASE(sha512_256) + MD_CASE(sha3_224) + MD_CASE(sha3_256) + MD_CASE(sha3_384) + MD_CASE(sha3_512) + default: + return NULL; + } +} + /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 /* - * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as + * Encodes a DigestInfo prefix of hash |type| and digest |m|, as * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This * encodes the DigestInfo (T and tLen) but does not add the padding. * * On success, it returns one and sets |*out| to a newly allocated buffer * containing the result and |*out_len| to its length. The caller must free - * |*out| with |OPENSSL_free|. Otherwise, it returns zero. + * |*out| with OPENSSL_free(). Otherwise, it returns zero. */ -static int encode_pkcs1(unsigned char **out, int *out_len, int type, - const unsigned char *m, unsigned int m_len) +static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, + const unsigned char *m, size_t m_len) { - X509_SIG sig; - X509_ALGOR algor; - ASN1_TYPE parameter; - ASN1_OCTET_STRING digest; - uint8_t *der = NULL; - int len; + size_t di_prefix_len, dig_info_len; + const unsigned char *di_prefix; + unsigned char *dig_info; - sig.algor = &algor; - sig.algor->algorithm = OBJ_nid2obj(type); - if (sig.algor->algorithm == NULL) { + if (type == NID_undef) { RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } - if (OBJ_length(sig.algor->algorithm) == 0) { + di_prefix = digestinfo_encoding(type, &di_prefix_len); + if (di_prefix == NULL) { RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return 0; } - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - sig.algor->parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; - sig.digest->length = m_len; - - len = i2d_X509_SIG(&sig, &der); - if (len < 0) + dig_info_len = di_prefix_len + m_len; + dig_info = OPENSSL_malloc(dig_info_len); + if (dig_info == NULL) { + RSAerr(RSA_F_ENCODE_PKCS1, ERR_R_MALLOC_FAILURE); return 0; + } + memcpy(dig_info, di_prefix, di_prefix_len); + memcpy(dig_info + di_prefix_len, m, m_len); - *out = der; - *out_len = len; + *out = dig_info; + *out_len = dig_info_len; return 1; } int RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { - int encrypt_len, encoded_len = 0, ret = 0; + int encrypt_len, ret = 0; + size_t encoded_len = 0; unsigned char *tmps = NULL; const unsigned char *encoded = NULL; - if (rsa->meth->rsa_sign) { + if (rsa->meth->rsa_sign != NULL) return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); - } /* Compute the encoded digest. */ if (type == NID_md5_sha1) { @@ -96,11 +227,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, encoded = tmps; } - if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { + if (encoded_len + RSA_PKCS1_PADDING_SIZE > (size_t)RSA_size(rsa)) { RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); goto err; } - encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, + encrypt_len = RSA_private_encrypt((int)encoded_len, encoded, sigret, rsa, RSA_PKCS1_PADDING); if (encrypt_len <= 0) goto err; @@ -109,23 +240,25 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, ret = 1; err: - OPENSSL_clear_free(tmps, (size_t)encoded_len); + OPENSSL_clear_free(tmps, encoded_len); return ret; } /* - * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be - * called in two modes. If |rm| is NULL, it verifies the signature for digest - * |m|. Otherwise, it recovers the digest from the signature, writing the digest - * to |rm| and the length to |*prm_len|. |type| is the NID of the digest - * algorithm to use. It returns one on successful verification and zero - * otherwise. + * Verify an RSA signature in |sigbuf| using |rsa|. + * |type| is the NID of the digest algorithm to use. + * If |rm| is NULL, it verifies the signature for digest |m|, otherwise + * it recovers the digest from the signature, writing the digest to |rm| and + * the length to |*prm_len|. + * + * It returns one on successful verification or zero otherwise. */ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { - int decrypt_len, ret = 0, encoded_len = 0; + int len, ret = 0; + size_t decrypt_len, encoded_len = 0; unsigned char *decrypt_buf = NULL, *encoded = NULL; if (siglen != (size_t)RSA_size(rsa)) { @@ -140,10 +273,11 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, goto err; } - decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, - RSA_PKCS1_PADDING); - if (decrypt_len <= 0) + len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, + RSA_PKCS1_PADDING); + if (len <= 0) goto err; + decrypt_len = len; if (type == NID_md5_sha1) { /* @@ -203,8 +337,11 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, goto err; } - m_len = EVP_MD_size(md); - if (m_len > (size_t)decrypt_len) { + len = EVP_MD_size(md); + if (len <= 0) + goto err; + m_len = (unsigned int)len; + if (m_len > decrypt_len) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); goto err; } @@ -216,7 +353,7 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, goto err; if (encoded_len != decrypt_len - || memcmp(encoded, decrypt_buf, encoded_len) != 0) { + || memcmp(encoded, decrypt_buf, encoded_len) != 0) { RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); goto err; } @@ -231,7 +368,7 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, ret = 1; err: - OPENSSL_clear_free(encoded, (size_t)encoded_len); + OPENSSL_clear_free(encoded, encoded_len); OPENSSL_clear_free(decrypt_buf, siglen); return ret; } @@ -240,9 +377,8 @@ int RSA_verify(int type, const unsigned char *m, unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) { - if (rsa->meth->rsa_verify) { + if (rsa->meth->rsa_verify != NULL) return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa); - } return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); } diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index d614504b..a580b1dc 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -75,38 +75,41 @@ int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) * See SP800-5bBr1 6.4.1.2.1 Part 5 (c) & (g) - used for both p and q. * * (√2)(2^(nbits/2 - 1) = (√2/2)(2^(nbits/2)) - * √2/2 = 0.707106781186547524400 = 0.B504F333F9DE6484597D8 - * 0.B504F334 gives an approximation to 11 decimal places. - * The range is then from - * 0xB504F334_0000.......................000 to - * 0xFFFFFFFF_FFFF.......................FFF */ int rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) { int ret = 0; - BIGNUM *tmp, *low; + BIGNUM *low; + int shift; nbits >>= 1; + shift = nbits - BN_num_bits(&bn_inv_sqrt_2); /* Upper bound check */ if (BN_num_bits(p) != nbits) return 0; BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); low = BN_CTX_get(ctx); + if (low == NULL) + goto err; /* set low = (√2)(2^(nbits/2 - 1) */ - if (low == NULL || !BN_set_word(tmp, 0xB504F334)) + if (!BN_copy(low, &bn_inv_sqrt_2)) goto err; - if (nbits >= 32) { - if (!BN_lshift(low, tmp, nbits - 32)) + if (shift >= 0) { + /* + * We don't have all the bits. bn_inv_sqrt_2 contains a rounded up + * value, so there is a very low probability that we'll reject a valid + * value. + */ + if (!BN_lshift(low, low, shift)) goto err; - } else if (!BN_rshift(low, tmp, 32 - nbits)) { + } else if (!BN_rshift(low, low, -shift)) { goto err; } - if (BN_cmp(p, low) < 0) + if (BN_cmp(p, low) <= 0) goto err; ret = 1; err: diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c index c22b10cf..5474aaa4 100644 --- a/crypto/rsa/rsa_sp800_56b_gen.c +++ b/crypto/rsa/rsa_sp800_56b_gen.c @@ -118,6 +118,7 @@ int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2, continue; break; /* successfully finished */ } + rsa->dirty_cnt++; ret = 1; err: /* Zeroize any internally generated values that are not returned */ @@ -239,6 +240,7 @@ int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, || BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx) == NULL) goto err; + rsa->dirty_cnt++; ret = 1; err: if (ret != 1) { diff --git a/crypto/rsa/rsa_x931g.c b/crypto/rsa/rsa_x931g.c index 3798d02b..1f6042a3 100644 --- a/crypto/rsa/rsa_x931g.c +++ b/crypto/rsa/rsa_x931g.c @@ -131,6 +131,7 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, if (rsa->iqmp == NULL) goto err; + rsa->dirty_cnt++; ret = 1; err: BN_CTX_end(ctx); @@ -184,6 +185,7 @@ int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) goto error; + rsa->dirty_cnt++; ok = 1; error: diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index eb00a4a7..f8e02349 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -19,7 +19,9 @@ #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 16) # include -# define OSSL_IMPLEMENT_GETAUXVAL +# if defined(HWCAP_S390_STFLE) && defined(HWCAP_S390_VX) +# define OSSL_IMPLEMENT_GETAUXVAL +# endif # endif #endif @@ -82,7 +84,7 @@ void OPENSSL_cpuid_setup(void) /* set a bit that will not be tested later */ OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); -#ifdef OSSL_IMPLEMENT_GETAUXVAL +#if defined(OSSL_IMPLEMENT_GETAUXVAL) { const unsigned long hwcap = getauxval(AT_HWCAP); diff --git a/crypto/s390xcpuid.pl b/crypto/s390xcpuid.pl index 0f63f7ed..ac0c5b48 100755 --- a/crypto/s390xcpuid.pl +++ b/crypto/s390xcpuid.pl @@ -504,14 +504,14 @@ $code.=<<___; .type s390x_flip_endian32,\@function .align 16 s390x_flip_endian32: - lrvg %r0,0(%r0,$src) - lrvg %r1,8(%r0,$src) - lrvg %r4,16(%r0,$src) - lrvg %r5,24(%r0,$src) - stg %r0,24(%r0,$dst) - stg %r1,16(%r0,$dst) - stg %r4,8(%r0,$dst) - stg %r5,0(%r0,$dst) + lrvg %r0,0($src) + lrvg %r1,8($src) + lrvg %r4,16($src) + lrvg %r5,24($src) + stg %r0,24($dst) + stg %r1,16($dst) + stg %r4,8($dst) + stg %r5,0($dst) br $ra .size s390x_flip_endian32,.-s390x_flip_endian32 ___ @@ -528,22 +528,22 @@ $code.=<<___; s390x_flip_endian64: stmg %r6,%r9,6*$SIZE_T($sp) - lrvg %r0,0(%r0,$src) - lrvg %r1,8(%r0,$src) - lrvg %r4,16(%r0,$src) - lrvg %r5,24(%r0,$src) - lrvg %r6,32(%r0,$src) - lrvg %r7,40(%r0,$src) - lrvg %r8,48(%r0,$src) - lrvg %r9,56(%r0,$src) - stg %r0,56(%r0,$dst) - stg %r1,48(%r0,$dst) - stg %r4,40(%r0,$dst) - stg %r5,32(%r0,$dst) - stg %r6,24(%r0,$dst) - stg %r7,16(%r0,$dst) - stg %r8,8(%r0,$dst) - stg %r9,0(%r0,$dst) + lrvg %r0,0($src) + lrvg %r1,8($src) + lrvg %r4,16($src) + lrvg %r5,24($src) + lrvg %r6,32($src) + lrvg %r7,40($src) + lrvg %r8,48($src) + lrvg %r9,56($src) + stg %r0,56($dst) + stg %r1,48($dst) + stg %r4,40($dst) + stg %r5,32($dst) + stg %r6,24($dst) + stg %r7,16($dst) + stg %r8,8($dst) + stg %r9,0($dst) lmg %r6,%r9,6*$SIZE_T($sp) br $ra diff --git a/crypto/seed/seed.c b/crypto/seed/seed.c index 224fb1f8..492853d5 100644 --- a/crypto/seed/seed.c +++ b/crypto/seed/seed.c @@ -34,6 +34,12 @@ */ #ifndef OPENSSL_NO_SEED +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + # include # include # include diff --git a/crypto/seed/seed_cbc.c b/crypto/seed/seed_cbc.c index 26116ab7..59ebbeef 100644 --- a/crypto/seed/seed_cbc.c +++ b/crypto/seed/seed_cbc.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/seed/seed_cfb.c b/crypto/seed/seed_cfb.c index b8ee9e91..0e86e169 100644 --- a/crypto/seed/seed_cfb.c +++ b/crypto/seed/seed_cfb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/seed/seed_ecb.c b/crypto/seed/seed_ecb.c index d7f34ec9..b7ea0d43 100644 --- a/crypto/seed/seed_ecb.c +++ b/crypto/seed/seed_ecb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, diff --git a/crypto/seed/seed_ofb.c b/crypto/seed/seed_ofb.c index e556c440..3bc6c17d 100644 --- a/crypto/seed/seed_ofb.c +++ b/crypto/seed/seed_ofb.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/self_test_core.c b/crypto/self_test_core.c new file mode 100644 index 00000000..77864a23 --- /dev/null +++ b/crypto/self_test_core.c @@ -0,0 +1,62 @@ +/* + * Copyright 2019 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 + */ + +#include +#include "internal/cryptlib.h" + +typedef struct self_test_cb_st +{ + OSSL_CALLBACK *cb; + void *cbarg; +} SELF_TEST_CB; + +static void *self_test_set_callback_new(OPENSSL_CTX *ctx) +{ + SELF_TEST_CB *stcb; + + stcb = OPENSSL_zalloc(sizeof(*stcb)); + return stcb; +} + +static void self_test_set_callback_free(void *stcb) +{ + OPENSSL_free(stcb); +} + +static const OPENSSL_CTX_METHOD self_test_set_callback_method = { + self_test_set_callback_new, + self_test_set_callback_free, +}; + +static SELF_TEST_CB *get_self_test_callback(OPENSSL_CTX *libctx) +{ + return openssl_ctx_get_data(libctx, OPENSSL_CTX_SELF_TEST_CB_INDEX, + &self_test_set_callback_method); +} + +void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb, + void *cbarg) +{ + SELF_TEST_CB *stcb = get_self_test_callback(libctx); + + if (stcb != NULL) { + stcb->cb = cb; + stcb->cbarg = cbarg; + } +} +void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb, + void **cbarg) +{ + SELF_TEST_CB *stcb = get_self_test_callback(libctx); + + if (cb != NULL) + *cb = (stcb != NULL ? stcb->cb : NULL); + if (cbarg != NULL) + *cbarg = (stcb != NULL ? stcb->cbarg : NULL); +} diff --git a/crypto/serializer/build.info b/crypto/serializer/build.info new file mode 100644 index 00000000..551319ed --- /dev/null +++ b/crypto/serializer/build.info @@ -0,0 +1,2 @@ +SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c \ + serializer_err.c diff --git a/crypto/serializer/serializer_err.c b/crypto/serializer/serializer_err.c new file mode 100644 index 00000000..0f0fc5fa --- /dev/null +++ b/crypto/serializer/serializer_err.c @@ -0,0 +1,31 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 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 + */ + +#include +#include + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA OSSL_SERIALIZER_str_reasons[] = { + {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY), + "incorrect property query"}, + {0, NULL} +}; + +#endif + +int ERR_load_OSSL_SERIALIZER_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(OSSL_SERIALIZER_str_reasons[0].error) == NULL) + ERR_load_strings_const(OSSL_SERIALIZER_str_reasons); +#endif + return 1; +} diff --git a/crypto/serializer/serializer_lib.c b/crypto/serializer/serializer_lib.c new file mode 100644 index 00000000..932ef1e3 --- /dev/null +++ b/crypto/serializer/serializer_lib.c @@ -0,0 +1,43 @@ +/* + * Copyright 2019 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 + */ + +#include +#include +#include "serializer_local.h" + +int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) +{ + return ctx->do_output(ctx, out); +} + +#ifndef OPENSSL_NO_STDIO +static BIO *bio_from_file(FILE *fp) +{ + BIO *b; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_BUF_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + return b; +} + +int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp) +{ + BIO *b = bio_from_file(fp); + int ret = 0; + + if (b != NULL) + ret = OSSL_SERIALIZER_to_bio(ctx, b); + + BIO_free(b); + return ret; +} +#endif diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h new file mode 100644 index 00000000..9ee0eb82 --- /dev/null +++ b/crypto/serializer/serializer_local.h @@ -0,0 +1,50 @@ +/* + * Copyright 2019 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 + */ + +#include +#include +#include "internal/cryptlib.h" +#include "internal/refcount.h" + +struct ossl_serializer_st { + OSSL_PROVIDER *prov; + int id; + const char *propdef; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_serializer_newctx_fn *newctx; + OSSL_OP_serializer_freectx_fn *freectx; + OSSL_OP_serializer_set_ctx_params_fn *set_ctx_params; + OSSL_OP_serializer_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_serializer_serialize_data_fn *serialize_data; + OSSL_OP_serializer_serialize_object_fn *serialize_object; +}; + +struct ossl_serializer_ctx_st { + OSSL_SERIALIZER *ser; + void *serctx; + + /* + * |object| is the libcrypto object to handle. + * |do_output| must have intimate knowledge of this object. + */ + const void *object; + int (*do_output)(OSSL_SERIALIZER_CTX *ctx, BIO *out); + + /* For any function that needs a passphrase reader */ + const UI_METHOD *ui_method; + void *ui_data; + /* + * if caller used OSSL_SERIALIZER_CTX_set_passphrase_cb(), we need + * intermediary storage. + */ + UI_METHOD *allocated_ui_method; +}; diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c new file mode 100644 index 00000000..a098ffb0 --- /dev/null +++ b/crypto/serializer/serializer_meth.c @@ -0,0 +1,516 @@ +/* + * Copyright 2019 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 + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "crypto/serializer.h" +#include "serializer_local.h" + +/* + * Serializer can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_SERIALIZER *ossl_serializer_new(void) +{ + OSSL_SERIALIZER *ser = NULL; + + if ((ser = OPENSSL_zalloc(sizeof(*ser))) == NULL + || (ser->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OSSL_SERIALIZER_free(ser); + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ser->refcnt = 1; + + return ser; +} + +int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser) +{ + int ref = 0; + + CRYPTO_UP_REF(&ser->refcnt, &ref, ser->lock); + return 1; +} + +void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser) +{ + int ref = 0; + + if (ser == NULL) + return; + + CRYPTO_DOWN_REF(&ser->refcnt, &ref, ser->lock); + if (ref > 0) + return; + ossl_provider_free(ser->prov); + CRYPTO_THREAD_lock_free(ser->lock); + OPENSSL_free(ser); +} + +/* Permanent serializer method store, constructor and destructor */ +static void serializer_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *serializer_store_new(OPENSSL_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OPENSSL_CTX_METHOD serializer_store_method = { + serializer_store_new, + serializer_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct serializer_data_st { + OPENSSL_CTX *libctx; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + int id; /* For get_serializer_from_store() */ + const char *names; /* For get_serializer_from_store() */ + const char *propquery; /* For get_serializer_from_store() */ +}; + +/* + * Generic routines to fetch / create SERIALIZER methods with + * ossl_method_construct() + */ + +/* Temporary serializer method store, constructor and destructor */ +static void *alloc_tmp_serializer_store(OPENSSL_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + static void dealloc_tmp_serializer_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent serializer store */ +static OSSL_METHOD_STORE *get_serializer_store(OPENSSL_CTX *libctx) +{ + return openssl_ctx_get_data(libctx, OPENSSL_CTX_SERIALIZER_STORE_INDEX, + &serializer_store_method); +} + +/* Get serializer methods from a store, or put one in */ +static void *get_serializer_from_store(OPENSSL_CTX *libctx, void *store, + void *data) +{ + struct serializer_data_st *methdata = data; + void *method = NULL; + int id; + + if ((id = methdata->id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + id = ossl_namemap_name2num(namemap, methdata->names); + } + + if (store == NULL + && (store = get_serializer_store(libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) + return NULL; + return method; +} + +static int put_serializer_in_store(OPENSSL_CTX *libctx, void *store, + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *names, + const char *propdef, void *unused) +{ + OSSL_NAMEMAP *namemap; + int id; + + if ((namemap = ossl_namemap_stored(libctx)) == NULL + || (id = ossl_namemap_name2num(namemap, names)) == 0) + return 0; + + if (store == NULL && (store = get_serializer_store(libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_SERIALIZER_up_ref, + (void (*)(void *))OSSL_SERIALIZER_free); +} + +/* Create and populate a serializer method */ +static void *serializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_SERIALIZER *ser = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((ser = ossl_serializer_new()) == NULL) + return NULL; + ser->id = id; + ser->propdef = algodef->property_definition; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_SERIALIZER_NEWCTX: + if (ser->newctx == NULL) + ser->newctx = + OSSL_get_OP_serializer_newctx(fns); + break; + case OSSL_FUNC_SERIALIZER_FREECTX: + if (ser->freectx == NULL) + ser->freectx = + OSSL_get_OP_serializer_freectx(fns); + break; + case OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS: + if (ser->set_ctx_params == NULL) + ser->set_ctx_params = + OSSL_get_OP_serializer_set_ctx_params(fns); + break; + case OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS: + if (ser->settable_ctx_params == NULL) + ser->settable_ctx_params = + OSSL_get_OP_serializer_settable_ctx_params(fns); + break; + case OSSL_FUNC_SERIALIZER_SERIALIZE_DATA: + if (ser->serialize_data == NULL) + ser->serialize_data = + OSSL_get_OP_serializer_serialize_data(fns); + break; + case OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT: + if (ser->serialize_object == NULL) + ser->serialize_object = + OSSL_get_OP_serializer_serialize_object(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * If you have a constructor, you must have a destructor and vice versa. + * You must have at least one of the serializing driver functions. + */ + if (!((ser->newctx == NULL && ser->freectx == NULL) + || (ser->newctx != NULL && ser->freectx != NULL)) + || (ser->serialize_data == NULL && ser->serialize_object == NULL)) { + OSSL_SERIALIZER_free(ser); + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_SERIALIZER_free(ser); + return NULL; + } + + ser->prov = prov; + return ser; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call serializer_from_dispatch() with that identity number. + */ +static void *construct_serializer(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *unused) +{ + /* + * This function is only called if get_serializer_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = serializer_from_dispatch(id, algodef, prov); + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_serializer(void *method, void *data) +{ + OSSL_SERIALIZER_free(method); +} + +static int up_ref_serializer(void *method) +{ + return OSSL_SERIALIZER_up_ref(method); +} + +static void free_serializer(void *method) +{ + OSSL_SERIALIZER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_SERIALIZER *inner_ossl_serializer_fetch(OPENSSL_CTX *libctx, + int id, const char *name, + const char *properties) +{ + OSSL_METHOD_STORE *store = get_serializer_store(libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + void *method = NULL; + + if (store == NULL || namemap == NULL) + return NULL; + + /* + * If we have been passed neither a name_id or a name, we have an + * internal programming error. + */ + if (!ossl_assert(id != 0 || name != NULL)) + return NULL; + + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + + if (id == 0 + || !ossl_method_store_cache_get(store, id, properties, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + alloc_tmp_serializer_store, + dealloc_tmp_serializer_store, + get_serializer_from_store, + put_serializer_in_store, + construct_serializer, + destruct_serializer + }; + struct serializer_data_st mcmdata; + + mcmdata.libctx = libctx; + mcmdata.mcm = &mcm; + mcmdata.id = id; + mcmdata.names = name; + mcmdata.propquery = properties; + if ((method = ossl_method_construct(libctx, OSSL_OP_SERIALIZER, + 0 /* !force_cache */, + &mcm, &mcmdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_serializer_from_store() and + * put_serializer_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + ossl_method_store_cache_set(store, id, properties, method, + up_ref_serializer, free_serializer); + } + } + + return method; +} + +OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx, const char *name, + const char *properties) +{ + return inner_ossl_serializer_fetch(libctx, 0, name, properties); +} + +OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id, + const char *properties) +{ + return inner_ossl_serializer_fetch(libctx, id, NULL, properties); +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->prov; +} + +const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->propdef; +} + +int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->id; +} + +int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, const char *name) +{ + if (ser->prov != NULL) { + OPENSSL_CTX *libctx = ossl_provider_library_context(ser->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == ser->id; + } + return 0; +} + +struct serializer_do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void serializer_do_one(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algodef, + int no_store, void *vdata) +{ + struct serializer_do_all_data_st *data = vdata; + OPENSSL_CTX *libctx = ossl_provider_library_context(provider); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = + serializer_from_dispatch(id, algodef, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + OSSL_SERIALIZER_free(method); + } +} + +void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(OSSL_SERIALIZER *ser, + void *arg), + void *arg) +{ + struct serializer_do_all_data_st data; + + data.user_fn = (void (*)(void *, void *))fn; + data.user_arg = arg; + ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, + serializer_do_one, &data); +} + +void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser, + void (*fn)(const char *name, void *data), + void *data) +{ + if (ser == NULL) + return; + + if (ser->prov != NULL) { + OPENSSL_CTX *libctx = ossl_provider_library_context(ser->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + ossl_namemap_doall_names(namemap, ser->id, fn, data); + } +} + +const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser) +{ + if (ser != NULL && ser->settable_ctx_params != NULL) + return ser->settable_ctx_params(); + return NULL; +} + +/* + * Serializer context support + */ + +/* + * |ser| value NULL is valid, and signifies that there is no serializer. + * This is useful to provide fallback mechanisms. + * Functions that want to verify if there is a serializer can do so with + * OSSL_SERIALIZER_CTX_get_serializer() + */ +OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser) +{ + OSSL_SERIALIZER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ctx->ser = ser; + if (ser != NULL && ser->newctx != NULL) { + const OSSL_PROVIDER *prov = OSSL_SERIALIZER_provider(ser); + void *provctx = ossl_provider_ctx(prov); + + if (OSSL_SERIALIZER_up_ref(ser)) { + ctx->serctx = ser->newctx(provctx); + } else { + OSSL_SERIALIZER_free(ser); + OPENSSL_free(ctx); + ctx = NULL; + } + } + + return ctx; +} + +const OSSL_SERIALIZER * +OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ctx->ser; +} + + +int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx, + const OSSL_PARAM params[]) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->ser != NULL && ctx->ser->set_ctx_params != NULL) + return ctx->ser->set_ctx_params(ctx->serctx, params); + return 0; +} + +void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx) +{ + if (ctx != NULL) { + if (ctx->ser != NULL && ctx->ser->freectx != NULL) + ctx->ser->freectx(ctx->serctx); + OSSL_SERIALIZER_free(ctx->ser); + UI_destroy_method(ctx->allocated_ui_method); + OPENSSL_free(ctx); + } +} diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c new file mode 100644 index 00000000..d3c3362f --- /dev/null +++ b/crypto/serializer/serializer_pkey.c @@ -0,0 +1,386 @@ +/* + * Copyright 2019 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 + */ + +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/property.h" +#include "crypto/evp.h" +#include "serializer_local.h" + +int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx, + const char *cipher_name, + const char *propquery) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, + (void *)cipher_name, 0); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_PROPERTIES, + (void *)propquery, 0); + + return OSSL_SERIALIZER_CTX_set_params(ctx, params); +} + +int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx, + const unsigned char *kstr, + size_t klen) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_SERIALIZER_PARAM_PASS, + (void *)kstr, klen); + + return OSSL_SERIALIZER_CTX_set_params(ctx, params); +} + +static void serializer_ctx_reset_passphrase_ui(OSSL_SERIALIZER_CTX *ctx) +{ + UI_destroy_method(ctx->allocated_ui_method); + ctx->allocated_ui_method = NULL; + ctx->ui_method = NULL; + ctx->ui_data = NULL; +} + +int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + serializer_ctx_reset_passphrase_ui(ctx); + ctx->ui_method = ui_method; + ctx->ui_data = ui_data; + return 1; +} + +int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx, int enc, + pem_password_cb *cb, void *cbarg) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + serializer_ctx_reset_passphrase_ui(ctx); + if (cb == NULL) + return 1; + ctx->ui_method = + ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, enc); + ctx->ui_data = cbarg; + + return ctx->ui_method != NULL; +} + +/* + * Support for OSSL_SERIALIZER_CTX_new_by_TYPE: + * finding a suitable serializer + */ + +struct selected_serializer_st { + OPENSSL_CTX *libctx; + const OSSL_PROVIDER *desired_provider; + const char *propquery; + + /* + * When selecting serializers, we need to check the intended use. + * This is governed by the |domainparams| flag in the EVP_PKEY, + * we must just make sure to filter on 'type=domainparams' accordingly. + */ + int want_domainparams; + + /* + * Serializers offer two functions, one that handles object data in + * the form of a OSSL_PARAM array, and one that directly handles a + * provider side object. The latter requires that the serializer + * is offered by the same provider that holds that object, but is + * more desirable because it usually provides faster serialization. + * + * When looking up possible serializers, we save the first that can + * handle an OSSL_PARAM array in |first|, and the first that can + * handle a provider side object in |desired|. + */ + OSSL_SERIALIZER *first; + OSSL_SERIALIZER *desired; +}; + +static void select_serializer(const char *name, void *data) +{ + struct selected_serializer_st *d = data; + OSSL_SERIALIZER *s = NULL; + OSSL_PROPERTY_LIST *check = + d->want_domainparams + ? ossl_parse_query(d->libctx, "type=domainparams") + : NULL; + + /* No need to look further if we already have the more desirable option */ + if (d->desired != NULL) + return; + + if ((s = OSSL_SERIALIZER_fetch(d->libctx, name, d->propquery)) != NULL) { + /* + * Extra check if domain parameters are explicitly specified: + * only accept serializers that have the "type=domainparams" + * property. + * + * For data that isn't marked as domain parameters, a domain + * parameters serializer is still acceptable, because a key + * may hold domain parameters too. + */ + if (d->want_domainparams) { + OSSL_PROPERTY_LIST *current_props = + ossl_parse_property(d->libctx, OSSL_SERIALIZER_properties(s)); + int check_cnt = ossl_property_match_count(check, current_props); + + if (check_cnt == 0) { + OSSL_SERIALIZER_free(s); + return; + } + } + + if (d->first == NULL && s->serialize_data != NULL) { + d->first = s; + } else if (OSSL_SERIALIZER_provider(s) == d->desired_provider + && s->serialize_object != NULL) { + OSSL_SERIALIZER_free(d->first); + d->first = NULL; + d->desired = s; + } else { + OSSL_SERIALIZER_free(s); + } + } +} + +/* + * Support for OSSL_SERIALIZER_CTX_new_by_TYPE and OSSL_SERIALIZER_to_bio: + * Passphrase callbacks + */ + +/* + * First, we define the generic passphrase function that supports both + * outgoing (with passphrase verify) and incoming (without passphrase verify) + * passphrase reading. + */ +static int serializer_passphrase(char *pass, size_t pass_size, + size_t *pass_len, int verify, + const OSSL_PARAM params[], void *arg) +{ + OSSL_SERIALIZER_CTX *ctx = arg; + const OSSL_PARAM *p; + const char *prompt_info = NULL; + char *prompt = NULL, *vpass = NULL; + int prompt_idx = -1, verify_idx = -1; + UI *ui = NULL; + int ret = 0; + + if (!ossl_assert(ctx != NULL && pass != NULL + && pass_size != 0 && pass_len != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, + OSSL_PASSPHRASE_PARAM_INFO)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + prompt_info = p->data; + } + + if ((ui = UI_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + return 0; + } + + UI_set_method(ui, ctx->ui_method); + UI_add_user_data(ui, ctx->ui_data); + + /* Get an application constructed prompt */ + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (prompt == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + goto end; + } + + prompt_idx = UI_add_input_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + pass, 0, pass_size - 1) - 1; + if (prompt_idx < 0) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_UI_LIB); + goto end; + } + + if (verify) { + /* Get a buffer for verification prompt */ + vpass = OPENSSL_zalloc(pass_size); + if (vpass == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + goto end; + } + verify_idx = UI_add_verify_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + vpass, 0, pass_size - 1, + pass) - 1; + if (verify_idx < 0) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_UI_LIB); + goto end; + } + } + + switch (UI_process(ui)) { + case -2: + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_INTERRUPTED_OR_CANCELLED); + break; + case -1: + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_UI_LIB); + break; + default: + *pass_len = (size_t)UI_get_result_length(ui, prompt_idx); + ret = 1; + break; + } + + end: + OPENSSL_free(vpass); + OPENSSL_free(prompt); + UI_free(ui); + return ret; +} + +/* Ensure correct function definition for outgoing passphrase reader */ +static OSSL_PASSPHRASE_CALLBACK serializer_passphrase_out_cb; +static int serializer_passphrase_out_cb(char *pass, size_t pass_size, + size_t *pass_len, + const OSSL_PARAM params[], void *arg) +{ + return serializer_passphrase(pass, pass_size, pass_len, 1, params, arg); +} + +/* + * Support for OSSL_SERIALIZER_to_bio: + * writing callback for the OSSL_PARAM (the implementation doesn't have + * intimate knowledge of the provider side object) + */ + +struct serializer_write_data_st { + OSSL_SERIALIZER_CTX *ctx; + BIO *out; +}; + +static int serializer_write_cb(const OSSL_PARAM params[], void *arg) +{ + struct serializer_write_data_st *write_data = arg; + OSSL_SERIALIZER_CTX *ctx = write_data->ctx; + BIO *out = write_data->out; + + return ctx->ser->serialize_data(ctx->serctx, params, out, + serializer_passphrase_out_cb, ctx); +} + +/* + * Support for OSSL_SERIALIZER_to_bio: + * Perform the actual output. + */ + +static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) +{ + const EVP_PKEY *pkey = ctx->object; + void *provdata = pkey->pkeys[0].provdata; + int domainparams = pkey->pkeys[0].domainparams; + EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt; + + /* + * OSSL_SERIALIZER_CTX_new() creates a context, even when the + * serializer it's given is NULL. Callers can detect the lack + * of serializer with OSSL_SERIALIZER_CTX_get_serializer() and + * should take precautions, possibly call a fallback instead of + * OSSL_SERIALIZER_to_bio() / OSSL_SERIALIZER_to_fp(). If it's + * come this far, we return an error. + */ + if (ctx->ser == NULL) + return 0; + + if (ctx->ser->serialize_object == NULL) { + struct serializer_write_data_st write_data; + + write_data.ctx = ctx; + write_data.out = out; + + if (domainparams) + return evp_keymgmt_exportdomparams(keymgmt, provdata, + serializer_write_cb, + &write_data); + return evp_keymgmt_exportkey(keymgmt, provdata, + serializer_write_cb, &write_data); + } + + return ctx->ser->serialize_object(ctx->serctx, provdata, out, + serializer_passphrase_out_cb, ctx); +} + +/* + * OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a ctx with no serializer if + * it couldn't find a suitable serializer. This allows a caller to detect if + * a suitable serializer was found, with OSSL_SERIALIZER_CTX_get_serializer(), + * and to use fallback methods if the result is NULL. + */ +OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, + const char *propquery) +{ + OSSL_SERIALIZER_CTX *ctx = NULL; + OSSL_SERIALIZER *ser = NULL; + EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt; + + if (!ossl_assert(pkey != NULL && propquery != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (keymgmt != NULL) { + const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt); + OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov); + struct selected_serializer_st sel_data; + + memset(&sel_data, 0, sizeof(sel_data)); + sel_data.libctx = libctx; + sel_data.desired_provider = desired_prov; + sel_data.propquery = propquery; + sel_data.want_domainparams = pkey->pkeys[0].domainparams; + EVP_KEYMGMT_names_do_all(keymgmt, select_serializer, &sel_data); + + if (sel_data.desired != NULL) { + ser = sel_data.desired; + sel_data.desired = NULL; + } else if (sel_data.first != NULL) { + ser = sel_data.first; + sel_data.first = NULL; + } + OSSL_SERIALIZER_free(sel_data.first); + OSSL_SERIALIZER_free(sel_data.desired); + } + + ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */ + OSSL_SERIALIZER_free(ser); /* refcnt(ser)-- */ + + if (ctx != NULL) { + /* Setup for OSSL_SERIALIZE_to_bio() */ + ctx->object = pkey; + ctx->do_output = serializer_EVP_PKEY_to_bio; + } + + return ctx; +} + diff --git a/crypto/sha/asm/keccak1600-x86_64.pl b/crypto/sha/asm/keccak1600-x86_64.pl index 80c7cc43..aee356ad 100755 --- a/crypto/sha/asm/keccak1600-x86_64.pl +++ b/crypto/sha/asm/keccak1600-x86_64.pl @@ -86,6 +86,7 @@ $code.=<<___; .type __KeccakF1600,\@abi-omnipotent .align 32 __KeccakF1600: +.cfi_startproc mov $A[4][0](%rdi),@C[0] mov $A[4][1](%rdi),@C[1] mov $A[4][2](%rdi),@C[2] @@ -344,6 +345,7 @@ $code.=<<___; lea -192($iotas),$iotas # rewind iotas ret +.cfi_endproc .size __KeccakF1600,.-__KeccakF1600 .type KeccakF1600,\@abi-omnipotent diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl index 6622b021..2c3c7bc9 100644 --- a/crypto/sha/asm/sha1-586.pl +++ b/crypto/sha/asm/sha1-586.pl @@ -143,7 +143,7 @@ $ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" && `ml 2>&1` =~ /Version ([0-9]+)\./ && $1>=10); # first version supporting AVX -$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9]\.[0-9]+)/ && +$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); # first version supporting AVX $shaext=$xmm; ### set to zero if compiling for 1.0.1 diff --git a/crypto/sha/asm/sha1-mb-x86_64.pl b/crypto/sha/asm/sha1-mb-x86_64.pl index 0804c580..2da2ffff 100644 --- a/crypto/sha/asm/sha1-mb-x86_64.pl +++ b/crypto/sha/asm/sha1-mb-x86_64.pl @@ -67,7 +67,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl index ab10d360..315f3d89 100755 --- a/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/sha/asm/sha1-x86_64.pl @@ -120,7 +120,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([2-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } @@ -470,8 +470,8 @@ $code.=<<___ if ($win64); .Lepilogue_shaext: ___ $code.=<<___; -.cfi_endproc ret +.cfi_endproc .size sha1_block_data_order_shaext,.-sha1_block_data_order_shaext ___ }}} diff --git a/crypto/sha/asm/sha256-586.pl b/crypto/sha/asm/sha256-586.pl index b28b62ab..33bb8a74 100644 --- a/crypto/sha/asm/sha256-586.pl +++ b/crypto/sha/asm/sha256-586.pl @@ -95,7 +95,7 @@ if ($xmm && !$avx && $ARGV[0] eq "win32" && $avx = ($1>=10) + ($1>=11); } -if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3-9]\.[0-9]+)/) { +if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha256-mb-x86_64.pl b/crypto/sha/asm/sha256-mb-x86_64.pl index 167d3324..99d786a2 100644 --- a/crypto/sha/asm/sha256-mb-x86_64.pl +++ b/crypto/sha/asm/sha256-mb-x86_64.pl @@ -68,7 +68,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl index ef84b090..7ecded19 100755 --- a/crypto/sha/asm/sha512-x86_64.pl +++ b/crypto/sha/asm/sha512-x86_64.pl @@ -136,7 +136,7 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } @@ -571,6 +571,7 @@ $code.=<<___; .align 64 sha256_block_data_order_shaext: _shaext_shortcut: +.cfi_startproc ___ $code.=<<___ if ($win64); lea `-8-5*16`(%rsp),%rsp @@ -714,6 +715,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size sha256_block_data_order_shaext,.-sha256_block_data_order_shaext ___ }}} @@ -1994,7 +1996,23 @@ $code.=<<___; vmovdqa $t0,0x00(%rsp) xor $a1,$a1 vmovdqa $t1,0x20(%rsp) +___ +$code.=<<___ if (!$win64); +# temporarily use %rdi as frame pointer + mov $_rsp,%rdi +.cfi_def_cfa %rdi,8 +___ +$code.=<<___; lea -$PUSH8(%rsp),%rsp +___ +$code.=<<___ if (!$win64); +# the frame info is at $_rsp, but the stack is moving... +# so a second frame pointer is saved at -8(%rsp) +# that is in the red zone + mov %rdi,-8(%rsp) +.cfi_cfa_expression %rsp-8,deref,+8 +___ +$code.=<<___; mov $B,$a3 vmovdqa $t2,0x00(%rsp) xor $C,$a3 # magic @@ -2014,7 +2032,18 @@ my @X = @_; my @insns = (&$body,&$body,&$body,&$body); # 96 instructions my $base = "+2*$PUSH8(%rsp)"; - &lea ("%rsp","-$PUSH8(%rsp)") if (($j%2)==0); + if (($j%2)==0) { + &lea ("%rsp","-$PUSH8(%rsp)"); +$code.=<<___ if (!$win64); +.cfi_cfa_expression %rsp+`$PUSH8-8`,deref,+8 +# copy secondary frame pointer to new location again at -8(%rsp) + pushq $PUSH8-8(%rsp) +.cfi_cfa_expression %rsp,deref,+8 + lea 8(%rsp),%rsp +.cfi_cfa_expression %rsp-8,deref,+8 +___ + } + foreach (Xupdate_256_AVX()) { # 29 instructions eval; eval(shift(@insns)); @@ -2085,7 +2114,23 @@ $code.=<<___; vmovdqa $t2,0x40(%rsp) vpaddq 0x40($Tbl),@X[6],$t2 vmovdqa $t3,0x60(%rsp) +___ +$code.=<<___ if (!$win64); +# temporarily use %rdi as frame pointer + mov $_rsp,%rdi +.cfi_def_cfa %rdi,8 +___ +$code.=<<___; lea -$PUSH8(%rsp),%rsp +___ +$code.=<<___ if (!$win64); +# the frame info is at $_rsp, but the stack is moving... +# so a second frame pointer is saved at -8(%rsp) +# that is in the red zone + mov %rdi,-8(%rsp) +.cfi_cfa_expression %rsp-8,deref,+8 +___ +$code.=<<___; vpaddq 0x60($Tbl),@X[7],$t3 vmovdqa $t0,0x00(%rsp) xor $a1,$a1 @@ -2109,7 +2154,18 @@ my @X = @_; my @insns = (&$body,&$body); # 48 instructions my $base = "+2*$PUSH8(%rsp)"; - &lea ("%rsp","-$PUSH8(%rsp)") if (($j%4)==0); + if (($j%4)==0) { + &lea ("%rsp","-$PUSH8(%rsp)"); +$code.=<<___ if (!$win64); +.cfi_cfa_expression %rsp+`$PUSH8-8`,deref,+8 +# copy secondary frame pointer to new location again at -8(%rsp) + pushq $PUSH8-8(%rsp) +.cfi_cfa_expression %rsp,deref,+8 + lea 8(%rsp),%rsp +.cfi_cfa_expression %rsp-8,deref,+8 +___ + } + foreach (Xupdate_512_AVX()) { # 23 instructions eval; if ($_ !~ /\;$/) { @@ -2184,6 +2240,8 @@ $code.=<<___; add $a1,$A #mov `2*$SZ*$rounds+8`(%rsp),$inp # $_inp lea `2*$SZ*($rounds-8)`(%rsp),%rsp +# restore frame pointer to original location at $_rsp +.cfi_cfa_expression $_rsp,deref,+8 add $SZ*0($ctx),$A add $SZ*1($ctx),$B @@ -2209,22 +2267,24 @@ $code.=<<___; jbe .Loop_avx2 lea (%rsp),$Tbl +# temporarily use $Tbl as index to $_rsp +# this avoids the need to save a secondary frame pointer at -8(%rsp) +.cfi_cfa_expression $Tbl+`16*$SZ+3*8`,deref,+8 .Ldone_avx2: - lea ($Tbl),%rsp - mov $_rsp,%rsi + mov `16*$SZ+3*8`($Tbl),%rsi .cfi_def_cfa %rsi,8 vzeroupper ___ $code.=<<___ if ($win64); - movaps 16*$SZ+32(%rsp),%xmm6 - movaps 16*$SZ+48(%rsp),%xmm7 - movaps 16*$SZ+64(%rsp),%xmm8 - movaps 16*$SZ+80(%rsp),%xmm9 + movaps 16*$SZ+32($Tbl),%xmm6 + movaps 16*$SZ+48($Tbl),%xmm7 + movaps 16*$SZ+64($Tbl),%xmm8 + movaps 16*$SZ+80($Tbl),%xmm9 ___ $code.=<<___ if ($win64 && $SZ>4); - movaps 16*$SZ+96(%rsp),%xmm10 - movaps 16*$SZ+112(%rsp),%xmm11 + movaps 16*$SZ+96($Tbl),%xmm10 + movaps 16*$SZ+112($Tbl),%xmm11 ___ $code.=<<___; mov -48(%rsi),%r15 diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c index 03189a9d..c70edf57 100644 --- a/crypto/sha/sha512.c +++ b/crypto/sha/sha512.c @@ -60,6 +60,14 @@ # define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA #endif +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define U64(C) C##UI64 +#elif defined(__arch64__) +# define U64(C) C##UL +#else +# define U64(C) C##ULL +#endif + int sha512_224_init(SHA512_CTX *c) { c->h[0] = U64(0x8c3d37c819544da2); diff --git a/crypto/sm3/build.info b/crypto/sm3/build.info index 6009b194..eca68216 100644 --- a/crypto/sm3/build.info +++ b/crypto/sm3/build.info @@ -1,2 +1,5 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=sm3.c m_sm3.c + +IF[{- !$disabled{sm3} -}] + SOURCE[../../libcrypto]=sm3.c legacy_sm3.c +ENDIF \ No newline at end of file diff --git a/crypto/sm3/legacy_sm3.c b/crypto/sm3/legacy_sm3.c new file mode 100644 index 00000000..da07aed1 --- /dev/null +++ b/crypto/sm3/legacy_sm3.c @@ -0,0 +1,30 @@ +/* + * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017 Ribose Inc. 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 + */ + + +#include "crypto/evp.h" +#include "../evp/legacy_meth.h" +#include "internal/sm3.h" + +IMPLEMENT_LEGACY_EVP_MD_METH_LC(sm3_int, sm3) + +static const EVP_MD sm3_md = { + NID_sm3, + NID_sm3WithRSAEncryption, + SM3_DIGEST_LENGTH, + 0, + LEGACY_EVP_MD_METH_TABLE(sm3_int_init, sm3_int_update, sm3_int_final, NULL, + SM3_CBLOCK), +}; + +const EVP_MD *EVP_sm3(void) +{ + return &sm3_md; +} diff --git a/crypto/sm3/m_sm3.c b/crypto/sm3/m_sm3.c deleted file mode 100644 index 4bccaaf1..00000000 --- a/crypto/sm3/m_sm3.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. - * Copyright 2017 Ribose Inc. 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 - */ - -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_SM3 -# include -# include "internal/sm3.h" -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return sm3_init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return sm3_update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return sm3_final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD sm3_md = { - NID_sm3, - NID_sm3WithRSAEncryption, - SM3_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - SM3_CBLOCK, - sizeof(EVP_MD *) + sizeof(SM3_CTX), -}; - -const EVP_MD *EVP_sm3(void) -{ - return &sm3_md; -} - -#endif diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c index c4dd5153..9505d426 100644 --- a/crypto/srp/srp_vfy.c +++ b/crypto/srp/srp_vfy.c @@ -525,7 +525,7 @@ int SRP_VBASE_add0_user(SRP_VBASE *vb, SRP_user_pwd *user_pwd) return 1; } -# if !OPENSSL_API_1_1_0 +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 /* * DEPRECATED: use SRP_VBASE_get1_by_user instead. * This method ignores the configured seed and fails for an unknown user. diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index 078c7c25..cf9951f0 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -930,7 +930,8 @@ static int file_expect(OSSL_STORE_LOADER_CTX *ctx, int expected) return 1; } -static int file_find(OSSL_STORE_LOADER_CTX *ctx, OSSL_STORE_SEARCH *search) +static int file_find(OSSL_STORE_LOADER_CTX *ctx, + const OSSL_STORE_SEARCH *search) { /* * If ctx == NULL, the library is looking to know if this loader supports diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 92b957c7..d39967cc 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -16,6 +16,7 @@ #include #include +#include #include #include "internal/thread_once.h" #include "crypto/store.h" @@ -74,9 +75,14 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, /* Try each scheme until we find one that could open the URI */ for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { - if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) + OSSL_TRACE1(STORE, "Looking up scheme %s\n", schemes[i]); + if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) { + OSSL_TRACE1(STORE, "Found loader for scheme %s\n", schemes[i]); loader_ctx = loader->open(loader, uri, ui_method, ui_data); + OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); + } } + if (loader_ctx == NULL) goto err; @@ -147,7 +153,7 @@ int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) return 1; } -int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search) +int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) { if (ctx->loading) { OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, @@ -172,6 +178,7 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) if (OSSL_STORE_eof(ctx)) return NULL; + OSSL_TRACE(STORE, "Loading next object\n"); v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data); if (ctx->post_process != NULL && v != NULL) { @@ -203,6 +210,10 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) } } + if (v != NULL) + OSSL_TRACE1(STORE, "Got a %s\n", + OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); + return v; } @@ -218,7 +229,10 @@ int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) int OSSL_STORE_close(OSSL_STORE_CTX *ctx) { - int loader_ret = ctx->loader->close(ctx->loader_ctx); + int loader_ret; + + OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); + loader_ret = ctx->loader->close(ctx->loader_ctx); OPENSSL_free(ctx); return loader_ret; @@ -569,7 +583,7 @@ int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) return criterion->search_type; } -X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion) +X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) { return criterion->name; } diff --git a/crypto/trace.c b/crypto/trace.c index 7ff6af88..18a8c641 100755 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -133,6 +133,7 @@ static const struct trace_category_st trace_categories[] = { TRACE_CATEGORY_(PKCS12_DECRYPT), TRACE_CATEGORY_(X509V3_POLICY), TRACE_CATEGORY_(BN_CTX), + TRACE_CATEGORY_(STORE), }; const char *OSSL_trace_get_category_name(int num) diff --git a/crypto/ui/ui_util.c b/crypto/ui/ui_util.c index b28c1332..f64780a6 100644 --- a/crypto/ui/ui_util.c +++ b/crypto/ui/ui_util.c @@ -8,6 +8,7 @@ */ #include +#include /* PEM_def_callback() */ #include "internal/thread_once.h" #include "ui_local.h" @@ -156,7 +157,7 @@ UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag) return NULL; } data->rwflag = rwflag; - data->cb = cb; + data->cb = cb != NULL ? cb : PEM_def_callback; return ui_method; } diff --git a/crypto/whrlpool/build.info b/crypto/whrlpool/build.info index 6630a779..c4897188 100644 --- a/crypto/whrlpool/build.info +++ b/crypto/whrlpool/build.info @@ -17,13 +17,21 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -SOURCE[../../libcrypto]=wp_dgst.c $WPASM - # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules. -DEFINE[../../libcrypto]=$WPDEF DEFINE[../../providers/libimplementations.a]=$WPDEF +SOURCE[../../libcrypto]=wp_dgst.c $WPASM +DEFINE[../../libcrypto]=$WPDEF + +# When all deprecated symbols are removed, libcrypto doesn't export the +# WHIRLPOOL functions, so we must include them directly in liblegacy.a +IF[{- $disabled{"deprecated"} + && (defined $config{"api"} && $config{"api"} >= 30000) -}] + SOURCE[../../providers/liblegacy.a]=wp_dgst.c $WPASM + DEFINE[../../providers/liblegacy.a]=$WPDEF +ENDIF + GENERATE[wp-mmx.s]=asm/wp-mmx.pl DEPEND[wp-mmx.s]=../perlasm/x86asm.pl diff --git a/crypto/whrlpool/wp_block.c b/crypto/whrlpool/wp_block.c index c24f6733..46fe0d57 100644 --- a/crypto/whrlpool/wp_block.c +++ b/crypto/whrlpool/wp_block.c @@ -36,6 +36,12 @@ * */ +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include "wp_local.h" #include diff --git a/crypto/whrlpool/wp_dgst.c b/crypto/whrlpool/wp_dgst.c index 3a4a8093..3b8232dc 100644 --- a/crypto/whrlpool/wp_dgst.c +++ b/crypto/whrlpool/wp_dgst.c @@ -52,6 +52,12 @@ * input. This is done for performance. */ +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "wp_local.h" #include diff --git a/crypto/x509/build.info b/crypto/x509/build.info index bee9f809..ca7bb2a0 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -5,7 +5,7 @@ SOURCE[../../libcrypto]=\ x509_set.c x509cset.c x509rset.c x509_err.c \ x509name.c x509_v3.c x509_ext.c x509_att.c \ x509type.c x509_meth.c x509_lu.c x_all.c x509_txt.c \ - x509_trs.c by_file.c by_dir.c x509_vpm.c \ + x509_trs.c by_file.c by_dir.c by_store.c x509_vpm.c \ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \ x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c \ v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \ diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c new file mode 100644 index 00000000..b2264d71 --- /dev/null +++ b/crypto/x509/by_store.c @@ -0,0 +1,227 @@ +/* + * Copyright 2018 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 + */ + +#include +#include "internal/cryptlib.h" +#include "crypto/x509.h" +#include "x509_local.h" + +/* Generic object loader, given expected type and criterion */ +static int cache_objects(X509_LOOKUP *lctx, const char *uri, + const OSSL_STORE_SEARCH *criterion, + int depth) +{ + int ok = 0; + OSSL_STORE_CTX *ctx = NULL; + X509_STORE *xstore = X509_LOOKUP_get_store(lctx); + + if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL) + return 0; + + /* + * We try to set the criterion, but don't care if it was valid or not. + * For a OSSL_STORE, it merely serves as an optimization, the expectation + * being that if the criterion couldn't be used, we will get *everything* + * from the container that the URI represents rather than the subset that + * the criterion indicates, so the biggest harm is that we cache more + * objects certs and CRLs than we may expect, but that's ok. + * + * Specifically for OpenSSL's own file: scheme, the only workable + * criterion is the BY_NAME one, which it can only apply on directories, + * but it's possible that the URI is a single file rather than a directory, + * and in that case, the BY_NAME criterion is pointless. + * + * We could very simply not apply any criterion at all here, and just let + * the code that selects certs and CRLs from the cached objects do its job, + * but it's a nice optimization when it can be applied (such as on an + * actual directory with a thousand CA certs). + */ + if (criterion != NULL) + OSSL_STORE_find(ctx, criterion); + + for (;;) { + OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); + int infotype; + + /* NULL means error or "end of file". Either way, we break. */ + if (info == NULL) + break; + + infotype = OSSL_STORE_INFO_get_type(info); + ok = 0; + + if (infotype == OSSL_STORE_INFO_NAME) { + /* + * This is an entry in the "directory" represented by the current + * uri. if |depth| allows, dive into it. + */ + if (depth > 0) + ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info), + criterion, depth - 1); + } else { + /* + * We know that X509_STORE_add_{cert|crl} increments the object's + * refcount, so we can safely use OSSL_STORE_INFO_get0_{cert,crl} + * to get them. + */ + switch (infotype) { + case OSSL_STORE_INFO_CERT: + ok = X509_STORE_add_cert(xstore, + OSSL_STORE_INFO_get0_CERT(info)); + break; + case OSSL_STORE_INFO_CRL: + ok = X509_STORE_add_crl(xstore, + OSSL_STORE_INFO_get0_CRL(info)); + break; + } + } + + OSSL_STORE_INFO_free(info); + if (!ok) + break; + } + OSSL_STORE_close(ctx); + + return ok; +} + + +/* Because OPENSSL_free is a macro and for C type match */ +static void free_uri(OPENSSL_STRING data) +{ + OPENSSL_free(data); +} + +static void by_store_free(X509_LOOKUP *ctx) +{ + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + sk_OPENSSL_STRING_pop_free(uris, free_uri); +} + +static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, + char **retp) +{ + switch (cmd) { + case X509_L_ADD_STORE: + /* If no URI is given, use the default cert dir as default URI */ + if (argp == NULL) + argp = ossl_safe_getenv(X509_get_default_cert_dir_env()); + if (argp == NULL) + argp = X509_get_default_cert_dir(); + + { + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + + if (uris == NULL) { + uris = sk_OPENSSL_STRING_new_null(); + X509_LOOKUP_set_method_data(ctx, uris); + } + return sk_OPENSSL_STRING_push(uris, OPENSSL_strdup(argp)) > 0; + } + case X509_L_LOAD_STORE: + /* This is a shortcut for quick loading of specific containers */ + return cache_objects(ctx, argp, NULL, 0); + } + + return 0; +} + +static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret) +{ + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + int i; + int ok = 0; + + for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) { + ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion, + 1 /* depth */); + + if (ok) + break; + } + return ok; +} + +static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret) +{ + OSSL_STORE_SEARCH *criterion = OSSL_STORE_SEARCH_by_name(name); + int ok = by_store(ctx, type, criterion, ret); + STACK_OF(X509_OBJECT) *store_objects = + X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx)); + X509_OBJECT *tmp = NULL; + + OSSL_STORE_SEARCH_free(criterion); + + if (ok) + tmp = X509_OBJECT_retrieve_by_subject(store_objects, type, name); + + ok = 0; + if (tmp != NULL) { + /* + * This could also be done like this: + * + * if (tmp != NULL) { + * *ret = *tmp; + * ok = 1; + * } + * + * However, we want to exercise the documented API to the max, so + * we do it the hard way. + * + * To be noted is that X509_OBJECT_set1_* increment the refcount, + * but so does X509_STORE_CTX_get_by_subject upon return of this + * function, so we must ensure the the refcount is decremented + * before we return, or we will get a refcount leak. We cannot do + * this with X509_OBJECT_free(), though, as that will free a bit + * too much. + */ + switch (type) { + case X509_LU_X509: + ok = X509_OBJECT_set1_X509(ret, tmp->data.x509); + if (ok) + X509_free(tmp->data.x509); + break; + case X509_LU_CRL: + ok = X509_OBJECT_set1_X509_CRL(ret, tmp->data.crl); + if (ok) + X509_CRL_free(tmp->data.crl); + break; + case X509_LU_NONE: + break; + } + } + return ok; +} + +/* + * We lack the implementations for get_by_issuer_serial, get_by_fingerprint + * and get_by_alias. There's simply not enough support in the X509_LOOKUP + * or X509_STORE APIs. + */ + +static X509_LOOKUP_METHOD x509_store_lookup = { + "Load certs from STORE URIs", + NULL, /* new_item */ + by_store_free, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_store_ctrl, /* ctrl */ + by_store_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_store(void) +{ + return &x509_store_lookup; +} diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c index 8ab09143..fa11e5e4 100644 --- a/crypto/x509/pcy_tree.c +++ b/crypto/x509/pcy_tree.c @@ -49,8 +49,8 @@ static void tree_print(BIO *channel, curr++; BIO_printf(channel, "Level print after %s\n", str); - BIO_printf(channel, "Printing Up to Level %zd\n", - curr - tree->levels); + BIO_printf(channel, "Printing Up to Level %ld\n", + (long)(curr - tree->levels)); for (plev = tree->levels; plev != curr; plev++) { int i; diff --git a/crypto/x509/v3_akey.c b/crypto/x509/v3_akey.c index b656b4b5..4898869b 100644 --- a/crypto/x509/v3_akey.c +++ b/crypto/x509/v3_akey.c @@ -42,13 +42,22 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, char *tmp; if (akeyid->keyid) { tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length); - X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL, tmp, &extlist); + if (tmp == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL, + tmp, &extlist); OPENSSL_free(tmp); } if (akeyid->issuer) extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); if (akeyid->serial) { tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length); + if (tmp == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } X509V3_add_value("serial", tmp, &extlist); OPENSSL_free(tmp); } diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index 5d1ece71..a910d5d7 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -52,11 +52,24 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, { int i; GENERAL_NAME *gen; + STACK_OF(CONF_VALUE) *tmpret = NULL, *origret = ret; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); - ret = i2v_GENERAL_NAME(method, gen, ret); + /* + * i2v_GENERAL_NAME allocates ret if it is NULL. If something goes + * wrong we need to free the stack - but only if it was empty when we + * originally entered this function. + */ + tmpret = i2v_GENERAL_NAME(method, gen, ret); + if (tmpret == NULL) { + if (origret == NULL) + sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); + return NULL; + } + ret = tmpret; } - if (!ret) + if (ret == NULL) return sk_CONF_VALUE_new_null(); return ret; } @@ -73,19 +86,38 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, case GEN_OTHERNAME: switch (OBJ_obj2nid(gen->d.otherName->type_id)) { case NID_id_on_SmtpUTF8Mailbox: - if (!X509V3_add_value_uchar("othername: SmtpUTF8Mailbox:", gen->d.otherName->value->value.utf8string->data, &ret)) + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: SmtpUTF8Mailbox:", + gen->d.otherName->value->value.utf8string->data, + &ret)) return NULL; break; case NID_XmppAddr: - if (!X509V3_add_value_uchar("othername: XmppAddr:", gen->d.otherName->value->value.utf8string->data, &ret)) + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: XmppAddr:", + gen->d.otherName->value->value.utf8string->data, + &ret)) return NULL; break; case NID_SRVName: - if (!X509V3_add_value_uchar("othername: SRVName:", gen->d.otherName->value->value.ia5string->data, &ret)) + if (gen->d.otherName->value->type != V_ASN1_IA5STRING + || !X509V3_add_value_uchar("othername: SRVName:", + gen->d.otherName->value->value.ia5string->data, + &ret)) return NULL; break; case NID_ms_upn: - if (!X509V3_add_value_uchar("othername: UPN:", gen->d.otherName->value->value.utf8string->data, &ret)) + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: UPN:", + gen->d.otherName->value->value.utf8string->data, + &ret)) + return NULL; + break; + case NID_NAIRealm: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: NAIRealm:", + gen->d.otherName->value->value.utf8string->data, + &ret)) return NULL; break; default: @@ -161,21 +193,40 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { unsigned char *p; - int i; + int i, nid; + switch (gen->type) { case GEN_OTHERNAME: - switch (OBJ_obj2nid(gen->d.otherName->type_id)) { + nid = OBJ_obj2nid(gen->d.otherName->type_id); + /* Validate the types are as we expect before we use them */ + if ((nid == NID_SRVName + && gen->d.otherName->value->type != V_ASN1_IA5STRING) + || (nid != NID_SRVName + && gen->d.otherName->value->type != V_ASN1_UTF8STRING)) { + BIO_printf(out, "othername:"); + break; + } + + switch (nid) { case NID_id_on_SmtpUTF8Mailbox: - BIO_printf(out, "othername:SmtpUTF8Mailbox:%s", gen->d.otherName->value->value.utf8string->data); + BIO_printf(out, "othername:SmtpUTF8Mailbox:%s", + gen->d.otherName->value->value.utf8string->data); break; case NID_XmppAddr: - BIO_printf(out, "othername:XmppAddr:%s", gen->d.otherName->value->value.utf8string->data); + BIO_printf(out, "othername:XmppAddr:%s", + gen->d.otherName->value->value.utf8string->data); break; case NID_SRVName: - BIO_printf(out, "othername:SRVName:%s", gen->d.otherName->value->value.ia5string->data); + BIO_printf(out, "othername:SRVName:%s", + gen->d.otherName->value->value.ia5string->data); break; case NID_ms_upn: - BIO_printf(out, "othername:UPN:%s", gen->d.otherName->value->value.utf8string->data); + BIO_printf(out, "othername:UPN:%s", + gen->d.otherName->value->value.utf8string->data); + break; + case NID_NAIRealm: + BIO_printf(out, "othername:NAIRealm:%s", + gen->d.otherName->value->value.utf8string->data); break; default: BIO_printf(out, "othername:"); diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index 70d57f52..cb0f84a7 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -26,32 +26,64 @@ int X509_STORE_set_default_paths(X509_STORE *ctx) return 0; X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store()); + if (lookup == NULL) + return 0; + X509_LOOKUP_add_store(lookup, NULL); + /* clear any errors */ ERR_clear_error(); return 1; } -int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *path) +int X509_STORE_load_file(X509_STORE *ctx, const char *file) { X509_LOOKUP *lookup; - if (file != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return 0; - if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) - return 0; - } - if (path != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return 0; - if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) - return 0; - } - if ((path == NULL) && (file == NULL)) + if (file == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file())) == NULL + || X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) == 0) + return 0; + + return 1; +} + +int X509_STORE_load_path(X509_STORE *ctx, const char *path) +{ + X509_LOOKUP *lookup; + + if (path == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir())) == NULL + || X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) == 0) + return 0; + + return 1; +} + +int X509_STORE_load_store(X509_STORE *ctx, const char *uri) +{ + X509_LOOKUP *lookup; + + if (uri == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store())) == NULL + || X509_LOOKUP_add_store(lookup, uri) == 0) + return 0; + + return 1; +} + +/* Deprecated */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + if (file == NULL && path == NULL) + return 0; + if (file != NULL && !X509_STORE_load_file(ctx, file)) + return 0; + if (path != NULL && !X509_STORE_load_path(ctx, path)) return 0; return 1; } +#endif diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 1e2e4cd5..c8d12588 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1851,6 +1851,31 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) return ret; } +/* + * Return 0 if time should not be checked or reference time is in range, + * or else 1 if it is past the end, or -1 if it is before the start + */ +int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm, + const ASN1_TIME *start, const ASN1_TIME *end) +{ + time_t ref_time; + time_t *time = NULL; + unsigned long flags = vpm == NULL ? 0 : X509_VERIFY_PARAM_get_flags(vpm); + + if ((flags & X509_V_FLAG_USE_CHECK_TIME) != 0) { + ref_time = X509_VERIFY_PARAM_get_time(vpm); + time = &ref_time; + } else if ((flags & X509_V_FLAG_NO_CHECK_TIME) != 0) { + return 0; /* this means ok */ + } /* else reference time is the current time */ + + if (end != NULL && X509_cmp_time(end, time) < 0) + return 1; + if (start != NULL && X509_cmp_time(start, time) > 0) + return -1; + return 0; +} + ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) { return X509_time_adj(s, adj, NULL); diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 782fa136..27156b9b 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -282,7 +282,7 @@ int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, return 1; } -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +unsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param) { return param->flags; } diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c index f1992ddc..23509952 100644 --- a/crypto/x509/x509cset.c +++ b/crypto/x509/x509cset.c @@ -91,7 +91,7 @@ const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) return crl->crl.nextUpdate; } -#if !OPENSSL_API_1_1_0 +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) { return crl->crl.lastUpdate; diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index 9517169b..fbdb100c 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -589,6 +589,30 @@ int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8) return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); } +#ifndef OPENSSL_NO_STDIO +X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_fp_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + fp, xpk); +} + +int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_fp_of(X509_PUBKEY, i2d_X509_PUBKEY, fp, xpk); +} +#endif + +X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_bio_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + bp, xpk); +} + +int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_bio_of(X509_PUBKEY, i2d_X509_PUBKEY, bp, xpk); +} + #ifndef OPENSSL_NO_STDIO PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) diff --git a/crypto/x86_64cpuid.pl b/crypto/x86_64cpuid.pl index 43e53d6f..c9d63644 100644 --- a/crypto/x86_64cpuid.pl +++ b/crypto/x86_64cpuid.pl @@ -41,6 +41,7 @@ print<<___; .type OPENSSL_atomic_add,\@abi-omnipotent .align 16 OPENSSL_atomic_add: +.cfi_startproc movl ($arg1),%eax .Lspin: leaq ($arg2,%rax),%r8 .byte 0xf0 # lock @@ -49,16 +50,19 @@ OPENSSL_atomic_add: movl %r8d,%eax .byte 0x48,0x98 # cltq/cdqe ret +.cfi_endproc .size OPENSSL_atomic_add,.-OPENSSL_atomic_add .globl OPENSSL_rdtsc .type OPENSSL_rdtsc,\@abi-omnipotent .align 16 OPENSSL_rdtsc: +.cfi_startproc rdtsc shl \$32,%rdx or %rdx,%rax ret +.cfi_endproc .size OPENSSL_rdtsc,.-OPENSSL_rdtsc .globl OPENSSL_ia32_cpuid @@ -234,6 +238,7 @@ OPENSSL_ia32_cpuid: .type OPENSSL_cleanse,\@abi-omnipotent .align 16 OPENSSL_cleanse: +.cfi_startproc xor %rax,%rax cmp \$15,$arg2 jae .Lot @@ -263,12 +268,14 @@ OPENSSL_cleanse: cmp \$0,$arg2 jne .Little ret +.cfi_endproc .size OPENSSL_cleanse,.-OPENSSL_cleanse .globl CRYPTO_memcmp .type CRYPTO_memcmp,\@abi-omnipotent .align 16 CRYPTO_memcmp: +.cfi_startproc xor %rax,%rax xor %r10,%r10 cmp \$0,$arg3 @@ -297,6 +304,7 @@ CRYPTO_memcmp: shr \$63,%rax .Lno_data: ret +.cfi_endproc .size CRYPTO_memcmp,.-CRYPTO_memcmp ___ @@ -305,6 +313,7 @@ print<<___ if (!$win64); .type OPENSSL_wipe_cpu,\@abi-omnipotent .align 16 OPENSSL_wipe_cpu: +.cfi_startproc pxor %xmm0,%xmm0 pxor %xmm1,%xmm1 pxor %xmm2,%xmm2 @@ -331,6 +340,7 @@ OPENSSL_wipe_cpu: xorq %r11,%r11 leaq 8(%rsp),%rax ret +.cfi_endproc .size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu ___ print<<___ if ($win64); @@ -367,6 +377,7 @@ print<<___; .type OPENSSL_instrument_bus,\@abi-omnipotent .align 16 OPENSSL_instrument_bus: +.cfi_startproc mov $arg1,$out # tribute to Win64 mov $arg2,$cnt mov $arg2,$max @@ -393,12 +404,14 @@ OPENSSL_instrument_bus: mov $max,%rax ret +.cfi_endproc .size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus .globl OPENSSL_instrument_bus2 .type OPENSSL_instrument_bus2,\@abi-omnipotent .align 16 OPENSSL_instrument_bus2: +.cfi_startproc mov $arg1,$out # tribute to Win64 mov $arg2,$cnt mov $arg3,$max @@ -441,6 +454,7 @@ OPENSSL_instrument_bus2: mov $redzone(%rsp),%rax sub $cnt,%rax ret +.cfi_endproc .size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 ___ } @@ -452,6 +466,7 @@ print<<___; .type OPENSSL_ia32_${rdop}_bytes,\@abi-omnipotent .align 16 OPENSSL_ia32_${rdop}_bytes: +.cfi_startproc xor %rax, %rax # return value cmp \$0,$arg2 je .Ldone_${rdop}_bytes @@ -488,6 +503,7 @@ OPENSSL_ia32_${rdop}_bytes: .Ldone_${rdop}_bytes: xor %r10,%r10 # Clear sensitive data from register ret +.cfi_endproc .size OPENSSL_ia32_${rdop}_bytes,.-OPENSSL_ia32_${rdop}_bytes ___ } diff --git a/demos/certs/apps/apps.cnf b/demos/certs/apps/apps.cnf index 531afe64..bd762b7d 100644 --- a/demos/certs/apps/apps.cnf +++ b/demos/certs/apps/apps.cnf @@ -5,7 +5,6 @@ # This definition stops the following lines choking if HOME or CN # is undefined. HOME = . -RANDFILE = $ENV::HOME/.rnd CN = "Not Defined" #################################################################### diff --git a/demos/certs/ca.cnf b/demos/certs/ca.cnf index 5a8a5f29..c75a71a6 100644 --- a/demos/certs/ca.cnf +++ b/demos/certs/ca.cnf @@ -5,7 +5,6 @@ # This definition stops the following lines choking if HOME or CN # is undefined. HOME = . -RANDFILE = $ENV::HOME/.rnd CN = "Not Defined" default_ca = ca diff --git a/doc/HOWTO/proxy_certificates.txt b/doc/HOWTO/proxy_certificates.txt deleted file mode 100644 index f6f754cc..00000000 --- a/doc/HOWTO/proxy_certificates.txt +++ /dev/null @@ -1,319 +0,0 @@ - HOWTO proxy certificates - -0. WARNING - -NONE OF THE CODE PRESENTED HERE HAS BEEN CHECKED! The code is just examples to -show you how things could be done. There might be typos or type conflicts, and -you will have to resolve them. - -1. Introduction - -Proxy certificates are defined in RFC 3820. They are really usual certificates -with the mandatory extension proxyCertInfo. - -Proxy certificates are issued by an End Entity (typically a user), either -directly with the EE certificate as issuing certificate, or by extension through -an already issued proxy certificate. Proxy certificates are used to extend -rights to some other entity (a computer process, typically, or sometimes to the -user itself). This allows the entity to perform operations on behalf of the -owner of the EE certificate. - -See https://www.ietf.org/rfc/rfc3820.txt for more information. - - -2. A warning about proxy certificates - -No one seems to have tested proxy certificates with security in mind. To this -date, it seems that proxy certificates have only been used in a context highly -aware of them. - -Existing applications might misbehave when trying to validate a chain of -certificates which use a proxy certificate. They might incorrectly consider the -leaf to be the certificate to check for authorisation data, which is controlled -by the EE certificate owner. - -subjectAltName and issuerAltName are forbidden in proxy certificates, and this -is enforced in OpenSSL. The subject must be the same as the issuer, with one -commonName added on. - -Possible threats we can think of at this time include: - - - impersonation through commonName (think server certificates). - - use of additional extensions, possibly non-standard ones used in certain - environments, that would grant extra or different authorisation rights. - -For these reasons, OpenSSL requires that the use of proxy certificates be -explicitly allowed. Currently, this can be done using the following methods: - - - if the application directly calls X509_verify_cert(), it can first call: - - X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); - - Where ctx is the pointer which then gets passed to X509_verify_cert(). - - - proxy certificate validation can be enabled before starting the application - by setting the environment variable OPENSSL_ALLOW_PROXY_CERTS. - -In the future, it might be possible to enable proxy certificates by editing -openssl.cnf. - - -3. How to create proxy certificates - -Creating proxy certificates is quite easy, by taking advantage of a lack of -checks in the 'openssl x509' application (*ahem*). You must first create a -configuration section that contains a definition of the proxyCertInfo extension, -for example: - - [ v3_proxy ] - # A proxy certificate MUST NEVER be a CA certificate. - basicConstraints=CA:FALSE - - # Usual authority key ID - authorityKeyIdentifier=keyid,issuer:always - - # The extension which marks this certificate as a proxy - proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB - -It's also possible to specify the proxy extension in a separate section: - - proxyCertInfo=critical,@proxy_ext - - [ proxy_ext ] - language=id-ppl-anyLanguage - pathlen=0 - policy=text:BC - -The policy value has a specific syntax, {syntag}:{string}, where the syntag -determines what will be done with the string. The following syntags are -recognised: - - text indicates that the string is simply bytes, without any encoding: - - policy=text:räksmörgÃ¥s - - Previous versions of this design had a specific tag for UTF-8 text. - However, since the bytes are copied as-is anyway, there is no need for - such a specific tag. - - hex indicates the string is encoded in hex, with colons between each byte - (every second hex digit): - - policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73 - - Previous versions of this design had a tag to insert a complete DER - blob. However, the only legal use for this would be to surround the - bytes that would go with the hex: tag with whatever is needed to - construct a correct OCTET STRING. The DER tag therefore felt - superfluous, and was removed. - - file indicates that the text of the policy should really be taken from a - file. The string is then really a filename. This is useful for - policies that are large (more than a few lines, e.g. XML documents). - -The 'policy' setting can be split up in multiple lines like this: - - 0.policy=This is - 1.policy= a multi- - 2.policy=line policy. - -NOTE: the proxy policy value is the part which determines the rights granted to -the process using the proxy certificate. The value is completely dependent on -the application reading and interpreting it! - -Now that you have created an extension section for your proxy certificate, you -can easily create a proxy certificate by doing: - - openssl req -new -config openssl.cnf -out proxy.req -keyout proxy.key - openssl x509 -req -CAcreateserial -in proxy.req -days 7 -out proxy.crt \ - -CA user.crt -CAkey user.key -extfile openssl.cnf -extensions v3_proxy - -You can also create a proxy certificate using another proxy certificate as -issuer (note: I'm using a different configuration section for it): - - openssl req -new -config openssl.cnf -out proxy2.req -keyout proxy2.key - openssl x509 -req -CAcreateserial -in proxy2.req -days 7 -out proxy2.crt \ - -CA proxy.crt -CAkey proxy.key -extfile openssl.cnf -extensions v3_proxy2 - - -4. How to have your application interpret the policy? - -The basic way to interpret proxy policies is to start with some default rights, -then compute the resulting rights by checking the proxy certificate against -the chain of proxy certificates, user certificate and CA certificates. You then -use the final computed rights. Sounds easy, huh? It almost is. - -The slightly complicated part is figuring out how to pass data between your -application and the certificate validation procedure. - -You need the following ingredients: - - - a callback function that will be called for every certificate being - validated. The callback be called several times for each certificate, - so you must be careful to do the proxy policy interpretation at the right - time. You also need to fill in the defaults when the EE certificate is - checked. - - - a data structure that is shared between your application code and the - callback. - - - a wrapper function that sets it all up. - - - an ex_data index function that creates an index into the generic ex_data - store that is attached to an X509 validation context. - -Here is some skeleton code you can fill in: - - #include - #include - #include - #include - - #define total_rights 25 - - /* - * In this example, I will use a view of granted rights as a bit - * array, one bit for each possible right. - */ - typedef struct your_rights { - unsigned char rights[(total_rights + 7) / 8]; - } YOUR_RIGHTS; - - /* - * The following procedure will create an index for the ex_data - * store in the X509 validation context the first time it's called. - * Subsequent calls will return the same index. */ - static int get_proxy_auth_ex_data_idx(X509_STORE_CTX *ctx) - { - static volatile int idx = -1; - if (idx < 0) { - X509_STORE_lock(X509_STORE_CTX_get0_store(ctx)); - if (idx < 0) { - idx = X509_STORE_CTX_get_ex_new_index(0, - "for verify callback", - NULL,NULL,NULL); - } - X509_STORE_unlock(X509_STORE_CTX_get0_store(ctx)); - } - return idx; - } - - /* Callback to be given to the X509 validation procedure. */ - static int verify_callback(int ok, X509_STORE_CTX *ctx) - { - if (ok == 1) { - /* - * It's REALLY important you keep the proxy policy - * check within this section. It's important to know - * that when ok is 1, the certificates are checked - * from top to bottom. You get the CA root first, - * followed by the possible chain of intermediate - * CAs, followed by the EE certificate, followed by - * the possible proxy certificates. - */ - X509 *xs = X509_STORE_CTX_get_current_cert(ctx); - - if (X509_get_extension_flags(xs) & EXFLAG_PROXY) { - YOUR_RIGHTS *rights = - (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, - get_proxy_auth_ex_data_idx(ctx)); - PROXY_CERT_INFO_EXTENSION *pci = - X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL); - - switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { - case NID_Independent: - /* - * Do whatever you need to grant explicit rights to - * this particular proxy certificate, usually by - * pulling them from some database. If there are none - * to be found, clear all rights (making this and any - * subsequent proxy certificate void of any rights). - */ - memset(rights->rights, 0, sizeof(rights->rights)); - break; - case NID_id_ppl_inheritAll: - /* - * This is basically a NOP, we simply let the current - * rights stand as they are. - */ - break; - default: - /* This is usually the most complex section of code. - * You really do whatever you want as long as you - * follow RFC 3820. In the example we use here, the - * simplest thing to do is to build another, temporary - * bit array and fill it with the rights granted by - * the current proxy certificate, then use it as a - * mask on the accumulated rights bit array, and - * voilà, you now have a new accumulated rights bit - * array. - */ - { - int i; - YOUR_RIGHTS tmp_rights; - memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights)); - - /* - * process_rights() is supposed to be a procedure - * that takes a string and its length, interprets - * it and sets the bits in the YOUR_RIGHTS pointed - * at by the third argument. - */ - process_rights((char *) pci->proxyPolicy->policy->data, - pci->proxyPolicy->policy->length, - &tmp_rights); - - for(i = 0; i < total_rights / 8; i++) - rights->rights[i] &= tmp_rights.rights[i]; - } - break; - } - PROXY_CERT_INFO_EXTENSION_free(pci); - } else if (!(X509_get_extension_flags(xs) & EXFLAG_CA)) { - /* We have an EE certificate, let's use it to set default! */ - YOUR_RIGHTS *rights = - (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, - get_proxy_auth_ex_data_idx(ctx)); - - /* The following procedure finds out what rights the owner - * of the current certificate has, and sets them in the - * YOUR_RIGHTS structure pointed at by the second - * argument. - */ - set_default_rights(xs, rights); - } - } - return ok; - } - - static int my_X509_verify_cert(X509_STORE_CTX *ctx, - YOUR_RIGHTS *needed_rights) - { - int ok; - int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) = - X509_STORE_CTX_get_verify_cb(ctx); - YOUR_RIGHTS rights; - - X509_STORE_CTX_set_verify_cb(ctx, verify_callback); - X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(ctx), &rights); - X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); - ok = X509_verify_cert(ctx); - - if (ok == 1) { - ok = check_needed_rights(rights, needed_rights); - } - - X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb); - - return ok; - } - - -If you use SSL or TLS, you can easily set up a callback to have the -certificates checked properly, using the code above: - - SSL_CTX_set_cert_verify_callback(s_ctx, my_X509_verify_cert, &needed_rights); - - --- -Richard Levitte diff --git a/doc/build.info b/doc/build.info new file mode 100644 index 00000000..47728fed --- /dev/null +++ b/doc/build.info @@ -0,0 +1,66 @@ +SUBDIRS = man1 + +{- + use File::Spec::Functions qw(:DEFAULT abs2rel rel2abs); + use File::Basename; + + foreach my $section ((1, 3, 5, 7)) { + my @htmlfiles = (); + my @manfiles = (); + my %podfiles = + map { $_ => 1 } glob catfile($sourcedir, "man$section", "*.pod"); + my %podinfiles = + map { $_ => 1 } glob catfile($sourcedir, "man$section", "*.pod.in"); + + foreach (keys %podinfiles) { + (my $p = $_) =~ s|\.in$||i; + $podfiles{$p} = 1; + } + + foreach my $p (sort keys %podfiles) { + my $podfile = abs2rel($p, $sourcedir); + my $podname = basename($podfile, '.pod'); + my $podinfile = $podinfiles{"$p.in"} ? "$podfile.in" : undef; + + my $podname = basename($podfile, ".pod"); + + my $htmlfile = abs2rel(catfile($buildtop, "doc", "html", "man$section", + "$podname.html"), + catdir($buildtop, "doc")); + my $manfile = abs2rel(catfile($buildtop, "doc", "man", "man$section", + "$podname.$section"), + catdir($buildtop, "doc")); + + # The build.info format requires file specs to be in Unix format. + # Especially, since VMS file specs use [ and ], the build.info parser + # will otherwise get terribly confused. + if ($^O eq 'VMS') { + $htmlfile = VMS::Filespec::unixify($htmlfile); + $manfile = VMS::Filespec::unixify($manfile); + $podfile = VMS::Filespec::unixify($podfile); + $podinfile = VMS::Filespec::unixify($podinfile) + if defined $podinfile; + } elsif ($^O eq 'MSWin32') { + $htmlfile =~ s|\\|/|g; + $manfile =~ s|\\|/|g; + $podfile =~ s|\\|/|g; + $podinfile =~ s|\\|/|g + if defined $podinfile; + } + push @htmlfiles, $htmlfile; + push @manfiles, $manfile; + $OUT .= << "_____"; +DEPEND[$htmlfile]=$podfile +GENERATE[$htmlfile]=$podfile +DEPEND[$manfile]=$podfile +GENERATE[$manfile]=$podfile +_____ + $OUT .= << "_____" if $podinfile; +DEPEND[$podfile]=$podinfile ../configdata.pm +GENERATE[$podfile]=$podinfile +_____ + } + $OUT .= "HTMLDOCS[man$section]=" . join(" \\\n", @htmlfiles) . "\n"; + $OUT .= "MANDOCS[man$section]=" . join(" \\\n", @manfiles) . "\n"; + } + -} diff --git a/doc/internal/man3/OSSL_METHOD_STORE.pod b/doc/internal/man3/OSSL_METHOD_STORE.pod index 2ffe8201..2768524e 100644 --- a/doc/internal/man3/OSSL_METHOD_STORE.pod +++ b/doc/internal/man3/OSSL_METHOD_STORE.pod @@ -33,7 +33,9 @@ ossl_method_store_cache_get, ossl_method_store_cache_set int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, const char *prop_query, void **method); int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, - const char *prop_query, void *method); + const char *prop_query, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)); =head1 DESCRIPTION @@ -95,6 +97,9 @@ The result, if any, is returned in I. ossl_method_store_cache_set() sets a cache entry identified by I with the property query I in the I. Future calls to ossl_method_store_cache_get() will return the specified I. +The I function is called to increment the +reference count of the method and the I function is called +to decrement it. =head1 RETURN VALUES diff --git a/doc/internal/man3/cms_add1_signing_cert.pod b/doc/internal/man3/cms_add1_signing_cert.pod index ac7f813e..97c5a511 100644 --- a/doc/internal/man3/cms_add1_signing_cert.pod +++ b/doc/internal/man3/cms_add1_signing_cert.pod @@ -27,7 +27,7 @@ which updates Section 5.4 of RFC 2634. This attribute is mandatory to make a CMS compliant with CAdES-BES (European Standard ETSI EN 319 122-1 V1.1.1). -For a fuller description see L). +For a fuller description see L). =head1 RETURN VALUES diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod index c4734394..4cff97de 100644 --- a/doc/internal/man3/evp_generic_fetch.pod +++ b/doc/internal/man3/evp_generic_fetch.pod @@ -252,7 +252,7 @@ And finally, the library functions: =head1 SEE ALSO -L +L =head1 HISTORY diff --git a/doc/internal/man3/ossl_algorithm_do_all.pod b/doc/internal/man3/ossl_algorithm_do_all.pod index 6ef85a72..ce925d32 100644 --- a/doc/internal/man3/ossl_algorithm_do_all.pod +++ b/doc/internal/man3/ossl_algorithm_do_all.pod @@ -41,11 +41,11 @@ The function described here are mainly useful for discovery, and possibly display of what has been discovered, for example an application that wants to display the loaded providers and what they may offer, but also for constructors, such as -L. +L. =head1 SEE ALSO -L, L +L, L =head1 HISTORY diff --git a/doc/internal/man3/ossl_cmp_hdr_init.pod b/doc/internal/man3/ossl_cmp_hdr_init.pod new file mode 100644 index 00000000..a7a4d87f --- /dev/null +++ b/doc/internal/man3/ossl_cmp_hdr_init.pod @@ -0,0 +1,127 @@ +=pod + +=head1 NAME + +ossl_cmp_hdr_set_pvno, +ossl_cmp_hdr_get_pvno, +ossl_cmp_hdr_get0_sendernonce, +ossl_cmp_hdr_set1_sender, +ossl_cmp_hdr_set1_recipient, +ossl_cmp_hdr_update_messagetime, +ossl_cmp_hdr_set1_senderKID, +ossl_cmp_hdr_push0_freeText, +ossl_cmp_hdr_push1_freeText, +ossl_cmp_hdr_generalinfo_item_push0, +ossl_cmp_hdr_generalinfo_items_push1, +ossl_cmp_hdr_set_implicitConfirm, +ossl_cmp_hdr_check_implicitConfirm, +ossl_cmp_hdr_init +- functions manipulating CMP message headers + +=head1 SYNOPSIS + + #include "cmp_int.h" + + int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); + int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); + ASN1_OCTET_STRING + *ossl_cmp_hdr_get0_sendernonce(const OSSL_CMP_PKIHEADER *hdr); + + int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); + int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); + int ossl_cmp_hdr_update_messagetime(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID); + int ossl_cmp_hdr_generalinfo_item_push0(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav); + int ossl_cmp_hdr_generalinfo_items_push1(OSSL_CMP_PKIHEADER *hdr, + STACK_OF(OSSL_CMP_ITAV) *itavs); + int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, + ASN1_UTF8STRING *text); + int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, + ASN1_UTF8STRING *text); + int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_check_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); + +=head1 DESCRIPTION + +ossl_cmp_hdr_set_pvno() sets hdr->pvno to the given B. + +ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. + +ossl_cmp_hdr_get0_sendernonce() returns the sender nonce of the given PKIHeader. + +ossl_cmp_hdr_set1_sender() sets the sender field in the given PKIHeader +to the given X509 Name value, without consuming the pointer. + +ossl_cmp_hdr_set1_recipient() sets the recipient field in the given +PKIHeader to the given X509 Name value, without consuming the pointer. +If B is NULL, recipient is set to the NULL DN (the empty list of strings). + +ossl_cmp_hdr_update_messagetime() (re-)sets the messageTime to the current +system time. As written in RFC 4210, section 5.1.1: +The messageTime field contains the time at which the sender created the message. +This may be useful to allow end entities to correct/check their local time for +consistency with the time on a central system. + +ossl_cmp_hdr_set1_senderKID() Sets hdr->senderKID to the given string. +In an PBMAC-protected IR this usually is a reference number issued by the CA, +else the subject key ID of the sender's protecting certificate. + +ossl_cmp_hdr_push0_freeText() pushes an ASN1_UTF8STRING to +hdr->freeText and consumes the given pointer. + +ossl_cmp_hdr_push1_freeText() pushes an ASN1_UTF8STRING to +hdr->freeText and does not consume the pointer. + +ossl_cmp_hdr_generalinfo_item_push0() adds the given InfoTypeAndValue +item to the hdr->generalInfo stack. Consumes the B pointer. + +ossl_cmp_hdr_generalinfo_items_push1() adds a copy of the B stack to +the generalInfo field of PKIheader of the B. Does not consume the B +pointer. + +ossl_cmp_hdr_set_implicitConfirm() sets implicitConfirm in the generalInfo field +of the PKIMessage header. + +ossl_cmp_hdr_check_implicitConfirm() returns 1 if implicitConfirm is +set int generalInfo field of the given PKIMessage header, 0 if not. + +ossl_cmp_hdr_init() initializes a PKIHeader structure based on the +values in the given OSSL_CMP_CTX structure. +This starts a new transaction in case ctx->transactionID is NULL. +The sender name is copied from the subject of the client cert, if any, +or else from the subject name provided for certification requests. +As required by RFC 4210 section 5.1.1., if the sender name is not known +to the client it set to the NULL-DN. In this case for identification at least +the senderKID must be set, which we take from any referenceValue provided. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. + +ossl_cmp_hdr_get0_sendernonce() returns the respective nonce. + +All other functions return 1 on success, 0 on error. + +See the individual functions above. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2019 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 +L. + +=cut diff --git a/doc/internal/man3/ossl_cmp_statusinfo_new.pod b/doc/internal/man3/ossl_cmp_statusinfo_new.pod new file mode 100644 index 00000000..6a720564 --- /dev/null +++ b/doc/internal/man3/ossl_cmp_statusinfo_new.pod @@ -0,0 +1,107 @@ +=pod + +=head1 NAME + +ossl_cmp_statusinfo_new, +ossl_cmp_pkisi_pkistatus_get, +ossl_cmp_pkisi_pkifailureinfo_get, +ossl_cmp_pkisi_pkifailureinfo_check, +ossl_cmp_pkisi_failinfo_get0, +ossl_cmp_pkisi_statusstring_get0, +ossl_pkisi_snprint +- functions for managing PKI status information + +=head1 SYNOPSIS + + #include "cmp.h" + +# define OSSL_CMP_PKIFAILUREINFO_badAlg 0 +# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1 +# define OSSL_CMP_PKIFAILUREINFO_badRequest 2 +# define OSSL_CMP_PKIFAILUREINFO_badTime 3 +# define OSSL_CMP_PKIFAILUREINFO_badCertId 4 +# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5 +# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6 +# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7 +# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8 +# define OSSL_CMP_PKIFAILUREINFO_badPOP 9 +# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10 +# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11 +# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12 +# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13 +# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16 +# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17 +# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18 +# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19 +# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20 +# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21 +# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22 +# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23 +# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24 +# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25 +# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26 +# define OSSL_CMP_PKIFAILUREINFO_MAX 26 + + OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info, + const char *text); + int ossl_cmp_pkisi_pkistatus_get(OSSL_CMP_PKISI *si); + int ossl_cmp_pkisi_pkifailureinfo_get(OSSL_CMP_PKISI *si); + int ossl_cmp_pkisi_pkifailureinfo_check(OSSL_CMP_PKISI *si, int bit_index); + OSSL_CMP_PKIFAILUREINFO *ossl_cmp_pkisi_failinfo_get0(const OSSL_CMP_PKISI *si); + OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_statusstring_get0(const OSSL_CMP_PKISI *si); + char *ossl_pkisi_snprint(OSSL_CMP_PKISI *si, char *buf, int bufsize); + +=head1 DESCRIPTION + +ossl_cmp_statusinfo_new() creates a new PKIStatusInfo structure and fills it +with the given values. It sets the status field to B. +If B is not NULL, it is copied to statusString. +B is is interpreted as bit pattern for the failInfo field. +Returns a pointer to the structure on success, or NULL on error. + +ossl_cmp_pkisi_pkistatus_get() returns the PKIStatus of B, or -1 on error. + +ossl_cmp_pkisi_pkifailureinfo_get() returns the PKIFailureInfo bits +of B, encoded as integer, or -1 on error. + +ossl_cmp_pkisi_pkifailureinfo_check() returns the state of the bit (0 or 1) +with index B in the PKIFailureInfo of the B, or -1 on error. + +ossl_cmp_pkisi_failinfo_get0() returns a direct pointer to the failInfo +field contained in B, or NULL on error. + +ossl_cmp_pkisi_statusstring_get0() returns a direct pointer to the statusString +field contained in B. + +ossl_pkisi_snprint() places at max B characters of human-readable +error string of B in pre-allocated B. Returns pointer to the same +B containing the string, or NULL on error. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +See the individual functions above. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2019 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 +L. + +=cut diff --git a/doc/internal/man3/ossl_init_thread_deregister.pod b/doc/internal/man3/ossl_init_thread_deregister.pod index 923b5254..6c9e0b5b 100644 --- a/doc/internal/man3/ossl_init_thread_deregister.pod +++ b/doc/internal/man3/ossl_init_thread_deregister.pod @@ -32,7 +32,7 @@ thread local variable and then register a stop handler. When the thread is stopping the stop handler is called (while on that thread) and the code can clean up the value stored in the thread local variable. -A new stop handler is registerd using the function ossl_init_thread_start(). +A new stop handler is registered using the function ossl_init_thread_start(). The I parameter should be a unique value that can be used to identify a set of common stop handlers and is passed in a later call to ossl_init_thread_deregister. If no later call to ossl_init_thread_deregister is diff --git a/doc/internal/man3/ossl_namemap_new.pod b/doc/internal/man3/ossl_namemap_new.pod index 2bcf2138..e041510c 100644 --- a/doc/internal/man3/ossl_namemap_new.pod +++ b/doc/internal/man3/ossl_namemap_new.pod @@ -2,8 +2,8 @@ =head1 NAME -ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, -ossl_namemap_add, ossl_namemap_add_n, +ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty, +ossl_namemap_add_name, ossl_namemap_add_name_n, ossl_namemap_add_names, ossl_namemap_name2num, ossl_namemap_name2num_n, ossl_namemap_doall_names - internal number E-E name map @@ -16,10 +16,11 @@ ossl_namemap_doall_names OSSL_NAMEMAP *ossl_namemap_new(void); void ossl_namemap_free(OSSL_NAMEMAP *namemap); + int ossl_namemap_empty(OSSL_NAMEMAP *namemap); - int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name); - int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number, - const char *name, size_t name_len); + int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name); + int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number, + const char *name, size_t name_len); int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name); int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap, @@ -28,6 +29,9 @@ ossl_namemap_doall_names void (*fn)(const char *name, void *data), void *data); + int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number, + const char *names, const char separator); + =head1 DESCRIPTION A B is a one-to-many number E-E names map, which @@ -40,12 +44,15 @@ new B. This is suitable to use when the B is embedded in other structures, or should be independent for any reason. +ossl_namemap_empty() checks if the given B is empty or +not. + ossl_namemap_stored() finds or auto-creates the default namemap in the given library context. The returned B can't be destructed using ossl_namemap_free(). -ossl_namemap_add() adds a new name to the namemap if it's not already +ossl_namemap_add_name() adds a new name to the namemap if it's not already present. If the given I is zero, a new number will be allocated to identify this I. @@ -55,25 +62,33 @@ names already associated with that number. ossl_namemap_name2num() finds the number corresponding to the given I. -ossl_namemap_add_n() and ossl_namemap_name2num_n() do the same thing -as ossl_namemap_add() and ossl_namemap_name2num(), but take a string +ossl_namemap_add_name_n() and ossl_namemap_name2num_n() do the same thing +as ossl_namemap_add_name() and ossl_namemap_name2num(), but take a string length I as well, allowing the caller to use a fragment of a string as a name. - ossl_namemap_doall_names() walks through all names associated with I in the given I and calls the function I for each of them. I is also passed the I argument, which allows any caller to pass extra data for that function to use. +ossl_namemap_add_names() divides up a set of names given in I, +separated by I, and adds each to the I, all with +the same number. If some of them already exist in the I, +they must all have the same associated number, which will be adopted +for any name that doesn't exist yet. + =head1 RETURN VALUES ossl_namemap_new() and ossl_namemap_stored() return the pointer to a B, or NULL on error. -ossl_namemap_add() and ossl_namemap_add_n() return the number associated -with the added string, or zero on error. +ossl_namemap_empty() returns 1 if the B is NULL or +empty, or 0 if it's not empty. + +ossl_namemap_add_name() and ossl_namemap_add_name_n() return the number +associated with the added string, or zero on error. ossl_namemap_num2names() returns a pointer to a NULL-terminated list of pointers to the names corresponding to the given number, or NULL if @@ -83,6 +98,9 @@ ossl_namemap_name2num() and ossl_namemap_name2num_n() return the number corresponding to the given name, or 0 if it's undefined in the given B. +ossl_namemap_add_names() returns the number associated with the added +names, or zero on error. + =head1 NOTES The result from ossl_namemap_num2names() isn't thread safe, other threads diff --git a/doc/internal/man3/ossl_param_bld_init.pod b/doc/internal/man3/ossl_param_bld_init.pod index 062e2c29..2fb7c4f3 100644 --- a/doc/internal/man3/ossl_param_bld_init.pod +++ b/doc/internal/man3/ossl_param_bld_init.pod @@ -178,7 +178,7 @@ public key. =head1 SEE ALSO -L, L +L, L =head1 HISTORY diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index 39c3cba0..36fe6301 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -261,7 +261,7 @@ ossl_provider_library_context() return a pointer to the library context. This may be NULL, and is perfectly valid, as it denotes the default global library context. -ossl_provider_teardown() doesnt't return any value. +ossl_provider_teardown() doesn't return any value. ossl_provider_gettable_params() returns a pointer to a constant I array if this function is available in the provider, diff --git a/doc/internal/man3/rsa_get0_all_params.pod b/doc/internal/man3/rsa_get0_all_params.pod new file mode 100644 index 00000000..c71028c1 --- /dev/null +++ b/doc/internal/man3/rsa_get0_all_params.pod @@ -0,0 +1,75 @@ +=pod + +=head1 NAME + +rsa_set0_all_params, rsa_get0_all_params +- Internal routines for getting and setting data in an RSA object + +=head1 SYNOPSIS + + #include "crypto/rsa.h" + + int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs); + int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs); + +=head1 DESCRIPTION + +rsa_set0_all_params() sets all primes, CRT exponents and CRT coefficients +in the B object I to the contents of the stacks of BIGNUMs I, +I and I. The B object takes ownership of the BIGNUMs, +but not of the stacks. + +rsa_get0_all_params() gets all primes, CRT exponents and CRT coefficients +in the B object I and pushes them on the stacks of constant BIGNUMs +I, I and I. The B object retains ownership of the +BIGNUMs, but not of the stacks. + +=head1 NOTES + +For RSA_set0_all_params() and RSA_get0_all_params(): + +=over 4 + +=item * + +the I stack contains I

, I, and then the rest of the primes +if the B object is a multi-prime RSA key. + +=item * + +the I stack contains I, I, and then the rest of the exponents +if the B object is a multi-prime RSA key. + +=item * + +the I stack contains I, and then the rest of the coefficients +if the B object is a multi-prime RSA key. + +=back + +The number of primes must always be equal to the number of exponents, and +the number of coefficients must be one less than the number of primes. + +=head1 RETURN VALUES + +rsa_get0_all_params() and rsa_set0_all_params() return 1 on success, or +0 on failure. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2019 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 +L. + +=cut diff --git a/doc/internal/man7/VERSION.pod b/doc/internal/man7/VERSION.pod new file mode 100644 index 00000000..4bc8ba6b --- /dev/null +++ b/doc/internal/man7/VERSION.pod @@ -0,0 +1,149 @@ +=pod + +=head1 NAME + +VERSION - OpenSSL version information + +=head1 SYNOPSIS + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=dev + BUILD_METADATA= + RELEASE_DATE= + SHLIB_VERSION=3 + +=head1 DESCRIPTION + +This file is a set of keyed information looking like simple variable +assignments. When given an empty value, they are seen as unassigned. +The keys that are recognised are: + +=over 4 + +=item B, B, B + +The three parts of OpenSSL's 3 numbered version number, MAJOR.MINOR.PATCH. +These are used to compose the values for the C macros B, +B, B. + +=item B + +This is the added pre-release tag, which is added to the version separated by +a dash. For a value C, the C macro B gets +the string C<-foo> (dash added). + +=item B + +Extra metadata to be used by anyone for their own purposes. This is added to +the version and possible pre-release tag, separated by a plus sign. For a +value C, the C macro B gets the string +C<+bar>. + +=item B + +Defined in releases. When not set, it gets the value C. + +=item B + +The shared library version, which is something other than the project version. + +=back + +It is a configuration error if B, B, B and B +don't have values. Configuration will stop in that case. + +=head2 Affected configuration data + +The following items in %config from F are affected: + +=over 4 + +=item $config{major}, $config{minor}, $config{patch}, $config{shlib_version} + +These items get their values from B, B, B, and +B, respectively. + +=item $config{prerelease} + +If B is assigned a value, $config{prerelease} gets that same value, +prefixed by a dash, otherwise the empty string. + +=item $config{build_metadata} + +If B is assigned a value, $config{build_metadata} gets that same +value, prefixed by a plus sign, otherwise the empty string. + +=item $config{release_date} + +If B is assigned a value, $config{release_date} gets that same +value, otherwise the string C. + +=item $config{version} + +The minimal version number, a string composed from B, B and +B, separated by periods. For C, C and C, +the string will be C<3.0.0>. + +=item $config{full_version} + +The fully loaded version number, a string composed from $config{version}, +$config{prerelease} and $config{build_metadata}. See See L for +a few examples. + +=back + +=head1 EXAMPLES + +=over 4 + +=item 1. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=dev + BUILD_METADATA= + +The fully loaded version number ($config{full_version}) will be +C<3.0.0-dev>. + +=item 2. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG= + BUILD_METADATA=something + +The fully loaded version number ($config{full_version}) will be +C<3.0.0+something>. + +=item 3. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=alpha3 + BUILD_METADATA=something + +The fully loaded version number ($config{full_version}) will be +C<3.0.0-alpha3+something>. + +=back + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2019 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 +L. + +=cut diff --git a/doc/internal/man7/build.info.pod b/doc/internal/man7/build.info.pod index 742f78ce..2be709f7 100644 --- a/doc/internal/man7/build.info.pod +++ b/doc/internal/man7/build.info.pod @@ -73,7 +73,7 @@ generators, and are used to specify exactly what end product files (programs, libraries, modules or scripts) are to be produced, and from what sources. -Intermediate files, such as object files, are seldom refered to at +Intermediate files, such as object files, are seldom referred to at all. They sometimes can be, if there's a need, but this should happen very rarely, and support for that sort of thing is added on as-needed basis. @@ -534,7 +534,7 @@ dependency is maintained: DEPEND[libfoo.a]{weak}=libfoo.a libcookie.a -This is useful in complex dependecy trees where two libraries can be +This is useful in complex dependency trees where two libraries can be used as alternatives for each other. In this example, C and C have alternative implementations of the same thing, and C has unresolved references to that same thing, and is diff --git a/doc/man1/build.info b/doc/man1/build.info new file mode 100644 index 00000000..aed1f948 --- /dev/null +++ b/doc/man1/build.info @@ -0,0 +1,84 @@ + +DEPEND[]= \ + openssl-ca.pod \ + openssl-cms.pod \ + openssl-crl.pod \ + openssl-dgst.pod \ + openssl-dhparam.pod \ + openssl-dsaparam.pod \ + openssl-ecparam.pod \ + openssl-enc.pod \ + openssl-gendsa.pod \ + openssl-genrsa.pod \ + openssl-ocsp.pod \ + openssl-passwd.pod \ + openssl-pkcs12.pod \ + openssl-pkcs8.pod \ + openssl-pkeyutl.pod \ + openssl-rand.pod \ + openssl-req.pod \ + openssl-rsautl.pod \ + openssl-s_client.pod \ + openssl-s_server.pod \ + openssl-s_time.pod \ + openssl-smime.pod \ + openssl-speed.pod \ + openssl-srp.pod \ + openssl-ts.pod \ + openssl-verify.pod \ + openssl-x509.pod + +DEPEND[openssl-ca.pod]=../perlvars.pm +GENERATE[openssl-ca.pod]=openssl-ca.pod.in +DEPEND[openssl-cms.pod]=../perlvars.pm +GENERATE[openssl-cms.pod]=openssl-cms.pod.in +DEPEND[openssl-crl.pod]=../perlvars.pm +GENERATE[openssl-crl.pod]=openssl-crl.pod.in +DEPEND[openssl-dgst.pod]=../perlvars.pm +GENERATE[openssl-dgst.pod]=openssl-dgst.pod.in +DEPEND[openssl-dhparam.pod]=../perlvars.pm +GENERATE[openssl-dhparam.pod]=openssl-dhparam.pod.in +DEPEND[openssl-dsaparam.pod]=../perlvars.pm +GENERATE[openssl-dsaparam.pod]=openssl-dsaparam.pod.in +DEPEND[openssl-ecparam.pod]=../perlvars.pm +GENERATE[openssl-ecparam.pod]=openssl-ecparam.pod.in +DEPEND[openssl-enc.pod]=../perlvars.pm +GENERATE[openssl-enc.pod]=openssl-enc.pod.in +DEPEND[openssl-gendsa.pod]=../perlvars.pm +GENERATE[openssl-gendsa.pod]=openssl-gendsa.pod.in +DEPEND[openssl-genrsa.pod]=../perlvars.pm +GENERATE[openssl-genrsa.pod]=openssl-genrsa.pod.in +DEPEND[openssl-ocsp.pod]=../perlvars.pm +GENERATE[openssl-ocsp.pod]=openssl-ocsp.pod.in +DEPEND[openssl-passwd.pod]=../perlvars.pm +GENERATE[openssl-passwd.pod]=openssl-passwd.pod.in +DEPEND[openssl-pkcs8.pod]=../perlvars.pm +GENERATE[openssl-pkcs8.pod]=openssl-pkcs8.pod.in +DEPEND[openssl-pkcs12.pod]=../perlvars.pm +GENERATE[openssl-pkcs12.pod]=openssl-pkcs12.pod.in +DEPEND[openssl-pkeyutl.pod]=../perlvars.pm +GENERATE[openssl-pkeyutl.pod]=openssl-pkeyutl.pod.in +DEPEND[openssl-rand.pod]=../perlvars.pm +GENERATE[openssl-rand.pod]=openssl-rand.pod.in +DEPEND[openssl-req.pod]=../perlvars.pm +GENERATE[openssl-req.pod]=openssl-req.pod.in +DEPEND[openssl-rsautl.pod]=../perlvars.pm +GENERATE[openssl-rsautl.pod]=openssl-rsautl.pod.in +DEPEND[openssl-s_client.pod]=../perlvars.pm +GENERATE[openssl-s_client.pod]=openssl-s_client.pod.in +DEPEND[openssl-s_server.pod]=../perlvars.pm +GENERATE[openssl-s_server.pod]=openssl-s_server.pod.in +DEPEND[openssl-s_time.pod]=../perlvars.pm +GENERATE[openssl-s_time.pod]=openssl-s_time.pod.in +DEPEND[openssl-smime.pod]=../perlvars.pm +GENERATE[openssl-smime.pod]=openssl-smime.pod.in +DEPEND[openssl-speed.pod]=../perlvars.pm +GENERATE[openssl-speed.pod]=openssl-speed.pod.in +DEPEND[openssl-srp.pod]=../perlvars.pm +GENERATE[openssl-srp.pod]=openssl-srp.pod.in +DEPEND[openssl-ts.pod]=../perlvars.pm +GENERATE[openssl-ts.pod]=openssl-ts.pod.in +DEPEND[openssl-verify.pod]=../perlvars.pm +GENERATE[openssl-verify.pod]=openssl-verify.pod.in +DEPEND[openssl-x509.pod]=../perlvars.pm +GENERATE[openssl-x509.pod]=openssl-x509.pod.in diff --git a/doc/man1/openssl-asn1parse.pod b/doc/man1/openssl-asn1parse.pod index 5e755596..698ce478 100644 --- a/doc/man1/openssl-asn1parse.pod +++ b/doc/man1/openssl-asn1parse.pod @@ -39,8 +39,8 @@ Print out a usage message. =item B<-inform> B|B -The input format. B is binary format and B (the default) is base64 -encoded. +The input format; the default is B. +See L for details. =item B<-in> I diff --git a/doc/man1/openssl-ca.pod b/doc/man1/openssl-ca.pod.in similarity index 96% rename from doc/man1/openssl-ca.pod rename to doc/man1/openssl-ca.pod.in index 5ff5fd95..44e581e0 100644 --- a/doc/man1/openssl-ca.pod +++ b/doc/man1/openssl-ca.pod.in @@ -1,4 +1,5 @@ =pod +{- OpenSSL::safe::output_do_not_edit_headers(); -} =head1 NAME @@ -47,17 +48,17 @@ B B [B<-msie_hack>] [B<-extensions> I

] [B<-extfile> I
] -[B<-engine> I] [B<-subj> I] [B<-utf8>] [B<-sigopt> I:I] [B<-create_serial>] [B<-rand_serial>] [B<-multivalue-rdn>] -[B<-rand> I] -[B<-writerand> I] [B<-sm2-id> I] [B<-sm2-hex-id> I] +{- $OpenSSL::safe::opt_r_synopsis -} +{- $OpenSSL::safe::opt_engine_synopsis -} +[I...] =for openssl ifdef engine sm2-id sm2-hex-id @@ -65,8 +66,11 @@ B B This command is a minimal CA application. It can be used to sign certificate requests in a variety of forms and generate -CRLs it also maintains a text database of issued certificates +CRLs. It also maintains a text database of issued certificates and their status. +When signing certificates, a single certificate request can be specified +with the B<-in> option, or multiple requests can be processed by +specifying a set of B files after all options. The options descriptions will be divided into each purpose. @@ -135,8 +139,8 @@ The private key to sign requests with. =item B<-keyform> B|B -The format of the data in the private key file. -The default is PEM. +The format of the private key file; the default is B. +See L for details. =item B<-sigopt> I:I @@ -249,13 +253,6 @@ An additional configuration file to read certificate extensions from (using the default section unless the B<-extensions> option is also used). -=item B<-engine> I - -Specifying an engine (by its unique I string) will cause B -to attempt to obtain a functional reference to the specified engine, -thus initialising it if needed. The engine will then be set as the default -for all available algorithms. - =item B<-subj> I Supersedes subject name given in the request. @@ -294,10 +291,6 @@ C If B<-multi-rdn> is not used then the UID value is C<123456+CN=John Doe>. -=item B<-rand> I, B<-writerand> I - -See L for more information. - =item B<-sm2-id> I Specify the ID string to use when verifying an SM2 certificate. The ID string is @@ -308,6 +301,10 @@ required by the SM2 signature algorithm for signing and verification. Specify a binary ID string to use when signing or verifying using an SM2 certificate. The argument for this option is string of hexadecimal digits. +{- $OpenSSL::safe::opt_r_item -} + +{- $OpenSSL::safe::opt_engine_item -} + =back =head1 CRL OPTIONS @@ -440,7 +437,8 @@ CA private key. Mandatory. =item B At startup the specified file is loaded into the random number generator, -and at exit 256 bytes will be written to it. +and at exit 256 bytes will be written to it. (Note: Using a RANDFILE is +not necessary anymore, see the L section. =item B @@ -648,7 +646,6 @@ A sample configuration file with the relevant sections for this command: serial = $dir/serial # serial no file #rand_serial = yes # for random serial#'s private_key = $dir/private/cakey.pem# CA private key - RANDFILE = $dir/private/.rand # random number file default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL @@ -684,7 +681,6 @@ The values below reflect the default values. ./demoCA/index.txt - CA text database file ./demoCA/index.txt.old - CA text database backup file ./demoCA/certs - certificate output file - ./demoCA/.rnd - CA random seed information =head1 RESTRICTIONS @@ -761,6 +757,11 @@ B<-enddate> and B<-days>) will be encoded as UTCTime if the dates are earlier than year 2049 (included), and as GeneralizedTime if the dates are in year 2050 or later. +OpenSSL 1.1.1 introduced a new random generator (CSPRNG) with an improved +seeding mechanism. The new seeding mechanism makes it unnecessary to +define a RANDFILE for saving and restoring randomness. This option is +retained mainly for compatibility reasons. + =head1 SEE ALSO L, diff --git a/doc/man1/openssl-ciphers.pod b/doc/man1/openssl-ciphers.pod index 3c66e92c..fcda3998 100644 --- a/doc/man1/openssl-ciphers.pod +++ b/doc/man1/openssl-ciphers.pod @@ -149,7 +149,7 @@ cipher list in order of encryption algorithm key length. The cipher string B<@SECLEVEL>=I can be used at any point to set the security level to I, which should be a number between zero and five, inclusive. -See L for a description of what each level means. +See L for a description of what each level means. The cipher list can be prefixed with the B keyword, which enables the default cipher list as defined below. Unlike cipher strings, diff --git a/doc/man1/openssl-ciphers.pod.orig b/doc/man1/openssl-ciphers.pod.orig index ed8e1a95..8ba80ba1 100644 --- a/doc/man1/openssl-ciphers.pod.orig +++ b/doc/man1/openssl-ciphers.pod.orig @@ -149,7 +149,7 @@ cipher list in order of encryption algorithm key length. The cipher string B<@SECLEVEL>=I can be used at any point to set the security level to I, which should be a number between zero and five, inclusive. -See L for a description of what each level means. +See L for a description of what each level means. The cipher list can be prefixed with the B keyword, which enables the default cipher list as defined below. Unlike cipher strings, diff --git a/doc/man1/openssl-cmds.pod b/doc/man1/openssl-cmds.pod index 9f7d6c65..8a649ca3 100644 --- a/doc/man1/openssl-cmds.pod +++ b/doc/man1/openssl-cmds.pod @@ -2,6 +2,8 @@ =head1 NAME +=for openssl names: openssl-cmds + asn1parse, ca, ciphers, @@ -53,6 +55,8 @@ version, x509 - OpenSSL application commands +=for comment foreign manuals: apropos(1) + =head1 SYNOPSIS =for openssl generic diff --git a/doc/man1/openssl-cms.pod b/doc/man1/openssl-cms.pod.in similarity index 95% rename from doc/man1/openssl-cms.pod rename to doc/man1/openssl-cms.pod.in index 54620fef..56fe42c7 100644 --- a/doc/man1/openssl-cms.pod +++ b/doc/man1/openssl-cms.pod.in @@ -1,4 +1,5 @@ =pod +{- OpenSSL::safe::output_do_not_edit_headers(); -} =head1 NAME @@ -25,10 +26,11 @@ B B [B<-sign_receipt>] [B<-verify_receipt> I] [B<-in> I] -[B<-inform> B|B|B] -[B<-rctform> B|B|B] [B<-out> I] +[B<-inform> B|B|B] [B<-outform> B|B|B] +[B<-rctform> B|B|B] +[B<-keyform> B|B|B] [B<-stream>] [B<-indef>] [B<-noindef>] @@ -37,10 +39,6 @@ B B [B<-text>] [B<-noout>] [B<-print>] -[B<-CAfile> I] -[B<-CApath> I] -[B<-no-CAfile>] -[B<-no-CApath>] [B<-attime> I] [B<-check_ss_sig>] [B<-crl_check>] @@ -96,11 +94,11 @@ B B [B<-inkey> I] [B<-keyopt> I:I] [B<-passin> I] -[B<-rand> I] -[B<-writerand> I] [B<-to> I] [B<-from> I] [B<-subject> I] +{- $OpenSSL::safe::opt_trust_synopsis -} +{- $OpenSSL::safe::opt_r_synopsis -} [I ...] =for openssl ifdef des-wrap engine @@ -216,33 +214,33 @@ to the B<-verify> operation. The input message to be encrypted or signed or the message to be decrypted or verified. -=item B<-inform> B|B|B - -This specifies the input format for the CMS structure. The default -is B which reads an S/MIME format message. B and B -format change this to expect PEM and DER format CMS structures -instead. This currently only affects the input format of the CMS -structure, if no CMS structure is being input (for example with -B<-encrypt> or B<-sign>) this option has no effect. - -=item B<-rctform> B|B|B - -Specify the format for a signed receipt for use with the B<-receipt_verify> -operation. - =item B<-out> I The message text that has been decrypted or verified or the output MIME format message that has been signed or verified. +=item B<-inform> B|B|B + +The input format of the CMS structure (if one is being read); +the default is B. +See L for details. + =item B<-outform> B|B|B -This specifies the output format for the CMS structure. The default -is B which writes an S/MIME format message. B and B -format change this to write PEM and DER format CMS structures -instead. This currently only affects the output format of the CMS -structure, if no CMS structure is being output (for example with -B<-verify> or B<-decrypt>) this option has no effect. +The output format of the CMS structure (if one is being written); +the default is B. +See L for details. + +=item B<-keyform> B|B|B + +The format of the private key file; the default is B. +See L for details. + +=item B<-rctform> B|B|B + +The signed receipt format for use with the B<-receipt_verify>; the default +is B. +See L for details. =item B<-stream>, B<-indef>, B<-noindef> @@ -285,10 +283,6 @@ structure is being checked. For the B<-cmsout> operation print out all fields of the CMS structure. This is mainly useful for testing purposes. -=item B<-CAfile> I, B<-no-CAfile>, B<-CApath> I, B<-no-CApath> - -See L for more information. - =item B<-md> I Digest algorithm to use when signing or resigning. If not present then the @@ -461,15 +455,6 @@ or to modify default parameters for ECDH. The private key password source. For more information about the format of B see L. -=item B<-rand> I, B<-writerand> I - -See L for more information. - -=item I ... - -One or more certificates of message recipients: used when encrypting -a message. - =item B<-to>, B<-from>, B<-subject> The relevant mail headers. These are included outside the signed @@ -488,6 +473,15 @@ B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set various certificate chain validation options. See the L manual page for details. +{- $OpenSSL::safe::opt_trust_item -} + +{- $OpenSSL::safe::opt_r_item -} + +=item I ... + +One or more certificates of message recipients: used when encrypting +a message. + =back =head1 NOTES @@ -738,6 +732,10 @@ the list of permitted ciphers in a database and only use those. No revocation checking is done on the signer's certificate. +=head1 SEE ALSO + +L + =head1 HISTORY The use of multiple B<-signer> options and the B<-resign> command were first diff --git a/doc/man1/openssl-crl.pod b/doc/man1/openssl-crl.pod.in similarity index 68% rename from doc/man1/openssl-crl.pod rename to doc/man1/openssl-crl.pod.in index 9e5f6ca7..680a11d0 100644 --- a/doc/man1/openssl-crl.pod +++ b/doc/man1/openssl-crl.pod.in @@ -1,4 +1,5 @@ =pod +{- OpenSSL::safe::output_do_not_edit_headers(); -} =head1 NAME @@ -10,19 +11,17 @@ B B [B<-help>] [B<-inform> B|B] [B<-outform> B|B] +[B<-keyform> B|B|B] [B<-text>] [B<-in> I] [B<-out> I] -[B<-nameopt> I