diff --git a/CHANGES b/CHANGES index c44dc0fd..c32f768f 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,143 @@ Changes between 1.1.1 and 3.0.0 [xx XXX xxxx] + *) Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just + the first value. + [Jon Spillett] + + *) Deprecated the public definition of ERR_STATE as well as the function + ERR_get_state(). This is done in preparation of making ERR_STATE an + opaque type. + [Richard Levitte] + + *) Added ERR functionality to give callers access to the stored function + names that have replaced the older function code based functions. + + New functions are ERR_get_error_func(), ERR_peek_error_func(), + ERR_peek_last_error_func(), ERR_get_error_data(), ERR_peek_error_data(), + ERR_peek_last_error_data(), ERR_get_error_all(), ERR_peek_error_all() + and ERR_peek_last_error_all(). + + These functions have become deprecated: ERR_get_error_line_data(), + ERR_peek_error_line_data(), ERR_peek_last_error_line_data() and + ERR_func_error_string(). + [Richard Levitte] + + *) Extended testing to be verbose for failing tests only. The make variables + VERBOSE_FAILURE or VF can be used to enable this: + + $ make VF=1 test # Unix + $ mms /macro=(VF=1) test ! OpenVMS + $ nmake VF=1 test # Windows + + [Richard Levitte] + + *) For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters, when loading a serialized key + or calling `EC_GROUP_new_from_ecpkparameters()`/ + `EC_GROUP_new_from_ecparameters()`. + This prevents bypass of security hardening and performance gains, + especially for curves with specialized EC_METHODs. + By default, if a key encoded with explicit parameters is loaded and later + serialized, the output is still encoded with explicit parameters, even if + internally a "named" EC_GROUP is used for computation. + [Nicola Tuveri] + + *) Compute ECC cofactors if not provided during EC_GROUP construction. Before + this change, EC_GROUP_set_generator would accept order and/or cofactor as + NULL. After this change, only the cofactor parameter can be NULL. It also + does some minimal sanity checks on the passed order. + (CVE-2019-1547) + [Billy Bob Brumley] + + *) Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey. + An attack is simple, if the first CMS_recipientInfo is valid but the + second CMS_recipientInfo is chosen ciphertext. If the second + recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct + encryption key will be replaced by garbage, and the message cannot be + decoded, but if the RSA decryption fails, the correct encryption key is + used and the recipient will not notice the attack. + As a work around for this potential attack the length of the decrypted + key must be equal to the cipher default key length, in case the + certifiate is not given and all recipientInfo are tried out. + The old behaviour can be re-enabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag. + [Bernd Edlinger] + + *) Early start up entropy quality from the DEVRANDOM seed source has been + improved for older Linux systems. The RAND subsystem will wait for + /dev/random to be producing output before seeding from /dev/urandom. + The seeded state is stored for future library initialisations using + a system global shared memory segment. The shared memory identifier + can be configured by defining OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID to + the desired value. The default identifier is 114. + [Paul Dale] + + *) Revised BN_generate_prime_ex to not avoid factors 2..17863 in p-1 + when primes for RSA keys are computed. + Since we previously always generated primes == 2 (mod 3) for RSA keys, + the 2-prime and 3-prime RSA modules were easy to distinguish, since + N = p*q = 1 (mod 3), but N = p*q*r = 2 (mod 3). Therefore fingerprinting + 2-prime vs. 3-prime RSA keys was possible by computing N mod 3. + This avoids possible fingerprinting of newly generated RSA modules. + [Bernd Edlinger] + + *) Correct the extended master secret constant on EBCDIC systems. Without this + fix TLS connections between an EBCDIC system and a non-EBCDIC system that + negotiate EMS will fail. Unfortunately this also means that TLS connections + between EBCDIC systems with this fix, and EBCDIC systems without this + fix will fail if they negotiate EMS. + [Matt Caswell] + + *) Changed the library initialisation so that the config file is now loaded + by default. This was already the case for libssl. It now occurs for both + libcrypto and libssl. Use the OPENSSL_INIT_NO_LOAD_CONFIG option to + OPENSSL_init_crypto() to suppress automatic loading of a config file. + [Matt Caswell] + + *) Introduced new error raising macros, ERR_raise() and ERR_raise_data(), + where the former acts as a replacement for ERR_put_error(), and the + latter replaces the combination ERR_put_error()+ERR_add_error_data(). + ERR_raise_data() adds more flexibility by taking a format string and + an arbitrary number of arguments following it, to be processed with + BIO_snprintf(). + [Richard Levitte] + + *) Introduced a new function, OSSL_PROVIDER_available(), which can be used + to check if a named provider is loaded and available. When called, it + will also activate all fallback providers if such are still present. + [Richard Levitte] + + *) Enforce a minimum DH modulus size of 512 bits. + [Bernd Edlinger] + + *) Changed DH parameters to generate the order q subgroup instead of 2q. + Previously generated DH parameters are still accepted by DH_check + but DH_generate_key works around that by clearing bit 0 of the + private key for those. This avoids leaking bit 0 of the private key. + [Bernd Edlinger] + + *) Significantly reduce secure memory usage by the randomness pools. + [Paul Dale] + + *) {CRYPTO,OPENSSL}_mem_debug_{push,pop} are now no-ops and have been + deprecated. + [Rich Salz] + + *) A new type, EVP_KEYEXCH, has been introduced to represent key exchange + algorithms. An implementation of a key exchange algorithm can be obtained + by using the function EVP_KEYEXCH_fetch(). An EVP_KEYEXCH algorithm can be + used in a call to EVP_PKEY_derive_init_ex() which works in a similar way to + the older EVP_PKEY_derive_init() function. See the man pages for the new + functions for further details. + [Matt Caswell] + + *) The EVP_PKEY_CTX_set_dh_pad() macro has now been converted to a function. + [Matt Caswell] + + *) Removed the function names from error messages and deprecated the + xxx_F_xxx define's. + *) Removed NextStep support and the macro OPENSSL_UNISTD [Rich Salz] diff --git a/Configurations/50-win-onecore.conf b/Configurations/50-win-onecore.conf index d4e6e64f..1e5d970b 100644 --- a/Configurations/50-win-onecore.conf +++ b/Configurations/50-win-onecore.conf @@ -1,3 +1,4 @@ +## -*- mode: perl; -*- # Windows OneCore targets. # # OneCore is new API stability "contract" that transcends Desktop, IoT and @@ -10,6 +11,25 @@ # TODO: extend error handling to use ETW based eventing # (Or rework whole error messaging) +my $UWP_info = {}; +sub UWP_info { + unless (%$UWP_info) { + my $SDKver = `powershell -Command \"& {\$(Get-Item \\\"hklm:\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\\").GetValue(\\\"CurrentVersion\\\")}\"`; + $SDKver =~ s|\R$||; + my @SDKver_split = split(/\./, $SDKver); + # SDK version older than 10.0.17763 don't support our ASM builds + if ($SDKver_split[0] < 10 + || ($SDKver_split[0] == 10 + && $SDKver_split[1] == 0 + && $SDKver_split[2] < 17763)) { + $UWP_info->{disable} = [ 'asm' ]; + } else { + $UWP_info->{disable} = [ ]; + } + } + return $UWP_info; +} + my %targets = ( "VC-WIN32-ONECORE" => { inherit_from => [ "VC-WIN32" ], @@ -80,7 +100,8 @@ my %targets = ( defines => add("WINAPI_FAMILY=WINAPI_FAMILY_APP", "_WIN32_WINNT=0x0A00"), dso_scheme => "", - disable => [ 'ui-console', 'stdio', 'async', 'uplink' ], + disable => sub { [ 'ui-console', 'stdio', 'async', 'uplink', + @{ UWP_info()->{disable} } ] }, ex_libs => "WindowsApp.lib", }, "VC-WIN64A-UWP" => { @@ -89,7 +110,8 @@ my %targets = ( defines => add("WINAPI_FAMILY=WINAPI_FAMILY_APP", "_WIN32_WINNT=0x0A00"), dso_scheme => "", - disable => [ 'ui-console', 'stdio', 'async', 'uplink' ], + disable => sub { [ 'ui-console', 'stdio', 'async', 'uplink', + @{ UWP_info()->{disable} } ] }, ex_libs => "WindowsApp.lib", }, "VC-WIN32-ARM-UWP" => { @@ -98,7 +120,8 @@ my %targets = ( defines => add("WINAPI_FAMILY=WINAPI_FAMILY_APP", "_WIN32_WINNT=0x0A00"), dso_scheme => "", - disable => [ 'ui-console', 'stdio', 'async', 'uplink' ], + disable => sub { [ 'ui-console', 'stdio', 'async', 'uplink', + @{ UWP_info()->{disable} } ] }, ex_libs => "WindowsApp.lib", }, "VC-WIN64-ARM-UWP" => { @@ -107,7 +130,8 @@ my %targets = ( defines => add("WINAPI_FAMILY=WINAPI_FAMILY_APP", "_WIN32_WINNT=0x0A00"), dso_scheme => "", - disable => [ 'ui-console', 'stdio', 'async', 'uplink' ], + disable => sub { [ 'ui-console', 'stdio', 'async', 'uplink', + @{ UWP_info()->{disable} } ] }, ex_libs => "WindowsApp.lib", }, ); diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl index 46f2302f..892102dd 100644 --- a/Configurations/descrip.mms.tmpl +++ b/Configurations/descrip.mms.tmpl @@ -114,6 +114,7 @@ BLDDIR={- $config{builddir} -} # Allow both V and VERBOSE to indicate verbosity. This only applies # to testing. VERBOSE=$(V) +VERBOSE_FAILURE=$(VF) VERSION={- "$config{full_version}" -} MAJOR={- $config{major} -} @@ -435,10 +436,12 @@ test : tests DEFINE BLDTOP {- builddir() -} 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 DEASSIGN SRCTOP @@ -784,15 +787,6 @@ $target : $args{generator}->[0] $deps EOF } } else { - my $target = platform->asm($args{src}); - if ($args{generator}->[0] =~ /\.pl$/) { - $generator = '$(PERL)'.$generator_incs.' '.$generator; - } elsif ($args{generator}->[0] =~ /\.S$/) { - $generator = undef; - } else { - die "Generator type for $src unknown: $generator\n"; - } - my $cppflags = { shlib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', lib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', @@ -809,6 +803,17 @@ EOF my $incs_on = join("\n\t\@ ", @{$incs_cmds[0]}) || '!'; my $incs_off = join("\n\t\@ ", @{$incs_cmds[1]}) || '!'; my $defs = join("", map { ",".$_ } @{$args{defs}}); + my $target = platform->asm($args{src}); + + if ($args{generator}->[0] =~ /\.pl$/) { + $generator = '$(PERL)'.$generator_incs.' '.$generator + .' '.$cppflags; + } elsif ($args{generator}->[0] =~ /\.S$/) { + $generator = undef; + } else { + die "Generator type for $src unknown: $generator\n"; + } + if (defined($generator)) { # If the target is named foo.S in build.info, we want to # end up generating foo.s in two steps. @@ -829,7 +834,11 @@ EOF # Otherwise.... return <<"EOF"; $target : $args{generator}->[0] $deps + \@ $incs_on + \@ extradefines = "$defs" $generator \$\@ + \@ DELETE/SYMBOL/LOCAL extradefines + \@ $incs_off EOF } return <<"EOF"; diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 52eeaa9a..1267a2a9 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -352,6 +352,7 @@ test: tests PERL="$(PERL)" \ 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) ) @ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} @@ -391,13 +392,13 @@ libclean: clean: libclean $(RM) $(PROGRAMS) $(TESTPROGS) $(MODULES) $(SCRIPTS) $(RM) $(GENERATED_MANDATORY) $(GENERATED) - -$(RM) `find . -name .git -prune -o -name '*{- platform->depext() -}' -print` - -$(RM) `find . -name .git -prune -o -name '*{- platform->objext() -}' -print` + -$(RM) `find . -name '*{- platform->depext() -}' \! -name '.*' -print` + -$(RM) `find . -name '*{- platform->objext() -}' \! -name '.*' -print` $(RM) core $(RM) tags TAGS doc-nits $(RM) -r test/test-runs $(RM) openssl.pc libcrypto.pc libssl.pc - -$(RM) `find . -name .git -prune -o -type l -print` + -$(RM) `find . -type l \! -name '.*' -print` $(RM) $(TARFILE) distclean: clean @@ -728,9 +729,7 @@ generate: generate_apps generate_crypto_bn generate_crypto_objects \ .PHONY: doc-nits doc-nits: build_generated - (cd $(SRCDIR); $(PERL) util/find-doc-nits -n -p -s ) >doc-nits - @if [ -s doc-nits ] ; then cat doc-nits ; exit 1; \ - else echo 'doc-nits: no errors.'; rm doc-nits ; fi + (cd $(SRCDIR); $(PERL) util/find-doc-nits -n -p -s ) # Test coverage is a good idea for the future #coverage: $(PROGRAMS) $(TESTPROGRAMS) @@ -742,6 +741,12 @@ lint: generate_apps: ( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \ < apps/openssl.cnf > apps/openssl-vms.cnf ) + @ : {- output_off() if $disabled{apps}; "" -} + ( b=`pwd`; cd $(SRCDIR); \ + $(PERL) -I$$b apps/progs.pl -H $(APPS_OPENSSL) > apps/progs.h ) + ( b=`pwd`; cd $(SRCDIR); \ + $(PERL) -I$$b apps/progs.pl -C $(APPS_OPENSSL) > apps/progs.c ) + @ : {- output_on() if $disabled{apps}; "" -} generate_crypto_bn: ( cd $(SRCDIR); $(PERL) crypto/bn/bn_prime.pl > crypto/bn/bn_prime.h ) @@ -973,8 +978,16 @@ $args{src}: $args{generator}->[0] $deps EOF } } else { + my $cppflags = { + shlib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', + lib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', + dso => '$(DSO_CFLAGS) $(DSO_CPPFLAGS)', + bin => '$(BIN_CFLAGS) $(BIN_CPPFLAGS)' + } -> {$args{intent}}; + if ($args{generator}->[0] =~ /\.pl$/) { - $generator = 'CC="$(CC)" $(PERL)'.$generator_incs.' '.$generator; + $generator = 'CC="$(CC)" $(PERL)'.$generator_incs.' '.$generator + .' "$(PERLASM_SCHEME)"'.$incs.' '.$cppflags.$defs.' $(PROCESSSOR)'; } elsif ($args{generator}->[0] =~ /\.m4$/) { $generator = 'm4 -B 8192'.$generator_incs.' '.$generator.' >' } elsif ($args{generator}->[0] =~ /\.S$/) { @@ -983,12 +996,6 @@ EOF die "Generator type for $args{src} unknown: $generator\n"; } - my $cppflags = { - shlib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', - lib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', - dso => '$(DSO_CFLAGS) $(DSO_CPPFLAGS)', - bin => '$(BIN_CFLAGS) $(BIN_CPPFLAGS)' - } -> {$args{intent}}; if (defined($generator)) { return <<"EOF"; $args{src}: $args{generator}->[0] $deps diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl index 3c8d51b6..bfe88f6c 100644 --- a/Configurations/windows-makefile.tmpl +++ b/Configurations/windows-makefile.tmpl @@ -369,6 +369,7 @@ test: tests set RESULT_D=$(BLDDIR)\test\test-runs 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(); } "" -} @@ -569,22 +570,23 @@ $target: "$args{generator}->[0]" $deps EOF } } else { + my $cppflags = { + shlib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', + lib => '$(LIB_CFLAGS) $(LIB_CPPFLAGS)', + dso => '$(DSO_CFLAGS) $(DSO_CPPFLAGS)', + bin => '$(BIN_CFLAGS) $(BIN_CPPFLAGS)' + } -> {$args{intent}}; my $target = platform->asm($args{src}); + if ($args{generator}->[0] =~ /\.pl$/) { - $generator = '"$(PERL)"'.$generator_incs.' '.$generator; + $generator = '"$(PERL)"'.$generator_incs.' '.$generator + .' "$(PERLASM_SCHEME)"'.$incs.' '.$cppflags.$defs.' $(PROCESSSOR)'; } elsif ($args{generator}->[0] =~ /\.S$/) { $generator = undef; } else { die "Generator type for $src unknown: $generator\n"; } - my $cppflags = $incs; - $cppflags .= { - shlib => ' $(LIB_CFLAGS) $(LIB_CPPFLAGS)', - lib => ' $(LIB_CFLAGS) $(LIB_CPPFLAGS)', - dso => ' $(DSO_CFLAGS) $(DSO_CPPFLAGS)', - bin => ' $(BIN_CFLAGS) $(BIN_CPPFLAGS)' - } -> {$args{intent}}; if (defined($generator)) { # If the target is named foo.S in build.info, we want to # end up generating foo.s in two steps. @@ -593,7 +595,7 @@ EOF $target: "$args{generator}->[0]" $deps set ASM=\$(AS) $generator \$@.S - \$(CPP) $cppflags $defs \$@.S > \$@.i && move /Y \$@.i \$@ + \$(CPP) $incs $cppflags $defs \$@.S > \$@.i && move /Y \$@.i \$@ del /Q \$@.S EOF } diff --git a/Configure b/Configure index 30f9e61a..4415e1d6 100755 --- a/Configure +++ b/Configure @@ -17,7 +17,9 @@ use lib "$FindBin::Bin/util/perl"; use File::Basename; use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/; use File::Path qw/mkpath/; +use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt"; use OpenSSL::Glob; +use OpenSSL::Template; # see INSTALL for instructions. @@ -144,13 +146,13 @@ my @gcc_devteam_warn = qw( # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc # -Wextended-offsetof -- no, needed in CMS ASN1 code my @clang_devteam_warn = qw( + -Wno-unknown-warning-option -Wswitch-default -Wno-parentheses-equality -Wno-language-extension-token -Wno-extended-offsetof -Wconditional-uninitialized -Wincompatible-pointer-types-discards-qualifiers - -Wno-unknown-warning-option -Wmissing-variable-declarations ); @@ -348,6 +350,7 @@ my @disablables = ( "dgram", "dh", "dsa", + "dso", "dtls", "dynamic-engine", "ec", @@ -440,7 +443,6 @@ my %deprecated_disablables = ( "hw-padlock" => "padlockeng", "ripemd" => "rmd160", "ui" => "ui-console", - "dso" => undef, "heartbeats" => undef, ); @@ -508,6 +510,7 @@ my @disable_cascades = ( # (note that even with shared libraries, both the app and dynamic engines # must be linked with the same library) "shared" => [ "dynamic-engine", "uplink" ], + "dso" => [ "dynamic-engine", "module" ], # Other modules don't necessarily have to link with libcrypto, so shared # libraries do not have to be a condition to produce those. @@ -1237,7 +1240,7 @@ foreach my $what (sort keys %disabled) { $skipdir{engines} = $what if $what eq 'engine'; $skipdir{"crypto/$skipdir"} = $what - unless $what eq 'async' || $what eq 'err'; + unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; } } @@ -1617,7 +1620,7 @@ my %unified_info = (); my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO}); if ($builder eq "unified") { - use with_fallback qw(Text::Template); + use Text::Template 1.46; sub cleandir { my $base = shift; @@ -1908,7 +1911,7 @@ if ($builder eq "unified") { qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ => sub { push @{$includes{$1}}, tokenize($expand_variables->($2)) if !@skip || $skip[$#skip] > 0 }, - qr/^\s*DEFINE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ + qr/^\s*DEFINE\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ => sub { push @{$defines{$1}}, tokenize($expand_variables->($2)) if !@skip || $skip[$#skip] > 0 }, qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ @@ -2109,24 +2112,33 @@ EOF } } - foreach (keys %defines) { - my $dest = $_; - my $ddest = cleanfile($sourced, $_, $blddir); + foreach my $dest (keys %defines) { + my $ddest; - # If the destination doesn't exist in source, it can only be - # a generated file in the build tree. - if (! -f $ddest) { - $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; + if ($dest ne "") { + $ddest = cleanfile($sourced, $dest, $blddir); + + # If the destination doesn't exist in source, it can only + # be a generated file in the build tree. + if (! -f $ddest) { + $ddest = cleanfile($buildd, $dest, $blddir); + if ($unified_info{rename}->{$ddest}) { + $ddest = $unified_info{rename}->{$ddest}; + } } } - foreach (@{$defines{$dest}}) { - m|^([^=]*)(=.*)?$|; + foreach my $v (@{$defines{$dest}}) { + $v =~ m|^([^=]*)(=.*)?$|; die "0 length macro name not permitted\n" if $1 eq ""; - die "$1 defined more than once\n" - if defined $unified_info{defines}->{$ddest}->{$1}; - $unified_info{defines}->{$ddest}->{$1} = $2; + if ($dest ne "") { + die "$1 defined more than once\n" + if defined $unified_info{defines}->{$ddest}->{$1}; + $unified_info{defines}->{$ddest}->{$1} = $2; + } else { + die "$1 defined more than once\n" + if grep { $v eq $_ } @{$config{defines}}; + push @{$config{defines}}, $v; + } } } } @@ -2377,452 +2389,50 @@ foreach (grep /_(asm|aux)_src$/, keys %target) { # Write down our configuration where it fits ######################### -print "Creating configdata.pm\n"; -open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n"; -print OUT <<"EOF"; -#! $config{HASHBANGPERL} - -package configdata; - -use strict; -use warnings; - -use Exporter; -#use vars qw(\@ISA \@EXPORT); -our \@ISA = qw(Exporter); -our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables \@disablables_int); - -EOF -print OUT "our %config = (\n"; -foreach (sort keys %config) { - if (ref($config{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$config{$_}}), " ],\n"; - } elsif (ref($config{$_}) eq "HASH") { - print OUT " ", $_, " => {"; - if (scalar keys %{$config{$_}} > 0) { - print OUT "\n"; - foreach my $key (sort keys %{$config{$_}}) { - print OUT " ", - join(" => ", - quotify("perl", $key), - defined $config{$_}->{$key} - ? quotify("perl", $config{$_}->{$key}) - : "undef"); - print OUT ",\n"; - } - print OUT " "; - } - print OUT "},\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n" - } -} -print OUT <<"EOF"; +my %template_vars = ( + config => \%config, + target => \%target, + disablables => \@disablables, + disablables_int => \@disablables_int, + disabled => \%disabled, + withargs => \%withargs, + unified_info => \%unified_info, + tls => \@tls, + dtls => \@dtls, + makevars => [ sort keys %user ], + disabled_info => \%disabled_info, + user_crossable => \@user_crossable, ); - -EOF -print OUT "our %target = (\n"; -foreach (sort keys %target) { - if (ref($target{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$target{$_}}), " ],\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n" - } -} -print OUT <<"EOF"; -); - -EOF -print OUT "our \%available_protocols = (\n"; -print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n"; -print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n"; -print OUT <<"EOF"; -); - -EOF -print OUT "our \@disablables = (\n"; -foreach (@disablables) { - print OUT " ", quotify("perl", $_), ",\n"; -} -print OUT <<"EOF"; -); - -EOF -print OUT "# The following come from Configure's @disablables_int\n"; -print OUT "our \@disablables_int = (\n"; -foreach (@disablables_int) { - print OUT " ", quotify("perl", $_), ",\n"; -} -print OUT <<"EOF"; -); - -EOF -print OUT "our \%disabled = (\n"; -foreach (sort keys %disabled) { - print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n"; -} -print OUT <<"EOF"; -); - -EOF -print OUT "our %withargs = (\n"; -foreach (sort keys %withargs) { - if (ref($withargs{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$withargs{$_}}), " ],\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n" - } -} -print OUT <<"EOF"; -); - -EOF -if ($builder eq "unified") { - my $recurse; - $recurse = sub { - my $indent = shift; - foreach (@_) { - if (ref $_ eq "ARRAY") { - print OUT " "x$indent, "[\n"; - foreach (@$_) { - $recurse->($indent + 4, $_); - } - print OUT " "x$indent, "],\n"; - } elsif (ref $_ eq "HASH") { - my %h = %$_; - print OUT " "x$indent, "{\n"; - foreach (sort keys %h) { - if (ref $h{$_} eq "") { - print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n"; - } else { - print OUT " "x($indent + 4), quotify("perl", $_), " =>\n"; - $recurse->($indent + 8, $h{$_}); - } - } - print OUT " "x$indent, "},\n"; - } else { - print OUT " "x$indent, quotify("perl", $_), ",\n"; - } - } - }; - print OUT "our %unified_info = (\n"; - foreach (sort keys %unified_info) { - if (ref $unified_info{$_} eq "") { - print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n"; - } else { - print OUT " "x4, quotify("perl", $_), " =>\n"; - $recurse->(8, $unified_info{$_}); - } - } - print OUT <<"EOF"; -); - -EOF -} -print OUT - "# The following data is only used when this files is use as a script\n"; -print OUT "my \@makevars = (\n"; -foreach (sort keys %user) { - print OUT " '",$_,"',\n"; -} -print OUT ");\n"; -print OUT "my \%disabled_info = (\n"; -foreach my $what (sort keys %disabled_info) { - print OUT " '$what' => {\n"; - foreach my $info (sort keys %{$disabled_info{$what}}) { - if (ref $disabled_info{$what}->{$info} eq 'ARRAY') { - print OUT " $info => [ ", - join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}), - " ],\n"; - } else { - print OUT " $info => '", $disabled_info{$what}->{$info}, - "',\n"; - } - } - print OUT " },\n"; -} -print OUT ");\n"; -print OUT 'my @user_crossable = qw( ', join (' ', @user_crossable), " );\n"; -print OUT << 'EOF'; -# If run directly, we can give some answers, and even reconfigure -unless (caller) { - use Getopt::Long; - use File::Spec::Functions; - use File::Basename; - use Pod::Usage; - - my $here = dirname($0); - - my $dump = undef; - my $cmdline = undef; - my $options = undef; - my $target = undef; - my $envvars = undef; - my $makevars = undef; - my $buildparams = undef; - my $reconf = undef; - my $verbose = undef; - my $help = undef; - my $man = undef; - GetOptions('dump|d' => \$dump, - 'command-line|c' => \$cmdline, - 'options|o' => \$options, - 'target|t' => \$target, - 'environment|e' => \$envvars, - 'make-variables|m' => \$makevars, - 'build-parameters|b' => \$buildparams, - 'reconfigure|reconf|r' => \$reconf, - 'verbose|v' => \$verbose, - 'help' => \$help, - 'man' => \$man) - or die "Errors in command line arguments\n"; - - unless ($dump || $cmdline || $options || $target || $envvars || $makevars - || $buildparams || $reconf || $verbose || $help || $man) { - print STDERR <<"_____"; -You must give at least one option. -For more information, do '$0 --help' -_____ - exit(2); - } - - if ($help) { - pod2usage(-exitval => 0, - -verbose => 1); - } - if ($man) { - pod2usage(-exitval => 0, - -verbose => 2); - } - if ($dump || $cmdline) { - print "\nCommand line (with current working directory = $here):\n\n"; - print ' ',join(' ', - $config{PERL}, - catfile($config{sourcedir}, 'Configure'), - @{$config{perlargv}}), "\n"; - print "\nPerl information:\n\n"; - print ' ',$config{perl_cmd},"\n"; - print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; - } - if ($dump || $options) { - my $longest = 0; - my $longest2 = 0; - foreach my $what (@disablables) { - $longest = length($what) if $longest < length($what); - $longest2 = length($disabled{$what}) - if $disabled{$what} && $longest2 < length($disabled{$what}); - } - print "\nEnabled features:\n\n"; - foreach my $what (@disablables) { - print " $what\n" unless $disabled{$what}; - } - print "\nDisabled features:\n\n"; - foreach my $what (@disablables) { - if ($disabled{$what}) { - print " $what", ' ' x ($longest - length($what) + 1), - "[$disabled{$what}]", ' ' x ($longest2 - length($disabled{$what}) + 1); - print $disabled_info{$what}->{macro} - if $disabled_info{$what}->{macro}; - print ' (skip ', - join(', ', @{$disabled_info{$what}->{skipped}}), - ')' - if $disabled_info{$what}->{skipped}; - print "\n"; - } - } - } - if ($dump || $target) { - print "\nConfig target attributes:\n\n"; - foreach (sort keys %target) { - next if $_ =~ m|^_| || $_ eq 'template'; - my $quotify = sub { - map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; - }; - print ' ', $_, ' => '; - if (ref($target{$_}) eq "ARRAY") { - print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; - } else { - print $quotify->($target{$_}), ",\n" - } - } - } - if ($dump || $envvars) { - print "\nRecorded environment:\n\n"; - foreach (sort keys %{$config{perlenv}}) { - print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; - } - } - if ($dump || $makevars) { - print "\nMakevars:\n\n"; - foreach my $var (@makevars) { - my $prefix = ''; - $prefix = $config{CROSS_COMPILE} - if grep { $var eq $_ } @user_crossable; - $prefix //= ''; - print ' ',$var,' ' x (16 - length $var),'= ', - (ref $config{$var} eq 'ARRAY' - ? join(' ', @{$config{$var}}) - : $prefix.$config{$var}), - "\n" - if defined $config{$var}; - } - - my @buildfile = ($config{builddir}, $config{build_file}); - unshift @buildfile, $here - unless file_name_is_absolute($config{builddir}); - my $buildfile = canonpath(catdir(@buildfile)); - print <<"_____"; - -NOTE: These variables only represent the configuration view. The build file -template may have processed these variables further, please have a look at the -build file for more exact data: - $buildfile -_____ - } - if ($dump || $buildparams) { - my @buildfile = ($config{builddir}, $config{build_file}); - unshift @buildfile, $here - unless file_name_is_absolute($config{builddir}); - print "\nbuild file:\n\n"; - print " ", canonpath(catfile(@buildfile)),"\n"; - - print "\nbuild file templates:\n\n"; - foreach (@{$config{build_file_templates}}) { - my @tmpl = ($_); - unshift @tmpl, $here - unless file_name_is_absolute($config{sourcedir}); - print ' ',canonpath(catfile(@tmpl)),"\n"; - } - } - if ($reconf) { - if ($verbose) { - print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; - foreach (sort keys %{$config{perlenv}}) { - print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; - } - } - - chdir $here; - exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; - } -} - -1; - -__END__ - -=head1 NAME - -configdata.pm - configuration data for OpenSSL builds - -=head1 SYNOPSIS - -Interactive: - - perl configdata.pm [options] - -As data bank module: - - use configdata; - -=head1 DESCRIPTION - -This module can be used in two modes, interactively and as a module containing -all the data recorded by OpenSSL's Configure script. - -When used interactively, simply run it as any perl script, with at least one -option, and you will get the information you ask for. See L below. - -When loaded as a module, you get a few databanks with useful information to -perform build related tasks. The databanks are: - - %config Configured things. - %target The OpenSSL config target with all inheritances - resolved. - %disabled The features that are disabled. - @disablables The list of features that can be disabled. - %withargs All data given through --with-THING options. - %unified_info All information that was computed from the build.info - files. - -=head1 OPTIONS - -=over 4 - -=item B<--help> - -Print a brief help message and exit. - -=item B<--man> - -Print the manual page and exit. - -=item B<--dump> | B<-d> - -Print all relevant configuration data. This is equivalent to B<--command-line> -B<--options> B<--target> B<--environment> B<--make-variables> -B<--build-parameters>. - -=item B<--command-line> | B<-c> - -Print the current configuration command line. - -=item B<--options> | B<-o> - -Print the features, both enabled and disabled, and display defined macro and -skipped directories where applicable. - -=item B<--target> | B<-t> - -Print the config attributes for this config target. - -=item B<--environment> | B<-e> - -Print the environment variables and their values at the time of configuration. - -=item B<--make-variables> | B<-m> - -Print the main make variables generated in the current configuration - -=item B<--build-parameters> | B<-b> - -Print the build parameters, i.e. build file and build file templates. - -=item B<--reconfigure> | B<--reconf> | B<-r> - -Redo the configuration. - -=item B<--verbose> | B<-v> - -Verbose output. - -=back - -=cut - -EOF -close(OUT); +my $configdata_outname = 'configdata.pm'; +print "Creating $configdata_outname\n"; +open CONFIGDATA, ">$configdata_outname.new" + or die "Trying to create $configdata_outname.new: $!"; +my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir); +my $configdata_tmpl = + OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname); +$configdata_tmpl->fill_in( + FILENAME => $configdata_tmplname, + OUTPUT => \*CONFIGDATA, + HASH => { %template_vars, + autowarntext => [ + 'WARNING: do not edit!', + "Generated by Configure from $configdata_tmplname", + ] } +) or die $Text::Template::ERROR; +close CONFIGDATA; +rename "$configdata_outname.new", $configdata_outname; if ($builder_platform eq 'unix') { my $mode = (0755 & ~umask); chmod $mode, 'configdata.pm' or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); } -my %builders = ( - unified => sub { - print 'Creating ',$target{build_file},"\n"; - run_dofile(catfile($blddir, $target{build_file}), - @{$config{build_file_templates}}); - }, - ); - -$builders{$builder}->($builder_platform, @builder_opts); +print "Running $configdata_outname\n"; +my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; +my $cmd = "$perlcmd $configdata_outname"; +#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; +system($cmd); +exit 1 if $? != 0; $SIG{__DIE__} = $orig_death_handler; @@ -3213,24 +2823,6 @@ sub usage exit(1); } -sub run_dofile -{ - my $out = shift; - my @templates = @_; - - unlink $out || warn "Can't remove $out, $!" - if -f $out; - foreach (@templates) { - die "Can't open $_, $!" unless -f $_; - } - my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; - my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\""; - #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; - system($cmd); - exit 1 if $? != 0; - rename("$out.new", $out) || die "Can't rename $out.new, $!"; -} - sub compiler_predefined { state %predefined; my $cc = shift; diff --git a/INSTALL b/INSTALL index 16de9b88..d576548c 100644 --- a/INSTALL +++ b/INSTALL @@ -99,6 +99,9 @@ $ nmake test $ nmake install + Note that in order to perform the install step above you need to have + appropriate permissions to write to the installation directory. + If any of these steps fails, see section Installation in Detail below. This will build and install OpenSSL in the default location, which is: @@ -108,6 +111,12 @@ OpenSSL version number with underscores instead of periods. Windows: C:\Program Files\OpenSSL or C:\Program Files (x86)\OpenSSL + The installation directory should be appropriately protected to ensure + unprivileged users cannot make changes to OpenSSL binaries or files, or install + engines. If you already have a pre-installed version of OpenSSL as part of + your Operating System it is recommended that you do not overwrite the system + version and instead install to somewhere else. + If you want to install it anywhere else, run config like this: On Unix: @@ -136,7 +145,10 @@ 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. + 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). --cross-compile-prefix=PREFIX The PREFIX to include in front of commands for your @@ -230,7 +242,7 @@ source exists. getrandom: Use the L or equivalent system call. - devrandom: Use the the first device from the DEVRANDOM list + devrandom: Use the first device from the DEVRANDOM list which can be opened to read random bytes. The DEVRANDOM preprocessor constant expands to "/dev/urandom","/dev/random","/dev/srandom" on @@ -352,6 +364,9 @@ Don't build support for datagram based BIOs. Selecting this option will also force the disabling of DTLS. + no-dso + Don't build support for loading Dynamic Shared Objects. + enable-devcryptoeng Build the /dev/crypto engine. It is automatically selected on BSD implementations, in which case it can be disabled with @@ -899,11 +914,17 @@ malfunction with Perl). You may want increased verbosity, that can be accomplished like this: - $ make VERBOSE=1 test # Unix + Verbosity on failure only (make macro VERBOSE_FAILURE or VF): - $ mms /macro=(VERBOSE=1) test ! OpenVMS + $ make VF=1 test # Unix + $ mms /macro=(VF=1) test ! OpenVMS + $ nmake VF=1 test # Windows - $ nmake VERBOSE=1 test # Windows + Full verbosity (make macro VERBOSE or V): + + $ make V=1 test # Unix + $ mms /macro=(V=1) test ! OpenVMS + $ nmake V=1 test # Windows If you want to run just one or a few specific tests, you can use the make variable TESTS to specify them, like this: @@ -914,7 +935,7 @@ And of course, you can combine (Unix example shown): - $ make VERBOSE=1 TESTS='test_rsa test_dsa' test + $ make VF=1 TESTS='test_rsa test_dsa' test You can find the list of available tests like this: @@ -941,8 +962,11 @@ $ mms install ! OpenVMS $ nmake install # Windows - This will install all the software components in this directory - tree under PREFIX (the directory given with --prefix or its + Note that in order to perform the install step above you need to have + appropriate permissions to write to the installation directory. + + The above commands will install all the software components in this + directory tree under PREFIX (the directory given with --prefix or its default): Unix: @@ -998,6 +1022,12 @@ for private key files. misc Various scripts. + The installation directory should be appropriately protected to ensure + unprivileged users cannot make changes to OpenSSL binaries or files, or + install engines. If you already have a pre-installed version of OpenSSL as + part of your Operating System it is recommended that you do not overwrite + the system version and instead install to somewhere else. + Package builders who want to configure the library for standard locations, but have the package installed somewhere else so that it can easily be packaged, can use diff --git a/NEWS b/NEWS index aeb2eb74..0463af6e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ Major changes between OpenSSL 1.1.1 and OpenSSL 3.0.0 [under development] + 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. o Added 'openssl mac' that uses the EVP_MAC API. o Added 'openssl kdf' that uses the EVP_KDF API. o Add OPENSSL_info() and 'openssl info' to get built-in data. diff --git a/apps/build.info b/apps/build.info index 3b4ea25d..f49edb4d 100644 --- a/apps/build.info +++ b/apps/build.info @@ -1,3 +1,5 @@ +SUBDIRS=lib + # Program init source, that don't have direct linkage with the rest of the # source, and can therefore not be part of a library. IF[{- !$disabled{uplink} -}] @@ -7,37 +9,18 @@ IF[{- $config{target} =~ /^vms-/ -}] $INITSRC=vms_decc_init.c ENDIF -# Auxilliary program source -IF[{- $config{target} =~ /^(?:VC-|mingw)/ -}] - # It's called 'init', but doesn't have much 'init' in it... - $AUXLIBAPPSSRC=win32_init.c -ENDIF -IF[{- $config{target} =~ /^vms-/ -}] - $AUXLIBAPPSSRC=vms_term_sock.c vms_decc_argv.c -ENDIF - # Source for the 'openssl' program -# We need the perl variable for the DEPEND generator further down. -$OPENSSLSRC={- - our @opensslsrc = - qw(openssl.c - asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c - dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c - genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c - pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c - rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c - spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c - info.c); - join(' ', @opensslsrc); -} -# 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 +$OPENSSLSRC=\ + openssl.c progs.c \ + asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c \ + dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c \ + genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c \ + pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c \ + rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \ + spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c \ + list.c info.c provider.c fipsinstall.c IF[{- !$disabled{apps} -}] - LIBS{noinst}=libapps.a - SOURCE[libapps.a]=$LIBAPPSSRC $AUXLIBAPPSSRC - INCLUDE[libapps.a]=.. ../include include - PROGRAMS=openssl SOURCE[openssl]=$INITSRC $OPENSSLSRC INCLUDE[openssl]=.. ../include include @@ -48,11 +31,6 @@ IF[{- !$disabled{apps} -}] SOURCE[openssl]=openssl.rc ENDIF - {- join("\n ", map { (my $x = $_) =~ s|\.c$|.o|; "DEPEND[$x]=progs.h" } - @opensslsrc) -} - GENERATE[progs.h]=progs.pl $(APPS_OPENSSL) - DEPEND[progs.h]=../configdata.pm - SCRIPTS{misc}=CA.pl SOURCE[CA.pl]=CA.pl.in # linkname tells build files that a symbolic link or copy of this script diff --git a/apps/dgst.c b/apps/dgst.c index 7b433385..b44468bc 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -461,7 +461,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, size_t len; int i, backslash = 0; - for (;;) { + 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); diff --git a/apps/dhparam.c b/apps/dhparam.c index b13a34ad..7cd69b92 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -37,7 +37,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, - OPT_DSAPARAM, OPT_C, OPT_2, OPT_5, + OPT_DSAPARAM, OPT_C, OPT_2, OPT_3, OPT_5, OPT_R_ENUM } OPTION_CHOICE; @@ -55,6 +55,7 @@ const OPTIONS dhparam_options[] = { 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, '-', @@ -125,6 +126,9 @@ int dhparam_main(int argc, char **argv) case OPT_2: g = 2; break; + case OPT_3: + g = 3; + break; case OPT_5: g = 5; break; diff --git a/apps/ecparam.c b/apps/ecparam.c index 0c893a39..6796af65 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -273,7 +273,7 @@ int ecparam_main(int argc, char **argv) if (check_named) { BIO_printf(bio_err, "validating named elliptic curve parameters: "); - if (EC_GROUP_check_named_curve(group, 0) <= 0) { + if (EC_GROUP_check_named_curve(group, 0, NULL) <= 0) { BIO_printf(bio_err, "failed\n"); ERR_print_errors(bio_err); goto end; diff --git a/apps/enc.c b/apps/enc.c index 57ce9243..d2505639 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -586,7 +586,7 @@ int enc_main(int argc, char **argv) if (benc != NULL) wbio = BIO_push(benc, wbio); - for (;;) { + while (BIO_pending(rbio) || !BIO_eof(rbio)) { inl = BIO_read(rbio, (char *)buff, bsize); if (inl <= 0) break; diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c new file mode 100644 index 00000000..78200c58 --- /dev/null +++ b/apps/fipsinstall.c @@ -0,0 +1,420 @@ +/* + * 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 +#include "apps.h" +#include "progs.h" + +#define BUFSIZE 4096 +#define DEFAULT_MAC_NAME "HMAC" +#define DEFAULT_FIPS_SECTION "fips_check_section" + +/* Configuration file values */ +#define VERSION_KEY "version" +#define VERSION_VAL "1" +#define INSTALL_STATUS_VAL "INSTALL_SELF_TEST_KATS_RUN" + +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 +} OPTION_CHOICE; + +const OPTIONS fipsinstall_options[] = { + {"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"}, + {"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)"}, + {"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"}, + {NULL} +}; + +static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in, + unsigned char *out, size_t *out_len) +{ + int ret = 0; + int i; + size_t outsz = *out_len; + + if (!EVP_MAC_init(ctx)) + goto err; + if (EVP_MAC_size(ctx) > outsz) + goto end; + while ((i = BIO_read(in, (char *)tmp, BUFSIZE)) != 0) { + if (i < 0 || !EVP_MAC_update(ctx, tmp, i)) + goto err; + } +end: + if (!EVP_MAC_final(ctx, out, out_len, outsz)) + goto err; + ret = 1; +err: + return ret; +} + +static int load_fips_prov_and_run_self_test(const char *prov_name) +{ + int ret = 0; + OSSL_PROVIDER *prov = NULL; + + prov = OSSL_PROVIDER_load(NULL, prov_name); + if (prov == NULL) { + BIO_printf(bio_err, "Failed to load FIPS module\n"); + goto end; + } + ret = 1; +end: + OSSL_PROVIDER_unload(prov); + return ret; +} + +static int print_mac(BIO *bio, const char *label, const unsigned char *mac, + size_t len) +{ + int ret; + char *hexstr = NULL; + + hexstr = OPENSSL_buf2hexstr(mac, (long)len); + if (hexstr == NULL) + return 0; + ret = BIO_printf(bio, "%s = %s\n", label, hexstr); + OPENSSL_free(hexstr); + return ret; +} + +static int write_config_header(BIO *out, const char *prov_name, + const char *section) +{ + return BIO_printf(out, "openssl_conf = openssl_init\n\n") + && BIO_printf(out, "[openssl_init]\n") + && BIO_printf(out, "providers = provider_section\n\n") + && BIO_printf(out, "[provider_section]\n") + && BIO_printf(out, "%s = %s\n\n", prov_name, section); +} + +/* + * Outputs a fips related config file that contains entries for the fips + * module checksum and the installation indicator checksum. + * + * Returns 1 if the config file is written otherwise it returns 0 on error. + */ +static int write_config_fips_section(BIO *out, const char *section, + unsigned char *module_mac, + size_t module_mac_len, + unsigned char *install_mac, + size_t install_mac_len) +{ + int ret = 0; + + if (!(BIO_printf(out, "[%s]\n", section) > 0 + && BIO_printf(out, "activate = 1\n") > 0 + && BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION, + VERSION_VAL) > 0 + && print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac, + module_mac_len))) + goto end; + + if (install_mac != NULL) { + if (!(print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac, + install_mac_len) + && BIO_printf(out, "%s = %s\n", + OSSL_PROV_FIPS_PARAM_INSTALL_STATUS, + INSTALL_STATUS_VAL) > 0)) + goto end; + } + ret = 1; +end: + return ret; +} + +static CONF *generate_config_and_load(const char *prov_name, + const char *section, + unsigned char *module_mac, + size_t module_mac_len) +{ + BIO *mem_bio = NULL; + CONF *conf = NULL; + + mem_bio = BIO_new(BIO_s_mem()); + if (mem_bio == NULL) + return 0; + if (!write_config_header(mem_bio, prov_name, section) + || !write_config_fips_section(mem_bio, section, module_mac, + module_mac_len, NULL, 0)) + goto end; + + conf = app_load_config_bio(mem_bio, NULL); + if (conf == NULL) + goto end; + + if (!CONF_modules_load(conf, NULL, 0)) + goto end; + BIO_free(mem_bio); + return conf; +end: + NCONF_free(conf); + BIO_free(mem_bio); + return NULL; +} + +static void free_config_and_unload(CONF *conf) +{ + if (conf != NULL) { + NCONF_free(conf); + CONF_modules_unload(1); + } +} + +/* + * Returns 1 if the config file entries match the passed in module_mac and + * install_mac values, otherwise it returns 0. + */ +static int verify_config(const char *infile, const char *section, + unsigned char *module_mac, size_t module_mac_len, + unsigned char *install_mac, size_t install_mac_len) +{ + int ret = 0; + char *s = NULL; + unsigned char *buf1 = NULL, *buf2 = NULL; + long len; + CONF *conf = NULL; + + /* read in the existing values and check they match the saved values */ + conf = app_load_config(infile); + if (conf == NULL) + goto end; + + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_VERSION); + if (s == NULL || strcmp(s, VERSION_VAL) != 0) { + BIO_printf(bio_err, "version not found\n"); + goto end; + } + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS); + if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) { + BIO_printf(bio_err, "install status not found\n"); + goto end; + } + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC); + if (s == NULL) { + BIO_printf(bio_err, "Module integrity MAC not found\n"); + goto end; + } + buf1 = OPENSSL_hexstr2buf(s, &len); + if (buf1 == NULL + || (size_t)len != module_mac_len + || memcmp(module_mac, buf1, module_mac_len) != 0) { + BIO_printf(bio_err, "Module integrity mismatch\n"); + goto end; + } + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC); + if (s == NULL) { + BIO_printf(bio_err, "Install indicator MAC not found\n"); + goto end; + } + buf2 = OPENSSL_hexstr2buf(s, &len); + if (buf2 == NULL + || (size_t)len != install_mac_len + || memcmp(install_mac, buf2, install_mac_len) != 0) { + BIO_printf(bio_err, "Install indicator status mismatch\n"); + goto end; + } + ret = 1; +end: + OPENSSL_free(buf1); + OPENSSL_free(buf2); + NCONF_free(conf); + return ret; +} + +int fipsinstall_main(int argc, char **argv) +{ + int ret = 1, verify = 0; + BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL; + char *in_fname = NULL, *out_fname = NULL, *prog, *section_name = NULL; + char *prov_name = NULL, *module_fname = NULL; + static const char *mac_name = DEFAULT_MAC_NAME; + EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL; + STACK_OF(OPENSSL_STRING) *opts = NULL; + OPTION_CHOICE o; + unsigned char *read_buffer = NULL; + unsigned char module_mac[EVP_MAX_MD_SIZE]; + size_t module_mac_len = EVP_MAX_MD_SIZE; + unsigned char install_mac[EVP_MAX_MD_SIZE]; + size_t install_mac_len = EVP_MAX_MD_SIZE; + EVP_MAC *mac = NULL; + CONF *conf = NULL; + + section_name = DEFAULT_FIPS_SECTION; + + prog = opt_init(argc, argv, fipsinstall_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(fipsinstall_options); + ret = 0; + goto end; + case OPT_IN: + in_fname = opt_arg(); + break; + case OPT_OUT: + out_fname = opt_arg(); + break; + case OPT_PROV_NAME: + prov_name = opt_arg(); + break; + case OPT_MODULE: + module_fname = opt_arg(); + break; + case OPT_SECTION_NAME: + section_name = opt_arg(); + break; + case OPT_MAC_NAME: + mac_name = opt_arg(); + break; + case OPT_MACOPT: + if (opts == NULL) + opts = sk_OPENSSL_STRING_new_null(); + if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) + goto opthelp; + break; + case OPT_VERIFY: + verify = 1; + break; + } + } + argc = opt_num_rest(); + if (module_fname == NULL + || (verify && in_fname == NULL) + || (!verify && (out_fname == NULL || prov_name == NULL)) + || opts == NULL + || argc != 0) + goto opthelp; + + module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY); + if (module_bio == NULL) { + BIO_printf(bio_err, "Failed to open module file\n"); + goto end; + } + + read_buffer = app_malloc(BUFSIZE, "I/O buffer"); + if (read_buffer == NULL) + goto end; + + mac = EVP_MAC_fetch(NULL, mac_name, NULL); + if (mac == NULL) { + BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name); + goto end; + } + + ctx = EVP_MAC_CTX_new(mac); + if (ctx == NULL) { + BIO_printf(bio_err, "Unable to create MAC CTX for module check\n"); + goto end; + } + + if (opts != NULL) { + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_MAC_CTX_settable_params(mac)); + + if (params == NULL) + goto end; + + if (!EVP_MAC_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "MAC parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; + } + app_params_free(params); + if (!ok) + goto end; + } + + ctx2 = EVP_MAC_CTX_dup(ctx); + if (ctx2 == NULL) { + BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n"); + goto end; + } + + if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len)) + goto end; + + mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL, + strlen(INSTALL_STATUS_VAL)); + if (mem_bio == NULL) { + BIO_printf(bio_err, "Unable to create memory BIO\n"); + goto end; + } + if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len)) + goto end; + + if (verify) { + if (!verify_config(in_fname, section_name, module_mac, module_mac_len, + install_mac, install_mac_len)) + goto end; + BIO_printf(bio_out, "VERIFY PASSED\n"); + } else { + + conf = generate_config_and_load(prov_name, section_name, module_mac, + module_mac_len); + if (conf == NULL) + goto end; + if (!load_fips_prov_and_run_self_test(prov_name)) + goto end; + + fout = bio_open_default(out_fname, 'w', FORMAT_TEXT); + if (fout == NULL) { + BIO_printf(bio_err, "Failed to open file\n"); + goto end; + } + if (!write_config_fips_section(fout, section_name, module_mac, + module_mac_len, install_mac, + install_mac_len)) + goto end; + BIO_printf(bio_out, "INSTALL PASSED\n"); + } + + ret = 0; +end: + if (ret == 1) { + BIO_printf(bio_err, "%s FAILED\n", verify ? "VERIFY" : "INSTALL"); + ERR_print_errors(bio_err); + } + + BIO_free(fout); + BIO_free(mem_bio); + BIO_free(module_bio); + sk_OPENSSL_STRING_free(opts); + EVP_MAC_free(mac); + EVP_MAC_CTX_free(ctx2); + EVP_MAC_CTX_free(ctx); + OPENSSL_free(read_buffer); + free_config_and_unload(conf); + return ret; +} diff --git a/apps/include/app_params.h b/apps/include/app_params.h new file mode 100644 index 00000000..2060b520 --- /dev/null +++ b/apps/include/app_params.h @@ -0,0 +1,13 @@ +/* + * 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 + +int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent); + diff --git a/apps/include/apps.h b/apps/include/apps.h index 59e3e928..8b28d749 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -102,11 +102,9 @@ typedef struct args_st { int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); int chopup_args(ARGS *arg, char *buf); -# ifdef HEADER_X509_H int dump_cert_text(BIO *out, X509 *x); void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags); -# endif void print_bignum_var(BIO *, const BIGNUM *, const char*, int, unsigned char *); void print_array(BIO *, const char *, int, const unsigned char *); @@ -266,4 +264,8 @@ typedef struct verify_options_st { extern VERIFY_CB_ARGS verify_args; +OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, + const OSSL_PARAM *paramdefs); +void app_params_free(OSSL_PARAM *params); + #endif diff --git a/apps/include/function.h b/apps/include/function.h new file mode 100644 index 00000000..41259793 --- /dev/null +++ b/apps/include/function.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 + */ + +#ifndef APPS_FUNCTION_H +# define APPS_FUNCTION_H + +# include +# include "opt.h" + +typedef enum FUNC_TYPE { + FT_none, FT_general, FT_md, FT_cipher, FT_pkey, + FT_md_alg, FT_cipher_alg +} FUNC_TYPE; + +typedef struct function_st { + FUNC_TYPE type; + const char *name; + int (*func)(int argc, char *argv[]); + const OPTIONS *help; +} FUNCTION; + +DEFINE_LHASH_OF(FUNCTION); + +/* Structure to hold the number of columns to be displayed and the + * field width used to display them. + */ +typedef struct { + int columns; + int width; +} DISPLAY_COLUMNS; + +void calculate_columns(FUNCTION *functions, DISPLAY_COLUMNS *dc); + +#endif diff --git a/apps/include/opt.h b/apps/include/opt.h index 81faf705..92a7fd1d 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -266,6 +266,7 @@ */ extern const char OPT_HELP_STR[]; extern const char OPT_MORE_STR[]; +extern const char OPT_SECTION_STR[]; typedef struct options_st { const char *name; int retval; @@ -307,6 +308,9 @@ typedef struct string_int_pair_st { OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ 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"} + char *opt_progname(const char *argv0); char *opt_getprog(void); char *opt_init(int ac, char **av, const OPTIONS * o); @@ -338,6 +342,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); 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 d941ccd9..4f976da0 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -9,13 +9,7 @@ #include -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -# include -#endif - -#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) -# define _kbhit kbhit -#endif +#include #define PORT "4433" #define PROTOCOL "tcp" @@ -24,17 +18,15 @@ typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context); int do_server(int *accept_sock, const char *host, const char *port, int family, int type, int protocol, do_server_cb cb, unsigned char *context, int naccept, BIO *bio_s_out); -#ifdef HEADER_X509_H + int verify_callback(int ok, X509_STORE_CTX *ctx); -#endif -#ifdef HEADER_SSL_H + int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, STACK_OF(X509) *chain, int build_chain); int ssl_print_sigalgs(BIO *out, SSL *s); int ssl_print_point_formats(BIO *out, SSL *s); int ssl_print_groups(BIO *out, SSL *s, int noshared); -#endif int ssl_print_tmp_key(BIO *out, SSL *s); int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, @@ -44,13 +36,11 @@ int should_retry(int i); long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret); -#ifdef HEADER_SSL_H void apps_ssl_info_callback(const SSL *s, int where, int ret); void msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); void tlsext_cb(SSL *s, int client_server, int type, const unsigned char *data, int len, void *arg); -#endif int generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len); @@ -75,7 +65,6 @@ int args_excert(int option, SSL_EXCERT **pexc); int load_excert(SSL_EXCERT **pexc); void print_verify_detail(SSL *s, BIO *bio); void print_ssl_summary(SSL *s); -#ifdef HEADER_SSL_H 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); @@ -86,4 +75,3 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose); int set_keylog_file(SSL_CTX *ctx, const char *keylog_file); void print_ca_names(BIO *bio, SSL *s); -#endif diff --git a/apps/vms_term_sock.h b/apps/include/vms_term_sock.h similarity index 100% rename from apps/vms_term_sock.h rename to apps/include/vms_term_sock.h diff --git a/apps/info.c b/apps/info.c index a2c359e0..46561411 100644 --- a/apps/info.c +++ b/apps/info.c @@ -14,7 +14,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_CONFIGDIR, OPT_ENGINESDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP, - OPT_LISTSEP + OPT_LISTSEP, OPT_SEEDS, OPT_CPUSETTINGS } OPTION_CHOICE; const OPTIONS info_options[] = { @@ -30,6 +30,8 @@ const OPTIONS info_options[] = { {"dsoext", OPT_DSOEXT, '-', "Configured extension for modules"}, {"dirnamesep", OPT_DIRNAMESEP, '-', "Directory-filename separator"}, {"listsep", OPT_LISTSEP, '-', "List separator character"}, + {"seeds", OPT_SEEDS, '-', "Seed sources"}, + {"cpusettings", OPT_CPUSETTINGS, '-', "CPU settings info"}, {NULL} }; @@ -74,6 +76,14 @@ opthelp: type = OPENSSL_INFO_LIST_SEPARATOR; dirty++; break; + case OPT_SEEDS: + type = OPENSSL_INFO_SEED_SOURCE; + dirty++; + break; + case OPT_CPUSETTINGS: + type = OPENSSL_INFO_CPU_SETTINGS; + dirty++; + break; } } if (opt_num_rest() != 0) { diff --git a/apps/kdf.c b/apps/kdf.c index 684fd44c..c2304306 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -15,6 +15,7 @@ #include #include #include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -34,27 +35,9 @@ const OPTIONS kdf_options[] = { {NULL} }; -static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value) -{ - int rv; - char *stmp, *vtmp = NULL; - - stmp = OPENSSL_strdup(value); - if (stmp == NULL) - return -1; - vtmp = strchr(stmp, ':'); - if (vtmp != NULL) { - *vtmp = 0; - vtmp++; - } - rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp); - OPENSSL_free(stmp); - return rv; -} - int kdf_main(int argc, char **argv) { - int ret = 1, i, id, out_bin = 0; + int ret = 1, out_bin = 0; OPTION_CHOICE o; STACK_OF(OPENSSL_STRING) *opts = NULL; char *prog, *hexout = NULL; @@ -62,6 +45,7 @@ int kdf_main(int argc, char **argv) unsigned char *dkm_bytes = NULL; size_t dkm_len = 0; BIO *out = NULL; + EVP_KDF *kdf = NULL; EVP_KDF_CTX *ctx = NULL; prog = opt_init(argc, argv, kdf_options); @@ -100,25 +84,31 @@ opthelp: goto opthelp; } - id = OBJ_sn2nid(argv[0]); - if (id == NID_undef) { + if ((kdf = EVP_KDF_fetch(NULL, argv[0], NULL)) == NULL) { BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]); goto opthelp; } - ctx = EVP_KDF_CTX_new_id(id); + ctx = EVP_KDF_CTX_new(kdf); if (ctx == NULL) goto err; if (opts != NULL) { - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (kdf_ctrl_string(ctx, opt) <= 0) { - BIO_printf(bio_err, "KDF parameter error '%s'\n", opt); - ERR_print_errors(bio_err); - goto err; - } + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_KDF_CTX_settable_params(kdf)); + + if (params == NULL) + goto err; + + if (!EVP_KDF_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "KDF parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; } + app_params_free(params); + if (!ok) + goto err; } out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); @@ -151,6 +141,7 @@ err: ERR_print_errors(bio_err); OPENSSL_clear_free(dkm_bytes, dkm_len); sk_OPENSSL_STRING_free(opts); + EVP_KDF_free(kdf); EVP_KDF_CTX_free(ctx); BIO_free(out); OPENSSL_free(hexout); diff --git a/apps/lib/app_params.c b/apps/lib/app_params.c new file mode 100644 index 00000000..ba507079 --- /dev/null +++ b/apps/lib/app_params.c @@ -0,0 +1,96 @@ +/* + * 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 "apps.h" +#include "app_params.h" + +static int describe_param_type(char *buf, size_t bufsz, const OSSL_PARAM *param) +{ + const char *type_mod = ""; + const char *type = NULL; + int show_type_number = 0; + int printed_len; + + switch (param->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + type_mod = "unsigned "; + /* FALLTHRU */ + case OSSL_PARAM_INTEGER: + type = "integer"; + break; + case OSSL_PARAM_UTF8_PTR: + type_mod = "pointer to a "; + /* FALLTHRU */ + case OSSL_PARAM_UTF8_STRING: + type = "UTF8 encoded string"; + break; + case OSSL_PARAM_OCTET_PTR: + type_mod = "pointer to an "; + /* FALLTHRU */ + case OSSL_PARAM_OCTET_STRING: + type = "octet string"; + break; + default: + type = "unknown type"; + show_type_number = 1; + break; + } + + printed_len = BIO_snprintf(buf, bufsz, "%s: ", param->key); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + printed_len = BIO_snprintf(buf, bufsz, "%s%s", type_mod, type); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + if (show_type_number) { + printed_len = BIO_snprintf(buf, bufsz, " [%d]", param->data_type); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + } + if (param->data_size == 0) + printed_len = BIO_snprintf(buf, bufsz, " (arbitrary size)"); + else + printed_len = BIO_snprintf(buf, bufsz, " (max %zu bytes large)", + param->data_size); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + *buf = '\0'; + return 1; +} + +int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent) +{ + if (pdefs == NULL) { + BIO_printf(bio_out, "%*sNo declared %s\n", indent, "", thing); + } else if (pdefs->key == NULL) { + /* + * An empty list? This shouldn't happen, but let's just make sure to + * say something if there's a badly written provider... + */ + BIO_printf(bio_out, "%*sEmpty list of %s (!!!)\n", indent, "", thing); + } else { + BIO_printf(bio_out, "%*s%s:\n", indent, "", thing); + for (; pdefs->key != NULL; pdefs++) { + char buf[200]; /* This should be ample space */ + + describe_param_type(buf, sizeof(buf), pdefs); + BIO_printf(bio_out, "%*s %s\n", indent, "", buf); + } + } + return 1; +} + diff --git a/apps/app_rand.c b/apps/lib/app_rand.c similarity index 100% rename from apps/app_rand.c rename to apps/lib/app_rand.c diff --git a/apps/apps.c b/apps/lib/apps.c similarity index 97% rename from apps/apps.c rename to apps/lib/apps.c index 8921c18c..50388177 100644 --- a/apps/apps.c +++ b/apps/lib/apps.c @@ -40,7 +40,6 @@ #endif #include #include -#include "s_apps.h" #include "apps.h" #ifdef _WIN32 @@ -48,6 +47,14 @@ static int WIN32_rename(const char *from, const char *to); # define rename(from,to) WIN32_rename((from),(to)) #endif +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) +# include +#endif + +#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) +# define _kbhit kbhit +#endif + #define PASS_SOURCE_SIZE_MAX 4 typedef struct { @@ -1388,8 +1395,8 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) #ifndef OPENSSL_NO_POSIX_IO BIO_get_fp(in, &dbfp); if (fstat(fileno(dbfp), &dbst) == -1) { - SYSerr(SYS_F_FSTAT, errno); - ERR_add_error_data(3, "fstat('", dbfile, "')"); + ERR_raise_data(ERR_LIB_SYS, errno, + "calling fstat(%s)", dbfile); ERR_print_errors(bio_err); goto err; } @@ -2559,3 +2566,53 @@ int opt_printf_stderr(const char *fmt, ...) va_end(ap); return ret; } + +OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, + const OSSL_PARAM *paramdefs) +{ + OSSL_PARAM *params = NULL; + size_t sz = (size_t)sk_OPENSSL_STRING_num(opts); + size_t params_n; + char *opt = "", *stmp, *vtmp = NULL; + + if (opts == NULL) + return NULL; + + params = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (sz + 1)); + if (params == NULL) + return NULL; + + for (params_n = 0; params_n < sz; params_n++) { + opt = sk_OPENSSL_STRING_value(opts, (int)params_n); + if ((stmp = OPENSSL_strdup(opt)) == NULL + || (vtmp = strchr(stmp, ':')) == NULL) + goto err; + /* Replace ':' with 0 to terminate the string pointed to by stmp */ + *vtmp = 0; + /* Skip over the separator so that vmtp points to the value */ + vtmp++; + if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], paramdefs, + stmp, vtmp, strlen(vtmp))) + goto err; + OPENSSL_free(stmp); + } + params[params_n] = OSSL_PARAM_construct_end(); + return params; +err: + OPENSSL_free(stmp); + BIO_printf(bio_err, "Parameter error '%s'\n", opt); + ERR_print_errors(bio_err); + app_params_free(params); + return NULL; +} + +void app_params_free(OSSL_PARAM *params) +{ + int i; + + if (params != NULL) { + for (i = 0; params[i].key != NULL; ++i) + OPENSSL_free(params[i].data); + OPENSSL_free(params); + } +} diff --git a/apps/apps_ui.c b/apps/lib/apps_ui.c similarity index 100% rename from apps/apps_ui.c rename to apps/lib/apps_ui.c diff --git a/apps/bf_prefix.c b/apps/lib/bf_prefix.c similarity index 100% rename from apps/bf_prefix.c rename to apps/lib/bf_prefix.c diff --git a/apps/lib/build.info b/apps/lib/build.info new file mode 100644 index 00000000..f92d4daf --- /dev/null +++ b/apps/lib/build.info @@ -0,0 +1,18 @@ +# Auxilliary program source +IF[{- $config{target} =~ /^(?:VC-|mingw)/ -}] + # It's called 'init', but doesn't have much 'init' in it... + $AUXLIBAPPSSRC=win32_init.c +ENDIF +IF[{- $config{target} =~ /^vms-/ -}] + $AUXLIBAPPSSRC=vms_term_sock.c vms_decc_argv.c +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 + +IF[{- !$disabled{apps} -}] + LIBS{noinst}=../libapps.a + SOURCE[../libapps.a]=$LIBAPPSSRC $AUXLIBAPPSSRC + INCLUDE[../libapps.a]=../.. ../../include ../include +ENDIF diff --git a/apps/lib/columns.c b/apps/lib/columns.c new file mode 100644 index 00000000..aa58fe17 --- /dev/null +++ b/apps/lib/columns.c @@ -0,0 +1,27 @@ +/* + * Copyright 2017-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 "apps.h" +#include "function.h" + +void calculate_columns(FUNCTION *functions, DISPLAY_COLUMNS *dc) +{ + FUNCTION *f; + int len, maxlen = 0; + + for (f = functions; f->name != NULL; ++f) + if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher) + if ((len = strlen(f->name)) > maxlen) + maxlen = len; + + dc->width = maxlen + 2; + dc->columns = (80 - 1) / dc->width; +} + diff --git a/apps/fmt.c b/apps/lib/fmt.c similarity index 100% rename from apps/fmt.c rename to apps/lib/fmt.c diff --git a/apps/opt.c b/apps/lib/opt.c similarity index 97% rename from apps/opt.c rename to apps/lib/opt.c index c2a5878e..44d2570a 100644 --- a/apps/opt.c +++ b/apps/lib/opt.c @@ -28,6 +28,7 @@ #define MAX_OPT_HELP_WIDTH 30 const char OPT_HELP_STR[] = "--"; const char OPT_MORE_STR[] = "---"; +const char OPT_SECTION_STR[] = "----"; /* Our state */ static char **argv; @@ -133,7 +134,8 @@ char *opt_init(int ac, char **av, const OPTIONS *o) int duplicated, i; #endif - if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR) + if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR || + o->name == OPT_SECTION_STR) continue; #ifndef NDEBUG i = o->valtype; @@ -832,40 +834,16 @@ static const char *valtype2param(const OPTIONS *o) return "parm"; } -void opt_help(const OPTIONS *list) +void opt_print(const OPTIONS *o, int width) { - const OPTIONS *o; - int i; - int standard_prolog; - int width = 5; + const char* help; char start[80 + 1]; char *p; - const char *help; - /* Starts with its own help message? */ - standard_prolog = list[0].name != OPT_HELP_STR; - - /* Find the widest help. */ - for (o = list; o->name; o++) { - if (o->name == OPT_MORE_STR) - continue; - i = 2 + (int)strlen(o->name); - if (o->valtype != '-') - i += 1 + strlen(valtype2param(o)); - if (i < MAX_OPT_HELP_WIDTH && i > width) - width = i; - OPENSSL_assert(i < (int)sizeof(start)); - } - - if (standard_prolog) - opt_printf_stderr("Usage: %s [options]\nValid options are:\n", prog); - - /* Now let's print. */ - for (o = list; o->name; o++) { help = o->helpstr ? o->helpstr : "(No additional info)"; - if (o->name == OPT_HELP_STR) { + if (o->name == OPT_HELP_STR || o->name == OPT_SECTION_STR) { opt_printf_stderr(help, prog); - continue; + return; } /* Pad out prefix */ @@ -876,7 +854,7 @@ void opt_help(const OPTIONS *list) /* Continuation of previous line; pad and print. */ start[width] = '\0'; opt_printf_stderr("%s %s\n", start, help); - continue; + return; } /* Build up the "-flag [param]" part. */ @@ -899,6 +877,40 @@ void opt_help(const OPTIONS *list) } start[width] = '\0'; opt_printf_stderr("%s %s\n", start, help); +} + +void opt_help(const OPTIONS *list) +{ + const OPTIONS *o; + int i; + int standard_prolog; + int width = 5; + char start[80 + 1]; + + /* Starts with its own help message? */ + standard_prolog = list[0].name != OPT_HELP_STR; + + /* Find the widest help. */ + for (o = list; o->name; o++) { + if (o->name == OPT_MORE_STR) + continue; + i = 2 + (int)strlen(o->name); + if (o->valtype != '-') + i += 1 + strlen(valtype2param(o)); + if (i < MAX_OPT_HELP_WIDTH && i > width) + width = i; + OPENSSL_assert(i < (int)sizeof(start)); + } + + if (standard_prolog) { + opt_printf_stderr("Usage: %s [options]\n", prog); + if (list[0].name != OPT_SECTION_STR) + opt_printf_stderr("Valid options are:\n", prog); + } + + /* Now let's print. */ + for (o = list; o->name; o++) { + opt_print(o, width); } } diff --git a/apps/s_cb.c b/apps/lib/s_cb.c similarity index 99% rename from apps/s_cb.c rename to apps/lib/s_cb.c index 935ea902..47b8afe9 100644 --- a/apps/s_cb.c +++ b/apps/lib/s_cb.c @@ -1508,7 +1508,8 @@ void print_ca_names(BIO *bio, SSL *s) int i; if (sk == NULL || sk_X509_NAME_num(sk) == 0) { - BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs); + if (!SSL_is_server(s)) + BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs); return; } diff --git a/apps/s_socket.c b/apps/lib/s_socket.c similarity index 100% rename from apps/s_socket.c rename to apps/lib/s_socket.c diff --git a/apps/vms_decc_argv.c b/apps/lib/vms_decc_argv.c similarity index 100% rename from apps/vms_decc_argv.c rename to apps/lib/vms_decc_argv.c diff --git a/apps/vms_term_sock.c b/apps/lib/vms_term_sock.c similarity index 99% rename from apps/vms_term_sock.c rename to apps/lib/vms_term_sock.c index 6d55a838..1b27699b 100644 --- a/apps/vms_term_sock.c +++ b/apps/lib/vms_term_sock.c @@ -238,8 +238,8 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket) } /* - ** Deassign the terminal channel - */ + ** Deassign the terminal channel + */ status = sys$dassgn (TerminalDeviceChan); if (! (status & 1)) { LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status); @@ -255,15 +255,15 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket) close (TerminalSocketPair[1]); /* - ** Return the initialized socket - */ + ** Return the initialized socket + */ *ReturnSocket = 0; break; default: /* - ** Invalid function code - */ + ** Invalid function code + */ LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode); return TERM_SOCK_FAILURE; break; diff --git a/apps/win32_init.c b/apps/lib/win32_init.c similarity index 100% rename from apps/win32_init.c rename to apps/lib/win32_init.c diff --git a/apps/list.c b/apps/list.c new file mode 100644 index 00000000..2b44cac7 --- /dev/null +++ b/apps/list.c @@ -0,0 +1,739 @@ +/* + * 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 +#include +#include +#include "apps.h" +#include "app_params.h" +#include "progs.h" +#include "opt.h" + +static int verbose = 0; + +static void legacy_cipher_fn(const EVP_CIPHER *c, + const char *from, const char *to, void *arg) +{ + if (c != NULL) { + BIO_printf(arg, " %s\n", EVP_CIPHER_name(c)); + } else { + if (from == NULL) + from = ""; + if (to == NULL) + to = ""; + BIO_printf(arg, " %s => %s\n", from, to); + } +} + +DEFINE_STACK_OF(EVP_CIPHER) +static int cipher_cmp(const EVP_CIPHER * const *a, + const EVP_CIPHER * const *b) +{ + int ret = strcasecmp(EVP_CIPHER_name(*a), EVP_CIPHER_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_CIPHER_provider(*a)), + OSSL_PROVIDER_name(EVP_CIPHER_provider(*b))); + + return ret; +} + +static void collect_ciphers(EVP_CIPHER *cipher, void *stack) +{ + STACK_OF(EVP_CIPHER) *cipher_stack = stack; + + if (sk_EVP_CIPHER_push(cipher_stack, cipher) > 0) + EVP_CIPHER_up_ref(cipher); +} + +static void list_ciphers(void) +{ + STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp); + int i; + + BIO_printf(bio_out, "Legacy:\n"); + EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out); + + BIO_printf(bio_out, "Provided:\n"); + EVP_CIPHER_do_all_ex(NULL, collect_ciphers, ciphers); + sk_EVP_CIPHER_sort(ciphers); + for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) { + const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i); + + BIO_printf(bio_out, " %s", EVP_CIPHER_name(c)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_CIPHER_provider(c))); + if (verbose) { + print_param_types("retrievable algorithm parameters", + EVP_CIPHER_gettable_params(c), 4); + print_param_types("retrievable operation parameters", + EVP_CIPHER_CTX_gettable_params(c), 4); + print_param_types("settable operation parameters", + EVP_CIPHER_CTX_settable_params(c), 4); + } + } + sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_free); +} + +static void list_md_fn(const EVP_MD *m, + const char *from, const char *to, void *arg) +{ + if (m != NULL) { + BIO_printf(arg, " %s\n", EVP_MD_name(m)); + } else { + if (from == NULL) + from = ""; + if (to == NULL) + to = ""; + BIO_printf((BIO *)arg, " %s => %s\n", from, to); + } +} + +DEFINE_STACK_OF(EVP_MD) +static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b) +{ + int ret = strcasecmp(EVP_MD_name(*a), EVP_MD_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_MD_provider(*a)), + OSSL_PROVIDER_name(EVP_MD_provider(*b))); + + return ret; +} + +static void collect_digests(EVP_MD *md, void *stack) +{ + STACK_OF(EVP_MD) *digest_stack = stack; + + if (sk_EVP_MD_push(digest_stack, md) > 0) + EVP_MD_up_ref(md); +} + +static void list_digests(void) +{ + STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp); + int i; + + BIO_printf(bio_out, "Legacy:\n"); + EVP_MD_do_all_sorted(list_md_fn, bio_out); + + BIO_printf(bio_out, "Provided:\n"); + EVP_MD_do_all_ex(NULL, collect_digests, digests); + sk_EVP_MD_sort(digests); + for (i = 0; i < sk_EVP_MD_num(digests); i++) { + const EVP_MD *m = sk_EVP_MD_value(digests, i); + + BIO_printf(bio_out, " %s", EVP_MD_name(m)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_MD_provider(m))); + if (verbose) { + print_param_types("retrievable algorithm parameters", + EVP_MD_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_MD_CTX_gettable_params(m), 4); + print_param_types("settable operation parameters", + EVP_MD_CTX_settable_params(m), 4); + } + } + sk_EVP_MD_pop_free(digests, EVP_MD_free); +} + +DEFINE_STACK_OF(EVP_MAC) +static int mac_cmp(const EVP_MAC * const *a, const EVP_MAC * const *b) +{ + int ret = strcasecmp(EVP_MAC_name(*a), EVP_MAC_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_MAC_provider(*a)), + OSSL_PROVIDER_name(EVP_MAC_provider(*b))); + + return ret; +} + +static void collect_macs(EVP_MAC *mac, void *stack) +{ + STACK_OF(EVP_MAC) *mac_stack = stack; + + if (sk_EVP_MAC_push(mac_stack, mac) > 0) + EVP_MAC_up_ref(mac); +} + +static void list_macs(void) +{ + STACK_OF(EVP_MAC) *macs = sk_EVP_MAC_new(mac_cmp); + int i; + + BIO_printf(bio_out, "Provided MACs:\n"); + EVP_MAC_do_all_ex(NULL, collect_macs, macs); + sk_EVP_MAC_sort(macs); + for (i = 0; i < sk_EVP_MAC_num(macs); i++) { + const EVP_MAC *m = sk_EVP_MAC_value(macs, i); + + BIO_printf(bio_out, " %s", EVP_MAC_name(m)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_MAC_provider(m))); + + if (verbose) { + print_param_types("retrievable algorithm parameters", + EVP_MAC_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_MAC_CTX_gettable_params(m), 4); + print_param_types("settable operation parameters", + EVP_MAC_CTX_settable_params(m), 4); + } + } + sk_EVP_MAC_pop_free(macs, EVP_MAC_free); +} + +/* + * KDFs and PRFs + */ +DEFINE_STACK_OF(EVP_KDF) +static int kdf_cmp(const EVP_KDF * const *a, const EVP_KDF * const *b) +{ + int ret = strcasecmp(EVP_KDF_name(*a), EVP_KDF_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_KDF_provider(*a)), + OSSL_PROVIDER_name(EVP_KDF_provider(*b))); + + return ret; +} + +static void collect_kdfs(EVP_KDF *kdf, void *stack) +{ + STACK_OF(EVP_KDF) *kdf_stack = stack; + + sk_EVP_KDF_push(kdf_stack, kdf); + EVP_KDF_up_ref(kdf); +} + +static void list_kdfs(void) +{ + STACK_OF(EVP_KDF) *kdfs = sk_EVP_KDF_new(kdf_cmp); + int i; + + BIO_printf(bio_out, "Provided KDFs and PDFs:\n"); + EVP_KDF_do_all_ex(NULL, collect_kdfs, kdfs); + sk_EVP_KDF_sort(kdfs); + for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) { + const EVP_KDF *m = sk_EVP_KDF_value(kdfs, i); + + BIO_printf(bio_out, " %s", EVP_KDF_name(m)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_KDF_provider(m))); + + if (verbose) { + print_param_types("retrievable algorithm parameters", + EVP_KDF_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_KDF_CTX_gettable_params(m), 4); + print_param_types("settable operation parameters", + EVP_KDF_CTX_settable_params(m), 4); + } + } + sk_EVP_KDF_pop_free(kdfs, EVP_KDF_free); +} + +static void list_missing_help(void) +{ + const FUNCTION *fp; + const OPTIONS *o; + + for (fp = functions; fp->name != NULL; fp++) { + if ((o = fp->help) != NULL) { + /* If there is help, list what flags are not documented. */ + for ( ; o->name != NULL; o++) { + if (o->helpstr == NULL) + BIO_printf(bio_out, "%s %s\n", fp->name, o->name); + } + } else if (fp->func != dgst_main) { + /* If not aliased to the dgst command, */ + BIO_printf(bio_out, "%s *\n", fp->name); + } + } +} + +static void list_objects(void) +{ + int max_nid = OBJ_new_nid(0); + int i; + char *oid_buf = NULL; + int oid_size = 0; + + /* Skip 0, since that's NID_undef */ + for (i = 1; i < max_nid; i++) { + const ASN1_OBJECT *obj = OBJ_nid2obj(i); + const char *sn = OBJ_nid2sn(i); + const char *ln = OBJ_nid2ln(i); + int n = 0; + + /* + * If one of the retrieved objects somehow generated an error, + * we ignore it. The check for NID_undef below will detect the + * error and simply skip to the next NID. + */ + ERR_clear_error(); + + if (OBJ_obj2nid(obj) == NID_undef) + continue; + + if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) { + BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln); + continue; + } + if (n < 0) + break; /* Error */ + + if (n > oid_size) { + oid_buf = OPENSSL_realloc(oid_buf, n + 1); + if (oid_buf == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + break; /* Error */ + } + oid_size = n + 1; + } + if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0) + break; /* Error */ + if (ln == NULL || strcmp(sn, ln) == 0) + BIO_printf(bio_out, "%s = %s\n", sn, oid_buf); + else + BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf); + } + + OPENSSL_free(oid_buf); +} + +static void list_options_for_command(const char *command) +{ + const FUNCTION *fp; + const OPTIONS *o; + + for (fp = functions; fp->name != NULL; fp++) + if (strcmp(fp->name, command) == 0) + break; + if (fp->name == NULL) { + BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", + command); + return; + } + + if ((o = fp->help) == NULL) + return; + + for ( ; o->name != NULL; o++) { + if (o->name == OPT_HELP_STR + || o->name == OPT_MORE_STR + || o->name[0] == '\0') + continue; + BIO_printf(bio_out, "%s %c\n", o->name, o->valtype); + } +} + +static void list_type(FUNC_TYPE ft, int one) +{ + FUNCTION *fp; + int i = 0; + DISPLAY_COLUMNS dc; + + memset(&dc, 0, sizeof(dc)); + if (!one) + calculate_columns(functions, &dc); + + for (fp = functions; fp->name != NULL; fp++) { + if (fp->type != ft) + continue; + if (one) { + BIO_printf(bio_out, "%s\n", fp->name); + } else { + if (i % dc.columns == 0 && i > 0) + BIO_printf(bio_out, "\n"); + BIO_printf(bio_out, "%-*s", dc.width, fp->name); + i++; + } + } + if (!one) + BIO_printf(bio_out, "\n\n"); +} + +static void list_pkey(void) +{ + int i; + + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id, pkey_base_id, pkey_flags; + const char *pinfo, *pem_str; + ameth = EVP_PKEY_asn1_get0(i); + EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, + &pinfo, &pem_str, ameth); + if (pkey_flags & ASN1_PKEY_ALIAS) { + BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tAlias for: %s\n", + OBJ_nid2ln(pkey_base_id)); + } else { + BIO_printf(bio_out, "Name: %s\n", pinfo); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? + "External" : "Builtin"); + BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + if (pem_str == NULL) + pem_str = "(none)"; + BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); + } + + } +} + +static void list_pkey_meth(void) +{ + size_t i; + size_t meth_count = EVP_PKEY_meth_get_count(); + + for (i = 0; i < meth_count; i++) { + const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); + int pkey_id, pkey_flags; + + EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); + BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); + } +} + +static void list_engines(void) +{ +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + + BIO_puts(bio_out, "Engines:\n"); + e = ENGINE_get_first(); + while (e) { + BIO_printf(bio_out, "%s\n", ENGINE_get_id(e)); + e = ENGINE_get_next(e); + } +#else + BIO_puts(bio_out, "Engine support is disabled.\n"); +#endif +} + +static void list_disabled(void) +{ + BIO_puts(bio_out, "Disabled algorithms:\n"); +#ifdef OPENSSL_NO_ARIA + BIO_puts(bio_out, "ARIA\n"); +#endif +#ifdef OPENSSL_NO_BF + BIO_puts(bio_out, "BF\n"); +#endif +#ifdef OPENSSL_NO_BLAKE2 + BIO_puts(bio_out, "BLAKE2\n"); +#endif +#ifdef OPENSSL_NO_CAMELLIA + BIO_puts(bio_out, "CAMELLIA\n"); +#endif +#ifdef OPENSSL_NO_CAST + BIO_puts(bio_out, "CAST\n"); +#endif +#ifdef OPENSSL_NO_CMAC + BIO_puts(bio_out, "CMAC\n"); +#endif +#ifdef OPENSSL_NO_CMS + BIO_puts(bio_out, "CMS\n"); +#endif +#ifdef OPENSSL_NO_COMP + BIO_puts(bio_out, "COMP\n"); +#endif +#ifdef OPENSSL_NO_DES + BIO_puts(bio_out, "DES\n"); +#endif +#ifdef OPENSSL_NO_DGRAM + BIO_puts(bio_out, "DGRAM\n"); +#endif +#ifdef OPENSSL_NO_DH + BIO_puts(bio_out, "DH\n"); +#endif +#ifdef OPENSSL_NO_DSA + BIO_puts(bio_out, "DSA\n"); +#endif +#if defined(OPENSSL_NO_DTLS) + BIO_puts(bio_out, "DTLS\n"); +#endif +#if defined(OPENSSL_NO_DTLS1) + BIO_puts(bio_out, "DTLS1\n"); +#endif +#if defined(OPENSSL_NO_DTLS1_2) + BIO_puts(bio_out, "DTLS1_2\n"); +#endif +#ifdef OPENSSL_NO_EC + BIO_puts(bio_out, "EC\n"); +#endif +#ifdef OPENSSL_NO_EC2M + BIO_puts(bio_out, "EC2M\n"); +#endif +#ifdef OPENSSL_NO_ENGINE + BIO_puts(bio_out, "ENGINE\n"); +#endif +#ifdef OPENSSL_NO_GOST + BIO_puts(bio_out, "GOST\n"); +#endif +#ifdef OPENSSL_NO_IDEA + BIO_puts(bio_out, "IDEA\n"); +#endif +#ifdef OPENSSL_NO_MD2 + BIO_puts(bio_out, "MD2\n"); +#endif +#ifdef OPENSSL_NO_MD4 + BIO_puts(bio_out, "MD4\n"); +#endif +#ifdef OPENSSL_NO_MD5 + BIO_puts(bio_out, "MD5\n"); +#endif +#ifdef OPENSSL_NO_MDC2 + BIO_puts(bio_out, "MDC2\n"); +#endif +#ifdef OPENSSL_NO_OCB + BIO_puts(bio_out, "OCB\n"); +#endif +#ifdef OPENSSL_NO_OCSP + BIO_puts(bio_out, "OCSP\n"); +#endif +#ifdef OPENSSL_NO_PSK + BIO_puts(bio_out, "PSK\n"); +#endif +#ifdef OPENSSL_NO_RC2 + BIO_puts(bio_out, "RC2\n"); +#endif +#ifdef OPENSSL_NO_RC4 + BIO_puts(bio_out, "RC4\n"); +#endif +#ifdef OPENSSL_NO_RC5 + BIO_puts(bio_out, "RC5\n"); +#endif +#ifdef OPENSSL_NO_RMD160 + BIO_puts(bio_out, "RMD160\n"); +#endif +#ifdef OPENSSL_NO_RSA + BIO_puts(bio_out, "RSA\n"); +#endif +#ifdef OPENSSL_NO_SCRYPT + BIO_puts(bio_out, "SCRYPT\n"); +#endif +#ifdef OPENSSL_NO_SCTP + BIO_puts(bio_out, "SCTP\n"); +#endif +#ifdef OPENSSL_NO_SEED + BIO_puts(bio_out, "SEED\n"); +#endif +#ifdef OPENSSL_NO_SM2 + BIO_puts(bio_out, "SM2\n"); +#endif +#ifdef OPENSSL_NO_SM3 + BIO_puts(bio_out, "SM3\n"); +#endif +#ifdef OPENSSL_NO_SM4 + BIO_puts(bio_out, "SM4\n"); +#endif +#ifdef OPENSSL_NO_SOCK + BIO_puts(bio_out, "SOCK\n"); +#endif +#ifdef OPENSSL_NO_SRP + BIO_puts(bio_out, "SRP\n"); +#endif +#ifdef OPENSSL_NO_SRTP + BIO_puts(bio_out, "SRTP\n"); +#endif +#ifdef OPENSSL_NO_SSL3 + BIO_puts(bio_out, "SSL3\n"); +#endif +#ifdef OPENSSL_NO_TLS1 + BIO_puts(bio_out, "TLS1\n"); +#endif +#ifdef OPENSSL_NO_TLS1_1 + BIO_puts(bio_out, "TLS1_1\n"); +#endif +#ifdef OPENSSL_NO_TLS1_2 + BIO_puts(bio_out, "TLS1_2\n"); +#endif +#ifdef OPENSSL_NO_WHIRLPOOL + BIO_puts(bio_out, "WHIRLPOOL\n"); +#endif +#ifndef ZLIB + BIO_puts(bio_out, "ZLIB\n"); +#endif +} + +/* Unified enum for help and list commands. */ +typedef enum HELPLIST_CHOICE { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE, OPT_VERBOSE, + OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, + OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, + OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_ENGINES, OPT_DISABLED, + OPT_KDF_ALGORITHMS, OPT_MISSING_HELP, OPT_OBJECTS +} HELPLIST_CHOICE; + +const OPTIONS list_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"1", OPT_ONE, '-', "List in one column"}, + {"verbose", OPT_VERBOSE, '-', "Verbose listing"}, + {"commands", OPT_COMMANDS, '-', "List of standard commands"}, + {"digest-commands", OPT_DIGEST_COMMANDS, '-', + "List of message digest commands"}, + {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', + "List of message digest algorithms"}, + {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-', + "List of key derivation and pseudo random function algorithms"}, + {"mac-algorithms", OPT_MAC_ALGORITHMS, '-', + "List of message authentication code algorithms"}, + {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, + {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', + "List of cipher algorithms"}, + {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', + "List of public key algorithms"}, + {"public-key-methods", OPT_PK_METHOD, '-', + "List of public key methods"}, + {"engines", OPT_ENGINES, '-', + "List of loaded engines"}, + {"disabled", OPT_DISABLED, '-', + "List of disabled features"}, + {"missing-help", OPT_MISSING_HELP, '-', + "List missing detailed help strings"}, + {"options", OPT_OPTIONS, 's', + "List options for specified command"}, + {"objects", OPT_OBJECTS, '-', + "List built in objects (OID<->name mappings)"}, + {NULL} +}; + +int list_main(int argc, char **argv) +{ + char *prog; + HELPLIST_CHOICE o; + int one = 0, done = 0; + struct { + unsigned int commands:1; + unsigned int digest_commands:1; + unsigned int digest_algorithms:1; + unsigned int kdf_algorithms:1; + unsigned int mac_algorithms:1; + unsigned int cipher_commands:1; + unsigned int cipher_algorithms:1; + unsigned int pk_algorithms:1; + unsigned int pk_method:1; + unsigned int engines:1; + unsigned int disabled:1; + unsigned int missing_help:1; + unsigned int objects:1; + unsigned int options:1; + } todo = { 0, }; + + verbose = 0; /* Clear a possible previous call */ + + prog = opt_init(argc, argv, list_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: /* Never hit, but suppresses warning */ + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + return 1; + case OPT_HELP: + opt_help(list_options); + break; + case OPT_ONE: + one = 1; + break; + case OPT_COMMANDS: + todo.commands = 1; + break; + case OPT_DIGEST_COMMANDS: + todo.digest_commands = 1; + break; + case OPT_DIGEST_ALGORITHMS: + todo.digest_algorithms = 1; + break; + case OPT_KDF_ALGORITHMS: + todo.kdf_algorithms = 1; + break; + case OPT_MAC_ALGORITHMS: + todo.mac_algorithms = 1; + break; + case OPT_CIPHER_COMMANDS: + todo.cipher_commands = 1; + break; + case OPT_CIPHER_ALGORITHMS: + todo.cipher_algorithms = 1; + break; + case OPT_PK_ALGORITHMS: + todo.pk_algorithms = 1; + break; + case OPT_PK_METHOD: + todo.pk_method = 1; + break; + case OPT_ENGINES: + todo.engines = 1; + break; + case OPT_DISABLED: + todo.disabled = 1; + break; + case OPT_MISSING_HELP: + todo.missing_help = 1; + break; + case OPT_OBJECTS: + todo.objects = 1; + break; + case OPT_OPTIONS: + list_options_for_command(opt_arg()); + break; + case OPT_VERBOSE: + verbose = 1; + break; + } + done = 1; + } + if (opt_num_rest() != 0) { + BIO_printf(bio_err, "Extra arguments given.\n"); + goto opthelp; + } + + if (todo.commands) + list_type(FT_general, one); + if (todo.digest_commands) + list_type(FT_md, one); + if (todo.digest_algorithms) + list_digests(); + if (todo.kdf_algorithms) + list_kdfs(); + if (todo.mac_algorithms) + list_macs(); + if (todo.cipher_commands) + list_type(FT_cipher, one); + if (todo.cipher_algorithms) + list_ciphers(); + if (todo.pk_algorithms) + list_pkey(); + if (todo.pk_method) + list_pkey_meth(); + if (todo.engines) + list_engines(); + if (todo.disabled) + list_disabled(); + if (todo.missing_help) + list_missing_help(); + if (todo.objects) + list_objects(); + + if (!done) + goto opthelp; + + return 0; +} diff --git a/apps/mac.c b/apps/mac.c index 946c3c7a..205d82f7 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -14,6 +14,7 @@ #include #include #include +#include #undef BUFSIZE #define BUFSIZE 1024*8 @@ -28,8 +29,8 @@ const OPTIONS mac_options[] = { {OPT_HELP_STR, 1, '-', "mac_name\t\t MAC algorithm (See list " "-mac-algorithms)"}, {"help", OPT_HELP, '-', "Display this summary"}, - {"macopt", OPT_MACOPT, 's', "MAC algorithm control parameters in n:v form. " - "See 'Supported Controls' in the EVP_MAC_ docs"}, + {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form. " + "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, {"in", OPT_IN, '<', "Input file to MAC (default is stdin)"}, {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, {"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal " @@ -37,29 +38,11 @@ const OPTIONS mac_options[] = { {NULL} }; -static int mac_ctrl_string(EVP_MAC_CTX *ctx, const char *value) -{ - int rv; - char *stmp, *vtmp = NULL; - - stmp = OPENSSL_strdup(value); - if (stmp == NULL) - return -1; - vtmp = strchr(stmp, ':'); - if (vtmp != NULL) { - *vtmp = 0; - vtmp++; - } - rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp); - OPENSSL_free(stmp); - return rv; -} - int mac_main(int argc, char **argv) { int ret = 1; char *prog; - const EVP_MAC *mac = NULL; + EVP_MAC *mac = NULL; OPTION_CHOICE o; EVP_MAC_CTX *ctx = NULL; STACK_OF(OPENSSL_STRING) *opts = NULL; @@ -109,7 +92,7 @@ opthelp: goto opthelp; } - mac = EVP_get_macbyname(argv[0]); + mac = EVP_MAC_fetch(NULL, argv[0], NULL); if (mac == NULL) { BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]); goto opthelp; @@ -120,14 +103,21 @@ opthelp: goto err; if (opts != NULL) { - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (mac_ctrl_string(ctx, opt) <= 0) { - BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); - ERR_print_errors(bio_err); - goto err; - } + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_MAC_CTX_settable_params(mac)); + + if (params == NULL) + goto err; + + if (!EVP_MAC_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "MAC parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; } + app_params_free(params); + if (!ok) + goto err; } /* Use text mode for stdin */ @@ -146,7 +136,6 @@ opthelp: goto err; } - for (;;) { i = BIO_read(in, (char *)buf, BUFSIZE); if (i < 0) { @@ -161,7 +150,7 @@ opthelp: } } - if (!EVP_MAC_final(ctx, NULL, &len)) { + if (!EVP_MAC_final(ctx, NULL, &len, 0)) { BIO_printf(bio_err, "EVP_MAC_final failed\n"); goto err; } @@ -170,7 +159,7 @@ opthelp: goto err; } - if (!EVP_MAC_final(ctx, buf, &len)) { + if (!EVP_MAC_final(ctx, buf, &len, BUFSIZE)) { BIO_printf(bio_err, "EVP_MAC_final failed\n"); goto err; } @@ -195,5 +184,6 @@ err: BIO_free(in); BIO_free(out); EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); return ret; } diff --git a/apps/ocsp.c b/apps/ocsp.c index 9f2cf453..71c6a56f 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1436,9 +1436,11 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, *q = '\0'; /* - * Skip "GET / HTTP..." requests often used by load-balancers + * Skip "GET / HTTP..." requests often used by load-balancers. Note: + * 'p' was incremented above to point to the first byte *after* the + * leading slash, so with 'GET / ' it is now an empty string. */ - if (p[1] == '\0') + if (p[0] == '\0') goto out; len = urldecode(p); diff --git a/apps/openssl.c b/apps/openssl.c index d6820a19..123c1ff4 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -23,23 +23,13 @@ # include #endif #include -#include "s_apps.h" /* Needed to get the other O_xxx flags. */ #ifdef OPENSSL_SYS_VMS # include #endif #include "apps.h" -#define INCLUDE_FUNCTION_TABLE #include "progs.h" -/* Structure to hold the number of columns to be displayed and the - * field width used to display them. - */ -typedef struct { - int columns; - int width; -} DISPLAY_COLUMNS; - /* Special sentinel to exit the program. */ #define EXIT_THE_PROGRAM (-1) @@ -51,31 +41,12 @@ typedef struct { */ static LHASH_OF(FUNCTION) *prog_init(void); static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); -static void list_pkey(void); -static void list_pkey_meth(void); -static void list_type(FUNC_TYPE ft, int one); -static void list_engines(void); -static void list_disabled(void); char *default_config_file = NULL; BIO *bio_in = NULL; BIO *bio_out = NULL; BIO *bio_err = NULL; -static void calculate_columns(DISPLAY_COLUMNS *dc) -{ - FUNCTION *f; - int len, maxlen = 0; - - for (f = functions; f->name != NULL; ++f) - if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher) - if ((len = strlen(f->name)) > maxlen) - maxlen = len; - - dc->width = maxlen + 2; - dc->columns = (80 - 1) / dc->width; -} - static int apps_startup(void) { #ifdef SIGPIPE @@ -408,256 +379,6 @@ int main(int argc, char *argv[]) EXIT(ret); } -static void list_cipher_fn(const EVP_CIPHER *c, - const char *from, const char *to, void *arg) -{ - if (c != NULL) { - BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); - } else { - if (from == NULL) - from = ""; - if (to == NULL) - to = ""; - BIO_printf(arg, "%s => %s\n", from, to); - } -} - -static void list_md_fn(const EVP_MD *m, - const char *from, const char *to, void *arg) -{ - if (m != NULL) { - BIO_printf(arg, "%s\n", EVP_MD_name(m)); - } else { - if (from == NULL) - from = ""; - if (to == NULL) - to = ""; - BIO_printf((BIO *)arg, "%s => %s\n", from, to); - } -} - -static void list_mac_fn(const EVP_MAC *m, - const char *from, const char *to, void *arg) -{ - if (m != NULL) { - BIO_printf(arg, "%s\n", EVP_MAC_name(m)); - } else { - if (from == NULL) - from = ""; - if (to == NULL) - to = ""; - BIO_printf(arg, "%s => %s\n", from, to); - } -} - -static void list_missing_help(void) -{ - const FUNCTION *fp; - const OPTIONS *o; - - for (fp = functions; fp->name != NULL; fp++) { - if ((o = fp->help) != NULL) { - /* If there is help, list what flags are not documented. */ - for ( ; o->name != NULL; o++) { - if (o->helpstr == NULL) - BIO_printf(bio_out, "%s %s\n", fp->name, o->name); - } - } else if (fp->func != dgst_main) { - /* If not aliased to the dgst command, */ - BIO_printf(bio_out, "%s *\n", fp->name); - } - } -} - -static void list_objects(void) -{ - int max_nid = OBJ_new_nid(0); - int i; - char *oid_buf = NULL; - int oid_size = 0; - - /* Skip 0, since that's NID_undef */ - for (i = 1; i < max_nid; i++) { - const ASN1_OBJECT *obj = OBJ_nid2obj(i); - const char *sn = OBJ_nid2sn(i); - const char *ln = OBJ_nid2ln(i); - int n = 0; - - /* - * If one of the retrieved objects somehow generated an error, - * we ignore it. The check for NID_undef below will detect the - * error and simply skip to the next NID. - */ - ERR_clear_error(); - - if (OBJ_obj2nid(obj) == NID_undef) - continue; - - if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) { - BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln); - continue; - } - if (n < 0) - break; /* Error */ - - if (n > oid_size) { - oid_buf = OPENSSL_realloc(oid_buf, n + 1); - if (oid_buf == NULL) { - BIO_printf(bio_err, "ERROR: Memory allocation\n"); - break; /* Error */ - } - oid_size = n + 1; - } - if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0) - break; /* Error */ - if (ln == NULL || strcmp(sn, ln) == 0) - BIO_printf(bio_out, "%s = %s\n", sn, oid_buf); - else - BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf); - } - - OPENSSL_free(oid_buf); -} - -static void list_options_for_command(const char *command) -{ - const FUNCTION *fp; - const OPTIONS *o; - - for (fp = functions; fp->name != NULL; fp++) - if (strcmp(fp->name, command) == 0) - break; - if (fp->name == NULL) { - BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", - command); - return; - } - - if ((o = fp->help) == NULL) - return; - - for ( ; o->name != NULL; o++) { - if (o->name == OPT_HELP_STR - || o->name == OPT_MORE_STR - || o->name[0] == '\0') - continue; - BIO_printf(bio_out, "%s %c\n", o->name, o->valtype); - } -} - - -/* Unified enum for help and list commands. */ -typedef enum HELPLIST_CHOICE { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE, - OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, - OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, - OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_ENGINES, OPT_DISABLED, - OPT_MISSING_HELP, OPT_OBJECTS -} HELPLIST_CHOICE; - -const OPTIONS list_options[] = { - {"help", OPT_HELP, '-', "Display this summary"}, - {"1", OPT_ONE, '-', "List in one column"}, - {"commands", OPT_COMMANDS, '-', "List of standard commands"}, - {"digest-commands", OPT_DIGEST_COMMANDS, '-', - "List of message digest commands"}, - {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', - "List of message digest algorithms"}, - {"mac-algorithms", OPT_MAC_ALGORITHMS, '-', - "List of message authentication code algorithms"}, - {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, - {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', - "List of cipher algorithms"}, - {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', - "List of public key algorithms"}, - {"public-key-methods", OPT_PK_METHOD, '-', - "List of public key methods"}, - {"engines", OPT_ENGINES, '-', - "List of loaded engines"}, - {"disabled", OPT_DISABLED, '-', - "List of disabled features"}, - {"missing-help", OPT_MISSING_HELP, '-', - "List missing detailed help strings"}, - {"options", OPT_OPTIONS, 's', - "List options for specified command"}, - {"objects", OPT_OBJECTS, '-', - "List built in objects (OID<->name mappings)"}, - {NULL} -}; - -int list_main(int argc, char **argv) -{ - char *prog; - HELPLIST_CHOICE o; - int one = 0, done = 0; - - prog = opt_init(argc, argv, list_options); - while ((o = opt_next()) != OPT_EOF) { - switch (o) { - case OPT_EOF: /* Never hit, but suppresses warning */ - case OPT_ERR: -opthelp: - BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); - return 1; - case OPT_HELP: - opt_help(list_options); - break; - case OPT_ONE: - one = 1; - break; - case OPT_COMMANDS: - list_type(FT_general, one); - break; - case OPT_DIGEST_COMMANDS: - list_type(FT_md, one); - break; - case OPT_DIGEST_ALGORITHMS: - EVP_MD_do_all_sorted(list_md_fn, bio_out); - break; - case OPT_MAC_ALGORITHMS: - EVP_MAC_do_all_sorted(list_mac_fn, bio_out); - break; - case OPT_CIPHER_COMMANDS: - list_type(FT_cipher, one); - break; - case OPT_CIPHER_ALGORITHMS: - EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); - break; - case OPT_PK_ALGORITHMS: - list_pkey(); - break; - case OPT_PK_METHOD: - list_pkey_meth(); - break; - case OPT_ENGINES: - list_engines(); - break; - case OPT_DISABLED: - list_disabled(); - break; - case OPT_MISSING_HELP: - list_missing_help(); - break; - case OPT_OBJECTS: - list_objects(); - break; - case OPT_OPTIONS: - list_options_for_command(opt_arg()); - break; - } - done = 1; - } - if (opt_num_rest() != 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); - goto opthelp; - } - - if (!done) - goto opthelp; - - return 0; -} - typedef enum HELP_CHOICE { OPT_hERR = -1, OPT_hEOF = 0, OPT_hHELP } HELP_CHOICE; @@ -705,7 +426,7 @@ int help_main(int argc, char **argv) return 1; } - calculate_columns(&dc); + calculate_columns(functions, &dc); BIO_printf(bio_err, "Standard commands"); i = 0; tp = FT_none; @@ -735,32 +456,6 @@ int help_main(int argc, char **argv) return 0; } -static void list_type(FUNC_TYPE ft, int one) -{ - FUNCTION *fp; - int i = 0; - DISPLAY_COLUMNS dc; - - memset(&dc, 0, sizeof(dc)); - if (!one) - calculate_columns(&dc); - - for (fp = functions; fp->name != NULL; fp++) { - if (fp->type != ft) - continue; - if (one) { - BIO_printf(bio_out, "%s\n", fp->name); - } else { - if (i % dc.columns == 0 && i > 0) - BIO_printf(bio_out, "\n"); - BIO_printf(bio_out, "%-*s", dc.width, fp->name); - i++; - } - } - if (!one) - BIO_printf(bio_out, "\n\n"); -} - static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) { FUNCTION f, *fp; @@ -806,51 +501,6 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) return 1; } -static void list_pkey(void) -{ - int i; - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id, pkey_base_id, pkey_flags; - const char *pinfo, *pem_str; - ameth = EVP_PKEY_asn1_get0(i); - EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, - &pinfo, &pem_str, ameth); - if (pkey_flags & ASN1_PKEY_ALIAS) { - BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tAlias for: %s\n", - OBJ_nid2ln(pkey_base_id)); - } else { - BIO_printf(bio_out, "Name: %s\n", pinfo); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? - "External" : "Builtin"); - BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); - if (pem_str == NULL) - pem_str = "(none)"; - BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); - } - - } -} - -static void list_pkey_meth(void) -{ - size_t i; - size_t meth_count = EVP_PKEY_meth_get_count(); - - for (i = 0; i < meth_count; i++) { - const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); - int pkey_id, pkey_flags; - - EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); - BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); - } -} - static int function_cmp(const FUNCTION * a, const FUNCTION * b) { return strncmp(a->name, b->name, 8); @@ -871,168 +521,6 @@ static int SortFnByName(const void *_f1, const void *_f2) return strcmp(f1->name, f2->name); } -static void list_engines(void) -{ -#ifndef OPENSSL_NO_ENGINE - ENGINE *e; - - BIO_puts(bio_out, "Engines:\n"); - e = ENGINE_get_first(); - while (e) { - BIO_printf(bio_out, "%s\n", ENGINE_get_id(e)); - e = ENGINE_get_next(e); - } -#else - BIO_puts(bio_out, "Engine support is disabled.\n"); -#endif -} - -static void list_disabled(void) -{ - BIO_puts(bio_out, "Disabled algorithms:\n"); -#ifdef OPENSSL_NO_ARIA - BIO_puts(bio_out, "ARIA\n"); -#endif -#ifdef OPENSSL_NO_BF - BIO_puts(bio_out, "BF\n"); -#endif -#ifdef OPENSSL_NO_BLAKE2 - BIO_puts(bio_out, "BLAKE2\n"); -#endif -#ifdef OPENSSL_NO_CAMELLIA - BIO_puts(bio_out, "CAMELLIA\n"); -#endif -#ifdef OPENSSL_NO_CAST - BIO_puts(bio_out, "CAST\n"); -#endif -#ifdef OPENSSL_NO_CMAC - BIO_puts(bio_out, "CMAC\n"); -#endif -#ifdef OPENSSL_NO_CMS - BIO_puts(bio_out, "CMS\n"); -#endif -#ifdef OPENSSL_NO_COMP - BIO_puts(bio_out, "COMP\n"); -#endif -#ifdef OPENSSL_NO_DES - BIO_puts(bio_out, "DES\n"); -#endif -#ifdef OPENSSL_NO_DGRAM - BIO_puts(bio_out, "DGRAM\n"); -#endif -#ifdef OPENSSL_NO_DH - BIO_puts(bio_out, "DH\n"); -#endif -#ifdef OPENSSL_NO_DSA - BIO_puts(bio_out, "DSA\n"); -#endif -#if defined(OPENSSL_NO_DTLS) - BIO_puts(bio_out, "DTLS\n"); -#endif -#if defined(OPENSSL_NO_DTLS1) - BIO_puts(bio_out, "DTLS1\n"); -#endif -#if defined(OPENSSL_NO_DTLS1_2) - BIO_puts(bio_out, "DTLS1_2\n"); -#endif -#ifdef OPENSSL_NO_EC - BIO_puts(bio_out, "EC\n"); -#endif -#ifdef OPENSSL_NO_EC2M - BIO_puts(bio_out, "EC2M\n"); -#endif -#ifdef OPENSSL_NO_ENGINE - BIO_puts(bio_out, "ENGINE\n"); -#endif -#ifdef OPENSSL_NO_GOST - BIO_puts(bio_out, "GOST\n"); -#endif -#ifdef OPENSSL_NO_IDEA - BIO_puts(bio_out, "IDEA\n"); -#endif -#ifdef OPENSSL_NO_MD2 - BIO_puts(bio_out, "MD2\n"); -#endif -#ifdef OPENSSL_NO_MD4 - BIO_puts(bio_out, "MD4\n"); -#endif -#ifdef OPENSSL_NO_MD5 - BIO_puts(bio_out, "MD5\n"); -#endif -#ifdef OPENSSL_NO_MDC2 - BIO_puts(bio_out, "MDC2\n"); -#endif -#ifdef OPENSSL_NO_OCB - BIO_puts(bio_out, "OCB\n"); -#endif -#ifdef OPENSSL_NO_OCSP - BIO_puts(bio_out, "OCSP\n"); -#endif -#ifdef OPENSSL_NO_PSK - BIO_puts(bio_out, "PSK\n"); -#endif -#ifdef OPENSSL_NO_RC2 - BIO_puts(bio_out, "RC2\n"); -#endif -#ifdef OPENSSL_NO_RC4 - BIO_puts(bio_out, "RC4\n"); -#endif -#ifdef OPENSSL_NO_RC5 - BIO_puts(bio_out, "RC5\n"); -#endif -#ifdef OPENSSL_NO_RMD160 - BIO_puts(bio_out, "RMD160\n"); -#endif -#ifdef OPENSSL_NO_RSA - BIO_puts(bio_out, "RSA\n"); -#endif -#ifdef OPENSSL_NO_SCRYPT - BIO_puts(bio_out, "SCRYPT\n"); -#endif -#ifdef OPENSSL_NO_SCTP - BIO_puts(bio_out, "SCTP\n"); -#endif -#ifdef OPENSSL_NO_SEED - BIO_puts(bio_out, "SEED\n"); -#endif -#ifdef OPENSSL_NO_SM2 - BIO_puts(bio_out, "SM2\n"); -#endif -#ifdef OPENSSL_NO_SM3 - BIO_puts(bio_out, "SM3\n"); -#endif -#ifdef OPENSSL_NO_SM4 - BIO_puts(bio_out, "SM4\n"); -#endif -#ifdef OPENSSL_NO_SOCK - BIO_puts(bio_out, "SOCK\n"); -#endif -#ifdef OPENSSL_NO_SRP - BIO_puts(bio_out, "SRP\n"); -#endif -#ifdef OPENSSL_NO_SRTP - BIO_puts(bio_out, "SRTP\n"); -#endif -#ifdef OPENSSL_NO_SSL3 - BIO_puts(bio_out, "SSL3\n"); -#endif -#ifdef OPENSSL_NO_TLS1 - BIO_puts(bio_out, "TLS1\n"); -#endif -#ifdef OPENSSL_NO_TLS1_1 - BIO_puts(bio_out, "TLS1_1\n"); -#endif -#ifdef OPENSSL_NO_TLS1_2 - BIO_puts(bio_out, "TLS1_2\n"); -#endif -#ifdef OPENSSL_NO_WHIRLPOOL - BIO_puts(bio_out, "WHIRLPOOL\n"); -#endif -#ifndef ZLIB - BIO_puts(bio_out, "ZLIB\n"); -#endif -} - static LHASH_OF(FUNCTION) *prog_init(void) { static LHASH_OF(FUNCTION) *ret = NULL; diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 407340b3..902b7502 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -41,6 +41,7 @@ int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bags, const char *pass, int passlen, int options, char *pempass, const EVP_CIPHER *enc); +void print_attribute(BIO *out, const ASN1_TYPE *av); int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); @@ -878,6 +879,38 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) return ret; } +/* Generalised x509 attribute value print */ + +void print_attribute(BIO *out, const ASN1_TYPE *av) +{ + char *value; + + switch (av->type) { + case V_ASN1_BMPSTRING: + value = OPENSSL_uni2asc(av->value.bmpstring->data, + av->value.bmpstring->length); + BIO_printf(out, "%s\n", value); + OPENSSL_free(value); + break; + + case V_ASN1_OCTET_STRING: + hex_prin(out, av->value.octet_string->data, + av->value.octet_string->length); + BIO_printf(out, "\n"); + break; + + case V_ASN1_BIT_STRING: + hex_prin(out, av->value.bit_string->data, + av->value.bit_string->length); + BIO_printf(out, "\n"); + break; + + default: + BIO_printf(out, "\n", av->type); + break; + } +} + /* Generalised attribute print: handle PKCS#8 and bag attributes */ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, @@ -885,8 +918,7 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, { X509_ATTRIBUTE *attr; ASN1_TYPE *av; - char *value; - int i, attr_nid; + int i, j, attr_nid; if (!attrlst) { BIO_printf(out, "%s: \n", name); return 1; @@ -910,30 +942,10 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, } if (X509_ATTRIBUTE_count(attr)) { - av = X509_ATTRIBUTE_get0_type(attr, 0); - switch (av->type) { - case V_ASN1_BMPSTRING: - value = OPENSSL_uni2asc(av->value.bmpstring->data, - av->value.bmpstring->length); - BIO_printf(out, "%s\n", value); - OPENSSL_free(value); - break; - - case V_ASN1_OCTET_STRING: - hex_prin(out, av->value.octet_string->data, - av->value.octet_string->length); - BIO_printf(out, "\n"); - break; - - case V_ASN1_BIT_STRING: - hex_prin(out, av->value.bit_string->data, - av->value.bit_string->length); - BIO_printf(out, "\n"); - break; - - default: - BIO_printf(out, "\n", av->type); - break; + for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) + { + av = X509_ATTRIBUTE_get0_type(attr, j); + print_attribute(out, av); } } else { BIO_printf(out, "\n"); diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index c8cac0d6..6b012211 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -398,8 +398,7 @@ int pkeyutl_main(int argc, char **argv) if (!rawin && buf_inlen > EVP_MAX_MD_SIZE && (pkey_op == EVP_PKEY_OP_SIGN - || pkey_op == EVP_PKEY_OP_VERIFY - || pkey_op == EVP_PKEY_OP_VERIFYRECOVER)) { + || pkey_op == EVP_PKEY_OP_VERIFY)) { BIO_printf(bio_err, "Error: The input data looks too long to be a hash\n"); goto end; diff --git a/apps/progs.c b/apps/progs.c new file mode 100644 index 00000000..721e8cbf --- /dev/null +++ b/apps/progs.c @@ -0,0 +1,400 @@ +/* + * WARNING: do not edit! + * Generated by apps/progs.pl + * + * 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 "progs.h" + +FUNCTION functions[] = { + {FT_general, "asn1parse", asn1parse_main, asn1parse_options}, + {FT_general, "ca", ca_main, ca_options}, +#ifndef OPENSSL_NO_SOCK + {FT_general, "ciphers", ciphers_main, ciphers_options}, +#endif +#ifndef OPENSSL_NO_CMS + {FT_general, "cms", cms_main, cms_options}, +#endif + {FT_general, "crl", crl_main, crl_options}, + {FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options}, + {FT_general, "dgst", dgst_main, dgst_options}, +#ifndef OPENSSL_NO_DH + {FT_general, "dhparam", dhparam_main, dhparam_options}, +#endif +#ifndef OPENSSL_NO_DSA + {FT_general, "dsa", dsa_main, dsa_options}, +#endif +#ifndef OPENSSL_NO_DSA + {FT_general, "dsaparam", dsaparam_main, dsaparam_options}, +#endif +#ifndef OPENSSL_NO_EC + {FT_general, "ec", ec_main, ec_options}, +#endif +#ifndef OPENSSL_NO_EC + {FT_general, "ecparam", ecparam_main, ecparam_options}, +#endif + {FT_general, "enc", enc_main, enc_options}, +#ifndef OPENSSL_NO_ENGINE + {FT_general, "engine", engine_main, engine_options}, +#endif + {FT_general, "errstr", errstr_main, errstr_options}, + {FT_general, "fipsinstall", fipsinstall_main, fipsinstall_options}, +#ifndef OPENSSL_NO_DSA + {FT_general, "gendsa", gendsa_main, gendsa_options}, +#endif + {FT_general, "genpkey", genpkey_main, genpkey_options}, +#ifndef OPENSSL_NO_RSA + {FT_general, "genrsa", genrsa_main, genrsa_options}, +#endif + {FT_general, "help", help_main, help_options}, + {FT_general, "info", info_main, info_options}, + {FT_general, "kdf", kdf_main, kdf_options}, + {FT_general, "list", list_main, list_options}, + {FT_general, "mac", mac_main, mac_options}, + {FT_general, "nseq", nseq_main, nseq_options}, +#ifndef OPENSSL_NO_OCSP + {FT_general, "ocsp", ocsp_main, ocsp_options}, +#endif + {FT_general, "passwd", passwd_main, passwd_options}, +#ifndef OPENSSL_NO_DES + {FT_general, "pkcs12", pkcs12_main, pkcs12_options}, +#endif + {FT_general, "pkcs7", pkcs7_main, pkcs7_options}, + {FT_general, "pkcs8", pkcs8_main, pkcs8_options}, + {FT_general, "pkey", pkey_main, pkey_options}, + {FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options}, + {FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options}, + {FT_general, "prime", prime_main, prime_options}, + {FT_general, "provider", provider_main, provider_options}, + {FT_general, "rand", rand_main, rand_options}, + {FT_general, "rehash", rehash_main, rehash_options}, + {FT_general, "req", req_main, req_options}, + {FT_general, "rsa", rsa_main, rsa_options}, +#ifndef OPENSSL_NO_RSA + {FT_general, "rsautl", rsautl_main, rsautl_options}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_client", s_client_main, s_client_options}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_server", s_server_main, s_server_options}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_time", s_time_main, s_time_options}, +#endif + {FT_general, "sess_id", sess_id_main, sess_id_options}, + {FT_general, "smime", smime_main, smime_options}, + {FT_general, "speed", speed_main, speed_options}, + {FT_general, "spkac", spkac_main, spkac_options}, +#ifndef OPENSSL_NO_SRP + {FT_general, "srp", srp_main, srp_options}, +#endif + {FT_general, "storeutl", storeutl_main, storeutl_options}, +#ifndef OPENSSL_NO_TS + {FT_general, "ts", ts_main, ts_options}, +#endif + {FT_general, "verify", verify_main, verify_options}, + {FT_general, "version", version_main, version_options}, + {FT_general, "x509", x509_main, x509_options}, +#ifndef OPENSSL_NO_MD2 + {FT_md, "md2", dgst_main}, +#endif +#ifndef OPENSSL_NO_MD4 + {FT_md, "md4", dgst_main}, +#endif + {FT_md, "md5", dgst_main}, +#ifndef OPENSSL_NO_GOST + {FT_md, "gost", dgst_main}, +#endif + {FT_md, "sha1", dgst_main}, + {FT_md, "sha224", dgst_main}, + {FT_md, "sha256", dgst_main}, + {FT_md, "sha384", dgst_main}, + {FT_md, "sha512", dgst_main}, + {FT_md, "sha512-224", dgst_main}, + {FT_md, "sha512-256", dgst_main}, + {FT_md, "sha3-224", dgst_main}, + {FT_md, "sha3-256", dgst_main}, + {FT_md, "sha3-384", dgst_main}, + {FT_md, "sha3-512", dgst_main}, + {FT_md, "shake128", dgst_main}, + {FT_md, "shake256", dgst_main}, +#ifndef OPENSSL_NO_MDC2 + {FT_md, "mdc2", dgst_main}, +#endif +#ifndef OPENSSL_NO_RMD160 + {FT_md, "rmd160", dgst_main}, +#endif +#ifndef OPENSSL_NO_BLAKE2 + {FT_md, "blake2b512", dgst_main}, +#endif +#ifndef OPENSSL_NO_BLAKE2 + {FT_md, "blake2s256", dgst_main}, +#endif +#ifndef OPENSSL_NO_SM3 + {FT_md, "sm3", dgst_main}, +#endif + {FT_cipher, "aes-128-cbc", enc_main, enc_options}, + {FT_cipher, "aes-128-ecb", enc_main, enc_options}, + {FT_cipher, "aes-192-cbc", enc_main, enc_options}, + {FT_cipher, "aes-192-ecb", enc_main, enc_options}, + {FT_cipher, "aes-256-cbc", enc_main, enc_options}, + {FT_cipher, "aes-256-ecb", enc_main, enc_options}, +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ctr", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb1", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb8", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ctr", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb1", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb8", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ctr", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb1", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb8", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-128-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-128-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-192-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-192-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-256-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-256-ecb", enc_main, enc_options}, +#endif + {FT_cipher, "base64", enc_main, enc_options}, +#ifdef ZLIB + {FT_cipher, "zlib", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des3", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "desx", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC4 + {FT_cipher, "rc4", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC4 + {FT_cipher, "rc4-40", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-64-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-40-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-cbc", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ecb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-cfb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ofb", enc_main, enc_options}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ctr", enc_main, enc_options}, +#endif + {0, NULL, NULL} +}; diff --git a/apps/progs.pl b/apps/progs.pl index 3aec7562..1b304a03 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -14,6 +14,10 @@ use warnings; use lib '.'; use configdata qw/@disablables %unified_info/; +my $opt = shift @ARGV; +die "Unrecognised option, must be -C or -H\n" + unless ($opt eq '-H' || $opt eq '-C'); + my %commands = (); my $cmdre = qr/^\s*int\s+([a-z_][a-z0-9_]*)_main\(\s*int\s+argc\s*,/; my $apps_openssl = shift @ARGV; @@ -38,7 +42,8 @@ foreach my $filename (@openssl_source) { @ARGV = sort keys %commands; -print <<"EOF"; +if ($opt eq '-H') { + print <<"EOF"; /* * WARNING: do not edit! * Generated by apps/progs.pl @@ -51,134 +56,139 @@ print <<"EOF"; * https://www.openssl.org/source/license.html */ -#include -#include "opt.h" - -typedef enum FUNC_TYPE { - FT_none, FT_general, FT_md, FT_cipher, FT_pkey, - FT_md_alg, FT_cipher_alg -} FUNC_TYPE; - -typedef struct function_st { - FUNC_TYPE type; - const char *name; - int (*func)(int argc, char *argv[]); - const OPTIONS *help; -} FUNCTION; - -DEFINE_LHASH_OF(FUNCTION); +#include "function.h" EOF -foreach (@ARGV) { - printf "extern int %s_main(int argc, char *argv[]);\n", $_; -} -print "\n"; - -foreach (@ARGV) { - printf "extern const OPTIONS %s_options[];\n", $_; -} -print "\n"; - -my %cmd_disabler = ( - ciphers => "sock", - genrsa => "rsa", - rsautl => "rsa", - gendsa => "dsa", - dsaparam => "dsa", - gendh => "dh", - dhparam => "dh", - ecparam => "ec", - pkcs12 => "des", -); - -print "#ifdef INCLUDE_FUNCTION_TABLE\n"; -print "static FUNCTION functions[] = {\n"; -foreach my $cmd ( @ARGV ) { - my $str = " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options},\n"; - if ($cmd =~ /^s_/) { - print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; - } elsif (grep { $cmd eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; - } elsif (my $disabler = $cmd_disabler{$cmd}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; + foreach (@ARGV) { + printf "extern int %s_main(int argc, char *argv[]);\n", $_; } -} + print "\n"; -my %md_disabler = ( - blake2b512 => "blake2", - blake2s256 => "blake2", -); -foreach my $cmd ( - "md2", "md4", "md5", - "gost", - "sha1", "sha224", "sha256", "sha384", - "sha512", "sha512-224", "sha512-256", - "sha3-224", "sha3-256", "sha3-384", "sha3-512", - "shake128", "shake256", - "mdc2", "rmd160", "blake2b512", "blake2s256", - "sm3" -) { - my $str = " {FT_md, \"$cmd\", dgst_main},\n"; - if (grep { $cmd eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; - } elsif (my $disabler = $md_disabler{$cmd}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; + foreach (@ARGV) { + printf "extern const OPTIONS %s_options[];\n", $_; } + print "\n"; + print "extern FUNCTION functions[];\n"; } -my %cipher_disabler = ( - des3 => "des", - desx => "des", - cast5 => "cast", -); -foreach my $cmd ( - "aes-128-cbc", "aes-128-ecb", - "aes-192-cbc", "aes-192-ecb", - "aes-256-cbc", "aes-256-ecb", - "aria-128-cbc", "aria-128-cfb", - "aria-128-ctr", "aria-128-ecb", "aria-128-ofb", - "aria-128-cfb1", "aria-128-cfb8", - "aria-192-cbc", "aria-192-cfb", - "aria-192-ctr", "aria-192-ecb", "aria-192-ofb", - "aria-192-cfb1", "aria-192-cfb8", - "aria-256-cbc", "aria-256-cfb", - "aria-256-ctr", "aria-256-ecb", "aria-256-ofb", - "aria-256-cfb1", "aria-256-cfb8", - "camellia-128-cbc", "camellia-128-ecb", - "camellia-192-cbc", "camellia-192-ecb", - "camellia-256-cbc", "camellia-256-ecb", - "base64", "zlib", - "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", - "rc2", "bf", "cast", "rc5", - "des-ecb", "des-ede", "des-ede3", - "des-cbc", "des-ede-cbc","des-ede3-cbc", - "des-cfb", "des-ede-cfb","des-ede3-cfb", - "des-ofb", "des-ede-ofb","des-ede3-ofb", - "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", - "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", - "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", - "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", - "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", - "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb", - "sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr" -) { - my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options},\n"; - (my $algo = $cmd) =~ s/-.*//g; - if ($cmd eq "zlib") { - print "#ifdef ZLIB\n${str}#endif\n"; - } elsif (grep { $algo eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; - } elsif (my $disabler = $cipher_disabler{$algo}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; +if ($opt eq '-C') { + print <<"EOF"; +/* + * WARNING: do not edit! + * Generated by apps/progs.pl + * + * Copyright 1995-$YEAR 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 "progs.h" + +EOF + + my %cmd_disabler = ( + ciphers => "sock", + genrsa => "rsa", + rsautl => "rsa", + gendsa => "dsa", + dsaparam => "dsa", + gendh => "dh", + dhparam => "dh", + ecparam => "ec", + pkcs12 => "des", + ); + + print "FUNCTION functions[] = {\n"; + foreach my $cmd ( @ARGV ) { + my $str = + " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options},\n"; + if ($cmd =~ /^s_/) { + print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; + } elsif (grep { $cmd eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; + } elsif (my $disabler = $cmd_disabler{$cmd}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } } -} -print " {0, NULL, NULL}\n};\n"; -print "#endif\n"; + my %md_disabler = ( + blake2b512 => "blake2", + blake2s256 => "blake2", + ); + foreach my $cmd ( + "md2", "md4", "md5", + "gost", + "sha1", "sha224", "sha256", "sha384", + "sha512", "sha512-224", "sha512-256", + "sha3-224", "sha3-256", "sha3-384", "sha3-512", + "shake128", "shake256", + "mdc2", "rmd160", "blake2b512", "blake2s256", + "sm3" + ) { + my $str = " {FT_md, \"$cmd\", dgst_main},\n"; + if (grep { $cmd eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; + } elsif (my $disabler = $md_disabler{$cmd}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } + } + + my %cipher_disabler = ( + des3 => "des", + desx => "des", + cast5 => "cast", + ); + foreach my $cmd ( + "aes-128-cbc", "aes-128-ecb", + "aes-192-cbc", "aes-192-ecb", + "aes-256-cbc", "aes-256-ecb", + "aria-128-cbc", "aria-128-cfb", + "aria-128-ctr", "aria-128-ecb", "aria-128-ofb", + "aria-128-cfb1", "aria-128-cfb8", + "aria-192-cbc", "aria-192-cfb", + "aria-192-ctr", "aria-192-ecb", "aria-192-ofb", + "aria-192-cfb1", "aria-192-cfb8", + "aria-256-cbc", "aria-256-cfb", + "aria-256-ctr", "aria-256-ecb", "aria-256-ofb", + "aria-256-cfb1", "aria-256-cfb8", + "camellia-128-cbc", "camellia-128-ecb", + "camellia-192-cbc", "camellia-192-ecb", + "camellia-256-cbc", "camellia-256-ecb", + "base64", "zlib", + "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", + "rc2", "bf", "cast", "rc5", + "des-ecb", "des-ede", "des-ede3", + "des-cbc", "des-ede-cbc","des-ede3-cbc", + "des-cfb", "des-ede-cfb","des-ede3-cfb", + "des-ofb", "des-ede-ofb","des-ede3-ofb", + "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", + "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", + "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", + "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", + "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", + "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb", + "sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr" + ) { + my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options},\n"; + (my $algo = $cmd) =~ s/-.*//g; + if ($cmd eq "zlib") { + print "#ifdef ZLIB\n${str}#endif\n"; + } elsif (grep { $algo eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; + } elsif (my $disabler = $cipher_disabler{$algo}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } + } + + print " {0, NULL, NULL}\n};\n"; +} diff --git a/apps/provider.c b/apps/provider.c new file mode 100644 index 00000000..fe5ca1d1 --- /dev/null +++ b/apps/provider.c @@ -0,0 +1,287 @@ +/* + * 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 "apps.h" +#include "app_params.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_V = 100, OPT_VV, OPT_VVV +} OPTION_CHOICE; + +const OPTIONS provider_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] provider...\n"}, + {OPT_HELP_STR, 1, '-', " provider... Providers to load\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"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"}, + {NULL} +}; + +typedef struct info_st INFO; +typedef struct meta_st META; + +struct info_st { + const char *name; + void *method; + const OSSL_PARAM *gettable_params; + const OSSL_PARAM *gettable_ctx_params; + const OSSL_PARAM *settable_ctx_params; +}; + +struct meta_st { + int first; /* For prints */ + int total; + int indent; + int subindent; + int verbose; + const char *label; + OSSL_PROVIDER *prov; + void (*fn)(META *meta, INFO *info); +}; + +static void print_caps(META *meta, INFO *info) +{ + switch (meta->verbose) { + case 1: + BIO_printf(bio_out, meta->first ? "%s" : " %s", info->name); + break; + case 2: + if (meta->first) { + if (meta->total > 0) + BIO_printf(bio_out, "\n"); + BIO_printf(bio_out, "%*s%ss:", meta->indent, "", meta->label); + } + BIO_printf(bio_out, " %s", info->name); + break; + case 3: + default: + BIO_printf(bio_out, "%*s%s %s\n", meta->indent, "", meta->label, + info->name); + print_param_types("retrievable algorithm parameters", + info->gettable_params, meta->subindent); + print_param_types("retrievable operation parameters", + info->gettable_ctx_params, meta->subindent); + print_param_types("settable operation parameters", + info->settable_ctx_params, meta->subindent); + break; + } + meta->first = 0; +} + +static void do_method(void *method, const char *name, + const OSSL_PARAM *gettable_params, + const OSSL_PARAM *gettable_ctx_params, + const OSSL_PARAM *settable_ctx_params, + META *meta) +{ + INFO info; + + info.name = name; + info.method = method; + info.gettable_params = gettable_params; + info.gettable_ctx_params = gettable_ctx_params; + info.settable_ctx_params = settable_ctx_params; + meta->fn(meta, &info); + meta->total++; +} + +static void do_cipher(EVP_CIPHER *cipher, void *meta) +{ + do_method(cipher, EVP_CIPHER_name(cipher), + EVP_CIPHER_gettable_params(cipher), + EVP_CIPHER_CTX_gettable_params(cipher), + EVP_CIPHER_CTX_settable_params(cipher), + meta); +} + +static void do_digest(EVP_MD *digest, void *meta) +{ + do_method(digest, EVP_MD_name(digest), + EVP_MD_gettable_params(digest), + EVP_MD_CTX_gettable_params(digest), + EVP_MD_CTX_settable_params(digest), + meta); +} + +static void do_mac(EVP_MAC *mac, void *meta) +{ + do_method(mac, EVP_MAC_name(mac), + EVP_MAC_gettable_params(mac), + EVP_MAC_CTX_gettable_params(mac), + EVP_MAC_CTX_settable_params(mac), + meta); +} + +/* + * TODO(3.0) Enable when KEYMGMT and KEYEXCH have gettables and settables + */ +#if 0 +static void do_keymgmt(EVP_KEYMGMT *keymgmt, void *meta) +{ + do_method(keymgmt, EVP_KEYMGMT_name(keymgmt), + EVP_KEYMGMT_gettable_params(keymgmt), + EVP_KEYMGMT_gettable_ctx_params(keymgmt), + EVP_KEYMGMT_settable_ctx_params(keymgmt), + meta); +} + +static void do_keyexch(EVP_KEYEXCH *keyexch, void *meta) +{ + do_method(keyexch, EVP_KEYEXCH_name(keyexch), + EVP_KEYEXCH_gettable_params(keyexch), + EVP_KEYEXCH_gettable_ctx_params(keyexch), + EVP_KEYEXCH_settable_ctx_params(keyexch), + meta); +} +#endif + +int provider_main(int argc, char **argv) +{ + int ret = 1, i; + int verbose = 0; + STACK_OF(OPENSSL_CSTRING) *providers = sk_OPENSSL_CSTRING_new_null(); + OPTION_CHOICE o; + char *prog; + + prog = opt_init(argc, argv, provider_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + default: /* Catching OPT_ERR & covering OPT_EOF which isn't possible */ + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(provider_options); + ret = 0; + goto end; + case OPT_VVV: + case OPT_VV: + case OPT_V: + /* Convert to an integer from one to four. */ + i = (int)(o - OPT_V) + 1; + if (verbose < i) + verbose = i; + break; + } + } + + /* Allow any trailing parameters as provider names. */ + argc = opt_num_rest(); + argv = opt_rest(); + for ( ; *argv; argv++) { + if (**argv == '-') { + BIO_printf(bio_err, "%s: Cannot mix flags and provider names.\n", + prog); + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + } + sk_OPENSSL_CSTRING_push(providers, *argv); + } + + ret = 0; + for (i = 0; i < sk_OPENSSL_CSTRING_num(providers); i++) { + const char *name = sk_OPENSSL_CSTRING_value(providers, i); + OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, name); + + if (prov != NULL) { + BIO_printf(bio_out, verbose == 0 ? "%s\n" : "[ %s ]\n", name); + + if (verbose > 0) { + META data; + + data.total = 0; + data.first = 1; + data.verbose = verbose; + data.prov = prov; + data.fn = print_caps; + + switch (verbose) { + case 1: + BIO_printf(bio_out, " "); + break; + case 2: + data.indent = 4; + break; + case 3: + default: + data.indent = 4; + data.subindent = 10; + break; + } + + if (verbose > 1) { + data.first = 1; + data.label = "Cipher"; + } + EVP_CIPHER_do_all_ex(NULL, do_cipher, &data); + if (verbose > 1) { + data.first = 1; + data.label = "Digest"; + } + EVP_MD_do_all_ex(NULL, do_digest, &data); + if (verbose > 1) { + data.first = 1; + data.label = "MAC"; + } + EVP_MAC_do_all_ex(NULL, do_mac, &data); + +/* + * TODO(3.0) Enable when KEYMGMT and KEYEXCH have do_all_ex functions + */ +#if 0 + if (verbose > 1) { + data.first = 1; + data.label = "Key manager"; + } + EVP_KEYMGMT_do_all_ex(NULL, do_keymgmt, &data); + if (verbose > 1) { + data.first = 1; + data.label = "Key exchange"; + } + EVP_KEYEXCH_do_all_ex(NULL, do_keyexch, &data); +#endif + + switch (verbose) { + default: + break; + case 2: + case 1: + BIO_printf(bio_out, "\n"); + break; + } + } + OSSL_PROVIDER_unload(prov); + } else { + ERR_print_errors(bio_err); + ret = 1; + /* + * Just because one provider module failed, there's no reason to + * stop, if there are more to try. + */ + } + } + + end: + + ERR_print_errors(bio_err); + sk_OPENSSL_CSTRING_free(providers); + return ret; +} diff --git a/apps/rsa.c b/apps/rsa.c index 78958e05..7c0620c6 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -227,7 +227,6 @@ int rsa_main(int argc, char **argv) while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && - ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY_EX && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); diff --git a/apps/s_client.c b/apps/s_client.c index 6f2d133d..016df7c6 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -2017,7 +2017,7 @@ int s_client_main(int argc, char **argv) if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) { if (servername == NULL) { - if(host == NULL || is_dNS_name(host)) + if(host == NULL || is_dNS_name(host)) servername = (host == NULL) ? "localhost" : host; } if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) { @@ -3104,7 +3104,7 @@ int s_client_main(int argc, char **argv) BIO_printf(bio_err, "RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len = 0; - } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) + } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) && cmdletters) { BIO_printf(bio_err, "KEYUPDATE\n"); SSL_key_update(con, @@ -3552,7 +3552,7 @@ static char *base64encode (const void *buf, size_t len) } /* - * Host dNS Name verifier: used for checking that the hostname is in dNS format + * Host dNS Name verifier: used for checking that the hostname is in dNS format * before setting it as SNI */ static int is_dNS_name(const char *host) diff --git a/apps/s_server.c b/apps/s_server.c index 3ded4f88..28937bd8 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -470,7 +470,7 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) BIO_printf(p->biodebug, "Hostname in TLS extension: \""); while ((uc = *cp++) != 0) BIO_printf(p->biodebug, - isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc); + (((uc) & ~127) == 0) && isprint(uc) ? "%c" : "\\x%02x", uc); BIO_printf(p->biodebug, "\"\n"); } diff --git a/apps/speed.c b/apps/speed.c index a5e9d443..59594f0e 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -3114,7 +3114,6 @@ int speed_main(int argc, char **argv) if (error == ERR_peek_last_error() && /* oldest and latest errors match */ /* check that the error origin matches */ ERR_GET_LIB(error) == ERR_LIB_EVP && - ERR_GET_FUNC(error) == EVP_F_INT_CTX_NEW && ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM) ERR_get_error(); /* pop error from queue */ if (ERR_peek_error()) { @@ -3364,6 +3363,7 @@ int speed_main(int argc, char **argv) printf("%s ", BF_options()); #endif printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS)); + printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO)); } if (pr_header) { @@ -3638,7 +3638,7 @@ static int do_multi(int multi, int size_num) close(fd[1]); mr = 1; usertime = 0; - free(fds); + OPENSSL_free(fds); return 0; } printf("Forked child %d\n", n); @@ -3750,7 +3750,7 @@ static int do_multi(int multi, int size_num) fclose(f); } - free(fds); + OPENSSL_free(fds); return 1; } #endif diff --git a/apps/version.c b/apps/version.c index 35bfb95c..7350ccf7 100644 --- a/apps/version.c +++ b/apps/version.c @@ -33,7 +33,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_B, OPT_D, OPT_E, OPT_M, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R + OPT_B, OPT_D, OPT_E, OPT_M, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R, OPT_C } OPTION_CHOICE; const OPTIONS version_options[] = { @@ -48,24 +48,15 @@ const OPTIONS version_options[] = { {"p", OPT_P, '-', "Show target build platform"}, {"r", OPT_R, '-', "Show random seeding options"}, {"v", OPT_V, '-', "Show library version"}, + {"c", OPT_C, '-', "Show CPU settings info"}, {NULL} }; -#if defined(OPENSSL_RAND_SEED_DEVRANDOM) || defined(OPENSSL_RAND_SEED_EGD) -static void printlist(const char *prefix, const char **dev) -{ - printf("%s (", prefix); - for ( ; *dev != NULL; dev++) - printf(" \"%s\"", *dev); - printf(" )"); -} -#endif - int version_main(int argc, char **argv) { int ret = 1, dirty = 0, seed = 0; int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0; - int engdir = 0, moddir = 0; + int engdir = 0, moddir = 0, cpuinfo = 0; char *prog; OPTION_CHOICE o; @@ -108,9 +99,12 @@ opthelp: case OPT_V: dirty = version = 1; break; + case OPT_C: + dirty = cpuinfo = 1; + break; case OPT_A: seed = options = cflags = version = date = platform - = dir = engdir = moddir + = dir = engdir = moddir = cpuinfo = 1; break; } @@ -158,39 +152,11 @@ opthelp: if (moddir) printf("%s\n", OpenSSL_version(OPENSSL_MODULES_DIR)); if (seed) { - printf("Seeding source:"); -#ifdef OPENSSL_RAND_SEED_RTDSC - printf(" rtdsc"); -#endif -#ifdef OPENSSL_RAND_SEED_RDCPU - printf(" rdrand ( rdseed rdrand )"); -#endif -#ifdef OPENSSL_RAND_SEED_LIBRANDOM - printf(" C-library-random"); -#endif -#ifdef OPENSSL_RAND_SEED_GETRANDOM - printf(" getrandom-syscall"); -#endif -#ifdef OPENSSL_RAND_SEED_DEVRANDOM - { - static const char *dev[] = { DEVRANDOM, NULL }; - printlist(" random-device", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_EGD - { - static const char *dev[] = { DEVRANDOM_EGD, NULL }; - printlist(" EGD", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_NONE - printf(" none"); -#endif -#ifdef OPENSSL_RAND_SEED_OS - printf(" os-specific"); -#endif - printf("\n"); + const char *src = OPENSSL_info(OPENSSL_INFO_SEED_SOURCE); + printf("Seeding source: %s\n", src ? src : "N/A"); } + if (cpuinfo) + printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO)); ret = 0; end: return ret; diff --git a/appveyor.yml b/appveyor.yml index 24966c0f..ab4444d6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -53,9 +53,9 @@ test_script: - ps: >- If ($env:Configuration -Match "shared" -or $env:EXTENDED_TESTS) { if ($env:EXTENDED_TESTS) { - cmd /c "nmake test V=1 2>&1" + cmd /c "nmake test HARNESS_VERBOSE_FAILURE=yes 2>&1" } Else { - cmd /c "nmake test V=1 TESTS=-test_fuzz 2>&1" + cmd /c "nmake test HARNESS_VERBOSE_FAILURE=yes TESTS=-test_fuzz 2>&1" } } - ps: >- diff --git a/configdata.pm.in b/configdata.pm.in new file mode 100644 index 00000000..6e5c1ad4 --- /dev/null +++ b/configdata.pm.in @@ -0,0 +1,418 @@ +#! {- $config{HASHBANGPERL} -} +# -*- mode: perl -*- +{- + sub out_item { + my $ref = shift; + # Available options: + # indent => callers indentation (int) + # delimiters => 1 if outer delimiters should be added + my %opts = @_; + + my $indent = $opts{indent} // 0; + # Indentation of the whole structure, where applicable + my $nlindent1 = "\n" . ' ' x $indent; + # Indentation of individual items, where applicable + my $nlindent2 = "\n" . ' ' x ($indent + 4); + + my $product; # Finished product, or reference to a function that + # produces a string, given $_ + # The following are only used when $product is a function reference + my $delim_l; # Left delimiter of structure + my $delim_r; # Right delimiter of structure + my $separator; # Item separator + my @items; # Items to iterate over + + if (ref($ref) eq "ARRAY") { + if (scalar @$ref == 0) { + $product = $opts{delimiters} ? '[]' : ''; + } else { + $product = sub { + out_item(\$_, delimiters => 1, indent => $indent + 4) + }; + $delim_l = ($opts{delimiters} ? '[' : '').$nlindent2; + $delim_r = $nlindent1.($opts{delimiters} ? ']' : ''); + $separator = ",$nlindent2"; + @items = @$ref; + } + } elsif (ref($ref) eq "HASH") { + if (scalar keys %$ref == 0) { + $product = $opts{delimiters} ? '{}' : ''; + } else { + $product = sub { + quotify1($_) . " => " + . out_item($ref->{$_}, delimiters => 1, indent => $indent + 4) + }; + $delim_l = ($opts{delimiters} ? '{' : '').$nlindent2; + $delim_r = $nlindent1.($opts{delimiters} ? '}' : ''); + $separator = ",$nlindent2"; + @items = sort keys %$ref; + } + } elsif (ref($ref) eq "SCALAR") { + $product = defined $$ref ? quotify1 $$ref : "undef"; + } else { + $product = defined $ref ? quotify1 $ref : "undef"; + } + + if (ref($product) eq "CODE") { + $delim_l . join($separator, map { &$product } @items) . $delim_r; + } else { + $product; + } + } + + # We must make sourcedir() return an absolute path, because configdata.pm + # may be loaded as a module from any script in any directory, making + # relative paths untrustable. Because the result is used with 'use lib', + # we must ensure that it returns a Unix style path. Cwd::abs_path does + # that (File::Spec::Functions::rel2abs return O/S specific paths) + use File::Spec::Functions; + use Cwd qw(abs_path); + sub sourcedir { + return abs_path(catdir($config{sourcedir}, @_)); + } + sub sourcefile { + return abs_path(catfile($config{sourcedir}, @_)); + } +-} +package configdata; + +use strict; +use warnings; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw( + %config %target %disabled %withargs %unified_info + @disablables @disablables_int +); + +our %config = ({- out_item(\%config); -}); +our %target = ({- out_item(\%target); -}); +our @disablables = ({- out_item(\@disablables) -}); +our @disablables_int = ({- out_item(\@disablables_int) -}); +our %disabled = ({- out_item(\%disabled); -}); +our %withargs = ({- out_item(\%withargs); -}); +our %unified_info = ({- out_item(\%unified_info); -}); + +# Unexported, only used by OpenSSL::Test::Utils::available_protocols() +our %available_protocols = ( + tls => [{- out_item(\@tls) -}], + dtls => [{- out_item(\@dtls) -}], +); + +# The following data is only used when this files is use as a script +my @makevars = ({- out_item(\@makevars); -}); +my %disabled_info = ({- out_item(\%disabled_info); -}); +my @user_crossable = qw( {- join (' ', @user_crossable) -} ); + +# If run directly, we can give some answers, and even reconfigure +unless (caller) { + use Getopt::Long; + use File::Spec::Functions; + use File::Basename; + use Pod::Usage; + + my $here = dirname($0); + + if (scalar @ARGV == 0) { + # With no arguments, re-create the build file + + use lib '{- sourcedir('util', 'perl') -}'; + use OpenSSL::fallback '{- sourcefile('external', 'perl', 'MODULES.txt') -}'; + use OpenSSL::Template; + + 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; +_____ + + my @autowarntext = ( + 'WARNING: do not edit!', + "Generated by configdata.pm from " + .join(", ", @{$config{build_file_templates}}) + ); + + print 'Creating ',$target{build_file},"\n"; + open BUILDFILE, ">$target{build_file}.new" + or die "Trying to create $target{build_file}.new: $!"; + foreach (@{$config{build_file_templates}}) { + my $tmpl = OpenSSL::Template->new(TYPE => 'FILE', + SOURCE => $_); + $tmpl->fill_in(FILENAME => $_, + OUTPUT => \*BUILDFILE, + HASH => { config => \%config, + target => \%target, + disabled => \%disabled, + withargs => \%withargs, + unified_info => \%unified_info, + autowarntext => \@autowarntext }, + PREPEND => $prepend, + # To ensure that global variables and functions + # defined in one template stick around for the + # next, making them combinable + PACKAGE => 'OpenSSL::safe') + or die $Text::Template::ERROR; + } + close BUILDFILE; + rename("$target{build_file}.new", $target{build_file}) + or die "Trying to rename $target{build_file}.new to $target{build_file}: $!"; + + exit(0); + } + + my $dump = undef; + my $cmdline = undef; + my $options = undef; + my $target = undef; + my $envvars = undef; + my $makevars = undef; + my $buildparams = undef; + my $reconf = undef; + my $verbose = undef; + my $help = undef; + my $man = undef; + GetOptions('dump|d' => \$dump, + 'command-line|c' => \$cmdline, + 'options|o' => \$options, + 'target|t' => \$target, + 'environment|e' => \$envvars, + 'make-variables|m' => \$makevars, + 'build-parameters|b' => \$buildparams, + 'reconfigure|reconf|r' => \$reconf, + 'verbose|v' => \$verbose, + 'help' => \$help, + 'man' => \$man) + or die "Errors in command line arguments\n"; + + if (scalar @ARGV > 0) { + print STDERR <<"_____"; +Unrecognised arguments. +For more information, do '$0 --help' +_____ + exit(2); + } + + if ($help) { + pod2usage(-exitval => 0, + -verbose => 1); + } + if ($man) { + pod2usage(-exitval => 0, + -verbose => 2); + } + if ($dump || $cmdline) { + print "\nCommand line (with current working directory = $here):\n\n"; + print ' ',join(' ', + $config{PERL}, + catfile($config{sourcedir}, 'Configure'), + @{$config{perlargv}}), "\n"; + print "\nPerl information:\n\n"; + print ' ',$config{perl_cmd},"\n"; + print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; + } + if ($dump || $options) { + my $longest = 0; + my $longest2 = 0; + foreach my $what (@disablables) { + $longest = length($what) if $longest < length($what); + $longest2 = length($disabled{$what}) + if $disabled{$what} && $longest2 < length($disabled{$what}); + } + print "\nEnabled features:\n\n"; + foreach my $what (@disablables) { + print " $what\n" unless $disabled{$what}; + } + print "\nDisabled features:\n\n"; + foreach my $what (@disablables) { + if ($disabled{$what}) { + print " $what", ' ' x ($longest - length($what) + 1), + "[$disabled{$what}]", ' ' x ($longest2 - length($disabled{$what}) + 1); + print $disabled_info{$what}->{macro} + if $disabled_info{$what}->{macro}; + print ' (skip ', + join(', ', @{$disabled_info{$what}->{skipped}}), + ')' + if $disabled_info{$what}->{skipped}; + print "\n"; + } + } + } + if ($dump || $target) { + print "\nConfig target attributes:\n\n"; + foreach (sort keys %target) { + next if $_ =~ m|^_| || $_ eq 'template'; + my $quotify = sub { + map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; + }; + print ' ', $_, ' => '; + if (ref($target{$_}) eq "ARRAY") { + print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; + } else { + print $quotify->($target{$_}), ",\n" + } + } + } + if ($dump || $envvars) { + print "\nRecorded environment:\n\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; + } + } + if ($dump || $makevars) { + print "\nMakevars:\n\n"; + foreach my $var (@makevars) { + my $prefix = ''; + $prefix = $config{CROSS_COMPILE} + if grep { $var eq $_ } @user_crossable; + $prefix //= ''; + print ' ',$var,' ' x (16 - length $var),'= ', + (ref $config{$var} eq 'ARRAY' + ? join(' ', @{$config{$var}}) + : $prefix.$config{$var}), + "\n" + if defined $config{$var}; + } + + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + my $buildfile = canonpath(catdir(@buildfile)); + print <<"_____"; + +NOTE: These variables only represent the configuration view. The build file +template may have processed these variables further, please have a look at the +build file for more exact data: + $buildfile +_____ + } + if ($dump || $buildparams) { + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + print "\nbuild file:\n\n"; + print " ", canonpath(catfile(@buildfile)),"\n"; + + print "\nbuild file templates:\n\n"; + foreach (@{$config{build_file_templates}}) { + my @tmpl = ($_); + unshift @tmpl, $here + unless file_name_is_absolute($config{sourcedir}); + print ' ',canonpath(catfile(@tmpl)),"\n"; + } + } + if ($reconf) { + if ($verbose) { + print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; + } + } + + chdir $here; + exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; + } +} + +1; + +__END__ + +=head1 NAME + +configdata.pm - configuration data for OpenSSL builds + +=head1 SYNOPSIS + +Interactive: + + perl configdata.pm [options] + +As data bank module: + + use configdata; + +=head1 DESCRIPTION + +This module can be used in two modes, interactively and as a module containing +all the data recorded by OpenSSL's Configure script. + +When used interactively, simply run it as any perl script. +If run with no arguments, it will rebuild the build file (Makefile or +corresponding). +With at least one option, it will instead get the information you ask for, or +re-run the configuration process. +See L below for more information. + +When loaded as a module, you get a few databanks with useful information to +perform build related tasks. The databanks are: + + %config Configured things. + %target The OpenSSL config target with all inheritances + resolved. + %disabled The features that are disabled. + @disablables The list of features that can be disabled. + %withargs All data given through --with-THING options. + %unified_info All information that was computed from the build.info + files. + +=head1 OPTIONS + +=over 4 + +=item B<--help> + +Print a brief help message and exit. + +=item B<--man> + +Print the manual page and exit. + +=item B<--dump> | B<-d> + +Print all relevant configuration data. This is equivalent to B<--command-line> +B<--options> B<--target> B<--environment> B<--make-variables> +B<--build-parameters>. + +=item B<--command-line> | B<-c> + +Print the current configuration command line. + +=item B<--options> | B<-o> + +Print the features, both enabled and disabled, and display defined macro and +skipped directories where applicable. + +=item B<--target> | B<-t> + +Print the config attributes for this config target. + +=item B<--environment> | B<-e> + +Print the environment variables and their values at the time of configuration. + +=item B<--make-variables> | B<-m> + +Print the main make variables generated in the current configuration + +=item B<--build-parameters> | B<-b> + +Print the build parameters, i.e. build file and build file templates. + +=item B<--reconfigure> | B<--reconf> | B<-r> + +Re-run the configuration process. + +=item B<--verbose> | B<-v> + +Verbose output. + +=back + +=cut + +EOF diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl index 514a0673..1fe8245f 100755 --- a/crypto/aes/asm/aes-586.pl +++ b/crypto/aes/asm/aes-586.pl @@ -198,9 +198,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); &static_label("AES_Te"); diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl index 456a4696..9367f1f3 100644 --- a/crypto/aes/asm/aes-armv4.pl +++ b/crypto/aes/asm/aes-armv4.pl @@ -39,9 +39,10 @@ # Profiler-assisted and platform-specific optimization resulted in 16% # improvement on Cortex A8 core and ~21.5 cycles per byte. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -49,9 +50,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $s0="r0"; diff --git a/crypto/aes/asm/aes-c64xplus.pl b/crypto/aes/asm/aes-c64xplus.pl index b418c577..d290afc0 100644 --- a/crypto/aes/asm/aes-c64xplus.pl +++ b/crypto/aes/asm/aes-c64xplus.pl @@ -37,8 +37,7 @@ # cost of 8x increased pressure on L1D. 8x because you'd have # to interleave both Te and Td tables... -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($TEA,$TEB)=("A5","B5"); ($KPA,$KPB)=("A3","B1"); diff --git a/crypto/aes/asm/aes-mips.pl b/crypto/aes/asm/aes-mips.pl index c93edc6e..c64933e9 100644 --- a/crypto/aes/asm/aes-mips.pl +++ b/crypto/aes/asm/aes-mips.pl @@ -65,8 +65,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; +$flavour ||= "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 if ($flavour =~ /64|n32/i) { $PTR_LA="dla"; @@ -95,17 +99,13 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2; $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } -open STDOUT,">$output"; - if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; - my ($MSB,$LSB)=(0,3); # automatically converted to little-endian +$output and open STDOUT,">$output"; + $code.=<<___; #include "mips_arch.h" diff --git a/crypto/aes/asm/aes-parisc.pl b/crypto/aes/asm/aes-parisc.pl index b962e999..96ba9986 100644 --- a/crypto/aes/asm/aes-parisc.pl +++ b/crypto/aes/asm/aes-parisc.pl @@ -28,9 +28,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/aes/asm/aes-ppc.pl b/crypto/aes/asm/aes-ppc.pl index 8a3110a9..b235b00b 100644 --- a/crypto/aes/asm/aes-ppc.pl +++ b/crypto/aes/asm/aes-ppc.pl @@ -36,7 +36,10 @@ # ppc_AES_encrypt_compact operates at 42 cycles per byte, while # ppc_AES_decrypt_compact - at 55 (in 64-bit build). -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -59,7 +62,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=32*$SIZE_T; diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl index 9a150918..1affce3f 100644 --- a/crypto/aes/asm/aes-s390x.pl +++ b/crypto/aes/asm/aes-s390x.pl @@ -89,7 +89,10 @@ # instructions, which deliver ~70% improvement at 8KB block size over # vanilla km-based code, 37% - at most like 512-bytes block size. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -99,8 +102,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $softonly=0; # allow hardware support diff --git a/crypto/aes/asm/aes-sparcv9.pl b/crypto/aes/asm/aes-sparcv9.pl index c847da36..f8063863 100755 --- a/crypto/aes/asm/aes-sparcv9.pl +++ b/crypto/aes/asm/aes-sparcv9.pl @@ -37,8 +37,7 @@ # optimal decrypt procedure]. Compared to GNU C generated code both # procedures are more than 60% faster:-) -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $frame="STACK_FRAME"; $bias="STACK_BIAS"; diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl index 6e1dcef2..6ab747d9 100755 --- a/crypto/aes/asm/aes-x86_64.pl +++ b/crypto/aes/asm/aes-x86_64.pl @@ -33,9 +33,10 @@ # # (*) with hyper-threading off -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -44,7 +45,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $verticalspin=1; # unlike 32-bit version $verticalspin performs diff --git a/crypto/aes/asm/aesfx-sparcv9.pl b/crypto/aes/asm/aesfx-sparcv9.pl index eea611d8..c59970d5 100644 --- a/crypto/aes/asm/aesfx-sparcv9.pl +++ b/crypto/aes/asm/aesfx-sparcv9.pl @@ -33,8 +33,7 @@ # instructions and improve single-block and short-input performance # with misaligned data. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; { my ($inp,$out,$key,$rounds,$tmp,$mask) = map("%o$_",(0..5)); diff --git a/crypto/aes/asm/aesni-mb-x86_64.pl b/crypto/aes/asm/aesni-mb-x86_64.pl index 7223de8a..72f55dbd 100644 --- a/crypto/aes/asm/aesni-mb-x86_64.pl +++ b/crypto/aes/asm/aesni-mb-x86_64.pl @@ -42,9 +42,10 @@ # (*) Sandy/Ivy Bridge are known to handle high interleave factors # suboptimally; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -74,7 +75,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void aesni_multi_cbc_encrypt ( diff --git a/crypto/aes/asm/aesni-sha1-x86_64.pl b/crypto/aes/asm/aesni-sha1-x86_64.pl index eb8364fe..800bd5ff 100644 --- a/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -88,9 +88,10 @@ # (**) Execution is fully dominated by integer code sequence and # SIMD still hardly shows [in single-process benchmark;-] -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -114,7 +115,8 @@ $shaext=1; ### set to zero if compiling for 1.0.1 $stitched_decrypt=0; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void aesni_cbc_sha1_enc(const void *inp, diff --git a/crypto/aes/asm/aesni-sha256-x86_64.pl b/crypto/aes/asm/aesni-sha256-x86_64.pl index e182ecc5..0a1dec77 100644 --- a/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -44,9 +44,10 @@ # -evp aes-256-cbc-hmac-sha256' will vary by percent or two; # (***) these are SHAEXT results; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -77,7 +78,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $shaext=$avx; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $func="aesni_cbc_sha256_enc"; diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl index 6b961957..2d04fd6e 100644 --- a/crypto/aes/asm/aesni-x86.pl +++ b/crypto/aes/asm/aesni-x86.pl @@ -76,9 +76,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/aes/asm/aesni-x86_64.pl b/crypto/aes/asm/aesni-x86_64.pl index 406377a6..486ebc8d 100644 --- a/crypto/aes/asm/aesni-x86_64.pl +++ b/crypto/aes/asm/aesni-x86_64.pl @@ -192,9 +192,10 @@ $PREFIX="aesni"; # if $PREFIX is set to "AES", the script # generates drop-in replacement for # crypto/aes/asm/aes-x86_64.pl:-) -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -203,7 +204,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $movkey = $PREFIX eq "aesni" ? "movups" : "movups"; diff --git a/crypto/aes/asm/aesp8-ppc.pl b/crypto/aes/asm/aesp8-ppc.pl index 44056e31..97734b4b 100755 --- a/crypto/aes/asm/aesp8-ppc.pl +++ b/crypto/aes/asm/aesp8-ppc.pl @@ -43,7 +43,10 @@ # POWER9[le] 4.02/0.86 0.84 1.05 # POWER9[be] 3.99/0.78 0.79 0.97 -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -70,7 +73,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=8*$SIZE_T; $prefix="aes_p8"; diff --git a/crypto/aes/asm/aest4-sparcv9.pl b/crypto/aes/asm/aest4-sparcv9.pl index cfbdda7d..d34a7ef0 100644 --- a/crypto/aes/asm/aest4-sparcv9.pl +++ b/crypto/aes/asm/aest4-sparcv9.pl @@ -75,8 +75,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $::evp=1; # if $evp is set to 0, script generates module with # AES_[en|de]crypt, AES_set_[en|de]crypt_key and AES_cbc_encrypt entry diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl index 3b3a53bf..c132d1d7 100755 --- a/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/aes/asm/aesv8-armx.pl @@ -56,15 +56,18 @@ # (**) numbers after slash are for 32-bit code, which is 3x- # interleaved; -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $prefix="aes_v8"; diff --git a/crypto/aes/asm/bsaes-armv7.pl b/crypto/aes/asm/bsaes-armv7.pl index 7f5219bc..b917dbf1 100644 --- a/crypto/aes/asm/bsaes-armv7.pl +++ b/crypto/aes/asm/bsaes-armv7.pl @@ -50,9 +50,10 @@ # April-August 2013 # Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -60,9 +61,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } my ($inp,$out,$len,$key)=("r0","r1","r2","r3"); diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl index 44651d43..6593f7a2 100644 --- a/crypto/aes/asm/bsaes-x86_64.pl +++ b/crypto/aes/asm/bsaes-x86_64.pl @@ -97,9 +97,10 @@ # # -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -108,7 +109,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx"); diff --git a/crypto/aes/asm/vpaes-armv8.pl b/crypto/aes/asm/vpaes-armv8.pl index c7839b32..4bf4630e 100755 --- a/crypto/aes/asm/vpaes-armv8.pl +++ b/crypto/aes/asm/vpaes-armv8.pl @@ -38,15 +38,18 @@ # code, but it's constant-time and therefore preferred; # (***) presented for reference/comparison purposes; -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; diff --git a/crypto/aes/asm/vpaes-ppc.pl b/crypto/aes/asm/vpaes-ppc.pl index f77deed2..1b839e8c 100644 --- a/crypto/aes/asm/vpaes-ppc.pl +++ b/crypto/aes/asm/vpaes-ppc.pl @@ -35,7 +35,10 @@ # (**) Inadequate POWER6 performance is due to astronomic AltiVec # latency, 9 cycles per simple logical operation. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -61,7 +64,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + || die "can't call $xlate: $!"; $code.=<<___; .machine "any" diff --git a/crypto/aes/asm/vpaes-x86.pl b/crypto/aes/asm/vpaes-x86.pl index 4a0491a6..c1417a8f 100644 --- a/crypto/aes/asm/vpaes-x86.pl +++ b/crypto/aes/asm/vpaes-x86.pl @@ -58,9 +58,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/aes/asm/vpaes-x86_64.pl b/crypto/aes/asm/vpaes-x86_64.pl index d3040031..51ff5df4 100644 --- a/crypto/aes/asm/vpaes-x86_64.pl +++ b/crypto/aes/asm/vpaes-x86_64.pl @@ -54,9 +54,10 @@ # # -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -65,7 +66,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $PREFIX="vpaes"; diff --git a/crypto/aes/build.info b/crypto/aes/build.info index 0ba1758d..aac88012 100644 --- a/crypto/aes/build.info +++ b/crypto/aes/build.info @@ -67,51 +67,48 @@ DEFINE[../../providers/fips]=$AESDEF GENERATE[aes-ia64.s]=asm/aes-ia64.S -GENERATE[aes-586.s]=asm/aes-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[aes-586.s]=asm/aes-586.pl DEPEND[aes-586.s]=../perlasm/x86asm.pl -GENERATE[vpaes-x86.s]=asm/vpaes-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[vpaes-x86.s]=asm/vpaes-x86.pl DEPEND[vpaes-586.s]=../perlasm/x86asm.pl -GENERATE[aesni-x86.s]=asm/aesni-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[aesni-x86.s]=asm/aesni-x86.pl DEPEND[aesni-586.s]=../perlasm/x86asm.pl -GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl $(PERLASM_SCHEME) +GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl +GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl +GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl +GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl +GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl +GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl +GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl -GENERATE[aes-sparcv9.S]=asm/aes-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aes-sparcv9.S]=asm/aes-sparcv9.pl INCLUDE[aes-sparcv9.o]=.. -GENERATE[aest4-sparcv9.S]=asm/aest4-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aest4-sparcv9.S]=asm/aest4-sparcv9.pl INCLUDE[aest4-sparcv9.o]=.. DEPEND[aest4-sparcv9.S]=../perlasm/sparcv9_modes.pl -GENERATE[aesfx-sparcv9.S]=asm/aesfx-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aesfx-sparcv9.S]=asm/aesfx-sparcv9.pl INCLUDE[aesfx-sparcv9.o]=.. -GENERATE[aes-ppc.s]=asm/aes-ppc.pl $(PERLASM_SCHEME) -GENERATE[vpaes-ppc.s]=asm/vpaes-ppc.pl $(PERLASM_SCHEME) -GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl $(PERLASM_SCHEME) +GENERATE[aes-ppc.s]=asm/aes-ppc.pl +GENERATE[vpaes-ppc.s]=asm/vpaes-ppc.pl +GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl -GENERATE[aes-parisc.s]=asm/aes-parisc.pl $(PERLASM_SCHEME) +GENERATE[aes-parisc.s]=asm/aes-parisc.pl -GENERATE[aes-mips.S]=asm/aes-mips.pl $(PERLASM_SCHEME) +GENERATE[aes-mips.S]=asm/aes-mips.pl INCLUDE[aes-mips.o]=.. -GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl $(PERLASM_SCHEME) +GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl INCLUDE[aesv8-armx.o]=.. -GENERATE[vpaes-armv8.S]=asm/vpaes-armv8.pl $(PERLASM_SCHEME) +GENERATE[vpaes-armv8.S]=asm/vpaes-armv8.pl -GENERATE[aes-armv4.S]=asm/aes-armv4.pl $(PERLASM_SCHEME) +GENERATE[aes-armv4.S]=asm/aes-armv4.pl INCLUDE[aes-armv4.o]=.. -GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl $(PERLASM_SCHEME) +GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl INCLUDE[bsaes-armv7.o]=.. -GENERATE[aes-s390x.S]=asm/aes-s390x.pl $(PERLASM_SCHEME) +GENERATE[aes-s390x.S]=asm/aes-s390x.pl INCLUDE[aes-s390x.o]=.. -GENERATE[aes-c64xplus.S]=asm/aes-c64xplus.pl $(PERLASM_SCHEME) +GENERATE[aes-c64xplus.S]=asm/aes-c64xplus.pl diff --git a/crypto/alphacpuid.pl b/crypto/alphacpuid.pl index 5abb82d1..50a41343 100644 --- a/crypto/alphacpuid.pl +++ b/crypto/alphacpuid.pl @@ -7,8 +7,7 @@ # https://www.openssl.org/source/license.html -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; print <<'___'; .text diff --git a/crypto/aria/aria.c b/crypto/aria/aria.c index 8cba74ef..67bd8d95 100644 --- a/crypto/aria/aria.c +++ b/crypto/aria/aria.c @@ -1007,7 +1007,7 @@ static void sl2(ARIA_c128 o, const ARIA_u128 *x, const ARIA_u128 *y) { unsigned int i; for (i = 0; i < ARIA_BLOCK_SIZE; i += 4) { - o[i ] = sb3[x->c[i ] ^ y->c[i ]]; + o[i ] = sb3[x->c[i ] ^ y->c[i ]]; o[i + 1] = sb4[x->c[i + 1] ^ y->c[i + 1]]; o[i + 2] = sb1[x->c[i + 2] ^ y->c[i + 2]]; o[i + 3] = sb2[x->c[i + 3] ^ y->c[i + 3]]; diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl index f25c6373..92027766 100755 --- a/crypto/arm64cpuid.pl +++ b/crypto/arm64cpuid.pl @@ -7,15 +7,18 @@ # https://www.openssl.org/source/license.html -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; diff --git a/crypto/armv4cpuid.pl b/crypto/armv4cpuid.pl index f8aeec64..6367cbff 100644 --- a/crypto/armv4cpuid.pl +++ b/crypto/armv4cpuid.pl @@ -7,15 +7,18 @@ # https://www.openssl.org/source/license.html -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c index 209e1ed4..630ac192 100644 --- a/crypto/asn1/a_strnid.c +++ b/crypto/asn1/a_strnid.c @@ -129,6 +129,9 @@ ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) int idx; ASN1_STRING_TABLE fnd; + /* "stable" can be impacted by config, so load the config file first */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + fnd.nid = nid; if (stable) { idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 491909b0..16f0cc3f 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -79,7 +79,11 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) char *a; int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md; struct tm tmp; - +#if defined(CHARSET_EBCDIC) + const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B; +#else + const char upper_z = 'Z', num_zero = '0', period = '.', minus = '-', plus = '+'; +#endif /* * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280 * time string format, in which: @@ -120,20 +124,20 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) if (l < min_l) goto err; for (i = 0; i < end; i++) { - if (!strict && (i == btz) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + if (!strict && (i == btz) && ((a[o] == upper_z) || (a[o] == plus) || (a[o] == minus))) { i++; break; } - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = a[o] - '0'; + n = a[o] - num_zero; /* incomplete 2-digital number */ if (++o == l) goto err; - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = (n * 10) + a[o] - '0'; + n = (n * 10) + a[o] - num_zero; /* no more bytes to read, but we haven't seen time-zone yet */ if (++o == l) goto err; @@ -185,14 +189,14 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) * Optional fractional seconds: decimal point followed by one or more * digits. */ - if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == '.') { + if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == period) { if (strict) /* RFC 5280 forbids fractional seconds */ goto err; if (++o == l) goto err; i = o; - while ((o < l) && ossl_isdigit(a[o])) + while ((o < l) && ascii_isdigit(a[o])) o++; /* Must have at least one digit after decimal point */ if (i == o) @@ -207,10 +211,10 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) * 'o' can point to '\0' is either the subsequent if or the first * else if is true. */ - if (a[o] == 'Z') { + if (a[o] == upper_z) { o++; - } else if (!strict && ((a[o] == '+') || (a[o] == '-'))) { - int offsign = a[o] == '-' ? 1 : -1; + } else if (!strict && ((a[o] == plus) || (a[o] == minus))) { + int offsign = a[o] == minus ? 1 : -1; int offset = 0; o++; @@ -223,13 +227,13 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) if (o + 4 != l) goto err; for (i = end; i < end + 2; i++) { - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = a[o] - '0'; + n = a[o] - num_zero; o++; - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = (n * 10) + a[o] - '0'; + n = (n * 10) + a[o] - num_zero; i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i; if ((n < min[i2]) || (n > max[i2])) goto err; @@ -300,7 +304,7 @@ ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); -#ifdef CHARSET_EBCDIC_not +#ifdef CHARSET_EBCDIC ebcdic2ascii(tmps->data, tmps->data, tmps->length); #endif return tmps; @@ -467,6 +471,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) char *v; int gmt = 0, l; struct tm stm; + const char upper_z = 0x5A, period = 0x2E; if (!asn1_time_to_tm(&stm, tm)) { /* asn1_time_to_tm will check the time type */ @@ -475,7 +480,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) l = tm->length; v = (char *)tm->data; - if (v[l - 1] == 'Z') + if (v[l - 1] == upper_z) gmt = 1; if (tm->type == V_ASN1_GENERALIZEDTIME) { @@ -486,10 +491,10 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) * Try to parse fractional seconds. '14' is the place of * 'fraction point' in a GeneralizedTime string. */ - if (tm->length > 15 && v[14] == '.') { + if (tm->length > 15 && v[14] == period) { f = &v[14]; f_len = 1; - while (14 + f_len < l && ossl_isdigit(f[f_len])) + while (14 + f_len < l && ascii_isdigit(f[f_len])) ++f_len; } diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index 0e1edc77..96878e2a 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -13,148 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ASN1_str_functs[] = { - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2D_ASN1_OBJECT, 0), "a2d_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_INTEGER, 0), "a2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_STRING, 0), "a2i_ASN1_STRING"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_APPEND_EXP, 0), "append_exp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIO_INIT, 0), "asn1_bio_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIT_STRING_SET_BIT, 0), - "ASN1_BIT_STRING_set_bit"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CB, 0), "asn1_cb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, 0), "asn1_check_tlen"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_COLLECT, 0), "asn1_collect"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_EX_PRIMITIVE, 0), - "asn1_d2i_ex_primitive"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_FP, 0), "ASN1_d2i_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, 0), "asn1_d2i_read_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DIGEST, 0), "ASN1_digest"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_ADB, 0), "asn1_do_adb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_LOCK, 0), "asn1_do_lock"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DUP, 0), "ASN1_dup"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ENC_SAVE, 0), "asn1_enc_save"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_EX_C2I, 0), "asn1_ex_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_FIND_END, 0), "asn1_find_end"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERALIZEDTIME_ADJ, 0), - "ASN1_GENERALIZEDTIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERATE_V3, 0), "ASN1_generate_v3"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_INT64, 0), "asn1_get_int64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, 0), "ASN1_get_object"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_UINT64, 0), "asn1_get_uint64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_BIO, 0), "ASN1_i2d_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_FP, 0), "ASN1_i2d_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_D2I_FP, 0), "ASN1_item_d2i_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_DUP, 0), "ASN1_item_dup"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_D2I, 0), - "asn1_item_embed_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_NEW, 0), - "asn1_item_embed_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_FLAGS_I2D, 0), - "asn1_item_flags_i2d"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_BIO, 0), "ASN1_item_i2d_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_FP, 0), "ASN1_item_i2d_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_PACK, 0), "ASN1_item_pack"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN, 0), "ASN1_item_sign"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN_CTX, 0), - "ASN1_item_sign_ctx"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_UNPACK, 0), "ASN1_item_unpack"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_VERIFY, 0), "ASN1_item_verify"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_MBSTRING_NCOPY, 0), - "ASN1_mbstring_ncopy"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OBJECT_NEW, 0), "ASN1_OBJECT_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OUTPUT_DATA, 0), "asn1_output_data"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PCTX_NEW, 0), "ASN1_PCTX_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PRIMITIVE_NEW, 0), - "asn1_primitive_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SCTX_NEW, 0), "ASN1_SCTX_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SIGN, 0), "ASN1_sign"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STR2TYPE, 0), "asn1_str2type"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_INT64, 0), - "asn1_string_get_int64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_UINT64, 0), - "asn1_string_get_uint64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_SET, 0), "ASN1_STRING_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TABLE_ADD, 0), - "ASN1_STRING_TABLE_add"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TO_BN, 0), "asn1_string_to_bn"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TYPE_NEW, 0), - "ASN1_STRING_type_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_EX_D2I, 0), - "asn1_template_ex_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NEW, 0), "asn1_template_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 0), - "asn1_template_noexp_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TIME_ADJ, 0), "ASN1_TIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, 0), - "ASN1_TYPE_get_int_octetstring"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_OCTETSTRING, 0), - "ASN1_TYPE_get_octetstring"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_UTCTIME_ADJ, 0), "ASN1_UTCTIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_VERIFY, 0), "ASN1_verify"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_READ_ASN1, 0), "b64_read_asn1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_WRITE_ASN1, 0), "B64_write_ASN1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BIO_NEW_NDEF, 0), "BIO_new_NDEF"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BITSTR_CB, 0), "bitstr_cb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BN_TO_ASN1_STRING, 0), "bn_to_asn1_string"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_BIT_STRING, 0), - "c2i_ASN1_BIT_STRING"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_INTEGER, 0), "c2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_OBJECT, 0), "c2i_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_IBUF, 0), "c2i_ibuf"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_UINT64_INT, 0), "c2i_uint64_int"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_COLLECT_DATA, 0), "collect_data"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_OBJECT, 0), "d2i_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_UINTEGER, 0), "d2i_ASN1_UINTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_AUTOPRIVATEKEY, 0), - "d2i_AutoPrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_KEYPARAMS, 0), "d2i_KeyParams"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PRIVATEKEY, 0), "d2i_PrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PUBLICKEY, 0), "d2i_PublicKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_BUF, 0), "do_buf"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_CREATE, 0), "do_create"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_DUMP, 0), "do_dump"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_TCREATE, 0), "do_tcreate"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2A_ASN1_OBJECT, 0), "i2a_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_BIO_STREAM, 0), - "i2d_ASN1_bio_stream"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_OBJECT, 0), "i2d_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_DSA_PUBKEY, 0), "i2d_DSA_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_EC_PUBKEY, 0), "i2d_EC_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_KEYPARAMS, 0), "i2d_KeyParams"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PRIVATEKEY, 0), "i2d_PrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PUBLICKEY, 0), "i2d_PublicKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_RSA_PUBKEY, 0), "i2d_RSA_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_LONG_C2I, 0), "long_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_PREFIX, 0), "ndef_prefix"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_SUFFIX, 0), "ndef_suffix"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_OID_MODULE_INIT, 0), "oid_module_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PARSE_TAGGING, 0), "parse_tagging"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_IV, 0), "PKCS5_pbe2_set_iv"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_SCRYPT, 0), - "PKCS5_pbe2_set_scrypt"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET, 0), "PKCS5_pbe_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET0_ALGOR, 0), - "PKCS5_pbe_set0_algor"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBKDF2_SET, 0), "PKCS5_pbkdf2_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_SCRYPT_SET, 0), "pkcs5_scrypt_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_READ_ASN1, 0), "SMIME_read_ASN1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_TEXT, 0), "SMIME_text"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STABLE_GET, 0), "stable_get"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STBL_MODULE_INIT, 0), "stbl_module_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_C2I, 0), "uint32_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_NEW, 0), "uint32_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_C2I, 0), "uint64_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_NEW, 0), "uint64_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_CRL_ADD0_REVOKED, 0), - "X509_CRL_add0_revoked"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_INFO_NEW, 0), "X509_INFO_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_ENCODE, 0), "x509_name_encode"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_D2I, 0), "x509_name_ex_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_NEW, 0), "x509_name_ex_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_PKEY_NEW, 0), "X509_PKEY_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ADDING_OBJECT), "adding object"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"}, @@ -343,10 +201,8 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { int ERR_load_ASN1_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { - ERR_load_strings_const(ASN1_str_functs); + if (ERR_reason_error_string(ASN1_str_reasons[0].error) == NULL) ERR_load_strings_const(ASN1_str_reasons); - } #endif return 1; } diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index d3be967f..db9bbba9 100644 --- a/crypto/asn1/bio_ndef.c +++ b/crypto/asn1/bio_ndef.c @@ -184,6 +184,8 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) return 0; derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + if (derlen < 0) + return 0; if ((p = OPENSSL_malloc(derlen)) == NULL) { ASN1err(ASN1_F_NDEF_SUFFIX, ERR_R_MALLOC_FAILURE); return 0; diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index 0612a04a..f9b924c1 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -52,10 +52,6 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) else asn1_cb = 0; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new"); -#endif - switch (it->itype) { case ASN1_ITYPE_EXTERN: @@ -85,9 +81,6 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (!i) goto auxerr; if (i == 2) { -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; } } @@ -110,9 +103,6 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (!i) goto auxerr; if (i == 2) { -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; } } @@ -141,27 +131,18 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) goto auxerr2; break; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; memerr2: asn1_item_embed_free(pval, it, embed); memerr: ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 0; auxerr2: asn1_item_embed_free(pval, it, embed); auxerr: ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 0; } @@ -219,10 +200,6 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) *pval = NULL; return 1; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_push(tt->field_name - ? tt->field_name : "asn1_template_new"); -#endif /* If SET OF or SEQUENCE OF, its a STACK */ if (tt->flags & ASN1_TFLG_SK_MASK) { STACK_OF(ASN1_VALUE) *skval; @@ -239,9 +216,6 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) /* Otherwise pass it back to the item routine */ ret = asn1_item_embed_new(pval, it, embed); done: -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return ret; } diff --git a/crypto/asn1/x_bignum.c b/crypto/asn1/x_bignum.c index d7abca6c..c5e89290 100644 --- a/crypto/asn1/x_bignum.c +++ b/crypto/asn1/x_bignum.c @@ -130,9 +130,20 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) { - if (!*pval) - bn_secure_new(pval, it); - return bn_c2i(pval, cont, len, utype, free_cont, it); + int ret; + BIGNUM *bn; + + if (!*pval && !bn_secure_new(pval, it)) + return 0; + + ret = bn_c2i(pval, cont, len, utype, free_cont, it); + if (!ret) + return 0; + + /* Set constant-time flag for all secure BIGNUMS */ + bn = (BIGNUM *)*pval; + BN_set_flags(bn, BN_FLG_CONSTTIME); + return ret; } static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, diff --git a/crypto/asn1_dsa.c b/crypto/asn1_dsa.c new file mode 100644 index 00000000..8423ff88 --- /dev/null +++ b/crypto/asn1_dsa.c @@ -0,0 +1,253 @@ +/* + * 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 + */ + +/* + * A simple ASN.1 DER encoder/decoder for DSA-Sig-Value and ECDSA-Sig-Value. + * + * DSA-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * ECDSA-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + */ + +#include +#include +#include "internal/asn1_dsa.h" +#include "internal/packet.h" + +#define ID_SEQUENCE 0x30 +#define ID_INTEGER 0x02 + +/* + * Outputs the encoding of the length octets for a DER value with a content + * length of cont_len bytes to pkt. The maximum supported content length is + * 65535 (0xffff) bytes. + * + * Returns 1 on success or 0 on error. + */ +int encode_der_length(WPACKET *pkt, size_t cont_len) +{ + if (cont_len > 0xffff) + return 0; /* Too large for supported length encodings */ + + if (cont_len > 0xff) { + if (!WPACKET_put_bytes_u8(pkt, 0x82) + || !WPACKET_put_bytes_u16(pkt, cont_len)) + return 0; + } else { + if (cont_len > 0x7f + && !WPACKET_put_bytes_u8(pkt, 0x81)) + return 0; + if (!WPACKET_put_bytes_u8(pkt, cont_len)) + return 0; + } + + return 1; +} + +/* + * Outputs the DER encoding of a positive ASN.1 INTEGER to pkt. + * + * Results in an error if n is negative or too large. + * + * Returns 1 on success or 0 on error. + */ +int encode_der_integer(WPACKET *pkt, const BIGNUM *n) +{ + unsigned char *bnbytes; + size_t cont_len; + + if (BN_is_negative(n)) + return 0; + + /* + * Calculate the ASN.1 INTEGER DER content length for n. + * This is the number of whole bytes required to represent n (i.e. rounded + * down), plus one. + * If n is zero then the content is a single zero byte (length = 1). + * If the number of bits of n is a multiple of 8 then an extra zero padding + * byte is included to ensure that the value is still treated as positive + * in the INTEGER two's complement representation. + */ + cont_len = BN_num_bits(n) / 8 + 1; + + if (!WPACKET_start_sub_packet(pkt) + || !WPACKET_put_bytes_u8(pkt, ID_INTEGER) + || !encode_der_length(pkt, cont_len) + || !WPACKET_allocate_bytes(pkt, cont_len, &bnbytes) + || !WPACKET_close(pkt)) + return 0; + + if (bnbytes != NULL + && BN_bn2binpad(n, bnbytes, (int)cont_len) != (int)cont_len) + return 0; + + return 1; +} + +/* + * 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. + * + * Returns 1 on success or 0 on error. + */ +int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s) +{ + WPACKET tmppkt, *dummypkt; + size_t cont_len; + int isnull = WPACKET_is_null_buf(pkt); + + if (!WPACKET_start_sub_packet(pkt)) + return 0; + + if (!isnull) { + if (!WPACKET_init_null(&tmppkt, 0)) + return 0; + dummypkt = &tmppkt; + } else { + /* If the input packet has a NULL buffer, we don't need a dummy packet */ + dummypkt = pkt; + } + + /* Calculate the content length */ + if (!encode_der_integer(dummypkt, r) + || !encode_der_integer(dummypkt, s) + || !WPACKET_get_length(dummypkt, &cont_len) + || (!isnull && !WPACKET_finish(dummypkt))) { + if (!isnull) + WPACKET_cleanup(dummypkt); + return 0; + } + + /* Add the tag and length bytes */ + if (!WPACKET_put_bytes_u8(pkt, ID_SEQUENCE) + || !encode_der_length(pkt, cont_len) + /* + * Really encode the integers. We already wrote to the main pkt + * if it had a NULL buffer, so don't do it again + */ + || (!isnull && !encode_der_integer(pkt, r)) + || (!isnull && !encode_der_integer(pkt, s)) + || !WPACKET_close(pkt)) + return 0; + + return 1; +} + +/* + * Decodes the DER length octets in pkt and initialises subpkt with the + * following bytes of that length. + * + * Returns 1 on success or 0 on failure. + */ +int decode_der_length(PACKET *pkt, PACKET *subpkt) +{ + unsigned int byte; + + if (!PACKET_get_1(pkt, &byte)) + return 0; + + if (byte < 0x80) + return PACKET_get_sub_packet(pkt, subpkt, (size_t)byte); + if (byte == 0x81) + return PACKET_get_length_prefixed_1(pkt, subpkt); + if (byte == 0x82) + return PACKET_get_length_prefixed_2(pkt, subpkt); + + /* Too large, invalid, or not DER. */ + return 0; +} + +/* + * Decodes a single ASN.1 INTEGER value from pkt, which must be DER encoded, + * and updates n with the decoded value. + * + * The BIGNUM, n, must have already been allocated by calling BN_new(). + * pkt must not be NULL. + * + * An attempt to consume more than len bytes results in an error. + * Returns 1 on success or 0 on error. + * + * If the PACKET is supposed to only contain a single INTEGER value with no + * trailing garbage then it is up to the caller to verify that all bytes + * were consumed. + */ +int decode_der_integer(PACKET *pkt, BIGNUM *n) +{ + PACKET contpkt, tmppkt; + unsigned int tag, tmp; + + /* Check we have an integer and get the content bytes */ + if (!PACKET_get_1(pkt, &tag) + || tag != ID_INTEGER + || !decode_der_length(pkt, &contpkt)) + return 0; + + /* Peek ahead at the first bytes to check for proper encoding */ + tmppkt = contpkt; + /* The INTEGER must be positive */ + if (!PACKET_get_1(&tmppkt, &tmp) + || (tmp & 0x80) != 0) + return 0; + /* If there a zero padding byte the next byte must have the msb set */ + if (PACKET_remaining(&tmppkt) > 0 && tmp == 0) { + if (!PACKET_get_1(&tmppkt, &tmp) + || (tmp & 0x80) == 0) + return 0; + } + + if (BN_bin2bn(PACKET_data(&contpkt), + (int)PACKET_remaining(&contpkt), n) == NULL) + return 0; + + return 1; +} + +/* + * Decodes a single DSA-Sig-Value or ECDSA-Sig-Value from *ppin, which must be + * DER encoded, updates r and s with the decoded values, and increments *ppin + * past the data that was consumed. + * + * The BIGNUMs, r and s, must have already been allocated by calls to BN_new(). + * ppin and *ppin must not be NULL. + * + * An attempt to consume more than len bytes results in an error. + * Returns the number of bytes of input consumed or 0 if an error occurs. + * + * If the buffer is supposed to only contain a single [EC]DSA-Sig-Value with no + * trailing garbage then it is up to the caller to verify that all bytes + * were consumed. + */ +size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, + size_t len) +{ + size_t consumed; + PACKET pkt, contpkt; + unsigned int tag; + + if (!PACKET_buf_init(&pkt, *ppin, len) + || !PACKET_get_1(&pkt, &tag) + || tag != ID_SEQUENCE + || !decode_der_length(&pkt, &contpkt) + || !decode_der_integer(&contpkt, r) + || !decode_der_integer(&contpkt, s) + || PACKET_remaining(&contpkt) != 0) + return 0; + + consumed = PACKET_data(&pkt) - *ppin; + *ppin += consumed; + return consumed; +} + diff --git a/crypto/async/async_err.c b/crypto/async/async_err.c index 646cba9c..7a06f752 100644 --- a/crypto/async/async_err.c +++ b/crypto/async/async_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,19 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ASYNC_str_functs[] = { - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_CTX_NEW, 0), "async_ctx_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_INIT_THREAD, 0), - "ASYNC_init_thread"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_JOB_NEW, 0), "async_job_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_PAUSE_JOB, 0), "ASYNC_pause_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_FUNC, 0), "async_start_func"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_JOB, 0), "ASYNC_start_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 0), - "ASYNC_WAIT_CTX_set_wait_fd"}, - {0, NULL} -}; - static const ERR_STRING_DATA ASYNC_str_reasons[] = { {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SET_POOL), "failed to set pool"}, @@ -42,10 +29,8 @@ static const ERR_STRING_DATA ASYNC_str_reasons[] = { int ERR_load_ASYNC_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) { - ERR_load_strings_const(ASYNC_str_functs); + if (ERR_reason_error_string(ASYNC_str_reasons[0].error) == NULL) ERR_load_strings_const(ASYNC_str_reasons); - } #endif return 1; } diff --git a/crypto/bf/asm/bf-586.pl b/crypto/bf/asm/bf-586.pl index 91b17c1b..8622f5b1 100644 --- a/crypto/bf/asm/bf-586.pl +++ b/crypto/bf/asm/bf-586.pl @@ -12,8 +12,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/bf/build.info b/crypto/bf/build.info index cc06212d..59d5bbcf 100644 --- a/crypto/bf/build.info +++ b/crypto/bf/build.info @@ -13,6 +13,5 @@ ENDIF SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM -GENERATE[bf-586.s]=asm/bf-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[bf-586.s]=asm/bf-586.pl DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c index d7fcf2fc..ae82f098 100644 --- a/crypto/bio/b_addr.c +++ b/crypto/bio/b_addr.c @@ -207,7 +207,8 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, flags)) != 0) { # ifdef EAI_SYSTEM if (ret == EAI_SYSTEM) { - SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getnameinfo()"); BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB); } else # endif @@ -675,7 +676,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, if (1) { #ifdef AI_PASSIVE - int gai_ret = 0; + int gai_ret = 0, old_ret = 0; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); @@ -683,12 +684,12 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = protocol; -#ifdef AI_ADDRCONFIG -#ifdef AF_UNSPEC +# ifdef AI_ADDRCONFIG +# ifdef AF_UNSPEC if (family == AF_UNSPEC) -#endif +# endif hints.ai_flags |= AI_ADDRCONFIG; -#endif +# endif if (lookup_type == BIO_LOOKUP_SERVER) hints.ai_flags |= AI_PASSIVE; @@ -700,29 +701,30 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, switch ((gai_ret = getaddrinfo(host, service, &hints, res))) { # ifdef EAI_SYSTEM case EAI_SYSTEM: - SYSerr(SYS_F_GETADDRINFO, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getaddrinfo()"); BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); break; +# endif +# ifdef EAI_MEMORY + case EAI_MEMORY: + BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + break; # endif case 0: ret = 1; /* Success */ break; -# if (defined(EAI_FAMILY) || defined(EAI_ADDRFAMILY)) && defined(AI_ADDRCONFIG) -# ifdef EAI_FAMILY - case EAI_FAMILY: -# endif -# ifdef EAI_ADDRFAMILY - case EAI_ADDRFAMILY: -# endif + default: +# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST) if (hints.ai_flags & AI_ADDRCONFIG) { hints.ai_flags &= ~AI_ADDRCONFIG; + hints.ai_flags |= AI_NUMERICHOST; + old_ret = gai_ret; goto retry; } # endif - /* fall through */ - default: BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); - ERR_add_error_data(1, gai_strerror(gai_ret)); + ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret)); break; } } else { @@ -804,12 +806,15 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, */ # if defined(OPENSSL_SYS_VXWORKS) /* h_errno doesn't exist on VxWorks */ - SYSerr(SYS_F_GETHOSTBYNAME, 1000 ); + ERR_raise_data(ERR_LIB_SYS, 1000, + "calling gethostbyname()"); # else - SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno); + ERR_raise_data(ERR_LIB_SYS, 1000 + h_errno, + "calling gethostbyname()"); # endif #else - SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling gethostbyname()"); #endif ret = 0; goto err; @@ -855,11 +860,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, se = getservbyname(service, proto); if (se == NULL) { -#ifndef OPENSSL_SYS_WINDOWS - SYSerr(SYS_F_GETSERVBYNAME, errno); -#else - SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError()); -#endif + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getservbyname()"); goto err; } } else { diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index 9877b3d7..1747cce6 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -120,8 +120,6 @@ int BIO_sock_init(void) static struct WSAData wsa_state; if (!wsa_init_done) { - int err; - wsa_init_done = 1; memset(&wsa_state, 0, sizeof(wsa_state)); /* @@ -131,8 +129,8 @@ int BIO_sock_init(void) * probed at run-time with DSO_global_lookup. */ if (WSAStartup(0x0202, &wsa_state) != 0) { - err = WSAGetLastError(); - SYSerr(SYS_F_WSASTARTUP, err); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling wsastartup()"); BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); return -1; } @@ -192,7 +190,8 @@ int BIO_socket_ioctl(int fd, long type, void *arg) i = ioctlsocket(fd, type, ARG); # endif /* __DJGPP__ */ if (i < 0) - SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling ioctlsocket()"); return i; } @@ -243,7 +242,8 @@ int BIO_accept(int sock, char **ip_port) ret = -2; goto end; } - SYSerr(SYS_F_ACCEPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling accept()"); BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); goto end; } @@ -308,7 +308,8 @@ int BIO_socket_nbio(int s, int mode) l = fcntl(s, F_GETFL, 0); if (l == -1) { - SYSerr(SYS_F_FCNTL, get_last_sys_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fcntl()"); ret = -1; } else { # if defined(O_NONBLOCK) @@ -326,7 +327,8 @@ int BIO_socket_nbio(int s, int mode) ret = fcntl(s, F_SETFL, l); if (ret < 0) { - SYSerr(SYS_F_FCNTL, get_last_sys_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fcntl()"); } } # else @@ -349,7 +351,8 @@ int BIO_sock_info(int sock, ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr), &addr_len); if (ret == -1) { - SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockname()"); BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR); return 0; } diff --git a/crypto/bio/b_sock2.c b/crypto/bio/b_sock2.c index 7e04d788..abfd7047 100644 --- a/crypto/bio/b_sock2.c +++ b/crypto/bio/b_sock2.c @@ -46,7 +46,8 @@ int BIO_socket(int domain, int socktype, int protocol, int options) sock = socket(domain, socktype, protocol); if (sock == -1) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket()"); BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); return INVALID_SOCKET; } @@ -89,7 +90,8 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_KEEPALIVE) { if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE); return 0; } @@ -98,7 +100,8 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_NODELAY) { if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY); return 0; } @@ -107,7 +110,8 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (connect(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) == -1) { if (!BIO_sock_should_retry(-1)) { - SYSerr(SYS_F_CONNECT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling connect()"); BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR); } return 0; @@ -150,7 +154,8 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_REUSEADDR) { if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR); return 0; } @@ -158,7 +163,8 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options) # endif if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) { - SYSerr(SYS_F_BIND, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling bind()"); BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET); return 0; } @@ -217,7 +223,8 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) if (getsockopt(sock, SOL_SOCKET, SO_TYPE, (void *)&socktype, &socktype_len) != 0 || socktype_len != sizeof(socktype)) { - SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE); return 0; } @@ -228,7 +235,8 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_KEEPALIVE) { if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE); return 0; } @@ -237,7 +245,8 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_NODELAY) { if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY); return 0; } @@ -252,7 +261,8 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) on = options & BIO_SOCK_V6_ONLY ? 1 : 0; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY); return 0; } @@ -263,7 +273,8 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) return 0; if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) { - SYSerr(SYS_F_LISTEN, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling listen()"); BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET); return 0; } @@ -290,7 +301,8 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options) BIO_ADDR_sockaddr_noconst(addr), &len); if (accepted_sock == -1) { if (!BIO_sock_should_retry(accepted_sock)) { - SYSerr(SYS_F_ACCEPT, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling accept()"); BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR); } return INVALID_SOCKET; diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index c7bea994..178fdd6a 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,66 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BIO_str_functs[] = { - {ERR_PACK(ERR_LIB_BIO, BIO_F_ACPT_STATE, 0), "acpt_state"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDRINFO_WRAP, 0), "addrinfo_wrap"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDR_STRINGS, 0), "addr_strings"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT, 0), "BIO_accept"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_EX, 0), "BIO_accept_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_NEW, 0), "BIO_ACCEPT_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ADDR_NEW, 0), "BIO_ADDR_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_BIND, 0), "BIO_bind"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CALLBACK_CTRL, 0), "BIO_callback_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT, 0), "BIO_connect"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT_NEW, 0), "BIO_CONNECT_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CTRL, 0), "BIO_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GETS, 0), "BIO_gets"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_HOST_IP, 0), "BIO_get_host_ip"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_NEW_INDEX, 0), "BIO_get_new_index"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_PORT, 0), "BIO_get_port"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LISTEN, 0), "BIO_listen"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP, 0), "BIO_lookup"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP_EX, 0), "BIO_lookup_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_MAKE_PAIR, 0), "bio_make_pair"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_METH_NEW, 0), "BIO_meth_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW, 0), "BIO_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_DGRAM_SCTP, 0), "BIO_new_dgram_sctp"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_FILE, 0), "BIO_new_file"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_MEM_BUF, 0), "BIO_new_mem_buf"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD, 0), "BIO_nread"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD0, 0), "BIO_nread0"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE, 0), "BIO_nwrite"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE0, 0), "BIO_nwrite0"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PARSE_HOSTSERV, 0), "BIO_parse_hostserv"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PUTS, 0), "BIO_puts"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ, 0), "BIO_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_EX, 0), "BIO_read_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_INTERN, 0), "bio_read_intern"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET, 0), "BIO_socket"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET_NBIO, 0), "BIO_socket_nbio"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INFO, 0), "BIO_sock_info"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INIT, 0), "BIO_sock_init"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE, 0), "BIO_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_EX, 0), "BIO_write_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_INTERN, 0), "bio_write_intern"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BUFFER_CTRL, 0), "buffer_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_CTRL, 0), "conn_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_STATE, 0), "conn_state"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_NEW, 0), "dgram_sctp_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_READ, 0), "dgram_sctp_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_WRITE, 0), "dgram_sctp_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DOAPR_OUTCH, 0), "doapr_outch"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_CTRL, 0), "file_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_READ, 0), "file_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_CTRL, 0), "linebuffer_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_NEW, 0), "linebuffer_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_MEM_WRITE, 0), "mem_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_NBIOF_NEW, 0), "nbiof_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_SLG_WRITE, 0), "slg_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_SSL_NEW, 0), "SSL_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET), @@ -136,10 +76,8 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { int ERR_load_BIO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) { - ERR_load_strings_const(BIO_str_functs); + if (ERR_reason_error_string(BIO_str_reasons[0].error) == NULL) ERR_load_strings_const(BIO_str_reasons); - } #endif return 1; } diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c index 8955aa8a..830c1b96 100644 --- a/crypto/bio/bss_acpt.c +++ b/crypto/bio/bss_acpt.c @@ -226,10 +226,9 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) BIO_ADDRINFO_socktype(c->addr_iter), BIO_ADDRINFO_protocol(c->addr_iter), 0); if (ret == (int)INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_addr, - " service=", c->param_serv); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket(%s, %s)", + c->param_addr, c->param_serv); BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); goto exit_loop; } diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index 818b2ee9..56fb392c 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -138,10 +138,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c) BIO_ADDRINFO_socktype(c->addr_iter), BIO_ADDRINFO_protocol(c->addr_iter), 0); if (ret == (int)INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket(%s, %s)", + c->param_hostname, c->param_service); BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); goto exit_loop; } @@ -170,10 +169,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c) ERR_clear_error(); break; } else { - SYSerr(SYS_F_CONNECT, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); + 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); } goto exit_loop; @@ -186,10 +184,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c) i = BIO_sock_error(b->num); if (i) { BIO_clear_retry_flags(b); - SYSerr(SYS_F_CONNECT, i); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); + ERR_raise_data(ERR_LIB_SYS, i, + "calling connect(%s, %s)", + c->param_hostname, c->param_service); BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); ret = 0; goto exit_loop; diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 941429a3..c52b0f04 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -53,6 +53,8 @@ static int dgram_sctp_puts(BIO *h, const char *str); static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int dgram_sctp_new(BIO *h); static int dgram_sctp_free(BIO *data); +static int dgram_sctp_wait_for_dry(BIO *b); +static int dgram_sctp_msg_waiting(BIO *b); # ifdef SCTP_AUTHENTICATION_EVENT static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp); @@ -124,7 +126,7 @@ typedef struct bio_dgram_sctp_data_st { struct bio_dgram_sctp_sndinfo sndinfo; struct bio_dgram_sctp_rcvinfo rcvinfo; struct bio_dgram_sctp_prinfo prinfo; - void (*handle_notifications) (BIO *bio, void *context, void *buf); + BIO_dgram_sctp_notification_handler_fn handle_notifications; void *notification_context; int in_handshake; int ccs_rcvd; @@ -1562,6 +1564,10 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) else data->save_shutdown = 0; break; + case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY: + return dgram_sctp_wait_for_dry(b); + case BIO_CTRL_DGRAM_SCTP_MSG_WAITING: + return dgram_sctp_msg_waiting(b); default: /* @@ -1574,11 +1580,8 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) } int BIO_dgram_sctp_notification_cb(BIO *b, - void (*handle_notifications) (BIO *bio, - void - *context, - void *buf), - void *context) + BIO_dgram_sctp_notification_handler_fn handle_notifications, + void *context) { bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; @@ -1605,6 +1608,11 @@ int BIO_dgram_sctp_notification_cb(BIO *b, * 1 when dry */ int BIO_dgram_sctp_wait_for_dry(BIO *b) +{ + return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL); +} + +static int dgram_sctp_wait_for_dry(BIO *b) { int is_dry = 0; int sockflags = 0; @@ -1763,6 +1771,11 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b) } int BIO_dgram_sctp_msg_waiting(BIO *b) +{ + return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL); +} + +static int dgram_sctp_msg_waiting(BIO *b) { int n, sockflags; union sctp_notification snp; diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index 0e07632f..c1acad98 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -7,10 +7,7 @@ * https://www.openssl.org/source/license.html */ -#ifndef HEADER_BSS_FILE_C -# define HEADER_BSS_FILE_C - -# if defined(__linux) || defined(__sun) || defined(__hpux) +#if defined(__linux) || defined(__sun) || defined(__hpux) /* * Following definition aliases fopen to fopen64 on above mentioned * platforms. This makes it possible to open and sequentially access files @@ -23,17 +20,17 @@ * of 32-bit platforms which allow for sequential access of large files * without extra "magic" comprise *BSD, Darwin, IRIX... */ -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 # endif +#endif -# include -# include -# include "bio_lcl.h" -# include +#include +#include +#include "bio_lcl.h" +#include -# if !defined(OPENSSL_NO_STDIO) +#if !defined(OPENSSL_NO_STDIO) static int file_write(BIO *h, const char *buf, int num); static int file_read(BIO *h, char *buf, int size); @@ -69,12 +66,13 @@ BIO *BIO_new_file(const char *filename, const char *mode) fp_flags |= BIO_FP_TEXT; if (file == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fopen(%s, %s)", + filename, mode); if (errno == ENOENT -# ifdef ENXIO +#ifdef ENXIO || errno == ENXIO -# endif +#endif ) BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); else @@ -149,7 +147,8 @@ static int file_read(BIO *b, char *out, int outl) if (ret == 0 && (b->flags & BIO_FLAGS_UPLINK_INTERNAL ? UP_ferror((FILE *)b->ptr) : ferror((FILE *)b->ptr))) { - SYSerr(SYS_F_FREAD, get_last_sys_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fread()"); BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); ret = -1; } @@ -212,33 +211,33 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) b->shutdown = (int)num & BIO_CLOSE; b->ptr = ptr; b->init = 1; -# if BIO_FLAGS_UPLINK_INTERNAL!=0 -# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) -# define _IOB_ENTRIES 20 -# endif +# if BIO_FLAGS_UPLINK_INTERNAL!=0 +# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) +# define _IOB_ENTRIES 20 +# endif /* Safety net to catch purely internal BIO_set_fp calls */ -# if defined(_MSC_VER) && _MSC_VER>=1900 +# if defined(_MSC_VER) && _MSC_VER>=1900 if (ptr == stdin || ptr == stdout || ptr == stderr) BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); -# elif defined(_IOB_ENTRIES) +# elif defined(_IOB_ENTRIES) if ((size_t)ptr >= (size_t)stdin && (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); -# endif # endif -# ifdef UP_fsetmod +# endif +# ifdef UP_fsetmod if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); else -# endif +# endif { -# if defined(OPENSSL_SYS_WINDOWS) +# if defined(OPENSSL_SYS_WINDOWS) int fd = _fileno((FILE *)ptr); if (num & BIO_FP_TEXT) _setmode(fd, _O_TEXT); else _setmode(fd, _O_BINARY); -# elif defined(OPENSSL_SYS_MSDOS) +# elif defined(OPENSSL_SYS_MSDOS) int fd = fileno((FILE *)ptr); /* Set correct text/binary mode */ if (num & BIO_FP_TEXT) @@ -251,11 +250,11 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) } else _setmode(fd, _O_BINARY); } -# elif defined(OPENSSL_SYS_WIN32_CYGWIN) +# elif defined(OPENSSL_SYS_WIN32_CYGWIN) int fd = fileno((FILE *)ptr); if (!(num & BIO_FP_TEXT)) setmode(fd, O_BINARY); -# endif +# endif } break; case BIO_C_SET_FILENAME: @@ -277,19 +276,20 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) ret = 0; break; } -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) if (!(num & BIO_FP_TEXT)) OPENSSL_strlcat(p, "b", sizeof(p)); else OPENSSL_strlcat(p, "t", sizeof(p)); -# elif defined(OPENSSL_SYS_WIN32_CYGWIN) +# elif defined(OPENSSL_SYS_WIN32_CYGWIN) if (!(num & BIO_FP_TEXT)) OPENSSL_strlcat(p, "b", sizeof(p)); -# endif +# endif fp = openssl_fopen(ptr, p); if (fp == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fopen(%s, %s)", + ptr, p); BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); ret = 0; break; @@ -316,8 +316,8 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) st = b->flags & BIO_FLAGS_UPLINK_INTERNAL ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); if (st == EOF) { - SYSerr(SYS_F_FFLUSH, get_last_sys_error()); - ERR_add_error_data(1, "fflush()"); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fflush()"); BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); ret = 0; } @@ -422,6 +422,4 @@ BIO *BIO_new_file(const char *filename, const char *mode) return NULL; } -# endif /* OPENSSL_NO_STDIO */ - -#endif /* HEADER_BSS_FILE_C */ +#endif /* OPENSSL_NO_STDIO */ diff --git a/crypto/blake2/blake2b_mac.c b/crypto/blake2/blake2b_mac.c deleted file mode 100644 index f6025b1f..00000000 --- a/crypto/blake2/blake2b_mac.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 - */ - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include "internal/blake2.h" -# include "internal/cryptlib.h" -# include "internal/evp_int.h" - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - BLAKE2B_CTX ctx; - BLAKE2B_PARAM params; - unsigned char key[BLAKE2B_KEYBYTES]; -}; - -static EVP_MAC_IMPL *blake2b_mac_new(void) -{ - EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx)); - if (macctx != NULL) { - blake2b_param_init(&macctx->params); - /* ctx initialization is deferred to blake2b_init() */ - } - return macctx; -} - -static void blake2b_mac_free(EVP_MAC_IMPL *macctx) -{ - if (macctx != NULL) { - OPENSSL_cleanse(macctx->key, sizeof(macctx->key)); - OPENSSL_free(macctx); - } -} - -static EVP_MAC_IMPL *blake2b_mac_dup(const EVP_MAC_IMPL *src) -{ - EVP_MAC_IMPL *dst; - - dst = OPENSSL_zalloc(sizeof(*dst)); - if (dst == NULL) - return NULL; - - *dst = *src; - return dst; -} - -static int blake2b_mac_init(EVP_MAC_IMPL *macctx) -{ - /* Check key has been set */ - if (macctx->params.key_length == 0) { - EVPerr(EVP_F_BLAKE2B_MAC_INIT, EVP_R_NO_KEY_SET); - return 0; - } - - return blake2b_init_key(&macctx->ctx, &macctx->params, macctx->key); -} - -static int blake2b_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data, - size_t datalen) -{ - return blake2b_update(&macctx->ctx, data, datalen); -} - -static int blake2b_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out) -{ - return blake2b_final(out, &macctx->ctx); -} - -/* - * ALL Ctrl functions should be set before init(). - */ -static int blake2b_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args) -{ - const unsigned char *p; - size_t len; - size_t size; - - switch (cmd) { - case EVP_MAC_CTRL_SET_SIZE: - size = va_arg(args, size_t); - if (size < 1 || size > BLAKE2B_OUTBYTES) { - EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH); - return 0; - } - blake2b_param_set_digest_length(&macctx->params, (uint8_t)size); - return 1; - - case EVP_MAC_CTRL_SET_KEY: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len < 1 || len > BLAKE2B_KEYBYTES) { - EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH); - return 0; - } - blake2b_param_set_key_length(&macctx->params, (uint8_t)len); - memcpy(macctx->key, p, len); - memset(macctx->key + len, 0, BLAKE2B_KEYBYTES - len); - return 1; - - case EVP_MAC_CTRL_SET_CUSTOM: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len > BLAKE2B_PERSONALBYTES) { - EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH); - return 0; - } - blake2b_param_set_personal(&macctx->params, p, len); - return 1; - - case EVP_MAC_CTRL_SET_SALT: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len > BLAKE2B_SALTBYTES) { - EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH); - return 0; - } - blake2b_param_set_salt(&macctx->params, p, len); - return 1; - - default: - return -2; - } -} - -static int blake2b_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = blake2b_mac_ctrl(macctx, cmd, args); - va_end(args); - - return rv; -} - -static int blake2b_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen) -{ - return blake2b_mac_ctrl_int(macctx, cmd, buf, buflen); -} - -static int blake2b_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type, - const char *value) -{ - if (value == NULL) - return 0; - - if (strcmp(type, "outlen") == 0) - return blake2b_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value)); - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "custom") == 0) - return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, - value); - if (strcmp(type, "hexcustom") == 0) - return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, - value); - if (strcmp(type, "salt") == 0) - return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, - value); - if (strcmp(type, "hexsalt") == 0) - return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, - value); - return -2; -} - -static size_t blake2b_mac_size(EVP_MAC_IMPL *macctx) -{ - return macctx->params.digest_length; -} - -const EVP_MAC blake2b_mac_meth = { - EVP_MAC_BLAKE2B, - blake2b_mac_new, - blake2b_mac_dup, - blake2b_mac_free, - blake2b_mac_size, - blake2b_mac_init, - blake2b_mac_update, - blake2b_mac_final, - blake2b_mac_ctrl, - blake2b_mac_ctrl_str -}; - -#endif diff --git a/crypto/blake2/blake2s_mac.c b/crypto/blake2/blake2s_mac.c deleted file mode 100644 index 9ce8db13..00000000 --- a/crypto/blake2/blake2s_mac.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 - */ - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include "internal/blake2.h" -# include "internal/cryptlib.h" -# include "internal/evp_int.h" - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - BLAKE2S_CTX ctx; - BLAKE2S_PARAM params; - unsigned char key[BLAKE2S_KEYBYTES]; -}; - -static EVP_MAC_IMPL *blake2s_mac_new(void) -{ - EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx)); - if (macctx != NULL) { - blake2s_param_init(&macctx->params); - /* ctx initialization is deferred to BLAKE2s_Init() */ - } - return macctx; -} - -static void blake2s_mac_free(EVP_MAC_IMPL *macctx) -{ - if (macctx != NULL) { - OPENSSL_cleanse(macctx->key, sizeof(macctx->key)); - OPENSSL_free(macctx); - } -} - -static EVP_MAC_IMPL *blake2s_mac_dup(const EVP_MAC_IMPL *src) -{ - EVP_MAC_IMPL *dst; - - dst = OPENSSL_malloc(sizeof(*dst)); - if (dst == NULL) - return NULL; - - *dst = *src; - return dst; -} - -static int blake2s_mac_init(EVP_MAC_IMPL *macctx) -{ - /* Check key has been set */ - if (macctx->params.key_length == 0) { - EVPerr(EVP_F_BLAKE2S_MAC_INIT, EVP_R_NO_KEY_SET); - return 0; - } - - return blake2s_init_key(&macctx->ctx, &macctx->params, macctx->key); -} - -static int blake2s_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data, - size_t datalen) -{ - return blake2s_update(&macctx->ctx, data, datalen); -} - -static int blake2s_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out) -{ - return blake2s_final(out, &macctx->ctx); -} - -/* - * ALL Ctrl functions should be set before init(). - */ -static int blake2s_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args) -{ - const unsigned char *p; - size_t len; - size_t size; - - switch (cmd) { - case EVP_MAC_CTRL_SET_SIZE: - size = va_arg(args, size_t); - if (size < 1 || size > BLAKE2S_OUTBYTES) { - EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH); - return 0; - } - blake2s_param_set_digest_length(&macctx->params, (uint8_t)size); - return 1; - - case EVP_MAC_CTRL_SET_KEY: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len < 1 || len > BLAKE2S_KEYBYTES) { - EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH); - return 0; - } - blake2s_param_set_key_length(&macctx->params, (uint8_t)len); - memcpy(macctx->key, p, len); - memset(macctx->key + len, 0, BLAKE2S_KEYBYTES - len); - return 1; - - case EVP_MAC_CTRL_SET_CUSTOM: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len > BLAKE2S_PERSONALBYTES) { - EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH); - return 0; - } - blake2s_param_set_personal(&macctx->params, p, len); - return 1; - - case EVP_MAC_CTRL_SET_SALT: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len > BLAKE2S_SALTBYTES) { - EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH); - return 0; - } - blake2s_param_set_salt(&macctx->params, p, len); - return 1; - - default: - return -2; - } -} - -static int blake2s_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = blake2s_mac_ctrl(macctx, cmd, args); - va_end(args); - - return rv; -} - -static int blake2s_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen) -{ - return blake2s_mac_ctrl_int(macctx, cmd, buf, buflen); -} - -static int blake2s_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type, - const char *value) -{ - if (value == NULL) - return 0; - - if (strcmp(type, "outlen") == 0) - return blake2s_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value)); - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "custom") == 0) - return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, - value); - if (strcmp(type, "hexcustom") == 0) - return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, - value); - if (strcmp(type, "salt") == 0) - return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, - value); - if (strcmp(type, "hexsalt") == 0) - return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, - value); - return -2; -} - -static size_t blake2s_mac_size(EVP_MAC_IMPL *macctx) -{ - return macctx->params.digest_length; -} - -const EVP_MAC blake2s_mac_meth = { - EVP_MAC_BLAKE2S, - blake2s_mac_new, - blake2s_mac_dup, - blake2s_mac_free, - blake2s_mac_size, - blake2s_mac_init, - blake2s_mac_update, - blake2s_mac_final, - blake2s_mac_ctrl, - blake2s_mac_ctrl_str -}; - -#endif diff --git a/crypto/blake2/build.info b/crypto/blake2/build.info index f02bf9a6..8b5ebcec 100644 --- a/crypto/blake2/build.info +++ b/crypto/blake2/build.info @@ -1,3 +1,2 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - blake2b_mac.c blake2s_mac.c m_blake2b.c m_blake2s.c +SOURCE[../../libcrypto]=m_blake2b.c m_blake2s.c diff --git a/crypto/bn/asm/alpha-mont.pl b/crypto/bn/asm/alpha-mont.pl index 2d282a1f..b46c79ca 100644 --- a/crypto/bn/asm/alpha-mont.pl +++ b/crypto/bn/asm/alpha-mont.pl @@ -22,8 +22,7 @@ # I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x # difference. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; # int bn_mul_mont( $rp="a0"; # BN_ULONG *rp, diff --git a/crypto/bn/asm/armv4-gf2m.pl b/crypto/bn/asm/armv4-gf2m.pl index 0bf6f63e..e7a86558 100644 --- a/crypto/bn/asm/armv4-gf2m.pl +++ b/crypto/bn/asm/armv4-gf2m.pl @@ -39,9 +39,10 @@ # # http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -49,9 +50,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $code=<<___; diff --git a/crypto/bn/asm/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl index 7e0a4d81..72c883fe 100644 --- a/crypto/bn/asm/armv4-mont.pl +++ b/crypto/bn/asm/armv4-mont.pl @@ -54,9 +54,10 @@ # integer-only on Cortex-A8, ~10-210% on Cortex-A15, ~70-450% on # Snapdragon S4. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -64,9 +65,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $num="r0"; # starts as num argument, but holds &tp[num-1] diff --git a/crypto/bn/asm/armv8-mont.pl b/crypto/bn/asm/armv8-mont.pl index c755555d..3e92881b 100755 --- a/crypto/bn/asm/armv8-mont.pl +++ b/crypto/bn/asm/armv8-mont.pl @@ -40,15 +40,18 @@ # 50-70% improvement for RSA4096 sign. RSA2048 sign is ~25% faster # on Cortex-A57 and ~60-100% faster on others. -$flavour = shift; -$output = shift; +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; *STDOUT=*OUT; ($lo0,$hi0,$aj,$m0,$alo,$ahi, diff --git a/crypto/bn/asm/bn-586.pl b/crypto/bn/asm/bn-586.pl index 12b51953..28716216 100644 --- a/crypto/bn/asm/bn-586.pl +++ b/crypto/bn/asm/bn-586.pl @@ -11,8 +11,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/bn/asm/c64xplus-gf2m.pl b/crypto/bn/asm/c64xplus-gf2m.pl index c77fc5ee..d4913867 100644 --- a/crypto/bn/asm/c64xplus-gf2m.pl +++ b/crypto/bn/asm/c64xplus-gf2m.pl @@ -23,8 +23,7 @@ # totally unfair, because this module utilizes Galois Field Multiply # instruction. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($rp,$a1,$a0,$b1,$b0)=("A4","B4","A6","B6","A8"); # argument vector diff --git a/crypto/bn/asm/co-586.pl b/crypto/bn/asm/co-586.pl index a0f5a469..d9263094 100644 --- a/crypto/bn/asm/co-586.pl +++ b/crypto/bn/asm/co-586.pl @@ -10,8 +10,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/bn/asm/ia64-mont.pl b/crypto/bn/asm/ia64-mont.pl index 1ab5d94e..ce51b17e 100644 --- a/crypto/bn/asm/ia64-mont.pl +++ b/crypto/bn/asm/ia64-mont.pl @@ -67,7 +67,8 @@ # hereafter less for longer keys, while verify - by 74-13%. # DSA performance improves by 115-30%. -$output=pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; if ($^O eq "hpux") { $ADDP="addp4"; diff --git a/crypto/bn/asm/mips-mont.pl b/crypto/bn/asm/mips-mont.pl index 3386128a..c0b46291 100644 --- a/crypto/bn/asm/mips-mont.pl +++ b/crypto/bn/asm/mips-mont.pl @@ -52,8 +52,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_ADD="daddu"; # incidentally works even on n32 @@ -74,8 +78,7 @@ $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000; # ###################################################################### -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if ($flavour =~ /64|n32/i) { $LD="ld"; diff --git a/crypto/bn/asm/mips.pl b/crypto/bn/asm/mips.pl index 35971769..af44c978 100644 --- a/crypto/bn/asm/mips.pl +++ b/crypto/bn/asm/mips.pl @@ -54,9 +54,10 @@ # has to content with 40-85% improvement depending on benchmark and # key length, more for longer keys. -$flavour = shift || "o32"; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $LD="ld"; @@ -91,6 +92,8 @@ if ($flavour =~ /64|n32/i) { $code="#if !(defined (__mips_isa_rev) && (__mips_isa_rev >= 6))\n.set mips2\n#endif\n"; } +$output and open STDOUT,">$output"; + # Below is N32/64 register layout used in the original module. # ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); diff --git a/crypto/bn/asm/parisc-mont.pl b/crypto/bn/asm/parisc-mont.pl index 1d66c21f..1420840d 100644 --- a/crypto/bn/asm/parisc-mont.pl +++ b/crypto/bn/asm/parisc-mont.pl @@ -69,10 +69,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -$flavour = shift; -$output = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/bn/asm/ppc-mont.pl b/crypto/bn/asm/ppc-mont.pl index 6e6f3a65..01c8d11b 100644 --- a/crypto/bn/asm/ppc-mont.pl +++ b/crypto/bn/asm/ppc-mont.pl @@ -41,7 +41,10 @@ # builds. On low-end 32-bit processors performance improvement turned # to be marginal... -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $BITS= 32; @@ -94,7 +97,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $sp="r1"; $toc="r2"; diff --git a/crypto/bn/asm/ppc.pl b/crypto/bn/asm/ppc.pl index 21f69636..4b4e6c61 100644 --- a/crypto/bn/asm/ppc.pl +++ b/crypto/bn/asm/ppc.pl @@ -103,7 +103,10 @@ # Performance increase of ~60% # Based on submission from Suresh N. Chari of IBM -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $BITS= 32; @@ -159,7 +162,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $data=<= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $SIZE_T=4; @@ -108,7 +111,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=64; # padded frame header $TRANSFER=16*8; diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl index fddb12ff..66822abe 100755 --- a/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/bn/asm/rsaz-avx2.pl @@ -37,9 +37,10 @@ # (***) scalar AD*X code is faster than AVX2 and is preferred code # path for Broadwell; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -72,7 +73,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([3- $addx = ($ver>=3.03); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT = *OUT; if ($avx>1) {{{ diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl index e3fe2e7c..c41d8e52 100755 --- a/crypto/bn/asm/rsaz-x86_64.pl +++ b/crypto/bn/asm/rsaz-x86_64.pl @@ -52,9 +52,10 @@ # purposes; # (**) MULX was attempted, but found to give only marginal improvement; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -63,7 +64,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/bn/asm/s390x-gf2m.pl b/crypto/bn/asm/s390x-gf2m.pl index afe8d355..85e5eaa8 100644 --- a/crypto/bn/asm/s390x-gf2m.pl +++ b/crypto/bn/asm/s390x-gf2m.pl @@ -32,7 +32,10 @@ # so that improvement coefficients can vary from one specific # setup to another. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -42,8 +45,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $stdframe=16*$SIZE_T+4*8; diff --git a/crypto/bn/asm/s390x-mont.pl b/crypto/bn/asm/s390x-mont.pl index 2e823989..00b2d467 100644 --- a/crypto/bn/asm/s390x-mont.pl +++ b/crypto/bn/asm/s390x-mont.pl @@ -51,7 +51,10 @@ # On z990 it was measured to perform 2.6-2.2 times better than # compiler-generated code, less for longer keys... -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -61,8 +64,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $stdframe=16*$SIZE_T+4*8; diff --git a/crypto/bn/asm/sparct4-mont.pl b/crypto/bn/asm/sparct4-mont.pl index 8e981be2..76fffaf2 100755 --- a/crypto/bn/asm/sparct4-mont.pl +++ b/crypto/bn/asm/sparct4-mont.pl @@ -83,8 +83,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $code.=<<___; #include "sparc_arch.h" diff --git a/crypto/bn/asm/sparcv9-gf2m.pl b/crypto/bn/asm/sparcv9-gf2m.pl index d2973f0b..d4dda792 100644 --- a/crypto/bn/asm/sparcv9-gf2m.pl +++ b/crypto/bn/asm/sparcv9-gf2m.pl @@ -25,8 +25,7 @@ # ~100-230% faster than gcc-generated code and ~35-90% faster than # the pure SPARCv9 code path. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $locals=16*8; diff --git a/crypto/bn/asm/sparcv9-mont.pl b/crypto/bn/asm/sparcv9-mont.pl index 04c22f8d..6348c2a6 100644 --- a/crypto/bn/asm/sparcv9-mont.pl +++ b/crypto/bn/asm/sparcv9-mont.pl @@ -49,8 +49,7 @@ # module still have hidden potential [see TODO list there], which is # estimated to be larger than 20%... -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; # int bn_mul_mont( $rp="%i0"; # BN_ULONG *rp, diff --git a/crypto/bn/asm/sparcv9a-mont.pl b/crypto/bn/asm/sparcv9a-mont.pl index af22d413..a1170c76 100755 --- a/crypto/bn/asm/sparcv9a-mont.pl +++ b/crypto/bn/asm/sparcv9a-mont.pl @@ -62,8 +62,10 @@ # key length, more for longer keys] on USI&II cores and 30-80% - on # USIII&IV. -$output = pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; $fname="bn_mul_mont_fpu"; diff --git a/crypto/bn/asm/via-mont.pl b/crypto/bn/asm/via-mont.pl index 1b5cdd8f..d873082d 100644 --- a/crypto/bn/asm/via-mont.pl +++ b/crypto/bn/asm/via-mont.pl @@ -88,8 +88,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/bn/asm/vis3-mont.pl b/crypto/bn/asm/vis3-mont.pl index 9e8f498f..53f9920e 100644 --- a/crypto/bn/asm/vis3-mont.pl +++ b/crypto/bn/asm/vis3-mont.pl @@ -25,8 +25,7 @@ # for reference purposes, because T4 has dedicated Montgomery # multiplication and squaring *instructions* that deliver even more. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $frame = "STACK_FRAME"; $bias = "STACK_BIAS"; diff --git a/crypto/bn/asm/x86-gf2m.pl b/crypto/bn/asm/x86-gf2m.pl index 8bcfcb4f..bcc6de08 100644 --- a/crypto/bn/asm/x86-gf2m.pl +++ b/crypto/bn/asm/x86-gf2m.pl @@ -43,8 +43,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/bn/asm/x86-mont.pl b/crypto/bn/asm/x86-mont.pl index 22baf8fc..864816fb 100755 --- a/crypto/bn/asm/x86-mont.pl +++ b/crypto/bn/asm/x86-mont.pl @@ -37,8 +37,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/bn/asm/x86_64-gf2m.pl b/crypto/bn/asm/x86_64-gf2m.pl index d0a73575..f312a0c7 100644 --- a/crypto/bn/asm/x86_64-gf2m.pl +++ b/crypto/bn/asm/x86_64-gf2m.pl @@ -27,9 +27,10 @@ # these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not # all CPU time is burnt in it... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -38,7 +39,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; ($lo,$hi)=("%rax","%rdx"); $a=$lo; diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl index ede009fc..aa06345f 100755 --- a/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/bn/asm/x86_64-mont.pl @@ -46,9 +46,10 @@ # # Add MULX/ADOX/ADCX code path. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -57,7 +58,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index 6331566c..d6d2764e 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -31,9 +31,10 @@ # the np argument is not just modulus value, but one interleaved # with 0. This is to optimize post-condition... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -42,7 +43,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index e003f9a0..826f3f06 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -270,7 +270,7 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, do { int rv; - if (!BN_priv_rand_range(ret->A, ret->mod)) + if (!BN_priv_rand_range_ex(ret->A, ret->mod, ctx)) goto err; if (int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) break; diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c index cc3c3034..a60c7442 100644 --- a/crypto/bn/bn_ctx.c +++ b/crypto/bn/bn_ctx.c @@ -143,10 +143,12 @@ BN_CTX *BN_CTX_new_ex(OPENSSL_CTX *ctx) return ret; } +#ifndef FIPS_MODE BN_CTX *BN_CTX_new(void) { return BN_CTX_new_ex(NULL); } +#endif BN_CTX *BN_CTX_secure_new_ex(OPENSSL_CTX *ctx) { @@ -157,10 +159,12 @@ BN_CTX *BN_CTX_secure_new_ex(OPENSSL_CTX *ctx) return ret; } +#ifndef FIPS_MODE BN_CTX *BN_CTX_secure_new(void) { return BN_CTX_secure_new_ex(NULL); } +#endif void BN_CTX_free(BN_CTX *ctx) { diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c index a28443c7..ce0ea386 100644 --- a/crypto/bn/bn_err.c +++ b/crypto/bn/bn_err.c @@ -13,70 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BN_str_functs[] = { - {ERR_PACK(ERR_LIB_BN, BN_F_BNRAND, 0), "bnrand"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BNRAND_RANGE, 0), "bnrand_range"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_CONVERT_EX, 0), - "BN_BLINDING_convert_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_CREATE_PARAM, 0), - "BN_BLINDING_create_param"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_INVERT_EX, 0), - "BN_BLINDING_invert_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_NEW, 0), "BN_BLINDING_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_UPDATE, 0), "BN_BLINDING_update"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BN2DEC, 0), "BN_bn2dec"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BN2HEX, 0), "BN_bn2hex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_COMPUTE_WNAF, 0), "bn_compute_wNAF"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_GET, 0), "BN_CTX_get"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_NEW, 0), "BN_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_NEW_EX, 0), "BN_CTX_new_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_START, 0), "BN_CTX_start"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_DIV, 0), "BN_div"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_DIV_RECP, 0), "BN_div_recp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_EXP, 0), "BN_exp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_EXPAND_INTERNAL, 0), "bn_expand_internal"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENCB_NEW, 0), "BN_GENCB_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENERATE_DSA_NONCE, 0), - "BN_generate_dsa_nonce"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX, 0), - "BN_generate_prime_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD, 0), "BN_GF2m_mod"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_EXP, 0), "BN_GF2m_mod_exp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_MUL, 0), "BN_GF2m_mod_mul"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SOLVE_QUAD, 0), - "BN_GF2m_mod_solve_quad"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, 0), - "BN_GF2m_mod_solve_quad_arr"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SQR, 0), "BN_GF2m_mod_sqr"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SQRT, 0), "BN_GF2m_mod_sqrt"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_LSHIFT, 0), "BN_lshift"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP2_MONT, 0), "BN_mod_exp2_mont"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT, 0), "BN_mod_exp_mont"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT_CONSTTIME, 0), - "BN_mod_exp_mont_consttime"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT_WORD, 0), - "BN_mod_exp_mont_word"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_RECP, 0), "BN_mod_exp_recp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_SIMPLE, 0), "BN_mod_exp_simple"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_INVERSE, 0), "BN_mod_inverse"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_INVERSE_NO_BRANCH, 0), - "BN_mod_inverse_no_branch"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_LSHIFT_QUICK, 0), "BN_mod_lshift_quick"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_SQRT, 0), "BN_mod_sqrt"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MONT_CTX_NEW, 0), "BN_MONT_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MPI2BN, 0), "BN_mpi2bn"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_NEW, 0), "BN_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_POOL_GET, 0), "BN_POOL_get"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RAND, 0), "BN_rand"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RAND_RANGE, 0), "BN_rand_range"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RECP_CTX_NEW, 0), "BN_RECP_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RSHIFT, 0), "BN_rshift"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"}, - {0, NULL} -}; - static const ERR_STRING_DATA BN_str_reasons[] = { {ERR_PACK(ERR_LIB_BN, 0, BN_R_ARG2_LT_ARG3), "arg2 lt arg3"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_BAD_RECIPROCAL), "bad reciprocal"}, @@ -111,10 +47,8 @@ static const ERR_STRING_DATA BN_str_reasons[] = { int ERR_load_BN_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { - ERR_load_strings_const(BN_str_functs); + if (ERR_reason_error_string(BN_str_reasons[0].error) == NULL) ERR_load_strings_const(BN_str_reasons); - } #endif return 1; } diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c index 910f0144..e025dae6 100644 --- a/crypto/bn/bn_gf2m.c +++ b/crypto/bn/bn_gf2m.c @@ -732,8 +732,8 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) /* generate blinding value */ do { - if (!BN_priv_rand(b, BN_num_bits(p) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(b, BN_num_bits(p) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) goto err; } while (BN_is_zero(b)); @@ -1031,7 +1031,8 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], if (tmp == NULL) goto err; do { - if (!BN_priv_rand(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, + ctx)) goto err; if (!BN_GF2m_mod_arr(rho, rho, p)) goto err; diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h index 160f2f5a..38e66ab1 100644 --- a/crypto/bn/bn_lcl.h +++ b/crypto/bn/bn_lcl.h @@ -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 @@ -654,9 +654,6 @@ BIGNUM *int_bn_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, int *noinv); -int bn_probable_prime_dh(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); - static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits) { if (bits > (INT_MAX - BN_BITS2 + 1)) @@ -668,6 +665,4 @@ static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits) return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2); } -OPENSSL_CTX *bn_get_lib_ctx(BN_CTX *ctx); - #endif diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index 17293ede..01c9da11 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -132,20 +132,66 @@ int BN_num_bits_word(BN_ULONG l) return bits; } +/* + * This function still leaks `a->dmax`: it's caller's responsibility to + * expand the input `a` in advance to a public length. + */ +static ossl_inline +int bn_num_bits_consttime(const BIGNUM *a) +{ + int j, ret; + unsigned int mask, past_i; + int i = a->top - 1; + bn_check_top(a); + + for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) { + mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */ + + ret += BN_BITS2 & (~mask & ~past_i); + ret += BN_num_bits_word(a->d[j]) & mask; + + past_i |= mask; /* past_i will become 0xff..ff after i==j */ + } + + /* + * if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the + * final result. + */ + mask = ~(constant_time_eq_int(i, ((int)-1))); + + return ret & mask; +} + int BN_num_bits(const BIGNUM *a) { int i = a->top - 1; bn_check_top(a); + if (a->flags & BN_FLG_CONSTTIME) { + /* + * We assume that BIGNUMs flagged as CONSTTIME have also been expanded + * so that a->dmax is not leaking secret information. + * + * In other words, it's the caller's responsibility to ensure `a` has + * been preallocated in advance to a public length if we hit this + * branch. + * + */ + return bn_num_bits_consttime(a); + } + if (BN_is_zero(a)) return 0; + return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); } -static void bn_free_d(BIGNUM *a) +static void bn_free_d(BIGNUM *a, int clear) { if (BN_get_flags(a, BN_FLG_SECURE)) - OPENSSL_secure_free(a->d); + OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0])); + else if (clear != 0) + OPENSSL_clear_free(a->d, a->dmax * sizeof(a->d[0])); else OPENSSL_free(a->d); } @@ -155,10 +201,8 @@ void BN_clear_free(BIGNUM *a) { if (a == NULL) return; - if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { - OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); - bn_free_d(a); - } + if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA)) + bn_free_d(a, 1); if (BN_get_flags(a, BN_FLG_MALLOCED)) { OPENSSL_cleanse(a, sizeof(*a)); OPENSSL_free(a); @@ -170,7 +214,7 @@ void BN_free(BIGNUM *a) if (a == NULL) return; if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) - bn_free_d(a); + bn_free_d(a, 0); if (a->flags & BN_FLG_MALLOCED) OPENSSL_free(a); } @@ -248,10 +292,8 @@ BIGNUM *bn_expand2(BIGNUM *b, int words) BN_ULONG *a = bn_expand_internal(b, words); if (!a) return NULL; - if (b->d) { - OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0])); - bn_free_d(b); - } + if (b->d != NULL) + bn_free_d(b, 1); b->d = a; b->dmax = words; } @@ -416,8 +458,11 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) return ret; } +typedef enum {big, little} endianess_t; + /* ignore negative */ -static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) +static +int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess) { int n; size_t i, lasti, j, atop, mask; @@ -449,10 +494,17 @@ static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) lasti = atop - 1; atop = a->top * BN_BYTES; - for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { + if (endianess == big) + to += tolen; /* start from the end of the buffer */ + for (i = 0, j = 0; j < (size_t)tolen; j++) { + unsigned char val; l = a->d[i / BN_BYTES]; mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); - *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + if (endianess == big) + *--to = val; + else + *to++ = val; i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ } @@ -463,12 +515,12 @@ int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) { if (tolen < 0) return -1; - return bn2binpad(a, to, tolen); + return bn2binpad(a, to, tolen, big); } int BN_bn2bin(const BIGNUM *a, unsigned char *to) { - return bn2binpad(a, to, -1); + return bn2binpad(a, to, -1, big); } BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) @@ -520,22 +572,9 @@ BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) { - int i; - BN_ULONG l; - bn_check_top(a); - i = BN_num_bytes(a); - if (tolen < i) + if (tolen < 0) return -1; - /* Add trailing zeroes if necessary */ - if (tolen > i) - memset(to + i, 0, tolen - i); - to += i; - while (i--) { - l = a->d[i / BN_BYTES]; - to--; - *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; - } - return tolen; + return bn2binpad(a, to, tolen, little); } BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret) diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index 47e2f235..9e735b72 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -19,10 +19,13 @@ */ #include "bn_prime.h" -static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods); -static int probable_prime_dh_safe(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, - BN_CTX *ctx); +static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods, + BN_CTX *ctx); +static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx); + +#define square(x) ((BN_ULONG)(x) * (BN_ULONG)(x)) #if BN_BITS2 == 64 # define BN_DEF(lo, hi) (BN_ULONG)hi<<32|lo @@ -84,19 +87,19 @@ int BN_GENCB_call(BN_GENCB *cb, int a, int b) return 0; } -int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb, + BN_CTX *ctx) { BIGNUM *t; int found = 0; int i, j, c1 = 0; - BN_CTX *ctx = NULL; prime_t *mods = NULL; int checks = BN_prime_checks_for_size(bits); if (bits < 2) { /* There are no prime numbers this small. */ - BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + BNerr(BN_F_BN_GENERATE_PRIME_EX2, BN_R_BITS_TOO_SMALL); return 0; } else if (add == NULL && safe && bits < 6 && bits != 3) { /* @@ -104,7 +107,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, * But the following two safe primes with less than 6 bits (11, 23) * are unreachable for BN_rand with BN_RAND_TOP_TWO. */ - BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + BNerr(BN_F_BN_GENERATE_PRIME_EX2, BN_R_BITS_TOO_SMALL); return 0; } @@ -112,9 +115,6 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, if (mods == NULL) goto err; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if (t == NULL) @@ -122,16 +122,11 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { - if (!probable_prime(ret, bits, mods)) + if (!probable_prime(ret, bits, safe, mods, ctx)) goto err; } else { - if (safe) { - if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) - goto err; - } else { - if (!bn_probable_prime_dh(ret, bits, add, rem, ctx)) - goto err; - } + if (!probable_prime_dh(ret, bits, safe, mods, add, rem, ctx)) + goto err; } if (!BN_GENCB_call(cb, 0, c1++)) @@ -175,11 +170,27 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, err: OPENSSL_free(mods); BN_CTX_end(ctx); - BN_CTX_free(ctx); bn_check_top(ret); return found; } +#ifndef FIPS_MODE +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +{ + BN_CTX *ctx = BN_CTX_new(); + int retval; + + if (ctx == NULL) + return 0; + + retval = BN_generate_prime_ex2(ret, bits, safe, add, rem, cb, ctx); + + BN_CTX_free(ctx); + return retval; +} +#endif + int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) { @@ -187,11 +198,17 @@ int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, } /* See FIPS 186-4 C.3.1 Miller Rabin Probabilistic Primality Test. */ -int BN_is_prime_fasttest_ex(const BIGNUM *w, int checks, BN_CTX *ctx_passed, +int BN_is_prime_fasttest_ex(const BIGNUM *w, int checks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb) { int i, status, ret = -1; - BN_CTX *ctx = NULL; +#ifndef FIPS_MODE + BN_CTX *ctxlocal = NULL; +#else + + if (ctx == NULL) + return -1; +#endif /* w must be bigger than 1 */ if (BN_cmp(w, BN_value_one()) <= 0) @@ -219,18 +236,19 @@ int BN_is_prime_fasttest_ex(const BIGNUM *w, int checks, BN_CTX *ctx_passed, if (!BN_GENCB_call(cb, 1, -1)) return -1; } - if (ctx_passed != NULL) - ctx = ctx_passed; - else if ((ctx = BN_CTX_new()) == NULL) +#ifndef FIPS_MODE + if (ctx == NULL && (ctxlocal = ctx = BN_CTX_new()) == NULL) goto err; +#endif ret = bn_miller_rabin_is_prime(w, checks, ctx, cb, 0, &status); if (!ret) goto err; ret = (status == BN_PRIMETEST_PROBABLY_PRIME); err: - if (ctx_passed == NULL) - BN_CTX_free(ctx); +#ifndef FIPS_MODE + BN_CTX_free(ctxlocal); +#endif return ret; } @@ -301,7 +319,8 @@ int bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx, /* (Step 4) */ for (i = 0; i < iterations; ++i) { /* (Step 4.1) obtain a Random string of bits b where 1 < b < w-1 */ - if (!BN_priv_rand_range(b, w3) || !BN_add_word(b, 2)) /* 1 < b < w-1 */ + if (!BN_priv_rand_range_ex(b, w3, ctx) + || !BN_add_word(b, 2)) /* 1 < b < w-1 */ goto err; if (enhanced) { @@ -379,16 +398,18 @@ err: return ret; } -static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods) +static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods, + BN_CTX *ctx) { int i; BN_ULONG delta; BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; - char is_single_word = bits <= BN_BITS2; again: /* TODO: Not all primes are private */ - if (!BN_priv_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) + if (!BN_priv_rand_ex(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD, ctx)) + return 0; + if (safe && !BN_set_bit(rnd, 1)) return 0; /* we now have a random number 'rnd' to test. */ for (i = 1; i < NUMPRIMES; i++) { @@ -397,61 +418,25 @@ static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods) return 0; mods[i] = (prime_t) mod; } - /* - * If bits is so small that it fits into a single word then we - * additionally don't want to exceed that many bits. - */ - if (is_single_word) { - BN_ULONG size_limit; - - if (bits == BN_BITS2) { - /* - * Shifting by this much has undefined behaviour so we do it a - * different way - */ - size_limit = ~((BN_ULONG)0) - BN_get_word(rnd); - } else { - size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1; - } - if (size_limit < maxdelta) - maxdelta = size_limit; - } delta = 0; loop: - if (is_single_word) { - BN_ULONG rnd_word = BN_get_word(rnd); - - /*- - * In the case that the candidate prime is a single word then - * we check that: - * 1) It's greater than primes[i] because we shouldn't reject - * 3 as being a prime number because it's a multiple of - * three. - * 2) That it's not a multiple of a known prime. We don't - * check that rnd-1 is also coprime to all the known - * primes because there aren't many small primes where - * that's true. + for (i = 1; i < NUMPRIMES; i++) { + /* + * check that rnd is a prime and also that + * gcd(rnd-1,primes) == 1 (except for 2) + * do the second check only if we are interested in safe primes + * in the case that the candidate prime is a single word then + * we check only the primes up to sqrt(rnd) */ - for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) { - if ((mods[i] + delta) % primes[i] == 0) { - delta += 2; - if (delta > maxdelta) - goto again; - goto loop; - } - } - } else { - for (i = 1; i < NUMPRIMES; i++) { - /* - * check that rnd is not a prime and also that gcd(rnd-1,primes) - * == 1 (except for 2) - */ - if (((mods[i] + delta) % primes[i]) <= 1) { - delta += 2; - if (delta > maxdelta) - goto again; - goto loop; - } + if (bits <= 31 && delta <= 0x7fffffff + && square(primes[i]) > BN_get_word(rnd) + delta) + break; + if (safe ? (mods[i] + delta) % primes[i] <= 1 + : (mods[i] + delta) % primes[i] == 0) { + delta += safe ? 4 : 2; + if (delta > maxdelta) + goto again; + goto loop; } } if (!BN_add_word(rnd, delta)) @@ -462,17 +447,24 @@ static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods) return 1; } -int bn_probable_prime_dh(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) +static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx) { int i, ret = 0; BIGNUM *t1; + BN_ULONG delta; + BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; - if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) + if (maxdelta > BN_MASK2 - BN_get_word(add)) + maxdelta = BN_MASK2 - BN_get_word(add); + + again: + if (!BN_rand_ex(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, ctx)) goto err; /* we need ((rnd-rem) % add) == 0 */ @@ -482,27 +474,44 @@ int bn_probable_prime_dh(BIGNUM *rnd, int bits, if (!BN_sub(rnd, rnd, t1)) goto err; if (rem == NULL) { - if (!BN_add_word(rnd, 1)) + if (!BN_add_word(rnd, safe ? 3u : 1u)) goto err; } else { if (!BN_add(rnd, rnd, rem)) goto err; } - /* we now have a random number 'rand' to test. */ + if (BN_num_bits(rnd) < bits + || BN_get_word(rnd) < (safe ? 5u : 3u)) { + if (!BN_add(rnd, rnd, add)) + goto err; + } - loop: + /* we now have a random number 'rnd' to test. */ for (i = 1; i < NUMPRIMES; i++) { - /* check that rnd is a prime */ BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); if (mod == (BN_ULONG)-1) goto err; - if (mod <= 1) { - if (!BN_add(rnd, rnd, add)) - goto err; + mods[i] = (prime_t) mod; + } + delta = 0; + loop: + for (i = 1; i < NUMPRIMES; i++) { + /* check that rnd is a prime */ + if (bits <= 31 && delta <= 0x7fffffff + && square(primes[i]) > BN_get_word(rnd) + delta) + break; + /* rnd mod p == 1 implies q = (rnd-1)/2 is divisible by p */ + if (safe ? (mods[i] + delta) % primes[i] <= 1 + : (mods[i] + delta) % primes[i] == 0) { + delta += BN_get_word(add); + if (delta > maxdelta) + goto again; goto loop; } } + if (!BN_add_word(rnd, delta)) + goto err; ret = 1; err: @@ -510,70 +519,3 @@ int bn_probable_prime_dh(BIGNUM *rnd, int bits, bn_check_top(rnd); return ret; } - -static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, - const BIGNUM *rem, BN_CTX *ctx) -{ - int i, ret = 0; - BIGNUM *t1, *qadd, *q; - - bits--; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - qadd = BN_CTX_get(ctx); - if (qadd == NULL) - goto err; - - if (!BN_rshift1(qadd, padd)) - goto err; - - if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) - goto err; - - /* we need ((rnd-rem) % add) == 0 */ - if (!BN_mod(t1, q, qadd, ctx)) - goto err; - if (!BN_sub(q, q, t1)) - goto err; - if (rem == NULL) { - if (!BN_add_word(q, 1)) - goto err; - } else { - if (!BN_rshift1(t1, rem)) - goto err; - if (!BN_add(q, q, t1)) - goto err; - } - - /* we now have a random number 'rand' to test. */ - if (!BN_lshift1(p, q)) - goto err; - if (!BN_add_word(p, 1)) - goto err; - - loop: - for (i = 1; i < NUMPRIMES; i++) { - /* check that p and q are prime */ - /* - * check that for p and q gcd(p-1,primes) == 1 (except for 2) - */ - BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]); - BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]); - if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1) - goto err; - if (pmod == 0 || qmod == 0) { - if (!BN_add(p, p, padd)) - goto err; - if (!BN_add(q, q, qadd)) - goto err; - goto loop; - } - } - ret = 1; - - err: - BN_CTX_end(ctx); - bn_check_top(p); - return ret; -} diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index a71e7d49..2b3e6f20 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -103,6 +103,7 @@ int BN_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx) { return bnrand(NORMAL, rnd, bits, top, bottom, ctx); } +#ifndef FIPS_MODE int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { return bnrand(NORMAL, rnd, bits, top, bottom, NULL); @@ -112,16 +113,19 @@ int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) { return bnrand(TESTING, rnd, bits, top, bottom, NULL); } +#endif int BN_priv_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx) { return bnrand(PRIVATE, rnd, bits, top, bottom, ctx); } +#ifndef FIPS_MODE int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom) { return bnrand(PRIVATE, rnd, bits, top, bottom, NULL); } +#endif /* random number r: 0 <= r < range */ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range, @@ -195,16 +199,19 @@ int BN_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx) return bnrand_range(NORMAL, r, range, ctx); } +#ifndef FIPS_MODE int BN_rand_range(BIGNUM *r, const BIGNUM *range) { return bnrand_range(NORMAL, r, range, NULL); } +#endif int BN_priv_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx) { return bnrand_range(PRIVATE, r, range, ctx); } +#ifndef FIPS_MODE int BN_priv_rand_range(BIGNUM *r, const BIGNUM *range) { return bnrand_range(PRIVATE, r, range, NULL); @@ -219,6 +226,7 @@ int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { return BN_rand_range(r, range); } +#endif /* * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike @@ -256,8 +264,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, goto err; /* We copy |priv| into a local buffer to avoid exposing its length. */ - todo = sizeof(priv->d[0]) * priv->top; - if (todo > sizeof(private_bytes)) { + if (BN_bn2binpad(priv, private_bytes, sizeof(private_bytes)) < 0) { /* * No reasonable DSA or ECDSA key should have a private key this * large and we don't handle this case in order to avoid leaking the @@ -266,8 +273,6 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE); goto err; } - memcpy(private_bytes, priv->d, todo); - memset(private_bytes + todo, 0, sizeof(private_bytes) - todo); md = EVP_MD_fetch(libctx, "SHA512", NULL); if (md == NULL) { @@ -302,7 +307,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, err: EVP_MD_CTX_free(mdctx); - EVP_MD_meth_free(md); + EVP_MD_free(md); OPENSSL_free(k_bytes); OPENSSL_cleanse(private_bytes, sizeof(private_bytes)); return ret; diff --git a/crypto/bn/bn_rsa_fips186_4.c b/crypto/bn/bn_rsa_fips186_4.c index 261669d0..9a3041e2 100644 --- a/crypto/bn/bn_rsa_fips186_4.c +++ b/crypto/bn/bn_rsa_fips186_4.c @@ -193,13 +193,15 @@ int bn_rsa_fips186_4_gen_prob_primes(BIGNUM *p, BIGNUM *Xpout, /* (Steps 4.1/5.1): Randomly generate Xp1 if it is not passed in */ if (Xp1 == NULL) { /* Set the top and bottom bits to make it odd and the correct size */ - if (!BN_priv_rand(Xp1i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) + if (!BN_priv_rand_ex(Xp1i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, + ctx)) goto err; } /* (Steps 4.1/5.1): Randomly generate Xp2 if it is not passed in */ if (Xp2 == NULL) { /* Set the top and bottom bits to make it odd and the correct size */ - if (!BN_priv_rand(Xp2i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) + if (!BN_priv_rand_ex(Xp2i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, + ctx)) goto err; } @@ -305,7 +307,8 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, * so largest number will have B5... as the top byte * Setting the top 2 bits gives 0xC0. */ - if (!BN_priv_rand(X, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(X, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, + ctx)) goto end; } /* (Step 4) Y = X + ((R - X) mod 2r1r2) */ diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c index 5981cd07..2107487b 100644 --- a/crypto/bn/bn_sqrt.c +++ b/crypto/bn/bn_sqrt.c @@ -180,7 +180,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) if (!BN_set_word(y, i)) goto end; } else { - if (!BN_priv_rand(y, BN_num_bits(p), 0, 0)) + if (!BN_priv_rand_ex(y, BN_num_bits(p), 0, 0, ctx)) goto end; if (BN_ucmp(y, p) >= 0) { if (!(p->neg ? BN_add : BN_sub) (y, y, p)) diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c index 35992705..c79e4278 100644 --- a/crypto/bn/bn_x931p.c +++ b/crypto/bn/bn_x931p.c @@ -173,7 +173,7 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) * - 1. By setting the top two bits we ensure that the lower bound is * exceeded. */ - if (!BN_priv_rand(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, ctx)) goto err; BN_CTX_start(ctx); @@ -182,7 +182,8 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) goto err; for (i = 0; i < 1000; i++) { - if (!BN_priv_rand(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, + ctx)) goto err; /* Check that |Xp - Xq| > 2^(nbits - 100) */ @@ -227,9 +228,9 @@ int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, if (Xp1 == NULL || Xp2 == NULL) goto error; - if (!BN_priv_rand(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, ctx)) goto error; - if (!BN_priv_rand(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, ctx)) goto error; if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) goto error; diff --git a/crypto/bn/build.info b/crypto/bn/build.info index 8353b322..18b5950f 100644 --- a/crypto/bn/build.info +++ b/crypto/bn/build.info @@ -96,7 +96,7 @@ IF[{- !$disabled{asm} -}] $BNDEF=$BNDEF $BNDEF_{- $target{asm_arch} -}_ec2m ENDIF IF[{- !$disabled{sse2} -}] - $BNDEF_sse2=$BNDEF $BNDEF_{- $target{asm_arch} -}_sse2 + $BNDEF=$BNDEF $BNDEF_{- $target{asm_arch} -}_sse2 ENDIF ENDIF ENDIF @@ -116,58 +116,54 @@ INCLUDE[../../libcrypto]=../../crypto/include INCLUDE[bn_exp.o]=.. -GENERATE[bn-586.s]=asm/bn-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[bn-586.s]=asm/bn-586.pl DEPEND[bn-586.s]=../perlasm/x86asm.pl -GENERATE[co-586.s]=asm/co-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[co-586.s]=asm/co-586.pl DEPEND[co-586.s]=../perlasm/x86asm.pl -GENERATE[x86-mont.s]=asm/x86-mont.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[x86-mont.s]=asm/x86-mont.pl DEPEND[x86-mont.s]=../perlasm/x86asm.pl -GENERATE[x86-gf2m.s]=asm/x86-gf2m.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[x86-gf2m.s]=asm/x86-gf2m.pl DEPEND[x86-gf2m.s]=../perlasm/x86asm.pl -GENERATE[sparcv9a-mont.S]=asm/sparcv9a-mont.pl $(PERLASM_SCHEME) +GENERATE[sparcv9a-mont.S]=asm/sparcv9a-mont.pl INCLUDE[sparcv9a-mont.o]=.. -GENERATE[sparcv9-mont.S]=asm/sparcv9-mont.pl $(PERLASM_SCHEME) +GENERATE[sparcv9-mont.S]=asm/sparcv9-mont.pl INCLUDE[sparcv9-mont.o]=.. -GENERATE[vis3-mont.S]=asm/vis3-mont.pl $(PERLASM_SCHEME) +GENERATE[vis3-mont.S]=asm/vis3-mont.pl INCLUDE[vis3-mont.o]=.. -GENERATE[sparct4-mont.S]=asm/sparct4-mont.pl $(PERLASM_SCHEME) +GENERATE[sparct4-mont.S]=asm/sparct4-mont.pl INCLUDE[sparct4-mont.o]=.. -GENERATE[sparcv9-gf2m.S]=asm/sparcv9-gf2m.pl $(PERLASM_SCHEME) +GENERATE[sparcv9-gf2m.S]=asm/sparcv9-gf2m.pl INCLUDE[sparcv9-gf2m.o]=.. -GENERATE[bn-mips.S]=asm/mips.pl $(PERLASM_SCHEME) +GENERATE[bn-mips.S]=asm/mips.pl INCLUDE[bn-mips.o]=.. -GENERATE[mips-mont.S]=asm/mips-mont.pl $(PERLASM_SCHEME) +GENERATE[mips-mont.S]=asm/mips-mont.pl INCLUDE[mips-mont.o]=.. -GENERATE[s390x-mont.S]=asm/s390x-mont.pl $(PERLASM_SCHEME) -GENERATE[s390x-gf2m.s]=asm/s390x-gf2m.pl $(PERLASM_SCHEME) +GENERATE[s390x-mont.S]=asm/s390x-mont.pl +GENERATE[s390x-gf2m.s]=asm/s390x-gf2m.pl -GENERATE[x86_64-mont.s]=asm/x86_64-mont.pl $(PERLASM_SCHEME) -GENERATE[x86_64-mont5.s]=asm/x86_64-mont5.pl $(PERLASM_SCHEME) -GENERATE[x86_64-gf2m.s]=asm/x86_64-gf2m.pl $(PERLASM_SCHEME) -GENERATE[rsaz-x86_64.s]=asm/rsaz-x86_64.pl $(PERLASM_SCHEME) -GENERATE[rsaz-avx2.s]=asm/rsaz-avx2.pl $(PERLASM_SCHEME) +GENERATE[x86_64-mont.s]=asm/x86_64-mont.pl +GENERATE[x86_64-mont5.s]=asm/x86_64-mont5.pl +GENERATE[x86_64-gf2m.s]=asm/x86_64-gf2m.pl +GENERATE[rsaz-x86_64.s]=asm/rsaz-x86_64.pl +GENERATE[rsaz-avx2.s]=asm/rsaz-avx2.pl GENERATE[bn-ia64.s]=asm/ia64.S -GENERATE[ia64-mont.s]=asm/ia64-mont.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[ia64-mont.s]=asm/ia64-mont.pl -GENERATE[parisc-mont.s]=asm/parisc-mont.pl $(PERLASM_SCHEME) +GENERATE[parisc-mont.s]=asm/parisc-mont.pl # ppc - AIX, Linux, MacOS X... -GENERATE[bn-ppc.s]=asm/ppc.pl $(PERLASM_SCHEME) -GENERATE[ppc-mont.s]=asm/ppc-mont.pl $(PERLASM_SCHEME) -GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl $(PERLASM_SCHEME) +GENERATE[bn-ppc.s]=asm/ppc.pl +GENERATE[ppc-mont.s]=asm/ppc-mont.pl +GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl -GENERATE[alpha-mont.S]=asm/alpha-mont.pl $(PERLASM_SCHEME) +GENERATE[alpha-mont.S]=asm/alpha-mont.pl -GENERATE[armv4-mont.S]=asm/armv4-mont.pl $(PERLASM_SCHEME) +GENERATE[armv4-mont.S]=asm/armv4-mont.pl INCLUDE[armv4-mont.o]=.. -GENERATE[armv4-gf2m.S]=asm/armv4-gf2m.pl $(PERLASM_SCHEME) +GENERATE[armv4-gf2m.S]=asm/armv4-gf2m.pl INCLUDE[armv4-gf2m.o]=.. -GENERATE[armv8-mont.S]=asm/armv8-mont.pl $(PERLASM_SCHEME) +GENERATE[armv8-mont.S]=asm/armv8-mont.pl diff --git a/crypto/buffer/buf_err.c b/crypto/buffer/buf_err.c index 00b137da..702707bb 100644 --- a/crypto/buffer/buf_err.c +++ b/crypto/buffer/buf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,13 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BUF_str_functs[] = { - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_GROW, 0), "BUF_MEM_grow"}, - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_GROW_CLEAN, 0), "BUF_MEM_grow_clean"}, - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_NEW, 0), "BUF_MEM_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA BUF_str_reasons[] = { {0, NULL} }; @@ -29,10 +22,8 @@ static const ERR_STRING_DATA BUF_str_reasons[] = { int ERR_load_BUF_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { - ERR_load_strings_const(BUF_str_functs); + if (ERR_reason_error_string(BUF_str_reasons[0].error) == NULL) ERR_load_strings_const(BUF_str_reasons); - } #endif return 1; } diff --git a/crypto/buffer/build.info b/crypto/buffer/build.info index 54da1f92..63de1a57 100644 --- a/crypto/buffer/build.info +++ b/crypto/buffer/build.info @@ -1,2 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=buffer.c buf_err.c +SOURCE[../../providers/fips]=buffer.c diff --git a/crypto/build.info b/crypto/build.info index fccca081..6c77f951 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 kdf store property \ - md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \ + txt_db pkcs7 pkcs12 ui store property \ + md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 blake2 \ 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 kmac ess crmf cmp + err comp ocsp cms ts srp cmac ct async ess crmf cmp LIBS=../libcrypto @@ -59,52 +59,51 @@ IF[{- !$disabled{asm} && $config{processor} ne '386' -}] ENDIF # The Core -$CORE_COMMON=provider_core.c provider_predefined.c core_fetch.c core_namemap.c +$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[../providers/fips]=$CORE_COMMON # Central utilities $UTIL_COMMON=\ - cryptlib.c params.c bsearch.c ex_data.c o_str.c \ + cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \ ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \ - context.c sparse_array.c $CPUIDASM + context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM $UTIL_DEFINE=$CPUIDDEF SOURCE[../libcrypto]=$UTIL_COMMON \ - mem.c mem_sec.c mem_str.c mem_dbg.c \ + mem.c mem_sec.c mem_dbg.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 DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF SOURCE[../providers/fips]=$UTIL_COMMON DEFINE[../providers/fips]=$UTIL_DEFINE - DEPEND[cversion.o]=buildinf.h GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)" DEPEND[buildinf.h]=../configdata.pm -GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME) -GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl $(PERLASM_SCHEME) -GENERATE[uplink-ia64.s]=../ms/uplink-ia64.pl $(PERLASM_SCHEME) +GENERATE[uplink-x86.s]=../ms/uplink-x86.pl +GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl +GENERATE[uplink-ia64.s]=../ms/uplink-ia64.pl -GENERATE[x86cpuid.s]=x86cpuid.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[x86cpuid.s]=x86cpuid.pl DEPEND[x86cpuid.s]=perlasm/x86asm.pl -GENERATE[x86_64cpuid.s]=x86_64cpuid.pl $(PERLASM_SCHEME) +GENERATE[x86_64cpuid.s]=x86_64cpuid.pl GENERATE[ia64cpuid.s]=ia64cpuid.S -GENERATE[ppccpuid.s]=ppccpuid.pl $(PERLASM_SCHEME) -GENERATE[pariscid.s]=pariscid.pl $(PERLASM_SCHEME) +GENERATE[ppccpuid.s]=ppccpuid.pl +GENERATE[pariscid.s]=pariscid.pl GENERATE[alphacpuid.s]=alphacpuid.pl -GENERATE[arm64cpuid.S]=arm64cpuid.pl $(PERLASM_SCHEME) +GENERATE[arm64cpuid.S]=arm64cpuid.pl INCLUDE[arm64cpuid.o]=. -GENERATE[armv4cpuid.S]=armv4cpuid.pl $(PERLASM_SCHEME) +GENERATE[armv4cpuid.S]=armv4cpuid.pl INCLUDE[armv4cpuid.o]=. -GENERATE[s390xcpuid.S]=s390xcpuid.pl $(PERLASM_SCHEME) +GENERATE[s390xcpuid.S]=s390xcpuid.pl INCLUDE[s390xcpuid.o]=. IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] diff --git a/crypto/camellia/asm/cmll-x86.pl b/crypto/camellia/asm/cmll-x86.pl index 5d206695..1a3ec88b 100644 --- a/crypto/camellia/asm/cmll-x86.pl +++ b/crypto/camellia/asm/cmll-x86.pl @@ -49,8 +49,7 @@ require "x86asm.pl"; $OPENSSL=1; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/camellia/asm/cmll-x86_64.pl b/crypto/camellia/asm/cmll-x86_64.pl index 8bebc808..bd1e4c06 100644 --- a/crypto/camellia/asm/cmll-x86_64.pl +++ b/crypto/camellia/asm/cmll-x86_64.pl @@ -36,9 +36,10 @@ # EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it # apparently emulates some of 64-bit operations in [32-bit] microcode. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -47,7 +48,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } diff --git a/crypto/camellia/asm/cmllt4-sparcv9.pl b/crypto/camellia/asm/cmllt4-sparcv9.pl index 3b2a7050..0b3448ee 100644 --- a/crypto/camellia/asm/cmllt4-sparcv9.pl +++ b/crypto/camellia/asm/cmllt4-sparcv9.pl @@ -53,8 +53,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $::evp=1; # if $evp is set to 0, script generates module with # Camellia_[en|de]crypt, Camellia_set_key and Camellia_cbc_encrypt diff --git a/crypto/camellia/build.info b/crypto/camellia/build.info index 8d74b9f0..c10babc7 100644 --- a/crypto/camellia/build.info +++ b/crypto/camellia/build.info @@ -15,11 +15,9 @@ ENDIF SOURCE[../../libcrypto]=cmll_ecb.c cmll_ofb.c cmll_cfb.c cmll_ctr.c $CMLLASM -GENERATE[cmll-x86.s]=asm/cmll-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) \ - $(PROCESSOR) +GENERATE[cmll-x86.s]=asm/cmll-x86.pl DEPEND[cmll-x86.s]=../perlasm/x86asm.pl -GENERATE[cmll-x86_64.s]=asm/cmll-x86_64.pl $(PERLASM_SCHEME) -GENERATE[cmllt4-sparcv9.S]=asm/cmllt4-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[cmll-x86_64.s]=asm/cmll-x86_64.pl +GENERATE[cmllt4-sparcv9.S]=asm/cmllt4-sparcv9.pl INCLUDE[cmllt4-sparcv9.o]=.. DEPEND[cmllt4-sparcv9.S]=../perlasm/sparcv9_modes.pl diff --git a/crypto/cast/asm/cast-586.pl b/crypto/cast/asm/cast-586.pl index ad47b406..9e8d7d9b 100644 --- a/crypto/cast/asm/cast-586.pl +++ b/crypto/cast/asm/cast-586.pl @@ -18,8 +18,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/cast/build.info b/crypto/cast/build.info index 97779c22..e21e6d55 100644 --- a/crypto/cast/build.info +++ b/crypto/cast/build.info @@ -14,6 +14,5 @@ ENDIF SOURCE[../../libcrypto]=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c -GENERATE[cast-586.s]=asm/cast-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[cast-586.s]=asm/cast-586.pl DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/chacha/asm/chacha-armv4.pl b/crypto/chacha/asm/chacha-armv4.pl index c4402961..8a9f6c4f 100755 --- a/crypto/chacha/asm/chacha-armv4.pl +++ b/crypto/chacha/asm/chacha-armv4.pl @@ -34,9 +34,10 @@ # but then Snapdragon S4 and Cortex-A8 results get # 20-25% worse; -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -44,9 +45,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour $output" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } sub AUTOLOAD() # thunk [simplified] x86-style perlasm diff --git a/crypto/chacha/asm/chacha-armv8.pl b/crypto/chacha/asm/chacha-armv8.pl index 1f510173..aed873d5 100755 --- a/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/chacha/asm/chacha-armv8.pl @@ -44,15 +44,18 @@ # # (*) slower than 4+1:-( -$flavour=shift; -$output=shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub AUTOLOAD() # thunk [simplified] x86-style perlasm diff --git a/crypto/chacha/asm/chacha-c64xplus.pl b/crypto/chacha/asm/chacha-c64xplus.pl index d81d8ce7..dfa89229 100755 --- a/crypto/chacha/asm/chacha-c64xplus.pl +++ b/crypto/chacha/asm/chacha-c64xplus.pl @@ -24,8 +24,7 @@ # dependent on input length. This module on the other hand is free # from such limitation. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; ($OUT,$INP,$LEN,$KEYB,$COUNTERA)=("A4","B4","A6","B6","A8"); ($KEYA,$COUNTERB,$STEP)=("A7","B7","A3"); diff --git a/crypto/chacha/asm/chacha-ia64.pl b/crypto/chacha/asm/chacha-ia64.pl index dd090603..e3641426 100644 --- a/crypto/chacha/asm/chacha-ia64.pl +++ b/crypto/chacha/asm/chacha-ia64.pl @@ -15,8 +15,7 @@ # pass runs slower than expected... Overall result is 15.6 cpb, two # cycles more than theoretical estimate. -$output = pop; -open STDOUT, ">$output" if $output; +$output = pop and open STDOUT, ">$output"; my @k = map("r$_",(16..31)); my @x = map("r$_",(38..53)); diff --git a/crypto/chacha/asm/chacha-ppc.pl b/crypto/chacha/asm/chacha-ppc.pl index b1cb0bdc..1db31fa9 100755 --- a/crypto/chacha/asm/chacha-ppc.pl +++ b/crypto/chacha/asm/chacha-ppc.pl @@ -44,7 +44,10 @@ # instructions, which is why switch to vector-only code pays # off that much; -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -69,7 +72,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $LOCALS=6*$SIZE_T; $FRAME=$LOCALS+64+18*$SIZE_T; # 64 is for local variables diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl index 1f22b261..1f577b86 100755 --- a/crypto/chacha/asm/chacha-s390x.pl +++ b/crypto/chacha/asm/chacha-s390x.pl @@ -42,7 +42,10 @@ use FindBin qw($Bin); use lib "$Bin/../.."; use perlasm::s390x qw(:DEFAULT :VX :LD AUTOLOAD LABEL INCLUDE); -my $flavour = shift; +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my ($z,$SIZE_T); if ($flavour =~ /3[12]/) { @@ -53,9 +56,6 @@ if ($flavour =~ /3[12]/) { $SIZE_T=8; } -my $output; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} - my $sp="%r15"; my $stdframe=16*$SIZE_T+4*8; diff --git a/crypto/chacha/asm/chacha-x86.pl b/crypto/chacha/asm/chacha-x86.pl index 5fec22ec..bcd8eb4b 100755 --- a/crypto/chacha/asm/chacha-x86.pl +++ b/crypto/chacha/asm/chacha-x86.pl @@ -40,8 +40,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl index 5584f017..b854e2e3 100755 --- a/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/chacha/asm/chacha-x86_64.pl @@ -58,9 +58,10 @@ # (vi) even though Skylake-X can execute AVX512F code and deliver 0.57 # cpb in single thread, the corresponding capability is suppressed; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -89,7 +90,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # input parameter block diff --git a/crypto/chacha/build.info b/crypto/chacha/build.info index e8eeaf0c..97577396 100644 --- a/crypto/chacha/build.info +++ b/crypto/chacha/build.info @@ -26,15 +26,14 @@ ENDIF SOURCE[../../libcrypto]=$CHACHAASM -GENERATE[chacha-x86.s]=asm/chacha-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl $(PERLASM_SCHEME) -GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl $(PERLASM_SCHEME) -GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl $(PERLASM_SCHEME) +GENERATE[chacha-x86.s]=asm/chacha-x86.pl +GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl +GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl +GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl INCLUDE[chacha-armv4.o]=.. -GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl $(PERLASM_SCHEME) +GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl INCLUDE[chacha-armv8.o]=.. INCLUDE[chacha-s390x.o]=.. -GENERATE[chacha-c64xplus.S]=asm/chacha-c64xplus.pl $(PERLASM_SCHEME) -GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl $(PERLASM_SCHEME) -GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl $(PERLASM_SCHEME) +GENERATE[chacha-c64xplus.S]=asm/chacha-c64xplus.pl +GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl +GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl diff --git a/crypto/cmac/build.info b/crypto/cmac/build.info index c460598e..f6c8bfab 100644 --- a/crypto/cmac/build.info +++ b/crypto/cmac/build.info @@ -1,2 +1,6 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_meth.c + +$COMMON=cmac.c + +SOURCE[../../libcrypto]=$COMMON cm_ameth.c +SOURCE[../../providers/fips]=$COMMON diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c index ed513b11..b1ee0d3d 100644 --- a/crypto/cmac/cm_ameth.c +++ b/crypto/cmac/cm_ameth.c @@ -25,7 +25,10 @@ static int cmac_size(const EVP_PKEY *pkey) static void cmac_key_free(EVP_PKEY *pkey) { EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey); + EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx); + EVP_MAC_CTX_free(cmctx); + EVP_MAC_free(mac); } const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { diff --git a/crypto/cmac/cm_meth.c b/crypto/cmac/cm_meth.c deleted file mode 100644 index 07acf050..00000000 --- a/crypto/cmac/cm_meth.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 -#include -#include -#include -#include "internal/evp_int.h" - -/* local CMAC pkey structure */ - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - /* tmpcipher and tmpengine are set to NULL after a CMAC_Init call */ - const EVP_CIPHER *tmpcipher; /* cached CMAC cipher */ - const ENGINE *tmpengine; /* cached CMAC cipher engine */ - CMAC_CTX *ctx; -}; - -static EVP_MAC_IMPL *cmac_new(void) -{ - EVP_MAC_IMPL *cctx; - - if ((cctx = OPENSSL_zalloc(sizeof(*cctx))) == NULL - || (cctx->ctx = CMAC_CTX_new()) == NULL) { - OPENSSL_free(cctx); - cctx = NULL; - } - - return cctx; -} - -static void cmac_free(EVP_MAC_IMPL *cctx) -{ - if (cctx != NULL) { - CMAC_CTX_free(cctx->ctx); - OPENSSL_free(cctx); - } -} - -static EVP_MAC_IMPL *cmac_dup(const EVP_MAC_IMPL *csrc) -{ - EVP_MAC_IMPL *cdst = cmac_new(); - - if (cdst == NULL) - return NULL; - - if (!CMAC_CTX_copy(cdst->ctx, csrc->ctx)) { - cmac_free(cdst); - return NULL; - } - - cdst->tmpengine = csrc->tmpengine; - cdst->tmpcipher = csrc->tmpcipher; - - return cdst; -} - -static size_t cmac_size(EVP_MAC_IMPL *cctx) -{ - return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(cctx->ctx)); -} - -static int cmac_init(EVP_MAC_IMPL *cctx) -{ - int rv = CMAC_Init(cctx->ctx, NULL, 0, cctx->tmpcipher, - (ENGINE *)cctx->tmpengine); - cctx->tmpcipher = NULL; - cctx->tmpengine = NULL; - - return rv; -} - -static int cmac_update(EVP_MAC_IMPL *cctx, const unsigned char *data, - size_t datalen) -{ - return CMAC_Update(cctx->ctx, data, datalen); -} - -static int cmac_final(EVP_MAC_IMPL *cctx, unsigned char *out) -{ - size_t hlen; - - return CMAC_Final(cctx->ctx, out, &hlen); -} - -static int cmac_ctrl(EVP_MAC_IMPL *cctx, int cmd, va_list args) -{ - switch (cmd) { - case EVP_MAC_CTRL_SET_KEY: - { - const unsigned char *key = va_arg(args, const unsigned char *); - size_t keylen = va_arg(args, size_t); - int rv = CMAC_Init(cctx->ctx, key, keylen, cctx->tmpcipher, - (ENGINE *)cctx->tmpengine); - - cctx->tmpcipher = NULL; - cctx->tmpengine = NULL; - - return rv; - } - break; - case EVP_MAC_CTRL_SET_CIPHER: - cctx->tmpcipher = va_arg(args, const EVP_CIPHER *); - break; - case EVP_MAC_CTRL_SET_ENGINE: - cctx->tmpengine = va_arg(args, const ENGINE *); - break; - default: - return -2; - } - return 1; -} - -static int cmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = cmac_ctrl(hctx, cmd, args); - va_end(args); - - return rv; -} - -static int cmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen) -{ - return cmac_ctrl_int(hctx, cmd, buf, buflen); -} - -static int cmac_ctrl_str(EVP_MAC_IMPL *cctx, const char *type, - const char *value) -{ - if (!value) - return 0; - if (strcmp(type, "cipher") == 0) { - const EVP_CIPHER *c = EVP_get_cipherbyname(value); - - if (c == NULL) - return 0; - return cmac_ctrl_int(cctx, EVP_MAC_CTRL_SET_CIPHER, c); - } - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY, - value); - return -2; -} - -const EVP_MAC cmac_meth = { - EVP_MAC_CMAC, - cmac_new, - cmac_dup, - cmac_free, - cmac_size, - cmac_init, - cmac_update, - cmac_final, - cmac_ctrl, - cmac_ctrl_str -}; diff --git a/crypto/cmac/cmac.c b/crypto/cmac/cmac.c index 79936a59..b1be991f 100644 --- a/crypto/cmac/cmac.c +++ b/crypto/cmac/cmac.c @@ -87,11 +87,13 @@ void CMAC_CTX_free(CMAC_CTX *ctx) int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) { int bl; + if (in->nlast_block == -1) return 0; + if ((bl = EVP_CIPHER_CTX_block_size(in->cctx)) < 0) + return 0; if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx)) return 0; - bl = EVP_CIPHER_CTX_block_size(in->cctx); memcpy(out->k1, in->k1, bl); memcpy(out->k2, in->k2, bl); memcpy(out->tbl, in->tbl, bl); @@ -104,6 +106,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) { static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 }; + /* All zeros means restart */ if (!key && !cipher && !impl && keylen == 0) { /* Not initialised */ @@ -121,13 +124,15 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, /* Non-NULL key means initialisation complete */ if (key) { int bl; + if (!EVP_CIPHER_CTX_cipher(ctx->cctx)) return 0; if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen)) return 0; if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv)) return 0; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); + if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0) + return 0; if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl)) return 0; make_kn(ctx->k1, ctx->tbl, bl); @@ -146,15 +151,18 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; - size_t bl; + int bl; + if (ctx->nlast_block == -1) return 0; if (dlen == 0) return 1; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); + if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0) + return 0; /* Copy into partial block if we need to */ if (ctx->nlast_block > 0) { size_t nleft; + nleft = bl - ctx->nlast_block; if (dlen < nleft) nleft = dlen; @@ -170,7 +178,7 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) return 0; } /* Encrypt all but one of the complete blocks left */ - while (dlen > bl) { + while (dlen > (size_t)bl) { if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl)) return 0; dlen -= bl; @@ -186,9 +194,11 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) { int i, bl, lb; + if (ctx->nlast_block == -1) return 0; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); + if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0) + return 0; *poutlen = (size_t)bl; if (!out) return 1; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index b85b8bac..4e3a5c34 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -13,10 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CMP_str_functs[] = { - {0, NULL} -}; - static const ERR_STRING_DATA CMP_str_reasons[] = { {0, NULL} }; @@ -26,10 +22,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { int ERR_load_CMP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CMP_str_functs[0].error) == NULL) { - ERR_load_strings_const(CMP_str_functs); + if (ERR_reason_error_string(CMP_str_reasons[0].error) == NULL) ERR_load_strings_const(CMP_str_reasons); - } #endif return 1; } diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index acfbf8c5..27e98ce0 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -363,6 +363,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, unsigned char *ek = NULL; size_t eklen; int ret = 0; + size_t fixlen = 0; CMS_EncryptedContentInfo *ec; ec = cms->d.envelopedData->encryptedContentInfo; @@ -371,6 +372,19 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, return 0; } + if (cms->d.envelopedData->encryptedContentInfo->havenocert + && !cms->d.envelopedData->encryptedContentInfo->debug) { + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm); + + if (ciph == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER); + return 0; + } + + fixlen = EVP_CIPHER_key_length(ciph); + } + ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); if (ktri->pctx == NULL) return 0; @@ -401,7 +415,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) { + ktri->encryptedKey->length) <= 0 + || eklen == 0 + || (fixlen != 0 && eklen != fixlen)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); goto err; } diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index c05de0e6..98500d7c 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -13,152 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CMS_str_functs[] = { - {ERR_PACK(ERR_LIB_CMS, CMS_F_CHECK_CONTENT, 0), "check_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_CERT, 0), "CMS_add0_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_KEY, 0), - "CMS_add0_recipient_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, 0), - "CMS_add0_recipient_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECEIPTREQUEST, 0), - "CMS_add1_ReceiptRequest"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT_CERT, 0), - "CMS_add1_recipient_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNINGTIME, 0), - "cms_add1_signingTime"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT, 0), - "CMS_add1_signing_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT_V2, 0), - "CMS_add1_signing_cert_v2"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESS, 0), "CMS_compress"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_CREATE, 0), - "cms_CompressedData_create"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, 0), - "cms_CompressedData_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_CONTENT, 0), "cms_copy_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_MESSAGEDIGEST, 0), - "cms_copy_messageDigest"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATA, 0), "CMS_data"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAFINAL, 0), "CMS_dataFinal"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAINIT, 0), "CMS_dataInit"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT, 0), "CMS_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_KEY, 0), - "CMS_decrypt_set1_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PASSWORD, 0), - "CMS_decrypt_set1_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY, 0), - "CMS_decrypt_set1_pkey"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 0), - "cms_DigestAlgorithm_find_ctx"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 0), - "cms_DigestAlgorithm_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTEDDATA_DO_FINAL, 0), - "cms_DigestedData_do_final"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGEST_VERIFY, 0), "CMS_digest_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCODE_RECEIPT, 0), "cms_encode_Receipt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPT, 0), "CMS_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT, 0), - "cms_EncryptedContent_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 0), - "cms_EncryptedContent_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 0), - "CMS_EncryptedData_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, 0), - "CMS_EncryptedData_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, 0), - "CMS_EncryptedData_set1_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_CREATE, 0), - "CMS_EnvelopedData_create"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 0), - "cms_EnvelopedData_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPED_DATA_INIT, 0), - "cms_enveloped_data_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENV_ASN1_CTRL, 0), "cms_env_asn1_ctrl"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_FINAL, 0), "CMS_final"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CERTIFICATE_CHOICES, 0), - "cms_get0_certificate_choices"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CONTENT, 0), "CMS_get0_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ECONTENT_TYPE, 0), - "cms_get0_econtent_type"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ENVELOPED, 0), "cms_get0_enveloped"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_REVOCATION_CHOICES, 0), - "cms_get0_revocation_choices"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_SIGNED, 0), "cms_get0_signed"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_MSGSIGDIGEST_ADD1, 0), - "cms_msgSigDigest_add1"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPTREQUEST_CREATE0, 0), - "CMS_ReceiptRequest_create0"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPT_VERIFY, 0), "cms_Receipt_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_DECRYPT, 0), - "CMS_RecipientInfo_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_ENCRYPT, 0), - "CMS_RecipientInfo_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, 0), - "cms_RecipientInfo_kari_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, 0), - "CMS_RecipientInfo_kari_get0_alg"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, 0), - "CMS_RecipientInfo_kari_get0_orig_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, 0), - "CMS_RecipientInfo_kari_get0_reks"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, 0), - "CMS_RecipientInfo_kari_orig_id_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 0), - "cms_RecipientInfo_kekri_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 0), - "cms_RecipientInfo_kekri_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, 0), - "CMS_RecipientInfo_kekri_get0_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, 0), - "CMS_RecipientInfo_kekri_id_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, 0), - "CMS_RecipientInfo_ktri_cert_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, 0), - "cms_RecipientInfo_ktri_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, 0), - "cms_RecipientInfo_ktri_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, 0), - "CMS_RecipientInfo_ktri_get0_algs"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, 0), - "CMS_RecipientInfo_ktri_get0_signer_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 0), - "cms_RecipientInfo_pwri_crypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_KEY, 0), - "CMS_RecipientInfo_set0_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, 0), - "CMS_RecipientInfo_set0_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, 0), - "CMS_RecipientInfo_set0_pkey"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SD_ASN1_CTRL, 0), "cms_sd_asn1_ctrl"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_IAS, 0), "cms_set1_ias"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_KEYID, 0), "cms_set1_keyid"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_SIGNERIDENTIFIER, 0), - "cms_set1_SignerIdentifier"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET_DETACHED, 0), "CMS_set_detached"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN, 0), "CMS_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNED_DATA_INIT, 0), - "cms_signed_data_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 0), - "cms_SignerInfo_content_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_SIGN, 0), - "CMS_SignerInfo_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY, 0), - "CMS_SignerInfo_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 0), - "cms_signerinfo_verify_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 0), - "CMS_SignerInfo_verify_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN_RECEIPT, 0), "CMS_sign_receipt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SI_CHECK_ATTRIBUTES, 0), - "CMS_si_check_attributes"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_STREAM, 0), "CMS_stream"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_UNCOMPRESS, 0), "CMS_uncompress"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_VERIFY, 0), "CMS_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_KEK_UNWRAP_KEY, 0), "kek_unwrap_key"}, - {0, NULL} -}; - static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ATTRIBUTE_ERROR), "attribute error"}, @@ -292,10 +146,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { int ERR_load_CMS_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { - ERR_load_strings_const(CMS_str_functs); + if (ERR_reason_error_string(CMS_str_reasons[0].error) == NULL) ERR_load_strings_const(CMS_str_reasons); - } #endif return 1; } diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index 95e3628d..8f80f6ba 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -17,6 +17,7 @@ #include #include "cms_lcl.h" #include "internal/ess_int.h" +#include "internal/cms_int.h" IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) @@ -339,12 +340,10 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) } /* - * Add signer certificate's V2 digest to a SignerInfo - * structure + * Add signer certificate's V2 digest |sc| to a SignerInfo structure |si| */ -int CMS_add1_signing_cert_v2(CMS_SignerInfo *si, - ESS_SIGNING_CERT_V2 *sc) +int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc) { ASN1_STRING *seq = NULL; unsigned char *p, *pp; @@ -373,11 +372,10 @@ int CMS_add1_signing_cert_v2(CMS_SignerInfo *si, } /* - * Add signer certificate's digest to a SignerInfo - * structure + * Add signer certificate's digest |sc| to a SignerInfo structure |si| */ -int CMS_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc) +int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc) { ASN1_STRING *seq = NULL; unsigned char *p, *pp; diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h index dbc329d1..40d9c4bb 100644 --- a/crypto/cms/cms_lcl.h +++ b/crypto/cms/cms_lcl.h @@ -125,6 +125,8 @@ struct CMS_EncryptedContentInfo_st { size_t keylen; /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ int debug; + /* Set to 1 if we have no cert and need extra safety measures for MMA */ + int havenocert; }; struct CMS_RecipientInfo_st { @@ -317,8 +319,6 @@ struct CMS_OtherKeyAttribute_st { /* ESS structures */ -# ifdef HEADER_X509V3_H - struct CMS_ReceiptRequest_st { ASN1_OCTET_STRING *signedContentIdentifier; CMS_ReceiptsFrom *receiptsFrom; @@ -332,7 +332,6 @@ struct CMS_ReceiptsFrom_st { STACK_OF(GENERAL_NAMES) *receiptList; } d; }; -# endif struct CMS_Receipt_st { int32_t version; diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index 40a33563..6715e84d 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -14,9 +14,12 @@ #include #include #include +#include #include "cms_lcl.h" #include "internal/asn1_int.h" #include "internal/evp_int.h" +#include "internal/cms_int.h" +#include "internal/ess_int.h" /* CMS SignedData Utilities */ @@ -355,13 +358,13 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if ((sc = ESS_SIGNING_CERT_new_init(signer, NULL, 1)) == NULL) goto err; - add_sc = CMS_add1_signing_cert(si, sc); + add_sc = cms_add1_signing_cert(si, sc); ESS_SIGNING_CERT_free(sc); } else { if ((sc2 = ESS_SIGNING_CERT_V2_new_init(md, signer, NULL, 1)) == NULL) goto err; - add_sc = CMS_add1_signing_cert_v2(si, sc2); + add_sc = cms_add1_signing_cert_v2(si, sc2); ESS_SIGNING_CERT_V2_free(sc2); } if (!add_sc) @@ -703,11 +706,23 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) si->pctx = pctx; } + /* + * TODO(3.0): This causes problems when providers are in use, so disabled + * for now. Can we get rid of this completely? AFAICT this ctrl has been + * present since CMS was first put in - but has never been used to do + * anything. All internal implementations just return 1 and ignore this ctrl + * and have always done so by the looks of things. To fix this we could + * convert this ctrl into a param, which would require us to send all the + * signer info data as a set of params...but that is non-trivial and since + * this isn't used by anything it may be better just to remove it. + */ +#if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); goto err; } +#endif alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, ASN1_ITEM_rptr(CMS_Attributes_Sign)); @@ -724,11 +739,23 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) goto err; + /* + * TODO(3.0): This causes problems when providers are in use, so disabled + * for now. Can we get rid of this completely? AFAICT this ctrl has been + * present since CMS was first put in - but has never been used to do + * anything. All internal implementations just return 1 and ignore this ctrl + * and have always done so by the looks of things. To fix this we could + * convert this ctrl into a param, which would require us to send all the + * signer info data as a set of params...but that is non-trivial and since + * this isn't used by anything it may be better just to remove it. + */ +#if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); goto err; } +#endif EVP_MD_CTX_reset(mctx); diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index 5f1a47d7..ae95ff2d 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -743,6 +743,10 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, cms->d.envelopedData->encryptedContentInfo->debug = 1; else cms->d.envelopedData->encryptedContentInfo->debug = 0; + if (!cert) + cms->d.envelopedData->encryptedContentInfo->havenocert = 1; + else + cms->d.envelopedData->encryptedContentInfo->havenocert = 0; if (!pk && !cert && !dcont && !out) return 1; if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 78219f20..1dd7d679 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -598,6 +598,28 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_copy_next_retry(b); break; + case BIO_CTRL_WPENDING: + if (ctx->obuf == NULL) + return 0; + + if (ctx->odone) { + ret = ctx->ocount; + } else { + ret = ctx->ocount; + if (ret == 0) + /* Unknown amount pending but we are not finished */ + ret = 1; + } + if (ret == 0) + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + case BIO_CTRL_PENDING: + ret = ctx->zin.avail_in; + if (ret == 0) + ret = BIO_ctrl(next, cmd, num, ptr); + break; + default: ret = BIO_ctrl(next, cmd, num, ptr); break; diff --git a/crypto/comp/comp_err.c b/crypto/comp/comp_err.c index ac91d0e1..d4ae0406 100644 --- a/crypto/comp/comp_err.c +++ b/crypto/comp/comp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,15 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA COMP_str_functs[] = { - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_FLUSH, 0), "bio_zlib_flush"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_NEW, 0), "bio_zlib_new"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_READ, 0), "bio_zlib_read"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_WRITE, 0), "bio_zlib_write"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_COMP_CTX_NEW, 0), "COMP_CTX_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA COMP_str_reasons[] = { {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"}, @@ -37,10 +28,8 @@ static const ERR_STRING_DATA COMP_str_reasons[] = { int ERR_load_COMP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) { - ERR_load_strings_const(COMP_str_functs); + if (ERR_reason_error_string(COMP_str_reasons[0].error) == NULL) ERR_load_strings_const(COMP_str_reasons); - } #endif return 1; } diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index 277e4d64..ff4c43fc 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -352,6 +352,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) && (p != pname + 8 || *p == '=')) { char *include = NULL; BIO *next; + const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE"); + char *include_path = NULL; if (*p == '=') { p++; @@ -360,17 +362,34 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) trim_ws(conf, p); if (!str_copy(conf, psection, &include, p)) goto err; + + if (include_dir != NULL) { + size_t newlen = strlen(include_dir) + strlen(include) + 2; + + include_path = OPENSSL_malloc(newlen); + OPENSSL_strlcpy(include_path, include_dir, newlen); + OPENSSL_strlcat(include_path, "/", newlen); + OPENSSL_strlcat(include_path, include, newlen); + } else { + include_path = include; + } + /* get the BIO of the included file */ #ifndef OPENSSL_NO_POSIX_IO - next = process_include(include, &dirctx, &dirpath); - if (include != dirpath) { + next = process_include(include_path, &dirctx, &dirpath); + if (include_path != dirpath) { /* dirpath will contain include in case of a directory */ OPENSSL_free(include); + if (include_path != include) + OPENSSL_free(include_path); } #else - next = BIO_new_file(include, "r"); + next = BIO_new_file(include_path, "r"); OPENSSL_free(include); + if (include_path != include) + OPENSSL_free(include_path); #endif + if (next != NULL) { /* push the currently processing BIO onto stack */ if (biosk == NULL) { @@ -673,8 +692,9 @@ static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, BIO *next; if (stat(include, &st) < 0) { - SYSerr(SYS_F_STAT, errno); - ERR_add_error_data(1, include); + ERR_raise_data(ERR_LIB_SYS, errno, + "calling stat(%s)", + include); /* missing include file is not fatal error */ return NULL; } diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c index e3e8b0ee..96d2cd99 100644 --- a/crypto/conf/conf_err.c +++ b/crypto/conf/conf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,34 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CONF_str_functs[] = { - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_DUMP_FP, 0), "CONF_dump_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_LOAD, 0), "CONF_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_LOAD_FP, 0), "CONF_load_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_PARSE_LIST, 0), "CONF_parse_list"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_DEF_LOAD, 0), "def_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_DEF_LOAD_BIO, 0), "def_load_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_GET_NEXT_FILE, 0), "get_next_file"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_ADD, 0), "module_add"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_INIT, 0), "module_init"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_LOAD_DSO, 0), "module_load_dso"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_RUN, 0), "module_run"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_DUMP_BIO, 0), "NCONF_dump_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_DUMP_FP, 0), "NCONF_dump_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_NUMBER_E, 0), - "NCONF_get_number_e"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_SECTION, 0), "NCONF_get_section"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_STRING, 0), "NCONF_get_string"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD, 0), "NCONF_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD_BIO, 0), "NCONF_load_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD_FP, 0), "NCONF_load_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_NEW, 0), "NCONF_new"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_PROCESS_INCLUDE, 0), "process_include"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_SSL_MODULE_INIT, 0), "ssl_module_init"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_STR_COPY, 0), "str_copy"}, - {0, NULL} -}; - 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_LIST_CANNOT_BE_NULL), @@ -86,10 +58,8 @@ static const ERR_STRING_DATA CONF_str_reasons[] = { int ERR_load_CONF_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { - ERR_load_strings_const(CONF_str_functs); + if (ERR_reason_error_string(CONF_str_reasons[0].error) == NULL) ERR_load_strings_const(CONF_str_reasons); - } #endif return 1; } diff --git a/crypto/context.c b/crypto/context.c index cc1ec0e6..a2e19bac 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -9,6 +9,7 @@ #include "internal/cryptlib_int.h" #include "internal/thread_once.h" +#include "internal/property.h" struct openssl_ctx_onfree_list_st { openssl_ctx_onfree_fn *fn; @@ -28,6 +29,9 @@ struct openssl_ctx_st { /* Map internal static indexes to dynamically created indexes */ int dyn_indexes[OPENSSL_CTX_MAX_INDEXES]; + /* Keep a separate lock for each index */ + CRYPTO_RWLOCK *index_locks[OPENSSL_CTX_MAX_INDEXES]; + CRYPTO_RWLOCK *oncelock; int run_once_done[OPENSSL_CTX_MAX_RUN_ONCE]; int run_once_ret[OPENSSL_CTX_MAX_RUN_ONCE]; @@ -44,6 +48,7 @@ static OPENSSL_CTX *default_context = NULL; static int context_init(OPENSSL_CTX *ctx) { size_t i; + int exdata_done = 0; ctx->lock = CRYPTO_THREAD_lock_new(); if (ctx->lock == NULL) @@ -53,11 +58,17 @@ static int context_init(OPENSSL_CTX *ctx) if (ctx->oncelock == NULL) goto err; - for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) + for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) { + ctx->index_locks[i] = CRYPTO_THREAD_lock_new(); ctx->dyn_indexes[i] = -1; + if (ctx->index_locks[i] == NULL) + goto err; + } + /* OPENSSL_CTX is built on top of ex_data so we initialise that directly */ if (!do_ex_data_init(ctx)) goto err; + exdata_done = 1; if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data)) { @@ -65,8 +76,14 @@ static int context_init(OPENSSL_CTX *ctx) goto err; } + /* Everything depends on properties, so we also pre-initialise that */ + if (!ossl_property_parse_init(ctx)) + goto err; + return 1; err: + if (exdata_done) + crypto_cleanup_all_ex_data_int(ctx); CRYPTO_THREAD_lock_free(ctx->oncelock); CRYPTO_THREAD_lock_free(ctx->lock); ctx->lock = NULL; @@ -76,6 +93,7 @@ static int context_init(OPENSSL_CTX *ctx) static int context_deinit(OPENSSL_CTX *ctx) { struct openssl_ctx_onfree_list_st *tmp, *onfree; + int i; if (ctx == NULL) return 1; @@ -91,6 +109,9 @@ static int context_deinit(OPENSSL_CTX *ctx) } CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data); crypto_cleanup_all_ex_data_int(ctx); + for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) + CRYPTO_THREAD_lock_free(ctx->index_locks[i]); + CRYPTO_THREAD_lock_free(ctx->oncelock); CRYPTO_THREAD_lock_free(ctx->lock); ctx->lock = NULL; @@ -187,25 +208,48 @@ void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, const OPENSSL_CTX_METHOD *meth) { void *data = NULL; + int dynidx; ctx = openssl_ctx_get_concrete(ctx); if (ctx == NULL) return NULL; CRYPTO_THREAD_read_lock(ctx->lock); + dynidx = ctx->dyn_indexes[index]; + CRYPTO_THREAD_unlock(ctx->lock); - if (ctx->dyn_indexes[index] == -1 - && !openssl_ctx_init_index(ctx, index, meth)) { + if (dynidx != -1) { + CRYPTO_THREAD_read_lock(ctx->index_locks[index]); + data = CRYPTO_get_ex_data(&ctx->data, dynidx); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return data; + } + + CRYPTO_THREAD_write_lock(ctx->index_locks[index]); + CRYPTO_THREAD_write_lock(ctx->lock); + + dynidx = ctx->dyn_indexes[index]; + if (dynidx != -1) { CRYPTO_THREAD_unlock(ctx->lock); + data = CRYPTO_get_ex_data(&ctx->data, dynidx); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return data; + } + + if (!openssl_ctx_init_index(ctx, index, meth)) { + CRYPTO_THREAD_unlock(ctx->lock); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); return NULL; } + CRYPTO_THREAD_unlock(ctx->lock); + /* The alloc call ensures there's a value there */ if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data, ctx->dyn_indexes[index])) data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]); - CRYPTO_THREAD_unlock(ctx->lock); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); return data; } diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c new file mode 100644 index 00000000..f88a0458 --- /dev/null +++ b/crypto/core_algorithm.c @@ -0,0 +1,75 @@ +/* + * 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/core.h" +#include "internal/property.h" +#include "internal/provider.h" + +struct algorithm_data_st { + OPENSSL_CTX *libctx; + int operation_id; /* May be zero for finding them all */ + void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, + void *data); + void *data; +}; + +static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) +{ + struct algorithm_data_st *data = cbdata; + int no_store = 0; /* Assume caching is ok */ + int first_operation = 1; + int last_operation = OSSL_OP__HIGHEST; + int cur_operation; + int ok = 0; + + if (data->operation_id != 0) + first_operation = last_operation = data->operation_id; + + for (cur_operation = first_operation; + cur_operation <= last_operation; + cur_operation++) { + const OSSL_ALGORITHM *map = + ossl_provider_query_operation(provider, data->operation_id, + &no_store); + + if (map == NULL) + break; + + ok = 1; /* As long as we've found *something* */ + while (map->algorithm_name != NULL) { + const OSSL_ALGORITHM *thismap = map++; + + data->fn(provider, thismap, no_store, data->data); + } + } + + return ok; +} + +void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, + OSSL_PROVIDER *provider, + void (*fn)(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *data), + void *data) +{ + struct algorithm_data_st cbdata; + + cbdata.libctx = libctx; + cbdata.operation_id = operation_id; + cbdata.fn = fn; + cbdata.data = data; + + if (provider == NULL) + ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata); + else + algorithm_do_this(provider, &cbdata); +} diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index 56a3c5ca..1e0d82fb 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -24,67 +24,54 @@ struct construct_data_st { void *mcm_data; }; -static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata) +static void ossl_method_construct_this(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *cbdata) { struct construct_data_st *data = cbdata; - int no_store = 0; /* Assume caching is ok */ - const OSSL_ALGORITHM *map = - ossl_provider_query_operation(provider, data->operation_id, &no_store); + void *method = NULL; - if (map == NULL) - return 0; + if ((method = data->mcm->construct(algo->algorithm_name, + algo->implementation, provider, + data->mcm_data)) == NULL) + return; - while (map->algorithm_name != NULL) { - const OSSL_ALGORITHM *thismap = map++; - void *method = NULL; - - if ((method = data->mcm->construct(thismap->algorithm_name, - thismap->implementation, provider, - data->mcm_data)) == NULL) - continue; + /* + * Note regarding putting the method in stores: + * + * we don't need to care if it actually got in or not here. + * If it didn't get in, it will simply not be available when + * ossl_method_construct() tries to get it from the store. + * + * It is *expected* that the put function increments the refcnt + * of the passed method. + */ + if (data->force_store || !no_store) { /* - * Note regarding putting the method in stores: - * - * we don't need to care if it actually got in or not here. - * If it didn't get in, it will simply not be available when - * ossl_method_construct() tries to get it from the store. - * - * It is *expected* that the put function increments the refcnt - * of the passed method. + * If we haven't been told not to store, + * add to the global store */ - - if (data->force_store || !no_store) { - /* - * If we haven't been told not to store, - * add to the global store - */ - data->mcm->put(data->libctx, NULL, method, data->operation_id, - thismap->algorithm_name, - thismap->property_definition, data->mcm_data); - } - - data->mcm->put(data->libctx, data->store, method, data->operation_id, - thismap->algorithm_name, thismap->property_definition, - data->mcm_data); - - /* refcnt-- because we're dropping the reference */ - data->mcm->destruct(method, data->mcm_data); + data->mcm->put(data->libctx, NULL, method, provider, + data->operation_id, algo->algorithm_name, + algo->property_definition, data->mcm_data); } - return 1; + data->mcm->put(data->libctx, data->store, method, provider, + data->operation_id, algo->algorithm_name, + algo->property_definition, data->mcm_data); + + /* refcnt-- because we're dropping the reference */ + data->mcm->destruct(method, data->mcm_data); } void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id, - const char *name, const char *propquery, int force_store, OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data) { void *method = NULL; - if ((method = - mcm->get(libctx, NULL, operation_id, name, propquery, mcm_data)) - == NULL) { + if ((method = mcm->get(libctx, NULL, mcm_data)) == NULL) { struct construct_data_st cbdata; /* @@ -99,11 +86,10 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id, cbdata.force_store = force_store; cbdata.mcm = mcm; cbdata.mcm_data = mcm_data; - ossl_provider_forall_loaded(libctx, ossl_method_construct_this, - &cbdata); + ossl_algorithm_do_all(libctx, operation_id, NULL, + ossl_method_construct_this, &cbdata); - method = mcm->get(libctx, cbdata.store, operation_id, name, - propquery, mcm_data); + method = mcm->get(libctx, cbdata.store, mcm_data); mcm->dealloc_tmp_store(cbdata.store); } diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index d4c94190..cf5f1e54 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -173,6 +173,32 @@ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name) return number; } +struct num2name_data_st { + size_t idx; /* Countdown */ + const char *name; /* Result */ +}; + +static void do_num2name(const char *name, void *vdata) +{ + struct num2name_data_st *data = vdata; + + if (data->idx > 0) + data->idx--; + else if (data->name == NULL) + data->name = name; +} + +const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number, + size_t idx) +{ + struct num2name_data_st data; + + data.idx = idx; + data.name = NULL; + ossl_namemap_doall_names(namemap, number, do_num2name, &data); + return data.name; +} + int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name) { NAMENUM_ENTRY *namenum = NULL; diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c index 25bb8134..0028b329 100644 --- a/crypto/cpt_err.c +++ b/crypto/cpt_err.c @@ -13,82 +13,37 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CRYPTO_str_functs[] = { - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CMAC_CTX_NEW, 0), "CMAC_CTX_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_DUP_EX_DATA, 0), - "CRYPTO_dup_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_FREE_EX_DATA, 0), - "CRYPTO_free_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, 0), - "CRYPTO_get_ex_new_index"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, 0), - "CRYPTO_get_ex_new_index_ex"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_MEMDUP, 0), "CRYPTO_memdup"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA, 0), - "CRYPTO_new_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, 0), - "crypto_new_ex_data_ex"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_COPY_CTX, 0), - "CRYPTO_ocb128_copy_ctx"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_INIT, 0), - "CRYPTO_ocb128_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_SET_EX_DATA, 0), - "CRYPTO_set_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_FIPS_MODE_SET, 0), "FIPS_mode_set"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_GET_AND_LOCK, 0), "get_and_lock"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_GET_PROVIDER_STORE, 0), - "get_provider_store"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_ATEXIT, 0), "OPENSSL_atexit"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_BUF2HEXSTR, 0), - "OPENSSL_buf2hexstr"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_FOPEN, 0), "openssl_fopen"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_HEXSTR2BUF, 0), - "OPENSSL_hexstr2buf"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_INIT_CRYPTO, 0), - "OPENSSL_init_crypto"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_LH_NEW, 0), "OPENSSL_LH_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DEEP_COPY, 0), - "OPENSSL_sk_deep_copy"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DUP, 0), "OPENSSL_sk_dup"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ACTIVATE, 0), - "ossl_provider_activate"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN, 0), - "OSSL_PROVIDER_add_builtin"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, 0), - "ossl_provider_add_parameter"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_NEW, 0), - "ossl_provider_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, 0), - "ossl_provider_set_module_path"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_HMAC_INIT, 0), "pkey_hmac_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_POLY1305_INIT, 0), - "pkey_poly1305_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_SIPHASH_INIT, 0), - "pkey_siphash_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_ACTIVATE, 0), - "provider_activate"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_CONF_INIT, 0), - "provider_conf_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_CONF_LOAD, 0), - "provider_conf_load"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_NEW, 0), "provider_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_STORE_NEW, 0), - "provider_store_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_SK_RESERVE, 0), "sk_reserve"}, - {0, NULL} -}; - static const ERR_STRING_DATA CRYPTO_str_reasons[] = { {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), "illegal hex digit"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_DATA_SPACE), + "insufficient data space"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_PARAM_SIZE), + "insufficient param size"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE), + "insufficient secure data space"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NULL_ARGUMENT), + "invalid null argument"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_OSSL_PARAM_TYPE), + "invalid ossl param type"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_ALREADY_EXISTS), "provider already exists"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR), "provider section error"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE), + "secure malloc failure"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_BYTES), "too many bytes"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_RECORDS), + "too many records"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER), + "too small buffer"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER), + "zero length number"}, {0, NULL} }; @@ -97,10 +52,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = { int ERR_load_CRYPTO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { - ERR_load_strings_const(CRYPTO_str_functs); + if (ERR_reason_error_string(CRYPTO_str_reasons[0].error) == NULL) ERR_load_strings_const(CRYPTO_str_reasons); - } #endif return 1; } diff --git a/crypto/crmf/crmf_err.c b/crypto/crmf/crmf_err.c index 62dc6bfc..87e6a2da 100644 --- a/crypto/crmf/crmf_err.c +++ b/crypto/crmf/crmf_err.c @@ -13,47 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CRMF_str_functs[] = { - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_CRMF_POPOSIGNINGKEY_INIT, 0), - "CRMF_poposigningkey_init"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_CERTID_GEN, 0), - "OSSL_CRMF_CERTID_gen"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, 0), - "OSSL_CRMF_CERTTEMPLATE_fill"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, 0), - "OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, 0), - "OSSL_CRMF_MSGS_verify_popo"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, 0), - "OSSL_CRMF_MSG_create_popo"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_GET0_TMPL, 0), - "OSSL_CRMF_MSG_get0_tmpl"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, 0), - "OSSL_CRMF_MSG_get_certReqId"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PKIPUBLICATIONINFO_PUSH0_SINGLEPUBINFO, 0), - "OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_EXTENSION, 0), - "OSSL_CRMF_MSG_push0_extension"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_REGCTRL, 0), - "OSSL_CRMF_MSG_push0_regCtrl"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_REGINFO, 0), - "OSSL_CRMF_MSG_push0_regInfo"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET0_EXTENSIONS, 0), - "OSSL_CRMF_MSG_set0_extensions"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET0_SINGLEPUBINFO, 0), - "OSSL_CRMF_MSG_set0_SinglePubInfo"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_CERTREQID, 0), - "OSSL_CRMF_MSG_set_certReqId"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_PKIPUBLICATIONINFO_ACTION, 0), - "OSSL_CRMF_MSG_set_PKIPublicationInfo_action"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY, 0), - "OSSL_CRMF_MSG_set_validity"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_PBMP_NEW, 0), - "OSSL_CRMF_pbmp_new"}, - {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_PBM_NEW, 0), "OSSL_CRMF_pbm_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA CRMF_str_reasons[] = { {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT), "bad pbm iterationcount"}, @@ -95,10 +54,8 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = { int ERR_load_CRMF_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CRMF_str_functs[0].error) == NULL) { - ERR_load_strings_const(CRMF_str_functs); + if (ERR_reason_error_string(CRMF_str_reasons[0].error) == NULL) ERR_load_strings_const(CRMF_str_reasons); - } #endif return 1; } diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 55f1f38a..29743414 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -29,6 +29,7 @@ #include #include "crmf_int.h" +#include "internal/constant_time_locl.h" /* explicit #includes not strictly needed since implied by the above: */ #include @@ -200,10 +201,7 @@ OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, /* * id-regCtrl-protocolEncrKey Control (section 6.6) * - * For some reason X509_PUBKEY_dup() is not implemented in OpenSSL X509 - * TODO: check whether that should go elsewhere */ -static IMPLEMENT_ASN1_DUP_FUNCTION(X509_PUBKEY) IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl) /*- @@ -299,20 +297,20 @@ int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid) } /* get ASN.1 encoded integer, return -1 on error */ -static int crmf_asn1_get_int(int func, const ASN1_INTEGER *a) +static int crmf_asn1_get_int(const ASN1_INTEGER *a) { int64_t res; if (!ASN1_INTEGER_get_int64(&res, a)) { - CRMFerr(func, ASN1_R_INVALID_NUMBER); + CRMFerr(0, ASN1_R_INVALID_NUMBER); return -1; } if (res < INT_MIN) { - CRMFerr(func, ASN1_R_TOO_SMALL); + CRMFerr(0, ASN1_R_TOO_SMALL); return -1; } if (res > INT_MAX) { - CRMFerr(func, ASN1_R_TOO_LARGE); + CRMFerr(0, ASN1_R_TOO_LARGE); return -1; } return (int)res; @@ -324,8 +322,7 @@ int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm) CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, CRMF_R_NULL_ARGUMENT); return -1; } - return crmf_asn1_get_int(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, - crm->certReq->certReqId); + return crmf_asn1_get_int(crm->certReq->certReqId); } @@ -658,7 +655,9 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, X509 *cert = NULL; /* decrypted certificate */ EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ unsigned char *ek = NULL; /* decrypted symmetric encryption key */ + size_t eksize = 0; /* size of decrypted symmetric encryption key */ const EVP_CIPHER *cipher = NULL; /* used cipher */ + int cikeysize = 0; /* key size from cipher */ unsigned char *iv = NULL; /* initial vector for symmetric encryption */ unsigned char *outbuf = NULL; /* decryption output buffer */ const unsigned char *p = NULL; /* needed for decoding ASN1 */ @@ -677,18 +676,31 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, CRMF_R_UNSUPPORTED_CIPHER); return NULL; } - + /* select symmetric cipher based on algorithm given in message */ + if ((cipher = EVP_get_cipherbynid(symmAlg)) == NULL) { + CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, + CRMF_R_UNSUPPORTED_CIPHER); + goto end; + } + cikeysize = EVP_CIPHER_key_length(cipher); /* first the symmetric key needs to be decrypted */ pkctx = EVP_PKEY_CTX_new(pkey, NULL); if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) { ASN1_BIT_STRING *encKey = ecert->encSymmKey; - size_t eksize = 0; + size_t failure; + int retval; - if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, encKey->data, encKey->length) - <= 0 - || (ek = OPENSSL_malloc(eksize)) == NULL - || EVP_PKEY_decrypt(pkctx, ek, &eksize, encKey->data, - encKey->length) <= 0) { + if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, + encKey->data, encKey->length) <= 0 + || (ek = OPENSSL_malloc(eksize)) == NULL) + goto oom; + retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, + encKey->data, encKey->length); + ERR_clear_error(); /* error state may have sensitive information */ + failure = ~constant_time_is_zero_s(constant_time_msb(retval) + | constant_time_is_zero(retval)); + failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize); + if (failure) { CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); goto end; @@ -696,13 +708,6 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, } else { goto oom; } - - /* select symmetric cipher based on algorithm given in message */ - if ((cipher = EVP_get_cipherbynid(symmAlg)) == NULL) { - CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, - CRMF_R_UNSUPPORTED_CIPHER); - goto end; - } if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL) goto oom; if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, @@ -747,7 +752,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert, EVP_PKEY_CTX_free(pkctx); OPENSSL_free(outbuf); EVP_CIPHER_CTX_free(evp_ctx); - OPENSSL_free(ek); + OPENSSL_clear_free(ek, eksize); OPENSSL_free(iv); return cert; } diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c index 7b291666..a3ac4555 100644 --- a/crypto/crmf/crmf_pbm.c +++ b/crypto/crmf/crmf_pbm.c @@ -12,6 +12,8 @@ */ +#include + #include #include @@ -22,6 +24,8 @@ #include #include #include +#include +#include /*- * creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4) @@ -120,9 +124,10 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, const unsigned char *msg, size_t msglen, const unsigned char *sec, size_t seclen, - unsigned char **mac, size_t *maclen) + unsigned char **out, size_t *outlen) { int mac_nid, hmac_md_nid = NID_undef; + const char *mdname = NULL; const EVP_MD *m = NULL; EVP_MD_CTX *ctx = NULL; unsigned char basekey[EVP_MAX_MD_SIZE]; @@ -130,9 +135,12 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, int64_t iterations; unsigned char *mac_res = 0; 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 }; - if (mac == NULL || pbmp == NULL || pbmp->mac == NULL + if (out == NULL || pbmp == NULL || pbmp->mac == NULL || pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) { CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_NULL_ARGUMENT); goto err; @@ -193,17 +201,22 @@ 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) - || ((m = EVP_get_digestbynid(hmac_md_nid)) == NULL)) { + || ((mdname = OBJ_nid2sn(hmac_md_nid)) == NULL)) { CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM); goto err; } - if ((mctx = EVP_MAC_CTX_new(EVP_get_macbyname("HMAC"))) == NULL - || EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_MD, m) <= 0 - || EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_KEY, basekey, bklen) <= 0 + 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) || !EVP_MAC_init(mctx) || !EVP_MAC_update(mctx, msg, msglen) - || !EVP_MAC_final(mctx, mac_res, maclen)) + || !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE)) goto err; ok = 1; @@ -212,10 +225,11 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, /* cleanup */ OPENSSL_cleanse(basekey, bklen); EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); EVP_MD_CTX_free(ctx); if (ok == 1) { - *mac = mac_res; + *out = mac_res; return 1; } diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index 6e5e65ea..7e89bbd6 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -18,7 +18,7 @@ extern unsigned int OPENSSL_ia32cap_P[4]; -# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) +# if defined(OPENSSL_CPUID_OBJ) /* * Purpose of these minimalistic and character-type-agnostic subroutines @@ -84,7 +84,7 @@ static variant_char *ossl_strchr(const variant_char *str, char srch) while((c = *str)) { if (c == srch) - return (variant_char *)str; + return (variant_char *)str; str++; } diff --git a/crypto/ct/ct_err.c b/crypto/ct/ct_err.c index 950c481c..f9b9b57b 100644 --- a/crypto/ct/ct_err.c +++ b/crypto/ct/ct_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,45 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CT_str_functs[] = { - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW, 0), "CTLOG_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_BASE64, 0), - "CTLOG_new_from_base64"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_CONF, 0), "ctlog_new_from_conf"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_CTX_NEW, 0), - "ctlog_store_load_ctx_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_FILE, 0), - "CTLOG_STORE_load_file"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_LOG, 0), - "ctlog_store_load_log"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_NEW, 0), "CTLOG_STORE_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_BASE64_DECODE, 0), "ct_base64_decode"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_POLICY_EVAL_CTX_NEW, 0), - "CT_POLICY_EVAL_CTX_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_V1_LOG_ID_FROM_PKEY, 0), - "ct_v1_log_id_from_pkey"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT, 0), "i2o_SCT"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_LIST, 0), "i2o_SCT_LIST"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_SIGNATURE, 0), "i2o_SCT_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT, 0), "o2i_SCT"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_LIST, 0), "o2i_SCT_LIST"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_SIGNATURE, 0), "o2i_SCT_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_NEW, 0), "SCT_CTX_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_VERIFY, 0), "SCT_CTX_verify"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW, 0), "SCT_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW_FROM_BASE64, 0), "SCT_new_from_base64"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET0_LOG_ID, 0), "SCT_set0_log_id"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_EXTENSIONS, 0), "SCT_set1_extensions"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_LOG_ID, 0), "SCT_set1_log_id"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_SIGNATURE, 0), "SCT_set1_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_LOG_ENTRY_TYPE, 0), - "SCT_set_log_entry_type"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_SIGNATURE_NID, 0), - "SCT_set_signature_nid"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_VERSION, 0), "SCT_set_version"}, - {0, NULL} -}; - static const ERR_STRING_DATA CT_str_reasons[] = { {ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), "base64 decode error"}, {ERR_PACK(ERR_LIB_CT, 0, CT_R_INVALID_LOG_ID_LENGTH), @@ -87,10 +48,8 @@ static const ERR_STRING_DATA CT_str_reasons[] = { int ERR_load_CT_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CT_str_functs[0].error) == NULL) { - ERR_load_strings_const(CT_str_functs); + if (ERR_reason_error_string(CT_str_reasons[0].error) == NULL) ERR_load_strings_const(CT_str_reasons); - } #endif return 1; } diff --git a/crypto/ctype.c b/crypto/ctype.c index e7aa6068..e7bc25b9 100644 --- a/crypto/ctype.c +++ b/crypto/ctype.c @@ -272,3 +272,9 @@ int ossl_toupper(int c) { return ossl_islower(c) ? c ^ case_change : c; } + +int ascii_isdigit(const char inchar) { + if (inchar > 0x2F && inchar < 0x3A) + return 1; + return 0; +} diff --git a/crypto/cversion.c b/crypto/cversion.c index aef84e9c..c81f56f4 100644 --- a/crypto/cversion.c +++ b/crypto/cversion.c @@ -11,12 +11,10 @@ #include "buildinf.h" -#if !OPENSSL_API_3 unsigned long OpenSSL_version_num(void) { return OPENSSL_VERSION_NUMBER; } -#endif unsigned int OPENSSL_version_major(void) { @@ -43,6 +41,8 @@ const char *OPENSSL_version_build_metadata(void) return OPENSSL_VERSION_BUILD_METADATA_STR; } +extern char ossl_cpu_info_str[]; + const char *OpenSSL_version(int t) { switch (t) { @@ -76,6 +76,11 @@ const char *OpenSSL_version(int t) #else return "MODULESDIR: N/A"; #endif + case OPENSSL_CPU_INFO: + if (OPENSSL_info(OPENSSL_INFO_CPU_SETTINGS) != NULL) + return ossl_cpu_info_str; + else + return "CPUINFO: N/A"; } return "not available"; } diff --git a/crypto/des/asm/crypt586.pl b/crypto/des/asm/crypt586.pl index ab5d1734..b611b4e9 100644 --- a/crypto/des/asm/crypt586.pl +++ b/crypto/des/asm/crypt586.pl @@ -13,8 +13,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/des/asm/des-586.pl b/crypto/des/asm/des-586.pl index 3d295388..483f1950 100644 --- a/crypto/des/asm/des-586.pl +++ b/crypto/des/asm/des-586.pl @@ -20,8 +20,7 @@ require "desboth.pl"; # format. # -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/des/asm/dest4-sparcv9.pl b/crypto/des/asm/dest4-sparcv9.pl index a7de3a51..0cf25add 100644 --- a/crypto/des/asm/dest4-sparcv9.pl +++ b/crypto/des/asm/dest4-sparcv9.pl @@ -34,8 +34,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $code.=<<___; #include "sparc_arch.h" diff --git a/crypto/des/build.info b/crypto/des/build.info index 474d14e2..774bad75 100644 --- a/crypto/des/build.info +++ b/crypto/des/build.info @@ -13,21 +13,20 @@ IF[{- !$disabled{asm} -}] ENDIF LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - set_key.c ecb_enc.c cbc_enc.c \ - ecb3_enc.c cfb64enc.c cfb64ede.c cfb_enc.c \ +$COMMON=set_key.c ecb3_enc.c $DESASM +SOURCE[../../libcrypto]=$COMMON\ + ecb_enc.c cbc_enc.c \ + cfb64enc.c cfb64ede.c cfb_enc.c \ ofb64ede.c ofb64enc.c ofb_enc.c \ str2key.c pcbc_enc.c qud_cksm.c rand_key.c \ - $DESASM \ fcrypt.c xcbc_enc.c cbc_cksm.c +SOURCE[../../providers/fips]=$COMMON GENERATE[des_enc-sparc.S]=asm/des_enc.m4 -GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl INCLUDE[dest4-sparcv9.o]=.. -GENERATE[des-586.s]=asm/des-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[des-586.s]=asm/des-586.pl DEPEND[des-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl -GENERATE[crypt586.s]=asm/crypt586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[crypt586.s]=asm/crypt586.pl DEPEND[crypt586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index 524cac5b..84f1f8b9 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -16,6 +16,8 @@ #include "internal/asn1_int.h" #include "internal/evp_int.h" #include +#include +#include "internal/param_build.h" /* * i2d/d2i like DH parameter functions which use the appropriate routine for @@ -181,7 +183,7 @@ static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); goto dherr; } - /* Calculate public key */ + /* Calculate public key, increments dirty_cnt */ if (!DH_generate_key(dh)) goto dherr; @@ -255,6 +257,7 @@ static int dh_param_decode(EVP_PKEY *pkey, DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); return 0; } + dh->dirty_cnt++; EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); return 1; } @@ -415,6 +418,7 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942) } } else to->length = from->length; + to->dirty_cnt++; return 1; } @@ -540,6 +544,59 @@ static int dh_pkey_param_check(const EVP_PKEY *pkey) return DH_check_ex(dh); } +static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.dh->dirty_cnt; +} + +static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) +{ + DH *dh = pk->pkey.dh; + OSSL_PARAM_BLD tmpl; + const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh); + const BIGNUM *pub_key = DH_get0_pub_key(dh); + const BIGNUM *priv_key = DH_get0_priv_key(dh); + OSSL_PARAM *params; + void *provkey = NULL; + + if (p == NULL || g == NULL) + return NULL; + + ossl_param_bld_init(&tmpl); + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g)) + return NULL; + + if (q != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)) + return NULL; + } + + /* + * This may be used to pass domain parameters only without any key data - + * so "pub_key" is optional. We can never have a "priv_key" without a + * corresponding "pub_key" though. + */ + if (pub_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key)) + return NULL; + + if (priv_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY, + priv_key)) + return NULL; + } + } + + params = ossl_param_bld_to_param(&tmpl); + + /* We export, the provider imports */ + provkey = evp_keymgmt_importkey(keymgmt, params); + + ossl_param_bld_free(params); + return provkey; +} + const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { EVP_PKEY_DH, EVP_PKEY_DH, @@ -576,7 +633,12 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { 0, dh_pkey_public_check, - dh_pkey_param_check + dh_pkey_param_check, + + 0, 0, 0, 0, + + dh_pkey_dirty_cnt, + dh_pkey_export_to, }; const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c index aabdfa83..71379d73 100644 --- a/crypto/dh/dh_asn1.c +++ b/crypto/dh/dh_asn1.c @@ -27,6 +27,8 @@ static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, DH_free((DH *)*pval); *pval = NULL; return 2; + } else if (operation == ASN1_OP_D2I_POST) { + ((DH *)*pval)->dirty_cnt++; } return 1; } diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 8be2b91a..2d19a8f1 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 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 @@ -24,12 +24,17 @@ int DH_check_params_ex(const DH *dh) { int errflags = 0; - (void)DH_check_params(dh, &errflags); + if (!DH_check_params(dh, &errflags)) + return 0; if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME); if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_NOT_SUITABLE_GENERATOR); + if ((errflags & DH_MODULUS_TOO_SMALL) != 0) + DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_MODULUS_TOO_SMALL); + if ((errflags & DH_MODULUS_TOO_LARGE) != 0) + DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_MODULUS_TOO_LARGE); return errflags == 0; } @@ -57,6 +62,10 @@ int DH_check_params(const DH *dh, int *ret) goto err; if (BN_cmp(dh->g, tmp) >= 0) *ret |= DH_NOT_SUITABLE_GENERATOR; + if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) + *ret |= DH_MODULUS_TOO_SMALL; + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) + *ret |= DH_MODULUS_TOO_LARGE; ok = 1; err: @@ -67,18 +76,14 @@ int DH_check_params(const DH *dh, int *ret) /*- * Check that p is a safe prime and - * if g is 2, 3 or 5, check that it is a suitable generator - * where - * for 2, p mod 24 == 11 - * for 3, p mod 12 == 5 - * for 5, p mod 10 == 3 or 7 - * should hold. + * g is a suitable generator. */ int DH_check_ex(const DH *dh) { int errflags = 0; - (void)DH_check(dh, &errflags); + if (!DH_check(dh, &errflags)) + return 0; if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) DHerr(DH_F_DH_CHECK_EX, DH_R_NOT_SUITABLE_GENERATOR); @@ -94,6 +99,10 @@ int DH_check_ex(const DH *dh) DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_PRIME); if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0) DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_SAFE_PRIME); + if ((errflags & DH_MODULUS_TOO_SMALL) != 0) + DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_SMALL); + if ((errflags & DH_MODULUS_TOO_LARGE) != 0) + DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_LARGE); return errflags == 0; } @@ -102,10 +111,11 @@ int DH_check(const DH *dh, int *ret) { int ok = 0, r; BN_CTX *ctx = NULL; - BN_ULONG l; BIGNUM *t1 = NULL, *t2 = NULL; - *ret = 0; + if (!DH_check_params(dh, ret)) + return 0; + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -139,21 +149,7 @@ int DH_check(const DH *dh, int *ret) *ret |= DH_CHECK_INVALID_Q_VALUE; if (dh->j && BN_cmp(dh->j, t1)) *ret |= DH_CHECK_INVALID_J_VALUE; - - } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { - l = BN_mod_word(dh->p, 24); - if (l == (BN_ULONG)-1) - goto err; - if (l != 11) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { - l = BN_mod_word(dh->p, 10); - if (l == (BN_ULONG)-1) - goto err; - if ((l != 3) && (l != 7)) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } else - *ret |= DH_UNABLE_TO_CHECK_GENERATOR; + } r = BN_is_prime_ex(dh->p, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL); if (r < 0) @@ -180,7 +176,8 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) { int errflags = 0; - (void)DH_check(dh, &errflags); + if (!DH_check_pub_key(dh, pub_key, &errflags)) + return 0; if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0) DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_SMALL); diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index a78a6a9c..e5eb3238 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -13,41 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA DH_str_functs[] = { - {ERR_PACK(ERR_LIB_DH, DH_F_COMPUTE_KEY, 0), "compute_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DHPARAMS_PRINT_FP, 0), "DHparams_print_fp"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_BUF2KEY, 0), "dh_buf2key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS, 0), - "dh_builtin_genparams"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_DECRYPT, 0), "dh_cms_decrypt"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_PEERKEY, 0), "dh_cms_set_peerkey"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0), - "dh_cms_set_shared_info"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_KEY2BUF, 0), "dh_key2buf"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_DUP, 0), "DH_meth_dup"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_NEW, 0), "DH_meth_new"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_SET1_NAME, 0), "DH_meth_set1_name"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_BY_NID, 0), "DH_new_by_nid"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_METHOD, 0), "DH_new_method"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PARAM_DECODE, 0), "dh_param_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PKEY_PUBLIC_CHECK, 0), - "dh_pkey_public_check"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_DECODE, 0), "dh_priv_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_ENCODE, 0), "dh_priv_encode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PUB_DECODE, 0), "dh_pub_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PUB_ENCODE, 0), "dh_pub_encode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DO_DH_PRINT, 0), "do_dh_print"}, - {ERR_PACK(ERR_LIB_DH, DH_F_GENERATE_KEY, 0), "generate_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_CTRL_STR, 0), "pkey_dh_ctrl_str"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_DERIVE, 0), "pkey_dh_derive"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_INIT, 0), "pkey_dh_init"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_KEYGEN, 0), "pkey_dh_keygen"}, - {0, NULL} -}; - static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"}, @@ -76,6 +41,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_SMALL), "modulus too small"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), "not suitable generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"}, @@ -94,10 +60,8 @@ static const ERR_STRING_DATA DH_str_reasons[] = { int ERR_load_DH_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DH_str_functs[0].error) == NULL) { - ERR_load_strings_const(DH_str_functs); + if (ERR_reason_error_string(DH_str_reasons[0].error) == NULL) ERR_load_strings_const(DH_str_reasons); - } #endif return 1; } diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 1e5c7ca2..76d6ad01 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 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 @@ -30,30 +30,29 @@ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, /*- * We generate DH parameters as follows - * find a prime q which is prime_len/2 bits long. - * p=(2*q)+1 or (p-1)/2 = q - * For this case, g is a generator if - * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. - * Since the factors of p-1 are q and 2, we just need to check - * g^2 mod p != 1 and g^q mod p != 1. + * find a prime p which is prime_len bits long, + * where q=(p-1)/2 is also prime. + * In the following we assume that g is not 0, 1 or p-1, since it + * would generate only trivial subgroups. + * For this case, g is a generator of the order-q subgroup if + * g^q mod p == 1. + * Or in terms of the Legendre symbol: (g/p) == 1. * * Having said all that, * there is another special case method for the generators 2, 3 and 5. - * for 2, p mod 24 == 11 - * for 3, p mod 12 == 5 <<<<< does not work for safe primes. - * for 5, p mod 10 == 3 or 7 + * Using the quadratic reciprocity law it is possible to solve + * (g/p) == 1 for the special values 2, 3, 5: + * (2/p) == 1 if p mod 8 == 1 or 7. + * (3/p) == 1 if p mod 12 == 1 or 11. + * (5/p) == 1 if p mod 5 == 1 or 4. + * See for instance: https://en.wikipedia.org/wiki/Legendre_symbol * - * Thanks to Phil Karn for the pointers about the - * special generators and for answering some of my questions. - * - * I've implemented the second simple method :-). - * Since DH should be using a safe prime (both p and q are prime), - * this generator function can take a very very long time to run. - */ -/* - * Actually there is no reason to insist that 'generator' be a generator. - * It's just as OK (and in some sense better) to use a generator of the - * order-q subgroup. + * Since all safe primes > 7 must satisfy p mod 12 == 11 + * and all safe primes > 11 must satisfy p mod 5 != 1 + * we can further improve the condition for g = 2, 3 and 5: + * for 2, p mod 24 == 23 + * for 3, p mod 12 == 11 + * for 5, p mod 60 == 59 */ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) @@ -62,6 +61,16 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, int g, ok = -1; BN_CTX *ctx = NULL; + if (prime_len > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_MODULUS_TOO_LARGE); + return 0; + } + + if (prime_len < DH_MIN_MODULUS_BITS) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_MODULUS_TOO_SMALL); + return 0; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -84,17 +93,14 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1, 24)) goto err; - if (!BN_set_word(t2, 11)) + if (!BN_set_word(t2, 23)) goto err; g = 2; } else if (generator == DH_GENERATOR_5) { - if (!BN_set_word(t1, 10)) + if (!BN_set_word(t1, 60)) goto err; - if (!BN_set_word(t2, 3)) + if (!BN_set_word(t2, 59)) goto err; - /* - * BN_set_word(t3,7); just have to miss out on these ones :-( - */ g = 5; } else { /* @@ -102,9 +108,9 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, * not: since we are using safe primes, it will generate either an * order-q or an order-2q group, which both is OK */ - if (!BN_set_word(t1, 2)) + if (!BN_set_word(t1, 12)) goto err; - if (!BN_set_word(t2, 1)) + if (!BN_set_word(t2, 11)) goto err; g = generator; } @@ -115,6 +121,7 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, goto err; if (!BN_set_word(ret->g, g)) goto err; + ret->dirty_cnt++; ok = 1; err: if (ok == -1) { diff --git a/crypto/dh/dh_kdf.c b/crypto/dh/dh_kdf.c index 03b1e4ed..a1bbea30 100644 --- a/crypto/dh/dh_kdf.c +++ b/crypto/dh/dh_kdf.c @@ -11,10 +11,12 @@ #ifndef OPENSSL_NO_CMS # include +# include # include # include # include # include +# include int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, @@ -23,8 +25,12 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, { int ret = 0, nid; EVP_KDF_CTX *kctx = NULL; - const EVP_KDF *kdf = NULL; + EVP_KDF *kdf = NULL; const char *oid_sn; + OSSL_PARAM params[5], *p = params; + const char *mdname = EVP_MD_name(md); + const OSSL_PROVIDER *prov = EVP_MD_provider(md); + OPENSSL_CTX *provctx = ossl_provider_library_context(prov); nid = OBJ_obj2nid(key_oid); if (nid == NID_undef) @@ -33,20 +39,24 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, if (oid_sn == NULL) return 0; - kdf = EVP_get_kdfbyname(SN_x942kdf); - if (kdf == NULL) + kdf = EVP_KDF_fetch(provctx, OSSL_KDF_NAME_X942KDF, NULL); + if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) goto err; - kctx = EVP_KDF_CTX_new(kdf); - ret = - kctx != NULL - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, md) > 0 - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, Z, Zlen) > 0 - && (ukm == NULL - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_UKM, ukm, ukmlen) > 0) - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_CEK_ALG, oid_sn) > 0 + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, strlen(mdname) + 1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)Z, Zlen); + if (ukm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, + (unsigned char *)ukm, ukmlen); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + (char *)oid_sn, strlen(oid_sn) + 1); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_CTX_set_params(kctx, params) > 0 && EVP_KDF_derive(kctx, out, outlen) > 0; err: EVP_KDF_CTX_free(kctx); + EVP_KDF_free(kdf); return ret; } #endif /* OPENSSL_NO_CMS */ diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 6b3a1247..8731cc2c 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.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 @@ -87,6 +87,11 @@ static int generate_key(DH *dh) return 0; } + if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_SMALL); + return 0; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -125,6 +130,15 @@ static int generate_key(DH *dh) l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; if (!BN_priv_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) goto err; + /* + * We handle just one known case where g is a quadratic non-residue: + * for g = 2: p % 8 == 3 + */ + if (BN_is_word(dh->g, DH_GENERATOR_2) && !BN_is_bit_set(dh->p, 2)) { + /* clear bit 0, since it won't be a secret anyway */ + if (!BN_clear_bit(priv_key, 0)) + goto err; + } } } @@ -136,15 +150,16 @@ static int generate_key(DH *dh) BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) { - BN_free(prk); + BN_clear_free(prk); goto err; } /* We MUST free prk before any further use of priv_key */ - BN_free(prk); + BN_clear_free(prk); } dh->pub_key = pub_key; dh->priv_key = priv_key; + dh->dirty_cnt++; ok = 1; err: if (ok != 1) @@ -171,6 +186,11 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; } + if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_SMALL); + return 0; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 70298edd..0382e442 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -209,6 +209,7 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) dh->length = BN_num_bits(q); } + dh->dirty_cnt++; return 1; } @@ -234,14 +235,15 @@ void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { if (pub_key != NULL) { - BN_free(dh->pub_key); + BN_clear_free(dh->pub_key); dh->pub_key = pub_key; } if (priv_key != NULL) { - BN_free(dh->priv_key); + BN_clear_free(dh->priv_key); dh->priv_key = priv_key; } + dh->dirty_cnt++; return 1; } diff --git a/crypto/dh/dh_locl.h b/crypto/dh/dh_locl.h index bb64cde9..a9041e94 100644 --- a/crypto/dh/dh_locl.h +++ b/crypto/dh/dh_locl.h @@ -10,6 +10,8 @@ #include #include "internal/refcount.h" +#define DH_MIN_MODULUS_BITS 512 + struct dh_st { /* * This first argument is used to pick up errors when a DH is passed @@ -35,6 +37,9 @@ struct dh_st { const DH_METHOD *meth; ENGINE *engine; CRYPTO_RWLOCK *lock; + + /* Provider data */ + size_t dirty_cnt; /* If any key material changes, increment this */ }; struct dh_method { diff --git a/crypto/dh/dh_rfc7919.c b/crypto/dh/dh_rfc7919.c index e9f3eafb..4e676fd3 100644 --- a/crypto/dh/dh_rfc7919.c +++ b/crypto/dh/dh_rfc7919.c @@ -22,6 +22,7 @@ static DH *dh_param_init(const BIGNUM *p, int32_t nbits) dh->p = (BIGNUM *)p; dh->g = (BIGNUM *)&_bignum_const_2; dh->length = nbits; + dh->dirty_cnt++; return dh; } diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index ef6fc763..4e0ed019 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -8,14 +8,16 @@ */ #include -#include "internal/cryptlib.h" #include #include -#include "dsa_locl.h" #include #include +#include +#include "internal/cryptlib.h" #include "internal/asn1_int.h" #include "internal/evp_int.h" +#include "internal/param_build.h" +#include "dsa_locl.h" static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { @@ -63,6 +65,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) goto err; } + dsa->dirty_cnt++; ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DSA(pkey, dsa); return 1; @@ -185,6 +188,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) goto dsaerr; } + dsa->dirty_cnt++; EVP_PKEY_assign_DSA(pkey, dsa); ret = 1; @@ -300,6 +304,7 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) return 0; BN_free(to->pkey.dsa->g); to->pkey.dsa->g = a; + to->pkey.dsa->dirty_cnt++; return 1; } @@ -381,6 +386,7 @@ static int dsa_param_decode(EVP_PKEY *pkey, DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); return 0; } + dsa->dirty_cnt++; EVP_PKEY_assign_DSA(pkey, dsa); return 1; } @@ -417,6 +423,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); return 0; } + dsa->dirty_cnt++; EVP_PKEY_assign_DSA(pkey, dsa); return 1; } @@ -514,6 +521,56 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) } +static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.dsa->dirty_cnt; +} + +static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) +{ + DSA *dsa = pk->pkey.dsa; + OSSL_PARAM_BLD tmpl; + const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa); + const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa); + const BIGNUM *priv_key = DSA_get0_priv_key(dsa); + OSSL_PARAM *params; + void *provkey = NULL; + + if (p == NULL || q == NULL || g == NULL) + return NULL; + + ossl_param_bld_init(&tmpl); + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q) + || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g)) + return NULL; + + /* + * This may be used to pass domain parameters only without any key data - + * so "pub_key" is optional. We can never have a "priv_key" without a + * corresponding "pub_key" though. + */ + if (pub_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY, + pub_key)) + return NULL; + + if (priv_key != NULL) { + if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY, + priv_key)) + return NULL; + } + } + + params = ossl_param_bld_to_param(&tmpl); + + /* We export, the provider imports */ + provkey = evp_keymgmt_importkey(keymgmt, params); + + ossl_param_bld_free(params); + return provkey; +} + /* NB these are sorted in pkey_id order, lowest first */ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = { @@ -570,5 +627,13 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = { int_dsa_free, dsa_pkey_ctrl, old_dsa_priv_decode, - old_dsa_priv_encode} + old_dsa_priv_encode, + + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + + dsa_pkey_dirty_cnt, + dsa_pkey_export_to + } }; diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c index acf80c65..eddcc118 100644 --- a/crypto/dsa/dsa_asn1.c +++ b/crypto/dsa/dsa_asn1.c @@ -13,13 +13,7 @@ #include #include #include - -ASN1_SEQUENCE(DSA_SIG) = { - ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) -} static_ASN1_SEQUENCE_END(DSA_SIG) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA_SIG, DSA_SIG, DSA_SIG) +#include "internal/asn1_dsa.h" DSA_SIG *DSA_SIG_new(void) { @@ -38,6 +32,74 @@ void DSA_SIG_free(DSA_SIG *sig) 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) diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index f664dd57..f4d187e4 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,36 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA DSA_str_functs[] = { - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT, 0), "DSAparams_print"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT_FP, 0), "DSAparams_print_fp"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN, 0), - "dsa_builtin_paramgen"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN2, 0), - "dsa_builtin_paramgen2"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, 0), "DSA_do_sign"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_VERIFY, 0), "DSA_do_verify"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_DUP, 0), "DSA_meth_dup"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_NEW, 0), "DSA_meth_new"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_SET1_NAME, 0), "DSA_meth_set1_name"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_NEW_METHOD, 0), "DSA_new_method"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PARAM_DECODE, 0), "dsa_param_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRINT_FP, 0), "DSA_print_fp"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRIV_DECODE, 0), "dsa_priv_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRIV_ENCODE, 0), "dsa_priv_encode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PUB_DECODE, 0), "dsa_pub_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PUB_ENCODE, 0), "dsa_pub_encode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIGN, 0), "DSA_sign"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIGN_SETUP, 0), "DSA_sign_setup"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIG_NEW, 0), "DSA_SIG_new"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_OLD_DSA_PRIV_DECODE, 0), - "old_dsa_priv_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, 0), "pkey_dsa_ctrl"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL_STR, 0), "pkey_dsa_ctrl_str"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_KEYGEN, 0), "pkey_dsa_keygen"}, - {0, NULL} -}; - static const ERR_STRING_DATA DSA_str_reasons[] = { {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error"}, @@ -52,6 +22,8 @@ static const ERR_STRING_DATA DSA_str_reasons[] = { "invalid digest type"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_PARAMETERS), "invalid parameters"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY), + "missing private key"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR), @@ -67,10 +39,8 @@ static const ERR_STRING_DATA DSA_str_reasons[] = { int ERR_load_DSA_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) { - ERR_load_strings_const(DSA_str_functs); + if (ERR_reason_error_string(DSA_str_reasons[0].error) == NULL) ERR_load_strings_const(DSA_str_reasons); - } #endif return 1; } diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 858f1273..14cb8e9f 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -281,6 +281,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, ret->p = BN_dup(p); ret->q = BN_dup(q); ret->g = BN_dup(g); + ret->dirty_cnt++; if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok = 0; goto err; @@ -598,6 +599,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, ok = -1; goto err; } + ret->dirty_cnt++; if (counter_ret != NULL) *counter_ret = counter; if (h_ret != NULL) diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index 333bff95..86f79b80 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -65,6 +65,7 @@ static int dsa_builtin_keygen(DSA *dsa) dsa->priv_key = priv_key; dsa->pub_key = pub_key; + dsa->dirty_cnt++; ok = 1; err: diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 1068f1da..034300fc 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -273,6 +273,7 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) BN_free(d->g); d->g = g; } + d->dirty_cnt++; return 1; } @@ -303,6 +304,7 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) BN_free(d->priv_key); d->priv_key = priv_key; } + d->dirty_cnt++; return 1; } diff --git a/crypto/dsa/dsa_locl.h b/crypto/dsa/dsa_locl.h index 5c464e7c..e56ff069 100644 --- a/crypto/dsa/dsa_locl.h +++ b/crypto/dsa/dsa_locl.h @@ -31,6 +31,9 @@ struct dsa_st { /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; CRYPTO_RWLOCK *lock; + + /* Provider data */ + size_t dirty_cnt; /* If any key material changes, increment this */ }; struct DSA_SIG_st { diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index a9384a0f..08f2e9f0 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -72,6 +72,10 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) reason = DSA_R_MISSING_PARAMETERS; goto err; } + if (dsa->priv_key == NULL) { + reason = DSA_R_MISSING_PRIVATE_KEY; + goto err; + } ret = DSA_SIG_new(); if (ret == NULL) @@ -195,6 +199,10 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS); return 0; } + if (dsa->priv_key == NULL) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PRIVATE_KEY); + return 0; + } k = BN_new(); l = BN_new(); diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c index 5e985134..d076c7eb 100644 --- a/crypto/dso/dso_dlfcn.c +++ b/crypto/dso/dso_dlfcn.c @@ -27,8 +27,7 @@ # endif # include # define HAVE_DLINFO 1 -# if defined(__CYGWIN__) || \ - defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ +# if defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ (defined(__osf__) && !defined(RTLD_NEXT)) || \ (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ defined(__ANDROID__) diff --git a/crypto/dso/dso_err.c b/crypto/dso/dso_err.c index 03b0b5b4..8a4d9a81 100644 --- a/crypto/dso/dso_err.c +++ b/crypto/dso/dso_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,48 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA DSO_str_functs[] = { - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_BIND_FUNC, 0), "dlfcn_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_LOAD, 0), "dlfcn_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_MERGER, 0), "dlfcn_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_NAME_CONVERTER, 0), - "dlfcn_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_UNLOAD, 0), "dlfcn_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_BIND_FUNC, 0), "dl_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_LOAD, 0), "dl_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_MERGER, 0), "dl_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_NAME_CONVERTER, 0), "dl_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_UNLOAD, 0), "dl_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_BIND_FUNC, 0), "DSO_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_CONVERT_FILENAME, 0), - "DSO_convert_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_CTRL, 0), "DSO_ctrl"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_FREE, 0), "DSO_free"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_GET_FILENAME, 0), "DSO_get_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_GLOBAL_LOOKUP, 0), "DSO_global_lookup"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_LOAD, 0), "DSO_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_MERGE, 0), "DSO_merge"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_NEW_METHOD, 0), "DSO_new_method"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_PATHBYADDR, 0), "DSO_pathbyaddr"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_SET_FILENAME, 0), "DSO_set_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_UP_REF, 0), "DSO_up_ref"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_BIND_SYM, 0), "vms_bind_sym"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_LOAD, 0), "vms_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_MERGER, 0), "vms_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_UNLOAD, 0), "vms_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_BIND_FUNC, 0), "win32_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_GLOBALLOOKUP, 0), "win32_globallookup"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_JOINER, 0), "win32_joiner"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_LOAD, 0), "win32_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_MERGER, 0), "win32_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_NAME_CONVERTER, 0), - "win32_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_PATHBYADDR, 0), ""}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_SPLITTER, 0), "win32_splitter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_UNLOAD, 0), "win32_unload"}, - {0, NULL} -}; - static const ERR_STRING_DATA DSO_str_reasons[] = { {ERR_PACK(ERR_LIB_DSO, 0, DSO_R_CTRL_FAILED), "control command failed"}, {ERR_PACK(ERR_LIB_DSO, 0, DSO_R_DSO_ALREADY_LOADED), "dso already loaded"}, @@ -91,10 +49,8 @@ static const ERR_STRING_DATA DSO_str_reasons[] = { int ERR_load_DSO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) { - ERR_load_strings_const(DSO_str_functs); + if (ERR_reason_error_string(DSO_str_reasons[0].error) == NULL) ERR_load_strings_const(DSO_str_reasons); - } #endif return 1; } diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl index 43a675b4..4e6bfef4 100755 --- a/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -33,9 +33,10 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +200% means 3x improvement. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -43,9 +44,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $code.=<<___; diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl index 4daa8cc0..2bcf130b 100644 --- a/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -31,15 +31,18 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +400% means 5x improvement. -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; { diff --git a/crypto/ec/asm/ecp_nistz256-avx2.pl b/crypto/ec/asm/ecp_nistz256-avx2.pl index b8f78349..275aabb4 100755 --- a/crypto/ec/asm/ecp_nistz256-avx2.pl +++ b/crypto/ec/asm/ecp_nistz256-avx2.pl @@ -15,9 +15,10 @@ # S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with # 256 Bit Primes" -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -26,7 +27,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/ec/asm/ecp_nistz256-ppc64.pl b/crypto/ec/asm/ecp_nistz256-ppc64.pl index c06a7c0d..94438010 100755 --- a/crypto/ec/asm/ecp_nistz256-ppc64.pl +++ b/crypto/ec/asm/ecp_nistz256-ppc64.pl @@ -25,15 +25,18 @@ # POWER7 +260-530% # POWER8 +220-340% -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my $sp="r1"; diff --git a/crypto/ec/asm/ecp_nistz256-sparcv9.pl b/crypto/ec/asm/ecp_nistz256-sparcv9.pl index 2bf697a3..3956a4a9 100755 --- a/crypto/ec/asm/ecp_nistz256-sparcv9.pl +++ b/crypto/ec/asm/ecp_nistz256-sparcv9.pl @@ -31,8 +31,7 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +200% means 3x improvement. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $code.=<<___; #include "sparc_arch.h" @@ -2301,7 +2300,6 @@ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); # !in1infty, !in2infty and result of check for zero. $code.=<<___; -.globl ecp_nistz256_point_add_vis3 .align 32 ecp_nistz256_point_add_vis3: save %sp,-STACK64_FRAME-32*18-32,%sp diff --git a/crypto/ec/asm/ecp_nistz256-x86.pl b/crypto/ec/asm/ecp_nistz256-x86.pl index 8f6b1264..b1b0b6bc 100755 --- a/crypto/ec/asm/ecp_nistz256-x86.pl +++ b/crypto/ec/asm/ecp_nistz256-x86.pl @@ -42,8 +42,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl index 7fbc3eb4..53b60ddb 100755 --- a/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -40,9 +40,10 @@ # higher - for ECDSA sign, relatively fastest server-side operation. # Keep in mind that +100% means 2x improvement. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -51,7 +52,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/ec/asm/x25519-ppc64.pl b/crypto/ec/asm/x25519-ppc64.pl index 5f6bff18..e2e0a14f 100755 --- a/crypto/ec/asm/x25519-ppc64.pl +++ b/crypto/ec/asm/x25519-ppc64.pl @@ -27,15 +27,18 @@ # this module delivers more than 2x improvement, and when it does, # from 12% to 30% improvement was measured... -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my $sp = "r1"; diff --git a/crypto/ec/asm/x25519-x86_64.pl b/crypto/ec/asm/x25519-x86_64.pl index b32a0415..14583bd7 100755 --- a/crypto/ec/asm/x25519-x86_64.pl +++ b/crypto/ec/asm/x25519-x86_64.pl @@ -61,9 +61,10 @@ # C implementation, so that comparison is always against # 2^51 radix; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -72,7 +73,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/ec/build.info b/crypto/ec/build.info index 5e9778d3..2befa3e7 100644 --- a/crypto/ec/build.info +++ b/crypto/ec/build.info @@ -18,7 +18,8 @@ IF[{- !$disabled{asm} -}] $ECASM_mips32= $ECASM_mips64= - $ECASM_s390x= + $ECASM_s390x=ecp_s390x_nistp.c + $ECDEF_s390x=S390X_NISTP_ASM $ECASM_armv4=ecp_nistz256.c ecp_nistz256-armv4.S $ECDEF_armv4=ECP_NISTZ256_ASM @@ -43,36 +44,39 @@ IF[{- !$disabled{asm} -}] ENDIF LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ - ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \ - ec2_smpl.c ec_ameth.c ec_pmeth.c eck_prn.c \ + +$COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ + ec_curve.c ec_check.c ec_print.c ec_key.c ec_asn1.c \ + ec2_smpl.c \ ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \ - ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \ - ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \ + ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c \ + ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \ curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \ curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ $ECASM +SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ec_err.c \ + ecdh_kdf.c eck_prn.c DEFINE[../../libcrypto]=$ECDEF +SOURCE[../../providers/fips]=$COMMON +DEFINE[../../providers/fips]=$ECDEF -GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl -GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl -GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl -GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl INCLUDE[ecp_nistz256-sparcv9.o]=.. -GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME) +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 $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl INCLUDE[ecp_nistz256-armv8.o]=.. -GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl -GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl $(PERLASM_SCHEME) -GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl $(PERLASM_SCHEME) +GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl +GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl INCLUDE[curve448/arch_32/f_impl.o]=curve448/arch_32 curve448 INCLUDE[curve448/f_generic.o]=curve448/arch_32 curve448 diff --git a/crypto/ec/curve448/curve448.c b/crypto/ec/curve448/curve448.c index 6236ad66..59f44795 100644 --- a/crypto/ec/curve448/curve448.c +++ b/crypto/ec/curve448/curve448.c @@ -501,9 +501,9 @@ struct smvt_control { }; #if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) -# define NUMTRAILINGZEROS __builtin_ctz +# define NUMTRAILINGZEROS __builtin_ctz #else -# define NUMTRAILINGZEROS numtrailingzeros +# define NUMTRAILINGZEROS numtrailingzeros static uint32_t numtrailingzeros(uint32_t i) { uint32_t tmp; diff --git a/crypto/ec/curve448/curve448_lcl.h b/crypto/ec/curve448/curve448_lcl.h index 3625e12a..9459f002 100644 --- a/crypto/ec/curve448/curve448_lcl.h +++ b/crypto/ec/curve448/curve448_lcl.h @@ -16,23 +16,24 @@ int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], void X448_public_from_private(uint8_t out_public_value[56], const uint8_t private_key[56]); -int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len); +int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, + size_t message_len, const uint8_t public_key[57], + const uint8_t private_key[57], const uint8_t *context, + size_t context_len); -int ED448_verify(const uint8_t *message, size_t message_len, +int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], const uint8_t *context, size_t context_len); -int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64], +int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, size_t context_len); -int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114], - const uint8_t public_key[57], const uint8_t *context, - size_t context_len); +int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], + const uint8_t signature[114], const uint8_t public_key[57], + const uint8_t *context, size_t context_len); -int ED448_public_from_private(uint8_t out_public_key[57], +int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], const uint8_t private_key[57]); #endif /* HEADER_CURVE448_LCL_H */ diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h index e66d3e38..b198f36e 100644 --- a/crypto/ec/curve448/ed448.h +++ b/crypto/ec/curve448/ed448.h @@ -38,6 +38,7 @@ * privkey (in): The private key. */ c448_error_t c448_ed448_derive_public_key( + OPENSSL_CTX *ctx, uint8_t pubkey [EDDSA_448_PUBLIC_BYTES], const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]); @@ -59,6 +60,7 @@ c448_error_t c448_ed448_derive_public_key( * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_sign( + OPENSSL_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], @@ -83,6 +85,7 @@ c448_error_t c448_ed448_sign( * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_sign_prehash( + OPENSSL_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], @@ -108,13 +111,14 @@ c448_error_t c448_ed448_sign_prehash( * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_verify(const uint8_t - signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t - pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, size_t message_len, - uint8_t prehashed, const uint8_t *context, - uint8_t context_len); +c448_error_t c448_ed448_verify(OPENSSL_CTX *ctx, + const uint8_t + signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t + pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t *message, size_t message_len, + uint8_t prehashed, const uint8_t *context, + uint8_t context_len); /* * EdDSA signature verification. @@ -134,6 +138,7 @@ c448_error_t c448_ed448_verify(const uint8_t * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_verify_prehash( + OPENSSL_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], @@ -189,6 +194,7 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( * ed (in): The EdDSA private key */ c448_error_t c448_ed448_convert_private_key_to_x448( + OPENSSL_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], const uint8_t ed[EDDSA_448_PRIVATE_BYTES]); diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c index ba362392..45b6c4ab 100644 --- a/crypto/ec/curve448/eddsa.c +++ b/crypto/ec/curve448/eddsa.c @@ -19,23 +19,30 @@ #define COFACTOR 4 -static c448_error_t oneshot_hash(uint8_t *out, size_t outlen, +static c448_error_t oneshot_hash(OPENSSL_CTX *ctx, uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); + EVP_MD *shake256 = NULL; + c448_error_t ret = C448_FAILURE; if (hashctx == NULL) return C448_FAILURE; - if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) - || !EVP_DigestUpdate(hashctx, in, inlen) - || !EVP_DigestFinalXOF(hashctx, out, outlen)) { - EVP_MD_CTX_free(hashctx); - return C448_FAILURE; - } + shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + if (shake256 == NULL) + goto err; + if (!EVP_DigestInit_ex(hashctx, shake256, NULL) + || !EVP_DigestUpdate(hashctx, in, inlen) + || !EVP_DigestFinalXOF(hashctx, out, outlen)) + goto err; + + ret = C448_SUCCESS; + err: EVP_MD_CTX_free(hashctx); - return C448_SUCCESS; + EVP_MD_free(shake256); + return ret; } static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) @@ -45,13 +52,15 @@ static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80; } -static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, +static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, + uint8_t prehashed, uint8_t for_prehash, const uint8_t *context, size_t context_len) { const char *dom_s = "SigEd448"; uint8_t dom[2]; + EVP_MD *shake256 = NULL; if (context_len > UINT8_MAX) return C448_FAILURE; @@ -60,27 +69,36 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, - (for_prehash == 0 ? 1 : 0)); dom[1] = (uint8_t)context_len; - if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) - || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s)) - || !EVP_DigestUpdate(hashctx, dom, sizeof(dom)) - || !EVP_DigestUpdate(hashctx, context, context_len)) + shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + if (shake256 == NULL) return C448_FAILURE; + if (!EVP_DigestInit_ex(hashctx, shake256, NULL) + || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s)) + || !EVP_DigestUpdate(hashctx, dom, sizeof(dom)) + || !EVP_DigestUpdate(hashctx, context, context_len)) { + EVP_MD_free(shake256); + return C448_FAILURE; + } + + EVP_MD_free(shake256); return C448_SUCCESS; } /* In this file because it uses the hash */ c448_error_t c448_ed448_convert_private_key_to_x448( + OPENSSL_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], const uint8_t ed [EDDSA_448_PRIVATE_BYTES]) { /* pass the private key through oneshot_hash function */ /* and keep the first X448_PRIVATE_BYTES bytes */ - return oneshot_hash(x, X448_PRIVATE_BYTES, ed, + return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed, EDDSA_448_PRIVATE_BYTES); } c448_error_t c448_ed448_derive_public_key( + OPENSSL_CTX *ctx, uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES]) { @@ -90,7 +108,8 @@ c448_error_t c448_ed448_derive_public_key( unsigned int c; curve448_point_t p; - if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey, + if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser), + privkey, EDDSA_448_PRIVATE_BYTES)) return C448_FAILURE; @@ -123,6 +142,7 @@ c448_error_t c448_ed448_derive_public_key( } c448_error_t c448_ed448_sign( + OPENSSL_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], @@ -148,7 +168,7 @@ c448_error_t c448_ed448_sign( */ uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2]; - if (!oneshot_hash(expanded, sizeof(expanded), privkey, + if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey, EDDSA_448_PRIVATE_BYTES)) goto err; clamp(expanded); @@ -156,7 +176,8 @@ c448_error_t c448_ed448_sign( EDDSA_448_PRIVATE_BYTES); /* Hash to create the nonce */ - if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, + context_len) || !EVP_DigestUpdate(hashctx, expanded + EDDSA_448_PRIVATE_BYTES, EDDSA_448_PRIVATE_BYTES) @@ -197,7 +218,7 @@ c448_error_t c448_ed448_sign( uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; /* Compute the challenge */ - if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len) || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point)) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -228,17 +249,19 @@ c448_error_t c448_ed448_sign( } c448_error_t c448_ed448_sign_prehash( + OPENSSL_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, size_t context_len) { - return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context, - context_len); + return c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1, + context, context_len); } c448_error_t c448_ed448_verify( + OPENSSL_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, @@ -291,7 +314,7 @@ c448_error_t c448_ed448_verify( uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; if (hashctx == NULL - || !hash_init_with_dom(hashctx, prehashed, 0, context, + || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len) || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) @@ -321,52 +344,54 @@ c448_error_t c448_ed448_verify( } c448_error_t c448_ed448_verify_prehash( + OPENSSL_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, uint8_t context_len) { - return c448_ed448_verify(signature, pubkey, hash, 64, 1, context, + return c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context, context_len); } -int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len) +int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, + size_t message_len, const uint8_t public_key[57], + const uint8_t private_key[57], const uint8_t *context, + size_t context_len) { - return c448_ed448_sign(out_sig, private_key, public_key, message, + return c448_ed448_sign(ctx, out_sig, private_key, public_key, message, message_len, 0, context, context_len) == C448_SUCCESS; } -int ED448_verify(const uint8_t *message, size_t message_len, +int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], const uint8_t *context, size_t context_len) { - return c448_ed448_verify(signature, public_key, message, message_len, 0, - context, (uint8_t)context_len) == C448_SUCCESS; + return c448_ed448_verify(ctx, signature, public_key, message, message_len, + 0, context, (uint8_t)context_len) == C448_SUCCESS; } -int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64], +int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, size_t context_len) { - return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash, + return c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, hash, context, context_len) == C448_SUCCESS; } -int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114], - const uint8_t public_key[57], const uint8_t *context, - size_t context_len) +int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], + const uint8_t signature[114], const uint8_t public_key[57], + const uint8_t *context, size_t context_len) { - return c448_ed448_verify_prehash(signature, public_key, hash, context, + return c448_ed448_verify_prehash(ctx, signature, public_key, hash, context, (uint8_t)context_len) == C448_SUCCESS; } -int ED448_public_from_private(uint8_t out_public_key[57], +int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], const uint8_t private_key[57]) { - return c448_ed448_derive_public_key(out_public_key, private_key) + return c448_ed448_derive_public_key(ctx, out_public_key, private_key) == C448_SUCCESS; } diff --git a/crypto/ec/ec2_oct.c b/crypto/ec/ec2_oct.c index ca36bb16..f9ee3be9 100644 --- a/crypto/ec/ec2_oct.c +++ b/crypto/ec/ec2_oct.c @@ -35,9 +35,10 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, const BIGNUM *x_, int y_bit, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *tmp, *x, *y, *z; int ret = 0, z0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; /* clear error queue */ ERR_clear_error(); @@ -47,6 +48,7 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, if (ctx == NULL) return 0; } +#endif y_bit = (y_bit != 0) ? 1 : 0; @@ -73,6 +75,7 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, if (!BN_GF2m_add(tmp, x, tmp)) goto err; if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) { +#ifndef FIPS_MODE unsigned long err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN @@ -81,8 +84,11 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); } else +#endif + { ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); + } goto err; } z0 = (BN_is_odd(z)) ? 1 : 0; @@ -101,7 +107,9 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -115,10 +123,12 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, unsigned char *buf, size_t len, BN_CTX *ctx) { size_t ret; - BN_CTX *new_ctx = NULL; int used_ctx = 0; BIGNUM *x, *y, *yxi; size_t field_len, i, skip; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if ((form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) @@ -152,11 +162,13 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, goto err; } +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); used_ctx = 1; @@ -218,13 +230,17 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, if (used_ctx) BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; err: if (used_ctx) BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return 0; } @@ -238,10 +254,12 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, { point_conversion_form_t form; int y_bit, m; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y, *yxi; size_t field_len, enc_len; int ret = 0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if (len == 0) { ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); @@ -281,11 +299,13 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, return 0; } +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x = BN_CTX_get(ctx); @@ -332,7 +352,9 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } #endif diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index ebd6f21e..f377b1f1 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -176,6 +176,7 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, { int ret = 0; BIGNUM *b; +#ifndef FIPS_MODE BN_CTX *new_ctx = NULL; if (ctx == NULL) { @@ -186,6 +187,7 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, goto err; } } +#endif BN_CTX_start(ctx); b = BN_CTX_get(ctx); if (b == NULL) @@ -205,7 +207,9 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -349,9 +353,11 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; int ret = 0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, a)) { if (!EC_POINT_copy(r, b)) @@ -365,11 +371,13 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, return 1; } +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x0 = BN_CTX_get(ctx); @@ -453,7 +461,9 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -494,11 +504,13 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { int ret = -1; - BN_CTX *new_ctx = NULL; BIGNUM *lh, *y2; int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, point)) return 1; @@ -510,11 +522,13 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, if (!point->Z_is_one) return -1; +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return -1; } +#endif BN_CTX_start(ctx); y2 = BN_CTX_get(ctx); @@ -546,7 +560,9 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -561,8 +577,10 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { BIGNUM *aX, *aY, *bX, *bY; - BN_CTX *new_ctx = NULL; int ret = -1; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, a)) { return EC_POINT_is_at_infinity(group, b) ? 0 : 1; @@ -575,11 +593,13 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1; } +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return -1; } +#endif BN_CTX_start(ctx); aX = BN_CTX_get(ctx); @@ -597,7 +617,9 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -605,18 +627,22 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; int ret = 0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) return 1; +#ifndef FIPS_MODE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x = BN_CTX_get(ctx); @@ -638,7 +664,9 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -696,8 +724,8 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group, /* s blinding: make sure lambda (s->Z here) is not zero */ do { - if (!BN_priv_rand(s->Z, BN_num_bits(group->field) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + if (!BN_priv_rand_ex(s->Z, BN_num_bits(group->field) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) { ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB); return 0; } @@ -711,8 +739,8 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group, /* r blinding: make sure lambda (r->Y here for storage) is not zero */ do { - if (!BN_priv_rand(r->Y, BN_num_bits(group->field) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + if (!BN_priv_rand_ex(r->Y, BN_num_bits(group->field) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) { ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB); return 0; } @@ -956,6 +984,9 @@ const EC_METHOD *EC_GF2m_simple_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ ec_GF2m_simple_ladder_pre, diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 35ff9488..2726f5d1 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -13,6 +13,9 @@ #include #include #include "internal/nelem.h" +#include "internal/asn1_dsa.h" + +#ifndef FIPS_MODE int EC_GROUP_get_basis_type(const EC_GROUP *group) { @@ -446,6 +449,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, unsigned char *buffer = NULL; const EC_POINT *point = NULL; point_conversion_form_t form; + ASN1_INTEGER *orig; if (params == NULL) { if ((ret = ECPARAMETERS_new()) == NULL) { @@ -496,8 +500,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB); goto err; } - ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); + ret->order = BN_to_ASN1_INTEGER(tmp, orig = ret->order); if (ret->order == NULL) { + ret->order = orig; ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB); goto err; } @@ -505,8 +510,9 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, /* set the cofactor (optional) */ tmp = EC_GROUP_get0_cofactor(group); if (tmp != NULL) { - ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); + ret->cofactor = BN_to_ASN1_INTEGER(tmp, orig = ret->cofactor); if (ret->cofactor == NULL) { + ret->cofactor = orig; ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB); goto err; } @@ -568,10 +574,12 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) { int ok = 0, tmp; - EC_GROUP *ret = NULL; + EC_GROUP *ret = NULL, *dup = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL; EC_POINT *point = NULL; long field_bits; + int curve_name = NID_undef; + BN_CTX *ctx = NULL; if (!params->fieldID || !params->fieldID->fieldType || !params->fieldID->p.ptr) { @@ -789,18 +797,79 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) goto err; } + /* + * Check if the explicit parameters group just created matches one of the + * built-in curves. + * + * We create a copy of the group just built, so that we can remove optional + * fields for the lookup: we do this to avoid the possibility that one of + * the optional parameters is used to force the library into using a less + * performant and less secure EC_METHOD instead of the specialized one. + * In any case, `seed` is not really used in any computation, while a + * cofactor different from the one in the built-in table is just + * mathematically wrong anyway and should not be used. + */ + if ((ctx = BN_CTX_new()) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB); + goto err; + } + if ((dup = EC_GROUP_dup(ret)) == NULL + || EC_GROUP_set_seed(dup, NULL, 0) != 1 + || !EC_GROUP_set_generator(dup, point, a, NULL)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB); + goto err; + } + if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) { + /* + * The input explicit parameters successfully matched one of the + * built-in curves: often for built-in curves we have specialized + * methods with better performance and hardening. + * + * In this case we replace the `EC_GROUP` created through explicit + * parameters with one created from a named group. + */ + EC_GROUP *named_group = NULL; + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + /* + * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for + * the same curve, we prefer the SECP nid when matching explicit + * parameters as that is associated with a specialized EC_METHOD. + */ + if (curve_name == NID_wap_wsg_idm_ecid_wtls12) + curve_name = NID_secp224r1; +#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ + + if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB); + goto err; + } + EC_GROUP_free(ret); + ret = named_group; + + /* + * Set the flag so that EC_GROUPs created from explicit parameters are + * serialized using explicit parameters by default. + */ + EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE); + } + ok = 1; err: if (!ok) { - EC_GROUP_clear_free(ret); + EC_GROUP_free(ret); ret = NULL; } + EC_GROUP_free(dup); BN_free(p); BN_free(a); BN_free(b); EC_POINT_free(point); + + BN_CTX_free(ctx); + return ret; } @@ -861,7 +930,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) } if (a) { - EC_GROUP_clear_free(*a); + EC_GROUP_free(*a); *a = group; } @@ -909,7 +978,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) ret = *a; if (priv_key->parameters) { - EC_GROUP_clear_free(ret->group); + EC_GROUP_free(ret->group); ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters); } @@ -1137,14 +1206,10 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) return buf_len; } -ASN1_SEQUENCE(ECDSA_SIG) = { - ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) -} static_ASN1_SEQUENCE_END(ECDSA_SIG) - DECLARE_ASN1_FUNCTIONS(ECDSA_SIG) DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG) + +#endif /* FIPS_MODE */ ECDSA_SIG *ECDSA_SIG_new(void) { @@ -1163,6 +1228,74 @@ void ECDSA_SIG_free(ECDSA_SIG *sig) OPENSSL_free(sig); } +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len) +{ + ECDSA_SIG *sig; + + if (len < 0) + return NULL; + if (psig != NULL && *psig != NULL) { + sig = *psig; + } else { + sig = ECDSA_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) + ECDSA_SIG_free(sig); + return NULL; + } + if (psig != NULL && *psig == NULL) + *psig = sig; + return sig; +} + +int i2d_ECDSA_SIG(const ECDSA_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 ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { if (pr != NULL) @@ -1192,6 +1325,7 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) return 1; } +#ifndef FIPS_MODE int ECDSA_size(const EC_KEY *r) { int ret, i; @@ -1219,3 +1353,4 @@ int ECDSA_size(const EC_KEY *r) ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); return ret; } +#endif diff --git a/crypto/ec/ec_check.c b/crypto/ec/ec_check.c index 315b9fd4..974fcb24 100644 --- a/crypto/ec/ec_check.c +++ b/crypto/ec/ec_check.c @@ -10,13 +10,30 @@ #include "ec_lcl.h" #include -int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only) +int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only, + BN_CTX *ctx) { - int nid; + int nid = NID_undef; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; - nid = ec_curve_nid_from_params(group); + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GROUP_CHECK_NAMED_CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + } +#endif + + nid = ec_curve_nid_from_params(group, ctx); if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL) nid = NID_undef; + +#ifndef FIPS_MODE + err: + BN_CTX_free(ctx); +#endif return nid; } @@ -27,7 +44,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) * ECC domain parameter validation. * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b. */ - return EC_GROUP_check_named_curve(group, 1) >= 0 ? 1 : 0; + return EC_GROUP_check_named_curve(group, 1, ctx) >= 0 ? 1 : 0; #else int ret = 0; const BIGNUM *order; diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 8b44c251..f3a526f1 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -193,6 +193,7 @@ static const struct { } }; +# ifndef FIPS_MODE /* the x9.62 prime curves (minus the nist prime curves) */ static const struct { EC_CURVE_DATA h; @@ -371,6 +372,7 @@ static const struct { 0x43, 0x21, 0x46, 0x52, 0x65, 0x51 } }; +#endif /* FIPS_MODE */ static const struct { EC_CURVE_DATA h; @@ -410,6 +412,7 @@ static const struct { } }; +#ifndef FIPS_MODE /* the secg prime curves (minus the nist and x9.62 prime curves) */ static const struct { EC_CURVE_DATA h; @@ -831,10 +834,13 @@ static const struct { 0x5C, 0x5C, 0x2A, 0x3D } }; +#endif /* FIPS_MODE */ #ifndef OPENSSL_NO_EC2M /* characteristic two curves */ + +# ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 15 * 6]; @@ -962,6 +968,7 @@ static const struct { 0x33, 0x04, 0x9B, 0xA9, 0x8F } }; +# endif /* FIPS_MODE */ static const struct { EC_CURVE_DATA h; @@ -993,6 +1000,7 @@ static const struct { } }; +# ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 21 * 6]; @@ -1021,6 +1029,7 @@ static const struct { 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B } }; +# endif /* FIPS_MODE */ static const struct { EC_CURVE_DATA h; @@ -1051,6 +1060,7 @@ static const struct { } }; +# ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 25 * 6]; @@ -1126,6 +1136,7 @@ static const struct { 0xD5 } }; +# endif /* FIPS_MODE */ static const struct { EC_CURVE_DATA h; @@ -1201,6 +1212,7 @@ static const struct { } }; +#ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 30 * 6]; @@ -1236,6 +1248,7 @@ static const struct { 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5 } }; +# endif /* FIPS_MODE */ static const struct { EC_CURVE_DATA h; @@ -1519,6 +1532,7 @@ static const struct { } }; +# ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 21 * 6]; @@ -2203,8 +2217,8 @@ static const struct { 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E } }; - -#endif +# endif /* FIPS_MODE */ +#endif /* OPENSSL_NO_EC2M */ /* * These curves were added by Annie Yousar. @@ -2214,6 +2228,7 @@ static const struct { * generation mechanism is different from those defined in ANSI X9.62. */ +#ifndef FIPS_MODE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 20 * 6]; @@ -2753,8 +2768,9 @@ static const struct { 0x9C, 0xA9, 0x00, 0x69 } }; +#endif /* FIPS_MODE */ -#ifndef OPENSSL_NO_SM2 +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODE) static const struct { EC_CURVE_DATA h; unsigned char data[0 + 32 * 6]; @@ -2812,16 +2828,23 @@ static const ec_list_element curve_list[] = { "NIST/SECG curve over a 224 bit prime field"}, # endif /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + {NID_secp384r1, &_EC_NIST_PRIME_384.h, +# if defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp384_method, +# else + 0, +# endif "NIST/SECG curve over a 384 bit prime field"}, -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, - "NIST/SECG curve over a 521 bit prime field"}, + {NID_secp521r1, &_EC_NIST_PRIME_521.h, +# if defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp521_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp521_method, # else - {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, - "NIST/SECG curve over a 521 bit prime field"}, + 0, # endif + "NIST/SECG curve over a 521 bit prime field"}, /* X9.62 curves */ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, @@ -2829,6 +2852,8 @@ static const ec_list_element curve_list[] = { {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, # if defined(ECP_NISTZ256_ASM) EC_GFp_nistz256_method, +# elif defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp256_method, # elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) EC_GFp_nistp256_method, # else @@ -2896,15 +2921,22 @@ static const ec_list_element curve_list[] = { {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"}, /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, - "NIST/SECG curve over a 384 bit prime field"}, -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, - "NIST/SECG curve over a 521 bit prime field"}, + {NID_secp384r1, &_EC_NIST_PRIME_384.h, +# if defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp384_method, # else - {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, - "NIST/SECG curve over a 521 bit prime field"}, + 0, # endif + "NIST/SECG curve over a 384 bit prime field"}, + {NID_secp521r1, &_EC_NIST_PRIME_521.h, +# if defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp521_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp521_method, +# else + 0, +# endif + "NIST/SECG curve over a 521 bit prime field"}, /* X9.62 curves */ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"}, @@ -2921,6 +2953,8 @@ static const ec_list_element curve_list[] = { {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, # if defined(ECP_NISTZ256_ASM) EC_GFp_nistz256_method, +# elif defined(S390X_NISTP_ASM) + EC_GFp_s390x_nistp256_method, # elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) EC_GFp_nistp256_method, # else @@ -3075,7 +3109,8 @@ static const ec_list_element curve_list[] = { #define curve_list_length OSSL_NELEM(curve_list) -static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) +static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, + const ec_list_element curve) { EC_GROUP *group = NULL; EC_POINT *P = NULL; @@ -3090,9 +3125,10 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) /* If no curve data curve method must handle everything */ if (curve.data == NULL) - return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL); + return EC_GROUP_new_ex(libctx, + curve.meth != NULL ? curve.meth() : NULL); - if ((ctx = BN_CTX_new()) == NULL) { + if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); goto err; } @@ -3112,7 +3148,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) if (curve.meth != 0) { meth = curve.meth(); - if (((group = EC_GROUP_new(meth)) == NULL) || + if (((group = EC_GROUP_new_ex(libctx, meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -3182,7 +3218,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) return group; } -EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid) { size_t i; EC_GROUP *ret = NULL; @@ -3201,18 +3237,25 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) #endif /* FIPS_MODE */ for (i = 0; i < curve_list_length; i++) if (curve_list[i].nid == nid) { - ret = ec_group_new_from_data(curve_list[i]); + ret = ec_group_new_from_data(libctx, curve_list[i]); break; } if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); + ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX, EC_R_UNKNOWN_GROUP); return NULL; } return ret; } +#ifndef FIPS_MODE +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +{ + return EC_GROUP_new_by_curve_name_ex(NULL, nid); +} +#endif + size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) { size_t i, min; @@ -3284,7 +3327,7 @@ int EC_curve_nist2nid(const char *name) * Returns: The nid associated with the found named curve, or NID_undef * if not found. If there was an error it returns -1. */ -int ec_curve_nid_from_params(const EC_GROUP *group) +int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx) { int ret = -1, nid, len, field_type, param_len; size_t i, seed_len; @@ -3296,7 +3339,6 @@ int ec_curve_nid_from_params(const EC_GROUP *group) const BIGNUM *cofactor = NULL; /* An array of BIGNUMs for (p, a, b, x, y, order) */ BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL}; - BN_CTX *ctx = NULL; meth = EC_GROUP_method_of(group); if (meth == NULL) @@ -3308,9 +3350,6 @@ int ec_curve_nid_from_params(const EC_GROUP *group) seed = EC_GROUP_get0_seed(group); cofactor = EC_GROUP_get0_cofactor(group); - ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; BN_CTX_start(ctx); /* @@ -3388,6 +3427,5 @@ int ec_curve_nid_from_params(const EC_GROUP *group) end: OPENSSL_free(param_bytes); BN_CTX_end(ctx); - BN_CTX_free(ctx); return ret; } diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index 05d4d882..9b3087ed 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -9,6 +9,7 @@ */ #include +#include "internal/bn_int.h" #include "ec_lcl.h" EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, @@ -47,7 +48,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, meth = EC_GFp_mont_method(); #endif - ret = EC_GROUP_new(meth); + ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth); if (ret == NULL) return NULL; @@ -68,7 +69,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, meth = EC_GF2m_simple_method(); - ret = EC_GROUP_new(meth); + ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth); if (ret == NULL) return NULL; diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index b7cf95bd..66d9c4b1 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -13,281 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA EC_str_functs[] = { - {ERR_PACK(ERR_LIB_EC, EC_F_BN_TO_FELEM, 0), "BN_to_felem"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPARAMETERS, 0), "d2i_ECParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPKPARAMETERS, 0), "d2i_ECPKParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPRIVATEKEY, 0), "d2i_ECPrivateKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_DO_EC_KEY_PRINT, 0), "do_EC_KEY_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_DECRYPT, 0), "ecdh_cms_decrypt"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_SET_SHARED_INFO, 0), - "ecdh_cms_set_shared_info"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_COMPUTE_KEY, 0), "ECDH_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_SIMPLE_COMPUTE_KEY, 0), - "ecdh_simple_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_SIGN_EX, 0), "ECDSA_do_sign_ex"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_VERIFY, 0), "ECDSA_do_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_EX, 0), "ECDSA_sign_ex"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_SETUP, 0), "ECDSA_sign_setup"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIG_NEW, 0), "ECDSA_SIG_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_VERIFY, 0), "ECDSA_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECD_ITEM_VERIFY, 0), "ecd_item_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM2TYPE, 0), "eckey_param2type"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM_DECODE, 0), "eckey_param_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_DECODE, 0), "eckey_priv_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_ENCODE, 0), "eckey_priv_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_DECODE, 0), "eckey_pub_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_ENCODE, 0), "eckey_pub_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_TYPE2PARAM, 0), "eckey_type2param"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT, 0), "ECParameters_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT_FP, 0), - "ECParameters_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT, 0), - "ECPKParameters_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT_FP, 0), - "ECPKParameters_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_GET_AFFINE, 0), - "ecp_nistz256_get_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_INV_MOD_ORD, 0), - "ecp_nistz256_inv_mod_ord"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, 0), - "ecp_nistz256_mult_precompute"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_POINTS_MUL, 0), - "ecp_nistz256_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_PRE_COMP_NEW, 0), - "ecp_nistz256_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_WINDOWED_MUL, 0), - "ecp_nistz256_windowed_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_KEY_OP, 0), "ecx_key_op"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PRIV_ENCODE, 0), "ecx_priv_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PUB_ENCODE, 0), "ecx_pub_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2CURVE, 0), "ec_asn1_group2curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2FIELDID, 0), - "ec_asn1_group2fieldid"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0), - "ec_GF2m_montgomery_point_multiply"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0), - "ec_GF2m_simple_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), - "ec_GF2m_simple_group_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0), - "ec_GF2m_simple_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_POST, 0), - "ec_GF2m_simple_ladder_post"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_PRE, 0), - "ec_GF2m_simple_ladder_pre"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_OCT2POINT, 0), - "ec_GF2m_simple_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT2OCT, 0), - "ec_GF2m_simple_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINTS_MUL, 0), - "ec_GF2m_simple_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GF2m_simple_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0), - "ec_GF2m_simple_point_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, 0), - "ec_GF2m_simple_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_DECODE, 0), - "ec_GFp_mont_field_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0), - "ec_GFp_mont_field_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_INV, 0), - "ec_GFp_mont_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0), - "ec_GFp_mont_field_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0), - "ec_GFp_mont_field_set_to_one"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SQR, 0), - "ec_GFp_mont_field_sqr"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_GROUP_SET_CURVE, 0), - "ec_GFp_mont_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, 0), - "ec_GFp_nistp224_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINTS_MUL, 0), - "ec_GFp_nistp224_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp224_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, 0), - "ec_GFp_nistp256_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINTS_MUL, 0), - "ec_GFp_nistp256_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp256_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, 0), - "ec_GFp_nistp521_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINTS_MUL, 0), - "ec_GFp_nistp521_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp521_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_MUL, 0), - "ec_GFp_nist_field_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_SQR, 0), - "ec_GFp_nist_field_sqr"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0), - "ec_GFp_nist_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0), - "ec_GFp_simple_blind_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0), - "ec_GFp_simple_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), - "ec_GFp_simple_group_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0), - "ec_GFp_simple_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, 0), - "ec_GFp_simple_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_OCT2POINT, 0), - "ec_GFp_simple_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT2OCT, 0), - "ec_GFp_simple_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, 0), - "ec_GFp_simple_points_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_simple_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0), - "ec_GFp_simple_point_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, 0), - "ec_GFp_simple_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK, 0), "EC_GROUP_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK_DISCRIMINANT, 0), - "EC_GROUP_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_COPY, 0), "EC_GROUP_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE, 0), "EC_GROUP_get_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GF2M, 0), - "EC_GROUP_get_curve_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GFP, 0), - "EC_GROUP_get_curve_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_DEGREE, 0), "EC_GROUP_get_degree"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPARAMETERS, 0), - "EC_GROUP_get_ecparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPKPARAMETERS, 0), - "EC_GROUP_get_ecpkparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 0), - "EC_GROUP_get_pentanomial_basis"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 0), - "EC_GROUP_get_trinomial_basis"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW, 0), "EC_GROUP_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_BY_CURVE_NAME, 0), - "EC_GROUP_new_by_curve_name"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_DATA, 0), - "ec_group_new_from_data"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, 0), - "EC_GROUP_new_from_ecparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, 0), - "EC_GROUP_new_from_ecpkparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE, 0), "EC_GROUP_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GF2M, 0), - "EC_GROUP_set_curve_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GFP, 0), - "EC_GROUP_set_curve_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_GENERATOR, 0), - "EC_GROUP_set_generator"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_SEED, 0), "EC_GROUP_set_seed"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_CHECK_KEY, 0), "EC_KEY_check_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_COPY, 0), "EC_KEY_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_GENERATE_KEY, 0), "EC_KEY_generate_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW, 0), "EC_KEY_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW_METHOD, 0), "EC_KEY_new_method"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_OCT2PRIV, 0), "EC_KEY_oct2priv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT, 0), "EC_KEY_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT_FP, 0), "EC_KEY_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2BUF, 0), "EC_KEY_priv2buf"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2OCT, 0), "EC_KEY_priv2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 0), - "EC_KEY_set_public_key_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_CHECK_KEY, 0), - "ec_key_simple_check_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_OCT2PRIV, 0), - "ec_key_simple_oct2priv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_PRIV2OCT, 0), - "ec_key_simple_priv2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_CHECK, 0), "ec_pkey_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0), - "EC_POINTs_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MUL, 0), "EC_POINTs_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_COPY, 0), "EC_POINT_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_DBL, 0), "EC_POINT_dbl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES, 0), - "EC_POINT_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 0), - "EC_POINT_get_affine_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 0), - "EC_POINT_get_affine_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 0), - "EC_POINT_get_Jprojective_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_INVERT, 0), "EC_POINT_invert"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_AT_INFINITY, 0), - "EC_POINT_is_at_infinity"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_ON_CURVE, 0), - "EC_POINT_is_on_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_MAKE_AFFINE, 0), - "EC_POINT_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_NEW, 0), "EC_POINT_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_OCT2POINT, 0), "EC_POINT_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2BUF, 0), "EC_POINT_point2buf"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2OCT, 0), "EC_POINT_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES, 0), - "EC_POINT_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0), - "EC_POINT_set_affine_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 0), - "EC_POINT_set_affine_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 0), - "EC_POINT_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 0), - "EC_POINT_set_compressed_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 0), - "EC_POINT_set_compressed_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 0), - "EC_POINT_set_Jprojective_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_TO_INFINITY, 0), - "EC_POINT_set_to_infinity"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PRE_COMP_NEW, 0), "ec_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_SCALAR_MUL_LADDER, 0), - "ec_scalar_mul_ladder"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_MUL, 0), "ec_wNAF_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_PRECOMPUTE_MULT, 0), - "ec_wNAF_precompute_mult"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPARAMETERS, 0), "i2d_ECParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPKPARAMETERS, 0), "i2d_ECPKParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPRIVATEKEY, 0), "i2d_ECPrivateKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2O_ECPUBLICKEY, 0), "i2o_ECPublicKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP224_PRE_COMP_NEW, 0), - "nistp224_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP256_PRE_COMP_NEW, 0), - "nistp256_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP521_PRE_COMP_NEW, 0), - "nistp521_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_O2I_ECPUBLICKEY, 0), "o2i_ECPublicKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OLD_EC_PRIV_DECODE, 0), "old_ec_priv_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDH_COMPUTE_KEY, 0), - "ossl_ecdh_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_SIGN_SIG, 0), "ossl_ecdsa_sign_sig"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_VERIFY_SIG, 0), - "ossl_ecdsa_verify_sig"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_CTRL, 0), "pkey_ecd_ctrl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN, 0), "pkey_ecd_digestsign"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN25519, 0), - "pkey_ecd_digestsign25519"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0), - "pkey_ecd_digestsign448"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_DERIVE, 0), "pkey_ec_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_INIT, 0), "pkey_ec_init"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KDF_DERIVE, 0), "pkey_ec_kdf_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"}, - {ERR_PACK(ERR_LIB_EC, EC_F_VALIDATE_ECX_DERIVE, 0), "validate_ecx_derive"}, - {0, NULL} -}; - static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_ASN1_ERROR), "asn1 error"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature"}, @@ -298,6 +23,8 @@ static const ERR_STRING_DATA EC_str_reasons[] = { "coordinates out of range"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH), "curve does not support ecdh"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA), + "curve does not support ecdsa"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_D2I_ECPKPARAMETERS_FAILURE), @@ -385,10 +112,8 @@ static const ERR_STRING_DATA EC_str_reasons[] = { int ERR_load_EC_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { - ERR_load_strings_const(EC_str_functs); + if (ERR_reason_error_string(EC_str_reasons[0].error) == NULL) ERR_load_strings_const(EC_str_reasons); - } #endif return 1; } diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 47ccfd0a..6a02a3bc 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -15,17 +15,24 @@ #include #include +#ifndef FIPS_MODE EC_KEY *EC_KEY_new(void) { - return EC_KEY_new_method(NULL); + return ec_key_new_method_int(NULL, NULL); +} +#endif + +EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx) +{ + return ec_key_new_method_int(ctx, NULL); } -EC_KEY *EC_KEY_new_by_curve_name(int nid) +EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid) { - EC_KEY *ret = EC_KEY_new(); + EC_KEY *ret = EC_KEY_new_ex(ctx); if (ret == NULL) return NULL; - ret->group = EC_GROUP_new_by_curve_name(nid); + ret->group = EC_GROUP_new_by_curve_name_ex(ctx, nid); if (ret->group == NULL) { EC_KEY_free(ret); return NULL; @@ -38,6 +45,13 @@ EC_KEY *EC_KEY_new_by_curve_name(int nid) return ret; } +#ifndef FIPS_MODE +EC_KEY *EC_KEY_new_by_curve_name(int nid) +{ + return EC_KEY_new_by_curve_name_ex(NULL, nid); +} +#endif + void EC_KEY_free(EC_KEY *r) { int i; @@ -54,14 +68,16 @@ void EC_KEY_free(EC_KEY *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ENGINE_finish(r->engine); #endif if (r->group && r->group->meth->keyfinish) r->group->meth->keyfinish(r); +#ifndef FIPS_MODE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); @@ -81,18 +97,19 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) dest->meth->finish(dest); if (dest->group && dest->group->meth->keyfinish) dest->group->meth->keyfinish(dest); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) if (ENGINE_finish(dest->engine) == 0) return 0; dest->engine = NULL; #endif } + dest->libctx = src->libctx; /* copy the parameters */ if (src->group != NULL) { const EC_METHOD *meth = EC_GROUP_method_of(src->group); /* clear the old group */ EC_GROUP_free(dest->group); - dest->group = EC_GROUP_new(meth); + dest->group = EC_GROUP_new_ex(src->libctx, meth); if (dest->group == NULL) return NULL; if (!EC_GROUP_copy(dest->group, src->group)) @@ -128,12 +145,14 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) dest->conv_form = src->conv_form; dest->version = src->version; dest->flags = src->flags; +#ifndef FIPS_MODE if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data, &src->ex_data)) return NULL; +#endif if (src->meth != dest->meth) { -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) if (src->engine != NULL && ENGINE_init(src->engine) == 0) return NULL; dest->engine = src->engine; @@ -149,7 +168,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) { - EC_KEY *ret = EC_KEY_new_method(ec_key->engine); + EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->engine); if (ret == NULL) return NULL; @@ -211,6 +230,10 @@ int ec_key_simple_generate_key(EC_KEY *eckey) const BIGNUM *order = NULL; EC_POINT *pub_key = NULL; const EC_GROUP *group = eckey->group; + BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx); + + if (ctx == NULL) + goto err; if (eckey->priv_key == NULL) { priv_key = BN_secure_new(); @@ -238,7 +261,7 @@ int ec_key_simple_generate_key(EC_KEY *eckey) * rand so the simpler backward compatible method has been used here. */ do - if (!BN_priv_rand_range(priv_key, order)) + if (!BN_priv_rand_range_ex(priv_key, order, ctx)) goto err; while (BN_is_zero(priv_key)) ; @@ -250,7 +273,7 @@ int ec_key_simple_generate_key(EC_KEY *eckey) pub_key = eckey->pub_key; /* Step (8) : pub_key = priv_key * G (where G is a point on the curve) */ - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) goto err; eckey->priv_key = priv_key; @@ -270,6 +293,7 @@ err: EC_POINT_free(pub_key); BN_clear_free(priv_key); + BN_CTX_free(ctx); return ok; } @@ -368,7 +392,7 @@ int ec_key_simple_check_key(const EC_KEY *eckey) goto err; } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) goto err; if ((point = EC_POINT_new(eckey->group)) == NULL) @@ -445,7 +469,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, ERR_R_PASSED_NULL_PARAMETER); return 0; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(key->libctx); if (ctx == NULL) return 0; diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index c3209bc5..036fec87 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -59,7 +59,7 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) if (finish != NULL) finish(key); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ENGINE_finish(key->engine); key->engine = NULL; #endif @@ -70,28 +70,30 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) return 1; } -EC_KEY *EC_KEY_new_method(ENGINE *engine) +EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; + ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } ret->meth = EC_KEY_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) if (engine != NULL) { if (!ENGINE_init(engine)) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB); + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -100,7 +102,7 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) if (ret->engine != NULL) { ret->meth = ENGINE_get_EC(ret->engine); if (ret->meth == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB); + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_ENGINE_LIB); goto err; } } @@ -109,12 +111,15 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) ret->version = 1; ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; +/* No ex_data inside the FIPS provider */ +#ifndef FIPS_MODE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { goto err; } +#endif if (ret->meth->init != NULL && ret->meth->init(ret) == 0) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL); + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_INIT_FAIL); goto err; } return ret; @@ -124,6 +129,13 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) return NULL; } +#ifndef FIPS_MODE +EC_KEY *EC_KEY_new_method(ENGINE *engine) +{ + return ec_key_new_method_int(NULL, engine); +} +#endif + int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, void *(*KDF) (const void *in, size_t inlen, void *out, diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 0b1697ec..5dd4d031 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -179,6 +179,14 @@ struct ec_method_st { /* custom ECDH operation */ int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); + /* custom ECDSA */ + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinvp, + BIGNUM **rp); + ECDSA_SIG *(*ecdsa_sign_sig)(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey); + int (*ecdsa_verify_sig)(const unsigned char *dgst, int dgstlen, + const ECDSA_SIG *sig, EC_KEY *eckey); /* Inverse modulo order */ int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r, const BIGNUM *x, BN_CTX *); @@ -268,6 +276,8 @@ struct ec_group_st { NISTZ256_PRE_COMP *nistz256; EC_PRE_COMP *ec; } pre_comp; + + OPENSSL_CTX *libctx; }; #define SETPRECOMP(g, type, pre) \ @@ -286,8 +296,11 @@ struct ec_key_st { point_conversion_form_t conv_form; CRYPTO_REF_COUNT references; int flags; +#ifndef FIPS_MODE CRYPTO_EX_DATA ex_data; +#endif CRYPTO_RWLOCK *lock; + OPENSSL_CTX *libctx; }; struct ec_point_st { @@ -584,6 +597,11 @@ int ec_group_simple_order_bits(const EC_GROUP *group); */ const EC_METHOD *EC_GFp_nistz256_method(void); #endif +#ifdef S390X_NISTP_ASM +const EC_METHOD *EC_GFp_s390x_nistp256_method(void); +const EC_METHOD *EC_GFp_s390x_nistp384_method(void); +const EC_METHOD *EC_GFp_s390x_nistp521_method(void); +#endif size_t ec_key_simple_priv2oct(const EC_KEY *eckey, unsigned char *buf, size_t len); @@ -592,7 +610,7 @@ int ec_key_simple_generate_key(EC_KEY *eckey); int ec_key_simple_generate_public_key(EC_KEY *eckey); int ec_key_simple_check_key(const EC_KEY *eckey); -int ec_curve_nid_from_params(const EC_GROUP *group); +int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx); /* EC_METHOD definitions */ @@ -625,6 +643,8 @@ struct ec_key_method_st { #define EC_KEY_METHOD_DYNAMIC 1 +EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine); + int ossl_ec_key_gen(EC_KEY *eckey); int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); @@ -648,6 +668,13 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); +int ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +ECDSA_SIG *ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey); +int ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[32], const uint8_t private_key[32]); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 762cac4f..bc52e634 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -17,25 +17,26 @@ /* functions for EC_GROUP objects */ -EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) { EC_GROUP *ret; if (meth == NULL) { - ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); + ECerr(EC_F_EC_GROUP_NEW_EX, EC_R_SLOT_FULL); return NULL; } if (meth->group_init == 0) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return NULL; } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; ret->meth = meth; if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { ret->order = BN_new(); @@ -58,6 +59,13 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) return NULL; } +#ifndef FIPS_MODE +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +{ + return EC_GROUP_new_ex(NULL, meth); +} +#endif + void EC_pre_comp_free(EC_GROUP *group) { switch (group->pre_comp_type) { @@ -140,6 +148,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) if (dest == src) return 1; + dest->libctx = src->libctx; dest->curve_name = src->curve_name; /* Copy precomputed */ @@ -238,7 +247,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) if (a == NULL) return NULL; - if ((t = EC_GROUP_new(a->meth)) == NULL) + if ((t = EC_GROUP_new_ex(a->libctx, a->meth)) == NULL) return NULL; if (!EC_GROUP_copy(t, a)) goto err; @@ -265,6 +274,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth) static int ec_precompute_mont_data(EC_GROUP *); +/*- + * Try computing cofactor from the generator order (n) and field cardinality (q). + * This works for all curves of cryptographic interest. + * + * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q) + * h_min = (q + 1 - 2*sqrt(q))/n + * h_max = (q + 1 + 2*sqrt(q))/n + * h_max - h_min = 4*sqrt(q)/n + * So if n > 4*sqrt(q) holds, there is only one possible value for h: + * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil + * + * Otherwise, zero cofactor and return success. + */ +static int ec_guess_cofactor(EC_GROUP *group) { + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *q = NULL; + + /*- + * If the cofactor is too large, we cannot guess it. + * The RHS of below is a strict overestimate of lg(4 * sqrt(q)) + */ + if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) { + /* default to 0 */ + BN_zero(group->cofactor); + /* return success */ + return 1; + } + + if ((ctx = BN_CTX_new_ex(group->libctx)) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((q = BN_CTX_get(ctx)) == NULL) + goto err; + + /* set q = 2**m for binary fields; q = p otherwise */ + if (group->meth->field_type == NID_X9_62_characteristic_two_field) { + BN_zero(q); + if (!BN_set_bit(q, BN_num_bits(group->field) - 1)) + goto err; + } else { + if (!BN_copy(q, group->field)) + goto err; + } + + /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */ + if (!BN_rshift1(group->cofactor, group->order) /* n/2 */ + || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */ + /* q + 1 + n/2 */ + || !BN_add(group->cofactor, group->cofactor, BN_value_one()) + /* (q + 1 + n/2)/n */ + || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx)) + goto err; + ret = 1; + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) { @@ -273,6 +343,34 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, return 0; } + /* require group->field >= 1 */ + if (group->field == NULL || BN_is_zero(group->field) + || BN_is_negative(group->field)) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD); + return 0; + } + + /*- + * - require order >= 1 + * - enforce upper bound due to Hasse thm: order can be no more than one bit + * longer than field cardinality + */ + if (order == NULL || BN_is_zero(order) || BN_is_negative(order) + || BN_num_bits(order) > BN_num_bits(group->field) + 1) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + /*- + * Unfortunately the cofactor is an optional field in many standards. + * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor". + * So accept cofactor == NULL or cofactor >= 0. + */ + if (cofactor != NULL && BN_is_negative(cofactor)) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR); + return 0; + } + if (group->generator == NULL) { group->generator = EC_POINT_new(group); if (group->generator == NULL) @@ -281,20 +379,18 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, if (!EC_POINT_copy(group->generator, generator)) return 0; - if (order != NULL) { - if (!BN_copy(group->order, order)) - return 0; - } else { - BN_zero(group->order); - } + if (!BN_copy(group->order, order)) + return 0; - /* The cofactor is an optional field, so it should be able to be NULL. */ - if (cofactor != NULL) { + /* Either take the provided positive cofactor, or try to compute it */ + if (cofactor != NULL && !BN_is_zero(cofactor)) { if (!BN_copy(group->cofactor, cofactor)) return 0; - } else { + } else if (!ec_guess_cofactor(group)) { BN_zero(group->cofactor); + return 0; } + /* * Some groups have an order with * factors of two, which makes the Montgomery setup fail. @@ -493,8 +589,15 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) { int r = 0; BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; +#ifndef FIPS_MODE BN_CTX *ctx_new = NULL; + if (ctx == NULL) + ctx_new = ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return -1; + /* compare the field types */ if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != EC_METHOD_get_field_type(EC_GROUP_method_of(b))) @@ -506,11 +609,6 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE) return 0; - if (ctx == NULL) - ctx_new = ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - BN_CTX_start(ctx); a1 = BN_CTX_get(ctx); a2 = BN_CTX_get(ctx); @@ -520,7 +618,9 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) b3 = BN_CTX_get(ctx); if (b3 == NULL) { BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(ctx_new); +#endif return -1; } @@ -570,8 +670,9 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) } end: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(ctx_new); - +#endif return r; } @@ -936,8 +1037,17 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, { int ret = 0; size_t i = 0; +#ifndef FIPS_MODE BN_CTX *new_ctx = NULL; + if (ctx == NULL) + ctx = new_ctx = BN_CTX_secure_new(); +#endif + if (ctx == NULL) { + ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); + return 0; + } + if ((scalar == NULL) && (num == 0)) { return EC_POINT_set_to_infinity(group, r); } @@ -953,18 +1063,15 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) { - ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); - return 0; - } - if (group->meth->mul != NULL) ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx); else /* use default */ ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1015,7 +1122,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) */ static int ec_precompute_mont_data(EC_GROUP *group) { - BN_CTX *ctx = BN_CTX_new(); + BN_CTX *ctx = BN_CTX_new_ex(group->libctx); int ret = 0; BN_MONT_CTX_free(group->mont_data); @@ -1042,6 +1149,7 @@ static int ec_precompute_mont_data(EC_GROUP *group) return ret; } +#ifndef FIPS_MODE int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg) { return CRYPTO_set_ex_data(&key->ex_data, idx, arg); @@ -1051,6 +1159,7 @@ void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) { return CRYPTO_get_ex_data(&key->ex_data, idx); } +#endif int ec_group_simple_order_bits(const EC_GROUP *group) { @@ -1063,14 +1172,18 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, const BIGNUM *x, BN_CTX *ctx) { BIGNUM *e = NULL; - BN_CTX *new_ctx = NULL; int ret = 0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) + ctx = new_ctx = BN_CTX_secure_new(); +#endif + if (ctx == NULL) + return 0; if (group->mont_data == NULL) - return 0; - - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) - return 0; + goto err; BN_CTX_start(ctx); if ((e = BN_CTX_get(ctx)) == NULL) @@ -1095,7 +1208,9 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 968125f3..be4f2306 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -815,12 +815,14 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { const EC_POINT *generator; EC_POINT *tmp_point = NULL, *base = NULL, **var; - BN_CTX *new_ctx = NULL; const BIGNUM *order; size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; EC_POINT **points = NULL; EC_PRE_COMP *pre_comp; int ret = 0; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif /* if there is an old EC_PRE_COMP object, throw it away */ EC_pre_comp_free(group); @@ -833,11 +835,12 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) goto err; } - if (ctx == NULL) { +#ifndef FIPS_MODE + if (ctx == NULL) ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } +#endif + if (ctx == NULL) + goto err; BN_CTX_start(ctx); @@ -949,7 +952,9 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif EC_ec_pre_comp_free(pre_comp); if (points) { EC_POINT **p; diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c index f556dc66..a1908094 100644 --- a/crypto/ec/ecdh_kdf.c +++ b/crypto/ec/ecdh_kdf.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -19,18 +20,27 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) { - int ret; + int ret = 0; EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[4], *p = params; + const char *mdname = EVP_MD_name(md); + EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL); - kctx = EVP_KDF_CTX_new(EVP_get_kdfbyname(SN_x963kdf)); - ret = - kctx != NULL - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, md) > 0 - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, Z, Zlen) > 0 - && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, sinfo, sinfolen) > 0 - && EVP_KDF_derive(kctx, out, outlen) > 0; + if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, + strlen(mdname) + 1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (void *)Z, Zlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + (void *)sinfo, sinfolen); + *p = OSSL_PARAM_construct_end(); - EVP_KDF_CTX_free(kctx); + ret = EVP_KDF_CTX_set_params(kctx, params) > 0 + && EVP_KDF_derive(kctx, out, outlen) > 0; + EVP_KDF_CTX_free(kctx); + } + EVP_KDF_free(kdf); return ret; } diff --git a/crypto/ec/ecdh_ossl.c b/crypto/ec/ecdh_ossl.c index 61789f4f..b3fb8792 100644 --- a/crypto/ec/ecdh_ossl.c +++ b/crypto/ec/ecdh_ossl.c @@ -47,7 +47,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, size_t buflen, len; unsigned char *buf = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(ecdh->libctx)) == NULL) goto err; BN_CTX_start(ctx); x = BN_CTX_get(ctx); @@ -58,7 +58,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, priv_key = EC_KEY_get0_private_key(ecdh); if (priv_key == NULL) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE); + ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_MISSING_PRIVATE_KEY); goto err; } diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c index a488d5c8..afa65233 100644 --- a/crypto/ec/ecdsa_ossl.c +++ b/crypto/ec/ecdsa_ossl.c @@ -14,6 +14,41 @@ #include "internal/bn_int.h" #include "ec_lcl.h" +int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + if (eckey->group->meth->ecdsa_sign_setup == NULL) { + ECerr(EC_F_OSSL_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return 0; + } + + return eckey->group->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); +} + +ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) +{ + if (eckey->group->meth->ecdsa_sign_sig == NULL) { + ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return NULL; + } + + return eckey->group->meth->ecdsa_sign_sig(dgst, dgst_len, + in_kinv, in_r, eckey); +} + +int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + if (eckey->group->meth->ecdsa_verify_sig == NULL) { + ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return 0; + } + + return eckey->group->meth->ecdsa_verify_sig(dgst, dgst_len, sig, eckey); +} + int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) @@ -41,11 +76,16 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, const EC_GROUP *group; int ret = 0; int order_bits; + const BIGNUM *priv_key; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } + if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) { + ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_MISSING_PRIVATE_KEY); + return 0; + } if (!EC_KEY_can_sign(eckey)) { ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); @@ -53,7 +93,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, } if ((ctx = ctx_in) == NULL) { - if ((ctx = BN_CTX_new()) == NULL) { + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) { ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); return 0; } @@ -83,15 +123,14 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, /* get random k */ do { if (dgst != NULL) { - if (!BN_generate_dsa_nonce(k, order, - EC_KEY_get0_private_key(eckey), + if (!BN_generate_dsa_nonce(k, order, priv_key, dgst, dlen, ctx)) { ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } } else { - if (!BN_priv_rand_range(k, order)) { + if (!BN_priv_rand_range_ex(k, order, ctx)) { ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; @@ -141,15 +180,15 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, return ret; } -int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) +int ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) { return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0); } -ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, - const BIGNUM *in_kinv, const BIGNUM *in_r, - EC_KEY *eckey) +ECDSA_SIG *ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) { int ok = 0, i; BIGNUM *kinv = NULL, *s, *m = NULL; @@ -162,32 +201,36 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); - if (group == NULL || priv_key == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER); + if (group == NULL) { + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (priv_key == NULL) { + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, EC_R_MISSING_PRIVATE_KEY); return NULL; } if (!EC_KEY_can_sign(eckey)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return NULL; } ret = ECDSA_SIG_new(); if (ret == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_MALLOC_FAILURE); return NULL; } ret->r = BN_new(); ret->s = BN_new(); if (ret->r == NULL || ret->s == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_MALLOC_FAILURE); goto err; } s = ret->s; - if ((ctx = BN_CTX_new()) == NULL + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL || (m = BN_new()) == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_MALLOC_FAILURE); goto err; } @@ -199,25 +242,25 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_BN_LIB); goto err; } /* If still too long, truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_BN_LIB); goto err; } do { if (in_kinv == NULL || in_r == NULL) { if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_ECDSA_LIB); goto err; } ckinv = kinv; } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_MALLOC_FAILURE); goto err; } } @@ -231,11 +274,11 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, */ if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx) || !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_BN_LIB); goto err; } if (!bn_mod_add_fixed_top(s, s, m, order)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_BN_LIB); goto err; } /* @@ -244,7 +287,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, */ if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx) || !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, ERR_R_BN_LIB); goto err; } @@ -254,7 +297,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, * generate new kinv and r values */ if (in_kinv != NULL && in_r != NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES); + ECerr(EC_F_ECDSA_SIMPLE_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES); goto err; } } else { @@ -306,8 +349,8 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, return ret; } -int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey) +int ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, i; BN_CTX *ctx; @@ -320,18 +363,18 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, /* check input values */ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, EC_R_MISSING_PARAMETERS); return -1; } if (!EC_KEY_can_sign(eckey)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return -1; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(eckey->libctx); if (ctx == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_MALLOC_FAILURE); return -1; } BN_CTX_start(ctx); @@ -340,26 +383,26 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); if (X == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } order = EC_GROUP_get0_order(group); if (order == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_EC_LIB); goto err; } if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, EC_R_BAD_SIGNATURE); ret = 0; /* signature is invalid */ goto err; } /* calculate tmp1 = inv(S) mod order */ if (!ec_group_do_inverse_ord(group, u2, sig->s, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } /* digest -> m */ @@ -370,41 +413,41 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } /* u1 = m * tmp mod order */ if (!BN_mod_mul(u1, m, u2, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } /* u2 = r * w mod q */ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } if ((point = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_EC_LIB); goto err; } if (!BN_nnmod(u1, X, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ECerr(EC_F_ECDSA_SIMPLE_VERIFY_SIG, ERR_R_BN_LIB); goto err; } /* if the signature is correct u1 is equal to sig->r */ diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 1654d595..61a203c1 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -63,6 +63,9 @@ const EC_METHOD *EC_GFp_mont_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ ec_GFp_simple_blind_coordinates, ec_GFp_simple_ladder_pre, @@ -146,7 +149,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, group->field_data2 = NULL; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -222,7 +225,8 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, if (group->field_data1 == NULL) return 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + if (ctx == NULL + && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c index 9f9045b5..99cc74b6 100644 --- a/crypto/ec/ecp_nist.c +++ b/crypto/ec/ecp_nist.c @@ -65,6 +65,9 @@ const EC_METHOD *EC_GFp_nist_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ ec_GFp_simple_blind_coordinates, ec_GFp_simple_ladder_pre, @@ -89,7 +92,7 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) + if ((ctx = new_ctx = BN_CTX_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -128,7 +131,7 @@ int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, goto err; } if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) + if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL) goto err; if (!BN_mul(r, a, b, ctx)) @@ -153,7 +156,7 @@ int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, goto err; } if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) + if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL) goto err; if (!BN_sqr(r, a, ctx)) diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index e6f095e7..8922a47b 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -292,6 +292,9 @@ const EC_METHOD *EC_GFp_nistp224_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -324,34 +327,21 @@ static void felem_to_bin28(u8 out[28], const felem in) } } -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - /* From OpenSSL BIGNUM to internal representation */ static int BN_to_felem(felem out, const BIGNUM *bn) { - felem_bytearray b_in; felem_bytearray b_out; - unsigned num_bytes; + int num_bytes; - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } if (BN_is_negative(bn)) { ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); + num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out)); + if (num_bytes < 0) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } bin28_to_felem(out, b_out); return 1; } @@ -359,10 +349,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn) /* From internal representation to OpenSSL BIGNUM */ static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) { - felem_bytearray b_in, b_out; - felem_to_bin28(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); + felem_bytearray b_out; + felem_to_bin28(b_out, in); + return BN_lebin2bn(b_out, sizeof(b_out), out); } /******************************************************************************/ @@ -1281,12 +1270,16 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1305,7 +1298,9 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1404,8 +1399,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, felem_bytearray *secrets = NULL; felem (*pre_comp)[17][3] = NULL; felem *tmp_felems = NULL; - felem_bytearray tmp; - unsigned num_bytes; + int num_bytes; int have_pre_comp = 0; size_t num_points = num; felem x_in, y_in, z_in, x_out, y_out, z_out; @@ -1480,14 +1474,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, * i.e., they contribute nothing to the linear combination */ for (i = 0; i < num_points; ++i) { - if (i == num) + if (i == num) { /* the generator */ - { p = EC_GROUP_get0_generator(group); p_scalar = scalar; - } else + } else { /* the i^th point */ - { p = points[i]; p_scalar = scalars[i]; } @@ -1503,10 +1495,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, + secrets[i], sizeof(secrets[i])); + } else { + num_bytes = BN_bn2lebinpad(p_scalar, + secrets[i], sizeof(secrets[i])); + } + if (num_bytes < 0) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } /* precompute multiples */ if ((!BN_to_felem(x_out, p->X)) || (!BN_to_felem(y_out, p->Y)) || @@ -1549,20 +1547,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); + } else { + num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret)); + } /* do the multiplication with generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp, g_pre_comp); - } else + } else { /* do the multiplication without generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + } /* reduce the output to its unique minimal representation */ felem_contract(x_in, x_out); felem_contract(y_in, y_out); @@ -1588,16 +1587,23 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) int ret = 0; NISTP224_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; felem tmp_felems[32]; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -1705,7 +1711,9 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif EC_nistp224_pre_comp_free(pre); return ret; } diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index ee5508fa..4d284fa3 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -146,34 +146,21 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in) *((u64 *)&out[24]) = in[3]; } -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - /* BN_to_felem converts an OpenSSL BIGNUM into an felem */ static int BN_to_felem(felem out, const BIGNUM *bn) { - felem_bytearray b_in; felem_bytearray b_out; - unsigned num_bytes; + int num_bytes; - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } if (BN_is_negative(bn)) { ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); + num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out)); + if (num_bytes < 0) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } bin32_to_felem(out, b_out); return 1; } @@ -181,10 +168,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn) /* felem_to_BN converts an felem into an OpenSSL BIGNUM */ static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) { - felem_bytearray b_in, b_out; - smallfelem_to_bin32(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); + felem_bytearray b_out; + smallfelem_to_bin32(b_out, in); + return BN_lebin2bn(b_out, sizeof(b_out), out); } /*- @@ -1823,6 +1809,9 @@ const EC_METHOD *EC_GFp_nistp256_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -1901,12 +1890,16 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1925,7 +1918,9 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -2024,8 +2019,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, felem_bytearray *secrets = NULL; smallfelem (*pre_comp)[17][3] = NULL; smallfelem *tmp_smallfelems = NULL; - felem_bytearray tmp; - unsigned i, num_bytes; + unsigned i; + int num_bytes; int have_pre_comp = 0; size_t num_points = num; smallfelem x_in, y_in, z_in; @@ -2102,17 +2097,15 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, memset(secrets, 0, sizeof(*secrets) * num_points); memset(pre_comp, 0, sizeof(*pre_comp) * num_points); for (i = 0; i < num_points; ++i) { - if (i == num) + if (i == num) { /* * we didn't have a valid precomputation, so we pick the * generator */ - { p = EC_GROUP_get0_generator(group); p_scalar = scalar; - } else + } else { /* the i^th point */ - { p = points[i]; p_scalar = scalars[i]; } @@ -2128,10 +2121,16 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, + secrets[i], sizeof(secrets[i])); + } else { + num_bytes = BN_bn2lebinpad(p_scalar, + secrets[i], sizeof(secrets[i])); + } + if (num_bytes < 0) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } /* precompute multiples */ if ((!BN_to_felem(x_out, p->X)) || (!BN_to_felem(y_out, p->Y)) || @@ -2176,20 +2175,21 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); + } else { + num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret)); + } /* do the multiplication with generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, g_secret, mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp); - } else + } else { /* do the multiplication without generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL); + } /* reduce the output to its unique minimal representation */ felem_contract(x_in, x_out); felem_contract(y_in, y_out); @@ -2215,17 +2215,24 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) int ret = 0; NISTP256_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; smallfelem tmp_smallfelems[32]; felem x_tmp, y_tmp, z_tmp; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -2343,7 +2350,9 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif EC_nistp256_pre_comp_free(pre); return ret; } diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 06f1a638..7b134bb7 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -169,34 +169,21 @@ static void felem_to_bin66(u8 out[66], const felem in) (*((limb *) & out[58])) = in[8]; } -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - /* BN_to_felem converts an OpenSSL BIGNUM into an felem */ static int BN_to_felem(felem out, const BIGNUM *bn) { - felem_bytearray b_in; felem_bytearray b_out; - unsigned num_bytes; + int num_bytes; - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } if (BN_is_negative(bn)) { ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); + num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out)); + if (num_bytes < 0) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } bin66_to_felem(out, b_out); return 1; } @@ -204,10 +191,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn) /* felem_to_BN converts an felem into an OpenSSL BIGNUM */ static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) { - felem_bytearray b_in, b_out; - felem_to_bin66(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); + felem_bytearray b_out; + felem_to_bin66(b_out, in); + return BN_lebin2bn(b_out, sizeof(b_out), out); } /*- @@ -1665,6 +1651,9 @@ const EC_METHOD *EC_GFp_nistp521_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -1743,12 +1732,16 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1767,7 +1760,9 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1866,8 +1861,8 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, felem_bytearray *secrets = NULL; felem (*pre_comp)[17][3] = NULL; felem *tmp_felems = NULL; - felem_bytearray tmp; - unsigned i, num_bytes; + unsigned i; + int num_bytes; int have_pre_comp = 0; size_t num_points = num; felem x_in, y_in, z_in, x_out, y_out, z_out; @@ -1942,17 +1937,15 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, * i.e., they contribute nothing to the linear combination */ for (i = 0; i < num_points; ++i) { - if (i == num) + if (i == num) { /* * we didn't have a valid precomputation, so we pick the * generator */ - { p = EC_GROUP_get0_generator(group); p_scalar = scalar; - } else + } else { /* the i^th point */ - { p = points[i]; p_scalar = scalars[i]; } @@ -1968,10 +1961,16 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, + secrets[i], sizeof(secrets[i])); + } else { + num_bytes = BN_bn2lebinpad(p_scalar, + secrets[i], sizeof(secrets[i])); + } + if (num_bytes < 0) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } /* precompute multiples */ if ((!BN_to_felem(x_out, p->X)) || (!BN_to_felem(y_out, p->Y)) || @@ -2014,21 +2013,22 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); goto err; } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); + num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); + } else { + num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret)); + } /* do the multiplication with generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp, (const felem(*)[3])g_pre_comp); - } else + } else { /* do the multiplication without generator precomputation */ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets, num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + } /* reduce the output to its unique minimal representation */ felem_contract(x_in, x_out); felem_contract(y_in, y_out); @@ -2054,16 +2054,23 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) int ret = 0; NISTP521_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; felem tmp_felems[16]; +#ifndef FIPS_MODE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -2151,7 +2158,9 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODE BN_CTX_free(new_ctx); +#endif EC_nistp521_pre_comp_free(pre); return ret; } diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 66bf4ecb..a09e9c5d 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -813,7 +813,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) return 0; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) goto err; } @@ -1689,6 +1689,9 @@ const EC_METHOD *EC_GFp_nistz256_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, ecp_nistz256_inv_mod_ord, /* can be #define-d NULL */ 0, /* blind_coordinates */ 0, /* ladder_pre */ diff --git a/crypto/ec/ecp_oct.c b/crypto/ec/ecp_oct.c index 9b430f9b..a00eac35 100644 --- a/crypto/ec/ecp_oct.c +++ b/crypto/ec/ecp_oct.c @@ -22,11 +22,13 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, BIGNUM *tmp1, *tmp2, *x, *y; int ret = 0; +#ifndef FIPS_MODE /* clear error queue */ ERR_clear_error(); +#endif if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -99,6 +101,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, } if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) { +#ifndef FIPS_MODE unsigned long err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN @@ -107,8 +110,11 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); } else +#endif + { ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); + } goto err; } @@ -194,7 +200,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -314,7 +320,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c new file mode 100644 index 00000000..be81f0b8 --- /dev/null +++ b/crypto/ec/ecp_s390x_nistp.c @@ -0,0 +1,394 @@ +/* + * 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 "ec_lcl.h" +#include "s390x_arch.h" + +/* Size of parameter blocks */ +#define S390X_SIZE_PARAM 4096 + +/* Size of fields in parameter blocks */ +#define S390X_SIZE_P256 32 +#define S390X_SIZE_P384 48 +#define S390X_SIZE_P521 80 + +/* Offsets of fields in PCC parameter blocks */ +#define S390X_OFF_RES_X(n) (0 * n) +#define S390X_OFF_RES_Y(n) (1 * n) +#define S390X_OFF_SRC_X(n) (2 * n) +#define S390X_OFF_SRC_Y(n) (3 * n) +#define S390X_OFF_SCALAR(n) (4 * n) + +/* Offsets of fields in KDSA parameter blocks */ +#define S390X_OFF_R(n) (0 * n) +#define S390X_OFF_S(n) (1 * n) +#define S390X_OFF_H(n) (2 * n) +#define S390X_OFF_K(n) (3 * n) +#define S390X_OFF_X(n) (3 * n) +#define S390X_OFF_RN(n) (4 * n) +#define S390X_OFF_Y(n) (4 * n) + +static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], + BN_CTX *ctx, unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + BIGNUM *x, *y; + const EC_POINT *point_ptr = NULL; + const BIGNUM *scalar_ptr = NULL; + BN_CTX *new_ctx = NULL; + int rc = -1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new_ex(group->libctx); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + rc = 0; + goto ret; + } + + /* + * Use PCC for EC keygen and ECDH key derivation: + * scalar * generator and scalar * peer public key, + * scalar in [0,order). + */ + if ((scalar != NULL && num == 0 && BN_is_negative(scalar) == 0) + || (scalar == NULL && num == 1 && BN_is_negative(scalars[0]) == 0)) { + + if (num == 0) { + point_ptr = EC_GROUP_get0_generator(group); + scalar_ptr = scalar; + } else { + point_ptr = points[0]; + scalar_ptr = scalars[0]; + } + + if (EC_POINT_is_at_infinity(group, point_ptr) == 1 + || BN_is_zero(scalar_ptr)) { + rc = EC_POINT_set_to_infinity(group, r); + goto ret; + } + + memset(¶m, 0, sizeof(param)); + + if (group->meth->point_get_affine_coordinates(group, point_ptr, + x, y, ctx) != 1 + || BN_bn2binpad(x, param + S390X_OFF_SRC_X(len), len) == -1 + || BN_bn2binpad(y, param + S390X_OFF_SRC_Y(len), len) == -1 + || BN_bn2binpad(scalar_ptr, + param + S390X_OFF_SCALAR(len), len) == -1 + || s390x_pcc(fc, param) != 0 + || BN_bin2bn(param + S390X_OFF_RES_X(len), len, x) == NULL + || BN_bin2bn(param + S390X_OFF_RES_Y(len), len, y) == NULL + || group->meth->point_set_affine_coordinates(group, r, + x, y, ctx) != 1) + goto ret; + + rc = 1; + } + +ret: + /* Otherwise use default. */ + if (rc == -1) + rc = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + OPENSSL_cleanse(param, sizeof(param)); + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return rc; +} + +static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst, + int dgstlen, + const BIGNUM *kinv, + const BIGNUM *r, + EC_KEY *eckey, + unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + int ok = 0; + BIGNUM *k; + ECDSA_SIG *sig; + const EC_GROUP *group; + const BIGNUM *privkey; + int off; + + group = EC_KEY_get0_group(eckey); + privkey = EC_KEY_get0_private_key(eckey); + if (group == NULL || privkey == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, EC_R_MISSING_PARAMETERS); + return NULL; + } + + if (!EC_KEY_can_sign(eckey)) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, + EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + return NULL; + } + + k = BN_secure_new(); + sig = ECDSA_SIG_new(); + if (k == NULL || sig == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_MALLOC_FAILURE); + goto ret; + } + + sig->r = BN_new(); + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_MALLOC_FAILURE); + goto ret; + } + + memset(param, 0, sizeof(param)); + off = len - (dgstlen > len ? len : dgstlen); + memcpy(param + S390X_OFF_H(len) + off, dgst, len - off); + + if (BN_bn2binpad(privkey, param + S390X_OFF_K(len), len) == -1) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB); + goto ret; + } + + if (r == NULL || kinv == NULL) { + /* + * Generate random k and copy to param param block. RAND_priv_bytes + * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce + * because kdsa instruction constructs an in-range, invertible nonce + * internally implementing counter-measures for RNG weakness. + */ + if (RAND_priv_bytes(param + S390X_OFF_RN(len), len) != 1) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, + EC_R_RANDOM_NUMBER_GENERATION_FAILED); + goto ret; + } + } else { + /* Reconstruct k = (k^-1)^-1. */ + if (ec_group_do_inverse_ord(group, k, kinv, NULL) == 0 + || BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB); + goto ret; + } + /* Turns KDSA internal nonce-generation off. */ + fc |= S390X_KDSA_D; + } + + if (s390x_kdsa(fc, param, NULL, 0) != 0) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_ECDSA_LIB); + goto ret; + } + + if (BN_bin2bn(param + S390X_OFF_R(len), len, sig->r) == NULL + || BN_bin2bn(param + S390X_OFF_S(len), len, sig->s) == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB); + goto ret; + } + + ok = 1; +ret: + OPENSSL_cleanse(param, sizeof(param)); + if (ok != 1) { + ECDSA_SIG_free(sig); + sig = NULL; + } + BN_clear_free(k); + return sig; +} + +static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen, + const ECDSA_SIG *sig, EC_KEY *eckey, + unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + int rc = -1; + BN_CTX *ctx; + BIGNUM *x, *y; + const EC_GROUP *group; + const EC_POINT *pubkey; + int off; + + group = EC_KEY_get0_group(eckey); + pubkey = EC_KEY_get0_public_key(eckey); + if (eckey == NULL || group == NULL || pubkey == NULL || sig == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, EC_R_MISSING_PARAMETERS); + return -1; + } + + if (!EC_KEY_can_sign(eckey)) { + ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, + EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + return -1; + } + + ctx = BN_CTX_new_ex(group->libctx); + if (ctx == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + return -1; + } + + BN_CTX_start(ctx); + + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + goto ret; + } + + memset(param, 0, sizeof(param)); + off = len - (dgstlen > len ? len : dgstlen); + memcpy(param + S390X_OFF_H(len) + off, dgst, len - off); + + if (group->meth->point_get_affine_coordinates(group, pubkey, + x, y, ctx) != 1 + || BN_bn2binpad(sig->r, param + S390X_OFF_R(len), len) == -1 + || BN_bn2binpad(sig->s, param + S390X_OFF_S(len), len) == -1 + || BN_bn2binpad(x, param + S390X_OFF_X(len), len) == -1 + || BN_bn2binpad(y, param + S390X_OFF_Y(len), len) == -1) { + ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_BN_LIB); + goto ret; + } + + rc = s390x_kdsa(fc, param, NULL, 0) == 0 ? 1 : 0; +ret: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return rc; +} + +#define EC_GFP_S390X_NISTP_METHOD(bits) \ + \ +static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \ + EC_POINT *r, \ + const BIGNUM *scalar, \ + size_t num, \ + const EC_POINT *points[], \ + const BIGNUM *scalars[], \ + BN_CTX *ctx) \ +{ \ + return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \ + scalars, ctx, \ + S390X_SCALAR_MULTIPLY_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +static ECDSA_SIG *ecdsa_s390x_nistp##bits##_sign_sig(const unsigned \ + char *dgst, \ + int dgstlen, \ + const BIGNUM *kinv,\ + const BIGNUM *r, \ + EC_KEY *eckey) \ +{ \ + return ecdsa_s390x_nistp_sign_sig(dgst, dgstlen, kinv, r, eckey, \ + S390X_ECDSA_SIGN_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +static int ecdsa_s390x_nistp##bits##_verify_sig(const \ + unsigned char *dgst, \ + int dgstlen, \ + const ECDSA_SIG *sig, \ + EC_KEY *eckey) \ +{ \ + return ecdsa_s390x_nistp_verify_sig(dgst, dgstlen, sig, eckey, \ + S390X_ECDSA_VERIFY_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \ +{ \ + static const EC_METHOD EC_GFp_s390x_nistp##bits##_meth = { \ + EC_FLAGS_DEFAULT_OCT, \ + NID_X9_62_prime_field, \ + ec_GFp_simple_group_init, \ + ec_GFp_simple_group_finish, \ + ec_GFp_simple_group_clear_finish, \ + ec_GFp_simple_group_copy, \ + ec_GFp_simple_group_set_curve, \ + ec_GFp_simple_group_get_curve, \ + ec_GFp_simple_group_get_degree, \ + ec_group_simple_order_bits, \ + ec_GFp_simple_group_check_discriminant, \ + ec_GFp_simple_point_init, \ + ec_GFp_simple_point_finish, \ + ec_GFp_simple_point_clear_finish, \ + ec_GFp_simple_point_copy, \ + ec_GFp_simple_point_set_to_infinity, \ + ec_GFp_simple_set_Jprojective_coordinates_GFp, \ + ec_GFp_simple_get_Jprojective_coordinates_GFp, \ + ec_GFp_simple_point_set_affine_coordinates, \ + ec_GFp_simple_point_get_affine_coordinates, \ + NULL, /* point_set_compressed_coordinates */ \ + NULL, /* point2oct */ \ + NULL, /* oct2point */ \ + ec_GFp_simple_add, \ + ec_GFp_simple_dbl, \ + ec_GFp_simple_invert, \ + ec_GFp_simple_is_at_infinity, \ + ec_GFp_simple_is_on_curve, \ + ec_GFp_simple_cmp, \ + ec_GFp_simple_make_affine, \ + ec_GFp_simple_points_make_affine, \ + ec_GFp_s390x_nistp##bits##_mul, \ + NULL, /* precompute_mult */ \ + NULL, /* have_precompute_mult */ \ + ec_GFp_simple_field_mul, \ + ec_GFp_simple_field_sqr, \ + NULL, /* field_div */ \ + ec_GFp_simple_field_inv, \ + NULL, /* field_encode */ \ + NULL, /* field_decode */ \ + NULL, /* field_set_to_one */ \ + ec_key_simple_priv2oct, \ + ec_key_simple_oct2priv, \ + NULL, /* set_private */ \ + ec_key_simple_generate_key, \ + ec_key_simple_check_key, \ + ec_key_simple_generate_public_key, \ + NULL, /* keycopy */ \ + NULL, /* keyfinish */ \ + ecdh_simple_compute_key, \ + ecdsa_simple_sign_setup, \ + ecdsa_s390x_nistp##bits##_sign_sig, \ + ecdsa_s390x_nistp##bits##_verify_sig, \ + NULL, /* field_inverse_mod_ord */ \ + ec_GFp_simple_blind_coordinates, \ + ec_GFp_simple_ladder_pre, \ + ec_GFp_simple_ladder_step, \ + ec_GFp_simple_ladder_post \ + }; \ + static const EC_METHOD *ret; \ + \ + if ((OPENSSL_s390xcap_P.pcc[1] \ + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \ + && (OPENSSL_s390xcap_P.kdsa[0] \ + & S390X_CAPBIT(S390X_ECDSA_VERIFY_P##bits)) \ + && (OPENSSL_s390xcap_P.kdsa[0] \ + & S390X_CAPBIT(S390X_ECDSA_SIGN_P##bits))) \ + ret = &EC_GFp_s390x_nistp##bits##_meth; \ + else \ + ret = EC_GFp_mont_method(); \ + \ + return ret; \ +} + +EC_GFP_S390X_NISTP_METHOD(256) +EC_GFP_S390X_NISTP_METHOD(384) +EC_GFP_S390X_NISTP_METHOD(521) diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 2fd2ce46..bf7aeb10 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -64,6 +64,9 @@ const EC_METHOD *EC_GFp_simple_method(void) 0, /* keycopy */ 0, /* keyfinish */ ecdh_simple_compute_key, + ecdsa_simple_sign_setup, + ecdsa_simple_sign_sig, + ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ ec_GFp_simple_blind_coordinates, ec_GFp_simple_ladder_pre, @@ -146,7 +149,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -204,7 +207,7 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, if (a != NULL || b != NULL) { if (group->meth->field_decode) { if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -248,7 +251,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) BN_CTX *new_ctx = NULL; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) { ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE); @@ -376,7 +379,7 @@ int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, int ret = 0; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -435,7 +438,7 @@ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, if (group->meth->field_decode != 0) { if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -509,7 +512,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -629,7 +632,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -813,7 +816,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -966,7 +969,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return -1; } @@ -1083,7 +1086,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, field_sqr = group->meth->field_sqr; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return -1; } @@ -1169,7 +1172,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, return 1; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -1210,7 +1213,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, return 1; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -1380,7 +1383,8 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *new_ctx = NULL; int ret = 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + if (ctx == NULL + && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -1388,7 +1392,7 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, goto err; do { - if (!BN_priv_rand_range(e, group->field)) + if (!BN_priv_rand_range_ex(e, group->field, ctx)) goto err; } while (BN_is_zero(e)); @@ -1436,7 +1440,7 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, /* make sure lambda is not zero */ do { - if (!BN_priv_rand_range(lambda, group->field)) { + if (!BN_priv_rand_range_ex(lambda, group->field, ctx)) { ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB); goto err; } diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 1958aa26..b8813921 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -110,7 +110,11 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, X448_public_from_private(pubkey, privkey); break; case EVP_PKEY_ED448: - ED448_public_from_private(pubkey, privkey); + /* + * TODO(3.0): We set the library context to NULL for now. This will + * need to change. + */ + ED448_public_from_private(NULL, pubkey, privkey); break; } } @@ -191,7 +195,7 @@ static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) } rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE); - ASN1_OCTET_STRING_free(oct); + ASN1_STRING_clear_free(oct); return rv; } @@ -771,8 +775,12 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, return 0; } - if (ED448_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL, - 0) == 0) + /* + * TODO(3.0): We use NULL for the library context for now. Will need to + * change later. + */ + if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey, + NULL, 0) == 0) return 0; *siglen = ED448_SIGSIZE; return 1; @@ -799,7 +807,11 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, if (siglen != ED448_SIGSIZE) return 0; - return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0); + /* + * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to + * change. + */ + return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0); } static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) diff --git a/crypto/engine/eng_all.c b/crypto/engine/eng_all.c index d06768a7..e1f09acd 100644 --- a/crypto/engine/eng_all.c +++ b/crypto/engine/eng_all.c @@ -12,9 +12,6 @@ void ENGINE_load_builtin_engines(void) { - /* Some ENGINEs need this */ - OPENSSL_cpuid_setup(); - OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); } diff --git a/crypto/engine/eng_err.c b/crypto/engine/eng_err.c index 1d470521..c602e0ff 100644 --- a/crypto/engine/eng_err.c +++ b/crypto/engine/eng_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,70 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ENGINE_str_functs[] = { - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DIGEST_UPDATE, 0), "digest_update"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_CTRL, 0), "dynamic_ctrl"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_GET_DATA_CTX, 0), - "dynamic_get_data_ctx"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_LOAD, 0), "dynamic_load"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_SET_DATA_CTX, 0), - "dynamic_set_data_ctx"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_ADD, 0), "ENGINE_add"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_BY_ID, 0), "ENGINE_by_id"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, 0), - "ENGINE_cmd_is_executable"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL, 0), "ENGINE_ctrl"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD, 0), "ENGINE_ctrl_cmd"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD_STRING, 0), - "ENGINE_ctrl_cmd_string"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_FINISH, 0), "ENGINE_finish"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_CIPHER, 0), - "ENGINE_get_cipher"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_DIGEST, 0), - "ENGINE_get_digest"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_FIRST, 0), - "ENGINE_get_first"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_LAST, 0), "ENGINE_get_last"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_NEXT, 0), "ENGINE_get_next"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, 0), - "ENGINE_get_pkey_asn1_meth"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_METH, 0), - "ENGINE_get_pkey_meth"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PREV, 0), "ENGINE_get_prev"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_INIT, 0), "ENGINE_init"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_ADD, 0), "engine_list_add"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_REMOVE, 0), - "engine_list_remove"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, 0), - "ENGINE_load_private_key"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, 0), - "ENGINE_load_public_key"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, 0), - "ENGINE_load_ssl_client_cert"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_NEW, 0), "ENGINE_new"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, 0), - "ENGINE_pkey_asn1_find_str"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_REMOVE, 0), "ENGINE_remove"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_DEFAULT_STRING, 0), - "ENGINE_set_default_string"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_ID, 0), "ENGINE_set_id"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_NAME, 0), "ENGINE_set_name"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_TABLE_REGISTER, 0), - "engine_table_register"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UNLOCKED_FINISH, 0), - "engine_unlocked_finish"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UP_REF, 0), "ENGINE_up_ref"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_CLEANUP_ITEM, 0), - "int_cleanup_item"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_CTRL_HELPER, 0), "int_ctrl_helper"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_CONFIGURE, 0), - "int_engine_configure"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_MODULE_INIT, 0), - "int_engine_module_init"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_OSSL_HMAC_INIT, 0), "ossl_hmac_init"}, - {0, NULL} -}; - static const ERR_STRING_DATA ENGINE_str_reasons[] = { {ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ALREADY_LOADED), "already loaded"}, {ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER), @@ -145,10 +81,8 @@ static const ERR_STRING_DATA ENGINE_str_reasons[] = { int ERR_load_ENGINE_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) { - ERR_load_strings_const(ENGINE_str_functs); + if (ERR_reason_error_string(ENGINE_str_reasons[0].error) == NULL) ERR_load_strings_const(ENGINE_str_reasons); - } #endif return 1; } diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index d41006f8..debbb16a 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -29,12 +29,14 @@ */ #define TEST_ENG_OPENSSL_RC4 #ifndef OPENSSL_NO_STDIO -#define TEST_ENG_OPENSSL_PKEY +# define TEST_ENG_OPENSSL_PKEY #endif /* #define TEST_ENG_OPENSSL_HMAC */ /* #define TEST_ENG_OPENSSL_HMAC_INIT */ /* #define TEST_ENG_OPENSSL_RC4_OTHERS */ -#define TEST_ENG_OPENSSL_RC4_P_INIT +#ifndef OPENSSL_NO_STDIO +# define TEST_ENG_OPENSSL_RC4_P_INIT +#endif /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ #define TEST_ENG_OPENSSL_SHA /* #define TEST_ENG_OPENSSL_SHA_OTHERS */ diff --git a/crypto/engine/eng_rdrand.c b/crypto/engine/eng_rdrand.c index 2fcc0edf..7dd3b9fd 100644 --- a/crypto/engine/eng_rdrand.c +++ b/crypto/engine/eng_rdrand.c @@ -12,6 +12,7 @@ #include #include #include "internal/engine.h" +#include "internal/cryptlib.h" #include #include #include @@ -79,8 +80,6 @@ static ENGINE *ENGINE_rdrand(void) void engine_load_rdrand_int(void) { - extern unsigned int OPENSSL_ia32cap_P[]; - if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { ENGINE *toadd = ENGINE_rdrand(); if (!toadd) diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c index c3afa583..62e94168 100644 --- a/crypto/engine/eng_table.c +++ b/crypto/engine/eng_table.c @@ -197,6 +197,9 @@ ENGINE *engine_table_select_int(ENGINE_TABLE **table, int nid, const char *f, ENGINE_PILE tmplate, *fnd = NULL; int initres, loop = 0; + /* Load the config before trying to check if engines are available */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (!(*table)) { OSSL_TRACE3(ENGINE_TABLE, "%s:%d, nid=%d, nothing registered!\n", diff --git a/crypto/err/build.info b/crypto/err/build.info index 6163d95b..c010ea4c 100644 --- a/crypto/err/build.info +++ b/crypto/err/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - err.c err_all.c err_prn.c + err_blocks.c err.c err_all.c err_prn.c diff --git a/crypto/err/err.c b/crypto/err/err.c index 8752c119..6ad995d6 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +/* TODO: When ERR_STATE becomes opaque, this musts be removed */ +#define OSSL_FORCE_ERR_STATE + #include #include #include @@ -22,6 +25,10 @@ #include "internal/ctype.h" #include "internal/constant_time_locl.h" #include "e_os.h" +#include "err_locl.h" + +/* Forward declaration in case it's not published because of configuration */ +ERR_STATE *ERR_get_state(void); static int err_load_strings(const ERR_STRING_DATA *str); @@ -63,7 +70,6 @@ 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"}, @@ -71,36 +77,6 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {0, NULL}, }; -static ERR_STRING_DATA ERR_str_functs[] = { - {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"}, - {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"}, - {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"}, - {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"}, - {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"}, - {ERR_PACK(0, SYS_F_BIND, 0), "bind"}, - {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"}, - {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"}, -# ifdef OPENSSL_SYS_WINDOWS - {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"}, -# endif - {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, - {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, - {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"}, - {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"}, - {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"}, - {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"}, - {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"}, - {ERR_PACK(0, SYS_F_GETHOSTBYNAME, 0), "gethostbyname"}, - {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"}, - {ERR_PACK(0, SYS_F_OPEN, 0), "open"}, - {ERR_PACK(0, SYS_F_CLOSE, 0), "close"}, - {ERR_PACK(0, SYS_F_IOCTL, 0), "ioctl"}, - {ERR_PACK(0, SYS_F_STAT, 0), "stat"}, - {ERR_PACK(0, SYS_F_FCNTL, 0), "fcntl"}, - {ERR_PACK(0, SYS_F_FSTAT, 0), "fstat"}, - {0, NULL}, -}; - static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_SYS_LIB, "system lib"}, {ERR_R_BN_LIB, "BN lib"}, @@ -155,8 +131,13 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; static int int_err_library_number = ERR_LIB_USER; -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, +typedef enum ERR_GET_ACTION_e { + EV_POP, EV_PEEK, EV_PEEK_LAST +} ERR_GET_ACTION; + +static unsigned long get_error_values(ERR_GET_ACTION g, + const char **file, int *line, + const char **func, const char **data, int *flags); static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) @@ -164,7 +145,7 @@ static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) unsigned long ret, l; l = a->error; - ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); + ret = l ^ ERR_GET_LIB(l); return (ret ^ ret % 19 * 13); } @@ -265,24 +246,6 @@ static void build_SYS_str_reasons(void) } #endif -#define err_clear_data(p, i) \ - do { \ - if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) {\ - OPENSSL_free((p)->err_data[i]); \ - (p)->err_data[i] = NULL; \ - } \ - (p)->err_data_flags[i] = 0; \ - } while (0) - -#define err_clear(p, i) \ - do { \ - err_clear_data(p, i); \ - (p)->err_flags[i] = 0; \ - (p)->err_buffer[i] = 0; \ - (p)->err_file[i] = NULL; \ - (p)->err_line[i] = -1; \ - } while (0) - static void ERR_STATE_free(ERR_STATE *s) { int i; @@ -290,7 +253,7 @@ static void ERR_STATE_free(ERR_STATE *s) if (s == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear_data(s, i); + err_clear_data(s, i, 1); } OPENSSL_free(s); } @@ -354,8 +317,6 @@ int ERR_load_ERR_strings(void) err_load_strings(ERR_str_libraries); err_load_strings(ERR_str_reasons); - err_patch(ERR_LIB_SYS, ERR_str_functs); - err_load_strings(ERR_str_functs); build_SYS_str_reasons(); #endif return 1; @@ -404,156 +365,170 @@ void err_free_strings_int(void) /********************************************************/ -void ERR_put_error(int lib, int func, int reason, const char *file, int line) -{ - ERR_STATE *es; - -#ifdef _OSD_POSIX - /* - * In the BS2000-OSD POSIX subsystem, the compiler generates path names - * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to - * something sensible. @@@ We shouldn't modify a const string, though. - */ - if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { - char *end; - - /* Skip the "*POSIX(" prefix */ - file += sizeof("*POSIX(") - 1; - end = &file[strlen(file) - 1]; - if (*end == ')') - *end = '\0'; - /* Optional: use the basename of the path only. */ - if ((end = strrchr(file, '/')) != NULL) - file = &end[1]; - } -#endif - es = ERR_get_state(); - if (es == NULL) - return; - - es->top = (es->top + 1) % ERR_NUM_ERRORS; - if (es->top == es->bottom) - es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; - es->err_flags[es->top] = 0; - es->err_buffer[es->top] = ERR_PACK(lib, func, reason); - es->err_file[es->top] = file; - es->err_line[es->top] = line; - err_clear_data(es, es->top); -} - void ERR_clear_error(void) { int i; ERR_STATE *es; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear(es, i); + err_clear(es, i, 0); } es->top = es->bottom = 0; } unsigned long ERR_get_error(void) { - return get_error_values(1, 0, NULL, NULL, NULL, NULL); + return get_error_values(EV_POP, NULL, NULL, NULL, NULL, NULL); } unsigned long ERR_get_error_line(const char **file, int *line) { - return get_error_values(1, 0, file, line, NULL, NULL); + return get_error_values(EV_POP, file, line, NULL, NULL, NULL); } +unsigned long ERR_get_error_func(const char **func) +{ + return get_error_values(EV_POP, NULL, NULL, func, NULL, NULL); +} + +unsigned long ERR_get_error_data(const char **data, int *flags) +{ + return get_error_values(EV_POP, NULL, NULL, NULL, data, flags); +} + +unsigned long ERR_get_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_POP, file, line, func, data, flags); +} + +#if !OPENSSL_API_3 unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(1, 0, file, line, data, flags); + return get_error_values(EV_POP, file, line, NULL, data, flags); } +#endif unsigned long ERR_peek_error(void) { - return get_error_values(0, 0, NULL, NULL, NULL, NULL); + return get_error_values(EV_PEEK, NULL, NULL, NULL, NULL, NULL); } unsigned long ERR_peek_error_line(const char **file, int *line) { - return get_error_values(0, 0, file, line, NULL, NULL); + return get_error_values(EV_PEEK, file, line, NULL, NULL, NULL); } +unsigned long ERR_peek_error_func(const char **func) +{ + return get_error_values(EV_PEEK, NULL, NULL, func, NULL, NULL); +} + +unsigned long ERR_peek_error_data(const char **data, int *flags) +{ + return get_error_values(EV_PEEK, NULL, NULL, NULL, data, flags); +} + +unsigned long ERR_peek_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_PEEK, file, line, func, data, flags); +} + +#if !OPENSSL_API_3 unsigned long ERR_peek_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(0, 0, file, line, data, flags); + return get_error_values(EV_PEEK, file, line, NULL, data, flags); } +#endif unsigned long ERR_peek_last_error(void) { - return get_error_values(0, 1, NULL, NULL, NULL, NULL); + return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, NULL, NULL); } unsigned long ERR_peek_last_error_line(const char **file, int *line) { - return get_error_values(0, 1, file, line, NULL, NULL); + return get_error_values(EV_PEEK_LAST, file, line, NULL, NULL, NULL); } +unsigned long ERR_peek_last_error_func(const char **func) +{ + return get_error_values(EV_PEEK_LAST, NULL, NULL, func, NULL, NULL); +} + +unsigned long ERR_peek_last_error_data(const char **data, int *flags) +{ + return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, data, flags); +} + +unsigned long ERR_peek_last_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_PEEK_LAST, file, line, func, data, flags); +} + +#if !OPENSSL_API_3 unsigned long ERR_peek_last_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(0, 1, file, line, data, flags); + return get_error_values(EV_PEEK_LAST, file, line, NULL, data, flags); } +#endif -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, - int *flags) +static unsigned long get_error_values(ERR_GET_ACTION g, + const char **file, int *line, + const char **func, + const char **data, int *flags) { int i = 0; ERR_STATE *es; unsigned long ret; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return 0; - if (inc && top) { - if (file) - *file = ""; - if (line) - *line = 0; - if (data) - *data = ""; - if (flags) - *flags = 0; - - return ERR_R_INTERNAL_ERROR; - } - + /* + * Clear anything that should have been cleared earlier. We do this + * here because this doesn't have constant-time issues. + */ while (es->bottom != es->top) { if (es->err_flags[es->top] & ERR_FLAG_CLEAR) { - err_clear(es, es->top); + err_clear(es, es->top, 0); es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; continue; } i = (es->bottom + 1) % ERR_NUM_ERRORS; if (es->err_flags[i] & ERR_FLAG_CLEAR) { es->bottom = i; - err_clear(es, es->bottom); + err_clear(es, es->bottom, 0); continue; } break; } + /* If everything has been cleared, the stack is empty. */ if (es->bottom == es->top) return 0; - if (top) - i = es->top; /* last error */ + /* Which error, the top of stack (latest one) or the first one? */ + if (g == EV_PEEK_LAST) + i = es->top; else - i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ + i = (es->bottom + 1) % ERR_NUM_ERRORS; ret = es->err_buffer[i]; - if (inc) { + if (g == EV_POP) { es->bottom = i; es->err_buffer[i] = 0; } @@ -568,9 +543,15 @@ static unsigned long get_error_values(int inc, int top, const char **file, } } + if (func != NULL) { + *func = es->err_func[i]; + if (*func == NULL) + *func = "N/A"; + } + if (data == NULL) { - if (inc) { - err_clear_data(es, i); + if (g == EV_POP) { + err_clear_data(es, i, 0); } } else { if (es->err_data[i] == NULL) { @@ -588,9 +569,9 @@ static unsigned long get_error_values(int inc, int top, const char **file, void ERR_error_string_n(unsigned long e, char *buf, size_t len) { - char lsbuf[64], fsbuf[64], rsbuf[64]; - const char *ls, *fs, *rs; - unsigned long l, f, r; + char lsbuf[64], rsbuf[64]; + const char *ls, *rs; + unsigned long f = 0, l, r; if (len == 0) return; @@ -602,13 +583,6 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len) ls = lsbuf; } - fs = ERR_func_error_string(e); - f = ERR_GET_FUNC(e); - if (fs == NULL) { - BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); - fs = fsbuf; - } - rs = ERR_reason_error_string(e); r = ERR_GET_REASON(e); if (rs == NULL) { @@ -616,7 +590,7 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len) rs = rsbuf; } - BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs); + BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, "", rs); if (strlen(buf) == len - 1) { /* Didn't fit; use a minimal format. */ BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, f, r); @@ -652,21 +626,12 @@ const char *ERR_lib_error_string(unsigned long e) return ((p == NULL) ? NULL : p->string); } +#if !OPENSSL_API_3 const char *ERR_func_error_string(unsigned long e) { - ERR_STRING_DATA d, *p; - unsigned long l, f; - - if (!RUN_ONCE(&err_string_init, do_err_strings_init)) { - return NULL; - } - - l = ERR_GET_LIB(e); - f = ERR_GET_FUNC(e); - d.error = ERR_PACK(l, f, 0); - p = int_err_get_item(&d); - return ((p == NULL) ? NULL : p->string); + return NULL; } +#endif const char *ERR_reason_error_string(unsigned long e) { @@ -717,7 +682,7 @@ DEFINE_RUN_ONCE_STATIC(err_do_init) return CRYPTO_THREAD_init_local(&err_thread_local, NULL); } -ERR_STATE *ERR_get_state(void) +ERR_STATE *err_get_state_int(void) { ERR_STATE *state; int saveerrno = get_last_sys_error(); @@ -756,6 +721,14 @@ ERR_STATE *ERR_get_state(void) return state; } +#if !OPENSSL_API_3 +ERR_STATE *ERR_get_state(void) +{ + return err_get_state_int(); +} +#endif + + /* * err_shelve_state returns the current thread local error state * and freezes the error module until err_unshelve_state is called. @@ -813,20 +786,17 @@ int ERR_get_next_error_library(void) return ret; } -static int err_set_error_data_int(char *data, int flags) +static int err_set_error_data_int(char *data, size_t size, int flags, + int deallocate) { ERR_STATE *es; - int i; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return 0; - i = es->top; - - err_clear_data(es, i); - es->err_data[i] = data; - es->err_data_flags[i] = flags; + err_clear_data(es, es->top, deallocate); + err_set_data(es, es->top, data, size, flags); return 1; } @@ -836,8 +806,18 @@ void ERR_set_error_data(char *data, int flags) /* * This function is void so we cannot propagate the error return. Since it * is also in the public API we can't change the return type. + * + * We estimate the size of the data. If it's not flagged as allocated, + * then this is safe, and if it is flagged as allocated, then our size + * may be smaller than the actual allocation, but that doesn't matter + * too much, the buffer will remain untouched or will eventually be + * reallocated to a new size. + * + * callers should be advised that this function takes over ownership of + * the allocated memory, i.e. they can't count on the pointer to remain + * valid. */ - err_set_error_data_int(data, flags); + err_set_error_data_int(data, strlen(data) + 1, flags, 1); } void ERR_add_error_data(int num, ...) @@ -851,42 +831,59 @@ void ERR_add_error_data(int num, ...) void ERR_add_error_vdata(int num, va_list args) { int i, len, size; - char *str, *p, *arg; + int flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + char *str, *arg; ERR_STATE *es; /* Get the current error data; if an allocated string get it. */ - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return; i = es->top; - p = es->err_data_flags[i] == (ERR_TXT_MALLOCED | ERR_TXT_STRING) - ? es->err_data[i] : ""; - /* Start with initial (or empty) string and allocate a new buffer */ - size = 80 + strlen(p); - if ((str = OPENSSL_malloc(size + 1)) == NULL) { - /* ERRerr(ERR_F_ERR_ADD_ERROR_VDATA, ERR_R_MALLOC_FAILURE); */ + /* + * If err_data is allocated already, re-use the space. + * Otherwise, allocate a small new buffer. + */ + if ((es->err_data_flags[i] & flags) == flags) { + str = es->err_data[i]; + size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + } else if ((str = OPENSSL_malloc(size = 81)) == NULL) { return; + } else { + str[0] = '\0'; } - strcpy(str, p); + len = strlen(str); - for (len = 0; --num >= 0; ) { + while (--num >= 0) { arg = va_arg(args, char *); if (arg == NULL) arg = ""; len += strlen(arg); - if (len > size) { + if (len >= size) { + char *p; + size = len + 20; - p = OPENSSL_realloc(str, size + 1); + p = OPENSSL_realloc(str, size); if (p == NULL) { OPENSSL_free(str); return; } str = p; } - OPENSSL_strlcat(str, arg, (size_t)size + 1); + OPENSSL_strlcat(str, arg, (size_t)size); } - if (!err_set_error_data_int(str, ERR_TXT_MALLOCED | ERR_TXT_STRING)) + if (!err_set_error_data_int(str, size, flags, 0)) OPENSSL_free(str); } @@ -894,7 +891,7 @@ int ERR_set_mark(void) { ERR_STATE *es; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return 0; @@ -908,13 +905,13 @@ int ERR_pop_to_mark(void) { ERR_STATE *es; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return 0; while (es->bottom != es->top && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { - err_clear(es, es->top); + err_clear(es, es->top, 0); es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; } @@ -929,7 +926,7 @@ int ERR_clear_last_mark(void) ERR_STATE *es; int top; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return 0; @@ -950,7 +947,7 @@ void err_clear_last_constant_time(int clear) ERR_STATE *es; int top; - es = ERR_get_state(); + es = err_get_state_int(); if (es == NULL) return; diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 8962fe5c..972421f4 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include "internal/propertyerr.h" @@ -103,7 +102,6 @@ int err_load_crypto_strings_int(void) ERR_load_ESS_strings() == 0 || ERR_load_ASYNC_strings() == 0 || #endif - ERR_load_KDF_strings() == 0 || ERR_load_OSSL_STORE_strings() == 0 || ERR_load_PROP_strings() == 0 || ERR_load_PROV_strings() == 0) diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c new file mode 100644 index 00000000..e50f580b --- /dev/null +++ b/crypto/err/err_blocks.c @@ -0,0 +1,116 @@ +/* + * 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: When ERR_STATE becomes opaque, this musts be removed */ +#define OSSL_FORCE_ERR_STATE + +#include +#include +#include "err_locl.h" + +void ERR_new(void) +{ + ERR_STATE *es; + + es = err_get_state_int(); + if (es == NULL) + return; + + /* Allocate a slot */ + err_get_slot(es); + err_clear(es, es->top, 0); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + ERR_STATE *es; + + es = err_get_state_int(); + if (es == NULL) + return; + + err_set_debug(es, es->top, file, line, func); +} + +void ERR_set_error(int lib, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(lib, reason, fmt, args); + va_end(args); +} + +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) +{ + ERR_STATE *es; + char *buf = NULL; + size_t buf_size = 0; + unsigned long flags = 0; + size_t i; + + es = err_get_state_int(); + if (es == NULL) + return; + i = es->top; + + if (fmt != NULL) { + int printed_len = 0; + char *rbuf = NULL; + + buf = es->err_data[i]; + buf_size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + + /* + * Try to maximize the space available. If that fails, we use what + * we have. + */ + if (buf_size < ERR_MAX_DATA_SIZE + && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) { + buf = rbuf; + buf_size = ERR_MAX_DATA_SIZE; + } + + if (buf != NULL) { + printed_len = BIO_vsnprintf(buf, buf_size, fmt, args); + } + if (printed_len < 0) + printed_len = 0; + buf[printed_len] = '\0'; + + /* + * Try to reduce the size, but only if we maximized above. If that + * fails, we keep what we have. + * (According to documentation, realloc leaves the old buffer untouched + * if it fails) + */ + if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) { + buf = rbuf; + buf_size = printed_len + 1; + } + + if (buf != NULL) + flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + } + + err_clear_data(es, es->top, 0); + err_set_error(es, es->top, lib, reason); + if (fmt != NULL) + err_set_data(es, es->top, buf, buf_size, flags); +} diff --git a/crypto/err/err_locl.h b/crypto/err/err_locl.h new file mode 100644 index 00000000..0374bf6a --- /dev/null +++ b/crypto/err/err_locl.h @@ -0,0 +1,70 @@ +/* + * 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 + +static ossl_inline void err_get_slot(ERR_STATE *es) +{ + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; +} + +static ossl_inline void err_clear_data(ERR_STATE *es, size_t i, int deall) +{ + if (es->err_data_flags[i] & ERR_TXT_MALLOCED) { + if (deall) { + OPENSSL_free(es->err_data[i]); + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } else if (es->err_data[i] != NULL) { + es->err_data[i][0] = '\0'; + } + } else { + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } +} + +static ossl_inline void err_set_error(ERR_STATE *es, size_t i, + int lib, int reason) +{ + es->err_buffer[i] = ERR_PACK(lib, 0, reason); +} + +static ossl_inline void err_set_debug(ERR_STATE *es, size_t i, + const char *file, int line, + const char *fn) +{ + es->err_file[i] = file; + es->err_line[i] = line; + es->err_func[i] = fn; +} + +static ossl_inline void err_set_data(ERR_STATE *es, size_t i, + void *data, size_t datasz, int flags) +{ + es->err_data[i] = data; + es->err_data_size[i] = datasz; + es->err_data_flags[i] = flags; +} + +static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) +{ + err_clear_data(es, i, (deall)); + es->err_flags[i] = 0; + es->err_buffer[i] = 0; + es->err_file[i] = NULL; + es->err_line[i] = -1; +} + +ERR_STATE *err_get_state_int(void); diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index b43367f6..1e1531b9 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -7,29 +7,38 @@ * https://www.openssl.org/source/license.html */ +/* TODO: When ERR_STATE becomes opaque, this musts be removed */ +#define OSSL_FORCE_ERR_STATE + #include #include "internal/cryptlib.h" #include #include #include +#include "err_locl.h" void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), void *u) { CRYPTO_THREAD_ID tid = CRYPTO_THREAD_get_current_id(); unsigned long l; - char buf[256]; - char buf2[4096], *hex; - const char *file, *data; + char buf[4096], *hex; + const char *lib, *reason; + const char *file, *data, *func; int line, flags; - while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { - ERR_error_string_n(l, buf, sizeof(buf)); + while ((l = ERR_get_error_all(&file, &line, &func, &data, &flags)) != 0) { + lib = ERR_lib_error_string(l); + reason = ERR_reason_error_string(l); + if (func == NULL) + func = "unknown function"; + if ((flags & ERR_TXT_STRING) == 0) + data = ""; hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); - BIO_snprintf(buf2, sizeof(buf2), "%s:%s:%s:%d:%s\n", hex, buf, file, - line, (flags & ERR_TXT_STRING) ? data : ""); + BIO_snprintf(buf, sizeof(buf), "%s:error:%s:%s:%s:%s:%d:%s\n", + hex, lib, func, reason, file, line, data); OPENSSL_free(hex); - if (cb(buf2, strlen(buf2), u) <= 0) + 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 04e76df6..925ed65b 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -3,6 +3,7 @@ # The INPUT HEADER is scanned for declarations # LIBNAME INPUT HEADER ERROR-TABLE FILE L ERR NONE NONE +L FUNC NONE NONE L BN include/openssl/bn.h crypto/bn/bn_err.c L RSA include/openssl/rsa.h crypto/rsa/rsa_err.c L DH include/openssl/dh.h crypto/dh/dh_err.c diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index b5ae4e1a..fc9001fb 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -205,6 +205,7 @@ BN_F_BN_EXPAND_INTERNAL:120:bn_expand_internal BN_F_BN_GENCB_NEW:143:BN_GENCB_new BN_F_BN_GENERATE_DSA_NONCE:140:BN_generate_dsa_nonce BN_F_BN_GENERATE_PRIME_EX:141:BN_generate_prime_ex +BN_F_BN_GENERATE_PRIME_EX2:152:BN_generate_prime_ex2 BN_F_BN_GF2M_MOD:131:BN_GF2m_mod BN_F_BN_GF2M_MOD_EXP:132:BN_GF2m_mod_exp BN_F_BN_GF2M_MOD_MUL:133:BN_GF2m_mod_mul @@ -245,8 +246,8 @@ CMS_F_CMS_ADD1_RECEIPTREQUEST:158:CMS_add1_ReceiptRequest CMS_F_CMS_ADD1_RECIPIENT_CERT:101:CMS_add1_recipient_cert CMS_F_CMS_ADD1_SIGNER:102:CMS_add1_signer CMS_F_CMS_ADD1_SIGNINGTIME:103:cms_add1_signingTime -CMS_F_CMS_ADD1_SIGNING_CERT:181:CMS_add1_signing_cert -CMS_F_CMS_ADD1_SIGNING_CERT_V2:182:CMS_add1_signing_cert_v2 +CMS_F_CMS_ADD1_SIGNING_CERT:181:cms_add1_signing_cert +CMS_F_CMS_ADD1_SIGNING_CERT_V2:182:cms_add1_signing_cert_v2 CMS_F_CMS_COMPRESS:104:CMS_compress CMS_F_CMS_COMPRESSEDDATA_CREATE:105:cms_CompressedData_create CMS_F_CMS_COMPRESSEDDATA_INIT_BIO:106:cms_CompressedData_init_bio @@ -390,17 +391,29 @@ CRYPTO_F_GET_AND_LOCK:113:get_and_lock CRYPTO_F_GET_PROVIDER_STORE:133:get_provider_store CRYPTO_F_OPENSSL_ATEXIT:114:OPENSSL_atexit CRYPTO_F_OPENSSL_BUF2HEXSTR:117:OPENSSL_buf2hexstr +CRYPTO_F_OPENSSL_BUF2HEXSTR_EX:153: CRYPTO_F_OPENSSL_FOPEN:119:openssl_fopen CRYPTO_F_OPENSSL_HEXSTR2BUF:118:OPENSSL_hexstr2buf +CRYPTO_F_OPENSSL_HEXSTR2BUF_EX:154: CRYPTO_F_OPENSSL_INIT_CRYPTO:116:OPENSSL_init_crypto CRYPTO_F_OPENSSL_LH_NEW:126:OPENSSL_LH_new CRYPTO_F_OPENSSL_SK_DEEP_COPY:127:OPENSSL_sk_deep_copy CRYPTO_F_OPENSSL_SK_DUP:128:OPENSSL_sk_dup +CRYPTO_F_OSSL_PARAM_BLD_PUSH_BN:143: +CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR:144: +CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING:145: +CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR:146: +CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING:147: +CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM:148: +CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX:149: +CRYPTO_F_OSSL_PARAM_TYPE_TO_PARAM:150: CRYPTO_F_OSSL_PROVIDER_ACTIVATE:130:ossl_provider_activate CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN:132:OSSL_PROVIDER_add_builtin CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER:139:ossl_provider_add_parameter CRYPTO_F_OSSL_PROVIDER_NEW:131:ossl_provider_new CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH:140:ossl_provider_set_module_path +CRYPTO_F_PARAM_PUSH:151: +CRYPTO_F_PARAM_PUSH_NUM:152: CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init @@ -534,9 +547,14 @@ EC_F_ECDH_COMPUTE_KEY:246:ECDH_compute_key EC_F_ECDH_SIMPLE_COMPUTE_KEY:257:ecdh_simple_compute_key EC_F_ECDSA_DO_SIGN_EX:251:ECDSA_do_sign_ex EC_F_ECDSA_DO_VERIFY:252:ECDSA_do_verify +EC_F_ECDSA_S390X_NISTP_SIGN_SIG:313:ecdsa_s390x_nistp_sign_sig +EC_F_ECDSA_S390X_NISTP_VERIFY_SIG:314:ecdsa_s390x_nistp_verify_sig EC_F_ECDSA_SIGN_EX:254:ECDSA_sign_ex EC_F_ECDSA_SIGN_SETUP:248:ECDSA_sign_setup EC_F_ECDSA_SIG_NEW:265:ECDSA_SIG_new +EC_F_ECDSA_SIMPLE_SIGN_SETUP:310:ecdsa_simple_sign_setup +EC_F_ECDSA_SIMPLE_SIGN_SIG:311:ecdsa_simple_sign_sig +EC_F_ECDSA_SIMPLE_VERIFY_SIG:312:ecdsa_simple_verify_sig EC_F_ECDSA_VERIFY:253:ECDSA_verify EC_F_ECD_ITEM_VERIFY:270:ecd_item_verify EC_F_ECKEY_PARAM2TYPE:223:eckey_param2type @@ -616,6 +634,7 @@ EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES:169:\ ec_GFp_simple_set_compressed_coordinates EC_F_EC_GROUP_CHECK:170:EC_GROUP_check EC_F_EC_GROUP_CHECK_DISCRIMINANT:171:EC_GROUP_check_discriminant +EC_F_EC_GROUP_CHECK_NAMED_CURVE:299:EC_GROUP_check_named_curve EC_F_EC_GROUP_COPY:106:EC_GROUP_copy EC_F_EC_GROUP_GET_CURVE:291:EC_GROUP_get_curve EC_F_EC_GROUP_GET_CURVE_GF2M:172:EC_GROUP_get_curve_GF2m @@ -627,6 +646,8 @@ EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS:193:EC_GROUP_get_pentanomial_basis EC_F_EC_GROUP_GET_TRINOMIAL_BASIS:194:EC_GROUP_get_trinomial_basis EC_F_EC_GROUP_NEW:108:EC_GROUP_new EC_F_EC_GROUP_NEW_BY_CURVE_NAME:174:EC_GROUP_new_by_curve_name +EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX:301:EC_GROUP_new_by_curve_name_ex +EC_F_EC_GROUP_NEW_EX:302:EC_GROUP_new_ex EC_F_EC_GROUP_NEW_FROM_DATA:175:ec_group_new_from_data EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS:263:EC_GROUP_new_from_ecparameters EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS:264:EC_GROUP_new_from_ecpkparameters @@ -640,6 +661,7 @@ EC_F_EC_KEY_COPY:178:EC_KEY_copy EC_F_EC_KEY_GENERATE_KEY:179:EC_KEY_generate_key EC_F_EC_KEY_NEW:182:EC_KEY_new EC_F_EC_KEY_NEW_METHOD:245:EC_KEY_new_method +EC_F_EC_KEY_NEW_METHOD_INT:300:ec_key_new_method_int EC_F_EC_KEY_OCT2PRIV:255:EC_KEY_oct2priv EC_F_EC_KEY_PRINT:180:EC_KEY_print EC_F_EC_KEY_PRINT_FP:181:EC_KEY_print_fp @@ -699,6 +721,7 @@ EC_F_NISTP521_PRE_COMP_NEW:237:nistp521_pre_comp_new EC_F_O2I_ECPUBLICKEY:152:o2i_ECPublicKey EC_F_OLD_EC_PRIV_DECODE:222:old_ec_priv_decode EC_F_OSSL_ECDH_COMPUTE_KEY:247:ossl_ecdh_compute_key +EC_F_OSSL_ECDSA_SIGN_SETUP:300:ossl_ecdsa_sign_setup EC_F_OSSL_ECDSA_SIGN_SIG:249:ossl_ecdsa_sign_sig EC_F_OSSL_ECDSA_VERIFY_SIG:250:ossl_ecdsa_verify_sig EC_F_PKEY_ECD_CTRL:271:pkey_ecd_ctrl @@ -778,10 +801,6 @@ EVP_F_ARIA_GCM_CTRL:197:aria_gcm_ctrl EVP_F_ARIA_GCM_INIT_KEY:176:aria_gcm_init_key EVP_F_ARIA_INIT_KEY:185:aria_init_key EVP_F_B64_NEW:198:b64_new -EVP_F_BLAKE2B_MAC_CTRL:220:blake2b_mac_ctrl -EVP_F_BLAKE2B_MAC_INIT:221:blake2b_mac_init -EVP_F_BLAKE2S_MAC_CTRL:222:blake2s_mac_ctrl -EVP_F_BLAKE2S_MAC_INIT:223:blake2s_mac_init EVP_F_CAMELLIA_INIT_KEY:159:camellia_init_key EVP_F_CHACHA20_POLY1305_CTRL:182:chacha20_poly1305_ctrl EVP_F_CMLL_T4_INIT_KEY:179:cmll_t4_init_key @@ -806,10 +825,10 @@ EVP_F_EVP_DIGESTUPDATE:231:EVP_DigestUpdate EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate -EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl -EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str -EVP_F_EVP_KDF_CTX_NEW:240:EVP_KDF_CTX_new -EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id +EVP_F_EVP_KDF_CTX_DUP:220: +EVP_F_EVP_KDF_CTX_NEW:221: +EVP_F_EVP_KEYEXCH_FETCH:245:EVP_KEYEXCH_fetch +EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup @@ -837,6 +856,7 @@ EVP_F_EVP_PKEY_DECRYPT_INIT:138:EVP_PKEY_decrypt_init EVP_F_EVP_PKEY_DECRYPT_OLD:151:EVP_PKEY_decrypt_old EVP_F_EVP_PKEY_DERIVE:153:EVP_PKEY_derive EVP_F_EVP_PKEY_DERIVE_INIT:154:EVP_PKEY_derive_init +EVP_F_EVP_PKEY_DERIVE_INIT_EX:243:EVP_PKEY_derive_init_ex EVP_F_EVP_PKEY_DERIVE_SET_PEER:155:EVP_PKEY_derive_set_peer EVP_F_EVP_PKEY_ENCRYPT:105:EVP_PKEY_encrypt EVP_F_EVP_PKEY_ENCRYPT_INIT:139:EVP_PKEY_encrypt_init @@ -894,53 +914,6 @@ EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl EVP_F_S390X_AES_GCM_TLS_CIPHER:208:s390x_aes_gcm_tls_cipher EVP_F_SCRYPT_ALG:228:scrypt_alg EVP_F_UPDATE:173:update -KDF_F_HKDF_EXTRACT:112:HKDF_Extract -KDF_F_KDF_HKDF_DERIVE:113:kdf_hkdf_derive -KDF_F_KDF_HKDF_NEW:114:kdf_hkdf_new -KDF_F_KDF_HKDF_SIZE:115:kdf_hkdf_size -KDF_F_KDF_MD2CTRL:116:kdf_md2ctrl -KDF_F_KDF_PBKDF2_CTRL:140:kdf_pbkdf2_ctrl -KDF_F_KDF_PBKDF2_CTRL_STR:117:kdf_pbkdf2_ctrl_str -KDF_F_KDF_PBKDF2_DERIVE:118:kdf_pbkdf2_derive -KDF_F_KDF_PBKDF2_NEW:119:kdf_pbkdf2_new -KDF_F_KDF_SCRYPT_CTRL_STR:120:kdf_scrypt_ctrl_str -KDF_F_KDF_SCRYPT_CTRL_UINT32:121:kdf_scrypt_ctrl_uint32 -KDF_F_KDF_SCRYPT_CTRL_UINT64:122:kdf_scrypt_ctrl_uint64 -KDF_F_KDF_SCRYPT_DERIVE:123:kdf_scrypt_derive -KDF_F_KDF_SCRYPT_NEW:124:kdf_scrypt_new -KDF_F_KDF_SSHKDF_CTRL:130:kdf_sshkdf_ctrl -KDF_F_KDF_SSHKDF_CTRL_STR:131:kdf_sshkdf_ctrl_str -KDF_F_KDF_SSHKDF_DERIVE:132:kdf_sshkdf_derive -KDF_F_KDF_SSHKDF_NEW:133:kdf_sshkdf_new -KDF_F_KDF_TLS1_PRF_CTRL_STR:125:kdf_tls1_prf_ctrl_str -KDF_F_KDF_TLS1_PRF_DERIVE:126:kdf_tls1_prf_derive -KDF_F_KDF_TLS1_PRF_NEW:127:kdf_tls1_prf_new -KDF_F_PBKDF2_DERIVE:141:pbkdf2_derive -KDF_F_PBKDF2_SET_MEMBUF:128:pbkdf2_set_membuf -KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str -KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive -KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init -KDF_F_PKEY_SCRYPT_CTRL_STR:104:pkey_scrypt_ctrl_str -KDF_F_PKEY_SCRYPT_CTRL_UINT64:105:pkey_scrypt_ctrl_uint64 -KDF_F_PKEY_SCRYPT_DERIVE:109:pkey_scrypt_derive -KDF_F_PKEY_SCRYPT_INIT:106:pkey_scrypt_init -KDF_F_PKEY_SCRYPT_SET_MEMBUF:107:pkey_scrypt_set_membuf -KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str -KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive -KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init -KDF_F_SCRYPT_SET_MEMBUF:129:scrypt_set_membuf -KDF_F_SSKDF_CTRL_STR:134:sskdf_ctrl_str -KDF_F_SSKDF_DERIVE:135:sskdf_derive -KDF_F_SSKDF_MAC2CTRL:136:sskdf_mac2ctrl -KDF_F_SSKDF_NEW:137:sskdf_new -KDF_F_SSKDF_SIZE:138:sskdf_size -KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg -KDF_F_X942KDF_CTRL:142:x942kdf_ctrl -KDF_F_X942KDF_DERIVE:143:x942kdf_derive -KDF_F_X942KDF_HASH_KDM:144:x942kdf_hash_kdm -KDF_F_X942KDF_NEW:145:x942kdf_new -KDF_F_X942KDF_SIZE:146:x942kdf_size -KDF_F_X963KDF_DERIVE:139:x963kdf_derive OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid OBJ_F_OBJ_CREATE:100:OBJ_create @@ -1128,14 +1101,19 @@ PROV_F_AESNI_INIT_KEY:101:aesni_init_key PROV_F_AES_BLOCK_FINAL:102:aes_block_final PROV_F_AES_BLOCK_UPDATE:103:aes_block_update PROV_F_AES_CIPHER:104:aes_cipher -PROV_F_AES_CTX_GET_PARAMS:105:aes_ctx_get_params -PROV_F_AES_CTX_SET_PARAMS:106:aes_ctx_set_params PROV_F_AES_DINIT:107:aes_dinit PROV_F_AES_DUPCTX:108:aes_dupctx PROV_F_AES_EINIT:109:aes_einit +PROV_F_AES_GET_CTX_PARAMS:105:aes_get_ctx_params PROV_F_AES_INIT_KEY:110:aes_init_key +PROV_F_AES_SET_CTX_PARAMS:106:aes_set_ctx_params PROV_F_AES_STREAM_UPDATE:111:aes_stream_update PROV_F_AES_T4_INIT_KEY:112:aes_t4_init_key +PROV_F_BLAKE2_MAC_INIT:115:blake2_mac_init +PROV_F_BLAKE2_MAC_SET_PARAMS:116:blake2_mac_set_params +PROV_F_GMAC_SET_PARAMS:117:gmac_set_params +PROV_F_KMAC_SET_PARAMS:118:kmac_set_params +PROV_F_POLY1305_SET_PARAMS:119:poly1305_set_params PROV_F_PROV_AES_KEY_GENERIC_INIT:113:PROV_AES_KEY_generic_init PROV_F_TRAILINGDATA:114:trailingdata PROV_F_UNPADBLOCK:100:unpadblock @@ -1164,6 +1142,7 @@ RAND_F_RAND_POOL_ADD_BEGIN:113:rand_pool_add_begin RAND_F_RAND_POOL_ADD_END:114:rand_pool_add_end 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_WRITE_FILE:112:RAND_write_file RSA_F_CHECK_PADDING_MD:140:check_padding_md @@ -2212,9 +2191,20 @@ CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted 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 +CRYPTO_R_INSUFFICIENT_PARAM_SIZE:107:insufficient param size +CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE:108:insufficient secure data space +CRYPTO_R_INVALID_NULL_ARGUMENT:109:invalid null argument +CRYPTO_R_INVALID_OSSL_PARAM_TYPE:110:invalid ossl param type CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error +CRYPTO_R_SECURE_MALLOC_FAILURE:111:secure malloc failure +CRYPTO_R_STRING_TOO_LONG:112:string too long +CRYPTO_R_TOO_MANY_BYTES:113:too many bytes +CRYPTO_R_TOO_MANY_RECORDS:114:too many records +CRYPTO_R_TOO_SMALL_BUFFER:116:too small buffer +CRYPTO_R_ZERO_LENGTH_NUMBER:115:zero length number CT_R_BASE64_DECODE_ERROR:108:base64 decode error CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length CT_R_LOG_CONF_INVALID:109:log conf invalid @@ -2251,6 +2241,7 @@ DH_R_KDF_PARAMETER_ERROR:112:kdf parameter error DH_R_KEYS_NOT_SET:108:keys not set DH_R_MISSING_PUBKEY:125:missing pubkey DH_R_MODULUS_TOO_LARGE:103:modulus too large +DH_R_MODULUS_TOO_SMALL:126:modulus too small DH_R_NOT_SUITABLE_GENERATOR:120:not suitable generator DH_R_NO_PARAMETERS_SET:107:no parameters set DH_R_NO_PRIVATE_VALUE:100:no private value @@ -2265,6 +2256,7 @@ DSA_R_DECODE_ERROR:104:decode error DSA_R_INVALID_DIGEST_TYPE:106:invalid digest type DSA_R_INVALID_PARAMETERS:112:invalid parameters DSA_R_MISSING_PARAMETERS:101:missing parameters +DSA_R_MISSING_PRIVATE_KEY:111:missing private key DSA_R_MODULUS_TOO_LARGE:103:modulus too large DSA_R_NO_PARAMETERS_SET:107:no parameters set DSA_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error @@ -2293,6 +2285,7 @@ EC_R_BUFFER_TOO_SMALL:100:buffer too small EC_R_CANNOT_INVERT:165:cannot invert EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh +EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA:170:curve does not support ecdsa EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing EC_R_D2I_ECPKPARAMETERS_FAILURE:117:d2i ecpkparameters failure EC_R_DECODE_ERROR:142:decode error @@ -2395,6 +2388,8 @@ EVP_R_BAD_DECRYPT:100:bad decrypt EVP_R_BAD_KEY_LENGTH:195:bad key length EVP_R_BUFFER_TOO_SMALL:155:buffer too small EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed +EVP_R_CANNOT_GET_PARAMETERS:197:cannot get parameters +EVP_R_CANNOT_SET_PARAMETERS:198:cannot set parameters EVP_R_CIPHER_NOT_GCM_MODE:184:cipher not gcm mode EVP_R_CIPHER_PARAMETER_ERROR:122:cipher parameter error EVP_R_COMMAND_NOT_SUPPORTED:147:command not supported @@ -2440,6 +2435,8 @@ EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length EVP_R_NO_CIPHER_SET:131:no cipher set EVP_R_NO_DEFAULT_DIGEST:158:no default digest EVP_R_NO_DIGEST_SET:139:no digest set +EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available +EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present EVP_R_NO_KEY_SET:154:no key set EVP_R_NO_OPERATION_SET:149:no operation set EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported @@ -2476,12 +2473,13 @@ EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys KDF_R_BAD_ENCODING:122:bad encoding KDF_R_BAD_LENGTH:123:bad length -KDF_R_INAVLID_UKM_LEN:124:inavlid ukm len +KDF_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int KDF_R_INVALID_DIGEST:100:invalid digest KDF_R_INVALID_ITERATION_COUNT:119:invalid iteration count KDF_R_INVALID_KEY_LEN:120:invalid key len KDF_R_INVALID_MAC_TYPE:116:invalid mac type -KDF_R_INVALID_SALT_LEN:121:invalid salt len +KDF_R_INVALID_MODE:128:invalid mode +KDF_R_INVALID_MODE_INT:129:invalid mode int KDF_R_MISSING_CEK_ALG:125:missing cek alg KDF_R_MISSING_ITERATION_COUNT:109:missing iteration count KDF_R_MISSING_KEY:104:missing key @@ -2662,12 +2660,54 @@ PROP_R_STRING_TOO_LONG:109:string too long PROP_R_TRAILING_CHARACTERS:110:trailing characters 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_BOTH_MODE_AND_MODE_INT:127:both mode and mode int PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +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_INVALID_KEYLEN:105:invalid keylen +PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length +PROV_R_INVALID_AAD:108:invalid aad +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_KEYLEN:117:invalid keylen +PROV_R_INVALID_KEY_LEN:124:invalid key len +PROV_R_INVALID_KEY_LENGTH:105:invalid key length +PROV_R_INVALID_MODE:125:invalid mode +PROV_R_INVALID_MODE_INT:126:invalid mode int +PROV_R_INVALID_SALT_LENGTH:112:invalid salt 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_KEY:128:missing key +PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest +PROV_R_MISSING_PASS:130:missing pass +PROV_R_MISSING_SALT:131:missing salt +PROV_R_MISSING_SECRET:132:missing secret +PROV_R_MISSING_SEED:140:missing seed +PROV_R_MISSING_SESSION_ID:133:missing session id +PROV_R_MISSING_TYPE:134:missing type +PROV_R_MISSING_XCGHASH:135:missing xcghash +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_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 +PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256 +PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg +PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type +PROV_R_VALUE_ERROR:138:value error PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length +PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size +PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE:148:xts data unit is too large +PROV_R_XTS_DUPLICATED_KEYS:149:xts duplicated keys RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long RAND_R_ALREADY_INSTANTIATED:103:already instantiated RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range @@ -2755,6 +2795,7 @@ RSA_R_KEY_PRIME_NUM_INVALID:165:key prime num invalid RSA_R_KEY_SIZE_TOO_SMALL:120:key size too small RSA_R_LAST_OCTET_INVALID:134:last octet invalid RSA_R_MGF1_DIGEST_NOT_ALLOWED:152:mgf1 digest not allowed +RSA_R_MISSING_PRIVATE_KEY:179:missing private key RSA_R_MODULUS_TOO_LARGE:105:modulus too large RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R:168:mp coefficient not inverse of r RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D:169:mp exponent not congruent to d diff --git a/crypto/ess/ess_err.c b/crypto/ess/ess_err.c index 215b7f1e..b494aa24 100644 --- a/crypto/ess/ess_err.c +++ b/crypto/ess/ess_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,22 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ESS_str_functs[] = { - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_CERT_ID_NEW_INIT, 0), - "ESS_CERT_ID_new_init"}, - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_CERT_ID_V2_NEW_INIT, 0), - "ESS_CERT_ID_V2_new_init"}, - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_SIGNING_CERT_ADD, 0), - "ESS_SIGNING_CERT_add"}, - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_SIGNING_CERT_NEW_INIT, 0), - "ESS_SIGNING_CERT_new_init"}, - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_SIGNING_CERT_V2_ADD, 0), - "ESS_SIGNING_CERT_V2_add"}, - {ERR_PACK(ERR_LIB_ESS, ESS_F_ESS_SIGNING_CERT_V2_NEW_INIT, 0), - "ESS_SIGNING_CERT_V2_new_init"}, - {0, NULL} -}; - static const ERR_STRING_DATA ESS_str_reasons[] = { {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR), "ess signing certificate error"}, @@ -44,10 +28,8 @@ static const ERR_STRING_DATA ESS_str_reasons[] = { int ERR_load_ESS_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ESS_str_functs[0].error) == NULL) { - ERR_load_strings_const(ESS_str_functs); + if (ERR_reason_error_string(ESS_str_reasons[0].error) == NULL) ERR_load_strings_const(ESS_str_reasons); - } #endif return 1; } diff --git a/crypto/evp/build.info b/crypto/evp/build.info index fa49f2ef..d9df7195 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -1,5 +1,6 @@ LIBS=../../libcrypto -$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c +$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 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\ @@ -10,12 +11,12 @@ SOURCE[../../libcrypto]=$COMMON\ p_open.c p_seal.c p_sign.c p_verify.c p_lib.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 kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ - pkey_kdf.c c_allkdf.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 m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ - mac_lib.c c_allm.c pkey_mac.c + pkey_mac.c exchange.c SOURCE[../../providers/fips]=$COMMON INCLUDE[e_aes.o]=.. ../modes diff --git a/crypto/evp/c_allkdf.c b/crypto/evp/c_allkdf.c deleted file mode 100644 index 860c11c5..00000000 --- a/crypto/evp/c_allkdf.c +++ /dev/null @@ -1,27 +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 - */ - -#include -#include "internal/evp_int.h" - -void openssl_add_all_kdfs_int(void) -{ - EVP_add_kdf(&pbkdf2_kdf_meth); -#ifndef OPENSSL_NO_SCRYPT - EVP_add_kdf(&scrypt_kdf_meth); -#endif - EVP_add_kdf(&tls1_prf_kdf_meth); - EVP_add_kdf(&hkdf_kdf_meth); - EVP_add_kdf(&sshkdf_kdf_meth); - EVP_add_kdf(&ss_kdf_meth); - EVP_add_kdf(&x963_kdf_meth); -#ifndef OPENSSL_NO_CMS - EVP_add_kdf(&x942_kdf_meth); -#endif -} diff --git a/crypto/evp/c_allm.c b/crypto/evp/c_allm.c deleted file mode 100644 index f5442dfa..00000000 --- a/crypto/evp/c_allm.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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/evp_int.h" - -void openssl_add_all_macs_int(void) -{ -#ifndef OPENSSL_NO_BLAKE2 - EVP_add_mac(&blake2b_mac_meth); - EVP_add_mac(&blake2s_mac_meth); -#endif -#ifndef OPENSSL_NO_CMAC - EVP_add_mac(&cmac_meth); -#endif - EVP_add_mac(&gmac_meth); - EVP_add_mac(&hmac_meth); - EVP_add_mac(&kmac128_meth); - EVP_add_mac(&kmac256_meth); -#ifndef OPENSSL_NO_SIPHASH - EVP_add_mac(&siphash_meth); -#endif -#ifndef OPENSSL_NO_POLY1305 - EVP_add_mac(&poly1305_meth); -#endif -} diff --git a/crypto/evp/cmeth_lib.c b/crypto/evp/cmeth_lib.c index 40aca34e..ba61c525 100644 --- a/crypto/evp/cmeth_lib.c +++ b/crypto/evp/cmeth_lib.c @@ -16,28 +16,29 @@ EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) { - EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); + EVP_CIPHER *cipher = evp_cipher_new(); if (cipher != NULL) { cipher->nid = cipher_type; cipher->block_size = block_size; cipher->key_len = key_len; - cipher->lock = CRYPTO_THREAD_lock_new(); - if (cipher->lock == NULL) { - OPENSSL_free(cipher); - return NULL; - } - cipher->refcnt = 1; } return cipher; } EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) { - EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size, - cipher->key_len); + EVP_CIPHER *to = NULL; - if (to != NULL) { + /* + * Non-legacy EVP_CIPHERs can't be duplicated like this. + * Use EVP_CIPHER_up_ref() instead. + */ + if (cipher->prov != NULL) + return NULL; + + if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size, + cipher->key_len)) != NULL) { CRYPTO_RWLOCK *lock = to->lock; memcpy(to, cipher, sizeof(*to)); @@ -48,40 +49,32 @@ EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) void EVP_CIPHER_meth_free(EVP_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_CIPHER_up_ref(EVP_CIPHER *cipher) -{ - int ref = 0; - - CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); - return 1; + EVP_CIPHER_free(cipher); } int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) { + if (cipher->iv_len != 0) + return 0; + cipher->iv_len = iv_len; return 1; } int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) { + if (cipher->flags != 0) + return 0; + cipher->flags = flags; return 1; } int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) { + if (cipher->ctx_size != 0) + return 0; + cipher->ctx_size = ctx_size; return 1; } @@ -92,6 +85,9 @@ int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, const unsigned char *iv, int enc)) { + if (cipher->init != NULL) + return 0; + cipher->init = init; return 1; } @@ -102,6 +98,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, const unsigned char *in, size_t inl)) { + if (cipher->do_cipher != NULL) + return 0; + cipher->do_cipher = do_cipher; return 1; } @@ -109,6 +108,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, int (*cleanup) (EVP_CIPHER_CTX *)) { + if (cipher->cleanup != NULL) + return 0; + cipher->cleanup = cleanup; return 1; } @@ -117,6 +119,9 @@ int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *)) { + if (cipher->set_asn1_parameters != NULL) + return 0; + cipher->set_asn1_parameters = set_asn1_parameters; return 1; } @@ -125,6 +130,9 @@ int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *)) { + if (cipher->get_asn1_parameters != NULL) + return 0; + cipher->get_asn1_parameters = get_asn1_parameters; return 1; } @@ -133,6 +141,9 @@ int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr)) { + if (cipher->ctrl != NULL) + return 0; + cipher->ctrl = ctrl; return 1; } diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 65b12e31..f39a443c 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -86,7 +86,7 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx) EVP_MD_CTX_reset(ctx); - EVP_MD_meth_free(ctx->fetched_digest); + EVP_MD_free(ctx->fetched_digest); ctx->fetched_digest = NULL; ctx->digest = NULL; ctx->reqdigest = NULL; @@ -156,7 +156,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) { if (ctx->digest == ctx->fetched_digest) ctx->digest = NULL; - EVP_MD_meth_free(ctx->fetched_digest); + EVP_MD_free(ctx->fetched_digest); ctx->fetched_digest = NULL; goto legacy; } @@ -181,7 +181,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) return 0; } type = provmd; - EVP_MD_meth_free(ctx->fetched_digest); + EVP_MD_free(ctx->fetched_digest); ctx->fetched_digest = provmd; #endif } @@ -266,8 +266,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) skip_to_init: #endif #ifndef FIPS_MODE - /* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */ - if (ctx->pctx != NULL) { + /* + * TODO(3.0): Temporarily no support for EVP_DigestSign* inside FIPS module + * or when using providers. + */ + if (ctx->pctx != NULL + && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + || ctx->pctx->op.sig.signature == NULL)) { int r; r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); @@ -415,7 +420,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) EVP_MD_CTX_reset(out); if (out->fetched_digest != NULL) - EVP_MD_meth_free(out->fetched_digest); + EVP_MD_free(out->fetched_digest); *out = *in; /* NULL out pointers in case of error */ out->pctx = NULL; @@ -524,68 +529,139 @@ int EVP_Digest(const void *data, size_t count, return ret; } +int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]) +{ + if (digest != NULL && digest->get_params != NULL) + return digest->get_params(params); + return 0; +} + +const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest) +{ + if (digest != NULL && digest->gettable_params != NULL) + return digest->gettable_params(); + return NULL; +} + int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]) { - if (ctx->digest != NULL && ctx->digest->set_params != NULL) - return ctx->digest->set_params(ctx->provctx, params); + if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL) + return ctx->digest->set_ctx_params(ctx->provctx, params); return 0; } +const OSSL_PARAM *EVP_MD_CTX_settable_params(const EVP_MD *digest) +{ + if (digest != NULL && digest->settable_ctx_params != NULL) + return digest->settable_ctx_params(); + return NULL; +} + int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]) { if (ctx->digest != NULL && ctx->digest->get_params != NULL) - return ctx->digest->get_params(ctx->provctx, params); + return ctx->digest->get_ctx_params(ctx->provctx, params); return 0; } +const OSSL_PARAM *EVP_MD_CTX_gettable_params(const EVP_MD *digest) +{ + if (digest != NULL && digest->gettable_ctx_params != NULL) + return digest->gettable_ctx_params(); + return NULL; +} + /* TODO(3.0): Remove legacy code below - only used by engines & DigestSign */ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) { - if (ctx->digest != NULL) { - if (ctx->digest->prov != NULL) { - OSSL_PARAM params[2]; - size_t i, n = 0; + int ret = EVP_CTRL_RET_UNSUPPORTED; + int set_params = 1; + size_t sz; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - switch (cmd) { - case EVP_MD_CTRL_XOF_LEN: - if (ctx->digest->set_params == NULL) - break; - i = (size_t)p1; - params[n++] = - OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &i); - params[n++] = OSSL_PARAM_construct_end(); - return ctx->digest->set_params(ctx->provctx, params); - case EVP_MD_CTRL_MICALG: - if (ctx->digest->get_params == NULL) - break; - params[n++] = - OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG, - p2, p1 ? p1 : 9999); - params[n++] = OSSL_PARAM_construct_end(); - return ctx->digest->get_params(ctx->provctx, params); - } - return 0; - } - /* legacy code */ - if (ctx->digest->md_ctrl != NULL) { - int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2); - if (ret <= 0) - return 0; - return 1; - } + if (ctx == NULL || ctx->digest == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL); + return 0; } - return 0; + + if (ctx->digest->prov == NULL) + goto legacy; + + switch (cmd) { + case EVP_MD_CTRL_XOF_LEN: + sz = (size_t)p1; + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz); + break; + case EVP_MD_CTRL_MICALG: + set_params = 0; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG, + p2, p1 ? p1 : 9999); + break; + default: + return EVP_CTRL_RET_UNSUPPORTED; + } + + if (set_params) + ret = evp_do_md_ctx_setparams(ctx->digest, ctx->provctx, params); + else + ret = evp_do_md_ctx_getparams(ctx->digest, ctx->provctx, params); + return ret; + + +/* TODO(3.0): Remove legacy code below */ + legacy: + if (ctx->digest->md_ctrl == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2); + if (ret <= 0) + return 0; + return ret; } -static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov) +EVP_MD *evp_md_new(void) +{ + EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); + + if (md != NULL) { + md->lock = CRYPTO_THREAD_lock_new(); + if (md->lock == NULL) { + OPENSSL_free(md); + return NULL; + } + md->refcnt = 1; + } + return md; +} + +static void *evp_md_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, void *unused) { EVP_MD *md = NULL; int fncnt = 0; /* EVP_MD_fetch() will set the legacy NID if available */ - if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL) + if ((md = evp_md_new()) == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } + md->name_id = name_id; + +#ifndef FIPS_MODE + { + /* + * FIPS module note: since internal fetches will be entirely + * provider based, we know that none of its code depends on legacy + * NIDs or any functionality that use them. + * + * TODO(3.x) get rid of the need for legacy NIDs + */ + md->type = OBJ_sn2nid(evp_first_name(prov, name_id)); + } +#endif for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -628,34 +704,44 @@ static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns, if (md->dupctx == NULL) md->dupctx = OSSL_get_OP_digest_dupctx(fns); break; - case OSSL_FUNC_DIGEST_SIZE: - if (md->size == NULL) - md->size = OSSL_get_OP_digest_size(fns); - break; - case OSSL_FUNC_DIGEST_BLOCK_SIZE: - if (md->dblock_size == NULL) - md->dblock_size = OSSL_get_OP_digest_block_size(fns); - break; - case OSSL_FUNC_DIGEST_SET_PARAMS: - if (md->set_params == NULL) - md->set_params = OSSL_get_OP_digest_set_params(fns); - break; case OSSL_FUNC_DIGEST_GET_PARAMS: if (md->get_params == NULL) md->get_params = OSSL_get_OP_digest_get_params(fns); break; + case OSSL_FUNC_DIGEST_SET_CTX_PARAMS: + if (md->set_ctx_params == NULL) + md->set_ctx_params = OSSL_get_OP_digest_set_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GET_CTX_PARAMS: + if (md->get_ctx_params == NULL) + md->get_ctx_params = OSSL_get_OP_digest_get_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GETTABLE_PARAMS: + if (md->gettable_params == NULL) + md->gettable_params = OSSL_get_OP_digest_gettable_params(fns); + break; + case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS: + if (md->settable_ctx_params == NULL) + md->settable_ctx_params = + OSSL_get_OP_digest_settable_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS: + if (md->gettable_ctx_params == NULL) + md->gettable_ctx_params = + OSSL_get_OP_digest_gettable_ctx_params(fns); + break; } } if ((fncnt != 0 && fncnt != 5) - || (fncnt == 0 && md->digest == NULL) - || md->size == NULL) { + || (fncnt == 0 && md->digest == NULL)) { /* * In order to be a consistent set of functions we either need the * whole set of init/update/final etc functions or none of them. * The "digest" function can standalone. We at least need one way to * generate digests. */ - EVP_MD_meth_free(md); + EVP_MD_free(md); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); return NULL; } md->prov = prov; @@ -672,7 +758,7 @@ static int evp_md_up_ref(void *md) static void evp_md_free(void *md) { - EVP_MD_meth_free(md); + EVP_MD_free(md); } EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, @@ -680,20 +766,40 @@ 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, evp_md_up_ref, + evp_md_from_dispatch, NULL, evp_md_up_ref, evp_md_free); -#ifndef FIPS_MODE - /* TODO(3.x) get rid of the need for legacy NIDs */ - if (md != NULL) { - /* - * FIPS module note: since internal fetches will be entirely - * provider based, we know that none of its code depends on legacy - * NIDs or any functionality that use them. - */ - md->type = OBJ_sn2nid(algorithm); - } -#endif - return md; } + +int EVP_MD_up_ref(EVP_MD *md) +{ + int ref = 0; + + CRYPTO_UP_REF(&md->refcnt, &ref, md->lock); + return 1; +} + +void EVP_MD_free(EVP_MD *md) +{ + int i; + + if (md == NULL) + return; + + CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock); + if (i > 0) + return; + ossl_provider_free(md->prov); + CRYPTO_THREAD_lock_free(md->lock); + OPENSSL_free(md); +} + +void EVP_MD_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_MD *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_DIGEST, + (void (*)(void *, void *))fn, arg, + evp_md_from_dispatch, NULL, evp_md_free); +} diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 6f58e270..39ed5280 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -19,7 +19,8 @@ #include "internal/evp_int.h" #include "internal/cryptlib.h" #include "internal/modes_int.h" -#include "modes_lcl.h" +#include "internal/siv_int.h" +#include "internal/ciphermode_platform.h" #include "evp_locl.h" typedef struct { @@ -111,50 +112,6 @@ typedef struct { #define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) -#ifdef VPAES_ASM -int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void vpaes_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void vpaes_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void vpaes_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); -#endif -#ifdef BSAES_ASM -void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char ivec[16], int enc); -void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -#endif -#ifdef AES_CTR_ASM -void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - const unsigned char ivec[AES_BLOCK_SIZE]); -#endif -#ifdef AES_XTS_ASM -void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -#endif - /* increment counter (64-bit int) by 1 */ static void ctr64_inc(unsigned char *counter) { @@ -171,105 +128,10 @@ static void ctr64_inc(unsigned char *counter) } while (n); } -#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) -# include "ppc_arch.h" -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) -# endif -# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) -# define HWAES_set_encrypt_key aes_p8_set_encrypt_key -# define HWAES_set_decrypt_key aes_p8_set_decrypt_key -# define HWAES_encrypt aes_p8_encrypt -# define HWAES_decrypt aes_p8_decrypt -# define HWAES_cbc_encrypt aes_p8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks -# define HWAES_xts_encrypt aes_p8_xts_encrypt -# define HWAES_xts_decrypt aes_p8_xts_decrypt -#endif - -#if defined(AES_ASM) && !defined(I386_ONLY) && ( \ - ((defined(__i386) || defined(__i386__) || \ - defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) ) - -extern unsigned int OPENSSL_ia32cap_P[]; - -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -# ifdef BSAES_ASM -# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -/* - * AES-NI section - */ -# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) - -int aesni_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int aesni_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void aesni_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aesni_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void aesni_ecb_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, const AES_KEY *key, int enc); -void aesni_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); - -void aesni_ctr32_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, const unsigned char *ivec); - -void aesni_xts_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_xts_decrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_ccm64_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - -void aesni_ccm64_decrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - +#if defined(AESNI_CAPABLE) # if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -size_t aesni_gcm_encrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); # define AES_gcm_encrypt aesni_gcm_encrypt -size_t aesni_gcm_decrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); # define AES_gcm_decrypt aesni_gcm_decrypt -void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, - size_t len); -# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \ - gctx->gcm.ghash==gcm_ghash_avx) # 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 */ @@ -405,7 +267,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, /* * Verify that the two keys are different. - * + * * This addresses Rogaway's vulnerability. * See comment in aes_xts_init_key() below. */ @@ -471,19 +333,6 @@ static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); # ifndef OPENSSL_NO_OCB -void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); - static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { @@ -584,81 +433,7 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ { return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } -#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) - -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -/* - * Initial Fujitsu SPARC64 X support - */ -# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX) -# define HWAES_set_encrypt_key aes_fx_set_encrypt_key -# define HWAES_set_decrypt_key aes_fx_set_decrypt_key -# define HWAES_encrypt aes_fx_encrypt -# define HWAES_decrypt aes_fx_decrypt -# define HWAES_cbc_encrypt aes_fx_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks - -# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) - -void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aes_t4_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -/* - * Key-length specific subroutines were chosen for following reason. - * Each SPARC T4 core can execute up to 8 threads which share core's - * resources. Loading as much key material to registers allows to - * minimize references to shared memory interface, as well as amount - * of instructions in inner loops [much needed on T4]. But then having - * non-key-length specific routines would require conditional branches - * either in inner loops or on subroutines' entries. Former is hardly - * acceptable, while latter means code size increase to size occupied - * by multiple key-length specific subroutines, so why fight? - */ -void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); +#elif defined(SPARC_AES_CAPABLE) static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -824,7 +599,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, /* * Verify that the two keys are different. - * + * * This addresses Rogaway's vulnerability. * See comment in aes_xts_init_key() below. */ @@ -1012,12 +787,8 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ { return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } -#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__) -/* - * IBM S390X support - */ -# include "s390x_arch.h" - +#elif defined(S390X_aes_128_CAPABLE) +/* IBM S390X support */ typedef struct { union { OSSL_UNION_ALIGN; @@ -1170,25 +941,11 @@ typedef struct { } aes; } S390X_AES_CCM_CTX; -/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ -# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6)) - -/* Most modes of operation need km for partial block processing. */ -# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_128)) -# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_192)) -# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_256)) - # define s390x_aes_init_key aes_init_key static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); -# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */ -# define S390X_aes_192_cbc_CAPABLE 1 -# define S390X_aes_256_cbc_CAPABLE 1 -# define S390X_AES_CBC_CTX EVP_AES_KEY +# define S390X_AES_CBC_CTX EVP_AES_KEY # define s390x_aes_cbc_init_key aes_init_key @@ -1196,10 +953,6 @@ static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int s390x_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE -# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE -# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE - static int s390x_aes_ecb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -1224,16 +977,6 @@ static int s390x_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_256))) - static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) @@ -1289,16 +1032,6 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_256))) - static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) @@ -1365,13 +1098,6 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_128)) -# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_192)) -# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_256)) - static int s390x_aes_cfb8_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) @@ -1400,20 +1126,13 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb1_CAPABLE 0 -# define S390X_aes_192_cfb1_CAPABLE 0 -# define S390X_aes_256_cfb1_CAPABLE 0 - # define s390x_aes_cfb1_init_key aes_init_key # define s390x_aes_cfb1_cipher aes_cfb1_cipher static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */ -# define S390X_aes_192_ctr_CAPABLE 1 -# define S390X_aes_256_ctr_CAPABLE 1 -# define S390X_AES_CTR_CTX EVP_AES_KEY +# define S390X_AES_CTR_CTX EVP_AES_KEY # define s390x_aes_ctr_init_key aes_init_key @@ -1421,18 +1140,8 @@ static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_gcm_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_gcm_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_gcm_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_256))) - /* iv + padding length for iv lengths != 12 */ -# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16) +# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16) /*- * Process additional authenticated data. Returns 0 on success. Code is @@ -1625,7 +1334,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) switch (type) { case EVP_CTRL_INIT: - ivlen = EVP_CIPHER_CTX_iv_length(c); + ivlen = EVP_CIPHER_iv_length(c->cipher); iv = EVP_CIPHER_CTX_iv_noconst(c); gctx->key_set = 0; gctx->iv_set = 0; @@ -1636,6 +1345,10 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = gctx->ivlen; + return 1; + case EVP_CTRL_AEAD_SET_IVLEN: if (arg <= 0) return 0; @@ -1953,9 +1666,7 @@ static int s390x_aes_gcm_cleanup(EVP_CIPHER_CTX *c) return 1; } -# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX -# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */ -# define S390X_aes_256_xts_CAPABLE 1 +# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX # define s390x_aes_xts_init_key aes_xts_init_key static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx, @@ -1968,18 +1679,6 @@ static int s390x_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_xts_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); # define s390x_aes_xts_cleanup aes_xts_cleanup -# define S390X_aes_128_ccm_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_ccm_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_ccm_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_256))) - -# define S390X_CCM_AAD_FLAG 0x40 - /*- * Set nonce and length fields. Code is big-endian. */ @@ -2092,13 +1791,13 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in, ctx->aes.ccm.nonce.b[15] = 1; if (n != len) - return -1; /* length mismatch */ + return -1; /* length mismatch */ if (enc) { /* Two operations per block plus one for tag encryption */ ctx->aes.ccm.blocks += (((len + 15) >> 4) << 1) + 1; if (ctx->aes.ccm.blocks > (1ULL << 61)) - return -2; /* too much data */ + return -2; /* too much data */ } num = 0; @@ -2147,7 +1846,7 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in, ctx->aes.ccm.kmac_param.icv.g[0] ^= ctx->aes.ccm.buf.g[0]; ctx->aes.ccm.kmac_param.icv.g[1] ^= ctx->aes.ccm.buf.g[1]; - ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */ + ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */ return 0; } @@ -2358,6 +2057,10 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->aes.ccm.tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = 15 - cctx->aes.ccm.l; + return 1; + case EVP_CTRL_AEAD_TLS1_AAD: if (arg != EVP_AEAD_TLS1_AAD_LEN) return 0; @@ -2451,10 +2154,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) # define s390x_aes_ccm_cleanup aes_ccm_cleanup # ifndef OPENSSL_NO_OCB -# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX -# define S390X_aes_128_ocb_CAPABLE 0 -# define S390X_aes_192_ocb_CAPABLE 0 -# define S390X_aes_256_ocb_CAPABLE 0 +# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX # define s390x_aes_ocb_init_key aes_ocb_init_key static int s390x_aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -2470,9 +2170,6 @@ static int s390x_aes_ocb_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); # ifndef OPENSSL_NO_SIV # define S390X_AES_SIV_CTX EVP_AES_SIV_CTX -# define S390X_aes_128_siv_CAPABLE 0 -# define S390X_aes_192_siv_CAPABLE 0 -# define S390X_aes_256_siv_CAPABLE 0 # define s390x_aes_siv_init_key aes_siv_init_key # define s390x_aes_siv_cipher aes_siv_cipher @@ -2480,77 +2177,77 @@ static int s390x_aes_ocb_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); # define s390x_aes_siv_ctrl aes_siv_ctrl # endif -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \ - MODE,flags) \ -static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize, \ - keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - s390x_aes_##mode##_init_key, \ - s390x_aes_##mode##_cipher, \ - NULL, \ - sizeof(S390X_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode, \ - blocksize, \ - keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - aes_init_key, \ - aes_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ \ - return S390X_aes_##keylen##_##mode##_CAPABLE ? \ - &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \ + MODE,flags) \ +static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + NULL, \ + sizeof(S390X_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +}; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode, \ + blocksize, \ + keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +}; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ \ + return S390X_aes_##keylen##_##mode##_CAPABLE ? \ + &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ } # define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags)\ -static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode, \ - blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - s390x_aes_##mode##_init_key, \ - s390x_aes_##mode##_cipher, \ - s390x_aes_##mode##_cleanup, \ - sizeof(S390X_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - s390x_aes_##mode##_ctrl, \ - NULL \ -}; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - aes_##mode##_init_key, \ - aes_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - aes_##mode##_ctrl, \ - NULL \ -}; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ \ - return S390X_aes_##keylen##_##mode##_CAPABLE ? \ - &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ +static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode, \ + blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + s390x_aes_##mode##_cleanup, \ + sizeof(S390X_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + s390x_aes_##mode##_ctrl, \ + NULL \ +}; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + aes_##mode##_ctrl, \ + NULL \ +}; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ \ + return S390X_aes_##keylen##_##mode##_CAPABLE ? \ + &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ } #else @@ -2583,48 +2280,6 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ #endif -#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) -# include "arm_arch.h" -# if __ARM_MAX_ARCH__>=7 -# if defined(BSAES_ASM) -# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -# if defined(VPAES_ASM) -# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) -# define HWAES_set_encrypt_key aes_v8_set_encrypt_key -# define HWAES_set_decrypt_key aes_v8_set_decrypt_key -# define HWAES_encrypt aes_v8_encrypt -# define HWAES_decrypt aes_v8_decrypt -# define HWAES_cbc_encrypt aes_v8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks -# endif -#endif - -#if defined(HWAES_CAPABLE) -int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -void HWAES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc); -void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -#endif - #define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ @@ -2889,13 +2544,17 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_INIT: gctx->key_set = 0; gctx->iv_set = 0; - gctx->ivlen = c->cipher->iv_len; + gctx->ivlen = EVP_CIPHER_iv_length(c->cipher); gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = gctx->ivlen; + return 1; + case EVP_CTRL_AEAD_SET_IVLEN: if (arg <= 0) return 0; @@ -3408,7 +3067,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, #define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY) + | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH) BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) @@ -3613,6 +3272,10 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = 15 - cctx->L; + return 1; + case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != EVP_AEAD_TLS1_AAD_LEN) @@ -4061,13 +3724,17 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_INIT: octx->key_set = 0; octx->iv_set = 0; - octx->ivlen = EVP_CIPHER_CTX_iv_length(c); + octx->ivlen = EVP_CIPHER_iv_length(c->cipher); octx->iv = EVP_CIPHER_CTX_iv_noconst(c); octx->taglen = 16; octx->data_buf_len = 0; octx->aad_buf_len = 0; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = octx->ivlen; + return 1; + case EVP_CTRL_AEAD_SET_IVLEN: /* IV len must be 1 to 15 */ if (arg <= 0 || arg > 15) @@ -4110,29 +3777,6 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) } } -# ifdef HWAES_CAPABLE -# ifdef HWAES_ocb_encrypt -void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -# else -# define HWAES_ocb_encrypt ((ocb128_f)NULL) -# endif -# ifdef HWAES_ocb_decrypt -void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -# else -# define HWAES_ocb_decrypt ((ocb128_f)NULL) -# endif -# endif - static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c index f6450f39..9e393f0b 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -7,17 +7,16 @@ * https://www.openssl.org/source/license.html */ -#include - #include #include - +#include #include #include #include #include #include -#include "modes_lcl.h" +#include "internal/cryptlib.h" +#include "internal/modes_int.h" #include "internal/evp_int.h" #include "internal/constant_time_locl.h" @@ -37,7 +36,6 @@ typedef struct { defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) -extern unsigned int OPENSSL_ia32cap_P[]; # define AESNI_CAPABLE (1<<(57-32)) int aesni_set_encrypt_key(const unsigned char *userKey, int bits, diff --git a/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/evp/e_aes_cbc_hmac_sha256.c index cd51e93c..e434ec00 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -7,18 +7,16 @@ * https://www.openssl.org/source/license.html */ -#include - #include #include - - +#include #include #include #include #include #include -#include "modes_lcl.h" +#include "internal/cryptlib.h" +#include "internal/modes_int.h" #include "internal/constant_time_locl.h" #include "internal/evp_int.h" @@ -38,7 +36,6 @@ typedef struct { defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) -extern unsigned int OPENSSL_ia32cap_P[]; # define AESNI_CAPABLE (1<<(57-32)) int aesni_set_encrypt_key(const unsigned char *userKey, int bits, diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index 5404dd48..84b14826 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -16,7 +16,7 @@ # include # include "internal/aria.h" # include "internal/evp_int.h" -# include "modes_lcl.h" +# include "internal/modes_int.h" # include "evp_locl.h" /* ARIA subkey Structure */ @@ -252,13 +252,17 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_INIT: gctx->key_set = 0; gctx->iv_set = 0; - gctx->ivlen = EVP_CIPHER_CTX_iv_length(c); + gctx->ivlen = EVP_CIPHER_iv_length(c->cipher); gctx->iv = EVP_CIPHER_CTX_iv_noconst(c); gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = gctx->ivlen; + return 1; + case EVP_CTRL_AEAD_SET_IVLEN: if (arg <= 0) return 0; @@ -539,6 +543,10 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = 15 - cctx->L; + return 1; + case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != EVP_AEAD_TLS1_AAD_LEN) @@ -742,7 +750,8 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, #define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER) + | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \ + | EVP_CIPH_CUSTOM_IV_LENGTH) #define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ static const EVP_CIPHER aria_##keylen##_##mode = { \ diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c index e018ba48..5e661014 100644 --- a/crypto/evp/e_camellia.c +++ b/crypto/evp/e_camellia.c @@ -18,7 +18,8 @@ NON_EMPTY_TRANSLATION_UNIT # include # include # include "internal/evp_int.h" -# include "modes_lcl.h" +# include "internal/modes_int.h" +# include "internal/ciphermode_platform.h" static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -43,34 +44,6 @@ typedef struct { * assembler support was in general requested... */ # include "sparc_arch.h" -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) - -void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); -void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); -void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); - -void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c index 08317939..46eb3391 100644 --- a/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/evp/e_chacha20_poly1305.c @@ -575,6 +575,10 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, } return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = actx->nonce_len; + return 1; + case EVP_CTRL_AEAD_SET_IVLEN: if (actx->draft) return -1; if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN) @@ -656,7 +660,8 @@ static EVP_CIPHER chacha20_poly1305 = { 12, /* iv_len, 96-bit nonce in the context */ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | - EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER, + EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER | + EVP_CIPH_CUSTOM_IV_LENGTH, chacha20_poly1305_init_key, chacha20_poly1305_cipher, chacha20_poly1305_cleanup, diff --git a/crypto/evp/e_rc4_hmac_md5.c b/crypto/evp/e_rc4_hmac_md5.c index 7ff08cb5..4d61faff 100644 --- a/crypto/evp/e_rc4_hmac_md5.c +++ b/crypto/evp/e_rc4_hmac_md5.c @@ -51,7 +51,7 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, return 1; } -# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ +# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) # define STITCHED_CALL @@ -71,7 +71,6 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * rc4_md5-x86_64.pl */ md5_off = MD5_CBLOCK - key->md.num, blocks; unsigned int l; - extern unsigned int OPENSSL_ia32cap_P[]; # endif size_t plen = key->payload_length; diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 3b83d117..ce113611 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_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 @@ -35,7 +35,7 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) ctx->provctx = NULL; } if (ctx->fetched_cipher != NULL) - EVP_CIPHER_meth_free(ctx->fetched_cipher); + EVP_CIPHER_free(ctx->fetched_cipher); memset(ctx, 0, sizeof(*ctx)); return 1; @@ -133,7 +133,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, || impl != NULL) { if (ctx->cipher == ctx->fetched_cipher) ctx->cipher = NULL; - EVP_CIPHER_meth_free(ctx->fetched_cipher); + EVP_CIPHER_free(ctx->fetched_cipher); ctx->fetched_cipher = NULL; goto legacy; } @@ -163,6 +163,104 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, case NID_aes_256_ctr: case NID_aes_192_ctr: case NID_aes_128_ctr: + case NID_aes_128_xts: + case NID_aes_256_xts: + case NID_aes_256_ocb: + case NID_aes_192_ocb: + case NID_aes_128_ocb: + case NID_aes_256_gcm: + case NID_aes_192_gcm: + case NID_aes_128_gcm: + case NID_id_aes256_wrap: + case NID_id_aes256_wrap_pad: + case NID_id_aes192_wrap: + case NID_id_aes192_wrap_pad: + case NID_id_aes128_wrap: + case NID_id_aes128_wrap_pad: + case NID_aria_256_gcm: + case NID_aria_192_gcm: + case NID_aria_128_gcm: + case NID_aes_256_ccm: + case NID_aes_192_ccm: + case NID_aes_128_ccm: + case NID_aria_256_ccm: + case NID_aria_192_ccm: + case NID_aria_128_ccm: + case NID_aria_256_ecb: + case NID_aria_192_ecb: + case NID_aria_128_ecb: + case NID_aria_256_cbc: + case NID_aria_192_cbc: + case NID_aria_128_cbc: + case NID_aria_256_ofb128: + case NID_aria_192_ofb128: + case NID_aria_128_ofb128: + case NID_aria_256_cfb128: + case NID_aria_192_cfb128: + case NID_aria_128_cfb128: + case NID_aria_256_cfb1: + case NID_aria_192_cfb1: + case NID_aria_128_cfb1: + case NID_aria_256_cfb8: + case NID_aria_192_cfb8: + case NID_aria_128_cfb8: + case NID_aria_256_ctr: + case NID_aria_192_ctr: + case NID_aria_128_ctr: + case NID_camellia_256_ecb: + case NID_camellia_192_ecb: + case NID_camellia_128_ecb: + case NID_camellia_256_cbc: + case NID_camellia_192_cbc: + case NID_camellia_128_cbc: + case NID_camellia_256_ofb128: + case NID_camellia_192_ofb128: + case NID_camellia_128_ofb128: + case NID_camellia_256_cfb128: + case NID_camellia_192_cfb128: + case NID_camellia_128_cfb128: + case NID_camellia_256_cfb1: + case NID_camellia_192_cfb1: + case NID_camellia_128_cfb1: + case NID_camellia_256_cfb8: + case NID_camellia_192_cfb8: + case NID_camellia_128_cfb8: + case NID_camellia_256_ctr: + case NID_camellia_192_ctr: + case NID_camellia_128_ctr: + case NID_des_ede3_cbc: + case NID_des_ede3_ecb: + case NID_des_ede3_ofb64: + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + case NID_des_ede_cbc: + case NID_des_ede_ecb: + case NID_des_ede_ofb64: + case NID_des_ede_cfb64: + case NID_desx_cbc: + case NID_id_smime_alg_CMS3DESwrap: + case NID_bf_cbc: + case NID_bf_ecb: + case NID_bf_cfb64: + case NID_bf_ofb64: + case NID_idea_cbc: + case NID_idea_ecb: + case NID_idea_cfb64: + case NID_idea_ofb64: + case NID_cast5_cbc: + case NID_cast5_ecb: + case NID_cast5_cfb64: + case NID_cast5_ofb64: + case NID_seed_cbc: + case NID_seed_ecb: + case NID_seed_cfb128: + case NID_seed_ofb128: + case NID_sm4_cbc: + case NID_sm4_ecb: + case NID_sm4_ctr: + case NID_sm4_cfb128: + case NID_sm4_ofb128: break; default: goto legacy; @@ -191,9 +289,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->flags = flags; } - if (cipher != NULL) - ctx->cipher = cipher; - else + if (cipher == NULL) cipher = ctx->cipher; if (cipher->prov == NULL) { @@ -210,7 +306,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return 0; } cipher = provciph; - EVP_CIPHER_meth_free(ctx->fetched_cipher); + EVP_CIPHER_free(ctx->fetched_cipher); ctx->fetched_cipher = provciph; #endif } @@ -920,11 +1016,14 @@ 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 = evp_do_param(c->cipher, &keylen, sizeof(keylen), - OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_setparams, c->provctx); + int ok; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t len = keylen; - if (ok != -2) + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len); + ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params); + + if (ok != EVP_CTRL_RET_UNSUPPORTED) return ok; /* TODO(3.0) legacy code follows */ @@ -943,23 +1042,28 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) { int ok; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned int pd = pad; if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; else ctx->flags |= EVP_CIPH_NO_PADDING; - ok = evp_do_param(ctx->cipher, &pad, sizeof(pad), - OSSL_CIPHER_PARAM_PADDING, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_setparams, ctx->provctx); + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pd); + ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + return ok != 0; } int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { - int ret = -2; /* Unsupported */ + int ret = EVP_CTRL_RET_UNSUPPORTED; + int set_params = 1; + size_t sz = arg; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - if (!ctx->cipher) { + if (ctx == NULL || ctx->cipher == NULL) { EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); return 0; } @@ -969,31 +1073,71 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) switch (type) { case EVP_CTRL_SET_KEY_LENGTH: - ret = evp_do_param(ctx->cipher, &arg, sizeof(arg), - OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_setparams, ctx->provctx); - break; - case EVP_CTRL_GET_IV: - ret = evp_do_param(ctx->cipher, ptr, arg, - OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_STRING, - evp_do_ciph_ctx_getparams, ctx->provctx); + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &sz); break; case EVP_CTRL_RAND_KEY: /* Used by DES */ + set_params = 0; + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, + ptr, sz); + break; + case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */ case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */ - ret = -2; /* Unsupported */ + default: + return EVP_CTRL_RET_UNSUPPORTED; + case EVP_CTRL_GET_IV: + set_params = 0; + params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV, + ptr, sz); break; + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg < 0) + 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); + 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_TLS1_AAD: + /* This one does a set and a get - since it returns a padding size */ + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, + ptr, sz); + 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_AEAD_TLS1_AAD_PAD, &sz); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + if (ret <= 0) + return 0; + return sz; } + + if (set_params) + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + else + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); return ret; - legacy: - if (!ctx->cipher->ctrl) { +/* TODO(3.0): Remove legacy code below */ +legacy: + if (ctx->cipher->ctrl == NULL) { EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); return 0; } ret = ctx->cipher->ctrl(ctx, type, arg, ptr); - if (ret == -1) { + if (ret == EVP_CTRL_RET_UNSUPPORTED) { EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); return 0; @@ -1001,19 +1145,66 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) return ret; } -#if !defined(FIPS_MODE) -/* TODO(3.0): No support for RAND yet in the FIPS module */ +int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[]) +{ + if (cipher != NULL && cipher->get_params != NULL) + return cipher->get_params(params); + return 0; +} + +int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->cipher != NULL && ctx->cipher->set_ctx_params != NULL) + return ctx->cipher->set_ctx_params(ctx->provctx, params); + return 0; +} + +int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->cipher != NULL && ctx->cipher->get_ctx_params != NULL) + return ctx->cipher->get_ctx_params(ctx->provctx, params); + return 0; +} + +const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher) +{ + if (cipher != NULL && cipher->gettable_params != NULL) + return cipher->gettable_params(); + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(const EVP_CIPHER *cipher) +{ + if (cipher != NULL && cipher->settable_ctx_params != NULL) + return cipher->settable_ctx_params(); + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(const EVP_CIPHER *cipher) +{ + if (cipher != NULL && cipher->gettable_ctx_params != NULL) + return cipher->gettable_ctx_params(); + return NULL; +} + int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { - int kl; if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); - kl = EVP_CIPHER_CTX_key_length(ctx); - if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0) - return 0; - return 1; + +#ifdef FIPS_MODE + return 0; +#else + { + int kl; + + kl = EVP_CIPHER_CTX_key_length(ctx); + if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0) + return 0; + return 1; + } +#endif /* FIPS_MODE */ } -#endif int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { @@ -1081,18 +1272,47 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) return 1; } -static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov) +EVP_CIPHER *evp_cipher_new(void) +{ + EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); + + if (cipher != NULL) { + cipher->lock = CRYPTO_THREAD_lock_new(); + if (cipher->lock == NULL) { + OPENSSL_free(cipher); + return NULL; + } + cipher->refcnt = 1; + } + return cipher; +} + +static void *evp_cipher_from_dispatch(const int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *unused) { EVP_CIPHER *cipher = NULL; int fnciphcnt = 0, fnctxcnt = 0; - /* - * The legacy NID is set by EVP_CIPHER_fetch() if the name exists in - * the object database. - */ - if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL) + if ((cipher = evp_cipher_new()) == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } + cipher->name_id = name_id; + +#ifndef FIPS_MODE + { + /* + * FIPS module note: since internal fetches will be entirely + * provider based, we know that none of its code depends on legacy + * NIDs or any functionality that use them. + * + * TODO(3.x) get rid of the need for legacy NIDs + */ + cipher->nid = OBJ_sn2nid(evp_first_name(prov, name_id)); + } +#endif for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -1147,15 +1367,32 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns, break; cipher->get_params = OSSL_get_OP_cipher_get_params(fns); break; - case OSSL_FUNC_CIPHER_CTX_GET_PARAMS: - if (cipher->ctx_get_params != NULL) + case OSSL_FUNC_CIPHER_GET_CTX_PARAMS: + if (cipher->get_ctx_params != NULL) break; - cipher->ctx_get_params = OSSL_get_OP_cipher_ctx_get_params(fns); + cipher->get_ctx_params = OSSL_get_OP_cipher_get_ctx_params(fns); break; - case OSSL_FUNC_CIPHER_CTX_SET_PARAMS: - if (cipher->ctx_set_params != NULL) + case OSSL_FUNC_CIPHER_SET_CTX_PARAMS: + if (cipher->set_ctx_params != NULL) break; - cipher->ctx_set_params = OSSL_get_OP_cipher_ctx_set_params(fns); + cipher->set_ctx_params = OSSL_get_OP_cipher_set_ctx_params(fns); + break; + case OSSL_FUNC_CIPHER_GETTABLE_PARAMS: + if (cipher->gettable_params != NULL) + break; + cipher->gettable_params = OSSL_get_OP_cipher_gettable_params(fns); + break; + case OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS: + if (cipher->gettable_ctx_params != NULL) + break; + cipher->gettable_ctx_params = + OSSL_get_OP_cipher_gettable_ctx_params(fns); + break; + case OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS: + if (cipher->settable_ctx_params != NULL) + break; + cipher->settable_ctx_params = + OSSL_get_OP_cipher_settable_ctx_params(fns); break; } } @@ -1165,11 +1402,10 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns, /* * In order to be a consistent set of functions we must have at least * a complete set of "encrypt" functions, or a complete set of "decrypt" - * functions, or a single "cipher" function. In all cases we need a - * complete set of context management functions, as well as the - * blocksize, iv_length and key_length functions. + * functions, or a single "cipher" function. In all cases we need both + * the "newctx" and "freectx" functions. */ - EVP_CIPHER_meth_free(cipher); + EVP_CIPHER_free(cipher); EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS); return NULL; } @@ -1187,7 +1423,7 @@ static int evp_cipher_up_ref(void *cipher) static void evp_cipher_free(void *cipher) { - EVP_CIPHER_meth_free(cipher); + EVP_CIPHER_free(cipher); } EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, @@ -1195,20 +1431,40 @@ 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, evp_cipher_up_ref, + evp_cipher_from_dispatch, NULL, evp_cipher_up_ref, evp_cipher_free); -#ifndef FIPS_MODE - /* TODO(3.x) get rid of the need for legacy NIDs */ - if (cipher != NULL) { - /* - * FIPS module note: since internal fetches will be entirely - * provider based, we know that none of its code depends on legacy - * NIDs or any functionality that use them. - */ - cipher->nid = OBJ_sn2nid(algorithm); - } -#endif - return cipher; } + +int EVP_CIPHER_up_ref(EVP_CIPHER *cipher) +{ + int ref = 0; + + CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + return 1; +} + +void EVP_CIPHER_free(EVP_CIPHER *cipher) +{ + int i; + + if (cipher == NULL) + return; + + 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); +} + +void EVP_CIPHER_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_CIPHER *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_CIPHER, + (void (*)(void *, void *))fn, arg, + evp_cipher_from_dispatch, NULL, evp_cipher_free); +} diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 99535c00..b74b87e4 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -13,188 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA EVP_str_functs[] = { - {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_INIT_KEY, 0), "aesni_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_XTS_INIT_KEY, 0), "aesni_xts_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_CTRL, 0), "aes_gcm_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_TLS_CIPHER, 0), "aes_gcm_tls_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_INIT_KEY, 0), "aes_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_OCB_CIPHER, 0), "aes_ocb_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_XTS_INIT_KEY, 0), - "aes_t4_xts_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_CIPHER, 0), "aes_xts_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_INIT_KEY, 0), "aes_xts_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_CTRL, 0), "aria_gcm_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_CTRL, 0), "blake2b_mac_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_INIT, 0), "blake2b_mac_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_CTRL, 0), "blake2s_mac_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_INIT, 0), "blake2s_mac_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0), - "chacha20_poly1305_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CMLL_T4_INIT_KEY, 0), "cmll_t4_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_DES_EDE3_WRAP_CIPHER, 0), - "des_ede3_wrap_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_DO_SIGVER_INIT, 0), "do_sigver_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ENC_NEW, 0), "enc_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHERINIT_EX, 0), "EVP_CipherInit_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_ASN1_TO_PARAM, 0), - "EVP_CIPHER_asn1_to_param"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_COPY, 0), - "EVP_CIPHER_CTX_copy"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_CTRL, 0), - "EVP_CIPHER_CTX_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, 0), - "EVP_CIPHER_CTX_set_key_length"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_PADDING, 0), - "EVP_CIPHER_CTX_set_padding"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_FROM_DISPATCH, 0), - "evp_cipher_from_dispatch"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_MODE, 0), "EVP_CIPHER_mode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0), - "EVP_CIPHER_param_to_asn1"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0), - "EVP_DecryptFinal_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINAL_EX, 0), "EVP_DigestFinal_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTUPDATE, 0), "EVP_DigestUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0), - "evp_EncryptDecryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0), - "EVP_EncryptFinal_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW, 0), "EVP_KDF_CTX_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_DUP, 0), "EVP_MAC_CTX_dup"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_NEW, 0), "EVP_MAC_CTX_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_INIT, 0), "EVP_MAC_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_BLOCK_SIZE, 0), "EVP_MD_block_size"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD, 0), "EVP_PBE_alg_add"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD_TYPE, 0), - "EVP_PBE_alg_add_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_CIPHERINIT, 0), "EVP_PBE_CipherInit"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_SCRYPT, 0), "EVP_PBE_scrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKCS82PKEY, 0), "EVP_PKCS82PKEY"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY2PKCS8, 0), "EVP_PKEY2PKCS8"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ASN1_ADD0, 0), "EVP_PKEY_asn1_add0"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CHECK, 0), "EVP_PKEY_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_COPY_PARAMETERS, 0), - "EVP_PKEY_copy_parameters"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, 0), "EVP_PKEY_CTX_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL_STR, 0), - "EVP_PKEY_CTX_ctrl_str"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_DUP, 0), "EVP_PKEY_CTX_dup"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_MD, 0), "EVP_PKEY_CTX_md"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT, 0), "EVP_PKEY_decrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_INIT, 0), - "EVP_PKEY_decrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_OLD, 0), - "EVP_PKEY_decrypt_old"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE, 0), "EVP_PKEY_derive"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_INIT, 0), - "EVP_PKEY_derive_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, 0), - "EVP_PKEY_derive_set_peer"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT, 0), "EVP_PKEY_encrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_INIT, 0), - "EVP_PKEY_encrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_OLD, 0), - "EVP_PKEY_encrypt_old"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DH, 0), "EVP_PKEY_get0_DH"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DSA, 0), "EVP_PKEY_get0_DSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_EC_KEY, 0), - "EVP_PKEY_get0_EC_KEY"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_HMAC, 0), "EVP_PKEY_get0_hmac"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_POLY1305, 0), - "EVP_PKEY_get0_poly1305"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0), - "EVP_PKEY_get0_siphash"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0), - "EVP_PKEY_get_raw_private_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0), - "EVP_PKEY_get_raw_public_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0), - "EVP_PKEY_keygen_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_ADD0, 0), "EVP_PKEY_meth_add0"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_NEW, 0), "EVP_PKEY_meth_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW, 0), "EVP_PKEY_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_CMAC_KEY, 0), - "EVP_PKEY_new_CMAC_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, 0), - "EVP_PKEY_new_raw_private_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, 0), - "EVP_PKEY_new_raw_public_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0), - "EVP_PKEY_paramgen_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAM_CHECK, 0), - "EVP_PKEY_param_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PUBLIC_CHECK, 0), - "EVP_PKEY_public_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0), - "EVP_PKEY_set1_engine"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0), - "EVP_PKEY_set_alias_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_INIT, 0), - "EVP_PKEY_verify_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER, 0), - "EVP_PKEY_verify_recover"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, 0), - "EVP_PKEY_verify_recover_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SET_DEFAULT_PROPERTIES, 0), - "EVP_set_default_properties"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_GMAC_CTRL, 0), "gmac_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_CTRL, 0), "kmac_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_INIT, 0), "kmac_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBE_KEYIVGEN, 0), - "PKCS5_v2_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 0), - "PKCS5_v2_PBKDF2_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0), - "PKCS5_v2_scrypt_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_COPY, 0), "pkey_mac_copy"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_R_32_12_16_INIT_KEY, 0), - "r_32_12_16_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0), - "s390x_aes_gcm_tls_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_SCRYPT_ALG, 0), "scrypt_alg"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"}, - {0, NULL} -}; - static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, @@ -205,6 +23,10 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS), + "cannot get parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_SET_PARAMETERS), + "cannot set parameters"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE), "cipher not gcm mode"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR), @@ -277,6 +99,9 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE), + "no keymgmt available"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED), @@ -336,10 +161,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { int ERR_load_EVP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { - ERR_load_strings_const(EVP_str_functs); + if (ERR_reason_error_string(EVP_str_reasons[0].error) == NULL) ERR_load_strings_const(EVP_str_reasons); - } #endif return 1; } diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 0c25f0d5..6e31af79 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -15,6 +15,7 @@ #include "internal/thread_once.h" #include "internal/property.h" #include "internal/core.h" +#include "internal/provider.h" #include "internal/namemap.h" #include "internal/evp_int.h" /* evp_locl.h needs it */ #include "evp_locl.h" @@ -38,9 +39,14 @@ static const OPENSSL_CTX_METHOD default_method_store_method = { /* Data to be passed through ossl_method_construct() */ struct method_data_st { OPENSSL_CTX *libctx; - const char *name; OSSL_METHOD_CONSTRUCT_METHOD *mcm; - void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *); + int operation_id; /* For get_method_from_store() */ + int name_id; /* For get_method_from_store() */ + const char *name; /* For get_method_from_store() */ + const char *propquery; /* For get_method_from_store() */ + void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *, + OSSL_PROVIDER *, void *); + void *method_data; int (*refcnt_up_method)(void *method); void (*destruct_method)(void *method); }; @@ -76,7 +82,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, unsigned int name_id) +static uint32_t 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)) @@ -85,25 +91,36 @@ static uint32_t method_id(unsigned int operation_id, unsigned int name_id) } static void *get_method_from_store(OPENSSL_CTX *libctx, void *store, - int operation_id, const char *name, - const char *propquery, void *data) + void *data) { struct method_data_st *methdata = data; void *method = NULL; - OSSL_NAMEMAP *namemap; - int nameid; - uint32_t methid; + 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. + */ + if ((name_id = methdata->name_id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + if (namemap == 0) + return NULL; + name_id = ossl_namemap_name2num(namemap, methdata->name); + } + + if (name_id == 0 + || (meth_id = method_id(methdata->operation_id, name_id)) == 0) + return NULL; if (store == NULL && (store = get_default_method_store(libctx)) == NULL) return NULL; - if ((namemap = ossl_namemap_stored(libctx)) == NULL - || (nameid = ossl_namemap_name2num(namemap, name)) == 0 - || (methid = method_id(operation_id, nameid)) == 0) - return NULL; - - (void)ossl_method_store_fetch(store, methid, propquery, &method); + (void)ossl_method_store_fetch(store, meth_id, methdata->propquery, + &method); if (method != NULL && !methdata->refcnt_up_method(method)) { @@ -113,37 +130,59 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store, } static int put_method_in_store(OPENSSL_CTX *libctx, void *store, - void *method, int operation_id, - const char *name, const char *propdef, - void *data) + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *name, + const char *propdef, void *data) { struct method_data_st *methdata = data; OSSL_NAMEMAP *namemap; - int nameid; - uint32_t methid; + int name_id; + uint32_t meth_id; - if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL - || (nameid = ossl_namemap_add(namemap, 0, name)) == 0 - || (methid = method_id(operation_id, nameid)) == 0) + /* + * put_method_in_store() is only called with a method that was + * successfully created by construct_method() below, which means + * the name should already be stored in the namemap, so just use it. + */ + if ((namemap = ossl_namemap_stored(libctx)) == NULL + || (name_id = ossl_namemap_name2num(namemap, name)) == 0 + || (meth_id = method_id(operation_id, name_id)) == 0) return 0; if (store == NULL && (store = get_default_method_store(libctx)) == NULL) return 0; - if (methdata->refcnt_up_method(method) - && ossl_method_store_add(store, methid, propdef, method, - methdata->destruct_method)) - return 1; - return 0; + return ossl_method_store_add(store, prov, meth_id, propdef, method, + methdata->refcnt_up_method, + methdata->destruct_method); } +/* + * 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 *name, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, void *data) { + /* + * This function is only called if get_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. + * + * TODO(3.0): If this function gets an array of names instead of just + * one, we need to check through all the names to see if at least one + * of them has an associated number, and use that. If several names + * have associated numbers that differ from each other, it's an error. + */ struct method_data_st *methdata = data; + OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + int name_id = ossl_namemap_add(namemap, 0, name); - return methdata->method_from_dispatch(fns, prov); + return methdata->method_from_dispatch(name_id, fns, prov, + methdata->method_data); } static void destruct_method(void *method, void *data) @@ -153,17 +192,20 @@ static void destruct_method(void *method, void *data) methdata->destruct_method(method); } -void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, - const char *name, const char *properties, - void *(*new_method)(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov), - int (*up_ref_method)(void *), - void (*free_method)(void *)) +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 *)) { OSSL_METHOD_STORE *store = get_default_method_store(libctx); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - int nameid = 0; - uint32_t methid = 0; + uint32_t meth_id = 0; void *method = NULL; if (store == NULL || namemap == NULL) @@ -177,17 +219,28 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, return NULL; /* + * If we have been passed neither a name_id or a name, we have an + * internal programming error. + */ + if (!ossl_assert(name_id != 0 || name != NULL)) + return NULL; + + /* If we haven't received a name id yet, try to get one for the name */ + if (name_id == 0) + name_id = ossl_namemap_name2num(namemap, name); + + /* + * If we have a name id, calculate a method id with 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. */ - if ((nameid = ossl_namemap_name2num(namemap, name)) != 0 - && (methid = method_id(operation_id, nameid)) == 0) + if (name_id != 0 && (meth_id = method_id(operation_id, name_id)) == 0) return NULL; - if (nameid == 0 - || !ossl_method_store_cache_get(store, methid, properties, - &method)) { + 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, @@ -200,23 +253,28 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, mcmdata.mcm = &mcm; mcmdata.libctx = libctx; + mcmdata.operation_id = operation_id; + mcmdata.name_id = name_id; mcmdata.name = 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; - if ((method = ossl_method_construct(libctx, operation_id, name, - properties, 0 /* !force_cache */, + 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 nameid and methodid, since those have + * 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. */ - nameid = ossl_namemap_name2num(namemap, name); - methid = method_id(operation_id, nameid); - ossl_method_store_cache_set(store, methid, properties, method); + 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); } } else { up_ref_method(method); @@ -225,6 +283,45 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, return method; } +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, + 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); +} + +/* + * evp_generic_fetch_by_number() is special, and only returns methods for + * already known names, i.e. it refuses to work if no name_id can be found + * (it's considered an internal programming error). + * This is meant to be used when one method needs to fetch an associated + * other method. + */ +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, + 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); +} + int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) { OSSL_METHOD_STORE *store = get_default_method_store(libctx); @@ -234,3 +331,65 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) EVPerr(EVP_F_EVP_SET_DEFAULT_PROPERTIES, ERR_R_INTERNAL_ERROR); return 0; } + +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 (*free_method)(void *); +}; + +static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, + int no_store, void *vdata) +{ + 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 = ossl_namemap_add(namemap, 0, algo->algorithm_name); + void *method = NULL; + + if (name_id != 0) + method = data->new_method(name_id, algo->implementation, provider, + NULL); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + data->free_method(method); + } +} + +void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data), + void *method_data, + void (*free_method)(void *)) +{ + struct do_all_data_st data; + + data.new_method = new_method; + data.free_method = free_method; + data.user_fn = user_fn; + data.user_arg = user_arg; + ossl_algorithm_do_all(libctx, operation_id, method_data, do_one, &data); +} + +const char *evp_first_name(OSSL_PROVIDER *prov, int name_id) +{ + OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_num2name(namemap, name_id, 0); +} + +int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name) +{ + OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == number; +} diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 9d1d197c..4ec880fd 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "internal/evp_int.h" #include "internal/provider.h" #include "evp_locl.h" @@ -59,10 +60,10 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) } } else ret = -1; - if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ret == -2 ? - ASN1_R_UNSUPPORTED_CIPHER : - EVP_R_CIPHER_PARAMETER_ERROR); + if (ret == -2) + EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER); + else if (ret <= 0) + EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; @@ -105,10 +106,10 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) } } else ret = -1; - if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, ret == -2 ? - EVP_R_UNSUPPORTED_CIPHER : - EVP_R_CIPHER_PARAMETER_ERROR); + if (ret == -2) + EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_UNSUPPORTED_CIPHER); + else if (ret <= 0) + EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; @@ -217,12 +218,14 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) int EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { - int v = cipher->block_size; - int ok = evp_do_param(cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_BLOCK_SIZE, OSSL_PARAM_INTEGER, - evp_do_ciph_getparams, NULL); + int ok; + size_t v = cipher->block_size; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v : -1; + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &v); + ok = evp_do_ciph_getparams(cipher, params); + + return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; } int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) @@ -265,10 +268,12 @@ 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; - int ok = evp_do_param(cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_FLAGS, OSSL_PARAM_UNSIGNED_INTEGER, - evp_do_ciph_getparams, NULL); + 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); return ok != 0 ? v : 0; } @@ -300,17 +305,46 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { - int v = cipher->iv_len; - int ok = evp_do_param(cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_IVLEN, OSSL_PARAM_UNSIGNED_INTEGER, - evp_do_ciph_getparams, NULL); + int ok; + size_t v = cipher->iv_len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: -1; + 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; } int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) { - return EVP_CIPHER_iv_length(ctx->cipher); + int rv, len = EVP_CIPHER_iv_length(ctx->cipher); + size_t v = len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &v); + rv = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + if (rv == EVP_CTRL_RET_UNSUPPORTED) + goto legacy; + return rv != 0 ? (int)v : -1; + /* TODO (3.0) Remove legacy support */ +legacy: + if ((EVP_CIPHER_flags(ctx->cipher) & EVP_CIPH_CUSTOM_IV_LENGTH) != 0) { + rv = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, + 0, &len); + return (rv == 1) ? len : -1; + } + return len; +} + +int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx) +{ + int ret; + size_t v = 0; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, &v); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + return ret == 1 ? (int)v : 0; } const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx) @@ -323,22 +357,30 @@ const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx) */ const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) { + int ok; const unsigned char *v = ctx->iv; - int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv), - OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR, - evp_do_ciph_ctx_getparams, ctx->provctx); + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: NULL; + params[0] = + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v, + sizeof(ctx->iv)); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + + return ok != 0 ? v : NULL; } unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) { + int ok; unsigned char *v = ctx->iv; - int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv), - OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR, - evp_do_ciph_ctx_getparams, ctx->provctx); + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: NULL; + params[0] = + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v, + sizeof(ctx->iv)); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + + return ok != 0 ? v : NULL; } unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) @@ -348,42 +390,52 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx) { - int v = ctx->num; - int ok = evp_do_param(ctx->cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_getparams, ctx->provctx); + int ok; + unsigned int v = (unsigned int)ctx->num; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: -1; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &v); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + + return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; } int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num) { - int ok = evp_do_param(ctx->cipher, &num, sizeof(num), - OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_setparams, ctx->provctx); + int ok; + unsigned int n = (unsigned int)num; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - ctx->num = num; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &n); + ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params); + + if (ok != 0) + ctx->num = (int)n; return ok != 0; } int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { - int v = cipher->key_len; - int ok = evp_do_param(cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER, - evp_do_ciph_getparams, NULL); + int ok; + size_t v = cipher->key_len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: -1; + 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; } int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { - int v = ctx->key_len; - int ok = evp_do_param(ctx->cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER, - evp_do_ciph_ctx_getparams, ctx->provctx); + int ok; + size_t v = ctx->key_len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - return ok != 0 ? v: -1; + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); + + return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; } int EVP_CIPHER_nid(const EVP_CIPHER *cipher) @@ -396,28 +448,70 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) return ctx->cipher->nid; } -int EVP_CIPHER_mode(const EVP_CIPHER *cipher) +int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name) { - int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE; - int ok = evp_do_param(cipher, &v, sizeof(v), - OSSL_CIPHER_PARAM_MODE, OSSL_PARAM_INTEGER, - evp_do_ciph_getparams, NULL); - - return ok != 0 ? v: 0; + return evp_is_a(cipher->prov, cipher->name_id, name); } +const char *EVP_CIPHER_name(const EVP_CIPHER *cipher) +{ + if (cipher->prov != NULL) + return evp_first_name(cipher->prov, cipher->name_id); +#ifndef FIPS_MODE + return OBJ_nid2sn(EVP_CIPHER_nid(cipher)); +#else + return NULL; +#endif +} + +const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher) +{ + return cipher->prov; +} + +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; +} + +const char *EVP_MD_name(const EVP_MD *md) +{ + if (md->prov != NULL) + return evp_first_name(md->prov, md->name_id); +#ifndef FIPS_MODE + return OBJ_nid2sn(EVP_MD_nid(md)); +#else + return NULL; +#endif +} + +const OSSL_PROVIDER *EVP_MD_provider(const EVP_MD *md) +{ + return md->prov; +} int EVP_MD_block_size(const EVP_MD *md) { + int ok; + size_t v = md->block_size; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + if (md == NULL) { EVPerr(EVP_F_EVP_MD_BLOCK_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } - if (md->prov != NULL && md->dblock_size != NULL) - return (int)md->dblock_size(); + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &v); + ok = evp_do_md_getparams(md, params); - return md->block_size; + return ok != 0 ? (int)v : -1; } int EVP_MD_type(const EVP_MD *md) @@ -432,94 +526,105 @@ int EVP_MD_pkey_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) { - if (!md) { + int ok; + size_t v = md->md_size; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (md == NULL) { EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } - if (md->prov != NULL && md->size != NULL) - return (int)md->size(); + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &v); + ok = evp_do_md_getparams(md, params); - return md->md_size; + return ok != 0 ? (int)v : -1; } unsigned long EVP_MD_flags(const EVP_MD *md) { - return md->flags; + int ok; + unsigned long v = md->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_md_getparams(md, params); + + return ok != 0 ? v : 0; } EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type) { - EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); + EVP_MD *md = evp_md_new(); if (md != NULL) { md->type = md_type; md->pkey_type = pkey_type; - md->lock = CRYPTO_THREAD_lock_new(); - if (md->lock == NULL) { - OPENSSL_free(md); - return NULL; - } - md->refcnt = 1; } return md; } EVP_MD *EVP_MD_meth_dup(const EVP_MD *md) { - EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type); + EVP_MD *to = NULL; - if (to != NULL) { + /* + * Non-legacy EVP_MDs can't be duplicated like this. + * Use EVP_MD_up_ref() instead. + */ + if (md->prov != NULL) + return NULL; + + if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) != NULL) { CRYPTO_RWLOCK *lock = to->lock; + memcpy(to, md, sizeof(*to)); to->lock = lock; } return to; } -int EVP_MD_up_ref(EVP_MD *md) -{ - int ref = 0; - - CRYPTO_UP_REF(&md->refcnt, &ref, md->lock); - return 1; -} - void EVP_MD_meth_free(EVP_MD *md) { - if (md != NULL) { - int i; - - CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock); - if (i > 0) - return; - ossl_provider_free(md->prov); - CRYPTO_THREAD_lock_free(md->lock); - OPENSSL_free(md); - } + EVP_MD_free(md); } int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) { + if (md->block_size != 0) + return 0; + md->block_size = blocksize; return 1; } int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize) { + if (md->md_size != 0) + return 0; + md->md_size = resultsize; return 1; } int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) { + if (md->ctx_size != 0) + return 0; + md->ctx_size = datasize; return 1; } int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) { + if (md->flags != 0) + return 0; + md->flags = flags; return 1; } int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) { + if (md->init != NULL) + return 0; + md->init = init; return 1; } @@ -527,29 +632,44 @@ int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) { + if (md->update != NULL) + return 0; + md->update = update; return 1; } int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) { + if (md->final != NULL) + return 0; + md->final = final; return 1; } int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) { + if (md->copy != NULL) + return 0; + md->copy = copy; return 1; } int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)) { + if (md->cleanup != NULL) + return 0; + md->cleanup = cleanup; return 1; } int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) { + if (md->md_ctrl != NULL) + return 0; + md->md_ctrl = ctrl; return 1; } diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 54f9e081..3437e04b 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -9,6 +9,11 @@ /* EVP_MD_CTX related stuff */ +#include + +#define EVP_CTRL_RET_UNSUPPORTED -1 + + struct evp_md_ctx_st { const EVP_MD *reqdigest; /* The original requested digest */ const EVP_MD *digest; @@ -51,15 +56,87 @@ struct evp_cipher_ctx_st { } /* EVP_CIPHER_CTX */ ; struct evp_mac_ctx_st { - const EVP_MAC *meth; /* Method structure */ + EVP_MAC *meth; /* Method structure */ void *data; /* Individual method data */ } /* EVP_MAC_CTX */; struct evp_kdf_ctx_st { - const EVP_KDF *meth; /* Method structure */ - EVP_KDF_IMPL *impl; /* Algorithm-specific data */ + EVP_KDF *meth; /* Method structure */ + void *data; /* Algorithm-specific data */ } /* EVP_KDF_CTX */ ; +struct evp_keymgmt_st { + int id; /* libcrypto internal */ + + int name_id; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + /* Domain parameter routines */ + OSSL_OP_keymgmt_importdomparams_fn *importdomparams; + OSSL_OP_keymgmt_gendomparams_fn *gendomparams; + OSSL_OP_keymgmt_freedomparams_fn *freedomparams; + OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams; + OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types; + OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types; + + /* Key routines */ + OSSL_OP_keymgmt_importkey_fn *importkey; + OSSL_OP_keymgmt_genkey_fn *genkey; + OSSL_OP_keymgmt_loadkey_fn *loadkey; + OSSL_OP_keymgmt_freekey_fn *freekey; + OSSL_OP_keymgmt_exportkey_fn *exportkey; + OSSL_OP_keymgmt_importkey_types_fn *importkey_types; + OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types; +} /* EVP_KEYMGMT */ ; + +struct keymgmt_data_st { + OPENSSL_CTX *ctx; + const char *properties; +}; + +struct evp_keyexch_st { + int name_id; + OSSL_PROVIDER *prov; + 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; + OSSL_OP_keyexch_derive_fn *derive; + OSSL_OP_keyexch_freectx_fn *freectx; + OSSL_OP_keyexch_dupctx_fn *dupctx; + OSSL_OP_keyexch_set_ctx_params_fn *set_ctx_params; + OSSL_OP_keyexch_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_KEYEXCH */; + +struct evp_signature_st { + int name_id; + OSSL_PROVIDER *prov; + 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; + OSSL_OP_signature_verify_init_fn *verify_init; + OSSL_OP_signature_verify_fn *verify; + OSSL_OP_signature_verify_recover_init_fn *verify_recover_init; + OSSL_OP_signature_verify_recover_fn *verify_recover; + OSSL_OP_signature_freectx_fn *freectx; + OSSL_OP_signature_dupctx_fn *dupctx; + OSSL_OP_signature_get_ctx_params_fn *get_ctx_params; + OSSL_OP_signature_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_signature_set_ctx_params_fn *set_ctx_params; + OSSL_OP_signature_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_SIGNATURE */; + 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, @@ -90,16 +167,45 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len); #include void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, - const char *algorithm, const char *properties, - void *(*new_method)(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov), + 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 *)); +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, + int (*up_ref_method)(void *), + void (*free_method)(void *)); +void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data), + void *method_data, + void (*free_method)(void *)); + +/* Internal fetchers for method types that are to be combined with others */ +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, + const char *properties); + +/* Internal structure constructors for fetched methods */ +EVP_MD *evp_md_new(void); +EVP_CIPHER *evp_cipher_new(void); /* Helper functions to avoid duplicating code */ /* - * The callbacks implement different ways to pass a params array to the + * These methods implement different ways to pass a params array to the * provider. They will return one of these values: * * -2 if the method doesn't come from a provider @@ -109,26 +215,39 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, * or the return value from the desired function * (evp_do_param will return it to the caller) */ -int evp_do_ciph_getparams(const void *vciph, void *ignored, - OSSL_PARAM params[]); -int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx, +int evp_do_ciph_getparams(const EVP_CIPHER *ciph, OSSL_PARAM params[]); +int evp_do_ciph_ctx_getparams(const EVP_CIPHER *ciph, void *provctx, OSSL_PARAM params[]); -int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx, +int evp_do_ciph_ctx_setparams(const EVP_CIPHER *ciph, void *provctx, OSSL_PARAM params[]); +int evp_do_md_getparams(const EVP_MD *md, OSSL_PARAM params[]); +int evp_do_md_ctx_getparams(const EVP_MD *md, void *provctx, + OSSL_PARAM params[]); +int evp_do_md_ctx_setparams(const EVP_MD *md, void *provctx, + OSSL_PARAM params[]); -/*- - * prepares a singular parameter, then calls the callback to execute. - * - * |method| points to the method used by the callback. - * EVP_CIPHER, EVP_MD, ... - * |ptr| points at the data to transfer. - * |sz| is the size of the data to transfer. - * |key| is the name of the parameter to pass. - * |datatype| is the data type of the parameter to pass. - * |cb| is the callback that actually performs the parameter passing - * |cb_ctx| is the cipher context - */ -int evp_do_param(const void *method, void *ptr, size_t sz, const char *key, - int datatype, - int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]), - void *cb_ctx); +OSSL_PARAM *evp_pkey_to_param(EVP_PKEY *pkey, size_t *sz); + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ + size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ + \ + if (pksize == 0) { \ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ + return 0; \ + } \ + if (arg == NULL) { \ + *arglen = pksize; \ + return 1; \ + } \ + if (*arglen < pksize) { \ + ERR_raise(ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ + return 0; \ + } \ + } + +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); diff --git a/crypto/evp/evp_utils.c b/crypto/evp/evp_utils.c index 48f548c7..3da208a6 100644 --- a/crypto/evp/evp_utils.c +++ b/crypto/evp/evp_utils.c @@ -17,62 +17,65 @@ #include "internal/evp_int.h" /* evp_locl.h needs it */ #include "evp_locl.h" -int evp_do_ciph_getparams(const void *vciph, void *ignored, - OSSL_PARAM params[]) -{ - const EVP_CIPHER *ciph = vciph; - - if (ciph->prov == NULL) - return -2; - if (ciph->get_params == NULL) - return -1; - return ciph->get_params(params); -} - -int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx, - OSSL_PARAM params[]) -{ - const EVP_CIPHER *ciph = vciph; - - if (ciph->prov == NULL) - return -2; - if (ciph->ctx_get_params == NULL) - return -1; - return ciph->ctx_get_params(provctx, params); -} - -int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx, - OSSL_PARAM params[]) -{ - const EVP_CIPHER *ciph = vciph; - - if (ciph->prov == NULL) - return -2; - if (ciph->ctx_set_params == NULL) - return -1; - return ciph->ctx_set_params(provctx, params); -} - -int evp_do_param(const void *method, void *ptr, size_t sz, const char *key, - int datatype, - int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]), - void *cb_ctx) -{ - OSSL_PARAM params[2] = { - OSSL_PARAM_END, - OSSL_PARAM_END - }; - int ret; - - params[0].key = key; - params[0].data_type = datatype; - params[0].data = ptr; - params[0].data_size = sz; - - ret = cb(method, cb_ctx, params); - if (ret == -1) { - EVPerr(0, EVP_R_CTRL_NOT_IMPLEMENTED); - ret = 0; +/* + * EVP_CTRL_RET_UNSUPPORTED = -1 is the returned value from any ctrl function + * where the control command isn't supported, and an alternative code path + * may be chosen. + * Since these functions are used to implement ctrl functionality, we + * use the same value, and other callers will have to compensate. + */ +#define PARAM_CHECK(obj, func, errfunc) \ + if (obj == NULL) \ + return 0; \ + if (obj->prov == NULL) \ + return EVP_CTRL_RET_UNSUPPORTED; \ + if (obj->func == NULL) { \ + errfunc(); \ + return 0; \ } - return ret; + +#define PARAM_FUNC(name, func, type, err) \ +int name (const type *obj, OSSL_PARAM params[]) \ +{ \ + PARAM_CHECK(obj, func, err) \ + return obj->func(params); \ } + +#define PARAM_CTX_FUNC(name, func, type, err) \ +int name (const type *obj, void *provctx, OSSL_PARAM params[]) \ +{ \ + PARAM_CHECK(obj, func, err) \ + return obj->func(provctx, params); \ +} + +#define PARAM_FUNCTIONS(type, \ + getname, getfunc, \ + getctxname, getctxfunc, \ + setctxname, setctxfunc) \ + PARAM_FUNC(getname, getfunc, type, geterr) \ + PARAM_CTX_FUNC(getctxname, getctxfunc, type, geterr) \ + PARAM_CTX_FUNC(setctxname, setctxfunc, type, seterr) + +/* + * These error functions are a workaround for the error scripts, which + * currently require that XXXerr method appears inside a function (not a macro). + */ +static void geterr(void) +{ + EVPerr(0, EVP_R_CANNOT_GET_PARAMETERS); +} + +static void seterr(void) +{ + EVPerr(0, EVP_R_CANNOT_SET_PARAMETERS); +} + +PARAM_FUNCTIONS(EVP_CIPHER, + evp_do_ciph_getparams, get_params, + evp_do_ciph_ctx_getparams, get_ctx_params, + evp_do_ciph_ctx_setparams, set_ctx_params) + +PARAM_FUNCTIONS(EVP_MD, + evp_do_md_getparams, get_params, + evp_do_md_ctx_getparams, get_ctx_params, + evp_do_md_ctx_setparams, set_ctx_params) diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c new file mode 100644 index 00000000..53a25a42 --- /dev/null +++ b/crypto/evp/exchange.c @@ -0,0 +1,388 @@ +/* + * 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 "internal/refcount.h" +#include "internal/evp_int.h" +#include "internal/provider.h" +#include "internal/numbers.h" /* includes SIZE_MAX */ +#include "evp_locl.h" + +static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) +{ + EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH)); + + exchange->lock = CRYPTO_THREAD_lock_new(); + if (exchange->lock == NULL) { + OPENSSL_free(exchange); + return NULL; + } + exchange->prov = prov; + ossl_provider_up_ref(prov); + exchange->refcnt = 1; + + return exchange; +} + +static void *evp_keyexch_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *vkeymgmt_data) +{ + /* + * 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) { + case OSSL_FUNC_KEYEXCH_NEWCTX: + if (exchange->newctx != NULL) + break; + exchange->newctx = OSSL_get_OP_keyexch_newctx(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_INIT: + if (exchange->init != NULL) + break; + exchange->init = OSSL_get_OP_keyexch_init(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_SET_PEER: + if (exchange->set_peer != NULL) + break; + exchange->set_peer = OSSL_get_OP_keyexch_set_peer(fns); + break; + case OSSL_FUNC_KEYEXCH_DERIVE: + if (exchange->derive != NULL) + break; + exchange->derive = OSSL_get_OP_keyexch_derive(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_FREECTX: + if (exchange->freectx != NULL) + break; + exchange->freectx = OSSL_get_OP_keyexch_freectx(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_DUPCTX: + if (exchange->dupctx != NULL) + break; + exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns); + break; + case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS: + if (exchange->set_ctx_params != NULL) + break; + exchange->set_ctx_params = OSSL_get_OP_keyexch_set_ctx_params(fns); + paramfncnt++; + break; + case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS: + if (exchange->settable_ctx_params != NULL) + break; + exchange->settable_ctx_params + = OSSL_get_OP_keyexch_settable_ctx_params(fns); + paramfncnt++; + break; + } + } + if (fncnt != 4 || (paramfncnt != 0 && paramfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "exchange" functions: init, derive, newctx, + * and freectx. The set_ctx_params and settable_ctx_params functions are + * optional, but if one of them is present then the other one must also + * be present. The dupctx and set_peer functions are optional. + */ + EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH, + EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return exchange; + + err: + EVP_KEYEXCH_free(exchange); + EVP_KEYMGMT_free(keymgmt); + return NULL; +} + +void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange) +{ + if (exchange != NULL) { + int i; + + 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); + } +} + +int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange) +{ + int ref = 0; + + CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock); + return 1; +} + +OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange) +{ + return exchange->prov; +} + +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; +} + +int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange) +{ + int ret; + void *provkey = NULL; + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_DERIVE; + + if (ctx->engine != 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; + + /* + * TODO(3.0): Check for legacy handling. Remove this once all all + * algorithms are moved to providers. + */ + 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 (exchange == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + + ctx->op.kex.exchange = exchange; + if (ctx->pkey != NULL) { + provkey = evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt); + if (provkey == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + 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); + goto err; + } + ret = exchange->init(ctx->op.kex.exchprovctx, provkey); + + return ret ? 1 : 0; + err: + ctx->operation = EVP_PKEY_OP_UNDEFINED; + 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); + return -2; + } + + if (ctx->pmeth->derive_init == NULL) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + 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; + void *provkey = NULL; + + if (ctx == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx) || ctx->op.kex.exchprovctx == NULL) + goto legacy; + + if (ctx->op.kex.exchange->set_peer == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + provkey = evp_keymgmt_export_to_provider(peer, + ctx->op.kex.exchange->keymgmt); + if (provkey == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR); + return 0; + } + return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey); + + legacy: + if (ctx->pmeth == NULL + || !(ctx->pmeth->derive != NULL + || ctx->pmeth->encrypt != NULL + || ctx->pmeth->decrypt != NULL) + || ctx->pmeth->ctrl == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE + && ctx->operation != EVP_PKEY_OP_ENCRYPT + && ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (ctx->pkey == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* + * For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -2 is OK for us here, as well as 1, so we can check for 0 only. + */ + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return ret; + } + + EVP_PKEY_up_ref(peer); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) +{ + int ret; + + if (ctx == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.kex.exchprovctx == NULL) + goto legacy; + + ret = ctx->op.kex.exchange->derive(ctx->op.kex.exchprovctx, key, pkeylen, + SIZE_MAX); + + return ret; + legacy: + if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); +} diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 6131d8ef..5c57cc36 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -15,12 +15,15 @@ #include #include #include +#include +#include #include "internal/asn1_int.h" #include "internal/evp_int.h" #include "internal/numbers.h" +#include "internal/provider.h" #include "evp_locl.h" -EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) +EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) { EVP_KDF_CTX *ctx = NULL; @@ -28,8 +31,12 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) return NULL; ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX)); - if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) { + if (ctx == NULL + || (ctx->data = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL + || !EVP_KDF_up_ref(kdf)) { EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + kdf->freectx(ctx->data); OPENSSL_free(ctx); ctx = NULL; } else { @@ -38,16 +45,52 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) return ctx; } -EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) { - const EVP_KDF *kdf = EVP_get_kdfbynid(id); - - return EVP_KDF_CTX_new(kdf); + if (ctx != NULL) { + ctx->meth->freectx(ctx->data); + ctx->data = NULL; + EVP_KDF_free(ctx->meth); + OPENSSL_free(ctx); + } } -int EVP_KDF_nid(const EVP_KDF *kdf) +EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) { - return kdf->type; + EVP_KDF_CTX *dst; + + if (src == NULL || src->data == NULL || src->meth->dupctx == NULL) + return NULL; + + dst = OPENSSL_malloc(sizeof(*dst)); + if (dst == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memcpy(dst, src, sizeof(*dst)); + if (!EVP_KDF_up_ref(dst->meth)) { + EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } + + dst->data = src->meth->dupctx(src->data); + if (dst->data == NULL) { + EVP_KDF_CTX_free(dst); + return NULL; + } + return dst; +} + +const char *EVP_KDF_name(const EVP_KDF *kdf) +{ + return evp_first_name(kdf->prov, kdf->name_id); +} + +const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf) +{ + return kdf->prov; } const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) @@ -55,75 +98,31 @@ const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) return ctx->meth; } -void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) -{ - if (ctx == NULL) - return; - - ctx->meth->free(ctx->impl); - OPENSSL_free(ctx); -} - void EVP_KDF_reset(EVP_KDF_CTX *ctx) { if (ctx == NULL) return; if (ctx->meth->reset != NULL) - ctx->meth->reset(ctx->impl); -} - -int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...) -{ - int ret; - va_list args; - - va_start(args, cmd); - ret = EVP_KDF_vctrl(ctx, cmd, args); - va_end(args); - - if (ret == -2) - EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; -} - -int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args) -{ - if (ctx == NULL) - return 0; - - return ctx->meth->ctrl(ctx->impl, cmd, args); -} - -int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value) -{ - int ret; - - if (ctx == NULL) - return 0; - - if (ctx->meth->ctrl_str == NULL) { - EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - - ret = ctx->meth->ctrl_str(ctx->impl, type, value); - if (ret == -2) - EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; + ctx->meth->reset(ctx->data); } size_t EVP_KDF_size(EVP_KDF_CTX *ctx) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t s; + if (ctx == NULL) return 0; - if (ctx->meth->size == NULL) - return SIZE_MAX; - - return ctx->meth->size(ctx->impl); + *params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s); + if (ctx->meth->get_ctx_params != NULL + && ctx->meth->get_ctx_params(ctx->data, params)) + return s; + if (ctx->meth->get_params != NULL + && ctx->meth->get_params(params)) + return s; + return 0; } int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) @@ -131,5 +130,32 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) if (ctx == NULL) return 0; - return ctx->meth->derive(ctx->impl, key, keylen); + return ctx->meth->derive(ctx->data, key, keylen); +} + +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]) +{ + if (kdf->get_params != NULL) + return kdf->get_params(params); + return 1; +} + +int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->meth->get_ctx_params != NULL) + return ctx->meth->get_ctx_params(ctx->data, params); + return 1; +} + +int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->data, params); + return 1; } diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c new file mode 100644 index 00000000..7bcdcc7d --- /dev/null +++ b/crypto/evp/kdf_meth.c @@ -0,0 +1,197 @@ +/* + * 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/evp_int.h" +#include "internal/provider.h" +#include "evp_locl.h" + +static int evp_kdf_up_ref(void *vkdf) +{ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); + return 1; +} + +static void evp_kdf_free(void *vkdf){ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + if (kdf != NULL) { + CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); + if (ref <= 0) { + ossl_provider_free(kdf->prov); + CRYPTO_THREAD_lock_free(kdf->lock); + OPENSSL_free(kdf); + } + } +} + +static void *evp_kdf_new(void) +{ + EVP_KDF *kdf = NULL; + + if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL + || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(kdf); + return NULL; + } + kdf->refcnt = 1; + return kdf; +} + +static void *evp_kdf_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data) +{ + EVP_KDF *kdf = NULL; + int fnkdfcnt = 0, fnctxcnt = 0; + + if ((kdf = evp_kdf_new()) == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + kdf->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KDF_NEWCTX: + if (kdf->newctx != NULL) + break; + kdf->newctx = OSSL_get_OP_kdf_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_DUPCTX: + if (kdf->dupctx != NULL) + break; + kdf->dupctx = OSSL_get_OP_kdf_dupctx(fns); + break; + case OSSL_FUNC_KDF_FREECTX: + if (kdf->freectx != NULL) + break; + kdf->freectx = OSSL_get_OP_kdf_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_RESET: + if (kdf->reset != NULL) + break; + kdf->reset = OSSL_get_OP_kdf_reset(fns); + break; + case OSSL_FUNC_KDF_DERIVE: + if (kdf->derive != NULL) + break; + kdf->derive = OSSL_get_OP_kdf_derive(fns); + fnkdfcnt++; + break; + case OSSL_FUNC_KDF_GETTABLE_PARAMS: + if (kdf->gettable_params != NULL) + break; + kdf->gettable_params = + OSSL_get_OP_kdf_gettable_params(fns); + break; + case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS: + if (kdf->gettable_ctx_params != NULL) + break; + kdf->gettable_ctx_params = + OSSL_get_OP_kdf_gettable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS: + if (kdf->settable_ctx_params != NULL) + break; + kdf->settable_ctx_params = + OSSL_get_OP_kdf_settable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_GET_PARAMS: + if (kdf->get_params != NULL) + break; + kdf->get_params = OSSL_get_OP_kdf_get_params(fns); + break; + case OSSL_FUNC_KDF_GET_CTX_PARAMS: + if (kdf->get_ctx_params != NULL) + break; + kdf->get_ctx_params = OSSL_get_OP_kdf_get_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SET_CTX_PARAMS: + if (kdf->set_ctx_params != NULL) + break; + kdf->set_ctx_params = OSSL_get_OP_kdf_set_ctx_params(fns); + break; + } + } + if (fnkdfcnt != 1 || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a derive function, and a complete set of context management + * functions. + */ + evp_kdf_free(kdf); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + kdf->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return kdf; +} + +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_free); +} + +int EVP_KDF_up_ref(EVP_KDF *kdf) +{ + return evp_kdf_up_ref(kdf); +} + +void EVP_KDF_free(EVP_KDF *kdf) +{ + evp_kdf_free(kdf); +} + +const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) +{ + if (kdf->gettable_params == NULL) + return NULL; + return kdf->gettable_params(); +} + +const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf) +{ + if (kdf->gettable_ctx_params == NULL) + return NULL; + return kdf->gettable_ctx_params(); +} + +const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf) +{ + if (kdf->settable_ctx_params == NULL) + return NULL; + return kdf->settable_ctx_params(); +} + +void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_KDF *kdf, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KDF, + (void (*)(void *, void *))fn, arg, + evp_kdf_from_dispatch, NULL, evp_kdf_free); +} diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c new file mode 100644 index 00000000..8ee28fbe --- /dev/null +++ b/crypto/evp/keymgmt_lib.c @@ -0,0 +1,288 @@ +/* + * 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 "internal/cryptlib.h" +#include "internal/nelem.h" +#include "internal/evp_int.h" +#include "internal/asn1_int.h" +#include "internal/provider.h" +#include "evp_locl.h" + +static OSSL_PARAM *paramdefs_to_params(const OSSL_PARAM *paramdefs) +{ + size_t cnt; + const OSSL_PARAM *p; + OSSL_PARAM *params, *q; + + 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; + + 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; +} + +void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) +{ + void *provkey = NULL; + size_t i, j; + + /* + * If there is an underlying legacy key and it has changed, invalidate + * the cache of provider keys. + */ + if (pk->pkey.ptr != NULL) { + /* + * If there is no dirty counter, this key can't be used with + * providers. + */ + if (pk->ameth->dirty_cnt == NULL) + return NULL; + + if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy) + evp_keymgmt_clear_pkey_cache(pk); + } + + /* + * See if we have exported to this provider already. + * If we have, return immediately. + */ + for (i = 0; + i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL; + i++) { + if (keymgmt == pk->pkeys[i].keymgmt) + return pk->pkeys[i].provkey; + } + + if (pk->pkey.ptr != NULL) { + /* There is a legacy key, try to export that one to the provider */ + + /* If the legacy key doesn't have an export function, give up */ + if (pk->ameth->export_to == NULL) + return NULL; + + /* Otherwise, simply use it */ + provkey = pk->ameth->export_to(pk, keymgmt); + + /* Synchronize the dirty count, but only if we exported successfully */ + if (provkey != NULL) + pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); + + } else { + /* + * Here, there is no legacy key, so we look at the already cached + * provider keys, and import from the first that supports it + * (i.e. use its export function), and export the imported data to + * the new provider. + */ + + /* + * If the given keymgmt doesn't have an import function, give up + */ + if (keymgmt->importkey == 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 = + ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + 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 */ + pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params); + + /* + * Allocate space and assign 'data' to point into the + * data block + */ + data = allocate_params_space(params); + + /* + * Call the exportkey function a second time, to get + * the data filled + */ + pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params); + + /* + * We should have all the data at this point, so import + * into the new provider and hope to get a key back. + */ + provkey = keymgmt->importkey(provctx, params); + OPENSSL_free(params); + OPENSSL_free(data); + + if (provkey != NULL) + break; + } + } + } + + /* + * TODO(3.0) Right now, we assume we have ample space. We will + * have to think about a cache aging scheme, though, if |i| indexes + * outside the array. + */ + j = ossl_assert(i < OSSL_NELEM(pk->pkeys)); + + if (provkey != NULL) { + EVP_KEYMGMT_up_ref(keymgmt); + pk->pkeys[i].keymgmt = keymgmt; + pk->pkeys[i].provkey = provkey; + } + return provkey; +} + +void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk) +{ + size_t i; + + if (pk != NULL) { + for (i = 0; + i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL; + i++) { + EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt; + void *provkey = pk->pkeys[i].provkey; + + pk->pkeys[i].keymgmt = NULL; + pk->pkeys[i].provkey = NULL; + keymgmt->freekey(provkey); + EVP_KEYMGMT_free(keymgmt); + } + } +} + + +/* internal functions */ +/* TODO(3.0) decide if these should be public or internal */ +void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + return keymgmt->importdomparams(provctx, params); +} + +void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + return keymgmt->gendomparams(provctx, params); +} + +void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, + void *provdomparams) +{ + keymgmt->freedomparams(provdomparams); +} + +int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt, + void *provdomparams, OSSL_PARAM params[]) +{ + return keymgmt->exportdomparams(provdomparams, params); +} + +const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->importdomparam_types(); +} + +const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->exportdomparam_types(); +} + + +void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + return keymgmt->importkey(provctx, params); +} + +void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams, + const OSSL_PARAM params[]) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + return keymgmt->genkey(provctx, domparams, params); +} + +void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt, + void *id, size_t idlen) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + + return keymgmt->loadkey(provctx, id, idlen); +} + +void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey) +{ + keymgmt->freekey(provkey); +} + +int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey, + OSSL_PARAM params[]) +{ + return keymgmt->exportkey(provkey, params); +} + +const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->importkey_types(); +} + +const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->exportkey_types(); +} diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c new file mode 100644 index 00000000..c170bd67 --- /dev/null +++ b/crypto/evp/keymgmt_meth.c @@ -0,0 +1,202 @@ +/* + * 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/provider.h" +#include "internal/refcount.h" +#include "internal/evp_int.h" +#include "evp_locl.h" + + +static void *keymgmt_new(void) +{ + EVP_KEYMGMT *keymgmt = NULL; + + if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL + || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) { + EVP_KEYMGMT_free(keymgmt); + EVPerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + + keymgmt->refcnt = 1; + + return keymgmt; +} + +static void *keymgmt_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *unused) +{ + EVP_KEYMGMT *keymgmt = NULL; + + if ((keymgmt = keymgmt_new()) == NULL) { + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + keymgmt->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS: + if (keymgmt->importdomparams != NULL) + break; + keymgmt->importdomparams = + OSSL_get_OP_keymgmt_importdomparams(fns); + break; + case OSSL_FUNC_KEYMGMT_GENDOMPARAMS: + if (keymgmt->gendomparams != NULL) + break; + keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns); + break; + case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS: + if (keymgmt->freedomparams != NULL) + break; + keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns); + break; + case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS: + if (keymgmt->exportdomparams != NULL) + break; + keymgmt->exportdomparams = + OSSL_get_OP_keymgmt_exportdomparams(fns); + break; + case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES: + if (keymgmt->importdomparam_types != NULL) + break; + keymgmt->importdomparam_types = + OSSL_get_OP_keymgmt_importdomparam_types(fns); + break; + case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES: + if (keymgmt->exportdomparam_types != NULL) + break; + keymgmt->exportdomparam_types = + OSSL_get_OP_keymgmt_exportdomparam_types(fns); + break; + case OSSL_FUNC_KEYMGMT_IMPORTKEY: + if (keymgmt->importkey != NULL) + break; + keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns); + break; + case OSSL_FUNC_KEYMGMT_GENKEY: + if (keymgmt->genkey != NULL) + break; + keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns); + break; + case OSSL_FUNC_KEYMGMT_LOADKEY: + if (keymgmt->loadkey != NULL) + break; + keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns); + break; + case OSSL_FUNC_KEYMGMT_FREEKEY: + if (keymgmt->freekey != NULL) + break; + keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns); + break; + case OSSL_FUNC_KEYMGMT_EXPORTKEY: + if (keymgmt->exportkey != NULL) + break; + keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns); + break; + case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES: + if (keymgmt->importkey_types != NULL) + break; + keymgmt->importkey_types = + OSSL_get_OP_keymgmt_importkey_types(fns); + break; + case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES: + if (keymgmt->exportkey_types != NULL) + break; + keymgmt->exportkey_types = + OSSL_get_OP_keymgmt_exportkey_types(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * It makes no sense being able to free stuff if you can't create it. + * It makes no sense providing OSSL_PARAM descriptors for import and + * export if you can't import or export. + */ + if ((keymgmt->freedomparams != NULL + && (keymgmt->importdomparams == NULL + && keymgmt->gendomparams == NULL)) + || (keymgmt->freekey != NULL + && (keymgmt->importkey == NULL + && keymgmt->genkey == NULL + && keymgmt->loadkey == NULL)) + || (keymgmt->importdomparam_types != NULL + && keymgmt->importdomparams == NULL) + || (keymgmt->exportdomparam_types != NULL + && keymgmt->exportdomparams == NULL) + || (keymgmt->importkey_types != NULL + && keymgmt->importkey == NULL) + || (keymgmt->exportkey_types != NULL + && keymgmt->exportkey == NULL)) { + EVP_KEYMGMT_free(keymgmt); + EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + keymgmt->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return keymgmt; +} + +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, + const char *properties) +{ + return evp_generic_fetch_by_number(ctx, + OSSL_OP_KEYMGMT, name_id, properties, + keymgmt_from_dispatch, NULL, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +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, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt) +{ + int ref = 0; + + CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + return 1; +} + +void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) +{ + int ref = 0; + + if (keymgmt == NULL) + return; + + CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + if (ref > 0) + return; + ossl_provider_free(keymgmt->prov); + CRYPTO_THREAD_lock_free(keymgmt->lock); + OPENSSL_free(keymgmt); +} + +const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->prov; +} + diff --git a/crypto/evp/m_sha3.c b/crypto/evp/m_sha3.c index f3266ebe..1e71eed9 100644 --- a/crypto/evp/m_sha3.c +++ b/crypto/evp/m_sha3.c @@ -36,12 +36,6 @@ static int shake_init(EVP_MD_CTX *ctx) return sha3_init(EVP_MD_CTX_md_data(ctx), '\x1f', ctx->digest->md_size * 8); } -static int kmac_init(EVP_MD_CTX *ctx) -{ - return keccak_kmac_init(EVP_MD_CTX_md_data(ctx), '\x04', - ctx->digest->md_size * 8 / 2); -} - static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) { KECCAK1600_CTX *ctx = evp_ctx->md_data; @@ -323,27 +317,3 @@ EVP_MD_SHA3(512) EVP_MD_SHAKE(128) EVP_MD_SHAKE(256) - - -# define EVP_MD_KECCAK_KMAC(bitlen) \ -const EVP_MD *evp_keccak_kmac##bitlen(void) \ -{ \ - static const EVP_MD kmac_##bitlen##_md = { \ - NID_kmac##bitlen, \ - 0, \ - 2 * bitlen / 8, \ - EVP_MD_FLAG_XOF, \ - kmac_init, \ - update, \ - final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - shake_ctrl \ - }; \ - return &kmac_##bitlen##_md; \ -} - -EVP_MD_KECCAK_KMAC(128) -EVP_MD_KECCAK_KMAC(256) diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index ee4a68f4..cf704ba4 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -11,26 +11,24 @@ #include #include #include +#include +#include #include #include "internal/nelem.h" #include "internal/evp_int.h" +#include "internal/provider.h" #include "evp_locl.h" -EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id) -{ - const EVP_MAC *mac = EVP_get_macbynid(id); - - if (mac == NULL) - return NULL; - return EVP_MAC_CTX_new(mac); -} - -EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac) +EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) { EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX)); - if (ctx == NULL || (ctx->data = mac->new()) == NULL) { + if (ctx == NULL + || (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL + || !EVP_MAC_up_ref(mac)) { EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + mac->freectx(ctx->data); OPENSSL_free(ctx); ctx = NULL; } else { @@ -41,9 +39,11 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac) void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx) { - if (ctx != NULL && ctx->data != NULL) { - ctx->meth->free(ctx->data); + if (ctx != NULL) { + ctx->meth->freectx(ctx->data); ctx->data = NULL; + /* refcnt-- */ + EVP_MAC_free(ctx->meth); } OPENSSL_free(ctx); } @@ -62,8 +62,13 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) } *dst = *src; + if (!EVP_MAC_up_ref(dst->meth)) { + EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } - dst->data = src->meth->dup(src->data); + dst->data = src->meth->dupctx(src->data); if (dst->data == NULL) { EVP_MAC_CTX_free(dst); return NULL; @@ -72,16 +77,31 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) return dst; } -const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx) +EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx) { return ctx->meth; } size_t EVP_MAC_size(EVP_MAC_CTX *ctx) { - if (ctx->data != NULL) - return ctx->meth->size(ctx->data); - /* If the MAC hasn't been initialized yet, we return zero */ + size_t sz = 0; + + if (ctx->data != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &sz); + if (ctx->meth->get_ctx_params != NULL) { + if (ctx->meth->get_ctx_params(ctx->data, params)) + return sz; + } else if (ctx->meth->get_params != NULL) { + if (ctx->meth->get_params(params)) + return sz; + } + } + /* + * If the MAC hasn't been initialized yet, or there is no size to get, + * we return zero + */ return 0; } @@ -97,101 +117,43 @@ int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen) return ctx->meth->update(ctx->data, data, datalen); } -int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen) +int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize) { - int l = ctx->meth->size(ctx->data); + int l = EVP_MAC_size(ctx); if (l < 0) return 0; - if (poutlen != NULL) - *poutlen = l; + if (outl != NULL) + *outl = l; if (out == NULL) return 1; - return ctx->meth->final(ctx->data, out); + return ctx->meth->final(ctx->data, out, outl, outsize); } -int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...) +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]) { - int ok = -1; - va_list args; - - va_start(args, cmd); - ok = EVP_MAC_vctrl(ctx, cmd, args); - va_end(args); - - if (ok == -2) - EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ok; + if (mac->get_params != NULL) + return mac->get_params(params); + return 1; } -int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args) +int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]) { - int ok = 1; - - if (ctx == NULL || ctx->meth == NULL) - return -2; - - switch (cmd) { -#if 0 - case ...: - /* code */ - ok = 1; - break; -#endif - default: - if (ctx->meth->ctrl != NULL) - ok = ctx->meth->ctrl(ctx->data, cmd, args); - else - ok = -2; - break; - } - - return ok; + if (ctx->meth->get_ctx_params != NULL) + return ctx->meth->get_ctx_params(ctx->data, params); + return 1; } -int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value) +int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]) { - int ok = 1; - - if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) { - EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - - ok = ctx->meth->ctrl_str(ctx->data, type, value); - - if (ok == -2) - EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return ok; -} - -int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value) -{ - size_t len; - - len = strlen(value); - if (len > INT_MAX) - return -1; - return EVP_MAC_ctrl(ctx, cmd, value, len); -} - -int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex) -{ - unsigned char *bin; - long binlen; - int rv = -1; - - bin = OPENSSL_hexstr2buf(hex, &binlen); - if (bin == NULL) - return 0; - if (binlen <= INT_MAX) - rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen); - OPENSSL_free(bin); - return rv; -} - -int EVP_MAC_nid(const EVP_MAC *mac) -{ - return mac->type; + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->data, params); + return 1; } diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c new file mode 100644 index 00000000..8c47a6c6 --- /dev/null +++ b/crypto/evp/mac_meth.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include "internal/evp_int.h" +#include "internal/provider.h" +#include "evp_locl.h" + +static int evp_mac_up_ref(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock); + return 1; +} + +static void evp_mac_free(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + if (mac == NULL) + return; + + CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock); + if (ref > 0) + return; + ossl_provider_free(mac->prov); + CRYPTO_THREAD_lock_free(mac->lock); + OPENSSL_free(mac); +} + +static void *evp_mac_new(void) +{ + EVP_MAC *mac = NULL; + + if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL + || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) { + evp_mac_free(mac); + return NULL; + } + + mac->refcnt = 1; + + return mac; +} + +static void *evp_mac_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *unused) +{ + EVP_MAC *mac = NULL; + int fnmaccnt = 0, fnctxcnt = 0; + + if ((mac = evp_mac_new()) == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + mac->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_MAC_NEWCTX: + if (mac->newctx != NULL) + break; + mac->newctx = OSSL_get_OP_mac_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_DUPCTX: + if (mac->dupctx != NULL) + break; + mac->dupctx = OSSL_get_OP_mac_dupctx(fns); + break; + case OSSL_FUNC_MAC_FREECTX: + if (mac->freectx != NULL) + break; + mac->freectx = OSSL_get_OP_mac_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_INIT: + if (mac->init != NULL) + break; + mac->init = OSSL_get_OP_mac_init(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_UPDATE: + if (mac->update != NULL) + break; + mac->update = OSSL_get_OP_mac_update(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_FINAL: + if (mac->final != NULL) + break; + mac->final = OSSL_get_OP_mac_final(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_GETTABLE_PARAMS: + if (mac->gettable_params != NULL) + break; + mac->gettable_params = + OSSL_get_OP_mac_gettable_params(fns); + break; + case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS: + if (mac->gettable_ctx_params != NULL) + break; + mac->gettable_ctx_params = + OSSL_get_OP_mac_gettable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS: + if (mac->settable_ctx_params != NULL) + break; + mac->settable_ctx_params = + OSSL_get_OP_mac_settable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_GET_PARAMS: + if (mac->get_params != NULL) + break; + mac->get_params = OSSL_get_OP_mac_get_params(fns); + break; + case OSSL_FUNC_MAC_GET_CTX_PARAMS: + if (mac->get_ctx_params != NULL) + break; + mac->get_ctx_params = OSSL_get_OP_mac_get_ctx_params(fns); + break; + case OSSL_FUNC_MAC_SET_CTX_PARAMS: + if (mac->set_ctx_params != NULL) + break; + mac->set_ctx_params = OSSL_get_OP_mac_set_ctx_params(fns); + break; + } + } + if (fnmaccnt != 3 + || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "mac" functions, and a complete set of context + * management functions, as well as the size function. + */ + evp_mac_free(mac); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + mac->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return mac; +} + +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_free); +} + +int EVP_MAC_up_ref(EVP_MAC *mac) +{ + return evp_mac_up_ref(mac); +} + +void EVP_MAC_free(EVP_MAC *mac) +{ + evp_mac_free(mac); +} + +int EVP_MAC_is_a(const EVP_MAC *mac, const char *name) +{ + return evp_is_a(mac->prov, mac->name_id, name); +} + +const char *EVP_MAC_name(const EVP_MAC *mac) +{ + return evp_first_name(mac->prov, mac->name_id); +} + +const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac) +{ + return mac->prov; +} + +const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac) +{ + if (mac->gettable_params == NULL) + return NULL; + return mac->gettable_params(); +} + +const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac) +{ + if (mac->gettable_ctx_params == NULL) + return NULL; + return mac->gettable_ctx_params(); +} + +const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac) +{ + if (mac->settable_ctx_params == NULL) + return NULL; + return mac->settable_ctx_params(); +} + +void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_MAC *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_MAC, + (void (*)(void *, void *))fn, arg, + evp_mac_from_dispatch, NULL, evp_mac_free); +} diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 5237bcaf..7c2f4f06 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -56,39 +56,6 @@ int EVP_add_digest(const EVP_MD *md) return r; } -int EVP_add_mac(const EVP_MAC *m) -{ - int r; - - if (m == NULL) - return 0; - - r = OBJ_NAME_add(OBJ_nid2sn(m->type), OBJ_NAME_TYPE_MAC_METH, - (const char *)m); - if (r == 0) - return 0; - r = OBJ_NAME_add(OBJ_nid2ln(m->type), OBJ_NAME_TYPE_MAC_METH, - (const char *)m); - return r; -} - -/* TODO(3.0) Is this needed after changing to providers? */ -int EVP_add_kdf(const EVP_KDF *k) -{ - int r; - - if (k == NULL) - return 0; - - r = OBJ_NAME_add(OBJ_nid2sn(k->type), OBJ_NAME_TYPE_KDF_METH, - (const char *)k); - if (r == 0) - return 0; - r = OBJ_NAME_add(OBJ_nid2ln(k->type), OBJ_NAME_TYPE_KDF_METH, - (const char *)k); - return r; -} - const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { const EVP_CIPHER *cp; @@ -111,32 +78,8 @@ const EVP_MD *EVP_get_digestbyname(const char *name) return cp; } -const EVP_MAC *EVP_get_macbyname(const char *name) -{ - const EVP_MAC *mp; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL)) - return NULL; - - mp = (const EVP_MAC *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MAC_METH); - return mp; -} - -/* TODO(3.0) Is this API needed after implementing providers? */ -const EVP_KDF *EVP_get_kdfbyname(const char *name) -{ - const EVP_KDF *kdf; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_KDFS, NULL)) - return NULL; - - kdf = (const EVP_KDF *)OBJ_NAME_get(name, OBJ_NAME_TYPE_KDF_METH); - return kdf; -} - void evp_cleanup_int(void) { - OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); @@ -237,48 +180,3 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md, dc.arg = arg; OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); } - -/* TODO(3.0) Are these do_all API's needed for MAC? */ -struct doall_mac { - void *arg; - void (*fn) (const EVP_MAC *ciph, - const char *from, const char *to, void *arg); -}; - -static void do_all_mac_fn(const OBJ_NAME *nm, void *arg) -{ - struct doall_mac *dc = arg; - - if (nm->alias) - dc->fn(NULL, nm->name, nm->data, dc->arg); - else - dc->fn((const EVP_MAC *)nm->data, nm->name, NULL, dc->arg); -} - -void EVP_MAC_do_all(void (*fn) - (const EVP_MAC *ciph, const char *from, const char *to, - void *x), void *arg) -{ - struct doall_mac dc; - - /* Ignore errors */ - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL); - - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc); -} - -void EVP_MAC_do_all_sorted(void (*fn) - (const EVP_MAC *ciph, const char *from, - const char *to, void *x), void *arg) -{ - struct doall_mac dc; - - /* Ignore errors */ - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL); - - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc); -} diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index a7d4cafa..96a72730 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "internal/evp_int.h" #include "evp_locl.h" @@ -23,8 +24,11 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const EVP_MD *digest, int keylen, unsigned char *out) { const char *empty = ""; - int rv = 1; + int rv = 1, mode = 1; + EVP_KDF *kdf; EVP_KDF_CTX *kctx; + const char *mdname = EVP_MD_name(digest); + OSSL_PARAM params[6], *p = params; /* Keep documented behaviour. */ if (pass == NULL) { @@ -36,15 +40,21 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, if (salt == NULL && saltlen == 0) salt = (unsigned char *)empty; - kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2); + kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); if (kctx == NULL) return 0; - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, 1) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, - salt, (size_t)saltlen) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1 + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (char *)pass, (size_t)passlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)salt, saltlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, strlen(mdname) + 1); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) != 1 || EVP_KDF_derive(kctx, out, keylen) != 1) rv = 0; diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index c6ebfe64..5ec519d2 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -20,9 +20,12 @@ #include #include #include +#include +#include #include "internal/asn1_int.h" #include "internal/evp_int.h" +#include "internal/provider.h" static void EVP_PKEY_free_it(EVP_PKEY *x); @@ -318,8 +321,18 @@ 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 + const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL; +# endif + const char *cipher_name = EVP_CIPHER_name(cipher); + const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher); + OPENSSL_CTX *libctx = + prov == NULL ? NULL : ossl_provider_library_context(prov); EVP_PKEY *ret = EVP_PKEY_new(); - EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC); + EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL); + EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL; + OSSL_PARAM params[4]; + size_t paramsn = 0; if (ret == NULL || cmctx == NULL @@ -328,9 +341,22 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, goto err; } - if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0 - || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0 - || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) { +# ifndef OPENSSL_NO_ENGINE + if (engine_id != NULL) + params[paramsn++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + (char *)engine_id, 0); +# endif + + params[paramsn++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + (char *)cipher_name, 0); + params[paramsn++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (char *)priv, len); + params[paramsn] = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_CTX_set_params(cmctx, params)) { EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); goto err; } @@ -341,6 +367,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, err: EVP_PKEY_free(ret); EVP_MAC_CTX_free(cmctx); + EVP_MAC_free(cmac); return NULL; #else EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, @@ -613,6 +640,9 @@ void EVP_PKEY_free(EVP_PKEY *x) 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; diff --git a/crypto/evp/pbe_scrypt.c b/crypto/evp/pbe_scrypt.c index c0ab238e..62b96879 100644 --- a/crypto/evp/pbe_scrypt.c +++ b/crypto/evp/pbe_scrypt.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "internal/numbers.h" #ifndef OPENSSL_NO_SCRYPT @@ -40,7 +41,9 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, { const char *empty = ""; int rv = 1; + EVP_KDF *kdf; EVP_KDF_CTX *kctx; + OSSL_PARAM params[7], *z = params; if (r > UINT32_MAX || p > UINT32_MAX) { EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE); @@ -59,17 +62,23 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); if (kctx == NULL) return 0; - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, - salt, (size_t)saltlen) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, N) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)r) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)p) != 1 - || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem) != 1 + *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (unsigned char *)pass, + passlen); + *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)salt, saltlen); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, &N); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_R, &r); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem); + *z = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) != 1 || EVP_KDF_derive(kctx, key, keylen) != 1) rv = 0; diff --git a/crypto/evp/pkey_kdf.c b/crypto/evp/pkey_kdf.c index f983ad2f..f32d2131 100644 --- a/crypto/evp/pkey_kdf.c +++ b/crypto/evp/pkey_kdf.c @@ -11,131 +11,247 @@ #include #include #include +#include #include +#include +#include +#include #include "internal/numbers.h" #include "internal/evp_int.h" +#define MAX_PARAM 20 + +typedef struct { + EVP_KDF_CTX *kctx; + /* + * EVP_PKEY implementations collect bits of certain data + */ + BUF_MEM *collected_seed; + BUF_MEM *collected_info; +} EVP_PKEY_KDF_CTX; + +static void pkey_kdf_free_collected(EVP_PKEY_KDF_CTX *pkctx) +{ + BUF_MEM_free(pkctx->collected_seed); + pkctx->collected_seed = NULL; + BUF_MEM_free(pkctx->collected_info); + pkctx->collected_info = NULL; +} + static int pkey_kdf_init(EVP_PKEY_CTX *ctx) { + EVP_PKEY_KDF_CTX *pkctx; EVP_KDF_CTX *kctx; + const char *kdf_name = OBJ_nid2sn(ctx->pmeth->pkey_id); + EVP_KDF *kdf; - kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id); - if (kctx == NULL) + pkctx = OPENSSL_zalloc(sizeof(*pkctx)); + if (pkctx == NULL) return 0; - ctx->data = kctx; + kdf = EVP_KDF_fetch(NULL, kdf_name, NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) { + OPENSSL_free(pkctx); + return 0; + } + + pkctx->kctx = kctx; + ctx->data = pkctx; return 1; } static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx) { - EVP_KDF_CTX *kctx = ctx->data; + EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_CTX_free(kctx); + EVP_KDF_CTX_free(pkctx->kctx); + pkey_kdf_free_collected(pkctx); + OPENSSL_free(pkctx); +} + +static int collect(BUF_MEM **collector, void *data, size_t datalen) +{ + size_t i; + + if (*collector == NULL) + *collector = BUF_MEM_new(); + if (*collector == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (data != NULL && datalen > 0) { + i = (*collector)->length; /* BUF_MEM_grow() changes it! */ + + if (!BUF_MEM_grow(*collector, i + datalen)) + return 0; + memcpy((*collector)->data + i, data, datalen); + } + return 1; } static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { - EVP_KDF_CTX *kctx = ctx->data; - uint64_t u64_value; - int cmd; - int ret; + EVP_PKEY_KDF_CTX *pkctx = ctx->data; + EVP_KDF_CTX *kctx = pkctx->kctx; + enum { T_OCTET_STRING, T_UINT64, T_DIGEST, T_INT } cmd; + const char *name, *mdname; + BUF_MEM **collector = NULL; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; switch (type) { case EVP_PKEY_CTRL_PASS: - cmd = EVP_KDF_CTRL_SET_PASS; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_PASSWORD; break; case EVP_PKEY_CTRL_HKDF_SALT: case EVP_PKEY_CTRL_SCRYPT_SALT: - cmd = EVP_KDF_CTRL_SET_SALT; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_SALT; break; case EVP_PKEY_CTRL_TLS_MD: case EVP_PKEY_CTRL_HKDF_MD: - cmd = EVP_KDF_CTRL_SET_MD; + cmd = T_DIGEST; + name = OSSL_KDF_PARAM_DIGEST; break; case EVP_PKEY_CTRL_TLS_SECRET: - cmd = EVP_KDF_CTRL_SET_TLS_SECRET; - ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED); - if (ret < 1) - return ret; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_SECRET; + /* + * Perform the semantics described in + * EVP_PKEY_CTX_add1_tls1_prf_seed(3) + */ + if (ctx->pmeth->pkey_id == NID_tls1_prf) { + BUF_MEM_free(pkctx->collected_seed); + pkctx->collected_seed = NULL; + } break; case EVP_PKEY_CTRL_TLS_SEED: - cmd = EVP_KDF_CTRL_ADD_TLS_SEED; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_SEED; + collector = &pkctx->collected_seed; break; case EVP_PKEY_CTRL_HKDF_KEY: - cmd = EVP_KDF_CTRL_SET_KEY; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_KEY; break; case EVP_PKEY_CTRL_HKDF_INFO: - cmd = EVP_KDF_CTRL_ADD_HKDF_INFO; + cmd = T_OCTET_STRING; + name = OSSL_KDF_PARAM_INFO; + collector = &pkctx->collected_info; break; case EVP_PKEY_CTRL_HKDF_MODE: - cmd = EVP_KDF_CTRL_SET_HKDF_MODE; + cmd = T_INT; + name = OSSL_KDF_PARAM_MODE; break; case EVP_PKEY_CTRL_SCRYPT_N: - cmd = EVP_KDF_CTRL_SET_SCRYPT_N; + cmd = T_UINT64; + name = OSSL_KDF_PARAM_SCRYPT_N; break; case EVP_PKEY_CTRL_SCRYPT_R: - cmd = EVP_KDF_CTRL_SET_SCRYPT_R; + cmd = T_UINT64; /* Range checking occurs on the provider side */ + name = OSSL_KDF_PARAM_SCRYPT_R; break; case EVP_PKEY_CTRL_SCRYPT_P: - cmd = EVP_KDF_CTRL_SET_SCRYPT_P; + cmd = T_UINT64; /* Range checking occurs on the provider side */ + name = OSSL_KDF_PARAM_SCRYPT_P; break; case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: - cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES; + cmd = T_UINT64; + name = OSSL_KDF_PARAM_SCRYPT_MAXMEM; break; default: return -2; } - switch (cmd) { - case EVP_KDF_CTRL_SET_PASS: - case EVP_KDF_CTRL_SET_SALT: - case EVP_KDF_CTRL_SET_KEY: - case EVP_KDF_CTRL_SET_TLS_SECRET: - case EVP_KDF_CTRL_ADD_TLS_SEED: - case EVP_KDF_CTRL_ADD_HKDF_INFO: - return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1); - - case EVP_KDF_CTRL_SET_MD: - return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2); - - case EVP_KDF_CTRL_SET_HKDF_MODE: - return EVP_KDF_ctrl(kctx, cmd, (int)p1); - - case EVP_KDF_CTRL_SET_SCRYPT_R: - case EVP_KDF_CTRL_SET_SCRYPT_P: - u64_value = *(uint64_t *)p2; - if (u64_value > UINT32_MAX) { - EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE); - return 0; + if (collector != NULL) { + switch (cmd) { + case T_OCTET_STRING: + return collect(collector, p2, p1); + default: + OPENSSL_assert("You shouldn't be here"); + break; } - - return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value); - - case EVP_KDF_CTRL_SET_SCRYPT_N: - case EVP_KDF_CTRL_SET_MAXMEM_BYTES: - return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2); - - default: - return 0; + return 1; } + + switch (cmd) { + case T_OCTET_STRING: + params[0] = + OSSL_PARAM_construct_octet_string(name, (unsigned char *)p2, + (size_t)p1); + break; + + case T_DIGEST: + mdname = EVP_MD_name((const EVP_MD *)p2); + params[0] = OSSL_PARAM_construct_utf8_string(name, (char *)mdname, + strlen(mdname) + 1); + break; + + /* + * These are special because the helper macros pass a pointer to the + * stack, so a local copy is required. + */ + case T_INT: + params[0] = OSSL_PARAM_construct_int(name, &p1); + break; + + case T_UINT64: + params[0] = OSSL_PARAM_construct_uint64(name, (uint64_t *)p2); + break; + } + + return EVP_KDF_CTX_set_params(kctx, params); } static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { - EVP_KDF_CTX *kctx = ctx->data; + EVP_PKEY_KDF_CTX *pkctx = ctx->data; + EVP_KDF_CTX *kctx = pkctx->kctx; + const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx); + BUF_MEM **collector = NULL; + const OSSL_PARAM *defs = EVP_KDF_CTX_settable_params(kdf); + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int ok = 0; + /* Deal with ctrl name aliasing */ if (strcmp(type, "md") == 0) - return EVP_KDF_ctrl_str(kctx, "digest", value); - return EVP_KDF_ctrl_str(kctx, type, value); + type = OSSL_KDF_PARAM_DIGEST; + /* scrypt uses 'N', params uses 'n' */ + if (strcmp(type, "N") == 0) + type = OSSL_KDF_PARAM_SCRYPT_N; + + if (!OSSL_PARAM_allocate_from_text(¶ms[0], defs, type, + value, strlen(value))) + return 0; + + /* + * We do the same special casing of seed and info here as in + * pkey_kdf_ctrl() + */ + if (strcmp(params[0].key, OSSL_KDF_PARAM_SEED) == 0) + collector = &pkctx->collected_seed; + else if (strcmp(params[0].key, OSSL_KDF_PARAM_INFO) == 0) + collector = &pkctx->collected_info; + + if (collector != NULL) + ok = collect(collector, params[0].data, params[0].data_size); + else + ok = EVP_KDF_CTX_set_params(kctx, params); + OPENSSL_free(params[0].data); + return ok; } static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx) { - EVP_KDF_CTX *kctx = ctx->data; + EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_reset(kctx); + pkey_kdf_free_collected(pkctx); + if (pkctx->kctx != NULL) + EVP_KDF_reset(pkctx->kctx); return 1; } @@ -146,9 +262,37 @@ static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx) static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { - EVP_KDF_CTX *kctx = ctx->data; + EVP_PKEY_KDF_CTX *pkctx = ctx->data; + EVP_KDF_CTX *kctx = pkctx->kctx; size_t outlen = EVP_KDF_size(kctx); + int r; + if (pkctx->collected_seed != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + pkctx->collected_seed->data, + pkctx->collected_seed->length); + + r = EVP_KDF_CTX_set_params(kctx, params); + pkey_kdf_free_collected(pkctx); + if (!r) + return 0; + } + if (pkctx->collected_info != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + pkctx->collected_info->data, + pkctx->collected_info->length); + + r = EVP_KDF_CTX_set_params(kctx, params); + pkey_kdf_free_collected(pkctx); + if (!r) + return 0; + } if (outlen == 0 || outlen == SIZE_MAX) { /* Variable-output algorithm */ if (key == NULL) diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c index fafe3c96..1343e19e 100644 --- a/crypto/evp/pkey_mac.c +++ b/crypto/evp/pkey_mac.c @@ -7,8 +7,12 @@ * https://www.openssl.org/source/license.html */ +#include #include #include +#include +#include +#include #include "internal/evp_int.h" #include "evp_locl.h" @@ -40,18 +44,21 @@ typedef struct { } raw_data; } MAC_PKEY_CTX; +static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); + static int pkey_mac_init(EVP_PKEY_CTX *ctx) { MAC_PKEY_CTX *hctx; + /* We're being smart and using the same base NIDs for PKEY and for MAC */ int nid = ctx->pmeth->pkey_id; + EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL); if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE); return 0; } - /* We're being smart and using the same base NIDs for PKEY and for MAC */ - hctx->ctx = EVP_MAC_CTX_new_id(nid); + hctx->ctx = EVP_MAC_CTX_new(mac); if (hctx->ctx == NULL) { OPENSSL_free(hctx); return 0; @@ -64,14 +71,13 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx) hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING; } + pkey_mac_cleanup(ctx); EVP_PKEY_CTX_set_data(ctx, hctx); ctx->keygen_info_count = 0; return 1; } -static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); - static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { MAC_PKEY_CTX *sctx, *dctx; @@ -93,6 +99,17 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) if (dctx->ctx == NULL) goto err; + /* + * Normally, nothing special would be done with the MAC method. In + * this particular case, though, the MAC method was fetched internally + * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed + * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX + * fetches the MAC method anew in this case. Therefore, its reference + * count must be adjusted here. + */ + if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx))) + goto err; + dctx->type = sctx->type; switch (dctx->type) { @@ -117,9 +134,16 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) { - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); + /* + * For the exact same reasons the MAC reference count is incremented + * in pkey_mac_copy() above, it must be explicitly freed here. + */ + + MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx); if (hctx != NULL) { + EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx); + switch (hctx->type) { case MAC_TYPE_RAW: OPENSSL_clear_free(hctx->raw_data.ktmp.data, @@ -127,6 +151,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) break; } EVP_MAC_CTX_free(hctx->ctx); + EVP_MAC_free(mac); OPENSSL_free(hctx); EVP_PKEY_CTX_set_data(ctx, NULL); } @@ -156,6 +181,8 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) if (cmkey == NULL) return 0; + if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx))) + return 0; EVP_PKEY_assign(pkey, nid, cmkey); } break; @@ -194,25 +221,34 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0; if (set_key) { - if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)) - != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx))) + if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx), + OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))))) return 0; key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); if (key == NULL) return 0; } - /* Some MACs don't support this control... that's fine */ - EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS, - EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); EVP_MD_CTX_set_update_fn(mctx, int_update); - if (set_key) - rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data, - key->length); - return rv > 0; + /* Some MACs don't support this control... that's fine */ + { + OSSL_PARAM params[3]; + size_t params_n = 0; + int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT); + + /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */ + params[params_n++] = + OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags); + if (set_key) + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + key->data, key->length); + params[params_n++] = OSSL_PARAM_construct_end(); + rv = EVP_MAC_CTX_set_params(hctx->ctx, params); + } + return rv; } static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, @@ -220,7 +256,7 @@ static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - return EVP_MAC_final(hctx->ctx, sig, siglen); + return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx)); } static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -235,14 +271,24 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return -2; /* The raw types don't support ciphers */ case MAC_TYPE_MAC: { - int rv; + OSSL_PARAM params[3]; + size_t params_n = 0; + char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2)); +#ifndef OPENSSL_NO_ENGINE + char *engineid = (char *)ENGINE_get_id(ctx->engine); - if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE, - ctx->engine)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER, - p2)) <= 0 - || !(rv = EVP_MAC_init(hctx->ctx))) - return rv; + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + engineid, 0); +#endif + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + ciphname, 0); + params[params_n] = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_CTX_set_params(hctx->ctx, params) + || !EVP_MAC_init(hctx->ctx)) + return 0; } break; default: @@ -276,8 +322,40 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) break; case EVP_PKEY_CTRL_SET_DIGEST_SIZE: - return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1); + { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t size = (size_t)p1; + size_t verify = 0; + /* + * We verify that the length is actually set by getting back + * the same parameter and checking that it matches what we + * tried to set. + * TODO(3.0) when we have a more direct mechanism to check if + * a parameter was used, we must refactor this to use that. + */ + + params[0] = + OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size); + + if (!EVP_MAC_CTX_set_params(hctx->ctx, params)) + return 0; + + params[0] = + OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify); + + if (!EVP_MAC_CTX_get_params(hctx->ctx, params)) + return 0; + + /* + * Since EVP_MAC_CTX_{get,set}_params() returned successfully, + * we can only assume that the size was ignored, i.e. this + * control is unsupported. + */ + if (verify != size) + return -2; + } + break; case EVP_PKEY_CTRL_SET_MAC_KEY: switch (hctx->type) { case MAC_TYPE_RAW: @@ -287,8 +365,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 0; break; case MAC_TYPE_MAC: - if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0) - return 0; + { + OSSL_PARAM params[2]; + size_t params_n = 0; + + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + p2, p1); + params[params_n] = OSSL_PARAM_construct_end(); + + return EVP_MAC_CTX_set_params(hctx->ctx, params); + } break; default: /* This should be dead code */ @@ -303,17 +390,31 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (!EVP_MAC_init(hctx->ctx)) return 0; { - int rv; ASN1_OCTET_STRING *key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; + OSSL_PARAM params[4]; + size_t params_n = 0; + char *mdname = + (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md)); +#ifndef OPENSSL_NO_ENGINE + char *engineid = ctx->engine == NULL + ? NULL : (char *)ENGINE_get_id(ctx->engine); - if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE, - ctx->engine)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD, - hctx->raw_data.md)) <= 0 - || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, - key->data, key->length)) <= 0) - return rv; + if (engineid != NULL) { + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE, + engineid, 0); + } +#endif + params[params_n++] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + mdname, 0); + params[params_n++] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + key->data, key->length); + params[params_n] = OSSL_PARAM_construct_end(); + + return EVP_MAC_CTX_set_params(hctx->ctx, params); } break; case MAC_TYPE_MAC: @@ -335,8 +436,32 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); + const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx); + OSSL_PARAM params[2]; + int ok = 0; - return EVP_MAC_ctrl_str(hctx->ctx, type, value); + /* + * Translation of some control names that are equivalent to a single + * parameter name. + * + * "md" and "digest" are the same thing, we use the single "digest" + * + * "digestsize" was a setting control in siphash, but naming wise, + * it's really the same as "size". + */ + if (strcmp(type, "md") == 0) + type = OSSL_MAC_PARAM_DIGEST; + else if (strcmp(type, "digestsize") == 0) + type = OSSL_MAC_PARAM_SIZE; + + if (!OSSL_PARAM_allocate_from_text(¶ms[0], + EVP_MAC_CTX_settable_params(mac), + type, value, strlen(value) + 1)) + return 0; + params[1] = OSSL_PARAM_construct_end(); + ok = EVP_MAC_CTX_set_params(hctx->ctx, params); + OPENSSL_free(params[0].data); + return ok; } const EVP_PKEY_METHOD cmac_pkey_meth = { diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c index 187f7a68..34db4863 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/pmeth_fn.c @@ -9,126 +9,483 @@ #include #include -#include "internal/cryptlib.h" #include #include +#include "internal/cryptlib.h" #include "internal/evp_int.h" +#include "internal/provider.h" +#include "evp_locl.h" -#define M_check_autoarg(ctx, arg, arglen, err) \ - if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ - size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ - \ - if (pksize == 0) { \ - EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ - return 0; \ - } \ - if (!arg) { \ - *arglen = pksize; \ - return 1; \ - } \ - if (*arglen < pksize) { \ - EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ - return 0; \ - } \ +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 gparamfncnt = 0, sparamfncnt = 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_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; + } + } + if (ctxfncnt != 2 + || (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 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 + * "signature" functions: (sign_init, sign) or (verify_init verify) or + * (verify_recover_init, verify_recover). 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 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); +} + +static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature, + int operation) +{ + int ret = 0; + void *provkey = 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->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; + + /* + * TODO(3.0): Check for legacy handling. Remove this once all all + * algorithms are moved to providers. + */ + 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 (signature == NULL) { + EVPerr(0, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + + ctx->op.sig.signature = signature; + if (ctx->pkey != NULL) { + provkey = evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt); + if (provkey == NULL) { + EVPerr(0, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + 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_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) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_SIGN; - if (!ctx->pmeth->sign_init) - return 1; - ret = ctx->pmeth->sign_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + 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) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + 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(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); + 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) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFY; - if (!ctx->pmeth->verify_init) - return 1; - ret = ctx->pmeth->verify_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + 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) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + 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(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); + 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) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; - if (!ctx->pmeth->verify_recover_init) - return 1; - ret = ctx->pmeth->verify_recover_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + 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) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + 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(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); + 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); } @@ -200,98 +557,3 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); } - -int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DERIVE; - if (!ctx->pmeth->derive_init) - return 1; - ret = ctx->pmeth->derive_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) -{ - int ret; - if (!ctx || !ctx->pmeth - || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) - || !ctx->pmeth->ctrl) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE - && ctx->operation != EVP_PKEY_OP_ENCRYPT - && ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); - - if (ret <= 0) - return ret; - - if (ret == 2) - return 1; - - if (!ctx->pkey) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); - return -1; - } - - if (ctx->pkey->type != peer->type) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); - return -1; - } - - /* - * For clarity. The error is if parameters in peer are - * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return - * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 - * (different key types) is impossible here because it is checked earlier. - * -2 is OK for us here, as well as 1, so we can check for 0 only. - */ - if (!EVP_PKEY_missing_parameters(peer) && - !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); - return -1; - } - - EVP_PKEY_free(ctx->peerkey); - ctx->peerkey = peer; - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); - - if (ret <= 0) { - ctx->peerkey = NULL; - return ret; - } - - EVP_PKEY_up_ref(peer); - return 1; -} - -int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) - return ctx->pmeth->derive(ctx, key, pkeylen); -} diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 28fa047a..2be51f15 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -1,3 +1,4 @@ + /* * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. * @@ -9,13 +10,17 @@ #include #include -#include "internal/cryptlib.h" #include #include #include +#include +#include +#include "internal/cryptlib.h" #include "internal/asn1_int.h" #include "internal/evp_int.h" #include "internal/numbers.h" +#include "internal/provider.h" +#include "evp_locl.h" typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); @@ -103,8 +108,17 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { EVP_PKEY_CTX *ret; - const EVP_PKEY_METHOD *pmeth; + const EVP_PKEY_METHOD *pmeth = NULL; + /* + * When using providers, the context is bound to the algo implementation + * later. + */ + if (pkey == NULL && e == NULL && id == -1) + goto common; + + /* TODO(3.0) Legacy code should be removed when all is provider based */ + /* BEGIN legacy */ if (id == -1) { if (pkey == NULL) return 0; @@ -140,7 +154,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); return NULL; } + /* END legacy */ + common: ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { #ifndef OPENSSL_NO_ENGINE @@ -156,7 +172,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) if (pkey != NULL) EVP_PKEY_up_ref(pkey); - if (pmeth->init) { + if (pmeth != NULL && pmeth->init != NULL) { if (pmeth->init(ret) <= 0) { ret->pmeth = NULL; EVP_PKEY_CTX_free(ret); @@ -167,6 +183,19 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) return ret; } +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 (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); + } +} + EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) { EVP_PKEY_METHOD *pmeth; @@ -253,7 +282,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) { EVP_PKEY_CTX *rctx; - if (!pctx->pmeth || !pctx->pmeth->copy) + + if (((pctx->pmeth == NULL) || (pctx->pmeth->copy == NULL)) + && ((EVP_PKEY_CTX_IS_DERIVE_OP(pctx) + && pctx->op.kex.exchprovctx == NULL) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx) + && pctx->op.sig.sigprovctx == NULL))) return NULL; #ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a pkey context using an ENGINE */ @@ -262,31 +296,68 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) return 0; } #endif - rctx = OPENSSL_malloc(sizeof(*rctx)); + rctx = OPENSSL_zalloc(sizeof(*rctx)); if (rctx == NULL) { EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE); return NULL; } + if (pctx->pkey != NULL) + EVP_PKEY_up_ref(pctx->pkey); + rctx->pkey = pctx->pkey; + rctx->operation = pctx->operation; + + if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) { + if (pctx->op.kex.exchange != NULL) { + rctx->op.kex.exchange = pctx->op.kex.exchange; + if (!EVP_KEYEXCH_up_ref(rctx->op.kex.exchange)) { + OPENSSL_free(rctx); + return NULL; + } + } + if (pctx->op.kex.exchprovctx != NULL) { + if (!ossl_assert(pctx->op.kex.exchange != NULL)) + return NULL; + rctx->op.kex.exchprovctx + = pctx->op.kex.exchange->dupctx(pctx->op.kex.exchprovctx); + if (rctx->op.kex.exchprovctx == NULL) { + EVP_KEYEXCH_free(rctx->op.kex.exchange); + OPENSSL_free(rctx); + return NULL; + } + return rctx; + } + } else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) { + if (pctx->op.sig.signature != NULL) { + rctx->op.sig.signature = pctx->op.sig.signature; + if (!EVP_SIGNATURE_up_ref(rctx->op.sig.signature)) { + OPENSSL_free(rctx); + return NULL; + } + } + if (pctx->op.sig.sigprovctx != NULL) { + if (!ossl_assert(pctx->op.sig.signature != NULL)) + return NULL; + rctx->op.sig.sigprovctx + = pctx->op.sig.signature->dupctx(pctx->op.sig.sigprovctx); + if (rctx->op.sig.sigprovctx == NULL) { + EVP_SIGNATURE_free(rctx->op.sig.signature); + OPENSSL_free(rctx); + return NULL; + } + return rctx; + } + } + rctx->pmeth = pctx->pmeth; #ifndef OPENSSL_NO_ENGINE rctx->engine = pctx->engine; #endif - if (pctx->pkey) - EVP_PKEY_up_ref(pctx->pkey); - - rctx->pkey = pctx->pkey; - if (pctx->peerkey) EVP_PKEY_up_ref(pctx->peerkey); - rctx->peerkey = pctx->peerkey; - rctx->data = NULL; - rctx->app_data = NULL; - rctx->operation = pctx->operation; - if (pctx->pmeth->copy(rctx, pctx) > 0) return rctx; @@ -355,6 +426,9 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) 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 @@ -363,12 +437,188 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) 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) +{ + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchprovctx != NULL + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->set_ctx_params != NULL) + return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx, + params); + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx != NULL + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->set_ctx_params != NULL) + return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx, + params); + return 0; +} + +const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) +{ + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->settable_ctx_params != NULL) + return ctx->op.kex.exchange->settable_ctx_params(); + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->settable_ctx_params != NULL) + return ctx->op.sig.signature->settable_ctx_params(); + + return NULL; +} + +#ifndef OPENSSL_NO_DH +int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) +{ + OSSL_PARAM dh_pad_params[2]; + unsigned int upad = pad; + + /* We use EVP_PKEY_CTX_ctrl return values */ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_PAD, pad, NULL); + + dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad); + dh_pad_params[1] = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, dh_pad_params); +} +#endif + +int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + OSSL_PARAM sig_md_params[3], *p = sig_md_params; + /* 80 should be big enough */ + char name[80] = ""; + const EVP_MD *tmp; + + if (ctx == NULL || !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; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.sig.sigprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_MD, 0, (void *)(md)); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + name, + sizeof(name)); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params)) + return 0; + + tmp = EVP_get_digestbyname(name); + if (tmp == NULL) + return 0; + + *md = tmp; + + return 1; +} + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + OSSL_PARAM sig_md_params[3], *p = sig_md_params; + size_t mdsize; + const char *name; + + if (ctx == NULL || !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; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.sig.sigprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_MD, 0, (void *)(md)); + + if (md == NULL) { + name = ""; + mdsize = 0; + } else { + mdsize = EVP_MD_size(md); + name = EVP_MD_name(md); + } + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)name, + strlen(name) + 1); + *p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, + &mdsize); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, sig_md_params); +} + +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 + case EVP_PKEY_CTRL_DH_PAD: + return EVP_PKEY_CTX_set_dh_pad(ctx, p1); +#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); + } + return 0; +} + int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + if (ctx == NULL) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + 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)) + return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2); + + if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) { EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); return -2; } @@ -404,9 +654,48 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value); } +static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, + const char *value) +{ +#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 + if (strcmp(name, "digest") == 0) { + int ret; + EVP_MD *md; + + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) || ctx->op.sig.signature == NULL) + return 0; + md = EVP_MD_fetch(ossl_provider_library_context(ctx->op.sig.signature->prov), + value, NULL); + if (md == NULL) + return 0; + ret = EVP_PKEY_CTX_set_signature_md(ctx, md); + EVP_MD_meth_free(md); + return ret; + } + + return 0; +} + int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value) { + if (ctx == NULL) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + 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)) + return legacy_ctrl_str_to_param(ctx, name, value); + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); return -2; diff --git a/crypto/ex_data.c b/crypto/ex_data.c index d7d0d5a7..cd8e6958 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -49,8 +49,8 @@ static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index) return NULL; } - ip = &global->ex_data[class_index]; CRYPTO_THREAD_write_lock(global->ex_data_lock); + ip = &global->ex_data[class_index]; return ip; } @@ -421,7 +421,7 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, if (f->new_func == NULL) return 0; - f->new_func(obj, curval, ad, idx, f->argl, f->argp); + f->new_func(obj, NULL, ad, idx, f->argl, f->argp); return 1; } diff --git a/crypto/gmac/build.info b/crypto/gmac/build.info deleted file mode 100644 index 6d9f22e2..00000000 --- a/crypto/gmac/build.info +++ /dev/null @@ -1,2 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=gmac.c diff --git a/crypto/gmac/gmac.c b/crypto/gmac/gmac.c deleted file mode 100644 index 0e2eda38..00000000 --- a/crypto/gmac/gmac.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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 -#include "internal/cryptlib.h" -#include "internal/evp_int.h" - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - EVP_CIPHER *cipher; /* Cache GCM cipher */ - EVP_CIPHER_CTX *ctx; /* Cipher context */ - ENGINE *engine; /* Engine implementating the algorithm */ -}; - -static void gmac_free(EVP_MAC_IMPL *gctx) -{ - if (gctx != NULL) { - EVP_CIPHER_CTX_free(gctx->ctx); - OPENSSL_free(gctx); - } -} - -static EVP_MAC_IMPL *gmac_new(void) -{ - EVP_MAC_IMPL *gctx; - - if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL - || (gctx->ctx = EVP_CIPHER_CTX_new()) == NULL) { - gmac_free(gctx); - return NULL; - } - return gctx; -} - -static EVP_MAC_IMPL *gmac_dup(const EVP_MAC_IMPL *gsrc) -{ - EVP_MAC_IMPL *gdst; - - gdst = gmac_new(); - if (gdst == NULL) - return NULL; - - if (!EVP_CIPHER_CTX_copy(gdst->ctx, gsrc->ctx)) { - gmac_free(gdst); - return NULL; - } - - gdst->cipher = gsrc->cipher; - gdst->engine = gsrc->engine; - - return gdst; -} - -static size_t gmac_size(EVP_MAC_IMPL *gctx) -{ - return EVP_GCM_TLS_TAG_LEN; -} - -static int gmac_init(EVP_MAC_IMPL *gctx) -{ - return 1; -} - -static int gmac_update(EVP_MAC_IMPL *gctx, const unsigned char *data, - size_t datalen) -{ - EVP_CIPHER_CTX *ctx = gctx->ctx; - int outlen; - - while (datalen > INT_MAX) { - if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX)) - return 0; - data += INT_MAX; - datalen -= INT_MAX; - } - return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen); -} - -static int gmac_final(EVP_MAC_IMPL *gctx, unsigned char *out) -{ - int hlen; - - if (!EVP_EncryptFinal_ex(gctx->ctx, out, &hlen) - || !EVP_CIPHER_CTX_ctrl(gctx->ctx, EVP_CTRL_AEAD_GET_TAG, - gmac_size(gctx), out)) - return 0; - return 1; -} - -static int gmac_ctrl(EVP_MAC_IMPL *gctx, int cmd, va_list args) -{ - const unsigned char *p; - size_t len; - EVP_CIPHER_CTX *ctx = gctx->ctx; - const EVP_CIPHER *cipher; - ENGINE *engine; - - switch (cmd) { - case EVP_MAC_CTRL_SET_CIPHER: - cipher = va_arg(args, const EVP_CIPHER *); - if (cipher == NULL) - return 0; - if (EVP_CIPHER_mode(cipher) != EVP_CIPH_GCM_MODE) { - EVPerr(EVP_F_GMAC_CTRL, EVP_R_CIPHER_NOT_GCM_MODE); - return 0; - } - return EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL); - - case EVP_MAC_CTRL_SET_KEY: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (len != (size_t)EVP_CIPHER_CTX_key_length(ctx)) { - EVPerr(EVP_F_GMAC_CTRL, EVP_R_INVALID_KEY_LENGTH); - return 0; - } - return EVP_EncryptInit_ex(ctx, NULL, NULL, p, NULL); - - case EVP_MAC_CTRL_SET_IV: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL) - && EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p); - - case EVP_MAC_CTRL_SET_ENGINE: - engine = va_arg(args, ENGINE *); - return EVP_EncryptInit_ex(ctx, NULL, engine, NULL, NULL); - - default: - return -2; - } -} - -static int gmac_ctrl_int(EVP_MAC_IMPL *gctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = gmac_ctrl(gctx, cmd, args); - va_end(args); - - return rv; -} - -static int gmac_ctrl_str_cb(void *gctx, int cmd, void *buf, size_t buflen) -{ - return gmac_ctrl_int(gctx, cmd, buf, buflen); -} - -static int gmac_ctrl_str(EVP_MAC_IMPL *gctx, const char *type, - const char *value) -{ - if (!value) - return 0; - if (strcmp(type, "cipher") == 0) { - const EVP_CIPHER *c = EVP_get_cipherbyname(value); - - if (c == NULL) - return 0; - return gmac_ctrl_int(gctx, EVP_MAC_CTRL_SET_CIPHER, c); - } - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "iv") == 0) - return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV, - value); - if (strcmp(type, "hexiv") == 0) - return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV, - value); - return -2; -} - -const EVP_MAC gmac_meth = { - EVP_MAC_GMAC, - gmac_new, - gmac_dup, - gmac_free, - gmac_size, - gmac_init, - gmac_update, - gmac_final, - gmac_ctrl, - gmac_ctrl_str -}; diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info index b1c14618..56ad67ef 100644 --- a/crypto/hmac/build.info +++ b/crypto/hmac/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto -$COMMON=hmac.c hm_meth.c +$COMMON=hmac.c SOURCE[../../libcrypto]=$COMMON hm_ameth.c SOURCE[../../providers/fips]=$COMMON diff --git a/crypto/hmac/hm_meth.c b/crypto/hmac/hm_meth.c deleted file mode 100644 index 19278ef6..00000000 --- a/crypto/hmac/hm_meth.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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 -#include -#include -#include -#include "internal/evp_int.h" - -/* local HMAC context structure */ - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - /* tmpmd and tmpengine are set to NULL after a CMAC_Init call */ - const EVP_MD *tmpmd; /* HMAC digest */ - const ENGINE *tmpengine; /* HMAC digest engine */ - HMAC_CTX *ctx; /* HMAC context */ -}; - -static EVP_MAC_IMPL *hmac_new(void) -{ - EVP_MAC_IMPL *hctx; - - if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL - || (hctx->ctx = HMAC_CTX_new()) == NULL) { - OPENSSL_free(hctx); - return NULL; - } - - return hctx; -} - -static void hmac_free(EVP_MAC_IMPL *hctx) -{ - if (hctx != NULL) { - HMAC_CTX_free(hctx->ctx); - OPENSSL_free(hctx); - } -} - -static EVP_MAC_IMPL *hmac_dup(const EVP_MAC_IMPL *hsrc) -{ - EVP_MAC_IMPL *hdst; - - hdst = hmac_new(); - if (hdst == NULL) - return NULL; - - if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx)) { - hmac_free(hdst); - return NULL; - } - - hdst->tmpengine = hsrc->tmpengine; - hdst->tmpmd = hsrc->tmpmd; - - return hdst; -} - -static size_t hmac_size(EVP_MAC_IMPL *hctx) -{ - return HMAC_size(hctx->ctx); -} - -static int hmac_init(EVP_MAC_IMPL *hctx) -{ - int rv = 1; - - /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */ - if (hctx->tmpmd != NULL) - rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd, - (ENGINE * )hctx->tmpengine); - hctx->tmpengine = NULL; - hctx->tmpmd = NULL; - return rv; -} - -static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data, - size_t datalen) -{ - return HMAC_Update(hctx->ctx, data, datalen); -} - -static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out) -{ - unsigned int hlen; - - return HMAC_Final(hctx->ctx, out, &hlen); -} - -static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args) -{ - switch (cmd) { - case EVP_MAC_CTRL_SET_FLAGS: - { - unsigned long flags = va_arg(args, unsigned long); - - HMAC_CTX_set_flags(hctx->ctx, flags); - } - break; - case EVP_MAC_CTRL_SET_KEY: - { - const unsigned char *key = va_arg(args, const unsigned char *); - size_t keylen = va_arg(args, size_t); - int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd, - (ENGINE *)hctx->tmpengine); - - hctx->tmpengine = NULL; - hctx->tmpmd = NULL; - return rv; - } - break; - case EVP_MAC_CTRL_SET_MD: - hctx->tmpmd = va_arg(args, const EVP_MD *); - break; - case EVP_MAC_CTRL_SET_ENGINE: - hctx->tmpengine = va_arg(args, const ENGINE *); - break; - default: - return -2; - - } - return 1; -} - -static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = hmac_ctrl(hctx, cmd, args); - va_end(args); - - return rv; -} - -static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen) -{ - return hmac_ctrl_int(hctx, cmd, buf, buflen); -} - -static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type, - const char *value) -{ - if (!value) - return 0; -#ifndef FIPS_MODE - /* - * We don't have EVP_get_digestbyname() in FIPS_MODE. That function returns - * an EVP_MD without an associated provider implementation (i.e. it is - * using "implicit fetch"). We could replace it with an "explicit" fetch - * using EVP_MD_fetch(), but we'd then be required to free the returned - * EVP_MD somewhere. Probably the complexity isn't worth it as we are - * unlikely to need this ctrl in FIPS_MODE anyway. - */ - if (strcmp(type, "digest") == 0) { - const EVP_MD *d = EVP_get_digestbyname(value); - - if (d == NULL) - return 0; - return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d); - } -#endif - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY, - value); - return -2; -} - -const EVP_MAC hmac_meth = { - EVP_MAC_HMAC, - hmac_new, - hmac_dup, - hmac_free, - hmac_size, - hmac_init, - hmac_update, - hmac_final, - hmac_ctrl, - hmac_ctrl_str -}; diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index 5d934e95..d392753c 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -39,7 +39,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, * The HMAC construction is not allowed to be used with the * extendable-output functions (XOF) shake128 and shake256. */ - if ((EVP_MD_meth_get_flags(md) & EVP_MD_FLAG_XOF) != 0) + if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0) return 0; if (key != NULL) { diff --git a/crypto/include/internal/asn1_dsa.h b/crypto/include/internal/asn1_dsa.h new file mode 100644 index 00000000..d2570516 --- /dev/null +++ b/crypto/include/internal/asn1_dsa.h @@ -0,0 +1,23 @@ +/* + * 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 HEADER_ASN1_DSA_H +# define HEADER_ASN1_DSA_H + +#include "internal/packet.h" + +int encode_der_length(WPACKET *pkt, size_t cont_len); +int encode_der_integer(WPACKET *pkt, const BIGNUM *n); +int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s); +int decode_der_length(PACKET *pkt, PACKET *subpkt); +int decode_der_integer(PACKET *pkt, BIGNUM *n); +size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, + size_t len); + +#endif diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h index 1f62063b..674fa704 100644 --- a/crypto/include/internal/asn1_int.h +++ b/crypto/include/internal/asn1_int.h @@ -63,6 +63,14 @@ struct evp_pkey_asn1_method_st { int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len); int (*get_priv_key) (const EVP_PKEY *pk, unsigned char *priv, size_t *len); int (*get_pub_key) (const EVP_PKEY *pk, unsigned char *pub, size_t *len); + + /* + * TODO: Make sure these functions are defined for key types that are + * implemented in providers. + */ + /* Exports to providers */ + size_t (*dirty_cnt) (const EVP_PKEY *pk); + void *(*export_to) (const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); } /* EVP_PKEY_ASN1_METHOD */ ; DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD) diff --git a/crypto/include/internal/bn_int.h b/crypto/include/internal/bn_int.h index 4fcbb145..cb8b1766 100644 --- a/crypto/include/internal/bn_int.h +++ b/crypto/include/internal/bn_int.h @@ -110,4 +110,5 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, const BIGNUM *r1, const BIGNUM *r2, int nlen, const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); +OPENSSL_CTX *bn_get_lib_ctx(BN_CTX *ctx); #endif diff --git a/crypto/include/internal/chacha.h b/crypto/include/internal/chacha.h index 7e79e121..e095522c 100644 --- a/crypto/include/internal/chacha.h +++ b/crypto/include/internal/chacha.h @@ -35,8 +35,8 @@ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, ((unsigned int)(p)[0]) | ((unsigned int)(p)[1]<<8) | \ ((unsigned int)(p)[2]<<16) | ((unsigned int)(p)[3]<<24) ) -#define CHACHA_KEY_SIZE 32 -#define CHACHA_CTR_SIZE 16 -#define CHACHA_BLK_SIZE 64 +#define CHACHA_KEY_SIZE 32 +#define CHACHA_CTR_SIZE 16 +#define CHACHA_BLK_SIZE 64 #endif diff --git a/crypto/include/internal/ciphermode_platform.h b/crypto/include/internal/ciphermode_platform.h new file mode 100644 index 00000000..a99ce0d4 --- /dev/null +++ b/crypto/include/internal/ciphermode_platform.h @@ -0,0 +1,444 @@ +/* + * 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 HEADER_INTERNAL_CIPHERMODE_PLATFORM_H +# define HEADER_INTERNAL_CIPHERMODE_PLATFORM_H + +# include "openssl/aes.h" + +# ifdef VPAES_ASM +int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +void vpaes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void vpaes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void vpaes_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); +# endif /* VPAES_ASM */ + +# ifdef BSAES_ASM +void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); +void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +# endif /* BSAES_ASM */ + +# ifdef AES_CTR_ASM +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char ivec[AES_BLOCK_SIZE]); +# endif /* AES_CTR_ASM */ + +# ifdef AES_XTS_ASM +void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +# endif /* AES_XTS_ASM */ + +# if defined(OPENSSL_CPUID_OBJ) +# if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) +# include "ppc_arch.h" +# ifdef VPAES_ASM +# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) +# endif +# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) +# define HWAES_set_encrypt_key aes_p8_set_encrypt_key +# define HWAES_set_decrypt_key aes_p8_set_decrypt_key +# define HWAES_encrypt aes_p8_encrypt +# define HWAES_decrypt aes_p8_decrypt +# define HWAES_cbc_encrypt aes_p8_cbc_encrypt +# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks +# define HWAES_xts_encrypt aes_p8_xts_encrypt +# define HWAES_xts_decrypt aes_p8_xts_decrypt +# endif /* PPC */ + +# if (defined(__arm__) || defined(__arm) || defined(__aarch64__)) +# include "arm_arch.h" +# if __ARM_MAX_ARCH__>=7 +# if defined(BSAES_ASM) +# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) +# endif +# if defined(VPAES_ASM) +# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) +# endif +# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) +# define HWAES_set_encrypt_key aes_v8_set_encrypt_key +# define HWAES_set_decrypt_key aes_v8_set_decrypt_key +# define HWAES_encrypt aes_v8_encrypt +# define HWAES_decrypt aes_v8_decrypt +# define HWAES_cbc_encrypt aes_v8_cbc_encrypt +# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks +# endif +# endif +# endif /* OPENSSL_CPUID_OBJ */ + +# if defined(AES_ASM) && !defined(I386_ONLY) && ( \ + ((defined(__i386) || defined(__i386__) || \ + defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) ) + +/* AES-NI section */ + +# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) +# ifdef VPAES_ASM +# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif +# ifdef BSAES_ASM +# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aesni_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void aesni_ecb_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); +# ifndef OPENSSL_NO_OCB +void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); +void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); +# endif /* OPENSSL_NO_OCB */ + +void aesni_ctr32_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, const unsigned char *ivec); + +void aesni_xts_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_ccm64_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void aesni_ccm64_decrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +size_t aesni_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); +size_t aesni_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); +void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, size_t len); + +# define AES_GCM_ASM(ctx) (ctx->ctr == aesni_ctr32_encrypt_blocks && \ + ctx->gcm.ghash == gcm_ghash_avx) +# endif + + +# elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) + +/* Fujitsu SPARC64 X support */ +extern unsigned int OPENSSL_sparcv9cap_P[]; +# include "sparc_arch.h" + +# ifndef OPENSSL_NO_CAMELLIA +# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) +# include "openssl/camellia.h" + +void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); +void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const CAMELLIA_KEY *key, + unsigned char *ivec); +# endif /* OPENSSL_NO_CAMELLIA */ + + +# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) +# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) +# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX) +# define HWAES_set_encrypt_key aes_fx_set_encrypt_key +# define HWAES_set_decrypt_key aes_fx_set_decrypt_key +# define HWAES_encrypt aes_fx_encrypt +# define HWAES_decrypt aes_fx_decrypt +# define HWAES_cbc_encrypt aes_fx_cbc_encrypt +# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks + +void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks); +void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks); +void aes_t4_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aes_t4_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +/* + * Key-length specific subroutines were chosen for following reason. + * Each SPARC T4 core can execute up to 8 threads which share core's + * resources. Loading as much key material to registers allows to + * minimize references to shared memory interface, as well as amount + * of instructions in inner loops [much needed on T4]. But then having + * non-key-length specific routines would require conditional branches + * either in inner loops or on subroutines' entries. Former is hardly + * acceptable, while latter means code size increase to size occupied + * by multiple key-length specific subroutines, so why fight? + */ +void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); + +# ifndef OPENSSL_NO_DES +# include +void des_t4_key_expand(const void *key, DES_key_schedule *ks); +void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); +void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); +# endif /* OPENSSL_NO_DES */ + +# elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__) +/* IBM S390X support */ +# include "s390x_arch.h" + + +/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ +# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6)) + +/* Most modes of operation need km for partial block processing. */ +# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ + S390X_CAPBIT(S390X_AES_128)) +# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ + S390X_CAPBIT(S390X_AES_192)) +# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ + S390X_CAPBIT(S390X_AES_256)) + +# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */ +# define S390X_aes_192_cbc_CAPABLE 1 +# define S390X_aes_256_cbc_CAPABLE 1 + +# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE +# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE +# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE + +# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE && \ + (OPENSSL_s390xcap_P.kmo[0] & \ + S390X_CAPBIT(S390X_AES_128))) +# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE && \ + (OPENSSL_s390xcap_P.kmo[0] & \ + S390X_CAPBIT(S390X_AES_192))) +# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE && \ + (OPENSSL_s390xcap_P.kmo[0] & \ + S390X_CAPBIT(S390X_AES_256))) + +# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE && \ + (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_128))) +# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE && \ + (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_192))) +# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE && \ + (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_256))) +# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_128)) +# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_192)) +# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ + S390X_CAPBIT(S390X_AES_256)) +# define S390X_aes_128_cfb1_CAPABLE 0 +# define S390X_aes_192_cfb1_CAPABLE 0 +# define S390X_aes_256_cfb1_CAPABLE 0 + +# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */ +# define S390X_aes_192_ctr_CAPABLE 1 +# define S390X_aes_256_ctr_CAPABLE 1 + +# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */ +# define S390X_aes_256_xts_CAPABLE 1 + +# define S390X_aes_128_gcm_CAPABLE (S390X_aes_128_CAPABLE && \ + (OPENSSL_s390xcap_P.kma[0] & \ + S390X_CAPBIT(S390X_AES_128))) +# define S390X_aes_192_gcm_CAPABLE (S390X_aes_192_CAPABLE && \ + (OPENSSL_s390xcap_P.kma[0] & \ + S390X_CAPBIT(S390X_AES_192))) +# define S390X_aes_256_gcm_CAPABLE (S390X_aes_256_CAPABLE && \ + (OPENSSL_s390xcap_P.kma[0] & \ + S390X_CAPBIT(S390X_AES_256))) + +# define S390X_aes_128_ccm_CAPABLE (S390X_aes_128_CAPABLE && \ + (OPENSSL_s390xcap_P.kmac[0] & \ + S390X_CAPBIT(S390X_AES_128))) +# define S390X_aes_192_ccm_CAPABLE (S390X_aes_192_CAPABLE && \ + (OPENSSL_s390xcap_P.kmac[0] & \ + S390X_CAPBIT(S390X_AES_192))) +# define S390X_aes_256_ccm_CAPABLE (S390X_aes_256_CAPABLE && \ + (OPENSSL_s390xcap_P.kmac[0] & \ + S390X_CAPBIT(S390X_AES_256))) +# define S390X_CCM_AAD_FLAG 0x40 + +# ifndef OPENSSL_NO_OCB +# define S390X_aes_128_ocb_CAPABLE 0 +# define S390X_aes_192_ocb_CAPABLE 0 +# define S390X_aes_256_ocb_CAPABLE 0 +# endif /* OPENSSL_NO_OCB */ + +# ifndef OPENSSL_NO_SIV +# define S390X_aes_128_siv_CAPABLE 0 +# define S390X_aes_192_siv_CAPABLE 0 +# define S390X_aes_256_siv_CAPABLE 0 +# endif /* OPENSSL_NO_SIV */ + +/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ +# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6)) +# endif + +# if defined(HWAES_CAPABLE) +int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +void HWAES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void HWAES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); +void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +# ifndef OPENSSL_NO_OCB +# ifdef HWAES_ocb_encrypt +void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); +# else +# define HWAES_ocb_encrypt ((ocb128_f)NULL) +# endif +# ifdef HWAES_ocb_decrypt +void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); +# else +# define HWAES_ocb_decrypt ((ocb128_f)NULL) +# endif +# endif /* OPENSSL_NO_OCB */ + +# endif /* HWAES_CAPABLE */ + +#endif /* HEADER_INTERNAL_CIPHERMODE_PLATFORM_H */ diff --git a/crypto/include/internal/cms_int.h b/crypto/include/internal/cms_int.h new file mode 100644 index 00000000..c630991d --- /dev/null +++ b/crypto/include/internal/cms_int.h @@ -0,0 +1,13 @@ +/* + * 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 + */ + +/* internal CMS-ESS related stuff */ + +int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc); +int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc); diff --git a/crypto/include/internal/cryptlib_int.h b/crypto/include/internal/cryptlib_int.h index 673a004f..69d94be5 100644 --- a/crypto/include/internal/cryptlib_int.h +++ b/crypto/include/internal/cryptlib_int.h @@ -27,6 +27,5 @@ void ossl_ctx_thread_stop(void *arg); # define OPENSSL_INIT_ZLIB 0x00010000L # define OPENSSL_INIT_BASE_ONLY 0x00040000L -int ossl_trace_init(void); void ossl_trace_cleanup(void); void ossl_malloc_setup_failures(void); diff --git a/crypto/include/internal/ctype.h b/crypto/include/internal/ctype.h index adcbc8b3..d0660cf9 100644 --- a/crypto/include/internal/ctype.h +++ b/crypto/include/internal/ctype.h @@ -57,6 +57,8 @@ int ossl_ctype_check(int c, unsigned int mask); int ossl_tolower(int c); int ossl_toupper(int c); +int ascii_isdigit(const char inchar); + # define ossl_isalnum(c) (ossl_ctype_check((c), CTYPE_MASK_alnum)) # define ossl_isalpha(c) (ossl_ctype_check((c), CTYPE_MASK_alpha)) # ifdef CHARSET_EBCDIC diff --git a/crypto/include/internal/dso_conf.h.in b/crypto/include/internal/dso_conf.h.in index b6703f7c..9a373b20 100644 --- a/crypto/include/internal/dso_conf.h.in +++ b/crypto/include/internal/dso_conf.h.in @@ -16,7 +16,7 @@ # has support compiled in for them. Currently each method is enabled # by a define "DSO_" ... we translate the "dso_scheme" config # string entry into using the following logic; - my $scheme = uc $target{dso_scheme}; + my $scheme = $disabled{dso} ? undef : uc $target{dso_scheme}; if (!$scheme) { $scheme = "NONE"; } diff --git a/crypto/include/internal/ess_int.h b/crypto/include/internal/ess_int.h index 26476ae9..ac6c5c61 100644 --- a/crypto/include/internal/ess_int.h +++ b/crypto/include/internal/ess_int.h @@ -12,9 +12,18 @@ ESS_SIGNING_CERT *ESS_SIGNING_CERT_get(PKCS7_SIGNER_INFO *si); int ESS_SIGNING_CERT_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs, + int issuer_needed); + ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_get(PKCS7_SIGNER_INFO *si); int ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT_V2 *sc); +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new_init(const EVP_MD *hash_alg, + X509 *signcert, + STACK_OF(X509) *certs, + int issuer_needed); + /*- * IssuerSerial ::= SEQUENCE { * issuer GeneralNames, diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index da4ae0f1..f1fb6720 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -18,6 +18,23 @@ #define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 struct evp_pkey_ctx_st { + /* Actual operation */ + int operation; + + union { + struct { + EVP_KEYEXCH *exchange; + void *exchprovctx; + } kex; + + struct { + EVP_SIGNATURE *signature; + void *sigprovctx; + } sig; + } op; + + /* Legacy fields below */ + /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; /* Engine that implements this method or NULL if builtin */ @@ -26,8 +43,6 @@ struct evp_pkey_ctx_st { EVP_PKEY *pkey; /* Peer key for key agreement, may be NULL */ EVP_PKEY *peerkey; - /* Actual operation */ - int operation; /* Algorithm specific data */ void *data; /* Application specific data */ @@ -113,57 +128,45 @@ extern const EVP_PKEY_METHOD hkdf_pkey_meth; extern const EVP_PKEY_METHOD poly1305_pkey_meth; extern const EVP_PKEY_METHOD siphash_pkey_meth; -/* struct evp_mac_impl_st is defined by the implementation */ -typedef struct evp_mac_impl_st EVP_MAC_IMPL; struct evp_mac_st { - int type; - EVP_MAC_IMPL *(*new) (void); - EVP_MAC_IMPL *(*dup) (const EVP_MAC_IMPL *macsrc); - void (*free) (EVP_MAC_IMPL *macctx); - size_t (*size) (EVP_MAC_IMPL *macctx); - int (*init) (EVP_MAC_IMPL *macctx); - int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data, - size_t datalen); - int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out); - int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args); - int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value); + OSSL_PROVIDER *prov; + int name_id; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_mac_newctx_fn *newctx; + OSSL_OP_mac_dupctx_fn *dupctx; + OSSL_OP_mac_freectx_fn *freectx; + OSSL_OP_mac_size_fn *size; + OSSL_OP_mac_init_fn *init; + OSSL_OP_mac_update_fn *update; + OSSL_OP_mac_final_fn *final; + OSSL_OP_mac_gettable_params_fn *gettable_params; + OSSL_OP_mac_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_mac_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_mac_get_params_fn *get_params; + OSSL_OP_mac_get_ctx_params_fn *get_ctx_params; + OSSL_OP_mac_set_ctx_params_fn *set_ctx_params; }; -extern const EVP_MAC blake2b_mac_meth; -extern const EVP_MAC blake2s_mac_meth; -extern const EVP_MAC cmac_meth; -extern const EVP_MAC gmac_meth; -extern const EVP_MAC hmac_meth; -extern const EVP_MAC kmac128_meth; -extern const EVP_MAC kmac256_meth; -extern const EVP_MAC siphash_meth; -extern const EVP_MAC poly1305_meth; - -/* Internal keccak algorithms used for KMAC */ -const EVP_MD *evp_keccak_kmac128(void); -const EVP_MD *evp_keccak_kmac256(void); - -/* - * This function is internal for now, but can be made external when needed. - * The documentation would read: - * - * EVP_add_mac() adds the MAC implementation C to the internal - * object database. - */ -int EVP_add_mac(const EVP_MAC *mac); -int EVP_add_kdf(const EVP_KDF *kdf); - -/* struct evp_kdf_impl_st is defined by the implementation */ -typedef struct evp_kdf_impl_st EVP_KDF_IMPL; struct evp_kdf_st { - int type; - EVP_KDF_IMPL *(*new) (void); - void (*free) (EVP_KDF_IMPL *impl); - void (*reset) (EVP_KDF_IMPL *impl); - int (*ctrl) (EVP_KDF_IMPL *impl, int cmd, va_list args); - int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value); - size_t (*size) (EVP_KDF_IMPL *impl); - int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen); + OSSL_PROVIDER *prov; + int name_id; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_kdf_newctx_fn *newctx; + OSSL_OP_kdf_dupctx_fn *dupctx; + OSSL_OP_kdf_freectx_fn *freectx; + OSSL_OP_kdf_reset_fn *reset; + OSSL_OP_kdf_derive_fn *derive; + OSSL_OP_kdf_gettable_params_fn *gettable_params; + OSSL_OP_kdf_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_kdf_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_kdf_get_params_fn *get_params; + OSSL_OP_kdf_get_ctx_params_fn *get_ctx_params; + OSSL_OP_kdf_set_ctx_params_fn *set_ctx_params; }; extern const EVP_KDF pbkdf2_kdf_meth; @@ -196,6 +199,7 @@ struct evp_md_st { /* New structure members */ /* TODO(3.0): Remove above comment when legacy has gone */ + int name_id; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -206,10 +210,12 @@ struct evp_md_st { OSSL_OP_digest_digest_fn *digest; OSSL_OP_digest_freectx_fn *freectx; OSSL_OP_digest_dupctx_fn *dupctx; - OSSL_OP_digest_size_fn *size; - OSSL_OP_digest_block_size_fn *dblock_size; - OSSL_OP_digest_set_params_fn *set_params; OSSL_OP_digest_get_params_fn *get_params; + OSSL_OP_digest_set_ctx_params_fn *set_ctx_params; + OSSL_OP_digest_get_ctx_params_fn *get_ctx_params; + OSSL_OP_digest_gettable_params_fn *gettable_params; + OSSL_OP_digest_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_digest_gettable_ctx_params_fn *gettable_ctx_params; } /* EVP_MD */ ; @@ -246,6 +252,7 @@ struct evp_cipher_st { /* New structure members */ /* TODO(3.0): Remove above comment when legacy has gone */ + int name_id; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -258,8 +265,11 @@ struct evp_cipher_st { OSSL_OP_cipher_freectx_fn *freectx; OSSL_OP_cipher_dupctx_fn *dupctx; OSSL_OP_cipher_get_params_fn *get_params; - OSSL_OP_cipher_ctx_get_params_fn *ctx_get_params; - OSSL_OP_cipher_ctx_set_params_fn *ctx_set_params; + OSSL_OP_cipher_get_ctx_params_fn *get_ctx_params; + OSSL_OP_cipher_set_ctx_params_fn *set_ctx_params; + OSSL_OP_cipher_gettable_params_fn *gettable_params; + OSSL_OP_cipher_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_cipher_settable_ctx_params_fn *settable_ctx_params; } /* EVP_CIPHER */ ; /* Macros to code block cipher wrappers */ @@ -499,9 +509,9 @@ typedef struct { * method, as in, can it do arbitrary encryption.... */ struct evp_pkey_st { + /* == Legacy attributes == */ int type; int save_type; - CRYPTO_REF_COUNT references; const EVP_PKEY_ASN1_METHOD *ameth; ENGINE *engine; ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */ @@ -521,19 +531,77 @@ struct evp_pkey_st { ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */ # endif } pkey; - int save_parameters; - STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + + /* == Common attributes == */ + CRYPTO_REF_COUNT references; CRYPTO_RWLOCK *lock; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + int save_parameters; + + /* == Provider attributes == */ + /* + * To support transparent export/import between providers that + * support the methods for it, and still not having to do the + * export/import every time a key is used, we maintain a cache + * of imported key, indexed by provider address. + * pkeys[0] is *always* the "original" key. + */ + struct { + EVP_KEYMGMT *keymgmt; + void *provkey; + } pkeys[10]; + /* + * If there is a legacy key assigned to this structure, we keep + * a copy of that key's dirty count. + */ + size_t dirty_cnt_copy; } /* EVP_PKEY */ ; +#define EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) \ + ((ctx)->operation == EVP_PKEY_OP_SIGN \ + || (ctx)->operation == EVP_PKEY_OP_SIGNCTX \ + || (ctx)->operation == EVP_PKEY_OP_VERIFY \ + || (ctx)->operation == EVP_PKEY_OP_VERIFYCTX \ + || (ctx)->operation == EVP_PKEY_OP_VERIFYRECOVER) + +#define EVP_PKEY_CTX_IS_DERIVE_OP(ctx) \ + ((ctx)->operation == EVP_PKEY_OP_DERIVE) void openssl_add_all_ciphers_int(void); void openssl_add_all_digests_int(void); -void openssl_add_all_macs_int(void); -void openssl_add_all_kdfs_int(void); void evp_cleanup_int(void); void evp_app_cleanup_int(void); +/* KEYMGMT helper functions */ +void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); +void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk); + +/* KEYMGMT provider interface functions */ +void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); +void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); +void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, + void *provdomparams); +int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt, + void *provdomparams, OSSL_PARAM params[]); +const OSSL_PARAM * +evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt); +const OSSL_PARAM * +evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt); + +void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); +void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams, + const OSSL_PARAM params[]); +void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt, + void *id, size_t idlen); +void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey); +int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, + void *provkey, OSSL_PARAM params[]); +const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt); +const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt); + /* Pulling defines out of C source files */ #define EVP_RC4_KEY_SIZE 16 diff --git a/crypto/include/internal/modes_int.h b/crypto/include/internal/modes_int.h index 8a8ef6e1..08e4ffae 100644 --- a/crypto/include/internal/modes_int.h +++ b/crypto/include/internal/modes_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-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 @@ -7,28 +7,214 @@ * https://www.openssl.org/source/license.html */ +/* TODO(3.0) Move this header into provider when dependencies are removed */ +#include + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef __int64 i64; +typedef unsigned __int64 u64; +# define U64(C) C##UI64 +#elif defined(__arch64__) +typedef long i64; +typedef unsigned long u64; +# define U64(C) C##UL +#else +typedef long long i64; +typedef unsigned long long u64; +# define U64(C) C##ULL +#endif + +typedef unsigned int u32; +typedef unsigned char u8; + +#define STRICT_ALIGNMENT 1 +#ifndef PEDANTIC +# if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__aarch64__) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +# endif +#endif + +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define BSWAP8(x) ({ u64 ret_=(x); \ + asm ("bswapq %0" \ + : "+r"(ret_)); ret_; }) +# define BSWAP4(x) ({ u32 ret_=(x); \ + asm ("bswapl %0" \ + : "+r"(ret_)); ret_; }) +# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) +# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ + asm ("bswapl %0; bswapl %1" \ + : "+r"(hi_),"+r"(lo_)); \ + (u64)hi_<<32|lo_; }) +# define BSWAP4(x) ({ u32 ret_=(x); \ + asm ("bswapl %0" \ + : "+r"(ret_)); ret_; }) +# elif defined(__aarch64__) +# define BSWAP8(x) ({ u64 ret_; \ + asm ("rev %0,%1" \ + : "=r"(ret_) : "r"(x)); ret_; }) +# define BSWAP4(x) ({ u32 ret_; \ + asm ("rev %w0,%w1" \ + : "=r"(ret_) : "r"(x)); ret_; }) +# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) +# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ + asm ("rev %0,%0; rev %1,%1" \ + : "+r"(hi_),"+r"(lo_)); \ + (u64)hi_<<32|lo_; }) +# define BSWAP4(x) ({ u32 ret_; \ + asm ("rev %0,%1" \ + : "=r"(ret_) : "r"((u32)(x))); \ + ret_; }) +# endif +# elif defined(_MSC_VER) +# if _MSC_VER>=1300 +# include +# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) +# define BSWAP8(x) _byteswap_uint64((u64)(x)) +# define BSWAP4(x) _byteswap_ulong((u32)(x)) +# elif defined(_M_IX86) +__inline u32 _bswap4(u32 val) +{ +_asm mov eax, val _asm bswap eax} +# define BSWAP4(x) _bswap4(x) +# endif +# endif +#endif +#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) +# define GETU32(p) BSWAP4(*(const u32 *)(p)) +# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#else +# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) +# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) +#endif +/*- GCM definitions */ typedef struct { + u64 hi, lo; +} u128; + +#ifdef TABLE_BITS +# undef TABLE_BITS +#endif +/* + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8 [or 1]. For further information see gcm128.c. + */ +#define TABLE_BITS 4 + +struct gcm128_context { + /* Following 6 names follow names in GCM specification */ + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + size_t t[16 / sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi, H; + /* + * Relative position of Xi, H and pre-computed Htable is used in some + * assembler modules, i.e. don't change the order! + */ +#if TABLE_BITS==8 + u128 Htable[256]; +#else + u128 Htable[16]; + void (*gmult) (u64 Xi[2], const u128 Htable[16]); + void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +#endif + unsigned int mres, ares; + block128_f block; + void *key; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + unsigned char Xn[48]; +#endif +}; + +/* + * The maximum permitted number of cipher blocks per data unit in XTS mode. + * Reference IEEE Std 1619-2018. + */ +#define XTS_MAX_BLOCKS_PER_DATA_UNIT (1<<20) + +struct xts128_context { + void *key1, *key2; + block128_f block1, block2; +}; + +struct ccm128_context { + union { + u64 u[2]; + u8 c[16]; + } nonce, cmac; + u64 blocks; + block128_f block; + void *key; +}; + +#ifndef OPENSSL_NO_OCB + +typedef union { + u64 a[2]; + unsigned char c[16]; +} OCB_BLOCK; +# define ocb_block16_xor(in1,in2,out) \ + ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ + (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) +# if STRICT_ALIGNMENT +# define ocb_block16_xor_misaligned(in1,in2,out) \ + ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) +# else +# define ocb_block16_xor_misaligned ocb_block16_xor +# endif + +struct ocb128_context { + /* Need both encrypt and decrypt key schedules for decryption */ + block128_f encrypt; + block128_f decrypt; + void *keyenc; + void *keydec; + ocb128_f stream; /* direction dependent */ + /* Key dependent variables. Can be reused if key remains the same */ + size_t l_index; + size_t max_l_index; + OCB_BLOCK l_star; + OCB_BLOCK l_dollar; + OCB_BLOCK *l; + /* Must be reset for each session */ + struct { + u64 blocks_hashed; + u64 blocks_processed; + OCB_BLOCK offset_aad; + OCB_BLOCK sum; + OCB_BLOCK offset; + OCB_BLOCK checksum; + } sess; +}; +#endif /* OPENSSL_NO_OCB */ + #ifndef OPENSSL_NO_SIV -typedef struct siv128_context SIV128_CONTEXT; +#define SIV_LEN 16 -SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, - EVP_CIPHER* cbc, EVP_CIPHER* ctr); -int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, - const EVP_CIPHER* cbc, const EVP_CIPHER* ctr); -int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src); -int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, - size_t len); -int CRYPTO_siv128_encrypt(SIV128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len); -int CRYPTO_siv128_decrypt(SIV128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len); -int CRYPTO_siv128_finish(SIV128_CONTEXT *ctx); -int CRYPTO_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, - size_t len); -int CRYPTO_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len); -int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx); -int CRYPTO_siv128_speed(SIV128_CONTEXT *ctx, int arg); +typedef union siv_block_u { + uint64_t word[SIV_LEN/sizeof(uint64_t)]; + unsigned char byte[SIV_LEN]; +} SIV_BLOCK; + +struct siv128_context { + /* d stores intermediate results of S2V; it corresponds to D from the + pseudocode in section 2.4 of RFC 5297. */ + SIV_BLOCK d; + SIV_BLOCK tag; + EVP_CIPHER_CTX *cipher_ctx; + EVP_MAC *mac; + EVP_MAC_CTX *mac_ctx_init; + int final_ret; + int crypto_ok; +}; #endif /* OPENSSL_NO_SIV */ diff --git a/crypto/include/internal/rand_int.h b/crypto/include/internal/rand_int.h index d964a1d4..bc427e3c 100644 --- a/crypto/include/internal/rand_int.h +++ b/crypto/include/internal/rand_int.h @@ -24,7 +24,6 @@ typedef struct rand_pool_st RAND_POOL; void rand_cleanup_int(void); -void rand_fork(void); /* Hardware-based seeding functions. */ size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool); @@ -58,7 +57,8 @@ void rand_crngt_cleanup_entropy(RAND_DRBG *drbg, /* * RAND_POOL functions */ -RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len); +RAND_POOL *rand_pool_new(int entropy_requested, int secure, + size_t min_len, size_t max_len); RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, size_t entropy); void rand_pool_free(RAND_POOL *pool); diff --git a/crypto/include/internal/siv_int.h b/crypto/include/internal/siv_int.h new file mode 100644 index 00000000..8a8ef6e1 --- /dev/null +++ b/crypto/include/internal/siv_int.h @@ -0,0 +1,34 @@ +/* + * 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_SIV + +typedef struct siv128_context SIV128_CONTEXT; + +SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, + EVP_CIPHER* cbc, EVP_CIPHER* ctr); +int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, + const EVP_CIPHER* cbc, const EVP_CIPHER* ctr); +int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src); +int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_siv128_encrypt(SIV128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_siv128_decrypt(SIV128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_siv128_finish(SIV128_CONTEXT *ctx); +int CRYPTO_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +int CRYPTO_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len); +int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx); +int CRYPTO_siv128_speed(SIV128_CONTEXT *ctx, int arg); + +#endif /* OPENSSL_NO_SIV */ diff --git a/crypto/include/internal/sm2err.h b/crypto/include/internal/sm2err.h index 2f404e07..923bb6c4 100644 --- a/crypto/include/internal/sm2err.h +++ b/crypto/include/internal/sm2err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -11,6 +11,10 @@ #ifndef HEADER_SM2ERR_H # define HEADER_SM2ERR_H +# include +# include + + # include # ifndef OPENSSL_NO_SM2 @@ -23,22 +27,24 @@ int ERR_load_SM2_strings(void); /* * SM2 function codes. */ -# define SM2_F_PKEY_SM2_COPY 115 -# define SM2_F_PKEY_SM2_CTRL 109 -# define SM2_F_PKEY_SM2_CTRL_STR 110 -# define SM2_F_PKEY_SM2_DIGEST_CUSTOM 114 -# define SM2_F_PKEY_SM2_INIT 111 -# define SM2_F_PKEY_SM2_SIGN 112 -# define SM2_F_SM2_COMPUTE_MSG_HASH 100 -# define SM2_F_SM2_COMPUTE_USERID_DIGEST 101 -# define SM2_F_SM2_COMPUTE_Z_DIGEST 113 -# define SM2_F_SM2_DECRYPT 102 -# define SM2_F_SM2_ENCRYPT 103 -# define SM2_F_SM2_PLAINTEXT_SIZE 104 -# define SM2_F_SM2_SIGN 105 -# define SM2_F_SM2_SIG_GEN 106 -# define SM2_F_SM2_SIG_VERIFY 107 -# define SM2_F_SM2_VERIFY 108 +# if !OPENSSL_API_3 +# define SM2_F_PKEY_SM2_COPY 0 +# define SM2_F_PKEY_SM2_CTRL 0 +# define SM2_F_PKEY_SM2_CTRL_STR 0 +# define SM2_F_PKEY_SM2_DIGEST_CUSTOM 0 +# define SM2_F_PKEY_SM2_INIT 0 +# define SM2_F_PKEY_SM2_SIGN 0 +# define SM2_F_SM2_COMPUTE_MSG_HASH 0 +# define SM2_F_SM2_COMPUTE_USERID_DIGEST 0 +# define SM2_F_SM2_COMPUTE_Z_DIGEST 0 +# define SM2_F_SM2_DECRYPT 0 +# define SM2_F_SM2_ENCRYPT 0 +# define SM2_F_SM2_PLAINTEXT_SIZE 0 +# define SM2_F_SM2_SIGN 0 +# define SM2_F_SM2_SIG_GEN 0 +# define SM2_F_SM2_SIG_VERIFY 0 +# define SM2_F_SM2_VERIFY 0 +# endif /* * SM2 reason codes. diff --git a/crypto/include/internal/x509_int.h b/crypto/include/internal/x509_int.h index f6897e14..11a77695 100644 --- a/crypto/include/internal/x509_int.h +++ b/crypto/include/internal/x509_int.h @@ -197,7 +197,7 @@ struct x509_st { * kept and passed around. */ struct x509_store_ctx_st { /* X509_STORE_CTX */ - X509_STORE *ctx; + X509_STORE *store; /* The following are set by the caller */ /* The cert to check */ X509 *cert; diff --git a/crypto/info.c b/crypto/info.c index 5a929ddd..355827c4 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -7,13 +7,121 @@ * https://www.openssl.org/source/license.html */ -#include #include #include "internal/dso_conf.h" +#include "internal/thread_once.h" +#include "internal/cryptlib.h" #include "e_os.h" +#include "buildinf.h" + +#if defined(__arm__) || defined(__arm) || defined(__aarch64__) +# include "arm_arch.h" +#endif + +/* extern declaration to avoid warning */ +extern char ossl_cpu_info_str[]; + +static char *seed_sources = NULL; + +char ossl_cpu_info_str[128] = ""; +#define CPUINFO_PREFIX "CPUINFO: " + +static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT; + +DEFINE_RUN_ONCE_STATIC(init_info_strings) +{ +#if defined(OPENSSL_CPUID_OBJ) +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + const char *env; + + BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), + CPUINFO_PREFIX "OPENSSL_ia32cap=0x%llx:0x%llx", + (long long)OPENSSL_ia32cap_P[0] | + (long long)OPENSSL_ia32cap_P[1] << 32, + (long long)OPENSSL_ia32cap_P[2] | + (long long)OPENSSL_ia32cap_P[3] << 32); + if ((env = getenv("OPENSSL_ia32cap")) != NULL) + BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), + sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), + " env:%s", env); +# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) + const char *env; + + BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), + CPUINFO_PREFIX "OPENSSL_armcap=0x%x", OPENSSL_armcap_P); + if ((env = getenv("OPENSSL_armcap")) != NULL) + BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), + sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), + " env:%s", env); +# endif +#endif + + { + static char seeds[512] = ""; + +#define add_seeds_string(str) \ + do { \ + if (seeds[0] != '\0') \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + OPENSSL_strlcat(seeds, str, sizeof(seeds)); \ + } while (0) +#define add_seeds_stringlist(label, strlist) \ + do { \ + add_seeds_string(label "("); \ + { \ + const char *dev[] = strlist; \ + int first = 1; \ + \ + for (; *dev != NULL; dev++) { \ + if (!first) \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + first = 0; \ + OPENSSL_strlcat(seeds, *dev, sizeof(seeds)); \ + } \ + } \ + OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \ + } while (0) + +#ifdef OPENSSL_RAND_SEED_NONE + add_seeds_string("none"); +#endif +#ifdef OPENSSL_RAND_SEED_RTDSC + add_seeds_string("stdsc"); +#endif +#ifdef OPENSSL_RAND_SEED_RDCPU + add_seeds_string("rdrand ( rdseed rdrand )"); +#endif +#ifdef OPENSSL_RAND_SEED_LIBRANDOM + add_seeds_string("C-library-random"); +#endif +#ifdef OPENSSL_RAND_SEED_GETRANDOM + add_seeds_string("getrandom-syscall"); +#endif +#ifdef OPENSSL_RAND_SEED_DEVRANDOM + add_seeds_stringlist("random-device", { DEVRANDOM, NULL }); +#endif +#ifdef OPENSSL_RAND_SEED_EGD + add_seeds_stringlist("EGD", { DEVRANDOM_EGD, NULL }); +#endif +#ifdef OPENSSL_RAND_SEED_OS + add_seeds_string("os-specific"); +#endif + seed_sources = seeds; + } + return 1; +} const char *OPENSSL_info(int t) { + /* + * We don't care about the result. Worst case scenario, the strings + * won't be initialised, i.e. remain NULL, which means that the info + * isn't available anyway... + */ + (void)RUN_ONCE(&init_info, init_info_strings); + switch (t) { case OPENSSL_INFO_CONFIG_DIR: return OPENSSLDIR; @@ -36,6 +144,17 @@ const char *OPENSSL_info(int t) static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' }; return list_sep; } + case OPENSSL_INFO_SEED_SOURCE: + return seed_sources; + case OPENSSL_INFO_CPU_SETTINGS: + /* + * If successfully initialized, ossl_cpu_info_str will start + * with CPUINFO_PREFIX, if failed it will be an empty string. + * Strip away the CPUINFO_PREFIX which we don't need here. + */ + if (ossl_cpu_info_str[0] != '\0') + return ossl_cpu_info_str + strlen(CPUINFO_PREFIX); + break; default: break; } diff --git a/crypto/init.c b/crypto/init.c index d5f0ebd7..6536bd52 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -44,8 +44,7 @@ static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; static int base_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_base) { - if (ossl_trace_init() == 0) - return 0; + /* no need to init trace */ OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n"); #ifndef OPENSSL_NO_CRYPTO_MDEBUG @@ -226,46 +225,6 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests, return 1; } -static CRYPTO_ONCE add_all_macs = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_macs) -{ - /* - * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time - * pulling in all the macs during static linking - */ -#ifndef OPENSSL_NO_AUTOALGINIT - OSSL_TRACE(INIT, "openssl_add_all_macs_int()\n"); - openssl_add_all_macs_int(); -#endif - return 1; -} - -DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs) -{ - /* Do nothing */ - return 1; -} - -static CRYPTO_ONCE add_all_kdfs = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_kdfs) -{ - /* - * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time - * pulling in all the macs during static linking - */ -#ifndef OPENSSL_NO_AUTOALGINIT - OSSL_TRACE(INIT, "openssl_add_all_kdfs_int()\n"); - openssl_add_all_kdfs_int(); -#endif - return 1; -} - -DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_kdfs, ossl_init_add_all_kdfs) -{ - /* Do nothing */ - return 1; -} - static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; static int config_inited = 0; static const OPENSSL_INIT_SETTINGS *conf_settings = NULL; @@ -558,24 +517,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests)) return 0; - if ((opts & OPENSSL_INIT_NO_ADD_ALL_MACS) - && !RUN_ONCE_ALT(&add_all_macs, ossl_init_no_add_all_macs, - ossl_init_add_all_macs)) - return 0; - - if ((opts & OPENSSL_INIT_ADD_ALL_MACS) - && !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs)) - return 0; - - if ((opts & OPENSSL_INIT_NO_ADD_ALL_KDFS) - && !RUN_ONCE_ALT(&add_all_kdfs, ossl_init_no_add_all_kdfs, - ossl_init_add_all_kdfs)) - return 0; - - if ((opts & OPENSSL_INIT_ADD_ALL_KDFS) - && !RUN_ONCE(&add_all_kdfs, ossl_init_add_all_kdfs)) - return 0; - if ((opts & OPENSSL_INIT_ATFORK) && !openssl_init_fork_handlers()) return 0; @@ -735,7 +676,6 @@ void OPENSSL_fork_parent(void) void OPENSSL_fork_child(void) { - rand_fork(); /* TODO(3.0): Inform all providers about a fork event */ } #endif diff --git a/crypto/initthread.c b/crypto/initthread.c index 99cd96ce..7de8a369 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -21,7 +21,7 @@ * we have our own copy of ossl_init_thread_start, which cascades notifications * about threads stopping from libcrypto to all the code in the FIPS provider * that needs to know about it. - * + * * The FIPS provider tells libcrypto about which threads it is interested in * by calling "c_thread_start" which is a function pointer created during * provider initialisation (i.e. OSSL_init_provider). @@ -77,6 +77,12 @@ static GLOBAL_TEVENT_REGISTER *get_global_tevent_register(void) } #endif +#ifndef FIPS_MODE +static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands); +static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin); +static void init_thread_destructor(void *hands); +static int init_thread_deregister(void *arg, int all); +#endif static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands); static THREAD_EVENT_HANDLER ** @@ -86,40 +92,22 @@ init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep) if (alloc) { if (hands == NULL) { -#ifndef FIPS_MODE - GLOBAL_TEVENT_REGISTER *gtr; -#endif - if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL) { - OPENSSL_free(hands); + if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL) return NULL; - } -#ifndef FIPS_MODE - /* - * The thread event handler is thread specific and is a linked - * list of all handler functions that should be called for the - * current thread. We also keep a global reference to that linked - * list, so that we can deregister handlers if necessary before all - * the threads are stopped. - */ - gtr = get_global_tevent_register(); - if (gtr == NULL) { - OPENSSL_free(hands); - return NULL; - } - CRYPTO_THREAD_write_lock(gtr->lock); - if (!sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands)) { - OPENSSL_free(hands); - CRYPTO_THREAD_unlock(gtr->lock); - return NULL; - } - CRYPTO_THREAD_unlock(gtr->lock); -#endif if (!CRYPTO_THREAD_set_local(local, hands)) { OPENSSL_free(hands); return NULL; } + +#ifndef FIPS_MODE + if (!init_thread_push_handlers(hands)) { + CRYPTO_THREAD_set_local(local, NULL); + OPENSSL_free(hands); + return NULL; + } +#endif } } else if (!keep) { CRYPTO_THREAD_set_local(local, NULL); @@ -148,6 +136,32 @@ static union { CRYPTO_THREAD_LOCAL value; } destructor_key = { -1 }; +/* + * The thread event handler list is a thread specific linked list + * of callback functions which are invoked in list order by the + * current thread in case of certain events. (Currently, there is + * only one type of event, the 'thread stop' event.) + * + * We also keep a global reference to that linked list, so that we + * can deregister handlers if necessary before all the threads are + * stopped. + */ +static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands) +{ + int ret; + GLOBAL_TEVENT_REGISTER *gtr; + + gtr = get_global_tevent_register(); + if (gtr == NULL) + return 0; + + CRYPTO_THREAD_write_lock(gtr->lock); + ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0); + CRYPTO_THREAD_unlock(gtr->lock); + + return ret; +} + static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin) { GLOBAL_TEVENT_REGISTER *gtr; @@ -187,8 +201,6 @@ int ossl_init_thread(void) return 1; } -static int init_thread_deregister(void *arg, int all); - void ossl_cleanup_thread(void) { init_thread_deregister(NULL, 1); diff --git a/crypto/kdf/build.info b/crypto/kdf/build.info deleted file mode 100644 index 4fdaccdd..00000000 --- a/crypto/kdf/build.info +++ /dev/null @@ -1,4 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c sshkdf.c \ - sskdf.c x942kdf.c diff --git a/crypto/kdf/kdf_err.c b/crypto/kdf/kdf_err.c deleted file mode 100644 index 1b6e7845..00000000 --- a/crypto/kdf/kdf_err.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 KDF_str_functs[] = { - {ERR_PACK(ERR_LIB_KDF, KDF_F_HKDF_EXTRACT, 0), "HKDF_Extract"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_DERIVE, 0), "kdf_hkdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_NEW, 0), "kdf_hkdf_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_SIZE, 0), "kdf_hkdf_size"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_MD2CTRL, 0), "kdf_md2ctrl"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL, 0), "kdf_pbkdf2_ctrl"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL_STR, 0), - "kdf_pbkdf2_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_DERIVE, 0), "kdf_pbkdf2_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_NEW, 0), "kdf_pbkdf2_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_STR, 0), - "kdf_scrypt_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT32, 0), - "kdf_scrypt_ctrl_uint32"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT64, 0), - "kdf_scrypt_ctrl_uint64"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_DERIVE, 0), "kdf_scrypt_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_NEW, 0), "kdf_scrypt_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SSHKDF_CTRL, 0), "kdf_sshkdf_ctrl"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SSHKDF_CTRL_STR, 0), - "kdf_sshkdf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SSHKDF_DERIVE, 0), "kdf_sshkdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SSHKDF_NEW, 0), "kdf_sshkdf_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_CTRL_STR, 0), - "kdf_tls1_prf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_DERIVE, 0), - "kdf_tls1_prf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_NEW, 0), "kdf_tls1_prf_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_DERIVE, 0), "pbkdf2_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_SET_MEMBUF, 0), "pbkdf2_set_membuf"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_CTRL_STR, 0), - "pkey_scrypt_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_CTRL_UINT64, 0), - "pkey_scrypt_ctrl_uint64"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_DERIVE, 0), "pkey_scrypt_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_INIT, 0), "pkey_scrypt_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_SET_MEMBUF, 0), - "pkey_scrypt_set_membuf"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_CTRL_STR, 0), - "pkey_tls1_prf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0), - "pkey_tls1_prf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SCRYPT_SET_MEMBUF, 0), "scrypt_set_membuf"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_CTRL_STR, 0), "sskdf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_DERIVE, 0), "sskdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_MAC2CTRL, 0), "sskdf_mac2ctrl"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_NEW, 0), "sskdf_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_SIZE, 0), "sskdf_size"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X942KDF_CTRL, 0), "x942kdf_ctrl"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X942KDF_DERIVE, 0), "x942kdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X942KDF_HASH_KDM, 0), "x942kdf_hash_kdm"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X942KDF_NEW, 0), "x942kdf_new"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X942KDF_SIZE, 0), "x942kdf_size"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_X963KDF_DERIVE, 0), "x963kdf_derive"}, - {0, NULL} -}; - -static const ERR_STRING_DATA KDF_str_reasons[] = { - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_BAD_ENCODING), "bad encoding"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_BAD_LENGTH), "bad length"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INAVLID_UKM_LEN), "inavlid ukm len"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_DIGEST), "invalid digest"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_ITERATION_COUNT), - "invalid iteration count"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_KEY_LEN), "invalid key len"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_MAC_TYPE), "invalid mac type"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_SALT_LEN), "invalid salt len"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_CEK_ALG), "missing cek alg"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_ITERATION_COUNT), - "missing iteration count"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_KEY), "missing key"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_MESSAGE_DIGEST), - "missing message digest"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_PARAMETER), "missing parameter"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_PASS), "missing pass"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SALT), "missing salt"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SECRET), "missing secret"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SEED), "missing seed"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SESSION_ID), "missing session id"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_TYPE), "missing type"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_XCGHASH), "missing xcghash"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_NOT_SUPPORTED), "not supported"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE), - "unknown parameter type"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNSUPPORTED_CEK_ALG), - "unsupported cek alg"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNSUPPORTED_MAC_TYPE), - "unsupported mac type"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_WRONG_OUTPUT_BUFFER_SIZE), - "wrong output buffer size"}, - {0, NULL} -}; - -#endif - -int ERR_load_KDF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(KDF_str_functs[0].error) == NULL) { - ERR_load_strings_const(KDF_str_functs); - ERR_load_strings_const(KDF_str_reasons); - } -#endif - return 1; -} diff --git a/crypto/kdf/kdf_local.h b/crypto/kdf/kdf_local.h deleted file mode 100644 index 4956dad9..00000000 --- a/crypto/kdf/kdf_local.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2018, Oracle and/or its affiliates. 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 - */ - -int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - EVP_KDF_IMPL *impl, int cmd, ...); -int kdf_str2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *str); -int kdf_hex2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *hex); -int kdf_md2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *md_name); - diff --git a/crypto/kdf/kdf_util.c b/crypto/kdf/kdf_util.c deleted file mode 100644 index 8eb6d26b..00000000 --- a/crypto/kdf/kdf_util.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2018, Oracle and/or its affiliates. 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 "internal/evp_int.h" -#include "internal/numbers.h" -#include "kdf_local.h" - -int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - EVP_KDF_IMPL *impl, int cmd, ...) -{ - int ret; - va_list args; - - va_start(args, cmd); - ret = ctrl(impl, cmd, args); - va_end(args); - - return ret; -} - -/* Utility functions to send a string or hex string to a ctrl */ - -int kdf_str2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *str) -{ - return call_ctrl(ctrl, impl, cmd, (const unsigned char *)str, strlen(str)); -} - -int kdf_hex2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *hex) -{ - unsigned char *bin; - long binlen; - int ret = -1; - - bin = OPENSSL_hexstr2buf(hex, &binlen); - if (bin == NULL) - return 0; - - if (binlen <= INT_MAX) - ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen); - OPENSSL_free(bin); - return ret; -} - -/* Pass a message digest to a ctrl */ -int kdf_md2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *md_name) -{ - const EVP_MD *md; - - if (md_name == NULL || (md = EVP_get_digestbyname(md_name)) == NULL) { - KDFerr(KDF_F_KDF_MD2CTRL, KDF_R_INVALID_DIGEST); - return 0; - } - return call_ctrl(ctrl, impl, cmd, md); -} - diff --git a/crypto/kdf/pbkdf2.c b/crypto/kdf/pbkdf2.c deleted file mode 100644 index d4168977..00000000 --- a/crypto/kdf/pbkdf2.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/evp_int.h" -#include "kdf_local.h" - -/* Constants specified in SP800-132 */ -#define KDF_PBKDF2_MIN_KEY_LEN_BITS 112 -#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF -#define KDF_PBKDF2_MIN_ITERATIONS 1000 -#define KDF_PBKDF2_MIN_SALT_LEN (128 / 8) -/* - * For backwards compatibility reasons, - * Extra checks are done by default in fips mode only. - */ -#ifdef FIPS_MODE -# define KDF_PBKDF2_DEFAULT_CHECKS 1 -#else -# define KDF_PBKDF2_DEFAULT_CHECKS 0 -#endif /* FIPS_MODE */ - -static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl); -static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl); -static int pbkdf2_derive(const char *pass, size_t passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, unsigned char *key, - size_t keylen, int extra_checks); - -struct evp_kdf_impl_st { - unsigned char *pass; - size_t pass_len; - unsigned char *salt; - size_t salt_len; - int iter; - const EVP_MD *md; - int lower_bound_checks; -}; - -static EVP_KDF_IMPL *kdf_pbkdf2_new(void) -{ - EVP_KDF_IMPL *impl; - - impl = OPENSSL_zalloc(sizeof(*impl)); - if (impl == NULL) { - KDFerr(KDF_F_KDF_PBKDF2_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - kdf_pbkdf2_init(impl); - return impl; -} - -static void kdf_pbkdf2_free(EVP_KDF_IMPL *impl) -{ - kdf_pbkdf2_reset(impl); - OPENSSL_free(impl); -} - -static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl) -{ - OPENSSL_free(impl->salt); - OPENSSL_clear_free(impl->pass, impl->pass_len); - memset(impl, 0, sizeof(*impl)); - kdf_pbkdf2_init(impl); -} - -static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl) -{ - impl->iter = PKCS5_DEFAULT_ITER; - impl->md = EVP_sha1(); - impl->lower_bound_checks = KDF_PBKDF2_DEFAULT_CHECKS; -} - -static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen, - const unsigned char *new_buffer, - size_t new_buflen) -{ - if (new_buffer == NULL) - return 1; - - OPENSSL_clear_free(*buffer, *buflen); - - if (new_buflen > 0) { - *buffer = OPENSSL_memdup(new_buffer, new_buflen); - } else { - *buffer = OPENSSL_malloc(1); - } - if (*buffer == NULL) { - KDFerr(KDF_F_PBKDF2_SET_MEMBUF, ERR_R_MALLOC_FAILURE); - return 0; - } - - *buflen = new_buflen; - return 1; -} - -static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) -{ - int iter, pkcs5, min_iter; - const unsigned char *p; - size_t len; - const EVP_MD *md; - - switch (cmd) { - case EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE: - pkcs5 = va_arg(args, int); - impl->lower_bound_checks = (pkcs5 == 0) ? 1 : 0; - return 1; - case EVP_KDF_CTRL_SET_PASS: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - return pbkdf2_set_membuf(&impl->pass, &impl->pass_len, p, len); - - case EVP_KDF_CTRL_SET_SALT: - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - if (impl->lower_bound_checks != 0 && len < KDF_PBKDF2_MIN_SALT_LEN) { - KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_SALT_LEN); - return 0; - } - return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len); - - case EVP_KDF_CTRL_SET_ITER: - iter = va_arg(args, int); - min_iter = impl->lower_bound_checks != 0 ? KDF_PBKDF2_MIN_ITERATIONS : 1; - if (iter < min_iter) { - KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_ITERATION_COUNT); - return 0; - } - impl->iter = iter; - return 1; - - case EVP_KDF_CTRL_SET_MD: - md = va_arg(args, const EVP_MD *); - if (md == NULL) { - KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_VALUE_MISSING); - return 0; - } - - impl->md = md; - return 1; - - default: - return -2; - } -} - -static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type, - const char *value) -{ - if (value == NULL) { - KDFerr(KDF_F_KDF_PBKDF2_CTRL_STR, KDF_R_VALUE_MISSING); - return 0; - } - - if (strcmp(type, "pass") == 0) - return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, - value); - - if (strcmp(type, "hexpass") == 0) - return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, - value); - - if (strcmp(type, "salt") == 0) - return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, - value); - - if (strcmp(type, "hexsalt") == 0) - return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, - value); - - if (strcmp(type, "iter") == 0) - return call_ctrl(kdf_pbkdf2_ctrl, impl, EVP_KDF_CTRL_SET_ITER, - atoi(value)); - - if (strcmp(type, "digest") == 0) - return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value); - - if (strcmp(type, "pkcs5") == 0) - return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, - EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, value); - return -2; -} - -static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key, - size_t keylen) -{ - if (impl->pass == NULL) { - KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_PASS); - return 0; - } - - if (impl->salt == NULL) { - KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_SALT); - return 0; - } - - return pbkdf2_derive((char *)impl->pass, impl->pass_len, - impl->salt, impl->salt_len, impl->iter, - impl->md, key, keylen, impl->lower_bound_checks); -} - -const EVP_KDF pbkdf2_kdf_meth = { - EVP_KDF_PBKDF2, - kdf_pbkdf2_new, - kdf_pbkdf2_free, - kdf_pbkdf2_reset, - kdf_pbkdf2_ctrl, - kdf_pbkdf2_ctrl_str, - NULL, - kdf_pbkdf2_derive -}; - -/* - * This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2. SHA1 version verified against test vectors - * posted by Peter Gutmann to the PKCS-TNG mailing list. - * - * The constraints specified by SP800-132 have been added i.e. - * - Check the range of the key length. - * - Minimum iteration count of 1000. - * - Randomly-generated portion of the salt shall be at least 128 bits. - */ -static int pbkdf2_derive(const char *pass, size_t passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, unsigned char *key, - size_t keylen, int lower_bound_checks) -{ - int ret = 0; - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; - - mdlen = EVP_MD_size(digest); - if (mdlen <= 0) - return 0; - - /* - * This check should always be done because keylen / mdlen >= (2^32 - 1) - * results in an overflow of the loop counter 'i'. - */ - if ((keylen / mdlen) >= KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO) { - KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN); - return 0; - } - - if (lower_bound_checks) { - if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) { - KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN); - return 0; - } - if (saltlen < KDF_PBKDF2_MIN_SALT_LEN) { - KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_SALT_LEN); - return 0; - } - if (iter < KDF_PBKDF2_MIN_ITERATIONS) { - KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_ITERATION_COUNT); - return 0; - } - } - - hctx_tpl = HMAC_CTX_new(); - if (hctx_tpl == NULL) - return 0; - p = key; - tkeylen = keylen; - if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) - goto err; - hctx = HMAC_CTX_new(); - if (hctx == NULL) - goto err; - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* - * We are unlikely to ever use more than 256 blocks (5120 bits!) but - * just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(hctx, hctx_tpl)) - goto err; - if (!HMAC_Update(hctx, salt, saltlen) - || !HMAC_Update(hctx, itmp, 4) - || !HMAC_Final(hctx, digtmp, NULL)) - goto err; - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(hctx, hctx_tpl)) - goto err; - if (!HMAC_Update(hctx, digtmp, mdlen) - || !HMAC_Final(hctx, digtmp, NULL)) - goto err; - for (k = 0; k < cplen; k++) - p[k] ^= digtmp[k]; - } - tkeylen -= cplen; - i++; - p += cplen; - } - ret = 1; - -err: - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return ret; -} diff --git a/crypto/kdf/sshkdf.c b/crypto/kdf/sshkdf.c deleted file mode 100644 index 4701c9ca..00000000 --- a/crypto/kdf/sshkdf.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2018-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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/cryptlib.h" -#include "internal/numbers.h" -#include "internal/evp_int.h" -#include "kdf_local.h" - -/* See RFC 4253, Section 7.2 */ - -static void kdf_sshkdf_reset(EVP_KDF_IMPL *impl); -static int SSHKDF(const EVP_MD *evp_md, - const unsigned char *key, size_t key_len, - const unsigned char *xcghash, size_t xcghash_len, - const unsigned char *session_id, size_t session_id_len, - char type, unsigned char *okey, size_t okey_len); - -struct evp_kdf_impl_st { - const EVP_MD *md; - unsigned char *key; /* K */ - size_t key_len; - unsigned char *xcghash; /* H */ - size_t xcghash_len; - char type; /* X */ - unsigned char *session_id; - size_t session_id_len; -}; - -static EVP_KDF_IMPL *kdf_sshkdf_new(void) -{ - EVP_KDF_IMPL *impl; - - if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) - KDFerr(KDF_F_KDF_SSHKDF_NEW, ERR_R_MALLOC_FAILURE); - return impl; -} - -static void kdf_sshkdf_free(EVP_KDF_IMPL *impl) -{ - kdf_sshkdf_reset(impl); - OPENSSL_free(impl); -} - -static void kdf_sshkdf_reset(EVP_KDF_IMPL *impl) -{ - OPENSSL_clear_free(impl->key, impl->key_len); - OPENSSL_clear_free(impl->xcghash, impl->xcghash_len); - OPENSSL_clear_free(impl->session_id, impl->session_id_len); - memset(impl, 0, sizeof(*impl)); -} - -static int kdf_sshkdf_parse_buffer_arg(unsigned char **dst, size_t *dst_len, - va_list args) -{ - const unsigned char *p; - size_t len; - - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - OPENSSL_clear_free(*dst, *dst_len); - *dst = OPENSSL_memdup(p, len); - if (*dst == NULL) - return 0; - - *dst_len = len; - return 1; -} - -static int kdf_sshkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) -{ - int t; - - switch (cmd) { - case EVP_KDF_CTRL_SET_MD: - impl->md = va_arg(args, const EVP_MD *); - if (impl->md == NULL) - return 0; - - return 1; - - case EVP_KDF_CTRL_SET_KEY: - return kdf_sshkdf_parse_buffer_arg(&impl->key, - &impl->key_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_XCGHASH: - return kdf_sshkdf_parse_buffer_arg(&impl->xcghash, - &impl->xcghash_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID: - return kdf_sshkdf_parse_buffer_arg(&impl->session_id, - &impl->session_id_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_TYPE: - t = va_arg(args, int); - if (t < 65 || t > 70) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL, KDF_R_VALUE_ERROR); - return 0; - } - - impl->type = (char)t; - return 1; - - default: - return -2; - - } -} - -static int kdf_sshkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type, - const char *value) -{ - if (value == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_VALUE_MISSING); - return 0; - } - - if (strcmp(type, "digest") == 0) - return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); - /* alias, for historical reasons */ - if (strcmp(type, "md") == 0) - return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); - - if (strcmp(type, "key") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_KEY, value); - - if (strcmp(type, "hexkey") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_KEY, value); - - if (strcmp(type, "xcghash") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, value); - - if (strcmp(type, "hexxcghash") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, value); - - if (strcmp(type, "session_id") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, value); - - if (strcmp(type, "hexsession_id") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, value); - - if (strcmp(type, "type") == 0) { - if (strlen(value) != 1) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_VALUE_ERROR); - return 0; - } - - return call_ctrl(kdf_sshkdf_ctrl, impl, EVP_KDF_CTRL_SET_SSHKDF_TYPE, - (int)value[0]); - } - - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); - return -2; -} - -static size_t kdf_sshkdf_size(EVP_KDF_IMPL *impl) -{ - return SIZE_MAX; -} - -static int kdf_sshkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, - size_t keylen) -{ - if (impl->md == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); - return 0; - } - if (impl->key == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_KEY); - return 0; - } - if (impl->xcghash == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_XCGHASH); - return 0; - } - if (impl->session_id == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_SESSION_ID); - return 0; - } - if (impl->type == 0) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_TYPE); - return 0; - } - return SSHKDF(impl->md, impl->key, impl->key_len, - impl->xcghash, impl->xcghash_len, - impl->session_id, impl->session_id_len, - impl->type, key, keylen); -} - -const EVP_KDF sshkdf_kdf_meth = { - EVP_KDF_SSHKDF, - kdf_sshkdf_new, - kdf_sshkdf_free, - kdf_sshkdf_reset, - kdf_sshkdf_ctrl, - kdf_sshkdf_ctrl_str, - kdf_sshkdf_size, - kdf_sshkdf_derive, -}; - -static int SSHKDF(const EVP_MD *evp_md, - const unsigned char *key, size_t key_len, - const unsigned char *xcghash, size_t xcghash_len, - const unsigned char *session_id, size_t session_id_len, - char type, unsigned char *okey, size_t okey_len) -{ - EVP_MD_CTX *md = NULL; - unsigned char digest[EVP_MAX_MD_SIZE]; - unsigned int dsize = 0; - size_t cursize = 0; - int ret = 0; - - md = EVP_MD_CTX_new(); - if (md == NULL) - return 0; - - if (!EVP_DigestInit_ex(md, evp_md, NULL)) - goto out; - - if (!EVP_DigestUpdate(md, key, key_len)) - goto out; - - if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) - goto out; - - if (!EVP_DigestUpdate(md, &type, 1)) - goto out; - - if (!EVP_DigestUpdate(md, session_id, session_id_len)) - goto out; - - if (!EVP_DigestFinal_ex(md, digest, &dsize)) - goto out; - - if (okey_len < dsize) { - memcpy(okey, digest, okey_len); - ret = 1; - goto out; - } - - memcpy(okey, digest, dsize); - - for (cursize = dsize; cursize < okey_len; cursize += dsize) { - - if (!EVP_DigestInit_ex(md, evp_md, NULL)) - goto out; - - if (!EVP_DigestUpdate(md, key, key_len)) - goto out; - - if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) - goto out; - - if (!EVP_DigestUpdate(md, okey, cursize)) - goto out; - - if (!EVP_DigestFinal_ex(md, digest, &dsize)) - goto out; - - if (okey_len < cursize + dsize) { - memcpy(okey + cursize, digest, okey_len - cursize); - ret = 1; - goto out; - } - - memcpy(okey + cursize, digest, dsize); - } - - ret = 1; - -out: - EVP_MD_CTX_free(md); - OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE); - return ret; -} - diff --git a/crypto/kmac/build.info b/crypto/kmac/build.info deleted file mode 100644 index 01d04be5..00000000 --- a/crypto/kmac/build.info +++ /dev/null @@ -1,3 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=kmac.c - diff --git a/crypto/md5/asm/md5-586.pl b/crypto/md5/asm/md5-586.pl index ea59ed91..74b82f02 100644 --- a/crypto/md5/asm/md5-586.pl +++ b/crypto/md5/asm/md5-586.pl @@ -18,8 +18,10 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/md5/asm/md5-sparcv9.pl b/crypto/md5/asm/md5-sparcv9.pl index db46fff7..fd77b8b1 100644 --- a/crypto/md5/asm/md5-sparcv9.pl +++ b/crypto/md5/asm/md5-sparcv9.pl @@ -24,8 +24,10 @@ # single-process result on 8-core processor, or ~11GBps per 2.85GHz # socket. -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; use integer; diff --git a/crypto/md5/asm/md5-x86_64.pl b/crypto/md5/asm/md5-x86_64.pl index adc2321d..c3d82455 100755 --- a/crypto/md5/asm/md5-x86_64.pl +++ b/crypto/md5/asm/md5-x86_64.pl @@ -119,9 +119,10 @@ EOF } no warnings qw(uninitialized); -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -130,7 +131,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code .= <references) <= 0) { - app_info_free(inf->next); - OPENSSL_free(inf); - } -} #endif int CRYPTO_mem_ctrl(int mode) @@ -237,78 +209,17 @@ static unsigned long mem_hash(const MEM *a) return ret; } -/* returns 1 if there was an info to pop, 0 if the stack was empty. */ -static int pop_info(void) -{ - APP_INFO *current = NULL; - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return 0; - - current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - if (current != NULL) { - APP_INFO *next = current->next; - - if (next != NULL) { - next->references++; - CRYPTO_THREAD_set_local(&appinfokey, next); - } else { - CRYPTO_THREAD_set_local(&appinfokey, NULL); - } - if (--(current->references) <= 0) { - current->next = NULL; - if (next != NULL) - next->references--; - OPENSSL_free(current); - } - return 1; - } - return 0; -} - +#if !OPENSSL_API_3 int CRYPTO_mem_debug_push(const char *info, const char *file, int line) { - APP_INFO *ami, *amim; - int ret = 0; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init) - || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL) - goto err; - - ami->threadid = CRYPTO_THREAD_get_current_id(); - ami->file = file; - ami->line = line; - ami->info = info; - ami->references = 1; - ami->next = NULL; - - amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - CRYPTO_THREAD_set_local(&appinfokey, ami); - - if (amim != NULL) - ami->next = amim; - ret = 1; - err: - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - - return ret; + return 0; } int CRYPTO_mem_debug_pop(void) { - int ret = 0; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - ret = pop_info(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - return ret; + return 0; } +#endif static unsigned long break_order_num = 0; @@ -316,7 +227,6 @@ void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p, const char *file, int line) { MEM *m, *mm; - APP_INFO *amim; switch (before_p & 127) { case 0: @@ -359,18 +269,8 @@ void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p, # endif m->time = time(NULL); - amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - m->app_info = amim; - if (amim != NULL) - amim->references++; - - if ((mm = lh_MEM_insert(mh, m)) != NULL) { - /* Not good, but don't sweat it */ - if (mm->app_info != NULL) { - mm->app_info->references--; - } + if ((mm = lh_MEM_insert(mh, m)) != NULL) OPENSSL_free(mm); - } err: CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); } @@ -391,14 +291,9 @@ void CRYPTO_mem_debug_free(void *addr, int before_p, if (mem_check_on() && (mh != NULL)) { CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - m.addr = addr; mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { - app_info_free(mp->app_info); - OPENSSL_free(mp); - } - + OPENSSL_free(mp); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); } break; @@ -456,11 +351,9 @@ static void print_leak(const MEM *m, MEM_LEAK *l) { char buf[1024]; char *bufp = buf, *hex; - size_t len = sizeof(buf), ami_cnt; - APP_INFO *amip; + size_t len = sizeof(buf); int n; struct tm *lcl = NULL; - CRYPTO_THREAD_ID ti; lcl = localtime(&m->time); n = BIO_snprintf(bufp, len, "[%02d:%02d:%02d] ", @@ -490,56 +383,9 @@ static void print_leak(const MEM *m, MEM_LEAK *l) len -= n; l->print_cb(buf, (size_t)(bufp - buf), l->print_cb_arg); - l->chunks++; l->bytes += m->num; - amip = m->app_info; - ami_cnt = 0; - - if (amip) { - ti = amip->threadid; - - do { - int buf_len; - int info_len; - - ami_cnt++; - if (ami_cnt >= sizeof(buf) - 1) - break; - memset(buf, '>', ami_cnt); - buf[ami_cnt] = '\0'; - hex = OPENSSL_buf2hexstr((const unsigned char *)&amip->threadid, - sizeof(amip->threadid)); - n = BIO_snprintf(buf + ami_cnt, sizeof(buf) - ami_cnt, - "thread=%s, file=%s, line=%d, info=\"", - hex, amip->file, amip->line); - OPENSSL_free(hex); - if (n <= 0) - break; - buf_len = ami_cnt + n; - info_len = strlen(amip->info); - if (128 - buf_len - 3 < info_len) { - memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); - buf_len = 128 - 3; - } else { - n = BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "%s", - amip->info); - if (n < 0) - break; - buf_len += n; - } - n = BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "\"\n"); - if (n <= 0) - break; - - l->print_cb(buf, buf_len + n, l->print_cb_arg); - - amip = amip->next; - } - while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti)); - } - #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE { size_t i; @@ -607,7 +453,6 @@ int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF); /* Clean up locks etc */ - CRYPTO_THREAD_cleanup_local(&appinfokey); CRYPTO_THREAD_lock_free(memdbg_lock); CRYPTO_THREAD_lock_free(long_memdbg_lock); memdbg_lock = NULL; diff --git a/crypto/mem_str.c b/crypto/mem_str.c deleted file mode 100644 index da13ea4a..00000000 --- a/crypto/mem_str.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2003-2017 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 "e_os.h" -#include -#include -#include "internal/cryptlib.h" - -char *CRYPTO_strdup(const char *str, const char* file, int line) -{ - char *ret; - - if (str == NULL) - return NULL; - ret = CRYPTO_malloc(strlen(str) + 1, file, line); - if (ret != NULL) - strcpy(ret, str); - return ret; -} - -char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) -{ - size_t maxlen; - char *ret; - - if (str == NULL) - return NULL; - - maxlen = OPENSSL_strnlen(str, s); - - ret = CRYPTO_malloc(maxlen + 1, file, line); - if (ret) { - memcpy(ret, str, maxlen); - ret[maxlen] = '\0'; - } - return ret; -} - -void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) -{ - void *ret; - - if (data == NULL || siz >= INT_MAX) - return NULL; - - ret = CRYPTO_malloc(siz, file, line); - if (ret == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE); - return NULL; - } - return memcpy(ret, data, siz); -} - -/* - * Give a string of hex digits convert to a buffer - */ -unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) -{ - unsigned char *hexbuf, *q; - unsigned char ch, cl; - int chi, cli; - const unsigned char *p; - size_t s; - - s = strlen(str); - if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (p = (const unsigned char *)str, q = hexbuf; *p; ) { - ch = *p++; - if (ch == ':') - continue; - cl = *p++; - if (!cl) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, - CRYPTO_R_ODD_NUMBER_OF_DIGITS); - OPENSSL_free(hexbuf); - return NULL; - } - cli = OPENSSL_hexchar2int(cl); - chi = OPENSSL_hexchar2int(ch); - if (cli < 0 || chi < 0) { - OPENSSL_free(hexbuf); - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); - return NULL; - } - *q++ = (unsigned char)((chi << 4) | cli); - } - - if (len) - *len = q - hexbuf; - return hexbuf; -} - -/* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) - */ -char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len) -{ - static const char hexdig[] = "0123456789ABCDEF"; - char *tmp, *q; - const unsigned char *p; - int i; - - if (len == 0) - return OPENSSL_zalloc(1); - - if ((tmp = OPENSSL_malloc(len * 3)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); - return NULL; - } - q = tmp; - for (i = 0, p = buffer; i < len; i++, p++) { - *q++ = hexdig[(*p >> 4) & 0xf]; - *q++ = hexdig[*p & 0xf]; - *q++ = ':'; - } - q[-1] = 0; -#ifdef CHARSET_EBCDIC - ebcdic2ascii(tmp, tmp, q - tmp - 1); -#endif - - return tmp; -} diff --git a/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/modes/asm/aesni-gcm-x86_64.pl index dcdb6a2d..d5ab0457 100644 --- a/crypto/modes/asm/aesni-gcm-x86_64.pl +++ b/crypto/modes/asm/aesni-gcm-x86_64.pl @@ -40,9 +40,10 @@ # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest # [2] http://www.intel.com/content/dam/www/public/us/en/documents/software-support/enabling-high-performance-gcm.pdf -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -70,7 +71,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if ($avx>1) {{{ diff --git a/crypto/modes/asm/ghash-armv4.pl b/crypto/modes/asm/ghash-armv4.pl index 1391b1b6..9a3a1f4e 100644 --- a/crypto/modes/asm/ghash-armv4.pl +++ b/crypto/modes/asm/ghash-armv4.pl @@ -78,9 +78,10 @@ # *native* byte order on current platform. See gcm128.c for working # example... -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -88,9 +89,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $Xi="r0"; # argument block diff --git a/crypto/modes/asm/ghash-c64xplus.pl b/crypto/modes/asm/ghash-c64xplus.pl index 16112198..70cef3bc 100644 --- a/crypto/modes/asm/ghash-c64xplus.pl +++ b/crypto/modes/asm/ghash-c64xplus.pl @@ -26,8 +26,7 @@ # better, because theoretical [though not necessarily achievable] # estimate for "4-bit" table-driven implementation is ~12 cycles. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($Xip,$Htable,$inp,$len)=("A4","B4","A6","B6"); # arguments diff --git a/crypto/modes/asm/ghash-parisc.pl b/crypto/modes/asm/ghash-parisc.pl index 6f45e461..4eccdc71 100644 --- a/crypto/modes/asm/ghash-parisc.pl +++ b/crypto/modes/asm/ghash-parisc.pl @@ -27,9 +27,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/modes/asm/ghash-s390x.pl b/crypto/modes/asm/ghash-s390x.pl index 260c49a7..5355a307 100644 --- a/crypto/modes/asm/ghash-s390x.pl +++ b/crypto/modes/asm/ghash-s390x.pl @@ -44,7 +44,10 @@ # it's actually almost 2 times slower. Which is the reason why # KIMD-GHASH is not used in gcm_gmult_4bit. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -54,8 +57,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $softonly=0; diff --git a/crypto/modes/asm/ghash-sparcv9.pl b/crypto/modes/asm/ghash-sparcv9.pl index 281b5f9a..b8b10228 100644 --- a/crypto/modes/asm/ghash-sparcv9.pl +++ b/crypto/modes/asm/ghash-sparcv9.pl @@ -53,8 +53,7 @@ # saturates at ~15.5x single-process result on 8-core processor, # or ~20.5GBps per 2.85GHz socket. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $frame="STACK_FRAME"; $bias="STACK_BIAS"; diff --git a/crypto/modes/asm/ghash-x86.pl b/crypto/modes/asm/ghash-x86.pl index 12d63cee..5372b487 100644 --- a/crypto/modes/asm/ghash-x86.pl +++ b/crypto/modes/asm/ghash-x86.pl @@ -135,8 +135,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/modes/asm/ghash-x86_64.pl b/crypto/modes/asm/ghash-x86_64.pl index a5d216ab..7a3412c0 100644 --- a/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/modes/asm/ghash-x86_64.pl @@ -90,9 +90,10 @@ # # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -120,7 +121,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $do4xaggr=1; diff --git a/crypto/modes/asm/ghashp8-ppc.pl b/crypto/modes/asm/ghashp8-ppc.pl index 1ae84bed..44add795 100755 --- a/crypto/modes/asm/ghashp8-ppc.pl +++ b/crypto/modes/asm/ghashp8-ppc.pl @@ -32,8 +32,10 @@ # aggregated reduction - by 170% or 2.7x (resulting in 0.55 cpb). # POWER9 delivers 0.51 cpb. -$flavour=shift; -$output =shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -61,7 +63,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6)); # argument block diff --git a/crypto/modes/asm/ghashv8-armx.pl b/crypto/modes/asm/ghashv8-armx.pl index fbc49d1c..aa5251df 100644 --- a/crypto/modes/asm/ghashv8-armx.pl +++ b/crypto/modes/asm/ghashv8-armx.pl @@ -46,15 +46,18 @@ # # (*) presented for reference/comparison purposes; -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $Xi="x0"; # argument block diff --git a/crypto/modes/build.info b/crypto/modes/build.info index 81525a99..8a8aead6 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -48,29 +48,30 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -$COMMON=cbc128.c ctr128.c cfb128.c ofb128.c $MODESASM +$COMMON=cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c xts128.c \ + wrap128.c $MODESASM SOURCE[../../libcrypto]=$COMMON \ - cts128.c gcm128.c ccm128.c xts128.c wrap128.c ocb128.c siv128.c + cts128.c ocb128.c siv128.c + DEFINE[../../libcrypto]=$MODESDEF SOURCE[../../providers/fips]=$COMMON DEFINE[../../providers/fips]=$MODESDEF INCLUDE[gcm128.o]=.. -GENERATE[ghash-ia64.s]=asm/ghash-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[ghash-x86.s]=asm/ghash-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[ghash-x86_64.s]=asm/ghash-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-gcm-x86_64.s]=asm/aesni-gcm-x86_64.pl $(PERLASM_SCHEME) -GENERATE[ghash-sparcv9.S]=asm/ghash-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[ghash-ia64.s]=asm/ghash-ia64.pl +GENERATE[ghash-x86.s]=asm/ghash-x86.pl +GENERATE[ghash-x86_64.s]=asm/ghash-x86_64.pl +GENERATE[aesni-gcm-x86_64.s]=asm/aesni-gcm-x86_64.pl +GENERATE[ghash-sparcv9.S]=asm/ghash-sparcv9.pl INCLUDE[ghash-sparcv9.o]=.. -GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl $(PERLASM_SCHEME) -GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl $(PERLASM_SCHEME) -GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl $(PERLASM_SCHEME) -GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl $(PERLASM_SCHEME) +GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl +GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl +GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl +GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl INCLUDE[ghash-armv4.o]=.. -GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl $(PERLASM_SCHEME) +GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl INCLUDE[ghashv8-armx.o]=.. -GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl $(PERLASM_SCHEME) +GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl INCLUDE[ghash-s390x.o]=.. -GENERATE[ghash-c64xplus.S]=asm/ghash-c64xplus.pl $(PERLASM_SCHEME) +GENERATE[ghash-c64xplus.S]=asm/ghash-c64xplus.pl diff --git a/crypto/modes/cbc128.c b/crypto/modes/cbc128.c index c510d96f..eb8e06c1 100644 --- a/crypto/modes/cbc128.c +++ b/crypto/modes/cbc128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) # define STRICT_ALIGNMENT 0 diff --git a/crypto/modes/ccm128.c b/crypto/modes/ccm128.c index bfa2d460..e97158a1 100644 --- a/crypto/modes/ccm128.c +++ b/crypto/modes/ccm128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" /* * First you setup M and L parameters and pass the key schedule. This is diff --git a/crypto/modes/cfb128.c b/crypto/modes/cfb128.c index 53522406..39644a23 100644 --- a/crypto/modes/cfb128.c +++ b/crypto/modes/cfb128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" /* * The input and output encrypted as though 128bit cfb mode is being used. diff --git a/crypto/modes/ctr128.c b/crypto/modes/ctr128.c index 177c9556..1755b850 100644 --- a/crypto/modes/ctr128.c +++ b/crypto/modes/ctr128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" /* * NOTE: the IV/counter CTR mode is big-endian. The code itself is diff --git a/crypto/modes/cts128.c b/crypto/modes/cts128.c index aca4ea87..b4f2f377 100644 --- a/crypto/modes/cts128.c +++ b/crypto/modes/cts128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" /* * Trouble with Ciphertext Stealing, CTS, mode is that there is no diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c index b4d7215f..f37653be 100644 --- a/crypto/modes/gcm128.c +++ b/crypto/modes/gcm128.c @@ -7,9 +7,10 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/cryptlib.h" +#include "internal/modes_int.h" #if defined(BSWAP4) && defined(STRICT_ALIGNMENT) /* redefine, because alignment is ensured */ @@ -635,7 +636,6 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) # define GHASH_ASM_X86_OR_64 # define GCM_FUNCREF_4BIT -extern unsigned int OPENSSL_ia32cap_P[]; void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); diff --git a/crypto/modes/modes_lcl.h b/crypto/modes/modes_lcl.h deleted file mode 100644 index d4ce4623..00000000 --- a/crypto/modes/modes_lcl.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2010-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 - -#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -typedef __int64 i64; -typedef unsigned __int64 u64; -# define U64(C) C##UI64 -#elif defined(__arch64__) -typedef long i64; -typedef unsigned long u64; -# define U64(C) C##UL -#else -typedef long long i64; -typedef unsigned long long u64; -# define U64(C) C##ULL -#endif - -typedef unsigned int u32; -typedef unsigned char u8; - -#define STRICT_ALIGNMENT 1 -#ifndef PEDANTIC -# if defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ - defined(__aarch64__) || \ - defined(__s390__) || defined(__s390x__) -# undef STRICT_ALIGNMENT -# endif -#endif - -#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(__GNUC__) && __GNUC__>=2 -# if defined(__x86_64) || defined(__x86_64__) -# define BSWAP8(x) ({ u64 ret_=(x); \ - asm ("bswapq %0" \ - : "+r"(ret_)); ret_; }) -# define BSWAP4(x) ({ u32 ret_=(x); \ - asm ("bswapl %0" \ - : "+r"(ret_)); ret_; }) -# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) -# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ - asm ("bswapl %0; bswapl %1" \ - : "+r"(hi_),"+r"(lo_)); \ - (u64)hi_<<32|lo_; }) -# define BSWAP4(x) ({ u32 ret_=(x); \ - asm ("bswapl %0" \ - : "+r"(ret_)); ret_; }) -# elif defined(__aarch64__) -# define BSWAP8(x) ({ u64 ret_; \ - asm ("rev %0,%1" \ - : "=r"(ret_) : "r"(x)); ret_; }) -# define BSWAP4(x) ({ u32 ret_; \ - asm ("rev %w0,%w1" \ - : "=r"(ret_) : "r"(x)); ret_; }) -# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) -# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ - asm ("rev %0,%0; rev %1,%1" \ - : "+r"(hi_),"+r"(lo_)); \ - (u64)hi_<<32|lo_; }) -# define BSWAP4(x) ({ u32 ret_; \ - asm ("rev %0,%1" \ - : "=r"(ret_) : "r"((u32)(x))); \ - ret_; }) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER>=1300 -# include -# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) -# define BSWAP8(x) _byteswap_uint64((u64)(x)) -# define BSWAP4(x) _byteswap_ulong((u32)(x)) -# elif defined(_M_IX86) -__inline u32 _bswap4(u32 val) -{ -_asm mov eax, val _asm bswap eax} -# define BSWAP4(x) _bswap4(x) -# endif -# endif -#endif -#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) -# define GETU32(p) BSWAP4(*(const u32 *)(p)) -# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) -#else -# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) -# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) -#endif -/*- GCM definitions */ typedef struct { - u64 hi, lo; -} u128; - -#ifdef TABLE_BITS -# undef TABLE_BITS -#endif -/* - * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should - * never be set to 8 [or 1]. For further information see gcm128.c. - */ -#define TABLE_BITS 4 - -struct gcm128_context { - /* Following 6 names follow names in GCM specification */ - union { - u64 u[2]; - u32 d[4]; - u8 c[16]; - size_t t[16 / sizeof(size_t)]; - } Yi, EKi, EK0, len, Xi, H; - /* - * Relative position of Xi, H and pre-computed Htable is used in some - * assembler modules, i.e. don't change the order! - */ -#if TABLE_BITS==8 - u128 Htable[256]; -#else - u128 Htable[16]; - void (*gmult) (u64 Xi[2], const u128 Htable[16]); - void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -#endif - unsigned int mres, ares; - block128_f block; - void *key; -#if !defined(OPENSSL_SMALL_FOOTPRINT) - unsigned char Xn[48]; -#endif -}; - -/* - * The maximum permitted number of cipher blocks per data unit in XTS mode. - * Reference IEEE Std 1619-2018. - */ -#define XTS_MAX_BLOCKS_PER_DATA_UNIT (1<<20) - -struct xts128_context { - void *key1, *key2; - block128_f block1, block2; -}; - -struct ccm128_context { - union { - u64 u[2]; - u8 c[16]; - } nonce, cmac; - u64 blocks; - block128_f block; - void *key; -}; - -#ifndef OPENSSL_NO_OCB - -typedef union { - u64 a[2]; - unsigned char c[16]; -} OCB_BLOCK; -# define ocb_block16_xor(in1,in2,out) \ - ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ - (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) -# if STRICT_ALIGNMENT -# define ocb_block16_xor_misaligned(in1,in2,out) \ - ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) -# else -# define ocb_block16_xor_misaligned ocb_block16_xor -# endif - -struct ocb128_context { - /* Need both encrypt and decrypt key schedules for decryption */ - block128_f encrypt; - block128_f decrypt; - void *keyenc; - void *keydec; - ocb128_f stream; /* direction dependent */ - /* Key dependent variables. Can be reused if key remains the same */ - size_t l_index; - size_t max_l_index; - OCB_BLOCK l_star; - OCB_BLOCK l_dollar; - OCB_BLOCK *l; - /* Must be reset for each session */ - struct { - u64 blocks_hashed; - u64 blocks_processed; - OCB_BLOCK offset_aad; - OCB_BLOCK sum; - OCB_BLOCK offset; - OCB_BLOCK checksum; - } sess; -}; -#endif /* OPENSSL_NO_OCB */ - -#ifndef OPENSSL_NO_SIV - -#include - -#define SIV_LEN 16 - -typedef union siv_block_u { - uint64_t word[SIV_LEN/sizeof(uint64_t)]; - unsigned char byte[SIV_LEN]; -} SIV_BLOCK; - -struct siv128_context { - /* d stores intermediate results of S2V; it corresponds to D from the - pseudocode in section 2.4 of RFC 5297. */ - SIV_BLOCK d; - SIV_BLOCK tag; - EVP_CIPHER_CTX *cipher_ctx; - EVP_MAC_CTX *mac_ctx_init; - int final_ret; - int crypto_ok; -}; - -#endif /* OPENSSL_NO_SIV */ diff --git a/crypto/modes/ocb128.c b/crypto/modes/ocb128.c index 7511101a..9e7af607 100644 --- a/crypto/modes/ocb128.c +++ b/crypto/modes/ocb128.c @@ -10,7 +10,7 @@ #include #include #include -#include "modes_lcl.h" +#include "internal/modes_int.h" #ifndef OPENSSL_NO_OCB diff --git a/crypto/modes/ofb128.c b/crypto/modes/ofb128.c index 96b15c71..b894cbb5 100644 --- a/crypto/modes/ofb128.c +++ b/crypto/modes/ofb128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" /* * The input and output encrypted as though 128bit ofb mode is being used. diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c index 4445cf36..1d91ee78 100644 --- a/crypto/modes/siv128.c +++ b/crypto/modes/siv128.c @@ -10,8 +10,11 @@ #include #include #include +#include +#include +#include #include "internal/modes_int.h" -#include "modes_lcl.h" +#include "internal/siv_int.h" #ifndef OPENSSL_NO_SIV @@ -116,7 +119,7 @@ __owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *ou if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN)) goto err; } - if (!EVP_MAC_final(mac_ctx, out->byte, &out_len) + if (!EVP_MAC_final(mac_ctx, out->byte, &out_len, sizeof(out->byte)) || out_len != SIV_LEN) goto err; @@ -166,6 +169,14 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, static const unsigned char zero[SIV_LEN] = { 0 }; size_t out_len = SIV_LEN; EVP_MAC_CTX *mac_ctx = NULL; + OSSL_PARAM params[3]; + const char *cbc_name = EVP_CIPHER_name(cbc); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + (char *)cbc_name, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key, klen); + params[2] = OSSL_PARAM_construct_end(); memset(&ctx->d, 0, sizeof(ctx->d)); ctx->cipher_ctx = NULL; @@ -173,16 +184,20 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, if (key == NULL || cbc == NULL || ctr == NULL || (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL - || (ctx->mac_ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_CMAC)) == NULL - || EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_CIPHER, cbc) <= 0 - || EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_KEY, key, klen) <= 0 + /* TODO(3.0) library context */ + || (ctx->mac = + EVP_MAC_fetch(NULL, OSSL_MAC_NAME_CMAC, NULL)) == NULL + || (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL + || !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params) || !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL) || (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL || !EVP_MAC_update(mac_ctx, zero, sizeof(zero)) - || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len)) { + || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len, + sizeof(ctx->d.byte))) { EVP_CIPHER_CTX_free(ctx->cipher_ctx); EVP_MAC_CTX_free(ctx->mac_ctx_init); EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free(ctx->mac); return 0; } EVP_MAC_CTX_free(mac_ctx); @@ -222,10 +237,10 @@ int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, siv128_dbl(&ctx->d); - mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init); - if (mac_ctx == NULL + if ((mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL || !EVP_MAC_update(mac_ctx, aad, len) - || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len) + || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len, + sizeof(mac_out.byte)) || out_len != SIV_LEN) { EVP_MAC_CTX_free(mac_ctx); return 0; @@ -344,6 +359,8 @@ int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx) ctx->cipher_ctx = NULL; EVP_MAC_CTX_free(ctx->mac_ctx_init); ctx->mac_ctx_init = NULL; + EVP_MAC_free(ctx->mac); + ctx->mac = NULL; OPENSSL_cleanse(&ctx->d, sizeof(ctx->d)); OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag)); ctx->final_ret = -1; diff --git a/crypto/modes/xts128.c b/crypto/modes/xts128.c index 6c17fdc5..03b83aa0 100644 --- a/crypto/modes/xts128.c +++ b/crypto/modes/xts128.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include -#include "modes_lcl.h" #include +#include +#include "internal/modes_int.h" int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], diff --git a/crypto/o_str.c b/crypto/o_str.c index 35bb6540..6780188c 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -12,6 +12,51 @@ #include #include "internal/cryptlib.h" +char *CRYPTO_strdup(const char *str, const char* file, int line) +{ + char *ret; + + if (str == NULL) + return NULL; + ret = CRYPTO_malloc(strlen(str) + 1, file, line); + if (ret != NULL) + strcpy(ret, str); + return ret; +} + +char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) +{ + size_t maxlen; + char *ret; + + if (str == NULL) + return NULL; + + maxlen = OPENSSL_strnlen(str, s); + + ret = CRYPTO_malloc(maxlen + 1, file, line); + if (ret) { + memcpy(ret, str, maxlen); + ret[maxlen] = '\0'; + } + return ret; +} + +void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) +{ + void *ret; + + if (data == NULL || siz >= INT_MAX) + return NULL; + + ret = CRYPTO_malloc(siz, file, line); + if (ret == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + return memcpy(ret, data, siz); +} + size_t OPENSSL_strnlen(const char *str, size_t maxlen) { const char *p; @@ -84,6 +129,130 @@ int OPENSSL_hexchar2int(unsigned char c) return -1; } +/* + * Give a string of hex digits convert to a buffer + */ +int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str) +{ + unsigned char *q; + unsigned char ch, cl; + int chi, cli; + const unsigned char *p; + size_t cnt; + + for (p = (const unsigned char *)str, q = buf, cnt = 0; *p; ) { + ch = *p++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, + CRYPTO_R_ODD_NUMBER_OF_DIGITS); + return 0; + } + cli = OPENSSL_hexchar2int(cl); + chi = OPENSSL_hexchar2int(ch); + if (cli < 0 || chi < 0) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, + CRYPTO_R_ILLEGAL_HEX_DIGIT); + return 0; + } + cnt++; + if (q != NULL) { + if (cnt > buf_n) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, + CRYPTO_R_TOO_SMALL_BUFFER); + return 0; + } + *q++ = (unsigned char)((chi << 4) | cli); + } + } + + if (buflen != NULL) + *buflen = cnt; + return 1; +} + +unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) +{ + unsigned char *buf; + size_t buf_n, tmp_buflen; + + buf_n = strlen(str) >> 1; + if ((buf = OPENSSL_malloc(buf_n)) == NULL) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (buflen != NULL) + *buflen = 0; + tmp_buflen = 0; + if (OPENSSL_hexstr2buf_ex(buf, buf_n, &tmp_buflen, str)) { + if (buflen != NULL) + *buflen = (long)tmp_buflen; + return buf; + } + OPENSSL_free(buf); + return NULL; +} + +int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, + const unsigned char *buf, size_t buflen) +{ + static const char hexdig[] = "0123456789ABCDEF"; + const unsigned char *p; + char *q; + size_t i; + + if (strlen != NULL) + *strlen = buflen * 3; + if (str == NULL) + return 1; + + if (str_n < (unsigned long)buflen * 3) { + CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR_EX, CRYPTO_R_TOO_SMALL_BUFFER); + return 0; + } + + q = str; + for (i = 0, p = buf; i < buflen; i++, p++) { + *q++ = hexdig[(*p >> 4) & 0xf]; + *q++ = hexdig[*p & 0xf]; + *q++ = ':'; + } + q[-1] = 0; +#ifdef CHARSET_EBCDIC + ebcdic2ascii(str, str, q - str - 1); +#endif + return 1; +} + +/* + * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its + * hex representation @@@ (Contents of buffer are always kept in ASCII, also + * on EBCDIC machines) + */ +char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) +{ + char *tmp; + size_t tmp_n; + + if (buflen == 0) + return OPENSSL_zalloc(1); + + tmp_n = buflen * 3; + if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { + CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (OPENSSL_buf2hexstr_ex(tmp, tmp_n, NULL, buf, buflen)) + return tmp; + OPENSSL_free(tmp); + return NULL; +} + int openssl_strerror_r(int errnum, char *buf, size_t buflen) { #if defined(_MSC_VER) && _MSC_VER>=1400 diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index ec9e1313..c4155a3d 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -228,20 +228,23 @@ ASN1_OBJECT *OBJ_nid2obj(int n) return NULL; } return (ASN1_OBJECT *)&(nid_objs[n]); - } else if (added == NULL) - return NULL; - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj; - else { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj; + + OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return NULL; } const char *OBJ_nid2sn(int n) @@ -255,20 +258,23 @@ const char *OBJ_nid2sn(int n) return NULL; } return nid_objs[n].sn; - } else if (added == NULL) - return NULL; - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj->sn; - else { - OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj->sn; + + OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + return NULL; } const char *OBJ_nid2ln(int n) @@ -282,20 +288,23 @@ const char *OBJ_nid2ln(int n) return NULL; } return nid_objs[n].ln; - } else if (added == NULL) - return NULL; - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj->ln; - else { - OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj->ln; + + OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + return NULL; } static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) @@ -327,6 +336,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) if (a->length == 0) return NID_undef; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (added != NULL) { ad.type = ADDED_DATA; ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ @@ -544,6 +556,9 @@ int OBJ_ln2nid(const char *s) ADDED_OBJ ad, *adp; const unsigned int *op; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + o.ln = s; if (added != NULL) { ad.type = ADDED_LNAME; @@ -565,6 +580,9 @@ int OBJ_sn2nid(const char *s) ADDED_OBJ ad, *adp; const unsigned int *op; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + o.sn = s; if (added != NULL) { ad.type = ADDED_SNAME; diff --git a/crypto/objects/obj_err.c b/crypto/objects/obj_err.c index 16d6e65e..b32e9f6f 100644 --- a/crypto/objects/obj_err.c +++ b/crypto/objects/obj_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,19 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OBJ_str_functs[] = { - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_ADD_OBJECT, 0), "OBJ_add_object"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_ADD_SIGID, 0), "OBJ_add_sigid"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_CREATE, 0), "OBJ_create"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_DUP, 0), "OBJ_dup"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NAME_NEW_INDEX, 0), "OBJ_NAME_new_index"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2LN, 0), "OBJ_nid2ln"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2OBJ, 0), "OBJ_nid2obj"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2SN, 0), "OBJ_nid2sn"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_TXT2OBJ, 0), "OBJ_txt2obj"}, - {0, NULL} -}; - static const ERR_STRING_DATA OBJ_str_reasons[] = { {ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_OID_EXISTS), "oid exists"}, {ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_UNKNOWN_NID), "unknown nid"}, @@ -37,10 +24,8 @@ static const ERR_STRING_DATA OBJ_str_reasons[] = { int ERR_load_OBJ_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { - ERR_load_strings_const(OBJ_str_functs); + if (ERR_reason_error_string(OBJ_str_reasons[0].error) == NULL) ERR_load_strings_const(OBJ_str_reasons); - } #endif return 1; } diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c index f72ed4ce..6e2152b3 100644 --- a/crypto/ocsp/ocsp_err.c +++ b/crypto/ocsp/ocsp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,33 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OCSP_str_functs[] = { - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_D2I_OCSP_NONCE, 0), "d2i_ocsp_nonce"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_ADD1_STATUS, 0), - "OCSP_basic_add1_status"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_SIGN, 0), "OCSP_basic_sign"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_SIGN_CTX, 0), - "OCSP_basic_sign_ctx"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_VERIFY, 0), "OCSP_basic_verify"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CERT_ID_NEW, 0), "OCSP_cert_id_new"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_DELEGATED, 0), - "ocsp_check_delegated"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_IDS, 0), "ocsp_check_ids"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_ISSUER, 0), "ocsp_check_issuer"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_VALIDITY, 0), - "OCSP_check_validity"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_MATCH_ISSUERID, 0), - "ocsp_match_issuerid"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_PARSE_URL, 0), "OCSP_parse_url"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_REQUEST_SIGN, 0), "OCSP_request_sign"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_REQUEST_VERIFY, 0), - "OCSP_request_verify"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_RESPONSE_GET1_BASIC, 0), - "OCSP_response_get1_basic"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_PARSE_HTTP_LINE1, 0), "parse_http_line1"}, - {0, NULL} -}; - static const ERR_STRING_DATA OCSP_str_reasons[] = { {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, @@ -92,10 +65,8 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { int ERR_load_OCSP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { - ERR_load_strings_const(OCSP_str_functs); + if (ERR_reason_error_string(OCSP_str_reasons[0].error) == NULL) ERR_load_strings_const(OCSP_str_reasons); - } #endif return 1; } diff --git a/ssl/packet.c b/crypto/packet.c similarity index 89% rename from ssl/packet.c rename to crypto/packet.c index 26cf1eb4..75a03176 100644 --- a/ssl/packet.c +++ b/crypto/packet.c @@ -8,7 +8,7 @@ */ #include "internal/cryptlib.h" -#include "packet_locl.h" +#include "internal/packet.h" #include #define DEFAULT_BUF_SIZE 256 @@ -35,7 +35,10 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, } #define GETBUF(p) (((p)->staticbuf != NULL) \ - ? (p)->staticbuf : (unsigned char *)(p)->buf->data) + ? (p)->staticbuf \ + : ((p)->buf != NULL \ + ? (unsigned char *)(p)->buf->data \ + : NULL)) int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) { @@ -46,7 +49,7 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) if (pkt->maxsize - pkt->written < len) return 0; - if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) { + if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) { size_t newlen; size_t reflen; @@ -74,7 +77,8 @@ int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes)) return 0; - *allocbytes += lenbytes; + if (*allocbytes != NULL) + *allocbytes += lenbytes; return 1; } @@ -110,7 +114,7 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) pkt->subs = NULL; return 0; } - pkt->subs->packet_len = lenchars - GETBUF(pkt); + pkt->subs->packet_len = 0; return 1; } @@ -149,6 +153,15 @@ int WPACKET_init(WPACKET *pkt, BUF_MEM *buf) return WPACKET_init_len(pkt, buf, 0); } +int WPACKET_init_null(WPACKET *pkt, size_t lenbytes) +{ + pkt->staticbuf = NULL; + pkt->buf = NULL; + pkt->maxsize = maxmaxsize(lenbytes); + + return wpacket_intern_init_len(pkt, 0); +} + int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) { /* Internal API, so should not fail */ @@ -163,6 +176,9 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) /* Store the |value| of length |len| at location |data| */ static int put_value(unsigned char *data, size_t value, size_t len) { + if (data == NULL) + return 1; + for (data += len - 1; len > 0; len--) { *data = (unsigned char)(value & 0xff); data--; @@ -209,10 +225,14 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) } /* Write out the WPACKET length if needed */ - if (sub->lenbytes > 0 - && !put_value(&GETBUF(pkt)[sub->packet_len], packlen, + if (sub->lenbytes > 0) { + unsigned char *buf = GETBUF(pkt); + + if (buf != NULL + && !put_value(&buf[sub->packet_len], packlen, sub->lenbytes)) return 0; + } if (doclose) { pkt->subs = sub->parent; @@ -293,10 +313,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) return 1; } + sub->packet_len = pkt->written; + if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) return 0; - /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */ - sub->packet_len = lenchars - GETBUF(pkt); return 1; } @@ -354,7 +374,8 @@ int WPACKET_memset(WPACKET *pkt, int ch, size_t len) if (!WPACKET_allocate_bytes(pkt, len, &dest)) return 0; - memset(dest, ch, len); + if (dest != NULL) + memset(dest, ch, len); return 1; } @@ -369,7 +390,8 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len) if (!WPACKET_allocate_bytes(pkt, len, &dest)) return 0; - memcpy(dest, src, len); + if (dest != NULL) + memcpy(dest, src, len); return 1; } @@ -409,7 +431,17 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len) unsigned char *WPACKET_get_curr(WPACKET *pkt) { - return GETBUF(pkt) + pkt->curr; + unsigned char *buf = GETBUF(pkt); + + if (buf == NULL) + return NULL; + + return buf + pkt->curr; +} + +int WPACKET_is_null_buf(WPACKET *pkt) +{ + return pkt->buf == NULL && pkt->staticbuf == NULL; } void WPACKET_cleanup(WPACKET *pkt) diff --git a/crypto/param_build.c b/crypto/param_build.c new file mode 100644 index 00000000..01866b01 --- /dev/null +++ b/crypto/param_build.c @@ -0,0 +1,353 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. 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 "internal/param_build.h" + +#define OSSL_PARAM_ALLOCATED_END 127 + +typedef union { + OSSL_UNION_ALIGN; +} OSSL_PARAM_BLD_BLOCK; + +#define ALIGN_SIZE sizeof(OSSL_PARAM_BLD_BLOCK) + +static size_t bytes_to_blocks(size_t bytes) +{ + return (bytes + ALIGN_SIZE - 1) / ALIGN_SIZE; +} + +static OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key, + int size, size_t alloc, int type, + int secure) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bld->curr >= OSSL_PARAM_BLD_MAX) { + CRYPTOerr(CRYPTO_F_PARAM_PUSH, CRYPTO_R_TOO_MANY_RECORDS); + return NULL; + } + pd = bld->params + bld->curr++; + memset(pd, 0, sizeof(*pd)); + pd->key = key; + pd->type = type; + pd->size = size; + pd->alloc_blocks = bytes_to_blocks(size); + if ((pd->secure = secure) != 0) + bld->secure_blocks += pd->alloc_blocks; + else + bld->total_blocks += pd->alloc_blocks; + return pd; +} + +static int param_push_num(OSSL_PARAM_BLD *bld, const char *key, + void *num, size_t size, int type) +{ + OSSL_PARAM_BLD_DEF *pd = param_push(bld, key, size, size, type, 0); + + if (pd == NULL) + return 0; + if (size > sizeof(pd->num)) { + CRYPTOerr(CRYPTO_F_PARAM_PUSH_NUM, CRYPTO_R_TOO_MANY_BYTES); + return 0; + } + memcpy(&pd->num, num, size); + return 1; +} + +void ossl_param_bld_init(OSSL_PARAM_BLD *bld) +{ + memset(bld, 0, sizeof(*bld)); +} + +int ossl_param_bld_push_int(OSSL_PARAM_BLD *bld, const char *key, int num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int ossl_param_bld_push_uint(OSSL_PARAM_BLD *bld, const char *key, + unsigned int num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int ossl_param_bld_push_long(OSSL_PARAM_BLD *bld, const char *key, + long int num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int ossl_param_bld_push_ulong(OSSL_PARAM_BLD *bld, const char *key, + unsigned long int num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int ossl_param_bld_push_int32(OSSL_PARAM_BLD *bld, const char *key, + int32_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int ossl_param_bld_push_uint32(OSSL_PARAM_BLD *bld, const char *key, + uint32_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int ossl_param_bld_push_int64(OSSL_PARAM_BLD *bld, const char *key, + int64_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int ossl_param_bld_push_uint64(OSSL_PARAM_BLD *bld, const char *key, + uint64_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int ossl_param_bld_push_size_t(OSSL_PARAM_BLD *bld, const char *key, + size_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int ossl_param_bld_push_double(OSSL_PARAM_BLD *bld, const char *key, + double num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL); +} + +int ossl_param_bld_push_BN(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn) +{ + int sz = -1, secure = 0; + OSSL_PARAM_BLD_DEF *pd; + + if (bn != NULL) { + sz = BN_num_bytes(bn); + if (sz < 0) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_BN, + CRYPTO_R_ZERO_LENGTH_NUMBER); + return 0; + } + if (BN_get_flags(bn, BN_FLG_SECURE) == BN_FLG_SECURE) + secure = 1; + } + pd = param_push(bld, key, sz, sz >= 0 ? sz : 0, + OSSL_PARAM_UNSIGNED_INTEGER, secure); + if (pd == NULL) + return 0; + pd->bn = bn; + return 1; +} + +int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, + const char *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize == 0) { + bsize = strlen(buf) + 1; + } else if (bsize > INT_MAX) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING, + CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_UTF8_STRING, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key, + char *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize == 0) { + bsize = strlen(buf) + 1; + } else if (bsize > INT_MAX) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR, + CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_UTF8_PTR, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, + const void *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize > INT_MAX) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING, + CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_OCTET_STRING, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key, + void *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize > INT_MAX) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR, + CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_OCTET_PTR, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param, + OSSL_PARAM_BLD_BLOCK *blk, + OSSL_PARAM_BLD_BLOCK *secure) +{ + size_t i; + OSSL_PARAM_BLD_DEF *pd; + void *p; + + for (i = 0; i < bld->curr; i++) { + pd = bld->params + i; + param[i].key = pd->key; + param[i].data_type = pd->type; + param[i].data_size = pd->size; + param[i].return_size = 0; + + if (pd->secure) { + p = secure; + secure += pd->alloc_blocks; + } else { + p = blk; + blk += pd->alloc_blocks; + } + param[i].data = p; + if (pd->bn != NULL) { + /* BIGNUM */ + BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size); + } else if (pd->type == OSSL_PARAM_OCTET_PTR + || pd->type == OSSL_PARAM_UTF8_PTR) { + /* PTR */ + *(const void **)p = pd->string; + } else if (pd->type == OSSL_PARAM_OCTET_STRING + || pd->type == OSSL_PARAM_UTF8_STRING) { + if (pd->string != NULL) + memcpy(p, pd->string, pd->size); + else + memset(p, 0, pd->size); + } else { + /* Number, but could also be a NULL BIGNUM */ + if (pd->size > sizeof(pd->num)) + memset(p, 0, pd->size); + else if (pd->size > 0) + memcpy(p, &pd->num, pd->size); + } + } + param[i] = OSSL_PARAM_construct_end(); + return param + i; +} + +OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld) +{ + OSSL_PARAM_BLD_BLOCK *blk, *s = NULL; + OSSL_PARAM *params, *last; + const size_t p_blks = bytes_to_blocks((1 + bld->curr) * sizeof(*params)); + const size_t total = ALIGN_SIZE * (p_blks + bld->total_blocks); + const size_t ss = ALIGN_SIZE * bld->secure_blocks; + + if (ss > 0) { + s = OPENSSL_secure_malloc(ss); + if (s == NULL) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM, + CRYPTO_R_SECURE_MALLOC_FAILURE); + return NULL; + } + } + params = OPENSSL_malloc(total); + if (params == NULL) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM, ERR_R_MALLOC_FAILURE); + OPENSSL_secure_free(s); + return NULL; + } + blk = p_blks + (OSSL_PARAM_BLD_BLOCK *)(params); + last = param_bld_convert(bld, params, blk, s); + last->data_size = ss; + last->data = s; + last->data_type = OSSL_PARAM_ALLOCATED_END; + return params; +} + +void ossl_param_bld_free(OSSL_PARAM *params) +{ + if (params != NULL) { + OSSL_PARAM *p; + + for (p = params; p->key != NULL; p++) + ; + if (p->data_type == OSSL_PARAM_ALLOCATED_END) + OPENSSL_secure_clear_free(p->data, p->data_size); + OPENSSL_free(params); + } +} + +OSSL_PARAM *ossl_param_bld_to_param_ex(OSSL_PARAM_BLD *bld, OSSL_PARAM *params, + size_t param_n, void *data, + size_t data_n, void *secure, + size_t secure_n) +{ + if (params == NULL || data == NULL) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX, + CRYPTO_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (param_n < bld->curr + 1) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX, + CRYPTO_R_INSUFFICIENT_PARAM_SIZE); + return NULL; + } + if (data_n < ALIGN_SIZE * bld->total_blocks) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX, + CRYPTO_R_INSUFFICIENT_DATA_SPACE); + return NULL; + } + if (bld->secure_blocks > 0 && secure_n < ALIGN_SIZE * bld->secure_blocks) { + CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX, + CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE); + return NULL; + } + param_bld_convert(bld, params, (OSSL_PARAM_BLD_BLOCK *)data, + (OSSL_PARAM_BLD_BLOCK *)secure); + return params; +} diff --git a/crypto/params.c b/crypto/params.c index 0c9e6f3e..20082ad9 100644 --- a/crypto/params.c +++ b/crypto/params.c @@ -11,6 +11,7 @@ #include #include #include "internal/thread_once.h" +#include "internal/numbers.h" OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key) { @@ -582,13 +583,6 @@ OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf) sizeof(size_t)); } -#ifndef FIPS_MODE -/* - * TODO(3.0): Make this available in FIPS mode. - * - * Temporarily we don't include these functions in FIPS mode to avoid pulling - * in the entire BN sub-library into the module at this point. - */ int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) { BIGNUM *b; @@ -632,7 +626,6 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, bsize); } -#endif int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val) { @@ -693,7 +686,7 @@ int OSSL_PARAM_set_double(OSSL_PARAM *p, double val) return 1; } } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER - && val == (uintmax_t)val) { + && val == (ossl_uintmax_t)val) { p->return_size = sizeof(double); switch (p->data_size) { case sizeof(uint32_t): @@ -710,7 +703,7 @@ int OSSL_PARAM_set_double(OSSL_PARAM *p, double val) return 1; } break; } - } else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) { + } else if (p->data_type == OSSL_PARAM_INTEGER && val == (ossl_intmax_t)val) { p->return_size = sizeof(double); switch (p->data_size) { case sizeof(int32_t): @@ -815,6 +808,8 @@ int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, size_t bsize) { + if (buf != NULL && bsize == 0) + bsize = strlen(buf) + 1; return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize); } diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c new file mode 100644 index 00000000..053b93d2 --- /dev/null +++ b/crypto/params_from_text.c @@ -0,0 +1,224 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. 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 + +/* + * When processing text to params, we're trying to be smart with numbers. + * Instead of handling each specific separate integer type, we use a bignum + * and ensure that it isn't larger than the expected size, and we then make + * sure it is the expected size... if there is one given. + * (if the size can be arbitrary, then we give whatever we have) + */ + +static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key, + const char *value, size_t value_n, + /* Output parameters */ + const OSSL_PARAM **paramdef, int *ishex, + size_t *buf_n, BIGNUM **tmpbn) +{ + const OSSL_PARAM *p; + + /* + * ishex is used to translate legacy style string controls in hex format + * to octet string parameters. + */ + *ishex = strncmp(key, "hex", 3) == 0; + + if (*ishex) + key += 3; + + p = *paramdef = OSSL_PARAM_locate_const(paramdefs, key); + if (p == NULL) + return 0; + + switch (p->data_type) { + case OSSL_PARAM_INTEGER: + case OSSL_PARAM_UNSIGNED_INTEGER: + if (*ishex) + BN_hex2bn(tmpbn, value); + else + BN_dec2bn(tmpbn, value); + + if (*tmpbn == NULL) + return 0; + + /* + * 2s complement negate, part 1 + * + * BN_bn2nativepad puts the absolute value of the number in the + * buffer, i.e. if it's negative, we need to deal with it. We do + * it by subtracting 1 here and inverting the bytes in + * construct_from_text() below. + */ + if (p->data_type == OSSL_PARAM_INTEGER && BN_is_negative(*tmpbn) + && !BN_sub_word(*tmpbn, 1)) { + return 0; + } + + *buf_n = BN_num_bytes(*tmpbn); + + /* + * TODO(v3.0) is this the right way to do this? This code expects + * a zero data size to simply mean "arbitrary size". + */ + if (p->data_size > 0) { + if (*buf_n >= p->data_size) { + CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER); + /* Since this is a different error, we don't break */ + return 0; + } + /* Change actual size to become the desired size. */ + *buf_n = p->data_size; + } + break; + case OSSL_PARAM_UTF8_STRING: + if (*ishex) { + CRYPTOerr(0, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *buf_n = strlen(value) + 1; + break; + case OSSL_PARAM_OCTET_STRING: + if (*ishex) { + *buf_n = strlen(value) >> 1; + } else { + *buf_n = value_n; + } + break; + } + + return 1; +} + +static int construct_from_text(OSSL_PARAM *to, const OSSL_PARAM *paramdef, + const char *value, size_t value_n, int ishex, + void *buf, size_t buf_n, BIGNUM *tmpbn) +{ + if (buf == NULL) + return 0; + + if (buf_n > 0) { + switch (paramdef->data_type) { + case OSSL_PARAM_INTEGER: + case OSSL_PARAM_UNSIGNED_INTEGER: + /* + { + if ((new_value = OPENSSL_malloc(new_value_n)) == NULL) { + BN_free(a); + break; + } + */ + + BN_bn2nativepad(tmpbn, buf, buf_n); + + /* + * 2s complement negate, part two. + * + * Because we did the first part on the BIGNUM itself, we can just + * invert all the bytes here and be done with it. + */ + if (paramdef->data_type == OSSL_PARAM_INTEGER + && BN_is_negative(tmpbn)) { + unsigned char *cp; + size_t i = buf_n; + + for (cp = buf; i-- > 0; cp++) + *cp ^= 0xFF; + } + break; + case OSSL_PARAM_UTF8_STRING: + strncpy(buf, value, buf_n); + break; + case OSSL_PARAM_OCTET_STRING: + if (ishex) { + size_t l = 0; + + if (!OPENSSL_hexstr2buf_ex(buf, buf_n, &l, value)) + return 0; + } else { + memcpy(buf, value, buf_n); + } + break; + } + } + + *to = *paramdef; + to->data = buf; + to->data_size = buf_n; + to->return_size = 0; + + return 1; +} + +int OSSL_PARAM_construct_from_text(OSSL_PARAM *to, + const OSSL_PARAM *paramdefs, + const char *key, const char *value, + size_t value_n, + void *buf, size_t *buf_n) +{ + const OSSL_PARAM *paramdef = NULL; + int ishex = 0; + BIGNUM *tmpbn = NULL; + int ok = 0; + + if (to == NULL || paramdefs == NULL) + return 0; + + if (!prepare_from_text(paramdefs, key, value, value_n, + ¶mdef, &ishex, buf_n, &tmpbn)) + return 0; + + /* + * The user gets the expected buffer size back even if the buffer isn't + * allocated. + */ + if (buf == NULL) + return 1; + + ok = construct_from_text(to, paramdef, value, value_n, ishex, + buf, *buf_n, tmpbn); + BN_free(tmpbn); + return ok; +} + +int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, + const OSSL_PARAM *paramdefs, + const char *key, const char *value, + size_t value_n) +{ + const OSSL_PARAM *paramdef = NULL; + int ishex = 0; + void *buf = NULL; + size_t buf_n = 0; + BIGNUM *tmpbn = NULL; + int ok = 0; + + if (to == NULL || paramdefs == NULL) + return 0; + + if (!prepare_from_text(paramdefs, key, value, value_n, + ¶mdef, &ishex, &buf_n, &tmpbn)) + return 0; + + if ((buf = OPENSSL_zalloc(buf_n > 0 ? buf_n : 1)) == NULL) { + CRYPTOerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + + ok = construct_from_text(to, paramdef, value, value_n, ishex, + buf, buf_n, tmpbn); + BN_free(tmpbn); + if (!ok) + OPENSSL_free(buf); + return ok; +} diff --git a/crypto/pariscid.pl b/crypto/pariscid.pl index 47fdce95..aafcb2a9 100644 --- a/crypto/pariscid.pl +++ b/crypto/pariscid.pl @@ -7,9 +7,12 @@ # https://www.openssl.org/source/license.html -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c index 80c65f78..014aade1 100644 --- a/crypto/pem/pem_err.c +++ b/crypto/pem/pem_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,63 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PEM_str_functs[] = { - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_DSS, 0), "b2i_dss"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_PVK_BIO, 0), "b2i_PVK_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_RSA, 0), "b2i_rsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_CHECK_BITLEN_DSA, 0), "check_bitlen_dsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_CHECK_BITLEN_RSA, 0), "check_bitlen_rsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, 0), - "d2i_PKCS8PrivateKey_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_FP, 0), - "d2i_PKCS8PrivateKey_fp"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_B2I, 0), "do_b2i"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_B2I_BIO, 0), "do_b2i_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_BLOB_HEADER, 0), "do_blob_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_I2B, 0), "do_i2b"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PK8PKEY, 0), "do_pk8pkey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PK8PKEY_FP, 0), "do_pk8pkey_fp"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PVK_BODY, 0), "do_PVK_body"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PVK_HEADER, 0), "do_PVK_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_GET_HEADER_AND_DATA, 0), - "get_header_and_data"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_GET_NAME, 0), "get_name"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_I2B_PVK, 0), "i2b_PVK"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_I2B_PVK_BIO, 0), "i2b_PVK_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_LOAD_IV, 0), "load_iv"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_READ, 0), "PEM_ASN1_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_READ_BIO, 0), "PEM_ASN1_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_WRITE, 0), "PEM_ASN1_write"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_WRITE_BIO, 0), "PEM_ASN1_write_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DEF_CALLBACK, 0), "PEM_def_callback"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, 0), "PEM_do_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_GET_EVP_CIPHER_INFO, 0), - "PEM_get_EVP_CIPHER_INFO"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ, 0), "PEM_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, 0), "PEM_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_DHPARAMS, 0), - "PEM_read_bio_DHparams"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_EX, 0), "PEM_read_bio_ex"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PARAMETERS, 0), - "PEM_read_bio_Parameters"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, 0), - "PEM_read_bio_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_DHPARAMS, 0), "PEM_read_DHparams"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_PRIVATEKEY, 0), - "PEM_read_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_SIGNFINAL, 0), "PEM_SignFinal"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE, 0), "PEM_write"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE_BIO, 0), "PEM_write_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE_PRIVATEKEY, 0), - "PEM_write_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_READ, 0), "PEM_X509_INFO_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_READ_BIO, 0), - "PEM_X509_INFO_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_WRITE_BIO, 0), - "PEM_X509_INFO_write_bio"}, - {0, NULL} -}; - static const ERR_STRING_DATA PEM_str_reasons[] = { {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_BASE64_DECODE), "bad base64 decode"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT), "bad decrypt"}, @@ -117,10 +60,8 @@ static const ERR_STRING_DATA PEM_str_reasons[] = { int ERR_load_PEM_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { - ERR_load_strings_const(PEM_str_functs); + if (ERR_reason_error_string(PEM_str_reasons[0].error) == NULL) ERR_load_strings_const(PEM_str_reasons); - } #endif return 1; } diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 348a92b6..adf29144 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -274,6 +274,9 @@ static EVP_PKEY *b2i_dss(const unsigned char **in, if (!read_lebn(&p, 20, &priv_key)) goto memerr; + /* Set constant time flag before public key calculation */ + BN_set_flags(priv_key, BN_FLG_CONSTTIME); + /* Calculate public key */ pub_key = BN_new(); if (pub_key == NULL) diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index dd07b6de..c3ad2bf7 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,58 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PKCS12_str_functs[] = { - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_ASC2UNI, 0), "OPENSSL_asc2uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UNI2ASC, 0), "OPENSSL_uni2asc"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UNI2UTF8, 0), - "OPENSSL_uni2utf8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UTF82UNI, 0), - "OPENSSL_utf82uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_CREATE, 0), "PKCS12_create"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_GEN_MAC, 0), "PKCS12_gen_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_INIT, 0), "PKCS12_init"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, 0), - "PKCS12_item_decrypt_d2i"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, 0), - "PKCS12_item_i2d_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, 0), - "PKCS12_item_pack_safebag"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_ASC, 0), - "PKCS12_key_gen_asc"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_UNI, 0), - "PKCS12_key_gen_uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_UTF8, 0), - "PKCS12_key_gen_utf8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_NEWPASS, 0), "PKCS12_newpass"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PACK_P7DATA, 0), - "PKCS12_pack_p7data"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PACK_P7ENCDATA, 0), - "PKCS12_pack_p7encdata"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PARSE, 0), "PKCS12_parse"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PBE_CRYPT, 0), - "PKCS12_pbe_crypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PBE_KEYIVGEN, 0), - "PKCS12_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, 0), - "PKCS12_SAFEBAG_create0_p8inf"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, 0), - "PKCS12_SAFEBAG_create0_pkcs8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, 0), - "PKCS12_SAFEBAG_create_pkcs8_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SETUP_MAC, 0), - "PKCS12_setup_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SET_MAC, 0), "PKCS12_set_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_AUTHSAFES, 0), - "PKCS12_unpack_authsafes"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_P7DATA, 0), - "PKCS12_unpack_p7data"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_VERIFY_MAC, 0), - "PKCS12_verify_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS8_ENCRYPT, 0), "PKCS8_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS8_SET0_PBE, 0), "PKCS8_set0_pbe"}, - {0, NULL} -}; - static const ERR_STRING_DATA PKCS12_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, @@ -108,10 +56,8 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { int ERR_load_PKCS12_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { - ERR_load_strings_const(PKCS12_str_functs); + if (ERR_reason_error_string(PKCS12_str_reasons[0].error) == NULL) ERR_load_strings_const(PKCS12_str_reasons); - } #endif return 1; } diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 38277095..030718a1 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -137,7 +137,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, } static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, - PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) + PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey, + size_t fixlen) { EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; @@ -170,7 +171,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, } if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) { + ri->enc_key->data, ri->enc_key->length) <= 0 + || eklen == 0 + || (fixlen != 0 && eklen != fixlen)) { ret = 0; PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); goto err; @@ -499,13 +502,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, + EVP_CIPHER_key_length(evp_cipher)) < 0) goto err; ERR_clear_error(); } } else { /* Only exit on fatal errors, not decrypt failure */ - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) goto err; ERR_clear_error(); } @@ -834,11 +838,29 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) goto err; + /* + * TODO(3.0): This causes problems when providers are in use, so disabled + * for now. Can we get rid of this completely? AFAICT this ctrl has never + * been used since it was first put in. All internal implementations just + * return 1 and ignore this ctrl and have always done so by the looks of + * things. To fix this we could convert this ctrl into a param, which would + * require us to send all the signer info data as a set of params...but that + * is non-trivial and since this isn't used by anything it may be better + * just to remove it. The original commit that added it had this + * justification in CHANGES: + * + * "During PKCS7 signing pass the PKCS7 SignerInfo structure to the + * EVP_PKEY_METHOD before and after signing via the + * EVP_PKEY_CTRL_PKCS7_SIGN ctrl. It can then customise the structure + * before and/or after signing if necessary." + */ +#if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } +#endif alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); @@ -856,11 +878,29 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) goto err; + /* + * TODO(3.0): This causes problems when providers are in use, so disabled + * for now. Can we get rid of this completely? AFAICT this ctrl has never + * been used since it was first put in. All internal implementations just + * return 1 and ignore this ctrl and have always done so by the looks of + * things. To fix this we could convert this ctrl into a param, which would + * require us to send all the signer info data as a set of params...but that + * is non-trivial and since this isn't used by anything it may be better + * just to remove it. The original commit that added it had this + * justification in CHANGES: + * + * "During PKCS7 signing pass the PKCS7 SignerInfo structure to the + * EVP_PKEY_METHOD before and after signing via the + * EVP_PKEY_CTRL_PKCS7_SIGN ctrl. It can then customise the structure + * before and/or after signing if necessary." + */ +#if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } +#endif EVP_MD_CTX_free(mctx); diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c index c6138216..f7b87d55 100644 --- a/crypto/pkcs7/pkcs7err.c +++ b/crypto/pkcs7/pkcs7err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,63 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PKCS7_str_functs[] = { - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, 0), - "do_pkcs7_signed_attrib"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, 0), - "PKCS7_add0_attrib_signing_time"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, 0), - "PKCS7_add_attrib_smimecap"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_CERTIFICATE, 0), - "PKCS7_add_certificate"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_CRL, 0), "PKCS7_add_crl"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, 0), - "PKCS7_add_recipient_info"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_SIGNATURE, 0), - "PKCS7_add_signature"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_SIGNER, 0), "PKCS7_add_signer"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_BIO_ADD_DIGEST, 0), - "PKCS7_bio_add_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, 0), - "pkcs7_copy_existing_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_CTRL, 0), "PKCS7_ctrl"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATADECODE, 0), "PKCS7_dataDecode"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAFINAL, 0), "PKCS7_dataFinal"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAINIT, 0), "PKCS7_dataInit"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAVERIFY, 0), "PKCS7_dataVerify"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DECRYPT, 0), "PKCS7_decrypt"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DECRYPT_RINFO, 0), - "pkcs7_decrypt_rinfo"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ENCODE_RINFO, 0), - "pkcs7_encode_rinfo"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ENCRYPT, 0), "PKCS7_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_FINAL, 0), "PKCS7_final"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_FIND_DIGEST, 0), - "PKCS7_find_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_GET0_SIGNERS, 0), - "PKCS7_get0_signers"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_RECIP_INFO_SET, 0), - "PKCS7_RECIP_INFO_set"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_CIPHER, 0), "PKCS7_set_cipher"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_CONTENT, 0), - "PKCS7_set_content"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_DIGEST, 0), "PKCS7_set_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_TYPE, 0), "PKCS7_set_type"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGN, 0), "PKCS7_sign"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNATUREVERIFY, 0), - "PKCS7_signatureVerify"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNER_INFO_SET, 0), - "PKCS7_SIGNER_INFO_set"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNER_INFO_SIGN, 0), - "PKCS7_SIGNER_INFO_sign"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 0), - "PKCS7_sign_add_signer"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIMPLE_SMIMECAP, 0), - "PKCS7_simple_smimecap"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_VERIFY, 0), "PKCS7_verify"}, - {0, NULL} -}; - static const ERR_STRING_DATA PKCS7_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, @@ -147,10 +90,8 @@ static const ERR_STRING_DATA PKCS7_str_reasons[] = { int ERR_load_PKCS7_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { - ERR_load_strings_const(PKCS7_str_functs); + if (ERR_reason_error_string(PKCS7_str_reasons[0].error) == NULL) ERR_load_strings_const(PKCS7_str_reasons); - } #endif return 1; } diff --git a/crypto/poly1305/asm/poly1305-armv4.pl b/crypto/poly1305/asm/poly1305-armv4.pl index 38622af1..8d604982 100755 --- a/crypto/poly1305/asm/poly1305-armv4.pl +++ b/crypto/poly1305/asm/poly1305-armv4.pl @@ -28,9 +28,10 @@ # the cost of 15/12% regression on Cortex-A5/A7, it's even possible # to improve Cortex-A9 result, but then A5/A7 loose more than 20%; -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -38,9 +39,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } ($ctx,$inp,$len,$padbit)=map("r$_",(0..3)); diff --git a/crypto/poly1305/asm/poly1305-armv8.pl b/crypto/poly1305/asm/poly1305-armv8.pl index b5dd61e1..5ebc5729 100755 --- a/crypto/poly1305/asm/poly1305-armv8.pl +++ b/crypto/poly1305/asm/poly1305-armv8.pl @@ -35,15 +35,18 @@ # i.e. measured result is worse than expected, presumably binary # translator is not almighty; -$flavour=shift; -$output=shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3)); diff --git a/crypto/poly1305/asm/poly1305-c64xplus.pl b/crypto/poly1305/asm/poly1305-c64xplus.pl index b858e807..2bcdced7 100755 --- a/crypto/poly1305/asm/poly1305-c64xplus.pl +++ b/crypto/poly1305/asm/poly1305-c64xplus.pl @@ -26,8 +26,7 @@ # time dependent on input length. This module on the other hand is free # from such limitation. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; ($CTXA,$INPB,$LEN,$PADBIT)=("A4","B4","A6","B6"); ($H0,$H1,$H2,$H3,$H4,$H4a)=("A8","B8","A10","B10","B2",$LEN); diff --git a/crypto/poly1305/asm/poly1305-mips.pl b/crypto/poly1305/asm/poly1305-mips.pl index 65d6b5cd..a2504347 100755 --- a/crypto/poly1305/asm/poly1305-mips.pl +++ b/crypto/poly1305/asm/poly1305-mips.pl @@ -56,7 +56,11 @@ # ###################################################################### -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; die "MIPS64 only" unless ($flavour =~ /64|n32/i); @@ -431,7 +435,7 @@ poly1305_emit: ___ } -$output=pop and open STDOUT,">$output"; +$output and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/poly1305/asm/poly1305-ppc.pl b/crypto/poly1305/asm/poly1305-ppc.pl index 2770f5e7..fa11afc6 100755 --- a/crypto/poly1305/asm/poly1305-ppc.pl +++ b/crypto/poly1305/asm/poly1305-ppc.pl @@ -52,7 +52,10 @@ # not, not one usable in the context. Improvement is ~40% over -m64 # result above and is ~1.43 on little-endian systems. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -79,7 +82,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T; diff --git a/crypto/poly1305/asm/poly1305-ppcfp.pl b/crypto/poly1305/asm/poly1305-ppcfp.pl index e5635133..71091656 100755 --- a/crypto/poly1305/asm/poly1305-ppcfp.pl +++ b/crypto/poly1305/asm/poly1305-ppcfp.pl @@ -27,7 +27,10 @@ # POWER7 3.50/+30% # POWER8 3.75/+10% -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -54,7 +57,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $LOCALS=6*$SIZE_T; $FRAME=$LOCALS+6*8+18*8; diff --git a/crypto/poly1305/asm/poly1305-s390x.pl b/crypto/poly1305/asm/poly1305-s390x.pl index 73efdd9e..7f1f8347 100755 --- a/crypto/poly1305/asm/poly1305-s390x.pl +++ b/crypto/poly1305/asm/poly1305-s390x.pl @@ -47,7 +47,10 @@ use FindBin qw($Bin); use lib "$Bin/../.."; use perlasm::s390x qw(:DEFAULT :LD :GE :EI :MI1 :VX AUTOLOAD LABEL INCLUDE); -my $flavour = shift; +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my ($z,$SIZE_T); if ($flavour =~ /3[12]/) { @@ -58,9 +61,6 @@ if ($flavour =~ /3[12]/) { $SIZE_T=8; } -my $output; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} - my $stdframe=16*$SIZE_T+4*8; my $sp="%r15"; diff --git a/crypto/poly1305/asm/poly1305-sparcv9.pl b/crypto/poly1305/asm/poly1305-sparcv9.pl index 442b2e2c..d7b67b85 100755 --- a/crypto/poly1305/asm/poly1305-sparcv9.pl +++ b/crypto/poly1305/asm/poly1305-sparcv9.pl @@ -41,17 +41,16 @@ # (***) Multi-process benchmark saturates at ~12.5x single-process # result on 8-core processor, or ~21GBps per 2.85GHz socket. -my $output = pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +open STDOUT,">$output" if $output; my ($ctx,$inp,$len,$padbit,$shl,$shr) = map("%i$_",(0..5)); my ($r0,$r1,$r2,$r3,$s1,$s2,$s3,$h4) = map("%l$_",(0..7)); my ($h0,$h1,$h2,$h3, $t0,$t1,$t2) = map("%o$_",(0..5,7)); my ($d0,$d1,$d2,$d3) = map("%g$_",(1..4)); -my $output = pop; -open STDOUT,">$stdout"; - $code.=<<___; #include "sparc_arch.h" diff --git a/crypto/poly1305/asm/poly1305-x86.pl b/crypto/poly1305/asm/poly1305-x86.pl index e8cbe9fd..9aa1bc16 100755 --- a/crypto/poly1305/asm/poly1305-x86.pl +++ b/crypto/poly1305/asm/poly1305-x86.pl @@ -47,8 +47,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/poly1305/asm/poly1305-x86_64.pl index 12f97176..c27d8779 100755 --- a/crypto/poly1305/asm/poly1305-x86_64.pl +++ b/crypto/poly1305/asm/poly1305-x86_64.pl @@ -63,9 +63,10 @@ # (***) strangely enough performance seems to vary from core to core, # listed result is best case; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -94,7 +95,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx"); diff --git a/crypto/poly1305/build.info b/crypto/poly1305/build.info index 064c2599..29cdf4c8 100644 --- a/crypto/poly1305/build.info +++ b/crypto/poly1305/build.info @@ -29,22 +29,21 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -SOURCE[../../libcrypto]=poly1305_ameth.c poly1305_meth.c poly1305.c $POLY1305ASM +SOURCE[../../libcrypto]=poly1305_ameth.c poly1305.c $POLY1305ASM DEFINE[../../libcrypto]=$POLY1305DEF -GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl INCLUDE[poly1305-sparcv9.o]=.. -GENERATE[poly1305-x86.s]=asm/poly1305-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[poly1305-x86_64.s]=asm/poly1305-x86_64.pl $(PERLASM_SCHEME) -GENERATE[poly1305-ppc.s]=asm/poly1305-ppc.pl $(PERLASM_SCHEME) -GENERATE[poly1305-ppcfp.s]=asm/poly1305-ppcfp.pl $(PERLASM_SCHEME) -GENERATE[poly1305-armv4.S]=asm/poly1305-armv4.pl $(PERLASM_SCHEME) +GENERATE[poly1305-x86.s]=asm/poly1305-x86.pl +GENERATE[poly1305-x86_64.s]=asm/poly1305-x86_64.pl +GENERATE[poly1305-ppc.s]=asm/poly1305-ppc.pl +GENERATE[poly1305-ppcfp.s]=asm/poly1305-ppcfp.pl +GENERATE[poly1305-armv4.S]=asm/poly1305-armv4.pl INCLUDE[poly1305-armv4.o]=.. -GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl $(PERLASM_SCHEME) +GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl INCLUDE[poly1305-armv8.o]=.. -GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME) +GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl INCLUDE[poly1305-mips.o]=.. -GENERATE[poly1305-c64xplus.S]=asm/poly1305-c64xplus.pl $(PERLASM_SCHEME) +GENERATE[poly1305-c64xplus.S]=asm/poly1305-c64xplus.pl INCLUDE[poly1305-s390x.o]=.. -GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl $(PERLASM_SCHEME) +GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl diff --git a/crypto/poly1305/poly1305_meth.c b/crypto/poly1305/poly1305_meth.c deleted file mode 100644 index f1ade58b..00000000 --- a/crypto/poly1305/poly1305_meth.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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/evp_int.h" -#include "internal/poly1305.h" -#include "internal/cryptlib.h" -#include "poly1305_local.h" - -/* typedef EVP_MAC_IMPL */ -struct evp_mac_impl_st { - POLY1305 *ctx; /* poly1305 context */ -}; - -static EVP_MAC_IMPL *poly1305_new(void) -{ - EVP_MAC_IMPL *ctx; - - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL - || (ctx->ctx = OPENSSL_zalloc(sizeof(POLY1305))) == NULL) { - OPENSSL_free(ctx); - return 0; - } - return ctx; -} - -static void poly1305_free(EVP_MAC_IMPL *ctx) -{ - if (ctx != NULL) { - OPENSSL_free(ctx->ctx); - OPENSSL_free(ctx); - } -} - -static EVP_MAC_IMPL *poly1305_dup(const EVP_MAC_IMPL *src) -{ - EVP_MAC_IMPL *dst; - - dst = poly1305_new(); - if (dst == NULL) - return NULL; - - *dst->ctx = *src->ctx; - - return dst; -} - -static size_t poly1305_size(EVP_MAC_IMPL *ctx) -{ - return POLY1305_DIGEST_SIZE; -} - -static int poly1305_init(EVP_MAC_IMPL *ctx) -{ - /* initialize the context in MAC_ctrl function */ - return 1; -} - -static int poly1305_update(EVP_MAC_IMPL *ctx, const unsigned char *data, - size_t datalen) -{ - POLY1305 *poly_ctx = ctx->ctx; - - /* poly1305 has nothing to return in its update function */ - Poly1305_Update(poly_ctx, data, datalen); - return 1; -} - -static int poly1305_final(EVP_MAC_IMPL *ctx, unsigned char *out) -{ - POLY1305 *poly_ctx = ctx->ctx; - - Poly1305_Final(poly_ctx, out); - return 1; -} - -static int poly1305_ctrl(EVP_MAC_IMPL *ctx, int cmd, va_list args) -{ - POLY1305 *poly_ctx = ctx->ctx; - unsigned char *key; - size_t keylen; - - switch (cmd) { - case EVP_MAC_CTRL_SET_KEY: - key = va_arg(args, unsigned char *); - keylen = va_arg(args, size_t); - - if (keylen != POLY1305_KEY_SIZE) { - EVPerr(EVP_F_POLY1305_CTRL, EVP_R_INVALID_KEY_LENGTH); - return 0; - } - Poly1305_Init(poly_ctx, key); - return 1; - default: - return -2; - } - return 1; -} - -static int poly1305_ctrl_int(EVP_MAC_IMPL *ctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = poly1305_ctrl(ctx, cmd, args); - va_end(args); - - return rv; -} - -static int poly1305_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen) -{ - return poly1305_ctrl_int(ctx, cmd, buf, buflen); -} - -static int poly1305_ctrl_str(EVP_MAC_IMPL *ctx, - const char *type, const char *value) -{ - if (value == NULL) - return 0; - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY, - value); - return -2; -} - -const EVP_MAC poly1305_meth = { - EVP_MAC_POLY1305, - poly1305_new, - poly1305_dup, - poly1305_free, - poly1305_size, - poly1305_init, - poly1305_update, - poly1305_final, - poly1305_ctrl, - poly1305_ctrl_str -}; diff --git a/crypto/ppccap.c b/crypto/ppccap.c index 9109c4d3..e540db14 100644 --- a/crypto/ppccap.c +++ b/crypto/ppccap.c @@ -145,8 +145,9 @@ int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) return 1; } # endif +#endif /* FIPS_MODE */ -# ifdef ECP_NISTZ256_ASM +#ifdef ECP_NISTZ256_ASM void ecp_nistz256_mul_mont(unsigned long res[4], const unsigned long a[4], const unsigned long b[4]); @@ -168,8 +169,7 @@ void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]) ecp_nistz256_mul_mont(res, in, one); } -# endif -#endif /* FIPS_MODE */ +#endif static sigjmp_buf ill_jmp; static void ill_handler(int sig) diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl index 0c1e1247..de5d7e26 100755 --- a/crypto/ppccpuid.pl +++ b/crypto/ppccpuid.pl @@ -7,14 +7,18 @@ # https://www.openssl.org/source/license.html -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($flavour=~/64/) { $CMPLI="cmpldi"; diff --git a/crypto/property/property.c b/crypto/property/property.c index 4c328ffb..e94c5de8 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -25,6 +25,7 @@ #define IMPL_CACHE_FLUSH_THRESHOLD 500 typedef struct { + const OSSL_PROVIDER *provider; OSSL_PROPERTY_LIST *properties; void *method; void (*method_destruct)(void *); @@ -58,9 +59,9 @@ struct ossl_method_store_st { }; typedef struct { - OSSL_METHOD_STORE *store; LHASH_OF(QUERY) *cache; size_t nelem; + uint32_t seed; } IMPL_CACHE_FLUSH; DEFINE_SPARSE_ARRAY_OF(ALGORITHM); @@ -83,12 +84,6 @@ int ossl_property_unlock(OSSL_METHOD_STORE *p) return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0; } -static openssl_ctx_run_once_fn do_method_store_init; -int do_method_store_init(OPENSSL_CTX *ctx) -{ - return ossl_property_parse_init(ctx); -} - static unsigned long query_hash(const QUERY *a) { return OPENSSL_LH_strhash(a->query); @@ -131,11 +126,6 @@ OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx) { OSSL_METHOD_STORE *res; - if (!openssl_ctx_run_once(ctx, - OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX, - do_method_store_init)) - return NULL; - res = OPENSSL_zalloc(sizeof(*res)); if (res != NULL) { res->ctx = ctx; @@ -173,13 +163,15 @@ static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg) return ossl_sa_ALGORITHM_set(store->algs, alg->nid, alg); } -int ossl_method_store_add(OSSL_METHOD_STORE *store, - int nid, const char *properties, - void *method, void (*method_destruct)(void *)) +int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, + int nid, const char *properties, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)) { ALGORITHM *alg = NULL; IMPLEMENTATION *impl; int ret = 0; + int i; if (nid <= 0 || method == NULL || store == NULL) return 0; @@ -190,6 +182,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, impl = OPENSSL_malloc(sizeof(*impl)); if (impl == NULL) return 0; + if (method_up_ref != NULL && !method_up_ref(method)) { + OPENSSL_free(impl); + return 0; + } + impl->provider = prov; impl->method = method; impl->method_destruct = method_destruct; @@ -219,8 +216,16 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, goto err; } - /* Push onto stack */ - if (sk_IMPLEMENTATION_push(alg->impls, impl)) + /* Push onto stack if there isn't one there already */ + for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) { + const IMPLEMENTATION *tmpimpl = sk_IMPLEMENTATION_value(alg->impls, i); + + if (tmpimpl->provider == impl->provider + && tmpimpl->properties == impl->properties) + break; + } + if (i == sk_IMPLEMENTATION_num(alg->impls) + && sk_IMPLEMENTATION_push(alg->impls, impl)) ret = 1; ossl_property_unlock(store); if (ret == 0) @@ -279,6 +284,10 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, int ret = 0; int j, best = -1, score, optional; +#ifndef FIPS_MODE + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + if (nid <= 0 || method == NULL || store == NULL) return 0; @@ -376,37 +385,40 @@ IMPLEMENT_LHASH_DOALL_ARG(QUERY, IMPL_CACHE_FLUSH); /* * Flush an element from the query cache (perhaps). * - * In order to avoid taking a write lock to keep accurate LRU information or - * using atomic operations to approximate similar, the procedure used here - * is to stochastically flush approximately half the cache. Since generating - * random numbers is relatively expensive, we produce them in blocks and - * consume them as we go, saving generated bits between generations of flushes. + * In order to avoid taking a write lock or using atomic operations + * to keep accurate least recently used (LRU) or least frequently used + * (LFU) information, the procedure used here is to stochastically + * flush approximately half the cache. * - * This procedure isn't ideal, LRU would be better. However, in normal - * operation, reaching a full cache would be quite unexpected. It means - * that no steady state of algorithm queries has been reached. I.e. it is most - * likely an attack of some form. A suboptimal clearance strategy that doesn't - * degrade performance of the normal case is preferable to a more refined - * approach that imposes a performance impact. + * This procedure isn't ideal, LRU or LFU would be better. However, + * in normal operation, reaching a full cache would be unexpected. + * It means that no steady state of algorithm queries has been reached. + * That is, it is most likely an attack of some form. A suboptimal clearance + * strategy that doesn't degrade performance of the normal case is + * preferable to a more refined approach that imposes a performance + * impact. */ static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state) { -#if !defined(FIPS_MODE) -/* TODO(3.0): No RAND_bytes yet in FIPS module. Add this back when available */ - OSSL_METHOD_STORE *store = state->store; - unsigned int n; + uint32_t n; - if (store->nbits == 0) { - if (!RAND_bytes(store->rand_bits, sizeof(store->rand_bits))) - return; - store->nbits = sizeof(store->rand_bits) * 8; - } - n = --store->nbits; - if ((store->rand_bits[n >> 3] & (1 << (n & 7))) != 0) + /* + * Implement the 32 bit xorshift as suggested by George Marsaglia in: + * https://doi.org/10.18637/jss.v008.i14 + * + * This is a very fast PRNG so there is no need to extract bits one at a + * time and use the entire value each time. + */ + n = state->seed; + n ^= n << 13; + n ^= n >> 17; + n ^= n << 5; + state->seed = n; + + if ((n & 1) != 0) OPENSSL_free(lh_QUERY_delete(state->cache, c)); else state->nelem++; -#endif /* !defined(FIPS_MODE) */ } static void impl_cache_flush_one_alg(ossl_uintmax_t idx, ALGORITHM *alg, @@ -424,9 +436,10 @@ static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store) IMPL_CACHE_FLUSH state; state.nelem = 0; - state.store = store; - ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state); + if ((state.seed = OPENSSL_rdtsc()) == 0) + state.seed = 1; store->need_flush = 0; + ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state); store->nelem = state.nelem; } @@ -480,7 +493,8 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, if (method == NULL) { elem.query = prop_query; - lh_QUERY_delete(alg->cache, &elem); + if (lh_QUERY_delete(alg->cache, &elem) != NULL) + store->nelem--; ossl_property_unlock(store); return 1; } @@ -489,11 +503,13 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, p->query = p->body; p->method = method; memcpy((char *)p->query, prop_query, len + 1); - if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) + if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) { OPENSSL_free(old); - if (old != NULL || !lh_QUERY_error(alg->cache)) { - store->nelem++; - if (store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD) + ossl_property_unlock(store); + return 1; + } + if (!lh_QUERY_error(alg->cache)) { + if (++store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD) store->need_flush = 1; ossl_property_unlock(store); return 1; diff --git a/crypto/property/property_err.c b/crypto/property/property_err.c index 619e5e7d..477dedfd 100644 --- a/crypto/property/property_err.c +++ b/crypto/property/property_err.c @@ -13,19 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PROP_str_functs[] = { - {ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_PROPERTY, 0), - "ossl_parse_property"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_QUERY, 0), "ossl_parse_query"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_HEX, 0), "parse_hex"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NAME, 0), "parse_name"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NUMBER, 0), "parse_number"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_OCT, 0), "parse_oct"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_STRING, 0), "parse_string"}, - {ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_UNQUOTED, 0), "parse_unquoted"}, - {0, NULL} -}; - static const ERR_STRING_DATA PROP_str_reasons[] = { {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NAME_TOO_LONG), "name too long"}, {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_ASCII_CHARACTER), @@ -52,10 +39,8 @@ static const ERR_STRING_DATA PROP_str_reasons[] = { int ERR_load_PROP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PROP_str_functs[0].error) == NULL) { - ERR_load_strings_const(PROP_str_functs); + if (ERR_reason_error_string(PROP_str_reasons[0].error) == NULL) ERR_load_strings_const(PROP_str_reasons); - } #endif return 1; } diff --git a/crypto/property/property_lcl.h b/crypto/property/property_lcl.h index 5fa34cea..25cfde46 100644 --- a/crypto/property/property_lcl.h +++ b/crypto/property/property_lcl.h @@ -21,7 +21,6 @@ OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, int create); /* Property list functions */ -int ossl_property_parse_init(OPENSSL_CTX *ctx); 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, diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 0b4dcfc8..c17b0dde 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -91,8 +91,8 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, for (;;) { if (!ossl_isalpha(*s)) { - PROPerr(PROP_F_PARSE_NAME, PROP_R_NOT_AN_IDENTIFIER); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER, + "HERE-->%s", *t); return 0; } do { @@ -112,8 +112,7 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, } name[i] = '\0'; if (err) { - PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NAME_TOO_LONG, "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -132,8 +131,8 @@ static int parse_number(const char *t[], PROPERTY_DEFINITION *res) v = v * 10 + (*s++ - '0'); } while (ossl_isdigit(*s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_NUMBER, PROP_R_NOT_A_DECIMAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -157,8 +156,8 @@ static int parse_hex(const char *t[], PROPERTY_DEFINITION *res) v += ossl_tolower(*s) - 'a'; } while (ossl_isxdigit(*++s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_HEX, PROP_R_NOT_AN_HEXADECIMAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -178,8 +177,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res) v = (v << 3) + (*s - '0'); } while (ossl_isdigit(*++s) && *s != '9' && *s != '8'); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_OCT, PROP_R_NOT_AN_OCTAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -204,18 +203,13 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, s++; } if (*s == '\0') { - char buf[2] = { 0, 0 }; - - PROPerr(PROP_F_PARSE_STRING, - PROP_R_NO_MATCHING_STRING_DELIMETER); - buf[0] = delim; - ERR_add_error_data(3, "HERE-->", buf, *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER, + "HERE-->%c%s", delim, *t); return 0; } v[i] = '\0'; if (err) { - PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); } else { res->v.str_val = ossl_property_value(ctx, v, create); } @@ -242,14 +236,13 @@ static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[], s++; } if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_NOT_AN_ASCII_CHARACTER); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER, + "HERE-->%s", s); return 0; } v[i] = 0; if (err) { - PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); } else { res->v.str_val = ossl_property_value(ctx, v, create); } @@ -358,14 +351,14 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) goto err; prop->oper = PROPERTY_OPER_EQ; if (prop->name_idx == 0) { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_PARSE_FAILED); - ERR_add_error_data(2, "Unknown name HERE-->", start); + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Unknown name HERE-->%s", start); goto err; } if (match_ch(&s, '=')) { if (!parse_value(ctx, &s, prop, 1)) { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE); - ERR_add_error_data(2, "HERE-->", start); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_VALUE, + "HERE-->%s", start); goto err; } } else { @@ -380,8 +373,8 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) done = !match_ch(&s, ','); } if (*s != '\0') { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_TRAILING_CHARACTERS); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); goto err; } res = stack_to_property_list(sk); @@ -442,8 +435,8 @@ skip_value: done = !match_ch(&s, ','); } if (*s != '\0') { - PROPerr(PROP_F_OSSL_PARSE_QUERY, PROP_R_TRAILING_CHARACTERS); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); goto err; } res = stack_to_property_list(sk); diff --git a/crypto/provider.c b/crypto/provider.c index 4e21bfe6..fe46d318 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -17,8 +17,8 @@ OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name) OSSL_PROVIDER *prov = NULL; /* Find it or create it */ - if ((prov = ossl_provider_find(libctx, name)) == NULL - && (prov = ossl_provider_new(libctx, name, NULL)) == NULL) + if ((prov = ossl_provider_find(libctx, name, 0)) == NULL + && (prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL) return NULL; if (!ossl_provider_activate(prov)) { @@ -35,9 +35,21 @@ int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) return 1; } -const OSSL_ITEM *OSSL_PROVIDER_get_param_types(const OSSL_PROVIDER *prov) +int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name) { - return ossl_provider_get_param_types(prov); + OSSL_PROVIDER *prov = NULL; + int available = 0; + + /* Find it or create it */ + prov = ossl_provider_find(libctx, name, 0); + available = ossl_provider_available(prov); + ossl_provider_free(prov); + return available; +} + +const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov) +{ + return ossl_provider_gettable_params(prov); } int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) @@ -57,7 +69,7 @@ int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, } /* Create it */ - if ((prov = ossl_provider_new(libctx, name, init_fn)) == NULL) + if ((prov = ossl_provider_new(libctx, name, init_fn, 0)) == NULL) return 0; /* @@ -68,3 +80,8 @@ int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, return 1; } + +const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov) +{ + return ossl_provider_name(prov); +} diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 74162a88..9b7a1fff 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -113,7 +113,9 @@ static int provider_conf_load(OPENSSL_CTX *libctx, const char *name, activate = 1; } - prov = ossl_provider_new(libctx, name, NULL); + prov = ossl_provider_find(libctx, name, 1); + if (prov == NULL) + prov = ossl_provider_new(libctx, name, NULL, 1); if (prov == NULL) { if (soft) ERR_clear_error(); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index c16e91d1..f8a002aa 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include "internal/cryptlib_int.h" @@ -62,7 +63,7 @@ struct ossl_provider_st { /* Provider side functions */ OSSL_provider_teardown_fn *teardown; - OSSL_provider_get_param_types_fn *get_param_types; + OSSL_provider_gettable_params_fn *gettable_params; OSSL_provider_get_params_fn *get_params; OSSL_provider_query_operation_fn *query_operation; @@ -159,7 +160,8 @@ static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx) return store; } -OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name) +OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, + int noconfig) { struct provider_store_st *store = NULL; OSSL_PROVIDER *prov = NULL; @@ -168,6 +170,15 @@ OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name) OSSL_PROVIDER tmpl = { 0, }; int i; +#ifndef FIPS_MODE + /* + * Make sure any providers are loaded from config before we try to find + * them. + */ + if (!noconfig) + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + tmpl.name = (char *)name; CRYPTO_THREAD_write_lock(store->lock); if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) == -1 @@ -215,7 +226,8 @@ int ossl_provider_up_ref(OSSL_PROVIDER *prov) } OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, - OSSL_provider_init_fn *init_function) + OSSL_provider_init_fn *init_function, + int noconfig) { struct provider_store_st *store = NULL; OSSL_PROVIDER *prov = NULL; @@ -223,11 +235,11 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, if ((store = get_provider_store(libctx)) == NULL) return NULL; - if ((prov = ossl_provider_find(libctx, name)) != NULL) { /* refcount +1 */ + if ((prov = ossl_provider_find(libctx, name, + noconfig)) != NULL) { /* refcount +1 */ ossl_provider_free(prov); /* refcount -1 */ - CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW, - CRYPTO_R_PROVIDER_ALREADY_EXISTS); - ERR_add_error_data(2, "name=", name); + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS, NULL, + "name=%s", name); return NULL; } @@ -438,8 +450,8 @@ static int provider_activate(OSSL_PROVIDER *prov) if (prov->init_function == NULL || !prov->init_function(prov, core_dispatch, &provider_dispatch, &prov->provctx)) { - CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL); - ERR_add_error_data(2, "name=", prov->name); + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, NULL, + "name=%s", prov->name); #ifndef FIPS_MODE DSO_free(prov->module); prov->module = NULL; @@ -453,9 +465,9 @@ static int provider_activate(OSSL_PROVIDER *prov) prov->teardown = OSSL_get_provider_teardown(provider_dispatch); break; - case OSSL_FUNC_PROVIDER_GET_PARAM_TYPES: - prov->get_param_types = - OSSL_get_provider_get_param_types(provider_dispatch); + case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: + prov->gettable_params = + OSSL_get_provider_gettable_params(provider_dispatch); break; case OSSL_FUNC_PROVIDER_GET_PARAMS: prov->get_params = @@ -553,7 +565,9 @@ static int provider_forall_loaded(struct provider_store_st *store, { int i; int ret = 1; - int num_provs = sk_OSSL_PROVIDER_num(store->providers); + int num_provs; + + num_provs = sk_OSSL_PROVIDER_num(store->providers); if (found_activated != NULL) *found_activated = 0; @@ -572,67 +586,87 @@ static int provider_forall_loaded(struct provider_store_st *store, return ret; } +/* + * This function only does something once when store->use_fallbacks == 1, + * and then sets store->use_fallbacks = 0, so the second call and so on is + * effectively a no-op. + */ +static void provider_activate_fallbacks(struct provider_store_st *store) +{ + if (store->use_fallbacks) { + int num_provs = sk_OSSL_PROVIDER_num(store->providers); + int activated_fallback_count = 0; + int i; + + for (i = 0; i < num_provs; i++) { + OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i); + + /* + * Note that we don't care if the activation succeeds or not. + * If it doesn't succeed, then any attempt to use any of the + * fallback providers will fail anyway. + */ + if (prov->flag_fallback) { + activated_fallback_count++; + provider_activate(prov); + } + } + + /* + * We assume that all fallbacks have been added to the store before + * any fallback is activated. + * TODO: We may have to reconsider this, IF we find ourselves adding + * fallbacks after any previous fallback has been activated. + */ + if (activated_fallback_count > 0) + store->use_fallbacks = 0; + } +} + int ossl_provider_forall_loaded(OPENSSL_CTX *ctx, int (*cb)(OSSL_PROVIDER *provider, void *cbdata), void *cbdata) { int ret = 1; - int i; struct provider_store_st *store = get_provider_store(ctx); - if (store != NULL) { - int found_activated = 0; +#ifndef FIPS_MODE + /* + * Make sure any providers are loaded from config before we try to use + * them. + */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + if (store != NULL) { CRYPTO_THREAD_read_lock(store->lock); - ret = provider_forall_loaded(store, &found_activated, cb, cbdata); + + provider_activate_fallbacks(store); /* - * If there's nothing activated ever in this store, try to activate - * all fallbacks. + * Now, we sweep through all providers */ - if (!found_activated && store->use_fallbacks) { - int num_provs = sk_OSSL_PROVIDER_num(store->providers); - int activated_fallback_count = 0; + ret = provider_forall_loaded(store, NULL, cb, cbdata); - for (i = 0; i < num_provs; i++) { - OSSL_PROVIDER *prov = - sk_OSSL_PROVIDER_value(store->providers, i); - - /* - * Note that we don't care if the activation succeeds or - * not. If it doesn't succeed, then the next loop will - * fail anyway. - */ - if (prov->flag_fallback) { - activated_fallback_count++; - provider_activate(prov); - } - } - - if (activated_fallback_count > 0) { - /* - * We assume that all fallbacks have been added to the store - * before any fallback is activated. - * TODO: We may have to reconsider this, IF we find ourselves - * adding fallbacks after any previous fallback has been - * activated. - */ - store->use_fallbacks = 0; - - /* - * Now that we've activated available fallbacks, try a - * second sweep - */ - ret = provider_forall_loaded(store, NULL, cb, cbdata); - } - } CRYPTO_THREAD_unlock(store->lock); } return ret; } +int ossl_provider_available(OSSL_PROVIDER *prov) +{ + if (prov != NULL) { + CRYPTO_THREAD_read_lock(prov->store->lock); + provider_activate_fallbacks(prov->store); + CRYPTO_THREAD_unlock(prov->store->lock); + + return prov->flag_initialized; + } + return 0; +} + /* Setters of Provider Object data */ int ossl_provider_set_fallback(OSSL_PROVIDER *prov) { @@ -673,6 +707,12 @@ const char *ossl_provider_module_path(const OSSL_PROVIDER *prov) #endif } +OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov) +{ + /* TODO(3.0) just: return prov->libctx; */ + return prov != NULL ? prov->libctx : NULL; +} + /* Wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov) { @@ -680,10 +720,10 @@ void ossl_provider_teardown(const OSSL_PROVIDER *prov) prov->teardown(prov->provctx); } -const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov) +const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov) { - return prov->get_param_types == NULL - ? NULL : prov->get_param_types(prov->provctx); + return prov->gettable_params == NULL + ? NULL : prov->gettable_params(prov->provctx); } int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) @@ -712,13 +752,28 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, * discovery. We do not expect that many providers will use this, but one * never knows. */ -static const OSSL_ITEM param_types[] = { - { OSSL_PARAM_UTF8_PTR, "openssl-version" }, - { OSSL_PARAM_UTF8_PTR, "provider-name" }, - { 0, NULL } +static const OSSL_PARAM param_types[] = { + OSSL_PARAM_DEFN("openssl-version", OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN("provider-name", OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_END }; -static const OSSL_ITEM *core_get_param_types(const OSSL_PROVIDER *prov) +/* + * Forward declare all the functions that are provided aa dispatch. + * This ensures that the compiler will complain if they aren't defined + * with the correct signature. + */ +static OSSL_core_gettable_params_fn core_gettable_params; +static OSSL_core_get_params_fn core_get_params; +static OSSL_core_thread_start_fn core_thread_start; +static OSSL_core_get_library_context_fn core_get_libctx; +#ifndef FIPS_MODE +static OSSL_core_new_error_fn core_new_error; +static OSSL_core_set_error_debug_fn core_set_error_debug; +static OSSL_core_vset_error_fn core_vset_error; +#endif + +static const OSSL_PARAM *core_gettable_params(const OSSL_PROVIDER *prov) { return param_types; } @@ -733,6 +788,11 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, "provider-name")) != NULL) OSSL_PARAM_set_utf8_ptr(p, prov->name); +#ifndef FIPS_MODE + if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_MODULE_FILENAME)) != NULL) + OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov)); +#endif + if (prov->parameters == NULL) return 1; @@ -742,14 +802,12 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL) OSSL_PARAM_set_utf8_ptr(p, pair->value); } - return 1; } -static OSSL_core_get_library_context_fn core_get_libctx; /* Check */ static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov) { - return prov->libctx; + return ossl_provider_library_context(prov); } static int core_thread_start(const OSSL_PROVIDER *prov, @@ -764,8 +822,26 @@ static int core_thread_start(const OSSL_PROVIDER *prov, * ones. */ #ifndef FIPS_MODE -static void core_put_error(const OSSL_PROVIDER *prov, - uint32_t reason, const char *file, int line) +/* + * TODO(3.0) These error functions should use |prov| to select the proper + * library context to report in the correct error stack, at least if error + * stacks become tied to the library context. + * We cannot currently do that since there's no support for it in the + * ERR subsystem. + */ +static void core_new_error(const OSSL_PROVIDER *prov) +{ + ERR_new(); +} + +static void core_set_error_debug(const OSSL_PROVIDER *prov, + const char *file, int line, const char *func) +{ + ERR_set_debug(file, line, func); +} + +static void core_vset_error(const OSSL_PROVIDER *prov, + uint32_t reason, const char *fmt, va_list args) { /* * If the uppermost 8 bits are non-zero, it's an OpenSSL library @@ -773,27 +849,11 @@ static void core_put_error(const OSSL_PROVIDER *prov, * provider error and will be treated as such. */ if (ERR_GET_LIB(reason) != 0) { - ERR_PUT_error(ERR_GET_LIB(reason), - ERR_GET_FUNC(reason), - ERR_GET_REASON(reason), - file, line); + ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args); } else { - ERR_PUT_error(prov->error_lib, 0, (int)reason, file, line); + ERR_vset_error(prov->error_lib, (int)reason, fmt, args); } } - -/* - * TODO(3.0) This, as well as core_put_error above, should use |prov| - * to select the proper library context to report in the correct error - * stack, at least if error stacks become tied to the library context. - * We cannot currently do that since there's no support for it in the - * ERR subsystem. - */ -static void core_add_error_vdata(const OSSL_PROVIDER *prov, - int num, va_list args) -{ - ERR_add_error_vdata(num, args); -} #endif /* @@ -801,20 +861,22 @@ static void core_add_error_vdata(const OSSL_PROVIDER *prov, * functions. */ static const OSSL_DISPATCH core_dispatch_[] = { - { OSSL_FUNC_CORE_GET_PARAM_TYPES, (void (*)(void))core_get_param_types }, + { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx }, { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, #ifndef FIPS_MODE - { OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))core_put_error }, - { OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))core_add_error_vdata }, + { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, + { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug }, + { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error }, + { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file }, + { 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 }, #endif { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, - { OSSL_FUNC_CRYPTO_MEMDUP, (void (*)(void))CRYPTO_memdup }, - { OSSL_FUNC_CRYPTO_STRDUP, (void (*)(void))CRYPTO_strdup }, - { OSSL_FUNC_CRYPTO_STRNDUP, (void (*)(void))CRYPTO_strndup }, { OSSL_FUNC_CRYPTO_FREE, (void (*)(void))CRYPTO_free }, { OSSL_FUNC_CRYPTO_CLEAR_FREE, (void (*)(void))CRYPTO_clear_free }, { OSSL_FUNC_CRYPTO_REALLOC, (void (*)(void))CRYPTO_realloc }, @@ -827,7 +889,6 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED, (void (*)(void))CRYPTO_secure_allocated }, { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse }, - { OSSL_FUNC_OPENSSL_HEXSTR2BUF, (void (*)(void))OPENSSL_hexstr2buf }, { 0, NULL } }; diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c index 23e504bf..28db4eed 100644 --- a/crypto/rand/drbg_ctr.c +++ b/crypto/rand/drbg_ctr.c @@ -354,7 +354,7 @@ static int drbg_ctr_uninstantiate(RAND_DRBG *drbg) { EVP_CIPHER_CTX_free(drbg->data.ctr.ctx); EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df); - EVP_CIPHER_meth_free(drbg->data.ctr.cipher); + EVP_CIPHER_free(drbg->data.ctr.cipher); OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr)); return 1; } @@ -392,7 +392,7 @@ int drbg_ctr_init(RAND_DRBG *drbg) if (cipher == NULL) return 0; - EVP_CIPHER_meth_free(ctr->cipher); + EVP_CIPHER_free(ctr->cipher); ctr->cipher = cipher; drbg->meth = &drbg_ctr_meth; diff --git a/crypto/rand/drbg_hash.c b/crypto/rand/drbg_hash.c index bb6f36ce..6bef917e 100644 --- a/crypto/rand/drbg_hash.c +++ b/crypto/rand/drbg_hash.c @@ -290,7 +290,7 @@ static int drbg_hash_generate(RAND_DRBG *drbg, static int drbg_hash_uninstantiate(RAND_DRBG *drbg) { - EVP_MD_meth_free(drbg->data.hash.md); + EVP_MD_free(drbg->data.hash.md); EVP_MD_CTX_free(drbg->data.hash.ctx); OPENSSL_cleanse(&drbg->data.hash, sizeof(drbg->data.hash)); return 1; @@ -346,12 +346,12 @@ int drbg_hash_init(RAND_DRBG *drbg) if (hash->ctx == NULL) { hash->ctx = EVP_MD_CTX_new(); if (hash->ctx == NULL) { - EVP_MD_meth_free(md); + EVP_MD_free(md); return 0; } } - EVP_MD_meth_free(hash->md); + EVP_MD_free(hash->md); hash->md = md; /* These are taken from SP 800-90 10.1 Table 2 */ diff --git a/crypto/rand/drbg_hmac.c b/crypto/rand/drbg_hmac.c index baafc590..14c4570b 100644 --- a/crypto/rand/drbg_hmac.c +++ b/crypto/rand/drbg_hmac.c @@ -184,7 +184,7 @@ static int drbg_hmac_generate(RAND_DRBG *drbg, static int drbg_hmac_uninstantiate(RAND_DRBG *drbg) { - EVP_MD_meth_free(drbg->data.hmac.md); + EVP_MD_free(drbg->data.hmac.md); HMAC_CTX_free(drbg->data.hmac.ctx); OPENSSL_cleanse(&drbg->data.hmac, sizeof(drbg->data.hmac)); return 1; @@ -239,13 +239,13 @@ int drbg_hmac_init(RAND_DRBG *drbg) if (hmac->ctx == NULL) { hmac->ctx = HMAC_CTX_new(); if (hmac->ctx == NULL) { - EVP_MD_meth_free(md); + EVP_MD_free(md); return 0; } } /* These are taken from SP 800-90 10.1 Table 2 */ - EVP_MD_meth_free(hmac->md); + EVP_MD_free(hmac->md); hmac->md = md; hmac->blocklen = EVP_MD_size(md); /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */ diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index c1b9b3b2..bce2f74e 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -191,6 +191,9 @@ static void drbg_ossl_ctx_free(void *vdgbl) { DRBG_GLOBAL *dgbl = vdgbl; + if (dgbl == NULL) + return; + RAND_DRBG_free(dgbl->master_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); @@ -230,6 +233,9 @@ static void drbg_nonce_ossl_ctx_free(void *vdngbl) { DRBG_NONCE_GLOBAL *dngbl = vdngbl; + if (dngbl == NULL) + return; + CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock); OPENSSL_free(dngbl); @@ -265,7 +271,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg, return 0; memset(&data, 0, sizeof(data)); - pool = rand_pool_new(0, min_len, max_len); + pool = rand_pool_new(0, 0, min_len, max_len); if (pool == NULL) return 0; @@ -295,7 +301,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg, void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { - OPENSSL_secure_clear_free(out, outlen); + OPENSSL_clear_free(out, outlen); } /* @@ -409,7 +415,7 @@ static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx, drbg->libctx = ctx; drbg->secure = secure && CRYPTO_secure_allocated(drbg); - drbg->fork_count = rand_fork_count; + drbg->fork_id = openssl_get_fork_id(); drbg->parent = parent; if (parent == NULL) { @@ -535,9 +541,10 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, } if (drbg->state != DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE - : RAND_R_ALREADY_INSTANTIATED); + if (drbg->state == DRBG_ERROR) + RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_IN_ERROR_STATE); + else + RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ALREADY_INSTANTIATED); goto end; } @@ -823,6 +830,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, int prediction_resistance, const unsigned char *adin, size_t adinlen) { + int fork_id; int reseed_required = 0; if (drbg->state != DRBG_READY) { @@ -848,8 +856,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, return 0; } - if (drbg->fork_count != rand_fork_count) { - drbg->fork_count = rand_fork_count; + fork_id = openssl_get_fork_id(); + + if (drbg->fork_id != fork_id) { + drbg->fork_id = fork_id; reseed_required = 1; } @@ -909,7 +919,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) if (drbg->adin_pool == NULL) { if (drbg->type == 0) goto err; - drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen); + drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen); if (drbg->adin_pool == NULL) goto err; } diff --git a/crypto/rand/rand_crng_test.c b/crypto/rand/rand_crng_test.c index 44e077e0..0ba0986b 100644 --- a/crypto/rand/rand_crng_test.c +++ b/crypto/rand/rand_crng_test.c @@ -45,7 +45,7 @@ static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx) return NULL; if ((crngt_glob->crngt_pool - = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) { + = rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) { OPENSSL_free(crngt_glob); return NULL; } @@ -87,7 +87,7 @@ int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx, if (r != 0) memcpy(buf, p, CRNGT_BUFSIZ); rand_pool_reattach(pool, p); - EVP_MD_meth_free(fmd); + EVP_MD_free(fmd); return r; } return 0; @@ -110,7 +110,7 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg, if (crngt_glob == NULL) return 0; - if ((pool = rand_pool_new(entropy, min_len, max_len)) == NULL) + if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL) return 0; while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) { diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index d729441e..53d32938 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -13,47 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA RAND_str_functs[] = { - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_BYTES, 0), "drbg_bytes"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_CTR_INIT, 0), "drbg_ctr_init"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_GET_ENTROPY, 0), "drbg_get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_GET_ENTROPY, 0), "get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES, 0), "RAND_bytes"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES_EX, 0), "rand_bytes_ex"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_ENABLE_LOCKING, 0), - "rand_drbg_enable_locking"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0), - "RAND_DRBG_generate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_ENTROPY, 0), - "rand_drbg_get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_NONCE, 0), - "rand_drbg_get_nonce"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_INSTANTIATE, 0), - "RAND_DRBG_instantiate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_NEW, 0), "RAND_DRBG_new"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET_DEFAULTS, 0), - "RAND_DRBG_set_defaults"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0), - "RAND_DRBG_uninstantiate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ACQUIRE_ENTROPY, 0), - "rand_pool_acquire_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD, 0), "rand_pool_add"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0), - "rand_pool_add_begin"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_END, 0), "rand_pool_add_end"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0), - "rand_pool_bytes_needed"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"}, - {0, NULL} -}; - static const ERR_STRING_DATA RAND_str_reasons[] = { {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ADDITIONAL_INPUT_TOO_LONG), "additional input too long"}, @@ -130,10 +89,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { int ERR_load_RAND_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { - ERR_load_strings_const(RAND_str_functs); + if (ERR_reason_error_string(RAND_str_reasons[0].error) == NULL) ERR_load_strings_const(RAND_str_reasons); - } #endif return 1; } diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index 416237ac..0c92d756 100644 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -54,7 +54,13 @@ # define DRBG_MAX_LENGTH INT32_MAX /* The default nonce */ +#ifdef CHARSET_EBCDIC +# define DRBG_DEFAULT_PERS_STRING { 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, \ + 0x4c, 0x20, 0x4e, 0x49, 0x53, 0x54, 0x20, 0x53, 0x50, 0x20, 0x38, 0x30, \ + 0x30, 0x2d, 0x39, 0x30, 0x41, 0x20, 0x44, 0x52, 0x42, 0x47, 0x00}; +#else # define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG" +#endif /* * Maximum allocation size for RANDOM_POOL buffers @@ -82,6 +88,24 @@ * 1.5 * (RAND_DRBG_STRENGTH / 8)) */ +/* + * Initial allocation minimum. + * + * There is a distinction between the secure and normal allocation minimums. + * Ideally, the secure allocation size should be a power of two. The normal + * allocation size doesn't have any such restriction. + * + * The secure value is based on 128 bits of secure material, which is 16 bytes. + * Typically, the DRBGs will set a minimum larger than this so optimal + * allocation ought to take place (for full quality seed material). + * + * The normal value has been chosed by noticing that the rand_drbg_get_nonce + * function is usually the largest of the built in allocation (twenty four + * bytes and then appending another sixteen bytes). This means the buffer ends + * with 40 bytes. The value of forty eight is comfortably above this which + * allows some slack in the platform specific values used. + */ +# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48) /* DRBG status values */ typedef enum drbg_status_e { @@ -180,9 +204,11 @@ struct rand_pool_st { size_t len; /* current number of random bytes contained in the pool */ int attached; /* true pool was attached to existing buffer */ + int secure; /* 1: allocated on the secure heap, 0: otherwise */ size_t min_len; /* minimum number of random bytes requested */ size_t max_len; /* maximum number of random bytes (allocated buffer size) */ + size_t alloc_len; /* current number of bytes allocated */ size_t entropy; /* current entropy count in bits */ size_t entropy_requested; /* requested entropy count in bits */ }; @@ -199,12 +225,12 @@ struct rand_drbg_st { int secure; /* 1: allocated on the secure heap, 0: otherwise */ int type; /* the nid of the underlying algorithm */ /* - * Stores the value of the rand_fork_count global as of when we last - * reseeded. The DRBG reseeds automatically whenever drbg->fork_count != - * rand_fork_count. Used to provide fork-safety and reseed this DRBG in - * the child process. + * Stores the return value of openssl_get_fork_id() as of when we last + * reseeded. The DRBG reseeds automatically whenever drbg->fork_id != + * openssl_get_fork_id(). Used to provide fork-safety and reseed this + * DRBG in the child process. */ - int fork_count; + int fork_id; unsigned short flags; /* various external flags */ /* @@ -305,19 +331,6 @@ struct rand_drbg_st { /* The global RAND method, and the global buffer and DRBG instance. */ extern RAND_METHOD rand_meth; -/* - * A "generation count" of forks. Incremented in the child process after a - * fork. Since rand_fork_count is increment-only, and only ever written to in - * the child process of the fork, which is guaranteed to be single-threaded, no - * locking is needed for normal (read) accesses; the rest of pthread fork - * processing is assumed to introduce the necessary memory barriers. Sibling - * children of a given parent will produce duplicate values, but this is not - * problematic because the reseeding process pulls input from the system CSPRNG - * and/or other global sources, so the siblings will end up generating - * different output streams. - */ -extern int rand_fork_count; - /* DRBG helpers */ int rand_drbg_restart(RAND_DRBG *drbg, const unsigned char *buffer, size_t len, size_t entropy); diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 7768ade8..b70b60a6 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -30,8 +30,6 @@ static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; static int rand_inited = 0; #endif /* FIPS_MODE */ -int rand_fork_count; - #ifdef OPENSSL_RAND_SEED_RDTSC /* * IMPORTANT NOTE: It is not currently possible to use this code @@ -69,8 +67,6 @@ size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool) size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len); size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len); -extern unsigned int OPENSSL_ia32cap_P[]; - /* * Acquire entropy using Intel-specific cpu instructions * @@ -149,7 +145,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, pool = drbg->seed_pool; pool->entropy_requested = entropy; } else { - pool = rand_pool_new(entropy, min_len, max_len); + pool = rand_pool_new(entropy, drbg->secure, min_len, max_len); if (pool == NULL) return 0; } @@ -162,7 +158,9 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, size_t bytes = 0; /* - * Get random from parent, include our state as additional input. + * Get random data from parent. Include our address as additional input, + * in order to provide some additional distinction between different + * DRBG child instances. * Our lock is already held, but we need to lock our parent before * generating bits from it. (Note: taking the lock will be a no-op * if locking if drbg->parent->lock == NULL.) @@ -171,7 +169,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, if (RAND_DRBG_generate(drbg->parent, buffer, bytes_needed, prediction_resistance, - NULL, 0) != 0) + (unsigned char *)&drbg, sizeof(drbg)) != 0) bytes = bytes_needed; drbg->reseed_next_counter = tsan_load(&drbg->parent->reseed_prop_counter); @@ -203,8 +201,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, void rand_drbg_cleanup_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { - if (drbg->seed_pool == NULL) - OPENSSL_secure_clear_free(out, outlen); + if (drbg->seed_pool == NULL) { + if (drbg->secure) + OPENSSL_secure_clear_free(out, outlen); + else + OPENSSL_clear_free(out, outlen); + } } /* @@ -236,11 +238,6 @@ void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out) rand_pool_reattach(pool, out); } -void rand_fork(void) -{ - rand_fork_count++; -} - #ifndef FIPS_MODE DEFINE_RUN_ONCE_STATIC(do_rand_init) { @@ -331,7 +328,7 @@ int RAND_poll(void) RAND_POOL *pool = NULL; /* fill random pool and seed the current legacy RNG */ - pool = rand_pool_new(RAND_DRBG_STRENGTH, + pool = rand_pool_new(RAND_DRBG_STRENGTH, 1, (RAND_DRBG_STRENGTH + 7) / 8, RAND_POOL_MAX_LENGTH); if (pool == NULL) @@ -360,9 +357,11 @@ int RAND_poll(void) * Allocate memory and initialize a new random pool */ -RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len) +RAND_POOL *rand_pool_new(int entropy_requested, int secure, + size_t min_len, size_t max_len) { RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); + size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure); if (pool == NULL) { RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); @@ -372,14 +371,22 @@ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len) pool->min_len = min_len; pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ? RAND_POOL_MAX_LENGTH : max_len; + pool->alloc_len = min_len < min_alloc_size ? min_alloc_size : min_len; + if (pool->alloc_len > pool->max_len) + pool->alloc_len = pool->max_len; + + if (secure) + pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len); + else + pool->buffer = OPENSSL_zalloc(pool->alloc_len); - pool->buffer = OPENSSL_secure_zalloc(pool->max_len); if (pool->buffer == NULL) { RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); goto err; } pool->entropy_requested = entropy_requested; + pool->secure = secure; return pool; @@ -414,7 +421,7 @@ RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, pool->attached = 1; - pool->min_len = pool->max_len = pool->len; + pool->min_len = pool->max_len = pool->alloc_len = pool->len; pool->entropy = entropy; return pool; @@ -434,8 +441,13 @@ void rand_pool_free(RAND_POOL *pool) * to rand_pool_attach() as `const unsigned char*`. * (see corresponding comment in rand_pool_attach()). */ - if (!pool->attached) - OPENSSL_secure_clear_free(pool->buffer, pool->max_len); + if (!pool->attached) { + if (pool->secure) + OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); + else + OPENSSL_clear_free(pool->buffer, pool->alloc_len); + } + OPENSSL_free(pool); } @@ -528,6 +540,42 @@ size_t rand_pool_entropy_needed(RAND_POOL *pool) return 0; } +/* Increase the allocation size -- not usable for an attached pool */ +static int rand_pool_grow(RAND_POOL *pool, size_t len) +{ + if (len > pool->alloc_len - pool->len) { + unsigned char *p; + const size_t limit = pool->max_len / 2; + size_t newlen = pool->alloc_len; + + if (pool->attached || len > pool->max_len - pool->len) { + RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_INTERNAL_ERROR); + return 0; + } + + do + newlen = newlen < limit ? newlen * 2 : pool->max_len; + while (len > newlen - pool->len); + + if (pool->secure) + p = OPENSSL_secure_zalloc(newlen); + else + p = OPENSSL_zalloc(newlen); + if (p == NULL) { + RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(p, pool->buffer, pool->len); + if (pool->secure) + OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); + else + OPENSSL_clear_free(pool->buffer, pool->alloc_len); + pool->buffer = p; + pool->alloc_len = newlen; + } + return 1; +} + /* * Returns the number of bytes needed to fill the pool, assuming * the input has 1 / |entropy_factor| entropy bits per data bit. @@ -557,6 +605,24 @@ size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor) /* to meet the min_len requirement */ bytes_needed = pool->min_len - pool->len; + /* + * Make sure the buffer is large enough for the requested amount + * of data. This guarantees that existing code patterns where + * rand_pool_add_begin, rand_pool_add_end or rand_pool_add + * are used to collect entropy data without any error handling + * whatsoever, continue to be valid. + * Furthermore if the allocation here fails once, make sure that + * we don't fall back to a less secure or even blocking random source, + * as that could happen by the existing code patterns. + * This is not a concern for additional data, therefore that + * is not needed if rand_pool_grow fails in other places. + */ + if (!rand_pool_grow(pool, bytes_needed)) { + /* persistent error for this pool */ + pool->max_len = pool->len = 0; + return 0; + } + return bytes_needed; } @@ -589,6 +655,27 @@ int rand_pool_add(RAND_POOL *pool, } if (len > 0) { + /* + * This is to protect us from accidentally passing the buffer + * returned from rand_pool_add_begin. + * The check for alloc_len makes sure we do not compare the + * address of the end of the allocated memory to something + * different, since that comparison would have an + * indeterminate result. + */ + if (pool->alloc_len > pool->len && pool->buffer + pool->len == buffer) { + RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR); + return 0; + } + /* + * We have that only for cases when a pool is used to collect + * additional data. + * For entropy data, as long as the allocation request stays within + * the limits given by rand_pool_bytes_needed this rand_pool_grow + * below is guaranteed to succeed, thus no allocation happens. + */ + if (!rand_pool_grow(pool, len)) + return 0; memcpy(pool->buffer + pool->len, buffer, len); pool->len += len; pool->entropy += entropy; @@ -624,6 +711,18 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len) return NULL; } + /* + * As long as the allocation request stays within the limits given + * by rand_pool_bytes_needed this rand_pool_grow below is guaranteed + * to succeed, thus no allocation happens. + * We have that only for cases when a pool is used to collect + * additional data. Then the buffer might need to grow here, + * and of course the caller is responsible to check the return + * value of this function. + */ + if (!rand_pool_grow(pool, len)) + return NULL; + return pool->buffer + pool->len; } @@ -638,7 +737,7 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len) */ int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy) { - if (len > pool->max_len - pool->len) { + if (len > pool->alloc_len - pool->len) { RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW); return 0; } diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index e45e018e..8641badb 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -14,12 +14,17 @@ #include #include "internal/cryptlib.h" #include +#include #include "rand_lcl.h" #include "internal/rand_int.h" #include #include "internal/dso.h" -#if defined(__linux) -# include +#ifdef __linux +# include +# ifdef DEVRANDOM_WAIT +# include +# include +# endif #endif #if defined(__FreeBSD__) && !defined(OPENSSL_SYS_UEFI) # include @@ -254,6 +259,17 @@ static ssize_t sysctl_random(char *buf, size_t buflen) # endif # if defined(OPENSSL_RAND_SEED_GETRANDOM) + +# if defined(__linux) && !defined(__NR_getrandom) +# if defined(__arm__) && defined(__NR_SYSCALL_BASE) +# define __NR_getrandom (__NR_SYSCALL_BASE+384) +# elif defined(__i386__) +# define __NR_getrandom 355 +# elif defined(__x86_64__) && !defined(__ILP32__) +# define __NR_getrandom 318 +# endif +# endif + /* * syscall_random(): Try to get random data using a system call * returns the number of bytes returned in buf, or < 0 on error. @@ -325,6 +341,96 @@ static struct random_device { } random_devices[OSSL_NELEM(random_device_paths)]; static int keep_random_devices_open = 1; +# if defined(__linux) && defined(DEVRANDOM_WAIT) +static void *shm_addr; + +# if !defined(FIPS_MODE) +static void cleanup_shm(void) +{ + shmdt(shm_addr); +} +# endif + +/* + * Ensure that the system randomness source has been adequately seeded. + * This is done by having the first start of libcrypto, wait until the device + * /dev/random becomes able to supply a byte of entropy. Subsequent starts + * of the library and later reseedings do not need to do this. + */ +static int wait_random_seeded(void) +{ + static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0; + static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL }; + int kernel[2]; + int shm_id, fd, r; + char c, *p; + struct utsname un; + fd_set fds; + + if (!seeded) { + /* See if anything has created the global seeded indication */ + if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) { + /* + * Check the kernel's version and fail if it is too recent. + * + * Linux kernels from 4.8 onwards do not guarantee that + * /dev/urandom is properly seeded when /dev/random becomes + * readable. However, such kernels support the getentropy(2) + * system call and this should always succeed which renders + * this alternative but essentially identical source moot. + */ + if (uname(&un) == 0) { + kernel[0] = atoi(un.release); + p = strchr(un.release, '.'); + kernel[1] = p == NULL ? 0 : atoi(p + 1); + if (kernel[0] > kernel_version[0] + || (kernel[0] == kernel_version[0] + && kernel[1] >= kernel_version[1])) { + return 0; + } + } + /* Open /dev/random and wait for it to be readable */ + if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) { + if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0 + && errno == EINTR); + } else { + while ((r = read(fd, &c, 1)) < 0 && errno == EINTR); + } + close(fd); + if (r == 1) { + seeded = 1; + /* Create the shared memory indicator */ + shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, + IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH); + } + } + } + if (shm_id != -1) { + seeded = 1; + /* + * Map the shared memory to prevent its premature destruction. + * If this call fails, it isn't a big problem. + */ + shm_addr = shmat(shm_id, NULL, SHM_RDONLY); +# ifndef FIPS_MODE + /* TODO 3.0: The FIPS provider doesn't have OPENSSL_atexit */ + if (shm_addr != (void *)-1) + OPENSSL_atexit(&cleanup_shm); +# endif + } + } + return seeded; +} +# else /* defined __linux */ +static int wait_random_seeded(void) +{ + return 1; +} +# endif + /* * Verify that the file descriptor associated with the random source is * still valid. The rationale for doing this is the fact that it is not @@ -451,12 +557,12 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) # if defined(OPENSSL_RAND_SEED_NONE) return rand_pool_entropy_available(pool); # else - size_t bytes_needed; - size_t entropy_available = 0; - unsigned char *buffer; + size_t entropy_available; # if defined(OPENSSL_RAND_SEED_GETRANDOM) { + size_t bytes_needed; + unsigned char *buffer; ssize_t bytes; /* Maximum allowed number of consecutive unsuccessful attempts */ int attempts = 3; @@ -486,13 +592,16 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) # endif # if defined(OPENSSL_RAND_SEED_DEVRANDOM) - bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - { + if (wait_random_seeded()) { + size_t bytes_needed; + unsigned char *buffer; size_t i; - for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) { + bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); + i++) { ssize_t bytes = 0; - /* Maximum allowed number of consecutive unsuccessful attempts */ + /* Maximum number of consecutive unsuccessful attempts */ int attempts = 3; const int fd = get_random_device(i); @@ -506,7 +615,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) if (bytes > 0) { rand_pool_add_end(pool, bytes, 8 * bytes); bytes_needed -= bytes; - attempts = 3; /* reset counter after successful attempt */ + attempts = 3; /* reset counter on successful attempt */ } else if (bytes < 0 && errno != EINTR) { break; } @@ -514,7 +623,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) if (bytes < 0 || !keep_random_devices_open) close_random_device(i); - bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + bytes_needed = rand_pool_bytes_needed(pool, 1); } entropy_available = rand_pool_entropy_available(pool); if (entropy_available > 0) @@ -535,26 +644,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) # endif # if defined(OPENSSL_RAND_SEED_EGD) - bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - if (bytes_needed > 0) { + { static const char *paths[] = { DEVRANDOM_EGD, NULL }; + size_t bytes_needed; + unsigned char *buffer; int i; - for (i = 0; paths[i] != NULL; i++) { - buffer = rand_pool_add_begin(pool, bytes_needed); - if (buffer != NULL) { - size_t bytes = 0; - int num = RAND_query_egd_bytes(paths[i], - buffer, (int)bytes_needed); - if (num == (int)bytes_needed) - bytes = bytes_needed; + bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) { + size_t bytes = 0; + int num; - rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = rand_pool_entropy_available(pool); - } - if (entropy_available > 0) - return entropy_available; + buffer = rand_pool_add_begin(pool, bytes_needed); + num = RAND_query_egd_bytes(paths[i], + buffer, (int)bytes_needed); + if (num == (int)bytes_needed) + bytes = bytes_needed; + + rand_pool_add_end(pool, bytes, 8 * bytes); + bytes_needed = rand_pool_bytes_needed(pool, 1); } + entropy_available = rand_pool_entropy_available(pool); + if (entropy_available > 0) + return entropy_available; } # endif @@ -592,6 +704,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) int rand_pool_add_additional_data(RAND_POOL *pool) { struct { + int fork_id; CRYPTO_THREAD_ID tid; uint64_t time; } data; @@ -601,9 +714,11 @@ int rand_pool_add_additional_data(RAND_POOL *pool) /* * Add some noise from the thread id and a high resolution timer. + * The fork_id adds some extra fork-safety. * The thread id adds a little randomness if the drbg is accessed * concurrently (which is the case for the drbg). */ + data.fork_id = openssl_get_fork_id(); data.tid = CRYPTO_THREAD_get_current_id(); data.time = get_timer_bits(); diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c index 8b874196..38852dc7 100644 --- a/crypto/rand/rand_win.c +++ b/crypto/rand/rand_win.c @@ -19,7 +19,8 @@ # include /* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */ -# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 +# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \ + && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 # define USE_BCRYPTGENRANDOM # endif diff --git a/crypto/rc4/asm/rc4-586.pl b/crypto/rc4/asm/rc4-586.pl index db43ca83..ad967407 100644 --- a/crypto/rc4/asm/rc4-586.pl +++ b/crypto/rc4/asm/rc4-586.pl @@ -68,8 +68,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/rc4/asm/rc4-c64xplus.pl b/crypto/rc4/asm/rc4-c64xplus.pl index f4e0814c..0167b05e 100644 --- a/crypto/rc4/asm/rc4-c64xplus.pl +++ b/crypto/rc4/asm/rc4-c64xplus.pl @@ -186,7 +186,6 @@ rc4_options: .align 4 ___ -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/rc4/asm/rc4-md5-x86_64.pl b/crypto/rc4/asm/rc4-md5-x86_64.pl index 83a29855..c9381ca9 100644 --- a/crypto/rc4/asm/rc4-md5-x86_64.pl +++ b/crypto/rc4/asm/rc4-md5-x86_64.pl @@ -53,9 +53,10 @@ my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(), # to be able to use 'openssl speed rc4' for # benchmarking the stitched subroutine... -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -64,7 +65,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs); diff --git a/crypto/rc4/asm/rc4-parisc.pl b/crypto/rc4/asm/rc4-parisc.pl index 71945750..a60f2f9e 100644 --- a/crypto/rc4/asm/rc4-parisc.pl +++ b/crypto/rc4/asm/rc4-parisc.pl @@ -27,9 +27,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/rc4/asm/rc4-s390x.pl b/crypto/rc4/asm/rc4-s390x.pl index 858ce153..c90013cf 100644 --- a/crypto/rc4/asm/rc4-s390x.pl +++ b/crypto/rc4/asm/rc4-s390x.pl @@ -30,7 +30,10 @@ # remains z/Architecture specific. On z990 it was measured to perform # 50% better than code generated by gcc 4.3. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -40,8 +43,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $rp="%r14"; $sp="%r15"; diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl index 42e711b4..ebca0473 100755 --- a/crypto/rc4/asm/rc4-x86_64.pl +++ b/crypto/rc4/asm/rc4-x86_64.pl @@ -111,9 +111,10 @@ # but more than likely at the cost of the others (see rc4-586.pl # to get the idea)... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -122,7 +123,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $dat="%rdi"; # arg1 diff --git a/crypto/rc4/build.info b/crypto/rc4/build.info index 30e36bac..abc0c52d 100644 --- a/crypto/rc4/build.info +++ b/crypto/rc4/build.info @@ -19,13 +19,12 @@ ENDIF SOURCE[../../libcrypto]=$RC4ASM -GENERATE[rc4-586.s]=asm/rc4-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[rc4-586.s]=asm/rc4-586.pl DEPEND[rc4-586.s]=../perlasm/x86asm.pl -GENERATE[rc4-x86_64.s]=asm/rc4-x86_64.pl $(PERLASM_SCHEME) -GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME) +GENERATE[rc4-x86_64.s]=asm/rc4-x86_64.pl +GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl -GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl $(PERLASM_SCHEME) -GENERATE[rc4-c64xplus.s]=asm/rc4-c64xplus.pl $(PERLASM_SCHEME) -GENERATE[rc4-s390x.s]=asm/rc4-s390x.pl $(PERLASM_SCHEME) +GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl +GENERATE[rc4-c64xplus.s]=asm/rc4-c64xplus.pl +GENERATE[rc4-s390x.s]=asm/rc4-s390x.pl diff --git a/crypto/rc5/asm/rc5-586.pl b/crypto/rc5/asm/rc5-586.pl index 592cbd7c..70ff5d41 100644 --- a/crypto/rc5/asm/rc5-586.pl +++ b/crypto/rc5/asm/rc5-586.pl @@ -12,8 +12,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/rc5/build.info b/crypto/rc5/build.info index 5780f3c5..c684d1ee 100644 --- a/crypto/rc5/build.info +++ b/crypto/rc5/build.info @@ -15,6 +15,5 @@ ENDIF SOURCE[../../libcrypto]=\ rc5_skey.c rc5_ecb.c $RC5ASM rc5cfb64.c rc5ofb64.c -GENERATE[rc5-586.s]=asm/rc5-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[rc5-586.s]=asm/rc5-586.pl DEPEND[rc5-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/ripemd/asm/rmd-586.pl b/crypto/ripemd/asm/rmd-586.pl index 6d619b8f..f6b283c9 100644 --- a/crypto/ripemd/asm/rmd-586.pl +++ b/crypto/ripemd/asm/rmd-586.pl @@ -16,8 +16,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/ripemd/build.info b/crypto/ripemd/build.info index e2db2932..c4baf631 100644 --- a/crypto/ripemd/build.info +++ b/crypto/ripemd/build.info @@ -15,6 +15,5 @@ ENDIF SOURCE[../../libcrypto]=rmd_dgst.c rmd_one.c $RMD160ASM DEFINE[../../libcrypto]=$RMD160DEF -GENERATE[rmd-586.s]=asm/rmd-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[rmd-586.s]=asm/rmd-586.pl DEPEND[rmd-586.s]=../perlasm/x86asm.pl diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 82d1d56d..bf56039b 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -458,6 +458,9 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { X509_ALGOR *alg = NULL; + const EVP_MD *md; + const EVP_MD *mgf1md; + int min_saltlen; switch (op) { @@ -497,6 +500,16 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) #endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + if (pkey->pkey.rsa->pss != NULL) { + if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, + &min_saltlen)) { + RSAerr(0, ERR_R_INTERNAL_ERROR); + return 0; + } + *(int *)arg2 = EVP_MD_type(md); + /* Return of 2 indicates this MD is mandatory */ + return 2; + } *(int *)arg2 = NID_sha256; return 1; diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index 936413d4..692b1a1b 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -13,109 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA RSA_str_functs[] = { - {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, 0), "check_padding_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_ENCODE_PKCS1, 0), "encode_pkcs1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_INT_RSA_VERIFY, 0), "int_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, 0), - "old_rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_PSS_INIT, 0), "pkey_pss_init"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, 0), "pkey_rsa_ctrl"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL_STR, 0), "pkey_rsa_ctrl_str"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_SIGN, 0), "pkey_rsa_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFY, 0), "pkey_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFYRECOVER, 0), - "pkey_rsa_verifyrecover"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ALGOR_TO_MD, 0), "rsa_algor_to_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_BUILTIN_KEYGEN, 0), "rsa_builtin_keygen"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY, 0), "RSA_check_key"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES, 0), - "rsa_fips186_4_gen_prob_primes"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_DUP, 0), "RSA_meth_dup"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_NEW, 0), "RSA_meth_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_SET1_NAME, 0), "RSA_meth_set1_name"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MGF1_TO_MD, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MULTIP_INFO_NEW, 0), - "rsa_multip_info_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NEW_METHOD, 0), "RSA_new_method"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, 0), - "rsa_ossl_private_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, 0), - "rsa_ossl_private_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, 0), - "rsa_ossl_public_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, 0), - "rsa_ossl_public_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_NONE, 0), - "RSA_padding_add_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, 0), - "RSA_padding_add_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 0), - "RSA_padding_add_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS, 0), - "RSA_padding_add_PKCS1_PSS"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, 0), - "RSA_padding_add_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, 0), - "RSA_padding_add_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, 0), - "RSA_padding_add_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_SSLV23, 0), - "RSA_padding_add_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_X931, 0), - "RSA_padding_add_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_NONE, 0), - "RSA_padding_check_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, 0), - "RSA_padding_check_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 0), - "RSA_padding_check_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 0), - "RSA_padding_check_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, 0), - "RSA_padding_check_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_SSLV23, 0), - "RSA_padding_check_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_X931, 0), - "RSA_padding_check_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), - "RSA_sign_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, 0), - "rsa_sp800_56b_check_keypair"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SP800_56B_CHECK_PUBLIC, 0), - "rsa_sp800_56b_check_public"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SP800_56B_PAIRWISE_TEST, 0), - "rsa_sp800_56b_pairwise_test"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH, 0), - "rsa_sp800_56b_validate_strength"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY, 0), "RSA_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, 0), - "RSA_verify_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), - "RSA_verify_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, - {0, NULL} -}; - static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE), "bad e value"}, @@ -189,6 +86,8 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MGF1_DIGEST_NOT_ALLOWED), "mgf1 digest not allowed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MISSING_PRIVATE_KEY), + "missing private key"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R), "mp coefficient not inverse of r"}, @@ -256,10 +155,8 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { int ERR_load_RSA_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { - ERR_load_strings_const(RSA_str_functs); + if (ERR_reason_error_string(RSA_str_reasons[0].error) == NULL) ERR_load_strings_const(RSA_str_reasons); - } #endif return 1; } diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index f337a0df..c6e57008 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -325,6 +325,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) if (d != NULL) { BN_clear_free(r->d); r->d = d; + BN_set_flags(r->d, BN_FLG_CONSTTIME); } return 1; @@ -342,10 +343,12 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) if (p != NULL) { BN_clear_free(r->p); r->p = p; + BN_set_flags(r->p, BN_FLG_CONSTTIME); } if (q != NULL) { BN_clear_free(r->q); r->q = q; + BN_set_flags(r->q, BN_FLG_CONSTTIME); } return 1; @@ -364,14 +367,17 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) if (dmp1 != NULL) { BN_clear_free(r->dmp1); r->dmp1 = dmp1; + BN_set_flags(r->dmp1, BN_FLG_CONSTTIME); } if (dmq1 != NULL) { BN_clear_free(r->dmq1); r->dmq1 = dmq1; + BN_set_flags(r->dmq1, BN_FLG_CONSTTIME); } if (iqmp != NULL) { BN_clear_free(r->iqmp); r->iqmp = iqmp; + BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); } return 1; @@ -403,12 +409,15 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], if (pinfo == NULL) goto err; if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) { - BN_free(pinfo->r); - BN_free(pinfo->d); - BN_free(pinfo->t); + BN_clear_free(pinfo->r); + BN_clear_free(pinfo->d); + BN_clear_free(pinfo->t); pinfo->r = primes[i]; pinfo->d = exps[i]; pinfo->t = coeffs[i]; + BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); } else { rsa_multip_info_free(pinfo); goto err; diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index e6876de6..5d5efdbd 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -321,6 +321,11 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } + if (rsa->d == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_MISSING_PRIVATE_KEY); + BN_free(d); + goto err; + } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, @@ -438,6 +443,11 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } + if (rsa->d == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_MISSING_PRIVATE_KEY); + BN_free(d); + goto err; + } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) @@ -460,6 +470,8 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, goto err; j = BN_bn2binpad(ret, buf, num); + if (j < 0) + goto err; switch (padding) { case RSA_PKCS1_PADDING: @@ -559,6 +571,8 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, goto err; i = BN_bn2binpad(ret, buf, num); + if (i < 0) + goto err; switch (padding) { case RSA_PKCS1_PADDING: diff --git a/crypto/s390x_arch.h b/crypto/s390x_arch.h index 5e12542c..bb69ed02 100644 --- a/crypto/s390x_arch.h +++ b/crypto/s390x_arch.h @@ -55,88 +55,88 @@ struct OPENSSL_s390xcap_st { extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; /* Max number of 64-bit words currently returned by STFLE */ -# define S390X_STFLE_MAX 3 +# define S390X_STFLE_MAX 3 /* convert facility bit number or function code to bit mask */ -# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) +# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) # endif /* OPENSSL_s390xcap_P offsets [bytes] */ -# define S390X_STFLE 0x00 -# define S390X_KIMD 0x20 -# define S390X_KLMD 0x30 -# define S390X_KM 0x40 -# define S390X_KMC 0x50 -# define S390X_KMAC 0x60 -# define S390X_KMCTR 0x70 -# define S390X_KMO 0x80 -# define S390X_KMF 0x90 -# define S390X_PRNO 0xa0 -# define S390X_KMA 0xb0 -# define S390X_PCC 0xc0 -# define S390X_KDSA 0xd0 +# define S390X_STFLE 0x00 +# define S390X_KIMD 0x20 +# define S390X_KLMD 0x30 +# define S390X_KM 0x40 +# define S390X_KMC 0x50 +# define S390X_KMAC 0x60 +# define S390X_KMCTR 0x70 +# define S390X_KMO 0x80 +# define S390X_KMF 0x90 +# define S390X_PRNO 0xa0 +# define S390X_KMA 0xb0 +# define S390X_PCC 0xc0 +# define S390X_KDSA 0xd0 /* Facility Bit Numbers */ -# define S390X_MSA 17 /* message-security-assist */ -# define S390X_STCKF 25 /* store-clock-fast */ -# define S390X_MSA5 57 /* message-security-assist-ext. 5 */ -# define S390X_MSA3 76 /* message-security-assist-ext. 3 */ -# define S390X_MSA4 77 /* message-security-assist-ext. 4 */ -# define S390X_VX 129 /* vector */ -# define S390X_VXD 134 /* vector packed decimal */ -# define S390X_VXE 135 /* vector enhancements 1 */ -# define S390X_MSA8 146 /* message-security-assist-ext. 8 */ -# define S390X_MSA9 155 /* message-security-assist-ext. 9 */ +# define S390X_MSA 17 /* message-security-assist */ +# define S390X_STCKF 25 /* store-clock-fast */ +# define S390X_MSA5 57 /* message-security-assist-ext. 5 */ +# define S390X_MSA3 76 /* message-security-assist-ext. 3 */ +# define S390X_MSA4 77 /* message-security-assist-ext. 4 */ +# define S390X_VX 129 /* vector */ +# define S390X_VXD 134 /* vector packed decimal */ +# define S390X_VXE 135 /* vector enhancements 1 */ +# define S390X_MSA8 146 /* message-security-assist-ext. 8 */ +# define S390X_MSA9 155 /* message-security-assist-ext. 9 */ /* Function Codes */ /* all instructions */ -# define S390X_QUERY 0 +# define S390X_QUERY 0 /* kimd/klmd */ -# define S390X_SHA_1 1 -# define S390X_SHA_256 2 -# define S390X_SHA_512 3 -# define S390X_SHA3_224 32 -# define S390X_SHA3_256 33 -# define S390X_SHA3_384 34 -# define S390X_SHA3_512 35 -# define S390X_SHAKE_128 36 -# define S390X_SHAKE_256 37 -# define S390X_GHASH 65 +# define S390X_SHA_1 1 +# define S390X_SHA_256 2 +# define S390X_SHA_512 3 +# define S390X_SHA3_224 32 +# define S390X_SHA3_256 33 +# define S390X_SHA3_384 34 +# define S390X_SHA3_512 35 +# define S390X_SHAKE_128 36 +# define S390X_SHAKE_256 37 +# define S390X_GHASH 65 /* km/kmc/kmac/kmctr/kmo/kmf/kma */ -# define S390X_AES_128 18 -# define S390X_AES_192 19 -# define S390X_AES_256 20 +# define S390X_AES_128 18 +# define S390X_AES_192 19 +# define S390X_AES_256 20 /* km */ -# define S390X_XTS_AES_128 50 -# define S390X_XTS_AES_256 52 +# define S390X_XTS_AES_128 50 +# define S390X_XTS_AES_256 52 /* prno */ -# define S390X_SHA_512_DRNG 3 -# define S390X_TRNG 114 +# define S390X_SHA_512_DRNG 3 +# define S390X_TRNG 114 /* pcc */ -# define S390X_SCALAR_MULTIPLY_P256 64 -# define S390X_SCALAR_MULTIPLY_P384 65 -# define S390X_SCALAR_MULTIPLY_P521 66 +# define S390X_SCALAR_MULTIPLY_P256 64 +# define S390X_SCALAR_MULTIPLY_P384 65 +# define S390X_SCALAR_MULTIPLY_P521 66 /* kdsa */ -# define S390X_ECDSA_VERIFY_P256 1 -# define S390X_ECDSA_VERIFY_P384 2 -# define S390X_ECDSA_VERIFY_P521 3 -# define S390X_ECDSA_SIGN_P256 9 -# define S390X_ECDSA_SIGN_P384 10 -# define S390X_ECDSA_SIGN_P521 11 +# define S390X_ECDSA_VERIFY_P256 1 +# define S390X_ECDSA_VERIFY_P384 2 +# define S390X_ECDSA_VERIFY_P521 3 +# define S390X_ECDSA_SIGN_P256 9 +# define S390X_ECDSA_SIGN_P384 10 +# define S390X_ECDSA_SIGN_P521 11 /* Register 0 Flags */ -# define S390X_DECRYPT 0x80 -# define S390X_KMA_LPC 0x100 -# define S390X_KMA_LAAD 0x200 -# define S390X_KMA_HS 0x400 -# define S390X_KDSA_D 0x80 +# define S390X_DECRYPT 0x80 +# define S390X_KMA_LPC 0x100 +# define S390X_KMA_LAAD 0x200 +# define S390X_KMA_HS 0x400 +# define S390X_KDSA_D 0x80 #endif diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index b75eacf2..5123e14f 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -16,56 +16,64 @@ #include "internal/ctype.h" #include "s390x_arch.h" -#define LEN 128 -#define STR_(S) #S -#define STR(S) STR_(S) +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 16) +# include +# define OSSL_IMPLEMENT_GETAUXVAL +# endif +#endif -#define TOK_FUNC(NAME) \ - (sscanf(tok_begin, \ - " " STR(NAME) " : %" STR(LEN) "[^:] : " \ - "%" STR(LEN) "s %" STR(LEN) "s ", \ - tok[0], tok[1], tok[2]) == 2) { \ - \ - off = (tok[0][0] == '~') ? 1 : 0; \ - if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \ - goto ret; \ - if (off) \ - cap->NAME[0] = ~cap->NAME[0]; \ - \ - off = (tok[1][0] == '~') ? 1 : 0; \ - if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \ - goto ret; \ - if (off) \ - cap->NAME[1] = ~cap->NAME[1]; \ +#define LEN 128 +#define STR_(S) #S +#define STR(S) STR_(S) + +#define TOK_FUNC(NAME) \ + (sscanf(tok_begin, \ + " " STR(NAME) " : %" STR(LEN) "[^:] : " \ + "%" STR(LEN) "s %" STR(LEN) "s ", \ + tok[0], tok[1], tok[2]) == 2) { \ + \ + off = (tok[0][0] == '~') ? 1 : 0; \ + if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \ + goto ret; \ + if (off) \ + cap->NAME[0] = ~cap->NAME[0]; \ + \ + off = (tok[1][0] == '~') ? 1 : 0; \ + if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \ + goto ret; \ + if (off) \ + cap->NAME[1] = ~cap->NAME[1]; \ } -#define TOK_CPU(NAME) \ - (sscanf(tok_begin, \ - " %" STR(LEN) "s %" STR(LEN) "s ", \ - tok[0], tok[1]) == 1 \ - && !strcmp(tok[0], #NAME)) { \ - memcpy(cap, &NAME, sizeof(*cap)); \ +#define TOK_CPU(NAME) \ + (sscanf(tok_begin, \ + " %" STR(LEN) "s %" STR(LEN) "s ", \ + tok[0], tok[1]) == 1 \ + && !strcmp(tok[0], #NAME)) { \ + memcpy(cap, &NAME, sizeof(*cap)); \ } +#ifndef OSSL_IMPLEMENT_GETAUXVAL static sigjmp_buf ill_jmp; static void ill_handler(int sig) { siglongjmp(ill_jmp, sig); } +void OPENSSL_vx_probe(void); +#endif + static const char *env; static int parse_env(struct OPENSSL_s390xcap_st *cap); void OPENSSL_s390x_facilities(void); void OPENSSL_s390x_functions(void); -void OPENSSL_vx_probe(void); struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; void OPENSSL_cpuid_setup(void) { - sigset_t oset; - struct sigaction ill_act, oact; struct OPENSSL_s390xcap_st cap; if (OPENSSL_s390xcap_P.stfle[0]) @@ -74,47 +82,70 @@ 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 + { + const unsigned long hwcap = getauxval(AT_HWCAP); + + /* protection against missing store-facility-list-extended */ + if (hwcap & HWCAP_S390_STFLE) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if (!(hwcap & HWCAP_S390_VX)) { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + } +#else + { + sigset_t oset; + struct sigaction ill_act, oact_ill, oact_fpe; + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); + sigdelset(&ill_act.sa_mask, SIGFPE); + sigdelset(&ill_act.sa_mask, SIGTRAP); + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact_ill); + sigaction(SIGFPE, &ill_act, &oact_fpe); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp, 1) == 0) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) + && (sigsetjmp(ill_jmp, 1) == 0)) { + OPENSSL_vx_probe(); + } else { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + + sigaction(SIGFPE, &oact_fpe, NULL); + sigaction(SIGILL, &oact_ill, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + } +#endif + env = getenv("OPENSSL_s390xcap"); if (env != NULL) { if (!parse_env(&cap)) env = NULL; } - memset(&ill_act, 0, sizeof(ill_act)); - ill_act.sa_handler = ill_handler; - sigfillset(&ill_act.sa_mask); - sigdelset(&ill_act.sa_mask, SIGILL); - sigdelset(&ill_act.sa_mask, SIGFPE); - sigdelset(&ill_act.sa_mask, SIGTRAP); - sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); - sigaction(SIGILL, &ill_act, &oact); - sigaction(SIGFPE, &ill_act, &oact); - - /* protection against missing store-facility-list-extended */ - if (sigsetjmp(ill_jmp, 1) == 0) - OPENSSL_s390x_facilities(); - if (env != NULL) { OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0]; OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1]; OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2]; } - /* protection against disabled vector facility */ - if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) - && (sigsetjmp(ill_jmp, 1) == 0)) { - OPENSSL_vx_probe(); - } else { - OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) - | S390X_CAPBIT(S390X_VXD) - | S390X_CAPBIT(S390X_VXE)); - } - - sigaction(SIGFPE, &oact, NULL); - sigaction(SIGILL, &oact, NULL); - sigprocmask(SIG_SETMASK, &oset, NULL); - - OPENSSL_s390x_functions(); + OPENSSL_s390x_functions(); /* check OPENSSL_s390xcap_P.stfle */ if (env != NULL) { OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0]; diff --git a/crypto/s390xcpuid.pl b/crypto/s390xcpuid.pl index 2678b21e..36f74206 100755 --- a/crypto/s390xcpuid.pl +++ b/crypto/s390xcpuid.pl @@ -6,7 +6,10 @@ # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -16,8 +19,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $ra="%r14"; $sp="%r15"; @@ -443,7 +445,7 @@ ___ } ################ -# void s390x_pcc(unsigned int fc, void *param) +# int s390x_pcc(unsigned int fc, void *param) { my ($fc,$param) = map("%r$_",(2..3)); $code.=<<___; @@ -468,8 +470,8 @@ ___ } ################ -# void s390x_kdsa(unsigned int fc, void *param, -# const unsigned char *in, size_t len) +# int s390x_kdsa(unsigned int fc, void *param, +# const unsigned char *in, size_t len) { my ($fc,$param,$in,$len) = map("%r$_",(2..5)); $code.=<<___; diff --git a/crypto/sha/asm/keccak1600-armv4.pl b/crypto/sha/asm/keccak1600-armv4.pl index be411ed7..1ab0e811 100755 --- a/crypto/sha/asm/keccak1600-armv4.pl +++ b/crypto/sha/asm/keccak1600-armv4.pl @@ -70,9 +70,10 @@ # Cortex-Mx, x>=3. Otherwise, non-NEON results for NEON-capable # processors are presented mostly for reference purposes. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -80,9 +81,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } my @C = map("r$_",(0..9)); @@ -1132,9 +1134,9 @@ KeccakF1600_neon: .align 4 .Loop_neon: @ Theta - vst1.64 {q4}, [r0:64] @ offload A[0..1][4] + vst1.64 {q4}, [r0,:64] @ offload A[0..1][4] veor q13, q0, q5 @ A[0..1][0]^A[2..3][0] - vst1.64 {d18}, [r1:64] @ offload A[2][4] + vst1.64 {d18}, [r1,:64] @ offload A[2][4] veor q14, q1, q6 @ A[0..1][1]^A[2..3][1] veor q15, q2, q7 @ A[0..1][2]^A[2..3][2] veor d26, d26, d27 @ C[0]=A[0][0]^A[1][0]^A[2][0]^A[3][0] @@ -1177,10 +1179,10 @@ KeccakF1600_neon: veor d16, d16, d28 @ A[2][3] ^= C[2] veor d17, d17, d28 @ A[3][3] ^= C[2] veor d23, d23, d28 @ A[4][3] ^= C[2] - vld1.64 {q4}, [r0:64] @ restore A[0..1][4] + vld1.64 {q4}, [r0,:64] @ restore A[0..1][4] vmov d28, d29 - vld1.64 {d18}, [r1:64] @ restore A[2][4] + vld1.64 {d18}, [r1,:64] @ restore A[2][4] veor q2, q2, q13 @ A[0..1][2] ^= D[2] veor q7, q7, q13 @ A[2..3][2] ^= D[2] veor d22, d22, d27 @ A[4][2] ^= D[2] @@ -1255,7 +1257,7 @@ KeccakF1600_neon: veor q13, q13, q0 @ A[0..1][0] ^ (~A[0..1][1] & A[0..1][2]) veor q14, q14, q1 @ A[0..1][1] ^ (~A[0..1][2] & A[0..1][3]) veor q2, q2, q15 @ A[0..1][2] ^= (~A[0..1][3] & A[0..1][4]) - vst1.64 {q13}, [r0:64] @ offload A[0..1][0] + vst1.64 {q13}, [r0,:64] @ offload A[0..1][0] vbic q13, q0, q4 vbic q15, q1, q0 vmov q1, q14 @ A[0..1][1] @@ -1276,10 +1278,10 @@ KeccakF1600_neon: vmov q14, q10 @ A[4][0..1] veor q9, q9, q13 @ A[2..3][4] ^= (~A[2..3][0] & A[2..3][1]) - vld1.64 d25, [r2:64]! @ Iota[i++] + vld1.64 d25, [r2,:64]! @ Iota[i++] vbic d26, d22, d21 vbic d27, d23, d22 - vld1.64 {q0}, [r0:64] @ restore A[0..1][0] + vld1.64 {q0}, [r0,:64] @ restore A[0..1][0] veor d20, d20, d26 @ A[4][0] ^= (~A[4][1] & A[4][2]) vbic d26, d24, d23 veor d21, d21, d27 @ A[4][1] ^= (~A[4][2] & A[4][3]) @@ -1307,32 +1309,32 @@ SHA3_absorb_neon: mov r5, r2 @ len mov r6, r3 @ bsz - vld1.32 {d0}, [r0:64]! @ A[0][0] - vld1.32 {d2}, [r0:64]! @ A[0][1] - vld1.32 {d4}, [r0:64]! @ A[0][2] - vld1.32 {d6}, [r0:64]! @ A[0][3] - vld1.32 {d8}, [r0:64]! @ A[0][4] + vld1.32 {d0}, [r0,:64]! @ A[0][0] + vld1.32 {d2}, [r0,:64]! @ A[0][1] + vld1.32 {d4}, [r0,:64]! @ A[0][2] + vld1.32 {d6}, [r0,:64]! @ A[0][3] + vld1.32 {d8}, [r0,:64]! @ A[0][4] - vld1.32 {d1}, [r0:64]! @ A[1][0] - vld1.32 {d3}, [r0:64]! @ A[1][1] - vld1.32 {d5}, [r0:64]! @ A[1][2] - vld1.32 {d7}, [r0:64]! @ A[1][3] - vld1.32 {d9}, [r0:64]! @ A[1][4] + vld1.32 {d1}, [r0,:64]! @ A[1][0] + vld1.32 {d3}, [r0,:64]! @ A[1][1] + vld1.32 {d5}, [r0,:64]! @ A[1][2] + vld1.32 {d7}, [r0,:64]! @ A[1][3] + vld1.32 {d9}, [r0,:64]! @ A[1][4] - vld1.32 {d10}, [r0:64]! @ A[2][0] - vld1.32 {d12}, [r0:64]! @ A[2][1] - vld1.32 {d14}, [r0:64]! @ A[2][2] - vld1.32 {d16}, [r0:64]! @ A[2][3] - vld1.32 {d18}, [r0:64]! @ A[2][4] + vld1.32 {d10}, [r0,:64]! @ A[2][0] + vld1.32 {d12}, [r0,:64]! @ A[2][1] + vld1.32 {d14}, [r0,:64]! @ A[2][2] + vld1.32 {d16}, [r0,:64]! @ A[2][3] + vld1.32 {d18}, [r0,:64]! @ A[2][4] - vld1.32 {d11}, [r0:64]! @ A[3][0] - vld1.32 {d13}, [r0:64]! @ A[3][1] - vld1.32 {d15}, [r0:64]! @ A[3][2] - vld1.32 {d17}, [r0:64]! @ A[3][3] - vld1.32 {d19}, [r0:64]! @ A[3][4] + vld1.32 {d11}, [r0,:64]! @ A[3][0] + vld1.32 {d13}, [r0,:64]! @ A[3][1] + vld1.32 {d15}, [r0,:64]! @ A[3][2] + vld1.32 {d17}, [r0,:64]! @ A[3][3] + vld1.32 {d19}, [r0,:64]! @ A[3][4] - vld1.32 {d20-d23}, [r0:64]! @ A[4][0..3] - vld1.32 {d24}, [r0:64] @ A[4][4] + vld1.32 {d20-d23}, [r0,:64]! @ A[4][0..3] + vld1.32 {d24}, [r0,:64] @ A[4][4] sub r0, r0, #24*8 @ rewind b .Loop_absorb_neon @@ -1439,32 +1441,32 @@ SHA3_absorb_neon: .align 4 .Labsorbed_neon: - vst1.32 {d0}, [r0:64]! @ A[0][0..4] - vst1.32 {d2}, [r0:64]! - vst1.32 {d4}, [r0:64]! - vst1.32 {d6}, [r0:64]! - vst1.32 {d8}, [r0:64]! + vst1.32 {d0}, [r0,:64]! @ A[0][0..4] + vst1.32 {d2}, [r0,:64]! + vst1.32 {d4}, [r0,:64]! + vst1.32 {d6}, [r0,:64]! + vst1.32 {d8}, [r0,:64]! - vst1.32 {d1}, [r0:64]! @ A[1][0..4] - vst1.32 {d3}, [r0:64]! - vst1.32 {d5}, [r0:64]! - vst1.32 {d7}, [r0:64]! - vst1.32 {d9}, [r0:64]! + vst1.32 {d1}, [r0,:64]! @ A[1][0..4] + vst1.32 {d3}, [r0,:64]! + vst1.32 {d5}, [r0,:64]! + vst1.32 {d7}, [r0,:64]! + vst1.32 {d9}, [r0,:64]! - vst1.32 {d10}, [r0:64]! @ A[2][0..4] - vst1.32 {d12}, [r0:64]! - vst1.32 {d14}, [r0:64]! - vst1.32 {d16}, [r0:64]! - vst1.32 {d18}, [r0:64]! + vst1.32 {d10}, [r0,:64]! @ A[2][0..4] + vst1.32 {d12}, [r0,:64]! + vst1.32 {d14}, [r0,:64]! + vst1.32 {d16}, [r0,:64]! + vst1.32 {d18}, [r0,:64]! - vst1.32 {d11}, [r0:64]! @ A[3][0..4] - vst1.32 {d13}, [r0:64]! - vst1.32 {d15}, [r0:64]! - vst1.32 {d17}, [r0:64]! - vst1.32 {d19}, [r0:64]! + vst1.32 {d11}, [r0,:64]! @ A[3][0..4] + vst1.32 {d13}, [r0,:64]! + vst1.32 {d15}, [r0,:64]! + vst1.32 {d17}, [r0,:64]! + vst1.32 {d19}, [r0,:64]! - vst1.32 {d20-d23}, [r0:64]! @ A[4][0..4] - vst1.32 {d24}, [r0:64] + vst1.32 {d20-d23}, [r0,:64]! @ A[4][0..4] + vst1.32 {d24}, [r0,:64] mov r0, r5 @ return value vldmia sp!, {d8-d15} @@ -1499,64 +1501,64 @@ SHA3_squeeze_neon: vstmdb sp!, {d8-d15} - vld1.32 {d0}, [r0:64]! @ A[0][0..4] - vld1.32 {d2}, [r0:64]! - vld1.32 {d4}, [r0:64]! - vld1.32 {d6}, [r0:64]! - vld1.32 {d8}, [r0:64]! + vld1.32 {d0}, [r0,:64]! @ A[0][0..4] + vld1.32 {d2}, [r0,:64]! + vld1.32 {d4}, [r0,:64]! + vld1.32 {d6}, [r0,:64]! + vld1.32 {d8}, [r0,:64]! - vld1.32 {d1}, [r0:64]! @ A[1][0..4] - vld1.32 {d3}, [r0:64]! - vld1.32 {d5}, [r0:64]! - vld1.32 {d7}, [r0:64]! - vld1.32 {d9}, [r0:64]! + vld1.32 {d1}, [r0,:64]! @ A[1][0..4] + vld1.32 {d3}, [r0,:64]! + vld1.32 {d5}, [r0,:64]! + vld1.32 {d7}, [r0,:64]! + vld1.32 {d9}, [r0,:64]! - vld1.32 {d10}, [r0:64]! @ A[2][0..4] - vld1.32 {d12}, [r0:64]! - vld1.32 {d14}, [r0:64]! - vld1.32 {d16}, [r0:64]! - vld1.32 {d18}, [r0:64]! + vld1.32 {d10}, [r0,:64]! @ A[2][0..4] + vld1.32 {d12}, [r0,:64]! + vld1.32 {d14}, [r0,:64]! + vld1.32 {d16}, [r0,:64]! + vld1.32 {d18}, [r0,:64]! - vld1.32 {d11}, [r0:64]! @ A[3][0..4] - vld1.32 {d13}, [r0:64]! - vld1.32 {d15}, [r0:64]! - vld1.32 {d17}, [r0:64]! - vld1.32 {d19}, [r0:64]! + vld1.32 {d11}, [r0,:64]! @ A[3][0..4] + vld1.32 {d13}, [r0,:64]! + vld1.32 {d15}, [r0,:64]! + vld1.32 {d17}, [r0,:64]! + vld1.32 {d19}, [r0,:64]! - vld1.32 {d20-d23}, [r0:64]! @ A[4][0..4] - vld1.32 {d24}, [r0:64] + vld1.32 {d20-d23}, [r0,:64]! @ A[4][0..4] + vld1.32 {d24}, [r0,:64] sub r0, r0, #24*8 @ rewind bl KeccakF1600_neon mov r12, r0 @ A_flat - vst1.32 {d0}, [r0:64]! @ A[0][0..4] - vst1.32 {d2}, [r0:64]! - vst1.32 {d4}, [r0:64]! - vst1.32 {d6}, [r0:64]! - vst1.32 {d8}, [r0:64]! + vst1.32 {d0}, [r0,:64]! @ A[0][0..4] + vst1.32 {d2}, [r0,:64]! + vst1.32 {d4}, [r0,:64]! + vst1.32 {d6}, [r0,:64]! + vst1.32 {d8}, [r0,:64]! - vst1.32 {d1}, [r0:64]! @ A[1][0..4] - vst1.32 {d3}, [r0:64]! - vst1.32 {d5}, [r0:64]! - vst1.32 {d7}, [r0:64]! - vst1.32 {d9}, [r0:64]! + vst1.32 {d1}, [r0,:64]! @ A[1][0..4] + vst1.32 {d3}, [r0,:64]! + vst1.32 {d5}, [r0,:64]! + vst1.32 {d7}, [r0,:64]! + vst1.32 {d9}, [r0,:64]! - vst1.32 {d10}, [r0:64]! @ A[2][0..4] - vst1.32 {d12}, [r0:64]! - vst1.32 {d14}, [r0:64]! - vst1.32 {d16}, [r0:64]! - vst1.32 {d18}, [r0:64]! + vst1.32 {d10}, [r0,:64]! @ A[2][0..4] + vst1.32 {d12}, [r0,:64]! + vst1.32 {d14}, [r0,:64]! + vst1.32 {d16}, [r0,:64]! + vst1.32 {d18}, [r0,:64]! - vst1.32 {d11}, [r0:64]! @ A[3][0..4] - vst1.32 {d13}, [r0:64]! - vst1.32 {d15}, [r0:64]! - vst1.32 {d17}, [r0:64]! - vst1.32 {d19}, [r0:64]! + vst1.32 {d11}, [r0,:64]! @ A[3][0..4] + vst1.32 {d13}, [r0,:64]! + vst1.32 {d15}, [r0,:64]! + vst1.32 {d17}, [r0,:64]! + vst1.32 {d19}, [r0,:64]! - vst1.32 {d20-d23}, [r0:64]! @ A[4][0..4] + vst1.32 {d20-d23}, [r0,:64]! @ A[4][0..4] mov r14, r6 @ bsz - vst1.32 {d24}, [r0:64] + vst1.32 {d24}, [r0,:64] mov r0, r12 @ rewind vldmia sp!, {d8-d15} diff --git a/crypto/sha/asm/keccak1600-armv8.pl b/crypto/sha/asm/keccak1600-armv8.pl index 66206908..515491a9 100755 --- a/crypto/sha/asm/keccak1600-armv8.pl +++ b/crypto/sha/asm/keccak1600-armv8.pl @@ -59,15 +59,18 @@ # Cortex-A57 to 25% on Cortex-A53. While in comparison to older # compiler this code is at least 2x faster... -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my @rhotates = ([ 0, 1, 62, 28, 27 ], diff --git a/crypto/sha/asm/keccak1600-avx2.pl b/crypto/sha/asm/keccak1600-avx2.pl index 56aeb0d9..a56756fb 100755 --- a/crypto/sha/asm/keccak1600-avx2.pl +++ b/crypto/sha/asm/keccak1600-avx2.pl @@ -476,7 +476,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX2, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/sha/asm/keccak1600-avx512.pl b/crypto/sha/asm/keccak1600-avx512.pl index bbad46db..be4a7ace 100755 --- a/crypto/sha/asm/keccak1600-avx512.pl +++ b/crypto/sha/asm/keccak1600-avx512.pl @@ -545,7 +545,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX-512F, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/sha/asm/keccak1600-avx512vl.pl b/crypto/sha/asm/keccak1600-avx512vl.pl index 86d26012..8616050a 100755 --- a/crypto/sha/asm/keccak1600-avx512vl.pl +++ b/crypto/sha/asm/keccak1600-avx512vl.pl @@ -386,7 +386,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX512VL, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/sha/asm/keccak1600-c64x.pl b/crypto/sha/asm/keccak1600-c64x.pl index b196b618..7433c998 100755 --- a/crypto/sha/asm/keccak1600-c64x.pl +++ b/crypto/sha/asm/keccak1600-c64x.pl @@ -879,7 +879,6 @@ iotas: .align 4 ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT; diff --git a/crypto/sha/asm/keccak1600-mmx.pl b/crypto/sha/asm/keccak1600-mmx.pl index d7a390d8..8be05a1f 100755 --- a/crypto/sha/asm/keccak1600-mmx.pl +++ b/crypto/sha/asm/keccak1600-mmx.pl @@ -65,8 +65,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/sha/asm/keccak1600-ppc64.pl b/crypto/sha/asm/keccak1600-ppc64.pl index 876632b1..6f590635 100755 --- a/crypto/sha/asm/keccak1600-ppc64.pl +++ b/crypto/sha/asm/keccak1600-ppc64.pl @@ -37,7 +37,10 @@ # much better (but watch out for them generating code specific # to processor they execute on). -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -53,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T+6*$SIZE_T+32; $LOCALS=6*$SIZE_T; diff --git a/crypto/sha/asm/keccak1600-s390x.pl b/crypto/sha/asm/keccak1600-s390x.pl index 2d5cb417..99cbee30 100755 --- a/crypto/sha/asm/keccak1600-s390x.pl +++ b/crypto/sha/asm/keccak1600-s390x.pl @@ -30,7 +30,10 @@ # amount of instruction and assumed instruction issue rate. It's ~2.5x # faster than compiler-generated code. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -40,8 +43,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; my @A = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (0,5,10,15,20)); diff --git a/crypto/sha/asm/keccak1600-x86_64.pl b/crypto/sha/asm/keccak1600-x86_64.pl index fda4ee12..80c7cc43 100755 --- a/crypto/sha/asm/keccak1600-x86_64.pl +++ b/crypto/sha/asm/keccak1600-x86_64.pl @@ -50,9 +50,10 @@ # improved by 14% by replacing rotates with double-precision # shift with same register as source and destination. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -61,7 +62,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my @A = map([ 8*$_-100, 8*($_+1)-100, 8*($_+2)-100, diff --git a/crypto/sha/asm/keccak1600p8-ppc.pl b/crypto/sha/asm/keccak1600p8-ppc.pl index 9a97cfdb..0fdc23f6 100755 --- a/crypto/sha/asm/keccak1600p8-ppc.pl +++ b/crypto/sha/asm/keccak1600p8-ppc.pl @@ -25,7 +25,10 @@ # successor can achieve higher scalar instruction issue rate, then # this module will loose... And it does on POWER9 with 12.0 vs. 9.4. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -48,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=6*$SIZE_T+13*16; # 13*16 is for v20-v31 offload diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl index abc84dd6..6622b021 100644 --- a/crypto/sha/asm/sha1-586.pl +++ b/crypto/sha/asm/sha1-586.pl @@ -123,8 +123,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl index cd0b95ad..24fc5bf4 100644 --- a/crypto/sha/asm/sha1-armv4-large.pl +++ b/crypto/sha/asm/sha1-armv4-large.pl @@ -75,9 +75,10 @@ # # Add ARMv8 code path performing at 2.35 cpb on Apple A7. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -85,9 +86,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; diff --git a/crypto/sha/asm/sha1-armv8.pl b/crypto/sha/asm/sha1-armv8.pl index 12403eb7..f9f3c5f3 100644 --- a/crypto/sha/asm/sha1-armv8.pl +++ b/crypto/sha/asm/sha1-armv8.pl @@ -33,15 +33,18 @@ # (**) Keep in mind that Denver relies on binary translation, which # optimizes compiler output at run-time. -$flavour = shift; -$output = shift; +# $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 +$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"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; *STDOUT=*OUT; ($ctx,$inp,$num)=("x0","x1","x2"); diff --git a/crypto/sha/asm/sha1-c64xplus.pl b/crypto/sha/asm/sha1-c64xplus.pl index 0a45d2fe..66f15e22 100644 --- a/crypto/sha/asm/sha1-c64xplus.pl +++ b/crypto/sha/asm/sha1-c64xplus.pl @@ -32,8 +32,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($CTX,$INP,$NUM) = ("A4","B4","A6"); # arguments diff --git a/crypto/sha/asm/sha1-ia64.pl b/crypto/sha/asm/sha1-ia64.pl index b0c10f8a..f1b412dc 100644 --- a/crypto/sha/asm/sha1-ia64.pl +++ b/crypto/sha/asm/sha1-ia64.pl @@ -21,7 +21,8 @@ # Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which # is >50% better than HP C and >2x better than gcc. -$output = pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; $code=<<___; .ident \"sha1-ia64.s, version 1.3\" diff --git a/crypto/sha/asm/sha1-mb-x86_64.pl b/crypto/sha/asm/sha1-mb-x86_64.pl index 243ac5ef..0804c580 100644 --- a/crypto/sha/asm/sha1-mb-x86_64.pl +++ b/crypto/sha/asm/sha1-mb-x86_64.pl @@ -38,9 +38,10 @@ # in real-life application are somewhat lower, e.g. for 2KB # fragments they range from 30% to 100% (on Haswell); -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -70,7 +71,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void sha1_multi_block ( diff --git a/crypto/sha/asm/sha1-mips.pl b/crypto/sha/asm/sha1-mips.pl index 86bd88b0..0f23b6b0 100644 --- a/crypto/sha/asm/sha1-mips.pl +++ b/crypto/sha/asm/sha1-mips.pl @@ -52,8 +52,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_ADD="daddu"; # incidentally works even on n32 @@ -77,8 +81,7 @@ if ($flavour =~ /64|n32/i) { $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } diff --git a/crypto/sha/asm/sha1-parisc.pl b/crypto/sha/asm/sha1-parisc.pl index 11f5b399..00c85378 100644 --- a/crypto/sha/asm/sha1-parisc.pl +++ b/crypto/sha/asm/sha1-parisc.pl @@ -26,9 +26,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/sha/asm/sha1-ppc.pl b/crypto/sha/asm/sha1-ppc.pl index ec33895d..f7a75b74 100755 --- a/crypto/sha/asm/sha1-ppc.pl +++ b/crypto/sha/asm/sha1-ppc.pl @@ -26,7 +26,10 @@ # PPC970,gcc-4.0.0 +76% +59% # Power6,xlc-7 +68% +33% -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -53,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T+64; $LOCALS=6*$SIZE_T; diff --git a/crypto/sha/asm/sha1-s390x.pl b/crypto/sha/asm/sha1-s390x.pl index 020a1f1b..091e1c00 100644 --- a/crypto/sha/asm/sha1-s390x.pl +++ b/crypto/sha/asm/sha1-s390x.pl @@ -40,7 +40,10 @@ $kimdfunc=1; # magic function code for kimd instruction -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -50,8 +53,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $K_00_39="%r0"; $K=$K_00_39; $K_40_79="%r1"; diff --git a/crypto/sha/asm/sha1-sparcv9.pl b/crypto/sha/asm/sha1-sparcv9.pl index e5c70257..8ef8b5fe 100644 --- a/crypto/sha/asm/sha1-sparcv9.pl +++ b/crypto/sha/asm/sha1-sparcv9.pl @@ -32,8 +32,7 @@ # single-process result on 8-core processor, or ~9GBps per 2.85GHz # socket. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); $rot1m="%g2"; diff --git a/crypto/sha/asm/sha1-sparcv9a.pl b/crypto/sha/asm/sha1-sparcv9a.pl index ec653361..e0ccea2a 100644 --- a/crypto/sha/asm/sha1-sparcv9a.pl +++ b/crypto/sha/asm/sha1-sparcv9a.pl @@ -47,8 +47,7 @@ for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } if ($bits==64) { $bias=2047; $frame=192; } else { $bias=0; $frame=112; } -$output=shift; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $ctx="%i0"; $inp="%i1"; diff --git a/crypto/sha/asm/sha1-thumb.pl b/crypto/sha/asm/sha1-thumb.pl index fe380e9f..dbe57547 100644 --- a/crypto/sha/asm/sha1-thumb.pl +++ b/crypto/sha/asm/sha1-thumb.pl @@ -26,8 +26,7 @@ # by over 40%, while code increases by only 10% or 32 bytes. But once # again, the goal was to establish _size_ benchmark, not performance. -$output=shift; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $inline=0; #$cheat_on_binutils=1; diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl index 5352afc3..ab10d360 100755 --- a/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/sha/asm/sha1-x86_64.pl @@ -93,9 +93,10 @@ # because SSSE3 code is compiled unconditionally; # (**) SHAEXT result -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -126,7 +127,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $shaext=1; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $ctx="%rdi"; # 1st arg diff --git a/crypto/sha/asm/sha256-586.pl b/crypto/sha/asm/sha256-586.pl index 3693f328..b28b62ab 100644 --- a/crypto/sha/asm/sha256-586.pl +++ b/crypto/sha/asm/sha256-586.pl @@ -73,8 +73,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/sha/asm/sha256-armv4.pl b/crypto/sha/asm/sha256-armv4.pl index cd01fcb5..80c697e0 100644 --- a/crypto/sha/asm/sha256-armv4.pl +++ b/crypto/sha/asm/sha256-armv4.pl @@ -44,9 +44,10 @@ # # Add ARMv8 code path performing at 2.0 cpb on Apple A7. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -54,9 +55,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; $t0="r0"; diff --git a/crypto/sha/asm/sha256-c64xplus.pl b/crypto/sha/asm/sha256-c64xplus.pl index 19d0f722..480b49e4 100644 --- a/crypto/sha/asm/sha256-c64xplus.pl +++ b/crypto/sha/asm/sha256-c64xplus.pl @@ -26,8 +26,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments $K256="A3"; diff --git a/crypto/sha/asm/sha256-mb-x86_64.pl b/crypto/sha/asm/sha256-mb-x86_64.pl index b2dba456..167d3324 100644 --- a/crypto/sha/asm/sha256-mb-x86_64.pl +++ b/crypto/sha/asm/sha256-mb-x86_64.pl @@ -39,9 +39,10 @@ # in real-life application are somewhat lower, e.g. for 2KB # fragments they range from 75% to 130% (on Haswell); -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -71,7 +72,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void sha256_multi_block ( diff --git a/crypto/sha/asm/sha512-586.pl b/crypto/sha/asm/sha512-586.pl index e823f65b..c20a673d 100644 --- a/crypto/sha/asm/sha512-586.pl +++ b/crypto/sha/asm/sha512-586.pl @@ -59,8 +59,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/sha/asm/sha512-armv4.pl b/crypto/sha/asm/sha512-armv4.pl index 39c943b4..410dde2c 100644 --- a/crypto/sha/asm/sha512-armv4.pl +++ b/crypto/sha/asm/sha512-armv4.pl @@ -57,9 +57,10 @@ $hi="HI"; $lo="LO"; # ==================================================================== -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -67,9 +68,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; # parameter block diff --git a/crypto/sha/asm/sha512-armv8.pl b/crypto/sha/asm/sha512-armv8.pl index b9ba05ba..2051157c 100644 --- a/crypto/sha/asm/sha512-armv8.pl +++ b/crypto/sha/asm/sha512-armv8.pl @@ -54,8 +54,10 @@ # deliver much less improvement, likely *negative* on Cortex-A5x. # Which is why NEON support is limited to SHA256.] -$output=pop; -$flavour=pop; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -63,10 +65,11 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open OUT,"| \"$^X\" $xlate $flavour $output"; + open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } if ($output =~ /512/) { diff --git a/crypto/sha/asm/sha512-c64xplus.pl b/crypto/sha/asm/sha512-c64xplus.pl index 27034352..b7a12544 100644 --- a/crypto/sha/asm/sha512-c64xplus.pl +++ b/crypto/sha/asm/sha512-c64xplus.pl @@ -29,8 +29,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +($output = pop) =~ m|\.\w+$| and open STDOUT,">$output"; ($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments $K512="A3"; diff --git a/crypto/sha/asm/sha512-ia64.pl b/crypto/sha/asm/sha512-ia64.pl index b6fb43a3..eccc6c92 100755 --- a/crypto/sha/asm/sha512-ia64.pl +++ b/crypto/sha/asm/sha512-ia64.pl @@ -75,7 +75,8 @@ # To generate code, pass the file name with either 256 or 512 in its # name and compiler flags. -$output=pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; if ($output =~ /512.*\.[s|asm]/) { $SZ=8; @@ -107,7 +108,7 @@ if ($output =~ /512.*\.[s|asm]/) { $rounds=64; } else { die "nonsense $output"; } -open STDOUT,">$output" || die "can't open $output: $!"; +$output and (open STDOUT,">$output" or die "can't open $output: $!"); if ($^O eq "hpux") { $ADDP="addp4"; diff --git a/crypto/sha/asm/sha512-mips.pl b/crypto/sha/asm/sha512-mips.pl index 727b36bd..c581bdcb 100644 --- a/crypto/sha/asm/sha512-mips.pl +++ b/crypto/sha/asm/sha512-mips.pl @@ -56,7 +56,14 @@ # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); # -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 +# if $output doesn't have an extension, it's not an output file +# so use it for $flavour. + +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_LA="dla"; @@ -83,7 +90,6 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2; $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } open STDOUT,">$output"; if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } diff --git a/crypto/sha/asm/sha512-parisc.pl b/crypto/sha/asm/sha512-parisc.pl index 66774e2f..f4064269 100755 --- a/crypto/sha/asm/sha512-parisc.pl +++ b/crypto/sha/asm/sha512-parisc.pl @@ -32,9 +32,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/sha/asm/sha512-ppc.pl b/crypto/sha/asm/sha512-ppc.pl index 424fe66f..722621ec 100755 --- a/crypto/sha/asm/sha512-ppc.pl +++ b/crypto/sha/asm/sha512-ppc.pl @@ -41,8 +41,10 @@ # block signals prior calling this routine. For the record, in 32-bit # context R2 serves as TLS pointer, while in 64-bit context - R13. -$flavour=shift; -$output =shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -69,7 +71,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($output =~ /512/) { $func="sha512_block_ppc"; diff --git a/crypto/sha/asm/sha512-s390x.pl b/crypto/sha/asm/sha512-s390x.pl index 9b38603b..65cb8831 100644 --- a/crypto/sha/asm/sha512-s390x.pl +++ b/crypto/sha/asm/sha512-s390x.pl @@ -43,7 +43,10 @@ # remains z/Architecture specific. On z990 SHA256 was measured to # perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3. -$flavour = shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -71,7 +74,6 @@ $tbl="%r13"; $T1="%r14"; $sp="%r15"; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} open STDOUT,">$output"; if ($output =~ /512/) { diff --git a/crypto/sha/asm/sha512-sparcv9.pl b/crypto/sha/asm/sha512-sparcv9.pl index daf6d226..fca6e863 100644 --- a/crypto/sha/asm/sha512-sparcv9.pl +++ b/crypto/sha/asm/sha512-sparcv9.pl @@ -56,8 +56,10 @@ # saturates at 11.5x single-process result on 8-core processor, or # ~11/16GBps per 2.85GHz socket. -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; if ($output =~ /512/) { $label="512"; diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl index 18a4385e..ef84b090 100755 --- a/crypto/sha/asm/sha512-x86_64.pl +++ b/crypto/sha/asm/sha512-x86_64.pl @@ -109,9 +109,10 @@ # below certain limit makes no difference/sense; to conserve # space SHA256 XOP code path is therefore omitted; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -142,7 +143,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([ $shaext=1; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if ($output =~ /512/) { diff --git a/crypto/sha/asm/sha512p8-ppc.pl b/crypto/sha/asm/sha512p8-ppc.pl index 4721e0af..9ee3ed77 100755 --- a/crypto/sha/asm/sha512p8-ppc.pl +++ b/crypto/sha/asm/sha512p8-ppc.pl @@ -40,8 +40,10 @@ # SHA256 9.7 [15.8] 11.2 [12.5] # SHA512 6.1 [10.3] 7.0 [7.9] -$flavour=shift; -$output =shift; +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -64,7 +66,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($output =~ /512/) { $bits=512; diff --git a/crypto/sha/build.info b/crypto/sha/build.info index 187d0c49..67d9fd47 100644 --- a/crypto/sha/build.info +++ b/crypto/sha/build.info @@ -79,89 +79,86 @@ DEFINE[../../libcrypto]=$SHA1DEF $KECCAK1600DEF SOURCE[../../providers/fips]= $COMMON DEFINE[../../providers/fips]= $SHA1DEF $KECCAK1600DEF -GENERATE[sha1-586.s]=asm/sha1-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[sha1-586.s]=asm/sha1-586.pl DEPEND[sha1-586.s]=../perlasm/x86asm.pl -GENERATE[sha256-586.s]=asm/sha256-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[sha256-586.s]=asm/sha256-586.pl DEPEND[sha256-586.s]=../perlasm/x86asm.pl -GENERATE[sha512-586.s]=asm/sha512-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[sha512-586.s]=asm/sha512-586.pl DEPEND[sha512-586.s]=../perlasm/x86asm.pl -GENERATE[sha1-ia64.s]=asm/sha1-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[sha256-ia64.s]=asm/sha512-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[sha512-ia64.s]=asm/sha512-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[sha1-ia64.s]=asm/sha1-ia64.pl +GENERATE[sha256-ia64.s]=asm/sha512-ia64.pl +GENERATE[sha512-ia64.s]=asm/sha512-ia64.pl -GENERATE[sha1-alpha.S]=asm/sha1-alpha.pl $(PERLASM_SCHEME) +GENERATE[sha1-alpha.S]=asm/sha1-alpha.pl -GENERATE[sha1-x86_64.s]=asm/sha1-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha1-mb-x86_64.s]=asm/sha1-mb-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha256-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha256-mb-x86_64.s]=asm/sha256-mb-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha512-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-x86_64.s]=asm/keccak1600-x86_64.pl $(PERLASM_SCHEME) +GENERATE[sha1-x86_64.s]=asm/sha1-x86_64.pl +GENERATE[sha1-mb-x86_64.s]=asm/sha1-mb-x86_64.pl +GENERATE[sha256-x86_64.s]=asm/sha512-x86_64.pl +GENERATE[sha256-mb-x86_64.s]=asm/sha256-mb-x86_64.pl +GENERATE[sha512-x86_64.s]=asm/sha512-x86_64.pl +GENERATE[keccak1600-x86_64.s]=asm/keccak1600-x86_64.pl -GENERATE[sha1-sparcv9a.S]=asm/sha1-sparcv9a.pl $(PERLASM_SCHEME) -GENERATE[sha1-sparcv9.S]=asm/sha1-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[sha1-sparcv9a.S]=asm/sha1-sparcv9a.pl +GENERATE[sha1-sparcv9.S]=asm/sha1-sparcv9.pl INCLUDE[sha1-sparcv9.o]=.. -GENERATE[sha256-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[sha256-sparcv9.S]=asm/sha512-sparcv9.pl INCLUDE[sha256-sparcv9.o]=.. -GENERATE[sha512-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[sha512-sparcv9.S]=asm/sha512-sparcv9.pl INCLUDE[sha512-sparcv9.o]=.. -GENERATE[sha1-ppc.s]=asm/sha1-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha256-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha512-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha256p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha512p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-ppc64.s]=asm/keccak1600-ppc64.pl $(PERLASM_SCHEME) +GENERATE[sha1-ppc.s]=asm/sha1-ppc.pl +GENERATE[sha256-ppc.s]=asm/sha512-ppc.pl +GENERATE[sha512-ppc.s]=asm/sha512-ppc.pl +GENERATE[sha256p8-ppc.s]=asm/sha512p8-ppc.pl +GENERATE[sha512p8-ppc.s]=asm/sha512p8-ppc.pl +GENERATE[keccak1600-ppc64.s]=asm/keccak1600-ppc64.pl -GENERATE[sha1-parisc.s]=asm/sha1-parisc.pl $(PERLASM_SCHEME) -GENERATE[sha256-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME) -GENERATE[sha512-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME) +GENERATE[sha1-parisc.s]=asm/sha1-parisc.pl +GENERATE[sha256-parisc.s]=asm/sha512-parisc.pl +GENERATE[sha512-parisc.s]=asm/sha512-parisc.pl -GENERATE[sha1-mips.S]=asm/sha1-mips.pl $(PERLASM_SCHEME) +GENERATE[sha1-mips.S]=asm/sha1-mips.pl INCLUDE[sha1-mips.o]=.. -GENERATE[sha256-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME) +GENERATE[sha256-mips.S]=asm/sha512-mips.pl INCLUDE[sha256-mips.o]=.. -GENERATE[sha512-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME) +GENERATE[sha512-mips.S]=asm/sha512-mips.pl INCLUDE[sha512-mips.o]=.. -GENERATE[sha1-armv4-large.S]=asm/sha1-armv4-large.pl $(PERLASM_SCHEME) +GENERATE[sha1-armv4-large.S]=asm/sha1-armv4-large.pl INCLUDE[sha1-armv4-large.o]=.. -GENERATE[sha256-armv4.S]=asm/sha256-armv4.pl $(PERLASM_SCHEME) +GENERATE[sha256-armv4.S]=asm/sha256-armv4.pl INCLUDE[sha256-armv4.o]=.. -GENERATE[sha512-armv4.S]=asm/sha512-armv4.pl $(PERLASM_SCHEME) +GENERATE[sha512-armv4.S]=asm/sha512-armv4.pl INCLUDE[sha512-armv4.o]=.. -GENERATE[keccak1600-armv4.S]=asm/keccak1600-armv4.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-armv4.S]=asm/keccak1600-armv4.pl INCLUDE[keccak1600-armv4.o]=.. -GENERATE[sha1-armv8.S]=asm/sha1-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha1-armv8.S]=asm/sha1-armv8.pl INCLUDE[sha1-armv8.o]=.. -GENERATE[sha256-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha256-armv8.S]=asm/sha512-armv8.pl INCLUDE[sha256-armv8.o]=.. -GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl INCLUDE[sha512-armv8.o]=.. -GENERATE[keccak1600-armv8.S]=asm/keccak1600-armv8.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-armv8.S]=asm/keccak1600-armv8.pl -GENERATE[sha1-s390x.S]=asm/sha1-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha1-s390x.S]=asm/sha1-s390x.pl INCLUDE[sha1-s390x.o]=.. -GENERATE[sha256-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha256-s390x.S]=asm/sha512-s390x.pl INCLUDE[sha256-s390x.o]=.. -GENERATE[sha512-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha512-s390x.S]=asm/sha512-s390x.pl INCLUDE[sha512-s390x.o]=.. -GENERATE[keccak1600-s390x.S]=asm/keccak1600-s390x.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-s390x.S]=asm/keccak1600-s390x.pl -GENERATE[sha1-c64xplus.S]=asm/sha1-c64xplus.pl $(PERLASM_SCHEME) -GENERATE[sha256-c64xplus.S]=asm/sha256-c64xplus.pl $(PERLASM_SCHEME) -GENERATE[sha512-c64xplus.S]=asm/sha512-c64xplus.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-c64x.S]=asm/keccak1600-c64x.pl $(PERLASM_SCHEME) +GENERATE[sha1-c64xplus.S]=asm/sha1-c64xplus.pl +GENERATE[sha256-c64xplus.S]=asm/sha256-c64xplus.pl +GENERATE[sha512-c64xplus.S]=asm/sha512-c64xplus.pl +GENERATE[keccak1600-c64x.S]=asm/keccak1600-c64x.pl # These are not yet used -GENERATE[keccak1600-avx2.S]=asm/keccak1600-avx2.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-avx512.S]=asm/keccak1600-avx512.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-avx512vl.S]=asm/keccak1600-avx512vl.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-mmx.S]=asm/keccak1600-mmx.pl $(PERLASM_SCHEME) -GENERATE[keccak1600p8-ppc.S]=asm/keccak1600p8-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha1-thumb.S]=asm/sha1-thumb.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-avx2.S]=asm/keccak1600-avx2.pl +GENERATE[keccak1600-avx512.S]=asm/keccak1600-avx512.pl +GENERATE[keccak1600-avx512vl.S]=asm/keccak1600-avx512vl.pl +GENERATE[keccak1600-mmx.S]=asm/keccak1600-mmx.pl +GENERATE[keccak1600p8-ppc.S]=asm/keccak1600p8-ppc.pl +GENERATE[sha1-thumb.S]=asm/sha1-thumb.pl diff --git a/crypto/sha/sha3.c b/crypto/sha/sha3.c index 19ef4266..fafa3556 100644 --- a/crypto/sha/sha3.c +++ b/crypto/sha/sha3.c @@ -89,6 +89,9 @@ int sha3_final(unsigned char *md, KECCAK1600_CTX *ctx) size_t bsz = ctx->block_size; size_t num = ctx->bufsz; + if (ctx->md_size == 0) + return 1; + /* * Pad the data with 10*1. Note that |num| can be |bsz - 1| * in which case both byte operations below are performed on diff --git a/crypto/siphash/build.info b/crypto/siphash/build.info index b56563f0..2dc7101a 100644 --- a/crypto/siphash/build.info +++ b/crypto/siphash/build.info @@ -1,5 +1,4 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ siphash.c \ - siphash_meth.c \ siphash_ameth.c diff --git a/crypto/siphash/siphash_meth.c b/crypto/siphash/siphash_meth.c deleted file mode 100644 index 5fcff2d1..00000000 --- a/crypto/siphash/siphash_meth.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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 -#include -#include -#include "internal/siphash.h" -#include "siphash_local.h" -#include "internal/evp_int.h" - -/* local SIPHASH structure is actually a SIPHASH */ - -struct evp_mac_impl_st { - SIPHASH ctx; -}; - -static EVP_MAC_IMPL *siphash_new(void) -{ - return OPENSSL_zalloc(sizeof(EVP_MAC_IMPL)); -} - -static void siphash_free(EVP_MAC_IMPL *sctx) -{ - OPENSSL_free(sctx); -} - -static EVP_MAC_IMPL *siphash_dup(const EVP_MAC_IMPL *ssrc) -{ - EVP_MAC_IMPL *sdst; - - sdst = siphash_new(); - if (sdst == NULL) - return NULL; - - *sdst = *ssrc; - - return sdst; -} - -static size_t siphash_size(EVP_MAC_IMPL *sctx) -{ - return SipHash_hash_size(&sctx->ctx); -} - -static int siphash_init(EVP_MAC_IMPL *sctx) -{ - /* Not much to do here, actual initialization happens through controls */ - return 1; -} - -static int siphash_update(EVP_MAC_IMPL *sctx, const unsigned char *data, - size_t datalen) -{ - SipHash_Update(&sctx->ctx, data, datalen); - return 1; -} - -static int siphash_final(EVP_MAC_IMPL *sctx, unsigned char *out) -{ - size_t hlen = siphash_size(sctx); - - return SipHash_Final(&sctx->ctx, out, hlen); -} - -static int siphash_ctrl(EVP_MAC_IMPL *sctx, int cmd, va_list args) -{ - switch (cmd) { - case EVP_MAC_CTRL_SET_SIZE: - { - size_t size = va_arg(args, size_t); - - return SipHash_set_hash_size(&sctx->ctx, size); - } - break; - case EVP_MAC_CTRL_SET_KEY: - { - const unsigned char *key = va_arg(args, const unsigned char *); - size_t keylen = va_arg(args, size_t); - - if (key == NULL || keylen != SIPHASH_KEY_SIZE) - return 0; - - return SipHash_Init(&sctx->ctx, key, 0, 0); - } - break; - default: - return -2; - } - return 1; -} - -static int siphash_ctrl_int(EVP_MAC_IMPL *sctx, int cmd, ...) -{ - int rv; - va_list args; - - va_start(args, cmd); - rv = siphash_ctrl(sctx, cmd, args); - va_end(args); - - return rv; -} - -static int siphash_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen) -{ - return siphash_ctrl_int(ctx, cmd, buf, buflen); -} - -static int siphash_ctrl_str(EVP_MAC_IMPL *ctx, - const char *type, const char *value) -{ - if (value == NULL) - return 0; - if (strcmp(type, "digestsize") == 0) { - size_t hash_size = atoi(value); - - return siphash_ctrl_int(ctx, EVP_MAC_CTRL_SET_SIZE, hash_size); - } - if (strcmp(type, "key") == 0) - return EVP_str2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY, - value); - if (strcmp(type, "hexkey") == 0) - return EVP_hex2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY, - value); - return -2; -} - -const EVP_MAC siphash_meth = { - EVP_MAC_SIPHASH, - siphash_new, - siphash_dup, - siphash_free, - siphash_size, - siphash_init, - siphash_update, - siphash_final, - siphash_ctrl, - siphash_ctrl_str -}; diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c index 95b0e116..d8e11790 100644 --- a/crypto/sm2/sm2_err.c +++ b/crypto/sm2/sm2_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,30 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA SM2_str_functs[] = { - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_COPY, 0), "pkey_sm2_copy"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_DIGEST_CUSTOM, 0), - "pkey_sm2_digest_custom"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0), - "sm2_compute_msg_hash"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0), - "sm2_compute_userid_digest"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_Z_DIGEST, 0), - "sm2_compute_z_digest"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_DECRYPT, 0), "sm2_decrypt"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_ENCRYPT, 0), "sm2_encrypt"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_PLAINTEXT_SIZE, 0), "sm2_plaintext_size"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIGN, 0), "sm2_sign"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_GEN, 0), "sm2_sig_gen"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_VERIFY, 0), "sm2_sig_verify"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_VERIFY, 0), "sm2_verify"}, - {0, NULL} -}; - static const ERR_STRING_DATA SM2_str_reasons[] = { {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature"}, @@ -60,10 +36,8 @@ static const ERR_STRING_DATA SM2_str_reasons[] = { int ERR_load_SM2_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) { - ERR_load_strings_const(SM2_str_functs); + if (ERR_reason_error_string(SM2_str_reasons[0].error) == NULL) ERR_load_strings_const(SM2_str_reasons); - } #endif return 1; } diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c index 8c81ca37..56e015d9 100644 --- a/crypto/sm2/sm2_pmeth.c +++ b/crypto/sm2/sm2_pmeth.c @@ -232,6 +232,10 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { + uint8_t *hex_id; + long hex_len = 0; + int ret = 0; + if (strcmp(type, "ec_paramgen_curve") == 0) { int nid = NID_undef; @@ -255,6 +259,21 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, } else if (strcmp(type, "sm2_id") == 0) { return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)strlen(value), (void *)value); + } else if (strcmp(type, "sm2_hex_id") == 0) { + /* + * TODO(3.0): reconsider the name "sm2_hex_id", OR change + * OSSL_PARAM_construct_from_text() / OSSL_PARAM_allocate_from_text() + * to handle infix "_hex_" + */ + hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len); + if (hex_id == NULL) { + SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len, + (void *)hex_id); + OPENSSL_free(hex_id); + return ret; } return -2; diff --git a/crypto/sparcv9cap.c b/crypto/sparcv9cap.c index e48ebf7e..ec825662 100644 --- a/crypto/sparcv9cap.c +++ b/crypto/sparcv9cap.c @@ -24,11 +24,6 @@ __attribute__ ((visibility("hidden"))) #endif unsigned int OPENSSL_sparcv9cap_P[2] = { SPARCV9_TICK_PRIVILEGED, 0 }; -/* - * TODO(3.0): Temporarily disabled some assembler that hasn't been brought into - * the FIPS module yet. - */ -#ifndef FIPS_MODE int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num) { @@ -91,7 +86,6 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, } return bn_mul_mont_int(rp, ap, bp, np, n0, num); } -#endif /* FIPS_MODE */ unsigned long _sparcv9_rdtick(void); void _sparcv9_vis1_probe(void); diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index 5a704995..206af12a 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -824,8 +824,9 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader, } if (stat(path_data[i].path, &st) < 0) { - SYSerr(SYS_F_STAT, errno); - ERR_add_error_data(1, path_data[i].path); + ERR_raise_data(ERR_LIB_SYS, errno, + "calling stat(%s)", + path_data[i].path); } else { path = path_data[i].path; } diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c index 254defc1..aa8ab4f9 100644 --- a/crypto/store/store_err.c +++ b/crypto/store/store_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,81 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OSSL_STORE_str_functs[] = { - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_CTRL, 0), "file_ctrl"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_FIND, 0), "file_find"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_GET_PASS, 0), - "file_get_pass"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD, 0), "file_load"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD_TRY_DECODE, 0), - "file_load_try_decode"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_NAME_TO_URI, 0), - "file_name_to_uri"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_OPEN, 0), "file_open"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 0), - "ossl_store_attach_pem_bio"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_EXPECT, 0), - "OSSL_STORE_expect"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, 0), - "ossl_store_file_attach_pem_bio_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FIND, 0), - "OSSL_STORE_find"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, 0), - "ossl_store_get0_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 0), - "OSSL_STORE_INFO_get1_CERT"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, 0), - "OSSL_STORE_INFO_get1_CRL"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, 0), - "OSSL_STORE_INFO_get1_NAME"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, 0), - "OSSL_STORE_INFO_get1_NAME_description"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, 0), - "OSSL_STORE_INFO_get1_PARAMS"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, 0), - "OSSL_STORE_INFO_get1_PKEY"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, 0), - "OSSL_STORE_INFO_new_CERT"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, 0), - "OSSL_STORE_INFO_new_CRL"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, 0), - "ossl_store_info_new_EMBEDDED"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, 0), - "OSSL_STORE_INFO_new_NAME"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, 0), - "OSSL_STORE_INFO_new_PARAMS"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, 0), - "OSSL_STORE_INFO_new_PKEY"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, 0), - "OSSL_STORE_INFO_set0_NAME_description"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INIT_ONCE, 0), - "ossl_store_init_once"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_LOADER_NEW, 0), - "OSSL_STORE_LOADER_new"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_OPEN, 0), - "OSSL_STORE_open"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_OPEN_INT, 0), ""}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, 0), - "ossl_store_register_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, 0), - "OSSL_STORE_SEARCH_by_alias"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, 0), - "OSSL_STORE_SEARCH_by_issuer_serial"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, 0), - "OSSL_STORE_SEARCH_by_key_fingerprint"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, 0), - "OSSL_STORE_SEARCH_by_name"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, 0), - "ossl_store_unregister_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PARAMS, 0), - "try_decode_params"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS12, 0), - "try_decode_PKCS12"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, 0), - "try_decode_PKCS8Encrypted"}, - {0, NULL} -}; - static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE), "ambiguous content type"}, @@ -137,10 +62,8 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { int ERR_load_OSSL_STORE_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OSSL_STORE_str_functs[0].error) == NULL) { - ERR_load_strings_const(OSSL_STORE_str_functs); + if (ERR_reason_error_string(OSSL_STORE_str_reasons[0].error) == NULL) ERR_load_strings_const(OSSL_STORE_str_reasons); - } #endif return 1; } diff --git a/crypto/threads_none.c b/crypto/threads_none.c index ff95556c..c12d5610 100644 --- a/crypto/threads_none.c +++ b/crypto/threads_none.c @@ -12,6 +12,11 @@ #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) +# if defined(OPENSSL_SYS_UNIX) +# include +# include +# endif + CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { CRYPTO_RWLOCK *lock; @@ -133,4 +138,12 @@ int openssl_init_fork_handlers(void) return 0; } +int openssl_get_fork_id(void) +{ +# if defined(OPENSSL_SYS_UNIX) + return getpid(); +# else + return 0; +# endif +} #endif diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 0d351ca6..762da60a 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -10,8 +10,17 @@ #include #include "internal/cryptlib.h" +#if defined(__sun) +# include +#endif + #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) +# if defined(OPENSSL_SYS_UNIX) +# include +# include +#endif + # ifdef PTHREAD_RWLOCK_INITIALIZER # define USE_RWLOCK # endif @@ -162,6 +171,12 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL); return 1; } +# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) + /* This will work for all future Solaris versions. */ + if (ret != NULL) { + *ret = atomic_add_int_nv((volatile unsigned int *)val, amount); + return 1; + } # endif if (!CRYPTO_THREAD_write_lock(lock)) return 0; @@ -197,4 +212,9 @@ int openssl_init_fork_handlers(void) return 0; } # endif /* FIPS_MODE */ + +int openssl_get_fork_id(void) +{ + return getpid(); +} #endif diff --git a/crypto/threads_win.c b/crypto/threads_win.c index 73203834..43bd0f51 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c @@ -24,15 +24,15 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) return NULL; } -#if !defined(_WIN32_WCE) +# if !defined(_WIN32_WCE) /* 0x400 is the spin count value suggested in the documentation */ if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) { OPENSSL_free(lock); return NULL; } -#else +# else InitializeCriticalSection(lock); -#endif +# endif return lock; } @@ -164,4 +164,8 @@ int openssl_init_fork_handlers(void) return 0; } +int openssl_get_fork_id(void) +{ + return 0; +} #endif diff --git a/crypto/trace.c b/crypto/trace.c old mode 100644 new mode 100755 index d9524da1..cc99fff3 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -10,6 +10,7 @@ #include #include +#include "internal/thread_once.h" #include #include #include @@ -218,6 +219,13 @@ static int trace_detach_cb(int category, int type, const void *data) return 1; } +static int do_ossl_trace_init(void); +static CRYPTO_ONCE trace_inited = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_trace_init) +{ + return do_ossl_trace_init(); +} + static int set_trace_data(int category, int type, BIO **channel, const char **prefix, const char **suffix, int (*attach_cb)(int, int, const void *), @@ -227,8 +235,9 @@ static int set_trace_data(int category, int type, BIO **channel, char *curr_prefix = NULL; char *curr_suffix = NULL; - /* Ensure ossl_trace_init() is called */ - OPENSSL_init_crypto(0, NULL); + /* Ensure do_ossl_trace_init() is called once */ + if (!RUN_ONCE(&trace_inited, ossl_trace_init)) + return 0; curr_channel = trace_channels[category].bio; curr_prefix = trace_channels[category].prefix; @@ -297,19 +306,15 @@ static int set_trace_data(int category, int type, BIO **channel, return 1; } -#endif -int ossl_trace_init(void) +static int do_ossl_trace_init(void) { -#ifndef OPENSSL_NO_TRACE trace_lock = CRYPTO_THREAD_lock_new(); - if (trace_lock == NULL) - return 0; -#endif - - return 1; + return trace_lock != NULL; } +#endif + void ossl_trace_cleanup(void) { #ifndef OPENSSL_NO_TRACE diff --git a/crypto/ts/ts_err.c b/crypto/ts/ts_err.c index c971d477..e87c4926 100644 --- a/crypto/ts/ts_err.c +++ b/crypto/ts/ts_err.c @@ -13,91 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA TS_str_functs[] = { - {ERR_PACK(ERR_LIB_TS, TS_F_DEF_SERIAL_CB, 0), "def_serial_cb"}, - {ERR_PACK(ERR_LIB_TS, TS_F_DEF_TIME_CB, 0), "def_time_cb"}, - {ERR_PACK(ERR_LIB_TS, TS_F_INT_TS_RESP_VERIFY_TOKEN, 0), - "int_ts_RESP_verify_token"}, - {ERR_PACK(ERR_LIB_TS, TS_F_PKCS7_TO_TS_TST_INFO, 0), - "PKCS7_to_TS_TST_INFO"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_MICROS, 0), - "TS_ACCURACY_set_micros"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_MILLIS, 0), - "TS_ACCURACY_set_millis"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_SECONDS, 0), - "TS_ACCURACY_set_seconds"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_IMPRINTS, 0), "ts_check_imprints"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_NONCES, 0), "ts_check_nonces"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_POLICY, 0), "ts_check_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_SIGNING_CERTS, 0), - "ts_check_signing_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_STATUS_INFO, 0), - "ts_check_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_COMPUTE_IMPRINT, 0), "ts_compute_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_INVALID, 0), "ts_CONF_invalid"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_CERT, 0), "TS_CONF_load_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_CERTS, 0), "TS_CONF_load_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_KEY, 0), "TS_CONF_load_key"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOOKUP_FAIL, 0), "ts_CONF_lookup_fail"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_SET_DEFAULT_ENGINE, 0), - "TS_CONF_set_default_engine"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_GET_STATUS_TEXT, 0), "ts_get_status_text"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_MSG_IMPRINT_SET_ALGO, 0), - "TS_MSG_IMPRINT_set_algo"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_MSG_IMPRINT, 0), - "TS_REQ_set_msg_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_NONCE, 0), "TS_REQ_set_nonce"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_POLICY_ID, 0), - "TS_REQ_set_policy_id"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CREATE_RESPONSE, 0), - "TS_RESP_create_response"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CREATE_TST_INFO, 0), - "ts_RESP_create_tst_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, 0), - "TS_RESP_CTX_add_failure_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_MD, 0), "TS_RESP_CTX_add_md"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_POLICY, 0), - "TS_RESP_CTX_add_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_NEW, 0), "TS_RESP_CTX_new"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_ACCURACY, 0), - "TS_RESP_CTX_set_accuracy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_CERTS, 0), - "TS_RESP_CTX_set_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_DEF_POLICY, 0), - "TS_RESP_CTX_set_def_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 0), - "TS_RESP_CTX_set_signer_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_STATUS_INFO, 0), - "TS_RESP_CTX_set_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_GET_POLICY, 0), "ts_RESP_get_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, 0), - "TS_RESP_set_genTime_with_precision"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_STATUS_INFO, 0), - "TS_RESP_set_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_TST_INFO, 0), - "TS_RESP_set_tst_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SIGN, 0), "ts_RESP_sign"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_VERIFY_SIGNATURE, 0), - "TS_RESP_verify_signature"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_ACCURACY, 0), - "TS_TST_INFO_set_accuracy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_MSG_IMPRINT, 0), - "TS_TST_INFO_set_msg_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_NONCE, 0), - "TS_TST_INFO_set_nonce"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_POLICY_ID, 0), - "TS_TST_INFO_set_policy_id"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_SERIAL, 0), - "TS_TST_INFO_set_serial"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_TIME, 0), - "TS_TST_INFO_set_time"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_TSA, 0), "TS_TST_INFO_set_tsa"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY, 0), ""}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY_CERT, 0), "ts_verify_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY_CTX_NEW, 0), "TS_VERIFY_CTX_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA TS_str_reasons[] = { {ERR_PACK(ERR_LIB_TS, 0, TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, {ERR_PACK(ERR_LIB_TS, 0, TS_R_BAD_TYPE), "bad type"}, @@ -163,10 +78,8 @@ static const ERR_STRING_DATA TS_str_reasons[] = { int ERR_load_TS_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { - ERR_load_strings_const(TS_str_functs); + if (ERR_reason_error_string(TS_str_reasons[0].error) == NULL) ERR_load_strings_const(TS_str_reasons); - } #endif return 1; } diff --git a/crypto/ui/ui_err.c b/crypto/ui/ui_err.c index 431987dc..2b564f71 100644 --- a/crypto/ui/ui_err.c +++ b/crypto/ui/ui_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,36 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA UI_str_functs[] = { - {ERR_PACK(ERR_LIB_UI, UI_F_CLOSE_CONSOLE, 0), "close_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_ECHO_CONSOLE, 0), "echo_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_GENERAL_ALLOCATE_BOOLEAN, 0), - "general_allocate_boolean"}, - {ERR_PACK(ERR_LIB_UI, UI_F_GENERAL_ALLOCATE_PROMPT, 0), - "general_allocate_prompt"}, - {ERR_PACK(ERR_LIB_UI, UI_F_NOECHO_CONSOLE, 0), "noecho_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_OPEN_CONSOLE, 0), "open_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CONSTRUCT_PROMPT, 0), "UI_construct_prompt"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CREATE_METHOD, 0), "UI_create_method"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CTRL, 0), "UI_ctrl"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_ERROR_STRING, 0), "UI_dup_error_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INFO_STRING, 0), "UI_dup_info_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INPUT_BOOLEAN, 0), - "UI_dup_input_boolean"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INPUT_STRING, 0), "UI_dup_input_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_USER_DATA, 0), "UI_dup_user_data"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_VERIFY_STRING, 0), - "UI_dup_verify_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_GET0_RESULT, 0), "UI_get0_result"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_GET_RESULT_LENGTH, 0), - "UI_get_result_length"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_NEW_METHOD, 0), "UI_new_method"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_PROCESS, 0), "UI_process"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_SET_RESULT, 0), "UI_set_result"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_SET_RESULT_EX, 0), "UI_set_result_ex"}, - {0, NULL} -}; - static const ERR_STRING_DATA UI_str_reasons[] = { {ERR_PACK(ERR_LIB_UI, 0, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), "common ok and cancel characters"}, @@ -69,10 +39,8 @@ static const ERR_STRING_DATA UI_str_reasons[] = { int ERR_load_UI_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { - ERR_load_strings_const(UI_str_functs); + if (ERR_reason_error_string(UI_str_reasons[0].error) == NULL) ERR_load_strings_const(UI_str_reasons); - } #endif return 1; } diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c index 8c3502e8..d0393511 100644 --- a/crypto/ui/ui_lib.c +++ b/crypto/ui/ui_lib.c @@ -874,13 +874,6 @@ int UI_get_result_maxsize(UI_STRING *uis) int UI_set_result(UI *ui, UI_STRING *uis, const char *result) { -#if 0 - /* - * This is placed here solely to preserve UI_F_UI_SET_RESULT - * To be removed for OpenSSL 1.2.0 - */ - UIerr(UI_F_UI_SET_RESULT, ERR_R_DISABLED); -#endif return UI_set_result_ex(ui, uis, result, strlen(result)); } diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c index 4c1ec554..52c675a1 100644 --- a/crypto/ui/ui_openssl.c +++ b/crypto/ui/ui_openssl.c @@ -88,8 +88,8 @@ * We know that VMS, MSDOS, VXWORKS, use entirely other mechanisms. */ # elif !defined(OPENSSL_SYS_VMS) \ - && !defined(OPENSSL_SYS_MSDOS) \ - && !defined(OPENSSL_SYS_VXWORKS) + && !defined(OPENSSL_SYS_MSDOS) \ + && !defined(OPENSSL_SYS_VXWORKS) # define TERMIOS # undef TERMIO # undef SGTTY diff --git a/crypto/whrlpool/asm/wp-mmx.pl b/crypto/whrlpool/asm/wp-mmx.pl index a0ab3a0a..39cd2204 100644 --- a/crypto/whrlpool/asm/wp-mmx.pl +++ b/crypto/whrlpool/asm/wp-mmx.pl @@ -56,8 +56,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/whrlpool/asm/wp-x86_64.pl b/crypto/whrlpool/asm/wp-x86_64.pl index 03e90207..e5b51501 100644 --- a/crypto/whrlpool/asm/wp-x86_64.pl +++ b/crypto/whrlpool/asm/wp-x86_64.pl @@ -37,9 +37,10 @@ # 3 on Opteron] and which is *unacceptably* slow with 64-bit # operand. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -48,7 +49,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub L() { $code.=".byte ".join(',',@_)."\n"; } diff --git a/crypto/whrlpool/build.info b/crypto/whrlpool/build.info index f67bf41b..3276bd12 100644 --- a/crypto/whrlpool/build.info +++ b/crypto/whrlpool/build.info @@ -20,8 +20,7 @@ ENDIF SOURCE[../../libcrypto]=wp_dgst.c $WPASM DEFINE[../../libcrypto]=$WPDEF -GENERATE[wp-mmx.s]=asm/wp-mmx.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[wp-mmx.s]=asm/wp-mmx.pl DEPEND[wp-mmx.s]=../perlasm/x86asm.pl -GENERATE[wp-x86_64.s]=asm/wp-x86_64.pl $(PERLASM_SCHEME) +GENERATE[wp-x86_64.s]=asm/wp-x86_64.pl \ No newline at end of file diff --git a/crypto/whrlpool/wp_block.c b/crypto/whrlpool/wp_block.c index 14327f16..c2c0b726 100644 --- a/crypto/whrlpool/wp_block.c +++ b/crypto/whrlpool/wp_block.c @@ -36,6 +36,7 @@ * */ +#include "internal/cryptlib.h" #include "wp_locl.h" #include @@ -75,7 +76,6 @@ typedef unsigned long long u64; # define OPENSSL_SMALL_FOOTPRINT # endif # define GO_FOR_MMX(ctx,inp,num) do { \ - extern unsigned long OPENSSL_ia32cap_P[]; \ void whirlpool_block_mmx(void *,const void *,size_t); \ if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ whirlpool_block_mmx(ctx->H.c,inp,num); return; \ @@ -87,6 +87,7 @@ typedef unsigned long long u64; #ifndef PEDANTIC # if defined(_MSC_VER) # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# include # pragma intrinsic(_rotl64) # define ROTATE(a,n) _rotl64((a),n) # endif diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 36c6b089..e53b9b44 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -327,10 +327,10 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, /* * we have added it to the cache so now pull it out again */ - CRYPTO_THREAD_write_lock(ctx->lock); + X509_STORE_lock(xl->store_ctx); j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); - CRYPTO_THREAD_unlock(ctx->lock); + X509_STORE_unlock(xl->store_ctx); /* If a CRL, update the last file suffix added for this */ diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c index 0c5887c2..5d4c6bd8 100644 --- a/crypto/x509/pcy_tree.c +++ b/crypto/x509/pcy_tree.c @@ -49,7 +49,7 @@ static void tree_print(BIO *channel, curr++; BIO_printf(channel, "Level print after %s\n", str); - BIO_printf(channel, "Printing Up to Level %ld\n", + BIO_printf(channel, "Printing Up to Level %zd\n", curr - tree->levels); for (plev = tree->levels; plev != curr; plev++) { int i; diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index 1d41380c..22876750 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -256,6 +256,7 @@ static int extract_min_max(ASIdOrRange *aor, static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) { ASN1_INTEGER *a_max_plus_one = NULL; + ASN1_INTEGER *orig; BIGNUM *bn = NULL; int i, ret = 0; @@ -298,9 +299,15 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) */ if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = - BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + !BN_add_word(bn, 1)) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, + ERR_R_MALLOC_FAILURE); + goto done; + } + + if ((a_max_plus_one = + BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { + a_max_plus_one = orig; X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, ERR_R_MALLOC_FAILURE); goto done; @@ -351,6 +358,7 @@ int X509v3_asid_is_canonical(ASIdentifiers *asid) static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) { ASN1_INTEGER *a_max_plus_one = NULL; + ASN1_INTEGER *orig; BIGNUM *bn = NULL; int i, ret = 0; @@ -416,9 +424,15 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) */ if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = - BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + !BN_add_word(bn, 1)) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + + if ((a_max_plus_one = + BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { + a_max_plus_one = orig; X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE); goto done; diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index d0ac7e6e..40f976bd 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -890,6 +890,20 @@ const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x) return (x->akid != NULL ? x->akid->keyid : NULL); } +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + X509_check_purpose(x, -1, -1); + return (x->akid != NULL ? x->akid->issuer : NULL); +} + +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x) +{ + /* Call for side-effect of computing hash and caching extensions */ + X509_check_purpose(x, -1, -1); + return (x->akid != NULL ? x->akid->serial : NULL); +} + long X509_get_pathlen(X509 *x) { /* Called for side effect of caching extensions */ diff --git a/crypto/x509/v3err.c b/crypto/x509/v3err.c index 421d9366..cbda3f2c 100644 --- a/crypto/x509/v3err.c +++ b/crypto/x509/v3err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * 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 @@ -13,120 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA X509V3_str_functs[] = { - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_A2I_GENERAL_NAME, 0), - "a2i_GENERAL_NAME"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ADDR_VALIDATE_PATH_INTERNAL, 0), - "addr_validate_path_internal"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 0), - "ASIdentifierChoice_canonize"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, 0), - "ASIdentifierChoice_is_canonical"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_BIGNUM_TO_STRING, 0), - "bignum_to_string"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_COPY_EMAIL, 0), "copy_email"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_COPY_ISSUER, 0), "copy_issuer"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_DIRNAME, 0), "do_dirname"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_EXT_I2D, 0), "do_ext_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_EXT_NCONF, 0), "do_ext_nconf"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_GNAMES_FROM_SECTNAME, 0), - "gnames_from_sectname"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_ENUMERATED, 0), - "i2s_ASN1_ENUMERATED"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_IA5STRING, 0), - "i2s_ASN1_IA5STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_INTEGER, 0), - "i2s_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_INFO_ACCESS, 0), - "i2v_AUTHORITY_INFO_ACCESS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_LEVEL_ADD_NODE, 0), "level_add_node"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_NOTICE_SECTION, 0), "notice_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_NREF_NOS, 0), "nref_nos"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_CACHE_CREATE, 0), - "policy_cache_create"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_CACHE_NEW, 0), - "policy_cache_new"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_DATA_NEW, 0), "policy_data_new"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_SECTION, 0), "policy_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_PROCESS_PCI_VALUE, 0), - "process_pci_value"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_R2I_CERTPOL, 0), "r2i_certpol"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_R2I_PCI, 0), "r2i_pci"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_IA5STRING, 0), - "s2i_ASN1_IA5STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_INTEGER, 0), - "s2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_OCTET_STRING, 0), - "s2i_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_SKEY_ID, 0), "s2i_skey_id"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SET_DIST_POINT_NAME, 0), - "set_dist_point_name"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_ASC, 0), - "SXNET_add_id_asc"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_INTEGER, 0), - "SXNET_add_id_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_ULONG, 0), - "SXNET_add_id_ulong"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_GET_ID_ASC, 0), - "SXNET_get_id_asc"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_GET_ID_ULONG, 0), - "SXNET_get_id_ulong"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_TREE_INIT, 0), "tree_init"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ASIDENTIFIERS, 0), - "v2i_ASIdentifiers"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ASN1_BIT_STRING, 0), - "v2i_ASN1_BIT_STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_AUTHORITY_INFO_ACCESS, 0), - "v2i_AUTHORITY_INFO_ACCESS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_AUTHORITY_KEYID, 0), - "v2i_AUTHORITY_KEYID"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_BASIC_CONSTRAINTS, 0), - "v2i_BASIC_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_CRLD, 0), "v2i_crld"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_EXTENDED_KEY_USAGE, 0), - "v2i_EXTENDED_KEY_USAGE"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_GENERAL_NAMES, 0), - "v2i_GENERAL_NAMES"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_GENERAL_NAME_EX, 0), - "v2i_GENERAL_NAME_ex"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_IDP, 0), "v2i_idp"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_IPADDRBLOCKS, 0), - "v2i_IPAddrBlocks"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ISSUER_ALT, 0), "v2i_issuer_alt"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_NAME_CONSTRAINTS, 0), - "v2i_NAME_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_POLICY_CONSTRAINTS, 0), - "v2i_POLICY_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_POLICY_MAPPINGS, 0), - "v2i_POLICY_MAPPINGS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_SUBJECT_ALT, 0), "v2i_subject_alt"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_TLS_FEATURE, 0), "v2i_TLS_FEATURE"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V3_GENERIC_EXTENSION, 0), - "v3_generic_extension"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_ADD1_I2D, 0), "X509V3_add1_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_ADD_VALUE, 0), - "X509V3_add_value"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_ADD, 0), "X509V3_EXT_add"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_ADD_ALIAS, 0), - "X509V3_EXT_add_alias"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_I2D, 0), "X509V3_EXT_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_NCONF, 0), - "X509V3_EXT_nconf"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_SECTION, 0), - "X509V3_get_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_STRING, 0), - "X509V3_get_string"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_VALUE_BOOL, 0), - "X509V3_get_value_bool"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_PARSE_LIST, 0), - "X509V3_parse_list"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509_PURPOSE_ADD, 0), - "X509_PURPOSE_add"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509_PURPOSE_SET, 0), - "X509_PURPOSE_set"}, - {0, NULL} -}; - static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OBJECT), "bad object"}, @@ -248,10 +134,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { int ERR_load_X509V3_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { - ERR_load_strings_const(X509V3_str_functs); + if (ERR_reason_error_string(X509V3_str_reasons[0].error) == NULL) ERR_load_strings_const(X509V3_str_reasons); - } #endif return 1; } diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 284ca545..d7bbbc19 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -450,9 +450,17 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) STACK_OF(X509) *ret; int i; ret = sk_X509_dup(chain); + if (ret == NULL) + return NULL; for (i = 0; i < sk_X509_num(ret); i++) { X509 *x = sk_X509_value(ret, i); - X509_up_ref(x); + if (!X509_up_ref(x)) + goto err; } return ret; + err: + while (i-- > 0) + X509_free (sk_X509_value(ret, i)); + sk_X509_free(ret); + return NULL; } diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index 1d0c518b..1b01fd01 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -13,109 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA X509_str_functs[] = { - {ERR_PACK(ERR_LIB_X509, X509_F_ADD_CERT_DIR, 0), "add_cert_dir"}, - {ERR_PACK(ERR_LIB_X509, X509_F_BUILD_CHAIN, 0), "build_chain"}, - {ERR_PACK(ERR_LIB_X509, X509_F_BY_FILE_CTRL, 0), "by_file_ctrl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0), - "check_name_constraints"}, - {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"}, - {ERR_PACK(ERR_LIB_X509, X509_F_COMMON_VERIFY_SM2, 0), "common_verify_sm2"}, - {ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"}, - {ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0), - "get_cert_by_subject"}, - {ERR_PACK(ERR_LIB_X509, X509_F_I2D_X509_AUX, 0), "i2d_X509_AUX"}, - {ERR_PACK(ERR_LIB_X509, X509_F_LOOKUP_CERTS_SK, 0), "lookup_certs_sk"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_DECODE, 0), - "NETSCAPE_SPKI_b64_decode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_ENCODE, 0), - "NETSCAPE_SPKI_b64_encode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NEW_DIR, 0), "new_dir"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509AT_ADD1_ATTR, 0), "X509at_add1_attr"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509V3_ADD_EXT, 0), "X509v3_add_ext"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_NID, 0), - "X509_ATTRIBUTE_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, 0), - "X509_ATTRIBUTE_create_by_OBJ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, 0), - "X509_ATTRIBUTE_create_by_txt"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_GET0_DATA, 0), - "X509_ATTRIBUTE_get0_data"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_SET1_DATA, 0), - "X509_ATTRIBUTE_set1_data"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CHECK_PRIVATE_KEY, 0), - "X509_check_private_key"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_DIFF, 0), "X509_CRL_diff"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_METHOD_NEW, 0), - "X509_CRL_METHOD_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_PRINT_FP, 0), "X509_CRL_print_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_NID, 0), - "X509_EXTENSION_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_OBJ, 0), - "X509_EXTENSION_create_by_OBJ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_GET_PUBKEY_PARAMETERS, 0), - "X509_get_pubkey_parameters"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_CRL_FILE, 0), - "X509_load_cert_crl_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_FILE, 0), - "X509_load_cert_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CRL_FILE, 0), - "X509_load_crl_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_METH_NEW, 0), - "X509_LOOKUP_meth_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_NEW, 0), "X509_LOOKUP_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ADD_ENTRY, 0), - "X509_NAME_add_entry"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_CANON, 0), "x509_name_canon"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_NID, 0), - "X509_NAME_ENTRY_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, 0), - "X509_NAME_ENTRY_create_by_txt"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_SET_OBJECT, 0), - "X509_NAME_ENTRY_set_object"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ONELINE, 0), "X509_NAME_oneline"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_PRINT, 0), "X509_NAME_print"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_OBJECT_NEW, 0), "X509_OBJECT_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PRINT_EX_FP, 0), "X509_print_ex_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_DECODE, 0), - "x509_pubkey_decode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_GET0, 0), "X509_PUBKEY_get0"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_SET, 0), "X509_PUBKEY_set"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_CHECK_PRIVATE_KEY, 0), - "X509_REQ_check_private_key"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY, 0), "X509_REQ_verify"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_VERIFY_SM2, 0), - "x509_req_verify_sm2"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0), - "X509_STORE_add_cert"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0), - "X509_STORE_add_crl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_LOOKUP, 0), - "X509_STORE_add_lookup"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_GET1_ISSUER, 0), - "X509_STORE_CTX_get1_issuer"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_INIT, 0), - "X509_STORE_CTX_init"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_NEW, 0), - "X509_STORE_CTX_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 0), - "X509_STORE_CTX_purpose_inherit"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_NEW, 0), "X509_STORE_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TO_X509_REQ, 0), "X509_to_X509_REQ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_ADD, 0), "X509_TRUST_add"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_SET, 0), "X509_TRUST_set"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY, 0), "X509_verify"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, 0), "X509_verify_cert"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_PARAM_NEW, 0), - "X509_VERIFY_PARAM_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_SM2, 0), "x509_verify_sm2"}, - {0, NULL} -}; - static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_AKID_MISMATCH), "akid mismatch"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_SELECTOR), "bad selector"}, @@ -180,10 +77,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = { int ERR_load_X509_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { - ERR_load_strings_const(X509_str_functs); + if (ERR_reason_error_string(X509_str_reasons[0].error) == NULL) ERR_load_strings_const(X509_str_reasons); - } #endif return 1; } diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index e994633f..c81a00e0 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -289,24 +289,25 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, X509_NAME *name, X509_OBJECT *ret) { - X509_STORE *ctx = vs->ctx; + X509_STORE *store = vs->store; X509_LOOKUP *lu; X509_OBJECT stmp, *tmp; int i, j; - if (ctx == NULL) + if (store == NULL) return 0; stmp.type = X509_LU_NONE; stmp.data.ptr = NULL; - CRYPTO_THREAD_write_lock(ctx->lock); - tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); - CRYPTO_THREAD_unlock(ctx->lock); + + X509_STORE_lock(store); + tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name); + X509_STORE_unlock(store); if (tmp == NULL || type == X509_LU_CRL) { - for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { - lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); j = X509_LOOKUP_by_subject(lu, type, name, &stmp); if (j) { tmp = &stmp; @@ -317,15 +318,16 @@ int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, return 0; } + if (!X509_OBJECT_up_ref_count(tmp)) + return 0; + ret->type = tmp->type; ret->data.ptr = tmp->data.ptr; - X509_OBJECT_up_ref_count(ret); - return 1; } -static int x509_store_add(X509_STORE *ctx, void *x, int crl) { +static int x509_store_add(X509_STORE *store, void *x, int crl) { X509_OBJECT *obj; int ret = 0, added = 0; @@ -342,18 +344,20 @@ static int x509_store_add(X509_STORE *ctx, void *x, int crl) { obj->type = X509_LU_X509; obj->data.x509 = (X509 *)x; } - X509_OBJECT_up_ref_count(obj); - - CRYPTO_THREAD_write_lock(ctx->lock); - - if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { - ret = 1; - } else { - added = sk_X509_OBJECT_push(ctx->objs, obj); - ret = added != 0; + if (!X509_OBJECT_up_ref_count(obj)) { + obj->type = X509_LU_NONE; + X509_OBJECT_free(obj); + return 0; } - CRYPTO_THREAD_unlock(ctx->lock); + X509_STORE_lock(store); + if (X509_OBJECT_retrieve_match(store->objs, obj)) { + ret = 1; + } else { + added = sk_X509_OBJECT_push(store->objs, obj); + ret = added != 0; + } + X509_STORE_unlock(store); if (added == 0) /* obj not pushed */ X509_OBJECT_free(obj); @@ -534,12 +538,13 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) STACK_OF(X509) *sk = NULL; X509 *x; X509_OBJECT *obj; + X509_STORE *store = ctx->store; - if (ctx->ctx == NULL) + if (store == NULL) return NULL; - CRYPTO_THREAD_write_lock(ctx->ctx->lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + X509_STORE_lock(store); + idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { /* * Nothing found in cache: do lookup to possibly add new objects to @@ -547,7 +552,8 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) */ X509_OBJECT *xobj = X509_OBJECT_new(); - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); + if (xobj == NULL) return NULL; if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) { @@ -555,27 +561,31 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) return NULL; } X509_OBJECT_free(xobj); - CRYPTO_THREAD_write_lock(ctx->ctx->lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + X509_STORE_lock(store); + idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); return NULL; } } sk = sk_X509_new_null(); for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + obj = sk_X509_OBJECT_value(store->objs, idx); x = obj->data.x509; - X509_up_ref(x); + if (!X509_up_ref(x)) { + X509_STORE_unlock(store); + sk_X509_pop_free(sk, X509_free); + return NULL; + } if (!sk_X509_push(sk, x)) { - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); X509_free(x); sk_X509_pop_free(sk, X509_free); return NULL; } } - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); return sk; } @@ -585,37 +595,42 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null(); X509_CRL *x; X509_OBJECT *obj, *xobj = X509_OBJECT_new(); + X509_STORE *store = ctx->store; /* Always do lookup to possibly add new CRLs to cache */ if (sk == NULL || xobj == NULL - || ctx->ctx == NULL + || store == NULL || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) { X509_OBJECT_free(xobj); sk_X509_CRL_free(sk); return NULL; } X509_OBJECT_free(xobj); - CRYPTO_THREAD_write_lock(ctx->ctx->lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + X509_STORE_lock(store); + idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt); if (idx < 0) { - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); sk_X509_CRL_free(sk); return NULL; } for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + obj = sk_X509_OBJECT_value(store->objs, idx); x = obj->data.crl; - X509_CRL_up_ref(x); + if (!X509_CRL_up_ref(x)) { + X509_STORE_unlock(store); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } if (!sk_X509_CRL_push(sk, x)) { - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); X509_CRL_free(x); sk_X509_CRL_pop_free(sk, X509_CRL_free); return NULL; } } - CRYPTO_THREAD_unlock(ctx->ctx->lock); + X509_STORE_unlock(store); return sk; } @@ -663,6 +678,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { X509_NAME *xn; X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL; + X509_STORE *store = ctx->store; int i, ok, idx, ret; if (obj == NULL) @@ -678,25 +694,28 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) if (ctx->check_issued(ctx, x, obj->data.x509)) { if (x509_check_cert_time(ctx, obj->data.x509, -1)) { *issuer = obj->data.x509; - X509_up_ref(*issuer); + if (!X509_up_ref(*issuer)) { + *issuer = NULL; + ok = -1; + } X509_OBJECT_free(obj); - return 1; + return ok; } } X509_OBJECT_free(obj); - if (ctx->ctx == NULL) + if (store == NULL) return 0; /* Else find index of first cert accepted by 'check_issued' */ ret = 0; - CRYPTO_THREAD_write_lock(ctx->ctx->lock); - idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + X509_STORE_lock(store); + idx = X509_OBJECT_idx_by_subject(store->objs, X509_LU_X509, xn); if (idx != -1) { /* should be true as we've had at least one * match */ /* Look through all matching certs for suitable issuer */ - for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { - pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + for (i = idx; i < sk_X509_OBJECT_num(store->objs); i++) { + pobj = sk_X509_OBJECT_value(store->objs, i); /* See if we've run past the matches */ if (pobj->type != X509_LU_X509) break; @@ -717,9 +736,11 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) } } } - CRYPTO_THREAD_unlock(ctx->ctx->lock); - if (*issuer) - X509_up_ref(*issuer); + if (*issuer && !X509_up_ref(*issuer)) { + *issuer = NULL; + ret = -1; + } + X509_STORE_unlock(store); return ret; } @@ -897,5 +918,5 @@ void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx) X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) { - return ctx->ctx; + return ctx->store; } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index bbf61d44..f337cd14 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1276,7 +1276,7 @@ static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) /* Don't allow recursive CRL path validation */ if (ctx->parent) return 0; - if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) return -1; crl_ctx.crls = ctx->crls; @@ -1788,7 +1788,11 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; ASN1_TIME *asn1_cmp_time = NULL; int i, day, sec, ret = 0; - +#ifdef CHARSET_EBCDIC + const char upper_z = 0x5A; +#else + const char upper_z = 'Z'; +#endif /* * Note that ASN.1 allows much more slack in the time format than RFC5280. * In RFC5280, the representation is fixed: @@ -1819,10 +1823,10 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) * Digit and date ranges will be verified in the conversion methods. */ for (i = 0; i < ctm->length - 1; i++) { - if (!ossl_isdigit(ctm->data[i])) + if (!ascii_isdigit(ctm->data[i])) return 0; } - if (ctm->data[ctm->length - 1] != 'Z') + if (ctm->data[ctm->length - 1] != upper_z) return 0; /* @@ -2201,7 +2205,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, { int ret = 1; - ctx->ctx = store; + ctx->store = store; ctx->cert = x509; ctx->untrusted = chain; ctx->crls = NULL; diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index eb5ea27b..d81f5384 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -56,6 +56,7 @@ ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_PUBKEY) /* TODO should better be called X509_PUBKEY_set1 */ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) diff --git a/crypto/x86_64cpuid.pl b/crypto/x86_64cpuid.pl index 6b337370..43e53d6f 100644 --- a/crypto/x86_64cpuid.pl +++ b/crypto/x86_64cpuid.pl @@ -7,9 +7,10 @@ # https://www.openssl.org/source/license.html -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -18,7 +19,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; ($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index f15d5572..bf8020d2 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -10,9 +10,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC, "${dir}perlasm", "perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod b/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod index db2ad36b..b36084dc 100644 --- a/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod +++ b/doc/internal/man3/DEFINE_SPARSE_ARRAY_OF.pod @@ -108,7 +108,7 @@ ossl_sa_TYPE_free_leaves() do not return values. =head1 HISTORY -This functionality was added to OpenSSL 3.0.0. +This functionality was added to OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/internal/man3/OSSL_METHOD_STORE.pod b/doc/internal/man3/OSSL_METHOD_STORE.pod index f95d397c..f178a0ee 100644 --- a/doc/internal/man3/OSSL_METHOD_STORE.pod +++ b/doc/internal/man3/OSSL_METHOD_STORE.pod @@ -19,9 +19,10 @@ ossl_method_store_cache_get, ossl_method_store_cache_set void ossl_method_store_free(OSSL_METHOD_STORE *store); int ossl_method_store_init(OPENSSL_CTX *ctx); void ossl_method_store_cleanup(OPENSSL_CTX *ctx); - int ossl_method_store_add(OSSL_METHOD_STORE *store, - int nid, const char *properties, - void *method, void (*method_destruct)(void *)); + int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, + int nid, const char *properties, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)); int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, const void *method); int ossl_method_store_fetch(OSSL_METHOD_STORE *store, @@ -62,15 +63,20 @@ B to allow access to the required underlying property data. ossl_method_store_free() frees resources allocated to B. -ossl_method_store_add() adds the B to the B as an instance of an -algorithm indicated by B and the property definition B. -The optional B function is called when B is being -released from B. +ossl_method_store_add() adds the B constructed from an implementation in +the provider B to the B as an instance of an algorithm indicated by +B and the property definition B, unless the B already +has a method from the same provider with the same B and B. +If the B function is given, it's called to increment the +reference count of the method. +If the B function is given, it's called when this function +fails to add the method to the store, or later on when it is being released from +the B. ossl_method_store_remove() removes the B identified by B from the B. -ossl_method_store_fetch() queries B for an method identified by B +ossl_method_store_fetch() queries B for a method identified by B that matches the property query B. The result, if any, is returned in B. @@ -82,28 +88,28 @@ and the ones passed to the ossl_method_store_free(). =head2 Cache Functions ossl_method_store_cache_get() queries the cache associated with the B -for an method identified by B that matches the property query +for a method identified by B that matches the property query B. The result, if any, is returned in B. ossl_method_store_cache_set() sets a cache entry identified by B with the property query B in the B. -Future cache gets will return the specified B. +Future calls to ossl_method_store_cache_get() will return the specified B. =head1 RETURN VALUES -ossl_method_store_new() a new method store object or B on failure. +ossl_method_store_new() returns a new method store object or B on failure. ossl_method_store_free(), ossl_method_store_add(), ossl_method_store_remove(), ossl_method_store_fetch(), ossl_method_store_set_global_properties(), ossl_method_store_cache_get() and ossl_method_store_cache_set() return B<1> on success and B<0> on error. -ossl_method_store_free() and ossl_method_store_cleanup() do not return values. +ossl_method_store_free() and ossl_method_store_cleanup() do not return any value. =head1 HISTORY -This functionality was added to OpenSSL 3.0.0. +This functionality was added to OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/CMS_add1_signing_cert.pod b/doc/internal/man3/cms_add1_signing_cert.pod similarity index 69% rename from doc/man3/CMS_add1_signing_cert.pod rename to doc/internal/man3/cms_add1_signing_cert.pod index 035e679d..a825c071 100644 --- a/doc/man3/CMS_add1_signing_cert.pod +++ b/doc/internal/man3/cms_add1_signing_cert.pod @@ -2,7 +2,7 @@ =head1 NAME -CMS_add1_signing_cert, CMS_add1_signing_cert_v2 +cms_add1_signing_cert, cms_add1_signing_cert_v2 - add ESS signing-certificate signed attribute to a CMS_SignerInfo data structure @@ -10,15 +10,15 @@ CMS_SignerInfo data structure #include - int CMS_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc); + int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc); - int CMS_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc2); + int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc2); =head1 DESCRIPTION -CMS_add1_signing_cert() adds an ESS Signing Certificate B (version 1) signed +cms_add1_signing_cert() adds an ESS Signing Certificate B (version 1) signed attribute to the CMS_SignerInfo B. -CMS_add1_signing_cert_v2() adds an ESS Signing Certificate B (version 2) signed +cms_add1_signing_cert_v2() adds an ESS Signing Certificate B (version 2) signed attribute to the CMS_SignerInfo B. The ESS Signing Certificate attributes version 1 and 2 are defined in RFC 5035 which updates Section 5.4 of RFC 2634. @@ -31,7 +31,8 @@ For a fuller description see L). =head1 RETURN VALUES -CMS_add1_signing_cert() and CMS_add1_signing_cert_v2() return 1 if attribute is added or 0 if an error occurred. +cms_add1_signing_cert() and cms_add1_signing_cert_v2() return 1 if attribute +is added or 0 if an error occurred. =head1 COPYRIGHT diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod index 0688ac01..6fe7bccb 100644 --- a/doc/internal/man3/evp_generic_fetch.pod +++ b/doc/internal/man3/evp_generic_fetch.pod @@ -2,7 +2,8 @@ =head1 NAME -evp_generic_fetch - generic algorithm fetcher and method creator for EVP +evp_generic_fetch, evp_generic_fetch_by_number +- generic algorithm fetchers and method creators for EVP =head1 SYNOPSIS @@ -11,26 +12,50 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, const char *name, const char *properties, - void *(*new_method)(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov), + 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 *)); + 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, + int (*up_ref_method)(void *), + void (*free_method)(void *)); + =head1 DESCRIPTION evp_generic_fetch() calls ossl_method_construct() with the given -C, C, C, and C and uses +I, I, I, and I and uses it to create an EVP method with the help of the functions -C, C, and C. +I, I, and I. -The three functions are supposed to: +evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(), +but takes a I instead of a number. +I must always be non-zero; as a matter of fact, it being zero +is considered a programming error. +This is meant to be used when one method needs to fetch an associated +other method, and is typically called from inside the given function +I. + +The three functions I, I, and +I are supposed to: =over 4 =item new_method() creates an internal method from function pointers found in the -dispatch table C. +dispatch table I, with name identity I. +The provider I and I are also passed to be used as +new_method() sees fit. =item up_ref_method() @@ -50,10 +75,10 @@ evp_generic_fetch() returns a method on success, or B on error. =head1 EXAMPLES This is a short example of the fictitious EVP API and operation called -C. +B. To begin with, let's assume something like this in -C: +F: #define OSSL_OP_FOO 100 @@ -75,6 +100,7 @@ And here's the implementation of the FOO method fetcher: /* typedef struct evp_foo_st EVP_FOO */ struct evp_foo_st { OSSL_PROVIDER *prov; + int name_id; CRYPTO_REF_COUNT refcnt; OSSL_OP_foo_newctx_fn *newctx; OSSL_OP_foo_init_fn *init; @@ -87,14 +113,18 @@ And here's the implementation of the FOO method fetcher: * In this example, we have a public method creator and destructor. * It's not absolutely necessary, but is in the spirit of OpenSSL. */ - EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns, - OSSL_PROVIDER *prov) + EVP_FOO *EVP_FOO_meth_from_dispatch(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *data) { EVP_FOO *foo = NULL; if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL) return NULL; + foo->name_id = name_id; + for (; fns->function_id != 0; fns++) { switch (fns->function_id) { case OSSL_OP_FOO_NEWCTX_FUNC: diff --git a/doc/internal/man3/evp_keymgmt_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_export_to_provider.pod new file mode 100644 index 00000000..72b766fb --- /dev/null +++ b/doc/internal/man3/evp_keymgmt_export_to_provider.pod @@ -0,0 +1,56 @@ +=pod + +=head1 NAME + +evp_keymgmt_export_to_provider, +evp_keymgmt_clear_pkey_cache +- key material provider export for EVP + +=head1 SYNOPSIS + + #include "internal/evp_int.h" + + void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); + void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk); + +=head1 DESCRIPTION + +evp_keymgmt_export_to_provider() exports the key material from the +given key I to a provider via a B interface, if this +hasn't already been done. +It maintains a cache of provider key references in I to keep track +of all such exports. + +If I has an assigned legacy key, a check is done to see if any of +its key material has changed since last export, i.e. the legacy key's +is_dirty() method returns 1. +If it has, the cache of already exported keys is cleared, and a new +export is made with the new key material. + +evp_keymgmt_clear_pkey_cache() can be used to explicitly clear the +cache of provider key references. + +=head1 RETURN VALUES + +evp_keymgmt_export_to_provider() returns a pointer to the appropriate +provider side key (created or found again), or NULL on error. + +=head1 NOTES + +"Legacy key" is the term used for any key that has been assigned to an +B with EVP_PKEY_assign_RSA() and similar functions. + +=head1 SEE ALSO + +L, 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/man3/evp_keymgmt_freekey.pod b/doc/internal/man3/evp_keymgmt_freekey.pod new file mode 100644 index 00000000..597c34b6 --- /dev/null +++ b/doc/internal/man3/evp_keymgmt_freekey.pod @@ -0,0 +1,109 @@ +=pod + +=head1 NAME + +evp_keymgmt_importdomparams, evp_keymgmt_gendomparams, +evp_keymgmt_freedomparams, +evp_keymgmt_exportdomparams, +evp_keymgmt_importdomparams_types, evp_keymgmt_exportdomparams_types, +evp_keymgmt_importkey, evp_keymgmt_genkey, evp_keymgmt_loadkey, +evp_keymgmt_freekey, +evp_keymgmt_exportkey, +evp_keymgmt_importkey_types, evp_keymgmt_exportkey_types +- internal KEYMGMT support functions + +=head1 SYNOPSIS + + #include "internal/evp_int.h" + + void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); + void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); + void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, void *provdomparams); + int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt, + void *provdomparams, OSSL_PARAM params[]); + const OSSL_PARAM *evp_keymgmt_importdomparams_types(const EVP_KEYMGMT *keymgmt); + const OSSL_PARAM *evp_keymgmt_exportdomparams_types(const EVP_KEYMGMT *keymgmt); + + void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt, + const OSSL_PARAM params[]); + void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams, + const OSSL_PARAM params[]); + void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt, + void *id, size_t idlen); + void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey); + int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey, + OSSL_PARAM params[]); + const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt); + const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt); + +=head1 DESCRIPTION + +All these functions are helpers to call the provider's corresponding +function. + +evp_keymgmt_importdomparams() calls the method's importdomparams() function. + +evp_keymgmt_gendomparams() calls the method's gendomparams() function. + +evp_keymgmt_freedomparams() calls the method's freedomparams() function. + +evp_keymgmt_exportdomparams() calls the method's exportdomparams() +function. + +evp_keymgmt_importdomparams_types() calls the method's +importdomparams_types() function. + +evp_keymgmt_exportdomparams_types() calls the method's +exportdomparams_types() function. + +evp_keymgmt_importkey() calls the method's importkey() +function. + +evp_keymgmt_genkey() calls the method's genkey() function. + +evp_keymgmt_loadkey() calls the method's loadkey() function. + +evp_keymgmt_freekey() calls the method's freekey() function. + +evp_keymgmt_exportkey() calls the method's exportkey() +function. + +evp_keymgmt_importkey_types() calls the method's importkey_types() function. + +evp_keymgmt_exportkey_types() calls the method's exportkey_types() function. + +=head1 RETURN VALUES + +evp_keymgmt_importdomparams(), evp_keymgmt_gendomparams() return a pointer +to a provider owned set of domparams parameters, or NULL on error. + +evp_keymgmt_importkey(), evp_keymgmt_genkey(), evp_keymgmt_loadkey() return +a pointer to a provider owned key, or NULL on error. + +evp_keymgmt_exportdomparams() and evp_keymgmt_exportkey() return 1 on success, +or 0 on error. + +evp_keymgmt_importdomparams_types(), evp_keymgmt_exportdomparams_types() +return parameter descriptor for importing and exporting domparams +parameters, or NULL if there are no such descriptors. + +evp_keymgmt_importkey_types() and evp_keymgmt_exportkey_types() +return parameter descriptor for importing and exporting keys, or NULL +if there are no such descriptors. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=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/man3/ossl_algorithm_do_all.pod b/doc/internal/man3/ossl_algorithm_do_all.pod new file mode 100644 index 00000000..6ef85a72 --- /dev/null +++ b/doc/internal/man3/ossl_algorithm_do_all.pod @@ -0,0 +1,63 @@ +=pod + +=head1 NAME + +ossl_algorithm_do_all - generic algorithm implementation iterator + +=head1 SYNOPSIS + + void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, + OSSL_PROVIDER *provider, + void (*fn)(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *data), + void *data) + +=head1 DESCRIPTION + +ossl_algorithm_do_all() looks up every algorithm it can find, given a +library context I, an operation identity I and a +provider I. +I may be NULL to signify that the default library context should +be used. +I may be zero to signify that all kinds of operations +will be looked up. +I may be NULL to signify that all loaded providers will be +queried. + +For each implementation found, the function I is called with the +I for the implementation, the algorithm descriptor I, +the flag I indicating whether the algorithm descriptor may +be remembered or not, and the caller I that was passed to +ossl_algorithm_do_all(). + +=head1 RETURN VALUES + +ossl_algorithm_do_all() doesn't return any value. + +=head1 NOTES + +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. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=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/man3/ossl_method_construct.pod b/doc/internal/man3/ossl_method_construct.pod index 9beb7942..a25ca4cd 100644 --- a/doc/internal/man3/ossl_method_construct.pod +++ b/doc/internal/man3/ossl_method_construct.pod @@ -15,13 +15,11 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct /* Remove a store */ void (*dealloc_tmp_store)(void *store); /* Get an already existing method from a store */ - void *(*get)(OPENSSL_CTX *libctx, void *store, - int operation_id, const char *name, const char *propquery, - void *data); + void *(*get)(OPENSSL_CTX *libctx, void *store, void *data); /* Store a method in a store */ int (*put)(OPENSSL_CTX *libctx, void *store, void *method, - int operation_id, const char *name, const char *propdef, - void *data); + const OSSL_PROVIDER *prov, int operation_id, const char *name, + const char *propdef, void *data); /* Construct a new method */ void *(*construct)(const char *name, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, void *data); @@ -31,7 +29,6 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct typedef struct ossl_method_construct_method OSSL_METHOD_CONSTRUCT_METHOD; void *ossl_method_construct(OPENSSL_CTX *ctx, int operation_id, - const char *name, const char *properties, int force_cache, OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data); @@ -58,11 +55,10 @@ It's important to keep in mind that a method is identified by three things: =head2 Functions ossl_method_construct() creates a method by asking all available -providers for a dispatch table given an I, an algorithm -I and a set of I, and then calling the appropriate -functions given by the sub-system specific method creator through -I and the data in I (which is passed by -ossl_method_construct()). +providers for a dispatch table given an I, and then +calling the appropriate functions given by the sub-system specific +method creator through I and the data in I (which is +passed by ossl_method_construct()). This function assumes that the sub-system method creator implements reference counting and acts accordingly (i.e. it will call the @@ -98,10 +94,10 @@ B is a valid value and means that a sub-system default store must be used. This default store should be stored in the library context I. -The method to be looked up should be identified with the given -I, I, the provided property query I -and data from I (which is the I that was passed to -ossl_construct_method()). +The method to be looked up should be identified with data found in I +(which is the I that was passed to ossl_construct_method()). +In other words, the ossl_method_construct() caller is entirely responsible +for ensuring the necesssary data is made available. This function is expected to increment the method's reference count. diff --git a/doc/internal/man3/ossl_param_bld_init.pod b/doc/internal/man3/ossl_param_bld_init.pod new file mode 100644 index 00000000..4acd8ebf --- /dev/null +++ b/doc/internal/man3/ossl_param_bld_init.pod @@ -0,0 +1,188 @@ +=pod + +=head1 NAME + +ossl_param_bld_init, ossl_param_bld_to_param, ossl_param_bld_to_param_ex, +ossl_param_bld_free, ossl_param_bld_push_int, ossl_param_bld_push_uint, +ossl_param_bld_push_long, ossl_param_bld_push_ulong, +ossl_param_bld_push_int32, ossl_param_bld_push_uint32, +ossl_param_bld_push_int64, ossl_param_bld_push_uint64, +ossl_param_bld_push_size_t, ossl_param_bld_push_double, +ossl_param_bld_push_BN, ossl_param_bld_push_utf8_string, +ossl_param_bld_push_utf8_ptr, ossl_param_bld_push_octet_string, +ossl_param_bld_push_octet_ptr +- functions to assist in the creation of OSSL_PARAM arrays + +=head1 SYNOPSIS + +=for comment generic + + #include "internal/params_build.h" + + #define OSSL_PARAM_BLD_MAX 10 + typedef struct { ... } OSSL_PARAM_BLD; + + void ossl_param_bld_init(OSSL_PARAM_BLD *bld); + OSSL_PARAM *ossl_param_bld_to_param(OSSL_PARAM_BLD *bld); + OSSL_PARAM *ossl_param_bld_to_param_ex(OSSL_PARAM_BLD *bld, + OSSL_PARAM *params, size_t param_n, + void *data, size_t data_n, + void *secure, size_t secure_n); + void ossl_param_bld_free(OSSL_PARAM *params); + + int ossl_param_bld_push_TYPE(OSSL_PARAM_BLD *bld, const char *key, TYPE val); + + int ossl_param_bld_push_BN(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn); + + int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, + const char *buf, size_t bsize); + int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key, + char *buf, size_t bsize); + int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, + const void *buf, size_t bsize); + int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key, + void *buf, size_t bsize); + + +=head1 DESCRIPTION + +A collection of utility functions that simplify the creation of OSSL_PARAM +arrays. The B names are as per L. + +ossl_param_bld_init() initialises the OSSL_PARAM_BLD structure so that values +can be added. +Any existing values are cleared. + +ossl_param_bld_to_param() converts a built up OSSL_PARAM_BLD structure +B into an allocated OSSL_PARAM array. +The OSSL_PARAM array and all associated storage must be freed by calling +ossl_param_bld_free() with the functions return value. + +ossl_param_bld_free() deallocates the memory allocated by +ossl_param_bld_to_param(). + +ossl_param_bld_to_param_ex() behaves like ossl_param_bld_to_param(), except that +no additional memory is allocated. +An OSSL_PARAM array of at least B elements is passed in as B. +The auxiliary storage for the parameters is a block of memory pointed to +by B of at least B bytes in size. +If required, secure memory for private BIGNUMs should be pointed to by +B of at least B bytes in size. + +ossl_param_bld_push_TYPE() are a series of functions which will create +OSSL_PARAM objects of the specified size and correct type for the B +argument. +B is stored by value and an expression or auto variable can be used. + +ossl_param_bld_push_BN() is a function that will create an OSSL_PARAM object +that holds the specified BIGNUM B. +If B is marked as being securely allocated, it's OSSL_PARAM representation +will also be securely allocated. +The B argument is stored by reference and the underlying BIGNUM object +must exist until after ossl_param_bld_to_param() has been called. + +ossl_param_bld_push_utf8_string() is a function that will create an OSSL_PARAM +object that references the UTF8 string specified by B. +If the length of the string, B, is zero then it will be calculated. +The string that B points to is stored by reference and must remain in +scope until after ossl_param_bld_to_param() has been called. + +ossl_param_bld_push_octet_string() is a function that will create an OSSL_PARAM +object that references the octet string specified by B and . +The memory that B points to is stored by reference and must remain in +scope until after ossl_param_bld_to_param() has been called. + +ossl_param_bld_push_utf8_ptr() is a function that will create an OSSL_PARAM +object that references the UTF8 string specified by B. +If the length of the string, B, is zero then it will be calculated. +The string B points to is stored by reference and must remain in +scope until the OSSL_PARAM array is freed. + +ossl_param_bld_push_octet_ptr() is a function that will create an OSSL_PARAM +object that references the octet string specified by B. +The memory B points to is stored by reference and must remain in +scope until the OSSL_PARAM array is freed. + +=head1 RETURN VALUES + +ossl_param_bld_to_param() and ossl_param_bld_to_param_ex() return the +allocated OSSL_PARAM array, or NULL on error. + +All of the ossl_param_bld_push_TYPE functions return 1 on success and 0 +on error. + +=head1 NOTES + +The constant B specifies the maximum number of parameters +that can be added. +Exceeding this will result in the push functions returning errors. + +The structure B should be considered opaque and subject to +change between versions. + +=head1 EXAMPLES + +Both examples creating an OSSL_PARAM array that contains an RSA key. +For both, the predefined key variables are: + + BIGNUM *p, *q; /* both prime */ + BIGNUM *n; /* = p * q */ + unsigned int e; /* exponent, usually 65537 */ + BIGNUM *d; /* e^-1 */ + +=head2 Example 1 + +This example shows how to create an OSSL_PARAM array that contains an RSA +private key. + + OSSL_PARAM_BLD bld; + OSSL_PARAM *params; + + ossl_param_bld_init(&bld, &secure); + if (!ossl_param_bld_push_BN(&bld, "p", p) + || !ossl_param_bld_push_BN(&bld, "q", q) + || !ossl_param_bld_push_uint(&bld, "e", e) + || !ossl_param_bld_push_BN(&bld, "n", n) + || !ossl_param_bld_push_BN(&bld, "d", d) + || (params = ossl_param_bld_to_param(&bld)) == NULL) + goto err; + /* Use params */ + ... + ossl_param_bld_free(params); + +=head2 Example 2 + +This example shows how to create an OSSL_PARAM array that contains an RSA +public key. + + OSSL_PARAM_BLD bld; + OSSL_PARAM *params; + + ossl_param_bld_init(&bld, &secure); + if (!ossl_param_bld_push_BN(&bld, "n", n) + || !ossl_param_bld_push_BN(&bld, "d", d) + || (params = ossl_param_bld_to_param(&bld)) == NULL) + goto err; + /* Use params */ + ... + ossl_param_bld_free(params); + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=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/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index cb40cb2c..7154d5f3 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -6,12 +6,13 @@ ossl_provider_find, ossl_provider_new, ossl_provider_up_ref, ossl_provider_free, ossl_provider_set_fallback, ossl_provider_set_module_path, ossl_provider_add_parameter, -ossl_provider_activate, +ossl_provider_activate, ossl_provider_available, ossl_provider_ctx, ossl_provider_forall_loaded, ossl_provider_name, ossl_provider_dso, ossl_provider_module_name, ossl_provider_module_path, -ossl_provider_teardown, ossl_provider_get_param_types, +ossl_provider_library_context, +ossl_provider_teardown, ossl_provider_gettable_params, ossl_provider_get_params, ossl_provider_query_operation - internal provider routines @@ -19,9 +20,11 @@ ossl_provider_get_params, ossl_provider_query_operation #include "internal/provider.h" - OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name); + OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, + int noconfig); OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, - ossl_provider_init_fn *init_function); + ossl_provider_init_fn *init_function + int noconfig); int ossl_provider_up_ref(OSSL_PROVIDER *prov); void ossl_provider_free(OSSL_PROVIDER *prov); @@ -33,6 +36,8 @@ ossl_provider_get_params, ossl_provider_query_operation /* Load and initialize the Provider */ int ossl_provider_activate(OSSL_PROVIDER *prov); + /* Check if provider is available */ + int ossl_provider_available(OSSL_PROVIDER *prov); /* Return pointer to the provider's context */ void *ossl_provider_ctx(const OSSL_PROVIDER *prov); @@ -48,10 +53,11 @@ ossl_provider_get_params, ossl_provider_query_operation const DSO *ossl_provider_dso(OSSL_PROVIDER *prov); const char *ossl_provider_module_name(OSSL_PROVIDER *prov); const char *ossl_provider_module_path(OSSL_PROVIDER *prov); + OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov); - const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov); + const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov); int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, @@ -79,7 +85,11 @@ times as ossl_provider_activate() has. =head2 Functions ossl_provider_find() finds an existing provider object in the provider -object store by I. +object store by I. +The config file will be automatically loaded unless I is set. +Typically I should be 0. +We set I to 1 only when calling these functions while processing a +config file in order to avoid recursively attempting to load the file. The provider object it finds has its reference count incremented. ossl_provider_new() creates a new provider object named I and @@ -87,6 +97,10 @@ stores it in the provider object store, unless there already is one there with the same name. If there already is one with the same name, it's returned with its reference count incremented. +The config file will be automatically loaded unless I is set. +Typically I should be 0. +We set I to 1 only when calling these functions while processing a +config file in order to avoid recursively attempting to load the file. The reference count of a newly created provider object will always be 2; one for being added to the store, and one for the returned reference. @@ -120,6 +134,9 @@ This will be used in preference to automatically trying to figure out the path from the provider name and the default module directory (more on this in L). +ossl_provider_library_context() returns the library context the given +provider I is registered in. + ossl_provider_add_parameter() adds a global parameter for the provider to retrieve as it sees fit. The parameters are a combination of I and I, and the @@ -148,6 +165,10 @@ be located in that module, and called. =back +ossl_provider_available() activates all fallbacks if no provider is +activated yet, then checks if given provider object I is +activated. + ossl_provider_ctx() returns a context created by the provider. Outside of the provider, it's completely opaque, but it needs to be passed back to some of the provider functions. @@ -172,9 +193,9 @@ for providers that come in the form of loadable modules. ossl_provider_teardown() calls the provider's I function, if the provider has one. -ossl_provider_get_param_types() calls the provider's I +ossl_provider_gettable_params() calls the provider's I function, if the provider has one. -It should return an array of I to describe all the +It should return an array of I to describe all the parameters that the provider has for the provider object. ossl_provider_get_params() calls the provider's parameter request @@ -228,16 +249,23 @@ ossl_provider_free() doesn't return any value. ossl_provider_set_module_path(), ossl_provider_set_fallback() and ossl_provider_activate() return 1 on success, or 0 on error. +ossl_provider_available() return 1 if the provider is available, +otherwise 0. + ossl_provider_name(), ossl_provider_dso(), ossl_provider_module_name(), and ossl_provider_module_path() return a pointer to their respective data if it's available, otherwise NULL is returned. +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_get_param_types() returns a pointer to an I -array if this function is available in the provider, otherwise -NULL. +ossl_provider_gettable_params() returns a pointer to a constant +I array if this function is available in the provider, +otherwise NULL. ossl_provider_get_params() returns 1 on success, or 0 on error. If this function isn't available in the provider, 0 is returned. diff --git a/doc/man1/CA.pl.pod b/doc/man1/CA.pl.pod index 8c8b3785..b055622b 100644 --- a/doc/man1/CA.pl.pod +++ b/doc/man1/CA.pl.pod @@ -199,7 +199,11 @@ behaviour of the certificate commands call the B command directly. =head1 SEE ALSO -L, L, L, L, +L, +L, +L, +L, +L, L =head1 COPYRIGHT diff --git a/doc/man1/fipsinstall.pod b/doc/man1/fipsinstall.pod new file mode 100644 index 00000000..7481cafb --- /dev/null +++ b/doc/man1/fipsinstall.pod @@ -0,0 +1,147 @@ +=pod + +=head1 NAME + +openssl-fipsinstall - perform FIPS configuration installation + +=head1 SYNOPSIS + +B +[B<-help>] +[B<-in configfilename>] +[B<-out configfilename>] +[B<-module modulefilename>] +[B<-provider_name providername>] +[B<-section_name sectionname>] +[B<-verify>] +[B<-mac_name macname>] +[B<-macopt>] + +B I [B<...>] + +=head1 DESCRIPTION + +This utility is used to generate a FIPS module configuration file. +The generated configuration file consists of: + +=over 4 + +=item - A mac of the FIPS module file. + +=item - A status indicator that indicates if the known answer Self Tests (KAT's) +have successfully run. + +=back + +This configuration file can be used each time a FIPS module is loaded +in order to pass data to the FIPS modules self tests. The FIPS module always +verifies the modules MAC, but only needs to run the KATS once during install. + +=head1 OPTIONS + +=over 4 + +=item B<-help> + +Print a usage message. + +=item B<-module filename> + +Filename of a fips module to perform an integrity check on. + +=item B<-out configfilename> + +Filename to output the configuration data to, or standard output by default. + +=item B<-in configfilename> + +Input filename to load configuration data from. Used with the '-verify' option. +Standard input is used if the filename is '-'. + +=item B<-verify> + +Verify that the input configuration file contains the correct information + +=item B<-provider_name providername> + +Name of the provider inside the configuration file. + +=item B<-section_name sectionname> + +Name of the section inside the configuration file. + +=item B<-mac_name name> + +Specifies the name of a supported MAC algorithm which will be used. +To see the list of supported MAC's use the command I. +The default is "HMAC". + +=item B<-macopt nm:v> + +Passes options to the MAC algorithm. +A comprehensive list of controls can be found in the EVP_MAC implementation +documentation. +Common control strings used for fipsinstall are: + +=over 4 + +=item B + +Specifies the MAC key as an alphanumeric string (use if the key contains +printable characters only). +The string length must conform to any restrictions of the MAC algorithm. +A key must be specified for every MAC algorithm. + +=item B + +Specifies the MAC key in hexadecimal form (two hex digits per byte). +The key length must conform to any restrictions of the MAC algorithm. +A key must be specified for every MAC algorithm. + +=item B + +Used by HMAC as an alphanumeric string (use if the key contains printable +characters only). +The string length must conform to any restrictions of the MAC algorithm. +To see the list of supported digests, use the command I. + +=back + +=back + +=head1 EXAMPLES + +Calculate the mac of a FIPS module 'fips.so' and run a FIPS self test +for the module, and save the fips.conf configuration file: + + openssl fipsinstall -module ./fips.so -out fips.conf -provider_name fips \ + -section_name fipsinstall -mac_name HMAC -macopt digest:SHA256 \ + -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 + +Verify that the configuration file 'fips.conf' contains the correct info: + + openssl fipsinstall -module ./fips.so -in fips.conf -provider_name fips \ + -section_name fips_install -mac_name HMAC -macopt digest:SHA256 \ + -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 -verify + +=head1 NOTES + +The MAC mechanisms that are available will depend on the options +used when building OpenSSL. +The B command can be used to list them. + +=head1 SEE ALSO + +L, +L + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (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/man1/asn1parse.pod b/doc/man1/openssl-asn1parse.pod similarity index 98% rename from doc/man1/asn1parse.pod rename to doc/man1/openssl-asn1parse.pod index ec6e6334..ccb2f034 100644 --- a/doc/man1/asn1parse.pod +++ b/doc/man1/openssl-asn1parse.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-asn1parse, -asn1parse - ASN.1 parsing tool +openssl-asn1parse - ASN.1 parsing tool =head1 SYNOPSIS @@ -201,11 +200,12 @@ ASN.1 types is not well handled (if at all). =head1 SEE ALSO +L, L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/ca.pod b/doc/man1/openssl-ca.pod similarity index 99% rename from doc/man1/ca.pod rename to doc/man1/openssl-ca.pod index 8438d1dc..9826fbfc 100644 --- a/doc/man1/ca.pod +++ b/doc/man1/openssl-ca.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ca, -ca - sample minimal CA application +openssl-ca - sample minimal CA application =head1 SYNOPSIS @@ -770,8 +769,13 @@ are in year 2050 or later. =head1 SEE ALSO -L, L, L, L, -L, L +L, +L, +L, +L, +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man1/ciphers.pod b/doc/man1/openssl-ciphers.pod similarity index 99% rename from doc/man1/ciphers.pod rename to doc/man1/openssl-ciphers.pod index 7d795c39..1d4e0a89 100644 --- a/doc/man1/ciphers.pod +++ b/doc/man1/openssl-ciphers.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ciphers, -ciphers - SSL cipher display and cipher list tool +openssl-ciphers - SSL cipher display and cipher list tool =head1 SYNOPSIS @@ -524,7 +523,7 @@ Note: these ciphers can also be used in SSL v3. TLS_DHE_DSS_WITH_RC4_128_SHA DHE-DSS-RC4-SHA -=head2 Elliptic curve cipher suites. +=head2 Elliptic curve cipher suites TLS_ECDHE_RSA_WITH_NULL_SHA ECDHE-RSA-NULL-SHA TLS_ECDHE_RSA_WITH_RC4_128_SHA ECDHE-RSA-RC4-SHA @@ -768,7 +767,10 @@ Set security level to 2 and display all ciphers consistent with level 2: =head1 SEE ALSO -L, L, L +L, +L, +L, +L =head1 HISTORY @@ -781,7 +783,7 @@ The B<-convert> option was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/openssl-cmds.pod b/doc/man1/openssl-cmds.pod new file mode 100644 index 00000000..cab89f12 --- /dev/null +++ b/doc/man1/openssl-cmds.pod @@ -0,0 +1,153 @@ +=pod + +=head1 NAME + +asn1parse, +ca, +ciphers, +cms, +crl, +crl2pkcs7, +dgst, +dhparam, +dsa, +dsaparam, +ec, +ecparam, +enc, +engine, +errstr, +gendsa, +genpkey, +genrsa, +info, +kdf, +mac, +nseq, +ocsp, +passwd, +pkcs12, +pkcs7, +pkcs8, +pkey, +pkeyparam, +pkeyutl, +prime, +rand, +rehash, +req, +rsa, +rsautl, +s_client, +s_server, +s_time, +sess_id, +smime, +speed, +spkac, +srp, +storeutl, +ts, +verify, +version, +x509 +- OpenSSL application commands + +=head1 SYNOPSIS + +=for comment generic + +B B [B<-help>] [B<...>] + +=head1 DESCRIPTION + +Every B listed above is a (sub-)command of the L application. +It has its own detailed manual page at B. For example, to view +the manual page for the B command, type B. + +=head1 OPTIONS + +Among others, every subcommand has a help option. + +=over 4 + +=item B<-help> + +Print out a usage message for the subcommand. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, + +=head1 HISTORY + +Initially, the manual page entry for the B command used +to be available at B. Later, the alias B was +introduced, which made it easier to group the openssl commands using +the L command or the shell's tab completion. + +In order to reduce cluttering of the global manual page namespace, +the manual page entries without the 'openssl-' prefix have been +deprecated in OpenSSL 3.0 and will be removed in OpenSSL 4.0. + +=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/man1/cms.pod b/doc/man1/openssl-cms.pod similarity index 99% rename from doc/man1/cms.pod rename to doc/man1/openssl-cms.pod index b2031c6a..54e757ff 100644 --- a/doc/man1/cms.pod +++ b/doc/man1/openssl-cms.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-cms, -cms - CMS utility +openssl-cms - CMS utility =head1 SYNOPSIS @@ -560,7 +559,7 @@ The B<-debug_decrypt> option can be used to disable the MMA attack protection and return an error if no recipient can be found: this option should be used with caution. For a fuller description see L). -=head1 CAdES Basic Electronic Signature (CAdES-BES) +=head1 CADES BASIC ELECTRONIC SIGNATURE (CADES-BES) A CAdES Basic Electronic Signature (CAdES-BES), as defined in the European Standard ETSI EN 319 122-1 V1.1.1, contains: @@ -626,7 +625,7 @@ the signers certificates. =back -=head1 COMPATIBILITY WITH PKCS#7 format. +=head1 COMPATIBILITY WITH PKCS#7 FORMAT The B utility can only process the older B format. The B utility supports Cryptographic Message Syntax format. Use of some features @@ -776,7 +775,7 @@ The -no_alt_chains option was added in OpenSSL 1.0.2b. =head1 COPYRIGHT -Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-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 diff --git a/doc/man1/crl.pod b/doc/man1/openssl-crl.pod similarity index 94% rename from doc/man1/crl.pod rename to doc/man1/openssl-crl.pod index a76f2ae0..35fe5ed1 100644 --- a/doc/man1/crl.pod +++ b/doc/man1/openssl-crl.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-crl, -crl - CRL utility +openssl-crl - CRL utility =head1 SYNOPSIS @@ -129,11 +128,14 @@ and files too. =head1 SEE ALSO -L, L, L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/crl2pkcs7.pod b/doc/man1/openssl-crl2pkcs7.pod similarity index 93% rename from doc/man1/crl2pkcs7.pod rename to doc/man1/openssl-crl2pkcs7.pod index df58b8a2..bb172529 100644 --- a/doc/man1/crl2pkcs7.pod +++ b/doc/man1/openssl-crl2pkcs7.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-crl2pkcs7, -crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates +openssl-crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates =head1 SYNOPSIS @@ -92,11 +91,12 @@ install user certificates and CAs in MSIE using the Xenroll control. =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/dgst.pod b/doc/man1/openssl-dgst.pod similarity index 99% rename from doc/man1/dgst.pod rename to doc/man1/openssl-dgst.pod index 0116a792..ed1a088e 100644 --- a/doc/man1/dgst.pod +++ b/doc/man1/openssl-dgst.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-dgst, -dgst - perform digest operations +openssl-dgst - perform digest operations =head1 SYNOPSIS diff --git a/doc/man1/dhparam.pod b/doc/man1/openssl-dhparam.pod similarity index 91% rename from doc/man1/dhparam.pod rename to doc/man1/openssl-dhparam.pod index 67a38941..6643e20e 100644 --- a/doc/man1/dhparam.pod +++ b/doc/man1/openssl-dhparam.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-dhparam, -dhparam - DH parameter manipulation and generation +openssl-dhparam - DH parameter manipulation and generation =head1 SYNOPSIS @@ -19,6 +18,7 @@ B [B<-text>] [B<-C>] [B<-2>] +[B<-3>] [B<-5>] [B<-rand file...>] [B<-writerand file>] @@ -77,9 +77,9 @@ avoid small-subgroup attacks that may be possible otherwise. Performs numerous checks to see if the supplied parameters are valid and displays a warning if not. -=item B<-2>, B<-5> +=item B<-2>, B<-3>, B<-5> -The generator to use, either 2 or 5. If present then the +The generator to use, either 2, 3 or 5. If present then the input file is ignored and parameters are generated instead. If not present but B is present, parameters are generated with the default generator 2. @@ -102,8 +102,9 @@ This can be used with a subsequent B<-rand> flag. This option specifies that a parameter set should be generated of size I. It must be the last option. If this option is present then the input file is ignored and parameters are generated instead. If -this option is not present but a generator (B<-2> or B<-5>) is +this option is not present but a generator (B<-2>, B<-3> or B<-5>) is present, parameters are generated with a default length of 2048 bits. +The minimim length is 512 bits. The maximum length is 10000 bits. =item B<-noout> @@ -152,11 +153,12 @@ There should be a way to generate and manipulate DH keys. =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/dsa.pod b/doc/man1/openssl-dsa.pod similarity index 96% rename from doc/man1/dsa.pod rename to doc/man1/openssl-dsa.pod index 3358131d..8039b395 100644 --- a/doc/man1/dsa.pod +++ b/doc/man1/openssl-dsa.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-dsa, -dsa - DSA key processing +openssl-dsa - DSA key processing =head1 SYNOPSIS @@ -167,12 +166,15 @@ To just output the public part of a private key: =head1 SEE ALSO -L, L, L, -L +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/dsaparam.pod b/doc/man1/openssl-dsaparam.pod similarity index 93% rename from doc/man1/dsaparam.pod rename to doc/man1/openssl-dsaparam.pod index 795c52d5..e6a63cf9 100644 --- a/doc/man1/dsaparam.pod +++ b/doc/man1/openssl-dsaparam.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-dsaparam, -dsaparam - DSA parameter manipulation and generation +openssl-dsaparam - DSA parameter manipulation and generation =head1 SYNOPSIS @@ -121,12 +120,15 @@ DSA parameters is often used to generate several distinct keys. =head1 SEE ALSO -L, L, L, -L +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/ec.pod b/doc/man1/openssl-ec.pod similarity index 97% rename from doc/man1/ec.pod rename to doc/man1/openssl-ec.pod index 0a1e7af7..6d86c1a1 100644 --- a/doc/man1/ec.pod +++ b/doc/man1/openssl-ec.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ec, -ec - EC key processing +openssl-ec - EC key processing =head1 SYNOPSIS @@ -189,11 +188,14 @@ To change the point conversion form to B: =head1 SEE ALSO -L, L, L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2003-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 diff --git a/doc/man1/ecparam.pod b/doc/man1/openssl-ecparam.pod similarity index 96% rename from doc/man1/ecparam.pod rename to doc/man1/openssl-ecparam.pod index fac930ea..9d8539bd 100644 --- a/doc/man1/ecparam.pod +++ b/doc/man1/openssl-ecparam.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ecparam, -ecparam - EC parameter manipulation and generation +openssl-ecparam - EC parameter manipulation and generation =head1 SYNOPSIS @@ -184,11 +183,13 @@ To print out the EC parameters to standard output: =head1 SEE ALSO -L, L +L, +L, +L =head1 COPYRIGHT -Copyright 2003-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2003-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 diff --git a/doc/man1/enc.pod b/doc/man1/openssl-enc.pod similarity index 99% rename from doc/man1/enc.pod rename to doc/man1/openssl-enc.pod index 7a6ce5a2..2ea69e77 100644 --- a/doc/man1/enc.pod +++ b/doc/man1/openssl-enc.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-enc, -enc - symmetric cipher routines +openssl-enc - symmetric cipher routines =head1 SYNOPSIS @@ -421,7 +420,7 @@ The default digest was changed from MD5 to SHA256 in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/engine.pod b/doc/man1/openssl-engine.pod similarity index 95% rename from doc/man1/engine.pod rename to doc/man1/openssl-engine.pod index 446b1981..976d69c2 100644 --- a/doc/man1/engine.pod +++ b/doc/man1/openssl-engine.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-engine, -engine - load and query engines +openssl-engine - load and query engines =head1 SYNOPSIS @@ -64,7 +63,7 @@ See the example below. =back -=head1 EXAMPLE +=head1 EXAMPLES To list all the commands available to a dynamic engine: @@ -105,11 +104,12 @@ The path to the engines directory. =head1 SEE ALSO +L, L =head1 COPYRIGHT -Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-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 diff --git a/doc/man1/errstr.pod b/doc/man1/openssl-errstr.pod similarity index 87% rename from doc/man1/errstr.pod rename to doc/man1/openssl-errstr.pod index ba6fc814..c910f84f 100644 --- a/doc/man1/errstr.pod +++ b/doc/man1/openssl-errstr.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-errstr, -errstr - lookup error codes +openssl-errstr - lookup error codes =head1 SYNOPSIS @@ -20,7 +19,7 @@ second colon. None. -=head1 EXAMPLE +=head1 EXAMPLES The error code: @@ -36,7 +35,7 @@ to produce the error message: =head1 COPYRIGHT -Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2004-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 diff --git a/doc/man1/gendsa.pod b/doc/man1/openssl-gendsa.pod similarity index 91% rename from doc/man1/gendsa.pod rename to doc/man1/openssl-gendsa.pod index 180ce57f..36da9983 100644 --- a/doc/man1/gendsa.pod +++ b/doc/man1/openssl-gendsa.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-gendsa, -gendsa - generate a DSA private key from a set of parameters +openssl-gendsa - generate a DSA private key from a set of parameters =head1 SYNOPSIS @@ -91,12 +90,15 @@ much quicker that RSA key generation for example. =head1 SEE ALSO -L, L, L, -L +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/genpkey.pod b/doc/man1/openssl-genpkey.pod similarity index 98% rename from doc/man1/genpkey.pod rename to doc/man1/openssl-genpkey.pod index e418c13f..c9364109 100644 --- a/doc/man1/genpkey.pod +++ b/doc/man1/openssl-genpkey.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-genpkey, -genpkey - generate a private key +openssl-genpkey - generate a private key =head1 SYNOPSIS @@ -325,7 +324,7 @@ The ability to generate X448, ED25519 and ED448 keys was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/genrsa.pod b/doc/man1/openssl-genrsa.pod similarity index 96% rename from doc/man1/genrsa.pod rename to doc/man1/openssl-genrsa.pod index f8cbb17e..c551792a 100644 --- a/doc/man1/genrsa.pod +++ b/doc/man1/openssl-genrsa.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-genrsa, -genrsa - generate an RSA private key +openssl-genrsa - generate an RSA private key =head1 SYNOPSIS @@ -119,11 +118,12 @@ of a key. =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/info.pod b/doc/man1/openssl-info.pod similarity index 89% rename from doc/man1/info.pod rename to doc/man1/openssl-info.pod index 6eddf0fa..637b60b2 100644 --- a/doc/man1/info.pod +++ b/doc/man1/openssl-info.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-info, -info - print OpenSSL built-in information +openssl-info - print OpenSSL built-in information =head1 SYNOPSIS @@ -15,6 +14,8 @@ B [B<-dsoext>] [B<-dirfilesep>] [B<-listsep]> +[B<-seeds]> +[B<-cpusettings]> =head1 DESCRIPTION @@ -63,6 +64,14 @@ Outputs the OpenSSL list separator character. This is typically used to construct C<$PATH> (C<%PATH%> on Windows) style lists. +=item B<-seeds> + +Outputs the randomness seed sources. + +=item B<-cpusettings> + +Outputs the OpenSSL CPU settings info. + =back =head1 HISTORY diff --git a/doc/man1/kdf.pod b/doc/man1/openssl-kdf.pod similarity index 88% rename from doc/man1/kdf.pod rename to doc/man1/openssl-kdf.pod index 7282d73c..2b14eaad 100644 --- a/doc/man1/kdf.pod +++ b/doc/man1/openssl-kdf.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-kdf, -kdf - perform Key Derivation Function operations +openssl-kdf - perform Key Derivation Function operations =head1 SYNOPSIS @@ -43,9 +42,9 @@ Output the derived key in binary form. Uses hexadecimal text format if not speci =item B<-kdfopt> I Passes options to the KDF algorithm. -A comprehensive list of controls can be found in the EVP_KDF_CTX implementation -documentation. -Common control strings used by EVP_KDF_ctrl_str() are: +A comprehensive list of parameters can be found in the EVP_KDF_CTX +implementation documentation. +Common parameter names used by EVP_KDF_CTX_set_params() are: =over 4 @@ -83,7 +82,8 @@ To see the list of supported digests, use the command I. =item I Specifies the name of a supported KDF algorithm which will be used. -The supported algorithms names are TLS1-PRF, HKDF, SSKDF, PBKDF2, SSHKDF and id-scrypt. +The supported algorithms names include TLS1-PRF, HKDF, SSKDF, PBKDF2, +SSHKDF, X942KDF, X963KDF and id-scrypt. =back @@ -143,14 +143,17 @@ used when building OpenSSL. =head1 SEE ALSO -L, -L -L -L -L -L -L -L +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L =head1 HISTORY diff --git a/doc/man1/list.pod b/doc/man1/openssl-list.pod similarity index 72% rename from doc/man1/list.pod rename to doc/man1/openssl-list.pod index 901a2668..3a3c5ab4 100644 --- a/doc/man1/list.pod +++ b/doc/man1/openssl-list.pod @@ -2,17 +2,18 @@ =head1 NAME -openssl-list, -list - list algorithms and features +openssl-list - list algorithms and features =head1 SYNOPSIS B [B<-help>] +[B<-verbose>] [B<-1>] [B<-commands>] [B<-digest-commands>] [B<-digest-algorithms>] +[B<-kdf-algorithms>] [B<-mac-algorithms>] [B<-cipher-commands>] [B<-cipher-algorithms>] @@ -34,6 +35,11 @@ features. Display a usage message. +=item B<-verbose> + +Displays extra information. +The options below where verbosity applies say a bit more about what that means. + =item B<-1> List the commands, digest-commands, or cipher-commands in a single column. @@ -53,12 +59,19 @@ as input to the L or L commands. Display a list of message digest algorithms. If a line is of the form C bar> then B is an alias for the official algorithm name, B. +If a line is of the form C, then B is provided by the provider +B. + +In verbose mode, the algorithms provided by a provider will get additional +information on what parameters each implementation supports. + +=item B<-kdf-algorithms> + +Display a list of key derivation function algorithms. =item B<-mac-algorithms> Display a list of message authentication code algorithms. -If a line is of the form C bar> then B is an alias for the -official algorithm name, B. =item B<-cipher-commands> @@ -70,6 +83,11 @@ to the L or L commands. Display a list of cipher algorithms. If a line is of the form C bar> then B is an alias for the official algorithm name, B. +If a line is of the form C, then B is provided by the provider +B. + +In verbose mode, the algorithms provided by a provider will get additional +information on what parameters each implementation supports. =item B<-public-key-algorithms> @@ -78,8 +96,7 @@ a block of multiple lines, all but the first are indented. =item B<-public-key-methods> -Display a list of public key method OIDs: this also includes public key methods -without an associated ASN.1 method, for example, KDF algorithms. +Display a list of public key method OIDs. =item B<-engines> @@ -99,7 +116,7 @@ format described in L. =head1 COPYRIGHT -Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-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 diff --git a/doc/man1/mac.pod b/doc/man1/openssl-mac.pod similarity index 92% rename from doc/man1/mac.pod rename to doc/man1/openssl-mac.pod index 3143df8d..d2e6c7f2 100644 --- a/doc/man1/mac.pod +++ b/doc/man1/openssl-mac.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-mac, -mac - perform Message Authentication Code operations +openssl-mac - perform Message Authentication Code operations =head1 SYNOPSIS @@ -50,7 +49,7 @@ Output the MAC in binary form. Uses hexadecimal text format if not specified. Passes options to the MAC algorithm. A comprehensive list of controls can be found in the EVP_MAC implementation documentation. -Common control strings used by EVP_MAC_ctrl_str() are: +Common parameter names used by EVP_MAC_CTX_get_params() are: =over 4 @@ -143,17 +142,18 @@ The B command can be used to list them. =head1 SEE ALSO +L, L, -L, -L, -L, -L, -L, -L +L, +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/nseq.pod b/doc/man1/openssl-nseq.pod similarity index 93% rename from doc/man1/nseq.pod rename to doc/man1/openssl-nseq.pod index 5760baf7..37ceae1b 100644 --- a/doc/man1/nseq.pod +++ b/doc/man1/openssl-nseq.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-nseq, -nseq - create or examine a Netscape certificate sequence +openssl-nseq - create or examine a Netscape certificate sequence =head1 SYNOPSIS @@ -75,7 +74,7 @@ output files and allowing multiple certificate files to be used. =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/ocsp.pod b/doc/man1/openssl-ocsp.pod similarity index 99% rename from doc/man1/ocsp.pod rename to doc/man1/openssl-ocsp.pod index 4c0aaac1..d5bc2f75 100644 --- a/doc/man1/ocsp.pod +++ b/doc/man1/openssl-ocsp.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ocsp, -ocsp - Online Certificate Status Protocol utility +openssl-ocsp - Online Certificate Status Protocol utility =head1 SYNOPSIS @@ -393,7 +392,7 @@ immediately available. =back -=head1 OCSP Response verification. +=head1 OCSP RESPONSE VERIFICATION OCSP Response follows the rules specified in RFC2560. @@ -497,7 +496,7 @@ The -no_alt_chains option was added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-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 diff --git a/doc/man1/passwd.pod b/doc/man1/openssl-passwd.pod similarity index 96% rename from doc/man1/passwd.pod rename to doc/man1/openssl-passwd.pod index 440dc036..d2dc63dc 100644 --- a/doc/man1/passwd.pod +++ b/doc/man1/openssl-passwd.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-passwd, -passwd - compute password hashes +openssl-passwd - compute password hashes =head1 SYNOPSIS @@ -122,7 +121,7 @@ This can be used with a subsequent B<-rand> flag. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/pkcs12.pod b/doc/man1/openssl-pkcs12.pod similarity index 98% rename from doc/man1/pkcs12.pod rename to doc/man1/openssl-pkcs12.pod index b1b68844..b7233920 100644 --- a/doc/man1/pkcs12.pod +++ b/doc/man1/openssl-pkcs12.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkcs12, -pkcs12 - PKCS#12 file utility +openssl-pkcs12 - PKCS#12 file utility =head1 SYNOPSIS @@ -225,7 +224,8 @@ for this search. If the search fails it is considered a fatal error. Encrypt the certificate using triple DES, this may render the PKCS#12 file unreadable by some "export grade" software. By default the private -key is encrypted using triple DES and the certificate using 40 bit RC2. +key is encrypted using triple DES and the certificate using 40 bit RC2 +unless RC2 is disabled in which case triple DES is used. =item B<-keypbe alg>, B<-certpbe alg> @@ -378,11 +378,12 @@ Include some extra certificates: =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/pkcs7.pod b/doc/man1/openssl-pkcs7.pod similarity index 94% rename from doc/man1/pkcs7.pod rename to doc/man1/openssl-pkcs7.pod index 3c6d971c..ef0655af 100644 --- a/doc/man1/pkcs7.pod +++ b/doc/man1/openssl-pkcs7.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkcs7, -pkcs7 - PKCS#7 utility +openssl-pkcs7 - PKCS#7 utility =head1 SYNOPSIS @@ -106,11 +105,12 @@ cannot currently parse, for example, the new CMS as described in RFC2630. =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/pkcs8.pod b/doc/man1/openssl-pkcs8.pod similarity index 97% rename from doc/man1/pkcs8.pod rename to doc/man1/openssl-pkcs8.pod index 8099c907..9b636949 100644 --- a/doc/man1/pkcs8.pod +++ b/doc/man1/openssl-pkcs8.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkcs8, -pkcs8 - PKCS#8 format private key conversion tool +openssl-pkcs8 - PKCS#8 format private key conversion tool =head1 SYNOPSIS @@ -210,7 +209,7 @@ It is possible to write out DER encoded encrypted private keys in PKCS#8 format because the encryption details are included at an ASN1 level whereas the traditional format includes them at a PEM level. -=head1 PKCS#5 v1.5 and PKCS#12 algorithms. +=head1 PKCS#5 V1.5 AND PKCS#12 ALGORITHMS Various algorithms can be used with the B<-v1> command line option, including PKCS#5 v1.5 and PKCS#12. These are described in more detail @@ -300,8 +299,11 @@ in use and other details such as the iteration count. =head1 SEE ALSO -L, L, L, -L +L, +L, +L, +L, +L =head1 HISTORY @@ -309,7 +311,7 @@ The B<-iter> option was added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/pkey.pod b/doc/man1/openssl-pkey.pod similarity index 93% rename from doc/man1/pkey.pod rename to doc/man1/openssl-pkey.pod index ba71ae4c..c6d1ae71 100644 --- a/doc/man1/pkey.pod +++ b/doc/man1/openssl-pkey.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkey, -pkey - public or private key processing tool +openssl-pkey - public or private key processing tool =head1 SYNOPSIS @@ -153,12 +152,17 @@ To just output the public part of a private key: =head1 SEE ALSO -L, L, L, -L, L, L +L, +L, +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/pkeyparam.pod b/doc/man1/openssl-pkeyparam.pod similarity index 85% rename from doc/man1/pkeyparam.pod rename to doc/man1/openssl-pkeyparam.pod index 048a1f2e..4ebb2411 100644 --- a/doc/man1/pkeyparam.pod +++ b/doc/man1/openssl-pkeyparam.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkeyparam, -pkeyparam - public key algorithm parameter processing tool +openssl-pkeyparam - public key algorithm parameter processing tool =head1 SYNOPSIS @@ -60,7 +59,7 @@ This option checks the correctness of parameters. =back -=head1 EXAMPLE +=head1 EXAMPLES Print out text version of parameters: @@ -73,12 +72,17 @@ PEM format is supported because the key type is determined by the PEM headers. =head1 SEE ALSO -L, L, L, -L, L, L +L, +L, +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/pkeyutl.pod b/doc/man1/openssl-pkeyutl.pod similarity index 94% rename from doc/man1/pkeyutl.pod rename to doc/man1/openssl-pkeyutl.pod index 3a7f31b8..e4a0d2c1 100644 --- a/doc/man1/pkeyutl.pod +++ b/doc/man1/openssl-pkeyutl.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-pkeyutl, -pkeyutl - public key algorithm utility +openssl-pkeyutl - public key algorithm utility =head1 SYNOPSIS @@ -310,12 +309,12 @@ The EC algorithm supports sign, verify and derive operations. The sign and verify operations use ECDSA and derive uses ECDH. SHA1 is assumed by default for the B<-pkeyopt> B option. -=head1 X25519 and X448 ALGORITHMS +=head1 X25519 AND X448 ALGORITHMS The X25519 and X448 algorithms support key derivation only. Currently there are no additional options. -=head1 Ed25519 and Ed448 ALGORITHMS +=head1 ED25519 AND ED448 ALGORITHMS These algorithms only support signing and verifying. OpenSSL only implements the "pure" variants of these algorithms so raw data can be passed directly to them @@ -341,6 +340,13 @@ This sets the ID string used in SM2 sign or verify operations. While verifying an SM2 signature, the ID string must be the same one used when signing the data. Otherwise the verification will fail. +=item B + +This sets the ID string used in SM2 sign or verify operations. While verifying +an SM2 signature, the ID string must be the same one used when signing the data. +Otherwise the verification will fail. The ID string provided with this option +should be a valid hexadecimal value. + =back =head1 EXAMPLES @@ -393,14 +399,21 @@ Verify some data using an L certificate and a specific ID: =head1 SEE ALSO -L, L, L -L, L, L, -L, L, -L +L, +L, +L, +L +L, +L, +L, +L +L, +L, + =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/prime.pod b/doc/man1/openssl-prime.pod similarity index 91% rename from doc/man1/prime.pod rename to doc/man1/openssl-prime.pod index 019f5060..068cf344 100644 --- a/doc/man1/prime.pod +++ b/doc/man1/openssl-prime.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-prime, -prime - compute prime numbers +openssl-prime - compute prime numbers =head1 SYNOPSIS @@ -58,7 +57,7 @@ is prime. The default is 20. =head1 COPYRIGHT -Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-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 diff --git a/doc/man1/rand.pod b/doc/man1/openssl-rand.pod similarity index 92% rename from doc/man1/rand.pod rename to doc/man1/openssl-rand.pod index d6260ee9..7d431e0e 100644 --- a/doc/man1/rand.pod +++ b/doc/man1/openssl-rand.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-rand, -rand - generate pseudo-random bytes +openssl-rand - generate pseudo-random bytes =head1 SYNOPSIS @@ -62,11 +61,12 @@ Show the output as a hex string. =head1 SEE ALSO +L, L =head1 COPYRIGHT -Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/rehash.pod b/doc/man1/openssl-rehash.pod similarity index 95% rename from doc/man1/rehash.pod rename to doc/man1/openssl-rehash.pod index 187a7905..d68b32c9 100644 --- a/doc/man1/rehash.pod +++ b/doc/man1/openssl-rehash.pod @@ -5,8 +5,7 @@ Original text by James Westby, contributed under the OpenSSL license. =head1 NAME -openssl-c_rehash, openssl-rehash, -c_rehash, rehash - Create symbolic links to files named by the hash values +openssl-c_rehash - Create symbolic links to files named by the hash values =head1 SYNOPSIS @@ -131,12 +130,12 @@ Ignored if directories are listed on the command line. =head1 SEE ALSO L, -L. -L. +L, +L =head1 COPYRIGHT -Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-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 diff --git a/doc/man1/req.pod b/doc/man1/openssl-req.pod similarity index 99% rename from doc/man1/req.pod rename to doc/man1/openssl-req.pod index 1e73ee5d..4300504f 100644 --- a/doc/man1/req.pod +++ b/doc/man1/openssl-req.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-req, -req - PKCS#10 certificate request and certificate generating utility +openssl-req - PKCS#10 certificate request and certificate generating utility =head1 SYNOPSIS @@ -710,8 +709,12 @@ address in subjectAltName should be input by the user. =head1 SEE ALSO -L, L, L, -L, L, +L, +L, +L, +L, +L, +L, L =head1 COPYRIGHT diff --git a/doc/man1/rsa.pod b/doc/man1/openssl-rsa.pod similarity index 96% rename from doc/man1/rsa.pod rename to doc/man1/openssl-rsa.pod index ae772d81..2b271fc6 100644 --- a/doc/man1/rsa.pod +++ b/doc/man1/openssl-rsa.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-rsa, -rsa - RSA key processing tool +openssl-rsa - RSA key processing tool =head1 SYNOPSIS @@ -190,12 +189,15 @@ without having to manually edit them. =head1 SEE ALSO -L, L, L, -L +L, +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/rsautl.pod b/doc/man1/openssl-rsautl.pod similarity index 97% rename from doc/man1/rsautl.pod rename to doc/man1/openssl-rsautl.pod index ac20b5e2..5ab282d0 100644 --- a/doc/man1/rsautl.pod +++ b/doc/man1/openssl-rsautl.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-rsautl, -rsautl - RSA utility +openssl-rsautl - RSA utility =head1 SYNOPSIS @@ -206,11 +205,14 @@ which it can be seen agrees with the recovered value above. =head1 SEE ALSO -L, L, L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/s_client.pod b/doc/man1/openssl-s_client.pod similarity index 98% rename from doc/man1/s_client.pod rename to doc/man1/openssl-s_client.pod index e42a6ba6..61d95244 100644 --- a/doc/man1/s_client.pod +++ b/doc/man1/openssl-s_client.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-s_client, -s_client - SSL/TLS client program +openssl-s_client - SSL/TLS client program =head1 SYNOPSIS @@ -149,7 +148,7 @@ SSL servers. =head1 OPTIONS In addition to the options below the B utility also supports the -common and client only options documented in the +common and client only options documented in the "Supported Command Line Commands" section of the L manual page. @@ -830,8 +829,13 @@ information whenever a session is renegotiated. =head1 SEE ALSO -L, L, L, L, -L, L, +L, +L, +L, +L, +L, +L, +L, L =head1 HISTORY @@ -841,7 +845,7 @@ The B<-name> option was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/s_server.pod b/doc/man1/openssl-s_server.pod similarity index 99% rename from doc/man1/s_server.pod rename to doc/man1/openssl-s_server.pod index e5c1821d..c3a0e7af 100644 --- a/doc/man1/s_server.pod +++ b/doc/man1/openssl-s_server.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-s_server, -s_server - SSL/TLS server program +openssl-s_server - SSL/TLS server program =head1 SYNOPSIS @@ -194,7 +193,7 @@ for connections on a given port using SSL/TLS. =head1 OPTIONS In addition to the options below the B utility also supports the -common and server only options documented in the +common and server only options documented in the "Supported Command Line Commands" section of the L manual page. @@ -833,7 +832,11 @@ unknown cipher suites a client says it supports. =head1 SEE ALSO -L, L, L, L +L, +L, +L, +L, +L, L, L, L @@ -847,7 +850,7 @@ The =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/s_time.pod b/doc/man1/openssl-s_time.pod similarity index 97% rename from doc/man1/s_time.pod rename to doc/man1/openssl-s_time.pod index ce626426..8a4f89fb 100644 --- a/doc/man1/s_time.pod +++ b/doc/man1/openssl-s_time.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-s_time, -s_time - SSL/TLS performance timing program +openssl-s_time - SSL/TLS performance timing program =head1 SYNOPSIS @@ -198,11 +197,14 @@ fails. =head1 SEE ALSO -L, L, L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2004-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 diff --git a/doc/man1/sess_id.pod b/doc/man1/openssl-sess_id.pod similarity index 95% rename from doc/man1/sess_id.pod rename to doc/man1/openssl-sess_id.pod index 1e76f73b..7b5a8f95 100644 --- a/doc/man1/sess_id.pod +++ b/doc/man1/openssl-sess_id.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-sess_id, -sess_id - SSL/TLS session handling utility +openssl-sess_id - SSL/TLS session handling utility =head1 SYNOPSIS @@ -152,11 +151,13 @@ The cipher and start time should be printed out in human readable form. =head1 SEE ALSO -L, L +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/smime.pod b/doc/man1/openssl-smime.pod similarity index 99% rename from doc/man1/smime.pod rename to doc/man1/openssl-smime.pod index be20161d..aaf44095 100644 --- a/doc/man1/smime.pod +++ b/doc/man1/openssl-smime.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-smime, -smime - S/MIME utility +openssl-smime - S/MIME utility =head1 SYNOPSIS @@ -514,7 +513,7 @@ The -no_alt_chains option was added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/speed.pod b/doc/man1/openssl-speed.pod similarity index 96% rename from doc/man1/speed.pod rename to doc/man1/openssl-speed.pod index 1cb4494e..796cced4 100644 --- a/doc/man1/speed.pod +++ b/doc/man1/openssl-speed.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-speed, -speed - test library performance +openssl-speed - test library performance =head1 SYNOPSIS @@ -104,7 +103,7 @@ pre-compiled grand selection is tested. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/spkac.pod b/doc/man1/openssl-spkac.pod similarity index 96% rename from doc/man1/spkac.pod rename to doc/man1/openssl-spkac.pod index dc66d7fb..ea992c61 100644 --- a/doc/man1/spkac.pod +++ b/doc/man1/openssl-spkac.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-spkac, -spkac - SPKAC printing and generating utility +openssl-spkac - SPKAC printing and generating utility =head1 SYNOPSIS @@ -141,11 +140,12 @@ to be used in a "replay attack". =head1 SEE ALSO -L +L, +L =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/srp.pod b/doc/man1/openssl-srp.pod similarity index 93% rename from doc/man1/srp.pod rename to doc/man1/openssl-srp.pod index 0fc4e079..8f137089 100644 --- a/doc/man1/srp.pod +++ b/doc/man1/openssl-srp.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-srp, -srp - maintain SRP password file +openssl-srp - maintain SRP password file =head1 SYNOPSIS @@ -63,7 +62,7 @@ Generate verbose output while processing. =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-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 diff --git a/doc/man1/storeutl.pod b/doc/man1/openssl-storeutl.pod similarity index 96% rename from doc/man1/storeutl.pod rename to doc/man1/openssl-storeutl.pod index 210a8878..61f30a8d 100644 --- a/doc/man1/storeutl.pod +++ b/doc/man1/openssl-storeutl.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-storeutl, -storeutl - STORE utility +openssl-storeutl - STORE utility =head1 SYNOPSIS @@ -123,7 +122,7 @@ The B B app was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-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 diff --git a/doc/man1/ts.pod b/doc/man1/openssl-ts.pod similarity index 98% rename from doc/man1/ts.pod rename to doc/man1/openssl-ts.pod index ade077a3..1544cc94 100644 --- a/doc/man1/ts.pod +++ b/doc/man1/openssl-ts.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-ts, -ts - Time Stamping Authority tool (client/server) +openssl-ts - Time Stamping Authority tool (client/server) =head1 SYNOPSIS @@ -660,13 +659,17 @@ test/testtsa). =head1 SEE ALSO -L, L, L, -L, L, L, +L, +L, +L, +L, +L, +L, L =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/tsget.pod b/doc/man1/openssl-tsget.pod similarity index 98% rename from doc/man1/tsget.pod rename to doc/man1/openssl-tsget.pod index a48ca405..15d0dd78 100644 --- a/doc/man1/tsget.pod +++ b/doc/man1/openssl-tsget.pod @@ -2,7 +2,6 @@ =head1 NAME -openssl-tsget, tsget - Time Stamping HTTP/HTTPS client =head1 SYNOPSIS @@ -187,12 +186,14 @@ example: =for comment foreign manuals: curl(1) -L, L, L, +L, +L, +L, B =head1 COPYRIGHT -Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-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 diff --git a/doc/man1/verify.pod b/doc/man1/openssl-verify.pod similarity index 99% rename from doc/man1/verify.pod rename to doc/man1/openssl-verify.pod index 10fd8486..e5111613 100644 --- a/doc/man1/verify.pod +++ b/doc/man1/openssl-verify.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-verify, -verify - Utility to verify certificates +openssl-verify - Utility to verify certificates =head1 SYNOPSIS @@ -770,7 +769,8 @@ B error codes. =head1 SEE ALSO -L +L, +L =head1 HISTORY @@ -779,7 +779,7 @@ The B<-show_chain> option was added in OpenSSL 1.1.0. The B<-issuer_checks> option is deprecated as of OpenSSL 1.1.0 and is silently ignored. -The B<-sm2-id> and B<-sm2-hex-id> options were added in OpenSSL 3.0.0. +The B<-sm2-id> and B<-sm2-hex-id> options were added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man1/version.pod b/doc/man1/openssl-version.pod similarity index 79% rename from doc/man1/version.pod rename to doc/man1/openssl-version.pod index 6d58f9de..27876942 100644 --- a/doc/man1/version.pod +++ b/doc/man1/openssl-version.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-version, -version - print OpenSSL version information +openssl-version - print OpenSSL version information =head1 SYNOPSIS @@ -17,6 +16,9 @@ B [B<-p>] [B<-d>] [B<-e>] +[B<-m>] +[B<-r>] +[B<-c>] =head1 DESCRIPTION @@ -62,6 +64,18 @@ OPENSSLDIR setting. ENGINESDIR settings. +=item B<-m> + +MODULESDIR settings. + +=item B<-r> + +The random number generator source settings. + +=item B<-c> + +The OpenSSL CPU settings info. + =back =head1 NOTES @@ -71,7 +85,7 @@ in a bug report. =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man1/x509.pod b/doc/man1/openssl-x509.pod similarity index 99% rename from doc/man1/x509.pod rename to doc/man1/openssl-x509.pod index ed03928d..004055a6 100644 --- a/doc/man1/x509.pod +++ b/doc/man1/openssl-x509.pod @@ -2,8 +2,7 @@ =head1 NAME -openssl-x509, -x509 - Certificate display and signing utility +openssl-x509 - Certificate display and signing utility =head1 SYNOPSIS @@ -940,8 +939,12 @@ dates rather than an offset from the current time. =head1 SEE ALSO -L, L, L, -L, L, +L, +L, +L, +L, +L, +L, L =head1 HISTORY diff --git a/doc/man1/openssl.pod b/doc/man1/openssl.pod index 41d04da2..5c00e8e4 100644 --- a/doc/man1/openssl.pod +++ b/doc/man1/openssl.pod @@ -615,22 +615,59 @@ BIGNUM context. =head1 SEE ALSO -L, L, L, L, L, -L, L, L, -L, L, L, -L, L, -L, L, L, L, L, -L, L, L, L, L, -L, -L, L, L, -L, L, L, L, -L, L, L, L, -L, L, -L, L, L, -L, L, L, L, L, -L, -L, L, L, -L, L, L +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L + =head1 HISTORY diff --git a/doc/man1/provider.pod b/doc/man1/provider.pod new file mode 100644 index 00000000..6c71d1cd --- /dev/null +++ b/doc/man1/provider.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +openssl-provider - load and query providers + +=head1 SYNOPSIS + +B +[B<-v>] +[B<-vv>] +[B<-vvv>] +[ I ] + +=head1 DESCRIPTION + +The B command is used to query the capabilities of the specified +I's. + +=head1 OPTIONS + +=over 4 + +=item B<-v> B<-vv> B<-vvv> + +Provides information about each specified provider. +The first flag lists the names of all algorithms each provider +implements; the second lists them by category; the third adds +information on what parameters each of them can handle. + +=back + +=head1 ENVIRONMENT + +=over 4 + +=item B + +The path to the modules directory, where one can expect provider +modules to be located. + +=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/man3/ASYNC_WAIT_CTX_new.pod b/doc/man3/ASYNC_WAIT_CTX_new.pod index 9076be81..9c3fd713 100644 --- a/doc/man3/ASYNC_WAIT_CTX_new.pod +++ b/doc/man3/ASYNC_WAIT_CTX_new.pod @@ -195,7 +195,7 @@ were added in OpenSSL 1.1.0. ASYNC_WAIT_CTX_set_callback(), ASYNC_WAIT_CTX_get_callback(), ASYNC_WAIT_CTX_set_status(), and ASYNC_WAIT_CTX_get_status() -were added in OpenSSL 3.0.0. +were added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/ASYNC_start_job.pod b/doc/man3/ASYNC_start_job.pod index 5ac368d3..c8c30bfe 100644 --- a/doc/man3/ASYNC_start_job.pod +++ b/doc/man3/ASYNC_start_job.pod @@ -174,7 +174,7 @@ is included, commonly as one of the first included headers. Therefore it is defined as an application developer's responsibility to include windows.h prior to async.h. -=head1 EXAMPLE +=head1 EXAMPLES The following example demonstrates how to use most of the core async APIs: diff --git a/doc/man3/BIO_ctrl.pod b/doc/man3/BIO_ctrl.pod index f51593fb..c8e33863 100644 --- a/doc/man3/BIO_ctrl.pod +++ b/doc/man3/BIO_ctrl.pod @@ -141,7 +141,7 @@ the case of BIO_seek() on a file BIO for a successful operation. =head1 HISTORY The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in -OpenSSL 3.0.0. +OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/BIO_f_ssl.pod b/doc/man3/BIO_f_ssl.pod index ba441330..82bb16c5 100644 --- a/doc/man3/BIO_f_ssl.pod +++ b/doc/man3/BIO_f_ssl.pod @@ -129,9 +129,25 @@ BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(), BIO_set_ssl_renegotiate_timeout(), BIO_get_num_renegotiates(), and BIO_do_handshake() are implemented as macros. -=head1 EXAMPLE +=head1 RETURN VALUES -This SSL/TLS client example, attempts to retrieve a page from an +BIO_f_ssl() returns the SSL B structure. + +BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(), +BIO_set_ssl_renegotiate_timeout() and BIO_get_num_renegotiates() return 1 on +success or a value which is less than or equal to 0 if an error occurred. + +BIO_new_ssl(), BIO_new_ssl_connect() and BIO_new_buffer_ssl_connect() return +a valid B structure on success or B if an error occurred. + +BIO_ssl_copy_session_id() returns 1 on success or 0 on error. + +BIO_do_handshake() returns 1 if the connection was established successfully. +A zero or negative value is returned if the connection could not be established. + +=head1 EXAMPLES + +This SSL/TLS client example attempts to retrieve a page from an SSL/TLS web server. The I/O routines are identical to those of the unencrypted example in L. @@ -271,22 +287,6 @@ a client and also echoes the request to standard output. BIO_flush(sbio); BIO_free_all(sbio); -=head1 RETURN VALUES - -BIO_f_ssl() returns the SSL B structure. - -BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(), -BIO_set_ssl_renegotiate_timeout() and BIO_get_num_renegotiates() return 1 on -success or a value which is less than or equal to 0 if an error occurred. - -BIO_new_ssl(), BIO_new_ssl_connect() and BIO_new_buffer_ssl_connect() return -a valid B structure on success or B if an error occurred. - -BIO_ssl_copy_session_id() returns 1 on success or 0 on error. - -BIO_do_handshake() returns 1 if the connection was established successfully. -A zero or negative value is returned if the connection could not be established. - =head1 HISTORY In OpenSSL before 1.0.0 the BIO_pop() call was handled incorrectly, diff --git a/doc/man3/BIO_find_type.pod b/doc/man3/BIO_find_type.pod index 7a84b6de..354e3473 100644 --- a/doc/man3/BIO_find_type.pod +++ b/doc/man3/BIO_find_type.pod @@ -40,7 +40,7 @@ BIO_next() returns the next BIO in a chain. BIO_method_type() returns the type of the BIO B. -=head1 EXAMPLE +=head1 EXAMPLES Traverse a chain looking for digest BIOs: diff --git a/doc/man3/BIO_new.pod b/doc/man3/BIO_new.pod index db1e0606..d75e63bb 100644 --- a/doc/man3/BIO_new.pod +++ b/doc/man3/BIO_new.pod @@ -53,7 +53,7 @@ on it other than the discarded return value. BIO_set() was removed in OpenSSL 1.1.0 as BIO type is now opaque. -=head1 EXAMPLE +=head1 EXAMPLES Create a memory BIO: diff --git a/doc/man3/BIO_s_accept.pod b/doc/man3/BIO_s_accept.pod index c50d32f9..e6ad95b4 100644 --- a/doc/man3/BIO_s_accept.pod +++ b/doc/man3/BIO_s_accept.pod @@ -174,7 +174,7 @@ BIO_get_bind_mode() returns the set of B flags, or -1 on failure. BIO_new_accept() returns a BIO or NULL on error. -=head1 EXAMPLE +=head1 EXAMPLES This example accepts two connections on port 4444, sends messages down each and finally closes both down. diff --git a/doc/man3/BIO_s_bio.pod b/doc/man3/BIO_s_bio.pod index a4571539..0f4ea77d 100644 --- a/doc/man3/BIO_s_bio.pod +++ b/doc/man3/BIO_s_bio.pod @@ -133,7 +133,7 @@ locations for B and B. Check the error stack for more information. [XXXXX: More return values need to be added here] -=head1 EXAMPLE +=head1 EXAMPLES The BIO pair can be used to have full control over the network access of an application. The application can call select() on the socket as required @@ -176,7 +176,7 @@ and must be transferred to the network. Use BIO_ctrl_get_read_request() to find out, how many bytes must be written into the buffer before the SSL_operation() can successfully be continued. -=head1 WARNING +=head1 WARNINGS As the data is buffered, SSL_operation() may return with an ERROR_SSL_WANT_READ condition, but there is still data in the write buffer. An application must diff --git a/doc/man3/BIO_s_connect.pod b/doc/man3/BIO_s_connect.pod index eb11557b..01fae195 100644 --- a/doc/man3/BIO_s_connect.pod +++ b/doc/man3/BIO_s_connect.pod @@ -163,7 +163,7 @@ BIO_set_nbio() always returns 1. BIO_do_connect() returns 1 if the connection was successfully established and 0 or -1 if the connection failed. -=head1 EXAMPLE +=head1 EXAMPLES This is example connects to a webserver on the local host and attempts to retrieve a page and copy the result to standard output. diff --git a/doc/man3/BIO_s_fd.pod b/doc/man3/BIO_s_fd.pod index c9d29bc6..f4f4239f 100644 --- a/doc/man3/BIO_s_fd.pod +++ b/doc/man3/BIO_s_fd.pod @@ -68,7 +68,7 @@ been initialized. BIO_new_fd() returns the newly allocated BIO or NULL is an error occurred. -=head1 EXAMPLE +=head1 EXAMPLES This is a file descriptor BIO version of "Hello World": diff --git a/doc/man3/BIO_s_mem.pod b/doc/man3/BIO_s_mem.pod index 7cb9efa9..69746dc9 100644 --- a/doc/man3/BIO_s_mem.pod +++ b/doc/man3/BIO_s_mem.pod @@ -118,7 +118,19 @@ BIO_FLAGS_NONCLEAR_RST set has the same effect as a write operation. There should be an option to set the maximum size of a memory BIO. -=head1 EXAMPLE +=head1 RETURN VALUES + +BIO_s_mem() and BIO_s_secmem() return a valid memory B structure. + +BIO_set_mem_eof_return(), BIO_set_mem_buf() and BIO_get_mem_ptr() +return 1 on success or a value which is less than or equal to 0 if an error occurred. + +BIO_get_mem_data() returns the total number of bytes available on success, +0 if b is NULL, or a negative value in case of other errors. + +BIO_new_mem_buf() returns a valid B structure on success or NULL on error. + +=head1 EXAMPLES Create a memory BIO and write some data to it: @@ -139,14 +151,6 @@ Extract the BUF_MEM structure from a memory BIO and then free up the BIO: BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */ BIO_free(mem); -=head1 RETURN VALUES - -BIO_s_mem() and BIO_s_secmem() return a valid memory B structure. - -BIO_set_mem_eof_return(), BIO_get_mem_data(), BIO_set_mem_buf() and BIO_get_mem_ptr() -return 1 on success or a value which is less than or equal to 0 if an error occurred. - -BIO_new_mem_buf() returns a valid B structure on success or NULL on error. =head1 COPYRIGHT diff --git a/doc/man3/BIO_set_callback.pod b/doc/man3/BIO_set_callback.pod index a420267a..9537a2e1 100644 --- a/doc/man3/BIO_set_callback.pod +++ b/doc/man3/BIO_set_callback.pod @@ -211,11 +211,6 @@ the actual call parameter, see B. =back -=head1 EXAMPLE - -The BIO_debug_callback() function is a good example, its source is -in crypto/bio/bio_cb.c - =head1 RETURN VALUES BIO_get_callback_ex() and BIO_get_callback() return the callback function @@ -228,6 +223,11 @@ via a call to BIO_set_callback_arg(). BIO_debug_callback() returns 1 or B if it's called after specific BIO operations. +=head1 EXAMPLES + +The BIO_debug_callback() function is a good example, its source is +in crypto/bio/bio_cb.c + =head1 COPYRIGHT Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/BN_generate_prime.pod b/doc/man3/BN_generate_prime.pod index eb5d89a3..6a3376b1 100644 --- a/doc/man3/BN_generate_prime.pod +++ b/doc/man3/BN_generate_prime.pod @@ -2,15 +2,19 @@ =head1 NAME -BN_generate_prime_ex, BN_is_prime_ex, BN_is_prime_fasttest_ex, BN_GENCB_call, -BN_GENCB_new, BN_GENCB_free, BN_GENCB_set_old, BN_GENCB_set, BN_GENCB_get_arg, -BN_generate_prime, BN_is_prime, BN_is_prime_fasttest - generate primes and test -for primality +BN_generate_prime_ex2, BN_generate_prime_ex, BN_is_prime_ex, +BN_is_prime_fasttest_ex, BN_GENCB_call, BN_GENCB_new, BN_GENCB_free, +BN_GENCB_set_old, BN_GENCB_set, BN_GENCB_get_arg, BN_generate_prime, +BN_is_prime, BN_is_prime_fasttest - generate primes and test for primality =head1 SYNOPSIS #include + int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb, + BN_CTX *ctx); + int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb); @@ -50,9 +54,12 @@ L: =head1 DESCRIPTION -BN_generate_prime_ex() generates a pseudo-random prime number of -at least bit length B. The returned number is probably prime -with a negligible error. +BN_generate_prime_ex2() generates a pseudo-random prime number of +at least bit length B using the BN_CTX provided in B. The value of +B must not be NULL. +The returned number is probably prime with a negligible error. +If B is B the returned prime number will have exact bit +length B with the top most two bits set. If B is not B, it will be used to store the number. @@ -89,11 +96,20 @@ If B is not B, the prime will fulfill the condition p % B generator. If B is true, it will be a safe prime (i.e. a prime p so -that (p-1)/2 is also prime). +that (p-1)/2 is also prime). If B is true, and B == B +the condition will be p % B == 3. +It is recommended that B is a multiple of 4. The random generator must be seeded prior to calling BN_generate_prime_ex(). If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to external circumstances (see L), the operation will fail. +The random number generator configured for the OPENSSL_CTX associated with +B will be used. + +BN_generate_prime_ex() is the same as BN_generate_prime_ex2() except that no +B parameter is passed. +In this case the random number generator associated with the default OPENSSL_CTX +will be used. BN_is_prime_ex() and BN_is_prime_fasttest_ex() test if the number B

is prime. The following tests are performed until one of them shows that @@ -206,7 +222,7 @@ and BN_GENCB_get_arg() functions were added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man3/BN_mod_mul_montgomery.pod b/doc/man3/BN_mod_mul_montgomery.pod index bb11c426..5cb2c2c3 100644 --- a/doc/man3/BN_mod_mul_montgomery.pod +++ b/doc/man3/BN_mod_mul_montgomery.pod @@ -64,7 +64,7 @@ BN_MONT_CTX_free() has no return value. For the other functions, 1 is returned for success, 0 on error. The error codes can be obtained by L. -=head1 WARNING +=head1 WARNINGS The inputs must be reduced modulo B, otherwise the result will be outside the expected range. diff --git a/doc/man3/BN_new.pod b/doc/man3/BN_new.pod index e7269e01..7e9da8fe 100644 --- a/doc/man3/BN_new.pod +++ b/doc/man3/BN_new.pod @@ -22,7 +22,7 @@ BN_new, BN_secure_new, BN_clear, BN_free, BN_clear_free - allocate and free BIGN BN_new() allocates and initializes a B structure. BN_secure_new() does the same except that the secure heap -OPENSSL_secure_malloc(3) is used to store the value. +L is used to store the value. BN_clear() is used to destroy sensitive data such as keys when they are no longer needed. It erases the memory used by B and sets it @@ -46,7 +46,7 @@ BN_clear(), BN_free() and BN_clear_free() have no return values. =head1 SEE ALSO -L +L, L =head1 HISTORY diff --git a/doc/man3/CMS_compress.pod b/doc/man3/CMS_compress.pod index 56cf26cd..31248461 100644 --- a/doc/man3/CMS_compress.pod +++ b/doc/man3/CMS_compress.pod @@ -17,8 +17,6 @@ is the compression algorithm to use or B to use the default algorithm (zlib compression). B is the content to be compressed. B is an optional set of flags. -=head1 NOTES - The only currently supported compression algorithm is zlib using the NID NID_zlib_compression. @@ -41,8 +39,6 @@ The compressed data is included in the CMS_ContentInfo structure, unless B is set in which case it is omitted. This is rarely used in practice and is not supported by SMIME_write_CMS(). -=head1 NOTES - If the flag B is set the returned B structure is B complete and outputting its contents via a function that does not properly finalize the B structure will give unpredictable diff --git a/doc/man3/CMS_encrypt.pod b/doc/man3/CMS_encrypt.pod index ff2cf8d2..1bc9fd04 100644 --- a/doc/man3/CMS_encrypt.pod +++ b/doc/man3/CMS_encrypt.pod @@ -17,8 +17,6 @@ CMS_encrypt() creates and returns a CMS EnvelopedData structure. B is a list of recipient certificates. B is the content to be encrypted. B is the symmetric cipher to use. B is an optional set of flags. -=head1 NOTES - Only certificates carrying RSA, Diffie-Hellman or EC keys are supported by this function. @@ -60,8 +58,6 @@ The data being encrypted is included in the CMS_ContentInfo structure, unless B is set in which case it is omitted. This is rarely used in practice and is not supported by SMIME_write_CMS(). -=head1 NOTES - If the flag B is set the returned B structure is B complete and outputting its contents via a function that does not properly finalize the B structure will give unpredictable diff --git a/doc/man3/CRYPTO_THREAD_run_once.pod b/doc/man3/CRYPTO_THREAD_run_once.pod index 8ccd05e5..ab7ff878 100644 --- a/doc/man3/CRYPTO_THREAD_run_once.pod +++ b/doc/man3/CRYPTO_THREAD_run_once.pod @@ -97,7 +97,16 @@ one of the first included headers. Therefore it is defined as an application developer's responsibility to include windows.h prior to crypto.h where use of CRYPTO_THREAD_* types and functions is required. -=head1 EXAMPLE +=head1 EXAMPLES + +You can find out if OpenSSL was configured with thread support: + + #include + #if defined(OPENSSL_THREADS) + /* thread support enabled */ + #else + /* no thread support */ + #endif This example safely initializes and uses a lock. @@ -144,17 +153,6 @@ no longer in use and is unloaded. The simplest solution is to just "leak" the lock in applications and not repeatedly load/unload shared libraries that allocate locks. -=head1 NOTES - -You can find out if OpenSSL was configured with thread support: - - #include - #if defined(OPENSSL_THREADS) - /* thread support enabled */ - #else - /* no thread support */ - #endif - =head1 SEE ALSO L diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod index f37d532b..b0321b09 100644 --- a/doc/man3/CRYPTO_get_ex_new_index.pod +++ b/doc/man3/CRYPTO_get_ex_new_index.pod @@ -162,7 +162,7 @@ dup_func() should return 0 for failure and 1 for success. =head1 HISTORY -CRYPTO_alloc_ex_data() was added in OpenSSL 3.0.0. +CRYPTO_alloc_ex_data() was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/DH_generate_parameters.pod b/doc/man3/DH_generate_parameters.pod index a1541caf..4908dcf5 100644 --- a/doc/man3/DH_generate_parameters.pod +++ b/doc/man3/DH_generate_parameters.pod @@ -73,6 +73,14 @@ The generator B is not suitable. Note that the lack of this bit doesn't guarantee that B is suitable, unless B

is known to be a strong prime. +=item DH_MODULUS_TOO_SMALL + +The modulus is too small. + +=item DH_MODULUS_TOO_LARGE + +The modulus is too large. + =back DH_check() confirms that the Diffie-Hellman parameters B are valid. The @@ -141,7 +149,7 @@ DH_generate_parameters_ex() instead. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man3/ECDSA_SIG_new.pod b/doc/man3/ECDSA_SIG_new.pod index e99a8237..02b4a54f 100644 --- a/doc/man3/ECDSA_SIG_new.pod +++ b/doc/man3/ECDSA_SIG_new.pod @@ -3,10 +3,10 @@ =head1 NAME ECDSA_SIG_get0, ECDSA_SIG_get0_r, ECDSA_SIG_get0_s, ECDSA_SIG_set0, -ECDSA_SIG_new, ECDSA_SIG_free, i2d_ECDSA_SIG, d2i_ECDSA_SIG, ECDSA_size, -ECDSA_sign, ECDSA_do_sign, ECDSA_verify, ECDSA_do_verify, ECDSA_sign_setup, -ECDSA_sign_ex, ECDSA_do_sign_ex - low level elliptic curve digital signature -algorithm (ECDSA) functions +ECDSA_SIG_new, ECDSA_SIG_free, ECDSA_size, ECDSA_sign, ECDSA_do_sign, +ECDSA_verify, ECDSA_do_verify, ECDSA_sign_setup, ECDSA_sign_ex, +ECDSA_do_sign_ex - low level elliptic curve digital signature algorithm (ECDSA) +functions =head1 SYNOPSIS @@ -18,8 +18,6 @@ algorithm (ECDSA) functions const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); - int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); - ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); int ECDSA_size(const EC_KEY *eckey); int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, @@ -68,15 +66,8 @@ function transfers the memory management of the values to the ECDSA_SIG object, and therefore the values that have been passed in should not be freed directly after this function has been called. -i2d_ECDSA_SIG() creates the DER encoding of the ECDSA signature B and -writes the encoded signature to B<*pp> (note: if B is NULL i2d_ECDSA_SIG() -returns the expected length in bytes of the DER encoded signature). -i2d_ECDSA_SIG() returns the length of the DER encoded signature (or 0 on -error). - -d2i_ECDSA_SIG() decodes a DER encoded ECDSA signature and returns the decoded -signature in a newly allocated B structure. B<*sig> points to the -buffer containing the DER encoded signature of size B. +See L and L for information about encoding +and decoding ECDSA signatures to/from DER. ECDSA_size() returns the maximum length of a DER encoded ECDSA signature created with the private EC key B. @@ -202,7 +193,9 @@ ANSI X9.62, US Federal Information Processing Standard FIPS 186-2 L, L, -L +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man3/EC_GROUP_copy.pod b/doc/man3/EC_GROUP_copy.pod index b62eaa95..1a4d7c01 100644 --- a/doc/man3/EC_GROUP_copy.pod +++ b/doc/man3/EC_GROUP_copy.pod @@ -51,7 +51,8 @@ EC_GROUP_get_pentanomial_basis, EC_GROUP_get0_field int EC_GROUP_get_degree(const EC_GROUP *group); int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); - int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only); + int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only, + BN_CTX *ctx); int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); @@ -152,6 +153,8 @@ then this method can be used to lookup the name of the curve that matches the gr aliases, so that multiple NID's can map to the same domain parameters. For such curves it is unspecified which of the aliases will be returned if the curve name of the given group is NID_undef. If B is 1 it will only look for NIST approved curves, otherwise it searches all built-in curves. +This function may be passed a BN_CTX object in the B parameter. +The B parameter may be NULL. EC_GROUP_cmp compares B and B to determine whether they represent the same curve or not. diff --git a/doc/man3/EC_GROUP_new.pod b/doc/man3/EC_GROUP_new.pod index 87c3adaf..6ac8e4aa 100644 --- a/doc/man3/EC_GROUP_new.pod +++ b/doc/man3/EC_GROUP_new.pod @@ -4,6 +4,7 @@ EC_GROUP_get_ecparameters, EC_GROUP_get_ecpkparameters, +EC_GROUP_new_ex, EC_GROUP_new, EC_GROUP_new_from_ecparameters, EC_GROUP_new_from_ecpkparameters, @@ -11,6 +12,7 @@ EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_new_curve_GFp, EC_GROUP_new_curve_GF2m, +EC_GROUP_new_by_curve_name_ex, EC_GROUP_new_by_curve_name, EC_GROUP_set_curve, EC_GROUP_get_curve, @@ -25,6 +27,7 @@ objects #include + EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth); EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) @@ -35,6 +38,7 @@ objects const BIGNUM *b, BN_CTX *ctx); EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid); EC_GROUP *EC_GROUP_new_by_curve_name(int nid); int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, @@ -71,12 +75,18 @@ y^2 + xy = x^3 + ax^2 + b (where b != 0) Operations in a binary field are performed relative to an B. All such curves with OpenSSL use a trinomial or a pentanomial for this parameter. -A new curve can be constructed by calling EC_GROUP_new, using the implementation provided by B (see -L). It is then necessary to call EC_GROUP_set_curve() to set the curve parameters. +A new curve can be constructed by calling EC_GROUP_new_ex, using the implementation provided by B (see +L) and associated with the library context B +(see L). +The B parameter may be NULL in which case the default library context is used. +It is then necessary to call EC_GROUP_set_curve() to set the curve parameters. EC_GROUP_new_from_ecparameters() will create a group from the specified B and EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK B. +EC_GROUP_new is the same as EC_GROUP_new_ex() except that the library context +used is always the default library context. + EC_GROUP_set_curve() sets the curve parameters B

, B and B. For a curve over Fp B is the prime for the field. For a curve over F2^m B

represents the irreducible polynomial - each bit represents a term in the polynomial. Therefore there will either be three or five bits set dependent on whether @@ -109,8 +119,12 @@ The EC_builtin_curve structure is defined as follows: Each EC_builtin_curve item has a unique integer id (B), and a human readable comment string describing the curve. -In order to construct a builtin curve use the function EC_GROUP_new_by_curve_name and provide the B of the curve to -be constructed. +In order to construct a builtin curve use the function EC_GROUP_new_by_curve_name_ex and provide the B of the curve to +be constructed and the associated library context to be used in B (see L). +The B value may be NULL in which case the default library context is used. + +EC_GROUP_new_by_curve_name is the same as EC_GROUP_new_by_curve_name_ex except +that the default library context is always used. EC_GROUP_free frees the memory associated with the EC_GROUP. If B is NULL nothing is done. @@ -130,7 +144,12 @@ EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, EC_GROUP_set_curve_GF2m, EC_GROU L, L, L, L, L, -L, L +L, L, +L + +=head1 HISTORY + +EC_GROUP_new_ex and EC_GROUP_new_by_curve_name_ex were added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EC_KEY_new.pod b/doc/man3/EC_KEY_new.pod index 04ab2d5f..ff4373ea 100644 --- a/doc/man3/EC_KEY_new.pod +++ b/doc/man3/EC_KEY_new.pod @@ -2,10 +2,10 @@ =head1 NAME -EC_KEY_get_method, EC_KEY_set_method, +EC_KEY_get_method, EC_KEY_set_method, EC_KEY_new_ex, EC_KEY_new, EC_KEY_get_flags, EC_KEY_set_flags, EC_KEY_clear_flags, -EC_KEY_new_by_curve_name, EC_KEY_free, EC_KEY_copy, EC_KEY_dup, EC_KEY_up_ref, -EC_KEY_get0_engine, +EC_KEY_new_by_curve_name_ex, EC_KEY_new_by_curve_name, EC_KEY_free, EC_KEY_copy, +EC_KEY_dup, EC_KEY_up_ref, EC_KEY_get0_engine, EC_KEY_get0_group, EC_KEY_set_group, EC_KEY_get0_private_key, EC_KEY_set_private_key, EC_KEY_get0_public_key, EC_KEY_set_public_key, EC_KEY_get_conv_form, @@ -19,10 +19,12 @@ EC_KEY objects #include + EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx); EC_KEY *EC_KEY_new(void); int EC_KEY_get_flags(const EC_KEY *key); void EC_KEY_set_flags(EC_KEY *key, int flags); void EC_KEY_clear_flags(EC_KEY *key, int flags); + EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid); EC_KEY *EC_KEY_new_by_curve_name(int nid); void EC_KEY_free(EC_KEY *key); EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); @@ -57,15 +59,31 @@ EC_KEY objects =head1 DESCRIPTION An EC_KEY represents a public key and, optionally, the associated private -key. A new EC_KEY with no associated curve can be constructed by calling -EC_KEY_new(). The reference count for the newly created EC_KEY is initially -set to 1. A curve can be associated with the EC_KEY by calling +key. +A new EC_KEY with no associated curve can be constructed by calling +EC_KEY_new_ex() and specifying the associated library context in B +(see L). +The B parameter may be NULL in which case the default library context is +used. +The reference count for the newly created EC_KEY is initially +set to 1. +A curve can be associated with the EC_KEY by calling EC_KEY_set_group(). +EC_KEY_new() is the same as EC_KEY_new_ex() except that the default library +context is always used. + Alternatively a new EC_KEY can be constructed by calling -EC_KEY_new_by_curve_name() and supplying the nid of the associated curve. See -L for a description of curve names. This function simply -wraps calls to EC_KEY_new() and EC_GROUP_new_by_curve_name(). +EC_KEY_new_by_curve_name_ex() and supplying the nid of the associated curve and +the library context to be used B (see L). +The B parameter may be NULL in which case the default library context is +used. +See L for a description of curve names. +This function simply wraps calls to EC_KEY_new_ex() and +EC_GROUP_new_by_curve_name_ex(). + +EC_KEY_new_by_curve_name() is the same as EC_KEY_new_by_curve_name_ex() except +that the default library context is always used. Calling EC_KEY_free() decrements the reference count for the EC_KEY object, and if it has dropped to zero then frees the memory associated with it. If @@ -144,8 +162,8 @@ EC_KEY_priv2buf() converts an EC_KEY private key into an allocated buffer. =head1 RETURN VALUES -EC_KEY_new(), EC_KEY_new_by_curve_name() and EC_KEY_dup() return a pointer to -the newly created EC_KEY object, or NULL on error. +EC_KEY_new_ex(), EC_KEY_new(), EC_KEY_new_by_curve_name() and EC_KEY_dup() +return a pointer to the newly created EC_KEY object, or NULL on error. EC_KEY_get_flags() returns the flags associated with the EC_KEY object as an integer. @@ -174,7 +192,8 @@ L, L, L, L, L, L, -L +L, +L =head1 COPYRIGHT diff --git a/doc/man3/ERR_GET_LIB.pod b/doc/man3/ERR_GET_LIB.pod index 6f14a09d..20461590 100644 --- a/doc/man3/ERR_GET_LIB.pod +++ b/doc/man3/ERR_GET_LIB.pod @@ -38,12 +38,13 @@ unique. However, when checking for sub-library specific reason codes, be sure to also compare the library number. ERR_GET_LIB(), ERR_GET_FUNC(), ERR_GET_REASON(), and ERR_FATAL_ERROR() - are macros. +are macros. =head1 RETURN VALUES The library number, function code, reason code, and whether the error is fatal, respectively. +Starting with OpenSSL 3.0.0, the function code is always set to zero. =head1 SEE ALSO diff --git a/doc/man3/ERR_error_string.pod b/doc/man3/ERR_error_string.pod index d46d0c39..42b19217 100644 --- a/doc/man3/ERR_error_string.pod +++ b/doc/man3/ERR_error_string.pod @@ -14,9 +14,12 @@ error message void ERR_error_string_n(unsigned long e, char *buf, size_t len); const char *ERR_lib_error_string(unsigned long e); - const char *ERR_func_error_string(unsigned long e); const char *ERR_reason_error_string(unsigned long e); +Deprecated in OpenSSL 3.0: + + const char *ERR_func_error_string(unsigned long e); + =head1 DESCRIPTION ERR_error_string() generates a human-readable string representing the @@ -33,13 +36,12 @@ For ERR_error_string_n(), I may not be B. The string will have the following format: - error:[error code]:[library name]:[function name]:[reason string] + error:[error code]:[library name]::[reason string] -I is an 8 digit hexadecimal number, I, -I and I are ASCII text. +I is an 8 digit hexadecimal number, I and +I are ASCII text. -ERR_lib_error_string(), ERR_func_error_string() and -ERR_reason_error_string() return the library name, function +ERR_lib_error_string() and ERR_reason_error_string() return the library name and reason string respectively. If there is no text string registered for the given error code, @@ -53,15 +55,20 @@ all error codes currently in the queue. ERR_error_string() returns a pointer to a static buffer containing the string if I B<== NULL>, I otherwise. -ERR_lib_error_string(), ERR_func_error_string() and -ERR_reason_error_string() return the strings, and B if -none is registered for the error code. +ERR_lib_error_string() and ERR_reason_error_string() return the strings, +and B if none is registered for the error code. + +ERR_func_error_string() returns NULL. =head1 SEE ALSO L, L +=head1 HISTORY + +ERR_func_error_string() became deprecated in OpenSSL 3.0. + =head1 COPYRIGHT Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/ERR_get_error.pod b/doc/man3/ERR_get_error.pod index c3fab39c..045ef210 100644 --- a/doc/man3/ERR_get_error.pod +++ b/doc/man3/ERR_get_error.pod @@ -4,8 +4,11 @@ ERR_get_error, ERR_peek_error, ERR_peek_last_error, ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line, -ERR_get_error_line_data, ERR_peek_error_line_data, -ERR_peek_last_error_line_data - obtain error code and data +ERR_get_error_func, ERR_peek_error_func, ERR_peek_last_error_func, +ERR_get_error_data, ERR_peek_error_data, ERR_peek_last_error_data, +ERR_get_error_all, ERR_peek_error_all, ERR_peek_last_error_all, +ERR_get_error_line_data, ERR_peek_error_line_data, ERR_peek_last_error_line_data +- obtain error code and data =head1 SYNOPSIS @@ -19,6 +22,26 @@ ERR_peek_last_error_line_data - obtain error code and data unsigned long ERR_peek_error_line(const char **file, int *line); unsigned long ERR_peek_last_error_line(const char **file, int *line); + unsigned long ERR_get_error_func(const char **func); + unsigned long ERR_peek_error_func(const char **func); + unsigned long ERR_peek_last_error_func(const char **func); + + unsigned long ERR_get_error_data(const char **data, int *flags); + unsigned long ERR_peek_error_data(const char **data, int *flags); + unsigned long ERR_peek_last_error_data(const char **data, int *flags); + + unsigned long ERR_get_error_all(const char **file, int *line, + const char *func, + const char **data, int *flags); + unsigned long ERR_peek_error_all(const char **file, int *line, + const char *func, + const char **data, int *flags); + unsigned long ERR_peek_last_error_all(const char **file, int *line, + const char *func, + const char **data, int *flags); + +Deprecated since OpenSSL 3.0: + unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags); unsigned long ERR_peek_error_line_data(const char **file, int *line, @@ -44,15 +67,31 @@ L for human-readable error messages. ERR_get_error_line(), ERR_peek_error_line() and -ERR_peek_last_error_line() are the same as the above, but they +ERR_peek_last_error_line() are the same as ERR_get_error(), +ERR_peek_error() and ERR_peek_last_error(), but they additionally store the file name and line number where the error occurred in *B and *B, unless these are B. +ERR_get_error_func(), ERR_peek_error_func() and +ERR_peek_last_error_func() are the same as ERR_get_error(), +ERR_peek_error() and ERR_peek_last_error(), but they +additionally store the name of the function where the error in *B, +unless it is B. + +ERR_get_error_data(), ERR_peek_error_data() and +ERR_peek_last_error_data() are the same as ERR_get_error(), +ERR_peek_error() and ERR_peek_last_error(), but they +additionally store additional data and flags associated with the error +code in *B and *B, unless these are B. +*B contains a string if *B&B is true. + +ERR_get_error_all(), ERR_peek_error_all() and +ERR_peek_last_error_all() are combinations of all of the above. + ERR_get_error_line_data(), ERR_peek_error_line_data() and -ERR_peek_last_error_line_data() store additional data and flags -associated with the error code in *B -and *B, unless these are B. *B contains a string -if *B&B is true. +ERR_peek_last_error_line_data() are older variants of ERR_get_error_all(), +ERR_peek_error_all() and ERR_peek_last_error_all(), and should no longer +be used. An application B free the *B pointer (or any other pointers returned by these functions) with OPENSSL_free() as freeing is handled @@ -67,6 +106,17 @@ The error code, or 0 if there is no error in the queue. L, L +=head1 HISTORY + +ERR_get_error_func(), ERR_peek_error_func(), ERR_peek_last_error_func(), +ERR_get_error_data(), ERR_peek_error_data(), ERR_peek_last_error_data(), +ERR_get_error_all(), ERR_peek_error_all() and ERR_peek_last_error_all() +were added in OpenSSL 3.0. + +ERR_get_error_line_data(), ERR_peek_error_line_data() and +ERR_peek_last_error_line_data() became deprecated in OpenSSL 3.0. + + =head1 COPYRIGHT Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/ERR_new.pod b/doc/man3/ERR_new.pod new file mode 100644 index 00000000..80419da2 --- /dev/null +++ b/doc/man3/ERR_new.pod @@ -0,0 +1,78 @@ +=pod + +=head1 NAME + +ERR_new, ERR_set_debug, ERR_set_error, ERR_vset_error +- Error recording building blocks + +=head1 SYNOPSIS + + #include + + void ERR_new(void); + void ERR_set_debug(const char *file, int line, const char *func); + void ERR_set_error(int lib, int reason, const char *fmt, ...); + void ERR_vset_error(int lib, int reason, const char *fmt, va_list args); + +=head1 DESCRIPTION + +The functions described here are generally not used directly, but +rather through macros such as L. +They can still be useful for anyone that wants to make their own +macros. + +ERR_new() allocates a new slot in the thread's error queue. + +ERR_set_debug() sets the debug information related to the current +error in the thread's error queue. +The values that can be given are the file name I, line in the +file I and the name of the function I where the error +occured. +The names must be constant, this function will only save away the +pointers, not copy the strings. + +ERR_set_error() sets the error information, which are the library +number I and the reason code I, and additional data as a +format string I and an arbitrary number of arguments. +The additional data is processed with L to form the +additional data string, which is allocated and store in the error +record. + +ERR_vset_error() works like ERR_set_error(), but takes a B +argument instead of a variable number of arguments. + +=head1 RETURN VALUES + +ERR_new, ERR_set_debug, ERR_set_error and ERR_vset_error +do not return any values. + +=head1 NOTES + +The library number is unique to each unit that records errors. +OpenSSL has a number of pre-allocated ones for its own uses, but +others may allocate their own library number dynamically with +L. + +Reason codes are unique within each library, and may have an +associated set of strings as a short description of the reason. +For dynamically allocated library numbers, reason strings are recorded +with L. + +Provider authors are supplied with core versions of these functions, +see L. + +=head1 SEE ALSO + +L, L, +L, L, L + +=head1 COPYRIGHT + +Copyright 2000-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/man3/ERR_put_error.pod b/doc/man3/ERR_put_error.pod index 31a0e76f..729eb574 100644 --- a/doc/man3/ERR_put_error.pod +++ b/doc/man3/ERR_put_error.pod @@ -2,19 +2,36 @@ =head1 NAME -ERR_put_error, ERR_add_error_data, ERR_add_error_vdata - record an error +ERR_raise, ERR_raise_data, +ERR_put_error, ERR_add_error_data, ERR_add_error_vdata +- record an error =head1 SYNOPSIS #include - void ERR_put_error(int lib, int func, int reason, const char *file, int line); + void ERR_raise(int lib, int reason); + void ERR_raise_data(int lib, int reason, const char *fmt, ...); void ERR_add_error_data(int num, ...); void ERR_add_error_vdata(int num, va_list arg); +Deprecated since OpenSSL 3.0: + + void ERR_put_error(int lib, int func, int reason, const char *file, int line); + =head1 DESCRIPTION +ERR_raise() adds a new error to the thread's error queue. The +error occured in the library B for the reason given by the +B code. Furthermore, the name of the file, the line, and name +of the function where the error occured is saved with the error +record. + +ERR_raise_data() does the same thing as ERR_raise(), but also lets the +caller specify additional information as a format string B and an +arbitrary number of values, which are processed with L. + ERR_put_error() adds an error code to the thread's error queue. It signals that the error of reason code B occurred in function B of library B, in line number B of B. @@ -31,6 +48,8 @@ error messages for the error code. =head2 Reporting errors +=for comment TODO(3.0) should this be internal documentation? + Each sub-library has a specific macro XXXerr() that is used to report errors. Its first argument is a function code B, the second argument is a reason code B. Function codes are derived @@ -57,8 +76,12 @@ the ASN1err() macro. =head1 RETURN VALUES -ERR_put_error() and ERR_add_error_data() return -no values. +ERR_raise(), ERR_put_error(), ERR_add_error_data() and +ERR_add_error_vdata() return no values. + +=head1 NOTES + +ERR_raise() and ERR_put_error() are implemented as macros. =head1 SEE ALSO @@ -66,7 +89,7 @@ L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-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 diff --git a/doc/man3/EVP_CIPHER_meth_new.pod b/doc/man3/EVP_CIPHER_meth_new.pod index 3d4da9c0..8a6a4b99 100644 --- a/doc/man3/EVP_CIPHER_meth_new.pod +++ b/doc/man3/EVP_CIPHER_meth_new.pod @@ -10,7 +10,7 @@ EVP_CIPHER_meth_set_set_asn1_params, EVP_CIPHER_meth_set_get_asn1_params, EVP_CIPHER_meth_set_ctrl, EVP_CIPHER_meth_get_init, EVP_CIPHER_meth_get_do_cipher, EVP_CIPHER_meth_get_cleanup, EVP_CIPHER_meth_get_set_asn1_params, EVP_CIPHER_meth_get_get_asn1_params, -EVP_CIPHER_meth_get_ctrl, EVP_CIPHER_up_ref +EVP_CIPHER_meth_get_ctrl - Routines to build up EVP_CIPHER methods =head1 SYNOPSIS @@ -63,8 +63,6 @@ EVP_CIPHER_meth_get_ctrl, EVP_CIPHER_up_ref int type, int arg, void *ptr); - int EVP_CIPHER_up_ref(EVP_CIPHER *cipher); - =head1 DESCRIPTION The B type is a structure for symmetric cipher method @@ -226,8 +224,6 @@ EVP_CIPHER_meth_get_get_asn1_params() and EVP_CIPHER_meth_get_ctrl() are all used to retrieve the method data given with the EVP_CIPHER_meth_set_*() functions above. -EVP_CIPHER_up_ref() increments the reference count for an EVP_CIPHER structure. - =head1 RETURN VALUES EVP_CIPHER_meth_new() and EVP_CIPHER_meth_dup() return a pointer to a @@ -236,8 +232,6 @@ All EVP_CIPHER_meth_set_*() functions return 1. All EVP_CIPHER_meth_get_*() functions return pointers to their respective B function. -EVP_CIPHER_up_ref() returns 1 for success or 0 otherwise. - =head1 SEE ALSO L @@ -245,6 +239,8 @@ L =head1 HISTORY The functions described here were added in OpenSSL 1.1.0. +The B structure created with these functions became reference +counted in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod index bc10fa36..69a52d10 100644 --- a/doc/man3/EVP_DigestInit.pod +++ b/doc/man3/EVP_DigestInit.pod @@ -2,28 +2,44 @@ =head1 NAME +EVP_MD_fetch, EVP_MD_up_ref, EVP_MD_free, +EVP_MD_get_params, EVP_MD_gettable_params, EVP_MD_CTX_new, EVP_MD_CTX_reset, EVP_MD_CTX_free, EVP_MD_CTX_copy, -EVP_MD_CTX_copy_ex, EVP_MD_CTX_ctrl, EVP_MD_CTX_set_params, EVP_MD_CTX_get_params, +EVP_MD_CTX_copy_ex, EVP_MD_CTX_ctrl, +EVP_MD_CTX_set_params, EVP_MD_CTX_get_params, +EVP_MD_CTX_settable_params, EVP_MD_CTX_gettable_params, EVP_MD_CTX_set_flags, EVP_MD_CTX_clear_flags, EVP_MD_CTX_test_flags, EVP_Digest, EVP_DigestInit_ex, EVP_DigestInit, EVP_DigestUpdate, EVP_DigestFinal_ex, EVP_DigestFinalXOF, EVP_DigestFinal, +EVP_MD_name, EVP_MD_provider, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size, EVP_MD_block_size, EVP_MD_flags, +EVP_MD_CTX_name, EVP_MD_CTX_md, EVP_MD_CTX_type, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_md_data, EVP_MD_CTX_update_fn, EVP_MD_CTX_set_update_fn, EVP_md_null, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj, -EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx - EVP digest routines +EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx, +EVP_MD_do_all_ex +- EVP digest routines =head1 SYNOPSIS #include + EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties); + int EVP_MD_up_ref(EVP_MD *md); + void EVP_MD_free(EVP_MD *md); + int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest); EVP_MD_CTX *EVP_MD_CTX_new(void); int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); void EVP_MD_CTX_free(EVP_MD_CTX *ctx); void EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void* p2); int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]); int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MD_CTX_settable_params(const EVP_MD *digest); + const OSSL_PARAM *EVP_MD_CTX_gettable_params(const EVP_MD *digest); void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); @@ -42,6 +58,8 @@ EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx - EVP digest routines int EVP_MD_CTX_copy(EVP_MD_CTX *out, EVP_MD_CTX *in); + const char *EVP_MD_name(const EVP_MD *md); + const OSSL_PROVIDER *EVP_MD_provider(const EVP_MD *md); int EVP_MD_type(const EVP_MD *md); int EVP_MD_pkey_type(const EVP_MD *md); int EVP_MD_size(const EVP_MD *md); @@ -49,6 +67,7 @@ EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx - EVP digest routines unsigned long EVP_MD_flags(const EVP_MD *md); const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); + const char *EVP_MD_CTX_name(const EVP_MD_CTX *ctx); int EVP_MD_CTX_size(const EVP_MD *ctx); int EVP_MD_CTX_block_size(const EVP_MD *ctx); int EVP_MD_CTX_type(const EVP_MD *ctx); @@ -68,13 +87,38 @@ EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx - EVP digest routines EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); + void EVP_MD_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_MD *mac, void *arg), + void *arg); + =head1 DESCRIPTION The EVP digest routines are a high level interface to message digests, -and should be used instead of the cipher-specific functions. +and should be used instead of the digest-specific functions. + +The B type is a structure for digest method implementation. =over 4 +=item EVP_MD_fetch() + +Fetches the digest implementation for the given B from any +provider offering it, within the criteria given by the B. +See L for further information. + +The returned value must eventually be freed with EVP_MD_free(). + +Fetched B structures are reference counted. + +=item EVP_MD_up_ref() + +Increments the reference count for an B structure. + +=item EVP_MD_free() + +Decrements the reference count for the fetched B structure. +If the reference count drops to 0 then the structure is freed. + =item EVP_MD_CTX_new() Allocates and returns a digest context. @@ -99,15 +143,28 @@ EVP_MD_CTX_ctrl() must be called after EVP_DigestInit_ex(). Other restrictions may apply depending on the control type and digest implementation. See L below for more information. -=item EVP_MD_CTX_get_params +=item EVP_MD_get_params() + +Retrieves the requested list of B from a MD B. +See L below for more information. + +=item EVP_MD_CTX_get_params() Retrieves the requested list of B from a MD context B. -See L below for more information. +See L below for more information. -=item EVP_MD_CTX_set_params +=item EVP_MD_CTX_set_params() -Sets the list of into a MD context B. -See L below for more information. +Sets the list of B into a MD context B. +See L below for more information. + +=item EVP_MD_gettable_params(), EVP_MD_CTX_gettable_params(), +EVP_MD_CTX_settable_params() + +Get a B array that describes the retrievable and settable +parameters, i.e. parameters that can be used with EVP_MD_get_params(), +EVP_MD_CTX_get_params() and EVP_MD_CTX_set_params(), respectively. +See L for the use of B as parameter descriptor. =item EVP_MD_CTX_set_flags(), EVP_MD_CTX_clear_flags(), EVP_MD_CTX_test_flags() @@ -123,9 +180,12 @@ If B is NULL the default implementation of digest B is used. =item EVP_DigestInit_ex() -Sets up digest context B to use a digest B from ENGINE B. -B will typically be supplied by a function such as EVP_sha1(). If -B is NULL then the default implementation of digest B is used. +Sets up digest context B to use a digest B. +B is typically supplied by a function such as EVP_sha1(), or a +value explicitly fetched with EVP_MD_fetch(). + +If B is non-NULL, its implementation of the digest B is used if +there is one, and if not, the default implementation is used. =item EVP_DigestUpdate() @@ -170,6 +230,16 @@ automatically cleaned up. Similar to EVP_MD_CTX_copy_ex() except the destination B does not have to be initialized. +=item EVP_MD_name(), +EVP_MD_CTX_name() + +Return the name of the given message digest. + +=item EVP_MD_provider() + +Returns an B pointer to the provider that implements the given +B. + =item EVP_MD_size(), EVP_MD_CTX_size() @@ -252,9 +322,16 @@ by the caller. A NULL B pointer is also allowed to clear the B. In such case, freeing the cleared B or not depends on how the B is created. +=item EVP_MD_do_all_ex() + +Traverses all messages digests implemented by all activated providers +in the given library context I, and for each of the implementations, +calls the given function I with the implementation method and the given +I as argument. + =back -=head1 PARAMS +=head1 PARAMETERS See L for information about passing parameters. @@ -262,12 +339,13 @@ EVP_MD_CTX_set_params() can be used with the following OSSL_PARAM keys: =over 4 -=item OSSL_PARAM_DIGEST_KEY_XOFLEN +=item OSSL_PARAM_DIGEST_KEY_XOFLEN Sets the digest length for extendable output functions. -It is used by the SHAKE algorithm. +It is used by the SHAKE algorithm and should not exceed what can be given +using a B. -=item OSSL_PARAM_DIGEST_KEY_PAD_TYPE +=item OSSL_PARAM_DIGEST_KEY_PAD_TYPE Sets the pad type. It is used by the MDC2 algorithm. @@ -278,7 +356,7 @@ EVP_MD_CTX_get_params() can be used with the following OSSL_PARAM keys: =over 4 -=item OSSL_PARAM_DIGEST_KEY_MICALG . +=item OSSL_PARAM_DIGEST_KEY_MICALG . Gets the digest Message Integrity Check algorithm string. This is used when creating S/MIME multipart/signed messages, as specified in RFC 3851. @@ -343,6 +421,14 @@ disabled with this flag. =over 4 +=item EVP_MD_fetch() + +Returns a pointer to a B for success or NULL for failure. + +=item EVP_MD_up_ref() + +Returns 1 for success or 0 for failure. + =item EVP_DigestInit_ex(), EVP_DigestUpdate(), EVP_DigestFinal_ex() @@ -359,6 +445,12 @@ EVP_MD_CTX_get_params() Returns 1 if successful or 0 for failure. +=item EVP_MD_CTX_settable_params(), +EVP_MD_CTX_gettable_params() + +Return an array of constant Bs, or NULL if there is none +to get. + =item EVP_MD_CTX_copy_ex() Returns 1 if successful or 0 for failure. @@ -415,14 +507,14 @@ implementations of digests to be specified. If digest contexts are not cleaned up after use, memory leaks will occur. -EVP_MD_CTX_size(), EVP_MD_CTX_block_size(), EVP_MD_CTX_type(), -EVP_get_digestbynid() and EVP_get_digestbyobj() are defined as -macros. +EVP_MD_CTX_name(), EVP_MD_CTX_size(), EVP_MD_CTX_block_size(), +EVP_MD_CTX_type(), EVP_get_digestbynid() and EVP_get_digestbyobj() are defined +as macros. EVP_MD_CTX_ctrl() sends commands to message digests for additional configuration or control. -=head1 EXAMPLE +=head1 EXAMPLES This example digests the data "Test Message\n" and "Hello World\n", using the digest name passed on the command line. @@ -487,6 +579,7 @@ L, L, L, L +L =head1 HISTORY @@ -500,8 +593,8 @@ The EVP_dss1() function was removed in OpenSSL 1.1.0. The EVP_MD_CTX_set_pkey_ctx() function was added in 1.1.1. -The EVP_MD_CTX_set_params() and EVP_MD_CTX_get_params() functions were -added in 3.0. +The EVP_MD_fetch(), EVP_MD_free(), EVP_MD_up_ref(), EVP_MD_CTX_set_params() +and EVP_MD_CTX_get_params() functions were added in 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod index 3c2e36bb..a2ccc6f3 100644 --- a/doc/man3/EVP_EncryptInit.pod +++ b/doc/man3/EVP_EncryptInit.pod @@ -2,6 +2,9 @@ =head1 NAME +EVP_CIPHER_fetch, +EVP_CIPHER_up_ref, +EVP_CIPHER_free, EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX_free, @@ -25,7 +28,12 @@ EVP_CipherFinal, EVP_get_cipherbyname, EVP_get_cipherbynid, EVP_get_cipherbyobj, +EVP_CIPHER_is_a, +EVP_CIPHER_name, +EVP_CIPHER_provider, EVP_CIPHER_nid, +EVP_CIPHER_get_params, +EVP_CIPHER_gettable_params, EVP_CIPHER_block_size, EVP_CIPHER_key_length, EVP_CIPHER_iv_length, @@ -33,10 +41,16 @@ EVP_CIPHER_flags, EVP_CIPHER_mode, EVP_CIPHER_type, EVP_CIPHER_CTX_cipher, +EVP_CIPHER_CTX_name, EVP_CIPHER_CTX_nid, +EVP_CIPHER_CTX_get_params, +EVP_CIPHER_CTX_gettable_params, +EVP_CIPHER_CTX_set_params, +EVP_CIPHER_CTX_settable_params, EVP_CIPHER_CTX_block_size, EVP_CIPHER_CTX_key_length, EVP_CIPHER_CTX_iv_length, +EVP_CIPHER_CTX_tag_length, EVP_CIPHER_CTX_get_app_data, EVP_CIPHER_CTX_set_app_data, EVP_CIPHER_CTX_type, @@ -45,7 +59,8 @@ EVP_CIPHER_CTX_mode, EVP_CIPHER_param_to_asn1, EVP_CIPHER_asn1_to_param, EVP_CIPHER_CTX_set_padding, -EVP_enc_null +EVP_enc_null, +EVP_CIPHER_do_all_ex - EVP cipher routines =head1 SYNOPSIS @@ -54,6 +69,10 @@ EVP_enc_null #include + EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties); + int EVP_CIPHER_up_ref(EVP_CIPHER *cipher); + void EVP_CIPHER_free(EVP_CIPHER *cipher); EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); @@ -98,6 +117,9 @@ EVP_enc_null const EVP_CIPHER *EVP_get_cipherbyobj(const ASN1_OBJECT *a); int EVP_CIPHER_nid(const EVP_CIPHER *e); + int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name); + const char *EVP_CIPHER_name(const EVP_CIPHER *cipher); + const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher); int EVP_CIPHER_block_size(const EVP_CIPHER *e); int EVP_CIPHER_key_length(const EVP_CIPHER *e); int EVP_CIPHER_iv_length(const EVP_CIPHER *e); @@ -107,9 +129,18 @@ EVP_enc_null const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); + const char *EVP_CIPHER_CTX_name(const EVP_CIPHER_CTX *ctx); + + int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[]); + int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]); + int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher); + const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(const EVP_CIPHER *cipher); + const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(const EVP_CIPHER *cipher); int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx); void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); void EVP_CIPHER_CTX_set_app_data(const EVP_CIPHER_CTX *ctx, void *data); int EVP_CIPHER_CTX_type(const EVP_CIPHER_CTX *ctx); @@ -118,11 +149,31 @@ EVP_enc_null int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + void EVP_CIPHER_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_CIPHER *cipher, void *arg), + void *arg); + =head1 DESCRIPTION The EVP cipher routines are a high level interface to certain symmetric ciphers. +The B type is a structure for cipher method implementation. + +EVP_CIPHER_fetch() fetches the cipher implementation for the given +B from any provider offering it, within the criteria given +by the B. +See L for further information. + +The returned value must eventually be freed with EVP_CIPHER_free(). + +EVP_CIPHER_up_ref() increments the reference count for an B +structure. + +EVP_CIPHER_free() decrements the reference count for the B +structure. +If the reference count drops to 0 then the structure is freed. + EVP_CIPHER_CTX_new() creates a cipher context. EVP_CIPHER_CTX_free() clears all information from a cipher context @@ -132,16 +183,19 @@ cipher are complete so sensitive information does not remain in memory. EVP_EncryptInit_ex() sets up cipher context B for encryption -with cipher B from ENGINE B. B must be created -before calling this function. B is normally supplied -by a function such as EVP_aes_256_cbc(). If B is NULL then the -default implementation is used. B is the symmetric key to use +with cipher B. B is typically supplied by a function such +as EVP_aes_256_cbc(), or a value explicitly fetched with +EVP_CIPHER_fetch(). If B is non-NULL, its implementation of the +cipher B is used if there is one, and if not, the default +implementation is used. B is the symmetric key to use and B is the IV to use (if necessary), the actual number of bytes used for the key and IV depends on the cipher. It is possible to set all parameters to NULL except B in an initial call and supply the remaining parameters in subsequent calls, all of which have B set to NULL. This is done when the default cipher parameters are not appropriate. +For EVP_CIPH_GCM_MODE the IV will be generated internally if it is not +specified. EVP_EncryptUpdate() encrypts B bytes from the buffer B and writes the encrypted version to B. This function can be called @@ -215,6 +269,22 @@ decrypting. If the B parameter is zero then no padding is performed, the total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur. +EVP_CIPHER_get_params() retrieves the requested list of algorithm +B from a B. + +EVP_CIPHER_CTX_set_params() Sets the list of operation B into a CIPHER +context B. + +EVP_CIPHER_CTX_get_params() retrieves the requested list of operation +B from CIPHER context B. + +EVP_CIPHER_gettable_params(), EVP_CIPHER_CTX_gettable_params(), and +EVP_CIPHER_CTX_settable_params() get a constant B array +that decribes the retrievable and settable parameters, i.e. parameters +that can be used with EVP_CIPHER_get_params(), EVP_CIPHER_CTX_get_params() +and EVP_CIPHER_CTX_set_params(), respectively. +See L for the use of B as parameter descriptor. + EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key length of a cipher when passed an B or B structure. The constant B is the maximum key length @@ -231,6 +301,10 @@ length of a cipher when passed an B or B. It will return zero if the cipher does not use an IV. The constant B is the maximum IV length for all ciphers. +EVP_CIPHER_CTX_tag_length() returns the tag length of a AEAD cipher when passed +a B. It will return zero if the cipher does not support a tag. +It returns a default value if the tag length has not been set. + EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block size of a cipher when passed an B or B structure. The constant B is also the maximum block @@ -243,14 +317,26 @@ IDENTIFIER as such it ignores the cipher parameters and 40 bit RC2 and identifier or does not have ASN1 support this function will return B. +EVP_CIPHER_is_a() returns 1 if the given I is an implementation of an +algorithm that's identifiable with I, otherwise 0. + +EVP_CIPHER_name() and EVP_CIPHER_CTX_name() return the name of the passed +cipher or context. + +EVP_CIPHER_provider() returns an B pointer to the provider +that implements the given B. + EVP_CIPHER_CTX_cipher() returns the B structure when passed an B structure. EVP_CIPHER_mode() and EVP_CIPHER_CTX_mode() return the block cipher mode: EVP_CIPH_ECB_MODE, EVP_CIPH_CBC_MODE, EVP_CIPH_CFB_MODE, EVP_CIPH_OFB_MODE, EVP_CIPH_CTR_MODE, EVP_CIPH_GCM_MODE, EVP_CIPH_CCM_MODE, EVP_CIPH_XTS_MODE, -EVP_CIPH_WRAP_MODE or EVP_CIPH_OCB_MODE. If the cipher is a stream cipher then -EVP_CIPH_STREAM_CIPHER is returned. +EVP_CIPH_WRAP_MODE, EVP_CIPH_OCB_MODE or EVP_CIPH_SIV_MODE. If the cipher is a +stream cipher then EVP_CIPH_STREAM_CIPHER is returned. + +EVP_CIPHER_flags() returns any flags associated with the cipher. See +EVP_CIPHER_meth_set_flags() for a list of currently defined flags. EVP_CIPHER_param_to_asn1() sets the AlgorithmIdentifier "parameter" based on the passed cipher. This will typically include any parameters and an @@ -278,8 +364,18 @@ based on the cipher context. The EVP_CIPHER can provide its own random key generation routine to support keys of a specific form. B must point to a buffer at least as big as the value returned by EVP_CIPHER_CTX_key_length(). +EVP_CIPHER_do_all_ex() traverses all ciphers implemented by all activated +providers in the given library context I, and for each of the +implementations, calls the given function I with the implementation method +and the given I as argument. + =head1 RETURN VALUES +EVP_CIPHER_fetch() returns a pointer to a B for success +and B for failure. + +EVP_CIPHER_up_ref() returns 1 for success or 0 otherwise. + EVP_CIPHER_CTX_new() returns a pointer to a newly created B for success and B for failure. @@ -310,6 +406,9 @@ EVP_CIPHER_CTX_set_padding() always returns 1. EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV length or zero if the cipher does not use an IV. +EVP_CIPHER_CTX_tag_length() return the tag length or zero if the cipher does not +use a tag. + EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the NID of the cipher's OBJECT IDENTIFIER or NID_undef if it has no defined OBJECT IDENTIFIER. @@ -335,7 +434,7 @@ Null cipher: does nothing. =back -=head1 AEAD Interface +=head1 AEAD INTERFACE The EVP interface for Authenticated Encryption with Associated Data (AEAD) modes are subtly altered and several additional I operations are supported @@ -414,7 +513,7 @@ the length of the tag (with the C parameter set to NULL) when encrypting. The tag length is often referred to as B. If not set a default value is used (12 for AES). When decrypting, the tag needs to be set before passing in data to be decrypted, but as in GCM and OCB mode, it can be set after -passing additional authenticated data (see L). +passing additional authenticated data (see L). =item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, ivlen, NULL) @@ -686,6 +785,10 @@ EVP_CIPHER_CTX_reset() appeared and EVP_CIPHER_CTX_cleanup() disappeared. EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset(). +The EVP_CIPHER_fetch(), EVP_CIPHER_free(), EVP_CIPHER_up_ref(), +EVP_CIPHER_CTX_set_params() and EVP_CIPHER_CTX_get_params() functions +were added in 3.0. + =head1 COPYRIGHT Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/EVP_KDF.pod b/doc/man3/EVP_KDF.pod new file mode 100644 index 00000000..9b88baad --- /dev/null +++ b/doc/man3/EVP_KDF.pod @@ -0,0 +1,265 @@ +=pod + +=head1 NAME + +EVP_KDF, EVP_KDF_fetch, EVP_KDF_free, EVP_KDF_provider, EVP_KDF_up_ref, +EVP_KDF_name, +EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_free, EVP_KDF_CTX_kdf, +EVP_KDF_reset, EVP_KDF_size, EVP_KDF_derive, EVP_KDF_CTX_dup, +EVP_KDF_CTX_get_params, EVP_KDF_CTX_set_params, EVP_KDF_do_all_ex, +EVP_KDF_get_params, EVP_KDF_CTX_gettable_params, EVP_KDF_CTX_settable_params, +EVP_KDF_gettable_params - EVP KDF routines + +=head1 SYNOPSIS + + #include + + typedef struct evp_kdf_st EVP_KDF; + typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + + EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf); + const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); + void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src); + void EVP_KDF_reset(EVP_KDF_CTX *ctx); + size_t EVP_KDF_size(EVP_KDF_CTX *ctx); + int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); + const char *EVP_KDF_name(const EVP_KDF *kdf); + int EVP_KDF_up_ref(EVP_KDF *kdf); + void EVP_KDF_free(EVP_KDF *kdf); + EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); + void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_KDF *kdf, void *arg), + void *arg); + int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]); + int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); + int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf); + const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf); + const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf); + const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf); + +=head1 DESCRIPTION + +The EVP KDF routines are a high level interface to Key Derivation Function +algorithms and should be used instead of algorithm-specific functions. + +After creating a B for the required algorithm using +EVP_KDF_CTX_new(), inputs to the algorithm are supplied +using calls to EVP_KDF_CTX_set_params() before +calling EVP_KDF_derive() to derive the key. + +=head2 Types + +B is a type that holds the implementation of a KDF. + +B is a context type that holds the algorithm inputs. + +=head2 Algorithm implementation fetching + +EVP_KDF_fetch() fetches an implementation of a KDF I, given +a library context I and a set of I. +See L for further information. + +The returned value must eventually be freed with +L. + +EVP_KDF_up_ref() increments the reference count of an already fetched +KDF. + +EVP_KDF_free() frees a fetched algorithm. +NULL is a valid parameter, for which this function is a no-op. + +=head2 Context manipulation functions + +EVP_KDF_CTX_new() creates a new context for the KDF implementation I. + +EVP_KDF_CTX_free() frees up the context C. If I is NULL, nothing +is done. + +EVP_KDF_CTX_kdf() returns the B associated with the context +I. + +=head2 Computing functions + +EVP_KDF_reset() resets the context to the default state as if the context +had just been created. + +EVP_KDF_derive() derives C bytes of key material and places it in the +I buffer. If the algorithm produces a fixed amount of output then an +error will occur unless the C parameter is equal to that output size, +as returned by EVP_KDF_size(). + +EVP_KDF_get_params() retrieves details about the implementation +I. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. + +EVP_KDF_CTX_get_params() retrieves chosen parameters, given the +context I and its underlying context. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. + +EVP_KDF_CTX_set_params() passes chosen parameters to the underlying +context, given a context I. +The set of parameters given with I determine exactly what +parameters are passed down. +Note that a parameter that is unknown in the underlying context is +simply ignored. +Also, what happens when a needed parameter isn't passed down is +defined by the implementation. + +EVP_KDF_gettable_params(), EVP_KDF_CTX_gettable_params() and +EVP_KDF_CTX_settable_params() get a constant B array that +decribes the retrievable and settable parameters, i.e. parameters that +can be used with EVP_KDF_get_params(), EVP_KDF_CTX_get_params() +and EVP_KDF_CTX_set_params(), respectively. +See L for the use of B as parameter descriptor. + +=head2 Information functions + +EVP_KDF_size() returns the output size if the algorithm produces a fixed amount +of output and B otherwise. If an error occurs then 0 is returned. +For some algorithms an error may result if input parameters necessary to +calculate a fixed output size have not yet been supplied. + +EVP_KDF_name() returns the name of the given KDF implementation. + +EVP_KDF_provider() returns the provider that holds the implementation +of the given I. + +EVP_KDF_do_all_ex() traverses all KDF implemented by all activated +providers in the given library context I, and for each of the +implementations, calls the given function I with the implementation method +and the given I as argument. + +=head1 PARAMETERS + +The standard parameter names are: + +=over 4 + +=item B ("pass") + +Some KDF implementations require a password. +For those KDF implementations that support it, this parameter sets the password. + +=item B ("salt") + +Some KDF implementations can take a salt. +For those KDF implementations that support it, this parameter sets the salt. + +The default value, if any, is implementation dependent. + +=item B ("iter") + +Some KDF implementations require an iteration count. +For those KDF implementations that support it, this parameter sets the +iteration count. + +The default value, if any, is implementation dependent. + +=item B ("properties") + +=item B ("mac") + +=item B ("digest") + +=item B ("engine") + +For KDF implementations that use an underlying computation MAC or +digest, these parameters set what the algorithm should be, and the +engine that implements the algorithm or the properties to fetch it +by if needed. + +The value is always the name of the intended engine, algorithm, +or the properties. + +Note that not all algorithms may support all possible underlying +implementations. + +=item B ("key") + +Some KDF implementations require a key. +For those KDF implementations that support it, this octet string parameter +sets the key. + +=item B ("maclen") + +Used by implementations that use a MAC with a variable output size (KMAC). +For those KDF implementations that support it, this parameter +sets the MAC output size. + +The default value, if any, is implementation dependent. +The length must never exceed what can be given with a B. + +=item B ("macmaxmem_byteslen") + +Memory-hard password-based KDF algorithms, such as scrypt, use an amount of +memory that depends on the load factors provided as input. +For those KDF implementations that support it, this uint64_t parameter sets +an upper limit on the amount of memory that may be consumed while performing +a key derivation. +If this memory usage limit is exceeded because the load factors are chosen +too high, the key derivation will fail. + +The default value is implementation dependent. +The memory size must never exceed what can be given with a B. + +=back + +=head1 RETURN VALUES + +EVP_MAC_fetch() returns a pointer to a newly fetched B, or +NULL if allocation failed. + +EVP_KDF_name() returns the name for the given I, if it has been +added to the object database. + +EVP_KDF_provider() returns a pointer to the provider for the KDF, or +NULL on error. + +EVP_MAC_up_ref() returns 1 on success, 0 on error. + +EVP_KDF_CTX_new() returns either the newly allocated +C structure or C if an error occurred. + +EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value. + +EVP_KDF_size() returns the output size. C is returned to indicate +that the algorithm produces a variable amount of output; 0 to indicate failure. + +The remaining functions return 1 for success and 0 or a negative value for +failure. In particular, a return value of -2 indicates the operation is not +supported by the KDF algorithm. + +=head1 SEE ALSO + +L +L +L +L +L +L +L +L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=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/man3/EVP_KDF_CTX.pod b/doc/man3/EVP_KDF_CTX.pod deleted file mode 100644 index 38993610..00000000 --- a/doc/man3/EVP_KDF_CTX.pod +++ /dev/null @@ -1,296 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF, EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_new_id, EVP_KDF_CTX_free, -EVP_KDF_CTX_kdf, EVP_KDF_reset, EVP_KDF_ctrl, EVP_KDF_vctrl, EVP_KDF_ctrl_str, -EVP_KDF_size, EVP_KDF_derive, EVP_KDF_nid, EVP_KDF_name, -EVP_get_kdfbyname, EVP_get_kdfbynid, EVP_get_kdfbyobj - EVP KDF routines - -=head1 SYNOPSIS - - #include - - typedef struct evp_kdf_st EVP_KDF; - typedef struct evp_kdf_ctx_st EVP_KDF_CTX; - - EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf); - EVP_KDF_CTX *EVP_KDF_CTX_new_id(int nid); - const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); - void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); - void EVP_KDF_reset(EVP_KDF_CTX *ctx); - int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); - int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); - int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); - size_t EVP_KDF_size(EVP_KDF_CTX *ctx); - int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); - int EVP_KDF_nid(const EVP_KDF *kdf); - const char *EVP_KDF_name(const EVP_KDF *kdf); - const EVP_KDF *EVP_get_kdfbyname(const char *name); - const EVP_KDF *EVP_get_kdfbynid(int nid); - const EVP_KDF *EVP_get_kdfbyobj(const ASN1_OBJECT *o); - -=head1 DESCRIPTION - -The EVP KDF routines are a high level interface to Key Derivation Function -algorithms and should be used instead of algorithm-specific functions. - -After creating a C for the required algorithm using either -EVP_KDF_CTX_new() or EVP_KDF_CTX_new_id(), inputs to the algorithm are supplied -using calls to EVP_KDF_ctrl(), EVP_KDF_vctrl() or EVP_KDF_ctrl_str() before -calling EVP_KDF_derive() to derive the key. - -=head2 Types - -B is a type that holds the implementation of a KDF. - -B is a context type that holds the algorithm inputs. - -=head2 Context manipulation functions - -EVP_KDF_CTX_new() creates a new context for the KDF type C. - -EVP_KDF_CTX_new_id() creates a new context for the numerical KDF identity C. - -EVP_KDF_CTX_free() frees up the context C. If C is C, nothing -is done. - -EVP_KDF_CTX_kdf() returns the B associated with the context -C. - -=head2 Computing functions - -EVP_KDF_reset() resets the context to the default state as if the context -had just been created. - -EVP_KDF_ctrl() is used to provide inputs to the KDF algorithm prior to -EVP_KDF_derive() being called. The inputs that may be provided will vary -depending on the KDF algorithm or its implementation. This functions takes -variable arguments, the exact expected arguments depend on C. -See L below for a description of standard controls. - -EVP_KDF_vctrl() is the variant of EVP_KDF_ctrl() that takes a C -argument instead of variadic arguments. - -EVP_KDF_ctrl_str() allows an application to send an algorithm specific control -operation to a context C in string form. This is intended to be used for -options specified on the command line or in text files. - -EVP_KDF_derive() derives C bytes of key material and places it in the -C buffer. If the algorithm produces a fixed amount of output then an -error will occur unless the C parameter is equal to that output size, -as returned by EVP_KDF_size(). - -=head2 Information functions - -EVP_KDF_size() returns the output size if the algorithm produces a fixed amount -of output and C otherwise. If an error occurs then 0 is returned. -For some algorithms an error may result if input parameters necessary to -calculate a fixed output size have not yet been supplied. - -EVP_KDF_nid() returns the numeric identity of the given KDF implementation. - -EVP_KDF_name() returns the name of the given KDF implementation. - -=head2 Object database functions - -EVP_get_kdfbyname() fetches a KDF implementation from the object -database by name. - -EVP_get_kdfbynid() fetches a KDF implementation from the object -database by numeric identity. - -EVP_get_kdfbyobj() fetches a KDF implementation from the object -database by ASN.1 OBJECT (i.e. an encoded OID). - -=head1 CONTROLS - -The standard controls are: - -=over 4 - -=item B - -This control expects two arguments: C, C - -Some KDF implementations require a password. For those KDF implementations -that support it, this control sets the password. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "pass" - -The value string is used as is. - -=item "hexpass" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects two arguments: C, C - -Some KDF implementations can take a salt. For those KDF implementations that -support it, this control sets the salt. - -The default value, if any, is implementation dependent. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "salt" - -The value string is used as is. - -=item "hexsalt" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects one argument: C - -Some KDF implementations require an iteration count. For those KDF implementations that support it, this control sets the iteration count. - -The default value, if any, is implementation dependent. - -EVP_KDF_ctrl_str() type string: "iter" - -The value string is expected to be a decimal number. - -=item B - -This control expects one argument: C - -Some KDF implementations use a MAC as an underlying computation -algorithm, this control sets what the MAC algorithm should be. - -EVP_KDF_ctrl_str() type string: "mac" - -The value string is expected to be the name of a MAC. - -=item B - -This control expects one argument: C - -For MAC implementations that use a message digest as an underlying computation -algorithm, this control sets what the digest algorithm should be. - -EVP_KDF_ctrl_str() type string: "digest" - -The value string is expected to be the name of a digest. - -=item B - -This control expects two arguments: C, C - -Some KDF implementations require a key. For those KDF implementations that -support it, this control sets the key. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects one argument: C - -Used by implementations that use a MAC with a variable output size (KMAC). For -those KDF implementations that support it, this control sets the MAC output size. - -The default value, if any, is implementation dependent. - -EVP_KDF_ctrl_str() type string: "outlen" - -The value string is expected to be a decimal number. - -=item B - -This control expects one argument: C - -Memory-hard password-based KDF algorithms, such as scrypt, use an amount of -memory that depends on the load factors provided as input. For those KDF -implementations that support it, this control sets an upper limit on the amount -of memory that may be consumed while performing a key derivation. If this -memory usage limit is exceeded because the load factors are chosen too high, -the key derivation will fail. - -The default value is implementation dependent. - -EVP_KDF_ctrl_str() type string: "maxmem_bytes" - -The value string is expected to be a decimal number. - -=back - -=head1 RETURN VALUES - -EVP_KDF_CTX_new() and EVP_KDF_CTX_new_id() return either the newly allocated -C structure or C if an error occurred. - -EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value. - -EVP_KDF_size() returns the output size. C is returned to indicate -that the algorithm produces a variable amount of output; 0 to indicate failure. - -EVP_KDF_nid() returns the numeric identity for the given C. - -EVP_KDF_name() returns the name for the given C, if it has been -added to the object database. - -EVP_add_kdf() returns 1 if the given C was successfully added to -the object database, otherwise 0. - -EVP_get_kdfbyname(), EVP_get_kdfbynid() and EVP_get_kdfbyobj() return -the requested KDF implementation, if it exists in the object database, -otherwise B. - -The remaining functions return 1 for success and 0 or a negative value for -failure. In particular, a return value of -2 indicates the operation is not -supported by the KDF algorithm. - -=head1 SEE ALSO - -L -L -L -L -L -L -L -L - -=head1 HISTORY - -This functionality was added to OpenSSL 3.0.0. - -=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/man3/EVP_KEYEXCH_free.pod b/doc/man3/EVP_KEYEXCH_free.pod new file mode 100644 index 00000000..41926f6b --- /dev/null +++ b/doc/man3/EVP_KEYEXCH_free.pod @@ -0,0 +1,61 @@ +=pod + +=head1 NAME + +EVP_KEYEXCH_fetch, EVP_KEYEXCH_free, EVP_KEYEXCH_up_ref, EVP_KEYEXCH_provider +- Functions to manage EVP_KEYEXCH algorithm objects + +=head1 SYNOPSIS + + #include + + EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties); + void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange); + int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange); + OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange); + +=head1 DESCRIPTION + +EVP_KEYEXCH_fetch() fetches the key exchange implementation for the given +B from any provider offering it, within the criteria given +by the B. +See L for further information. + +The returned value must eventually be freed with EVP_KEYEXCH_free(). + +EVP_KEYEXCH_free() decrements the reference count for the B +structure. Typically this structure will have been obtained from an earlier call +to EVP_KEYEXCH_fetch(). If the reference count drops to 0 then the +structure is freed. + +EVP_KEYEXCH_up_ref() increments the reference count for an B +structure. + +EVP_KEYEXCH_provider() returns the provider that I was fetched from. + +=head1 RETURN VALUES + +EVP_KEYEXCH_fetch() returns a pointer to a B for success +or B for failure. + +EVP_KEYEXCH_up_ref() returns 1 for success or 0 otherwise. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=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/man3/EVP_KEYMGMT.pod b/doc/man3/EVP_KEYMGMT.pod new file mode 100644 index 00000000..ab209da7 --- /dev/null +++ b/doc/man3/EVP_KEYMGMT.pod @@ -0,0 +1,84 @@ +=pod + +=head1 NAME + +EVP_KEYMGMT, +EVP_KEYMGMT_fetch, +EVP_KEYMGMT_up_ref, +EVP_KEYMGMT_free, +EVP_KEYMGMT_provider +- EVP key management routines + +=head1 SYNOPSIS + + #include + + typedef struct evp_keymgmt_st EVP_KEYMGMT; + + EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties); + int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt); + void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt); + const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt); + +=head1 DESCRIPTION + +B is a method object that represents key management +implementations for different cryptographic algorithms. +This method object provides functionality to have providers import key +material from the outside, as well as export key material to the +outside. +Most of the functionality can only be used internally and has no +public interface, this object is simply passed into other functions +when needed. + +EVP_KEYMGMT_fetch() looks for an algorithm within the provider that +has been loaded into the B given by I, having the +name given by I and the properties given by I. + +EVP_KEYMGMT_up_ref() increments the reference count for the given +B I. + +EVP_KEYMGMT_free() decrements the reference count for the given +B I, and when the count reaches zero, frees it. + +EVP_KEYMGMT_provider() returns the provider that has this particular +implementation. + +=head1 NOTES + +EVP_KEYMGMT_fetch() may be called implicitly by other fetching +functions, using the same library context and properties. +Any other API that uses keys will typically do this. + +=head1 RETURN VALUES + +EVP_KEYMGMT_fetch() returns a pointer to the key management +implementation represented by an EVP_KEYMGMT object, or NULL on +error. + +EVP_KEYMGMT_up_ref() returns 1 on success, or 0 on error. + +EVP_KEYMGMT_free() doesn't return any value. + +EVP_KEYMGMT_provider() returns a pointer to a provider object, or NULL +on error. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=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/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index 01ad6ed5..df15a907 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -2,11 +2,14 @@ =head1 NAME -EVP_MAC, EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_new_id, EVP_MAC_CTX_free, -EVP_MAC_CTX_dup, EVP_MAC_CTX_mac, EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, -EVP_MAC_final, EVP_MAC_ctrl, EVP_MAC_vctrl, EVP_MAC_ctrl_str, -EVP_MAC_str2ctrl, EVP_MAC_hex2ctrl, EVP_MAC_nid, EVP_MAC_name, -EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines +EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free, +EVP_MAC_is_a, EVP_MAC_name, +EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params, +EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup, +EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params, +EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final, +EVP_MAC_CTX_gettable_params, EVP_MAC_CTX_settable_params, +EVP_MAC_do_all_ex - EVP MAC routines =head1 SYNOPSIS @@ -15,25 +18,35 @@ EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines typedef struct evp_mac_st EVP_MAC; typedef struct evp_mac_ctx_st EVP_MAC_CTX; - EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac); - EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid); + EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); + int EVP_MAC_up_ref(EVP_MAC *mac); + void EVP_MAC_free(EVP_MAC *mac); + int EVP_MAC_is_a(const EVP_MAC *mac, const char *name); + const char *EVP_MAC_name(const EVP_MAC *mac); + const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac); + int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); + + EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src); - const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); + EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); + int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); + int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + size_t EVP_MAC_size(EVP_MAC_CTX *ctx); int EVP_MAC_init(EVP_MAC_CTX *ctx); int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); - int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen); - int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...); - int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args); - int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value); - int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); - int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value); - int EVP_MAC_nid(const EVP_MAC *mac); - const char *EVP_MAC_name(const EVP_MAC *mac); - const EVP_MAC *EVP_get_macbyname(const char *name); - const EVP_MAC *EVP_get_macbynid(int nid); - const EVP_MAC *EVP_get_macbyobj(const ASN1_OBJECT *o); + int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize); + + const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); + const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac); + const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac); + + void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_MAC *mac, void *arg), + void *arg); =head1 DESCRIPTION @@ -60,23 +73,36 @@ B is a context type that holds internal MAC information as well as a reference to a computation context, for those MACs that rely on an underlying computation algorithm. +=head2 Algorithm implementation fetching + +EVP_MAC_fetch() fetches an implementation of a MAC I, given +a library context I and a set of I. +See L for further information. + +The returned value must eventually be freed with +L. + +EVP_MAC_up_ref() increments the reference count of an already fetched +MAC. + +EVP_MAC_free() frees a fetched algorithm. +NULL is a valid parameter, for which this function is a no-op. + =head2 Context manipulation functions -EVP_MAC_CTX_new() creates a new context for the MAC type C. -EVP_MAC_CTX_new_id() creates a new context for the numerical MAC -identity . +EVP_MAC_CTX_new() creates a new context for the MAC type I. The created context can then be used with most other functions described here. EVP_MAC_CTX_free() frees the contents of the context, including an underlying context if there is one, as well as the context itself. -B is a valid parameter, for which this function is a no-op. +NULL is a valid parameter, for which this function is a no-op. -EVP_MAC_CTX_dup() duplicates the C context and returns a newly allocated +EVP_MAC_CTX_dup() duplicates the I context and returns a newly allocated context. EVP_MAC_CTX_mac() returns the B associated with the context -C. +I. =head2 Computing functions @@ -85,180 +111,180 @@ through diverse controls. This should be called before calling EVP_MAC_update() and EVP_MAC_final(). -EVP_MAC_update() adds C bytes from C to the MAC input. +EVP_MAC_update() adds I bytes from I to the MAC input. EVP_MAC_final() does the final computation and stores the result in -the memory pointed at by C, and sets its size in the B -the C points at. -If C is B, then no computation is made. +the memory pointed at by I of size I, and sets the number +of bytes written in I<*outl> at. +If I is B or I is too small, then no computation +is made. To figure out what the output length will be and allocate space for it -dynamically, simply call with C being B and C +dynamically, simply call with I being B and I pointing at a valid location, then allocate space and make a second -call with C pointing at the allocated space. +call with I pointing at the allocated space. -EVP_MAC_ctrl() is used to manipulate or get information on aspects of -the MAC which may vary depending on the MAC algorithm or its -implementation. -This includes the MAC key, and for MACs that use other algorithms to -do their computation, this is also the way to tell it which one to -use. -This functions takes variable arguments, the exact expected arguments -depend on C. -EVP_MAC_ctrl() can be called both before and after EVP_MAC_init(), but -the effect will depend on what control is being use. -See L below for a description of standard controls. +EVP_MAC_get_params() retrieves details about the implementation +I. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. -EVP_MAC_vctrl() is the variant of EVP_MAC_ctrl() that takes a -C argument instead of variadic arguments. +EVP_MAC_CTX_get_params() retrieves chosen parameters, given the +context I and its underlying context. +The set of parameters given with I determine exactly what +parameters should be retrieved. +Note that a parameter that is unknown in the underlying context is +simply ignored. -EVP_MAC_ctrl_str() is an alternative to EVP_MAC_ctrl() to control the -MAC implementation as E C, C E pairs. -The MAC implementation documentation should specify what control type -strings are accepted. +EVP_MAC_CTX_set_params() passes chosen parameters to the underlying +context, given a context I. +The set of parameters given with I determine exactly what +parameters are passed down. +Note that a parameter that is unknown in the underlying context is +simply ignored. +Also, what happens when a needed parameter isn't passed down is +defined by the implementation. -EVP_MAC_str2ctrl() and EVP_MAC_hex2ctrl() are helper functions to -control the MAC implementation with raw strings or with strings -containing hexadecimal numbers. -The latter are decoded into bitstrings that are sent on to -EVP_MAC_ctrl(). +EVP_MAC_gettable_params(), EVP_MAC_CTX_gettable_params() and +EVP_MAC_CTX_settable_params() get a constant B array that +decribes the retrievable and settable parameters, i.e. parameters that +can be used with EVP_MAC_get_params(), EVP_MAC_CTX_get_params() +and EVP_MAC_CTX_set_params(), respectively. +See L for the use of B as parameter descriptor. =head2 Information functions EVP_MAC_size() returns the MAC output size for the given context. -EVP_MAC_nid() returns the numeric identity of the given MAC implementation. - EVP_MAC_name() returns the name of the given MAC implementation. -=head2 Object database functions +EVP_MAC_is_a() checks if the given I is an implementation of an +algorithm that's identifiable with I. -EVP_get_macbyname() fetches a MAC implementation from the object -database by name. +EVP_MAC_provider() returns the provider that holds the implementation +of the given I. -EVP_get_macbynid() fetches a MAC implementation from the object -database by numeric identity. +EVP_MAC_do_all_ex() traverses all MAC implemented by all activated +providers in the given library context I, and for each of the +implementations, calls the given function I with the implementation method +and the given I as argument. -EVP_get_macbyobj() fetches a MAC implementation from the object -database by ASN.1 OBJECT (i.e. an encoded OID). +=head1 PARAMETERS -=head1 CONTROLS +Parameters are identified by name as strings, and have an expected +data type and maximum size. +OpenSSL has a set of macros for parameter names it expects to see in +its own MAC implementations. +Here, we show all three, the OpenSSL macro for the parameter name, the +name in string form, and a type description. -The standard controls are: +The standard parameter names are: =over 4 -=item B +=item B ("key") -This control expects two arguments: C, C - -These will set the MAC key from the given string of the given length. -The string may be any bitstring, and can contain NUL bytes. +Its value is the MAC key as an array of bytes. For MACs that use an underlying computation algorithm, the algorithm -I be set first, see B, -B and B below. +must be set first, see parameter names "algorithm" below. -=item B +=item B ("iv") -This control expects two arguments: C, C +Some MAC implementations require an IV, this parameter sets the IV. -Some MAC implementations require an IV, this control sets the IV. - -=item B - -This control expects two arguments: C, C +=item B ("custom") Some MAC implementations (KMAC, BLAKE2) accept a Customization String, -this control sets the Customization String. The default value is "". +this parameter sets the Customization String. The default value is the +empty string. -=item B - -This control expects two arguments: C, C +=item B ("salt") This option is used by BLAKE2 MAC. -=item B +=item B ("xof") -This control expects one argument: C +It's a simple flag, the value 0 or 1 are expected. This option is used by KMAC. -=item B - -This control expects one argument: C +=item B ("flags") These will set the MAC flags to the given numbers. Some MACs do not support this option. -=item B +=item B ("engine") -=item B +=item B ("properties") -=item B +=item B ("digest") -For MAC implementations that use an underlying computation algorithm, -these controls set what the algorithm should be, and the engine that -implements the algorithm if needed. +=item B ("cipher") -Note that not all algorithms may support all digests. HMAC does not support -variable output length digests such as SHAKE128 or SHAKE256. +For MAC implementations that use an underlying computation cipher or +digest, these parameters set what the algorithm should be, and the +engine that implements the algorithm or the properties to fetch it +by if needed. -B takes one argument: C +The value is always the name of the intended engine, algorithm, +or the properties. -B takes one argument: C +Note that not all algorithms may support all digests. +HMAC does not support variable output length digests such as SHAKE128 +or SHAKE256. -B takes one argument: C - -=item B +=item B ("size") For MAC implementations that support it, set the output size that EVP_MAC_final() should produce. -The allowed sizes vary between MAC implementations. +The allowed sizes vary between MAC implementations, but must never exceed +what can be given with a B. =back -All these control should be used before the calls to any of +All these parameters should be used before the calls to any of EVP_MAC_init(), EVP_MAC_update() and EVP_MAC_final() for a full computation. Anything else may give undefined results. -=head1 NOTES - -EVP_get_macbynid(), EVP_get_macbyobj() and EVP_MAC_name() are -implemented as a macro. - =head1 RETURN VALUES -EVP_MAC_CTX_new(), EVP_MAC_CTX_new_id() and EVP_MAC_CTX_dup() return a pointer -to a newly created EVP_MAC_CTX, or NULL if allocation failed. +EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or +NULL if allocation failed. + +EVP_MAC_up_ref() returns 1 on success, 0 on error. + +EVP_MAC_free() returns nothing at all. + +EVP_MAC_name() returns the name of the MAC, or NULL if NULL was +passed. + +EVP_MAC_is_a() returns 1 if the given method can be identified with +the given name, otherwise 0. + +EVP_MAC_provider() returns a pointer to the provider for the MAC, or +NULL on error. + +EVP_MAC_CTX_new() and EVP_MAC_CTX_dup() return a pointer to a newly +created EVP_MAC_CTX, or NULL if allocation failed. EVP_MAC_CTX_free() returns nothing at all. -EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 on error. +EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on +success, 0 on error. -EVP_MAC_ctrl(), EVP_MAC_ctrl_str(), EVP_MAC_str2ctrl() and -EVP_MAC_hex2ctrl() return 1 on success and 0 or a negative value on -error. -In particular, the value -2 indicates that the given control type -isn't supported by the MAC implementation. +EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 +on error. EVP_MAC_size() returns the expected output size, or 0 if it isn't set. If it isn't set, a call to EVP_MAC_init() should get it set. -EVP_MAC_nid() returns the numeric identity for the given C. +EVP_MAC_do_all_ex() returns nothing at all. -EVP_MAC_name() returns the name for the given C, if it has been -added to the object database. - -EVP_add_mac() returns 1 if the given C was successfully added to -the object database, otherwise 0. - -EVP_get_macbyname(), EVP_get_macbynid() and EVP_get_macbyobj() return -the request MAC implementation, if it exists in the object database, -otherwise B. - -=head1 EXAMPLE +=head1 EXAMPLES #include #include @@ -268,29 +294,12 @@ otherwise B. #include #include - - int ctrl_ign_unsupported(EVP_MAC_CTX *ctx, int cmd, ...) - { - va_list args; - int rv; - - va_start(args, cmd); - rv = EVP_MAC_vctrl(ctx, cmd, args); - va_end(args); - - if (rv == -2) - rv = 1; /* Ignore unsupported, pretend it worked fine */ - - return rv; - } + #include int main() { - const EVP_MAC *mac = - EVP_get_macbyname(getenv("MY_MAC")); - const EVP_CIPHER *cipher = - EVP_get_cipherbyname(getenv("MY_MAC_CIPHER")); - const EVP_MD *digest = - EVP_get_digestbyname(getenv("MY_MAC_DIGEST")); + EVP_MAC *mac = EVP_MAC_fetch(NULL, getenv("MY_MAC"), NULL); + const char *cipher = getenv("MY_MAC_CIPHER"); + const char *digest = getenv("MY_MAC_DIGEST"); const char *key = getenv("MY_KEY"); EVP_MAC_CTX *ctx = NULL; @@ -300,14 +309,23 @@ otherwise B. size_t i; + OSSL_PARAM params[4]; + size_t params_n = 0; + + if (cipher != NULL) + params[params_n++] = + OSSL_PARAM_construct_utf8_string("cipher", cipher, 0, NULL); + if (digest != NULL) + params[params_n++] = + OSSL_PARAM_construct_utf8_string("digest", digest, 0, NULL); + params[params_n++] = + OSSL_PARAM_construct_octet_string("key", key, strlen(key), NULL); + params[params_n] = OSSL_PARAM_construct_end(); + if (mac == NULL || key == NULL || (ctx = EVP_MAC_CTX_new(mac)) == NULL - || (cipher != NULL - && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_CIPHER, cipher)) - || (digest != NULL - && !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_MD, digest)) - || EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY, key, strlen(key)) <= 0) + || EVP_MAC_CTX_set_params(ctx, params) <= 0) goto err; if (!EVP_MAC_init(ctx)) @@ -327,10 +345,12 @@ otherwise B. printf("\n"); EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); exit(0); err: EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); fprintf(stderr, "Something went wrong\n"); ERR_print_errors_fp(stderr); exit (1); @@ -348,6 +368,8 @@ F<./foo>) =head1 SEE ALSO +L +L, L, L, L, @@ -358,11 +380,11 @@ L =head1 HISTORY -These functions were added in OpenSSL 3.0.0. +These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -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 diff --git a/doc/man3/EVP_MD_fetch.pod b/doc/man3/EVP_MD_fetch.pod deleted file mode 100644 index 1e43b4fb..00000000 --- a/doc/man3/EVP_MD_fetch.pod +++ /dev/null @@ -1,237 +0,0 @@ -=pod - -=head1 NAME - -EVP_MD_fetch, EVP_CIPHER_fetch -- Functions to explicitly fetch algorithm implementations - -=head1 SYNOPSIS - - #include - - EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, - const char *properties); - EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, - const char *properties); - -=head1 DESCRIPTION - -Cryptographic algorithms are represented by different OpenSSL objects depending -on what type of algorithm it is. The following cryptographic algorithm types are -supported. - -=over 4 - -=item B - -Represents a digest algorithm. - -=item B - -Represents a symmetric cipher algorithm. - -=item B - -Represents a Message Authentication Code algorithm. - -=item B - -Represents a Key Derivation Function algorithm. - -=back - -The algorithm objects may or may not have an associated algorithm -implementation. -Cryptographic algorithms are implemented by providers. -Any algorithm may be supported by zero or more providers. -In order to use an algorithm an implementation must first be obtained. -This can happen in one of three ways, i.e. implicit fetch, explicit fetch or -user defined. - -=over 4 - -=item Implicit Fetch - -With implicit fetch an application can use functions such as L, -L or L to obtain an algorithm object with -no associated implementation. -When used in a function like L or L -the actual implementation to be used will be fetched implicitly using default -search criteria. -Typically, this will return an implementation of the appropriate algorithm from -the default provider unless the default search criteria have been changed and/or -different providers have been loaded. - -=item Explicit Fetch - -With explicit fetch an application uses one of the "fetch" functions to obtain -an algorithm object with an associated implementation. -An implementation with the given name that satisfies the search criteria -specified in the B parameter combined with the default search -criteria will be looked for within the available providers and returned. -See L for information on default search criteria -and L for information about providers. - -=item User defined - -Using the user defined approach an application constructs its own algorithm -object. -See L and L for details. - -=back - -Having obtained an algorithm implementation as an algorithm object it can then -be used to perform cryptographic operations. -For example to calculate the digest of input data with an B algorithm -object you can use functions such as L, -L and L. - -The fetch functions will look for an algorithm within the providers that -have been loaded into the B given in the B parameter. -This parameter may be NULL in which case the default B will be -used. -See L and L for further details. - -The B parameter gives the name of the algorithm to be looked up. -Different algorithms can be made available by loading different providers. - -The built-in default provider digest algorithm implementation names are: SHA1, -SHA224, SHA256, SHA384, SHA512, SHA512-224, SHA512-256, SHA3-224, SHA3-256, -SHA3-384, SHA3-512, SHAKE128, SHAKE256, SM3, BLAKE2b512, BLAKE2s256 and -MD5-SHA1. - -The built-in default provider cipher algorithm implementation names are: -AES-256-ECB, AES-192-ECB, AES-128-ECB, AES-256-CBC, AES-192-CBC, AES-128-CBC, -AES-256-OFB, AES-192-OFB, AES-128-OFB, AES-256-CFB, AES-192-CFB, AES-128-CFB, -AES-256-CFB1, AES-192-CFB1, AES-128-CFB1, AES-256-CFB8, AES-192-CFB8, -AES-128-CFB8, AES-256-CTR, AES-192-CTR, AES-128-CTR, id-aes256-GCM, -id-aes192-GCM and id-aes128-GCM. - -Additional algorithm implementations may be obtained by loading the "legacy" -provider. - -The legacy provider digest algorithms are: RIPEMD160, MD2, MD4, MD5, MDC2 and -whirlpool. - -The B parameter specifies the search criteria that will be used to -look for an algorithm implementation. Properties are given as a comma delimited -string of name value pairs. In order for an implementation to match, all the -properties in the query string must match those defined for that implementation. -Any properties defined by an implementation but not given in the query string -are ignored. All algorithm implementations in the default provider have the -property "default=yes". All algorithm implementations in the legacy provider have -the property "legacy=yes". All algorithm implementations in the FIPS provider -have the property "fips=yes". In the event that more than one implementation -of the given algorithm name matches the specified properties then an unspecified -one of those implementations may be returned. The B parameter may be -NULL in which case any implementation from the available providers with the -given algorithm name will be returned. - -The return value from a call to EVP_MD_fetch() must be freed by the caller using -L. -Note that EVP_MD objects are reference counted. See L. - -The return value from a call to EVP_CIPHER_fetch() must be freed by the caller -using L. -Note that EVP_CIPHER objects are reference counted. -See L. - -=head1 NOTES - -Where an application that previously used implicit fetch is converted to use -explicit fetch care should be taken with the L function. -Specifically, this function returns the EVP_MD object originally passed to -EVP_DigestInit_ex() (or other similar function). With implicit fetch the -returned EVP_MD object is guaranteed to be available throughout the application -lifetime. However, with explicit fetch EVP_MD objects are reference counted. -EVP_MD_CTX_md does not increment the reference count and so the returned EVP_MD -object may not be accessible beyond the lifetime of the EVP_MD_CTX it is -associated with. - -=head1 RETURN VALUES - -EVP_MD_fetch() returns a pointer to the algorithm implementation represented by -an EVP_MD object, or NULL on error. - -=head1 EXAMPLES - -Fetch any available implementation of SHA256 in the default context: - - EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", NULL); - ... - EVP_MD_meth_free(md); - -Fetch any available implementation of AES-128-CBC in the default context: - - EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", NULL); - ... - EVP_CIPHER_meth_free(cipher); - -Fetch an implementation of SHA256 from the default provider in the default -context: - - EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", "default=yes"); - ... - EVP_MD_meth_free(md); - -Fetch an implementation of SHA256 that is not from the default provider in the -default context: - - EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", "default=no"); - ... - EVP_MD_meth_free(md); - -Fetch an implementation of SHA256 from the default provider in the specified -context: - - EVP_MD *md = EVP_MD_fetch(ctx, "SHA256", "default=yes"); - ... - EVP_MD_meth_free(md); - -Load the legacy provider into the default context and then fetch an -implementation of whirlpool from it: - - /* This only needs to be done once - usually at application start up */ - OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy"); - - EVP_MD *md = EVP_MD_fetch(NULL, "whirlpool", "legacy=yes"); - ... - EVP_MD_meth_free(md); - -Note that in the above example the property string "legacy=yes" is optional -since, assuming no other providers have been loaded, the only implementation of -the "whirlpool" algorithm is in the "legacy" provider. Also note that the -default provider should be explicitly loaded if it is required in addition to -other providers: - - /* This only needs to be done once - usually at application start up */ - OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy"); - OSSL_PROVIDER *default = OSSL_PROVIDER_load(NULL, "default"); - - EVP_MD *md_whirlpool = EVP_MD_fetch(NULL, "whirlpool", NULL); - EVP_MD *md_sha256 = EVP_MD_fetch(NULL, "SHA256", NULL); - ... - EVP_MD_meth_free(md_whirlpool); - EVP_MD_meth_free(md_sha256); - -=head1 SEE ALSO - -L, L, L, -L, L, L, -L, L, L, -L, L - -=head1 HISTORY - -The functions described here were added in OpenSSL 3.0. - -=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/man3/EVP_MD_meth_new.pod b/doc/man3/EVP_MD_meth_new.pod index 5e35539e..7777a335 100644 --- a/doc/man3/EVP_MD_meth_new.pod +++ b/doc/man3/EVP_MD_meth_new.pod @@ -2,8 +2,8 @@ =head1 NAME -EVP_MD_meth_dup, -EVP_MD_meth_new, EVP_MD_meth_free, EVP_MD_meth_set_input_blocksize, +EVP_MD_meth_new, EVP_MD_meth_dup, EVP_MD_meth_free, +EVP_MD_meth_set_input_blocksize, EVP_MD_meth_set_result_size, EVP_MD_meth_set_app_datasize, EVP_MD_meth_set_flags, EVP_MD_meth_set_init, EVP_MD_meth_set_update, EVP_MD_meth_set_final, EVP_MD_meth_set_copy, EVP_MD_meth_set_cleanup, @@ -11,8 +11,8 @@ EVP_MD_meth_set_ctrl, EVP_MD_meth_get_input_blocksize, EVP_MD_meth_get_result_size, EVP_MD_meth_get_app_datasize, EVP_MD_meth_get_flags, EVP_MD_meth_get_init, EVP_MD_meth_get_update, EVP_MD_meth_get_final, EVP_MD_meth_get_copy, EVP_MD_meth_get_cleanup, -EVP_MD_meth_get_ctrl, EVP_MD_up_ref -- Routines to build up EVP_MD methods +EVP_MD_meth_get_ctrl +- Routines to build up legacy EVP_MD methods =head1 SYNOPSIS @@ -54,16 +54,14 @@ EVP_MD_meth_get_ctrl, EVP_MD_up_ref int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); - int EVP_MD_up_ref(EVP_MD *md); - =head1 DESCRIPTION The B type is a structure for digest method implementation. It can also have associated public/private key signing and verifying routines. -EVP_MD_meth_new() creates a new B structure. Note that B -structures are reference counted. +EVP_MD_meth_new() creates a new B structure. +These B structures are reference counted. EVP_MD_meth_dup() creates a copy of B. @@ -162,8 +160,6 @@ EVP_MD_meth_get_cleanup() and EVP_MD_meth_get_ctrl() are all used to retrieve the method data given with the EVP_MD_meth_set_*() functions above. -EVP_MD_up_ref() increments the reference count for an EVP_MD structure. - =head1 RETURN VALUES EVP_MD_meth_new() and EVP_MD_meth_dup() return a pointer to a newly @@ -175,8 +171,6 @@ indicated sizes or flags. All other EVP_CIPHER_meth_get_*() functions return pointers to their respective B function. -EVP_MD_up_ref() returns 1 for success or 0 otherwise. - =head1 SEE ALSO L, L, L @@ -184,8 +178,10 @@ L, L, L =head1 HISTORY The B structure was openly available in OpenSSL before version -1.1. EVP_MD_up_ref() was added in OpenSSL 3.0. All other functions described -here were added in OpenSSL 1.1. +1.1. +The functions described here were added in OpenSSL 1.1. +The B structure created with these functions became reference +counted in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_PKEY_ASN1_METHOD.pod b/doc/man3/EVP_PKEY_ASN1_METHOD.pod index 1d89c38f..ed44749c 100644 --- a/doc/man3/EVP_PKEY_ASN1_METHOD.pod +++ b/doc/man3/EVP_PKEY_ASN1_METHOD.pod @@ -361,6 +361,16 @@ public key data for an EVP_PKEY. They MUST return 0 on error, or 1 on success. They are called by L, and L respectively. + size_t (*dirty) (const EVP_PKEY *pk); + void *(*export_to) (const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); + +dirty_cnt() returns the internal key's dirty count. +This can be used to synchronise different copies of the same keys. + +The export_to() method exports the key material from the given key to +a provider, through the L interface, if that provider +supports importing key material. + =head2 Functions EVP_PKEY_asn1_new() creates and returns a new B diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod index 1bab6d16..13ea5708 100644 --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod @@ -2,6 +2,10 @@ =head1 NAME +EVP_PKEY_CTX_get_params, +EVP_PKEY_CTX_gettable_params, +EVP_PKEY_CTX_set_params, +EVP_PKEY_CTX_settable_params, EVP_PKEY_CTX_ctrl, EVP_PKEY_CTX_ctrl_str, EVP_PKEY_CTX_ctrl_uint64, @@ -62,6 +66,11 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len #include + int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); + const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx); + int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); + const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx); + int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, @@ -141,6 +150,50 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len =head1 DESCRIPTION +The EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() functions get and +send arbitrary parameters from and to the algorithm implementation respectively. +Not all parameters may be supported by all providers. +See L for more information on providers. +See L for more information on parameters. +These functions must only be called after the EVP_PKEY_CTX has been initialised +for use in an operation (for example by L, +L or other similar functions). + +The parameters currently supported by the default provider are: + +=over 4 + +=item "pad" (B) + +Sets the DH padding mode. +If B is 1 then the shared secret is padded with zeroes +up to the size of the DH prime B

. +If B is zero (the default) then no padding is +performed. + +=item "digest" (B) + +Gets and sets the name of the digest algorithm used for the input to the +signature functions. + +=item "digest-size" (B) + +Gets and sets the output size of the digest algorithm used for the input to the +signature functions. +The internal algorithm that supports this parameter is DSA. + +=back + +EVP_PKEY_CTX_gettable_params() and EVP_PKEY_CTX_settable_params() gets a +constant B array that decribes the gettable and +settable parameters for the current algorithm implementation, i.e. parameters +that can be used with EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() +respectively. +See L for the use of B as parameter descriptor. +These functions must only be called after the EVP_PKEY_CTX has been initialised +for use in an operation (for example by L, +L or other similar functions). + The function EVP_PKEY_CTX_ctrl() sends a control operation to the context B. The key type used must match B if it is not -1. The parameter B is a mask indicating which operations the control can be applied to. @@ -166,13 +219,13 @@ B, B and B commands. The function EVP_PKEY_CTX_md() sends a message digest control operation to the context B. The message digest is specified by its name B. -All the remaining "functions" are implemented as macros. - -The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used +The EVP_PKEY_CTX_set_signature_md() function sets the message digest type used in a signature. It can be used in the RSA, DSA and ECDSA algorithms. -The EVP_PKEY_CTX_get_signature_md() macro gets the message digest type used in a -signature. It can be used in the RSA, DSA and ECDSA algorithms. +The EVP_PKEY_CTX_get_signature_md() function gets the message digest type used +in a signature. It can be used in the RSA, DSA and ECDSA algorithms. + +All the remaining "functions" are implemented as macros. Key generation typically involves setting up parameters to be used and generating the private and public key data. Some algorithm implementations @@ -290,8 +343,9 @@ The EVP_PKEY_CTX_set_dh_paramgen_type() macro sets the key type for DH parameter generation. Use 0 for PKCS#3 DH and 1 for X9.42 DH. The default is 0. -The EVP_PKEY_CTX_set_dh_pad() macro sets the DH padding mode. If B is -1 the shared secret is padded with zeroes up to the size of the DH prime B

. +The EVP_PKEY_CTX_set_dh_pad() function sets the DH padding mode. +If B is 1 the shared secret is padded with zeroes up to the size of the DH +prime B

. If B is zero (the default) then no padding is performed. EVP_PKEY_CTX_set_dh_nid() sets the DH parameters to values corresponding to @@ -437,9 +491,15 @@ allocate adequate memory space for the B before calling EVP_PKEY_CTX_get1_id =head1 RETURN VALUES -EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0 -or a negative value for failure. In particular a return value of -2 -indicates the operation is not supported by the public key algorithm. +EVP_PKEY_CTX_set_params() returns 1 for success or 0 otherwise. +EVP_PKEY_CTX_settable_params() returns an OSSL_PARAM array on success or NULL on +error. +It may also return NULL if there are no settable parameters available. + +EVP_PKEY_CTX_set_signature_md(), EVP_PKEY_CTX_set_dh_pad(), EVP_PKEY_CTX_ctrl() +and its macros return a positive value for success and 0 or a negative value for +failure. In particular a return value of -2 indicates the operation is not +supported by the public key algorithm. =head1 SEE ALSO @@ -458,6 +518,10 @@ The EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len() macros were added in 1.1.1, other functions were added in OpenSSL 1.0.0. +EVP_PKEY_CTX_get_signature_md(), EVP_PKEY_CTX_set_signature_md() and +EVP_PKEY_CTX_set_dh_pad() were macros in OpenSSL 1.1.1 and below. From OpenSSL +3.0 they are functions. + =head1 COPYRIGHT Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/EVP_PKEY_CTX_set_hkdf_md.pod b/doc/man3/EVP_PKEY_CTX_set_hkdf_md.pod index 72a5b0ff..7fc833e0 100644 --- a/doc/man3/EVP_PKEY_CTX_set_hkdf_md.pod +++ b/doc/man3/EVP_PKEY_CTX_set_hkdf_md.pod @@ -121,7 +121,7 @@ All these functions return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES This example derives 10 bytes using SHA-256 with the secret key "secret", salt value "salt" and info value "label": diff --git a/doc/man3/EVP_PKEY_CTX_set_scrypt_N.pod b/doc/man3/EVP_PKEY_CTX_set_scrypt_N.pod index e9ca3515..dfde4ff8 100644 --- a/doc/man3/EVP_PKEY_CTX_set_scrypt_N.pod +++ b/doc/man3/EVP_PKEY_CTX_set_scrypt_N.pod @@ -29,7 +29,7 @@ EVP_PKEY_CTX_set_scrypt_maxmem_bytes These functions are used to set up the necessary data to use the scrypt KDF. -For more information on scrypt, see L. +For more information on scrypt, see L. EVP_PKEY_CTX_set1_scrypt_salt() sets the B bytes long salt value. @@ -54,6 +54,9 @@ respectively. =head1 NOTES +There is a newer generic API for KDFs, L, which is +preferred over the EVP_PKEY method. + The scrypt KDF also uses EVP_PKEY_CTX_set1_pbe_pass() as well as the value from the string controls "pass" and "hexpass". See L. @@ -69,7 +72,7 @@ supported by the public key algorithm. =head1 SEE ALSO -L, +L L, L, L diff --git a/doc/man3/EVP_PKEY_CTX_set_tls1_prf_md.pod b/doc/man3/EVP_PKEY_CTX_set_tls1_prf_md.pod index cc87c00a..e0629acc 100644 --- a/doc/man3/EVP_PKEY_CTX_set_tls1_prf_md.pod +++ b/doc/man3/EVP_PKEY_CTX_set_tls1_prf_md.pod @@ -70,7 +70,7 @@ All these functions return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES This example derives 10 bytes using SHA-256 with the secret key "secret" and seed value "seed": diff --git a/doc/man3/EVP_PKEY_decrypt.pod b/doc/man3/EVP_PKEY_decrypt.pod index a2363af2..a78c1ee8 100644 --- a/doc/man3/EVP_PKEY_decrypt.pod +++ b/doc/man3/EVP_PKEY_decrypt.pod @@ -41,7 +41,7 @@ EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Decrypt data using OAEP (for RSA keys): diff --git a/doc/man3/EVP_PKEY_derive.pod b/doc/man3/EVP_PKEY_derive.pod index a6747f41..832498ba 100644 --- a/doc/man3/EVP_PKEY_derive.pod +++ b/doc/man3/EVP_PKEY_derive.pod @@ -2,20 +2,33 @@ =head1 NAME -EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret +EVP_PKEY_derive_init, EVP_PKEY_derive_init_ex, EVP_PKEY_derive_set_peer, +EVP_PKEY_derive - derive public key algorithm shared secret =head1 SYNOPSIS #include + int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange); int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); =head1 DESCRIPTION -The EVP_PKEY_derive_init() function initializes a public key algorithm -context using key B for shared secret derivation. +The EVP_PKEY_derive_init_ex() function initializes a public key algorithm +context for shared secret derivation using the key exchange algorithm +B. +The key exchange algorithm B should be fetched using a call to +L. +The EVP_PKEY object associated with B must be compatible with that +algorithm. +B may be NULL in which case the EVP_KEYEXCH algorithm is fetched +implicitly based on the type of EVP_PKEY associated with B. +See L for more information about implict fetches. + +The EVP_PKEY_derive_init() function is the same as EVP_PKEY_derive_init_ex() +except that the EVP_KEYEXCH algorithm is always implicitly fetched. The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally be a public key. @@ -29,20 +42,21 @@ written to B. =head1 NOTES -After the call to EVP_PKEY_derive_init() algorithm specific control -operations can be performed to set any appropriate parameters for the -operation. +After the call to EVP_PKEY_derive_init() or EVP_PKEY_derive_init_ex() algorithm +specific control operations can be performed to set any appropriate parameters +for the operation. The function EVP_PKEY_derive() can be called more than once on the same context if several operations are performed using the same parameters. =head1 RETURN VALUES -EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0 -or a negative value for failure. In particular a return value of -2 -indicates the operation is not supported by the public key algorithm. +EVP_PKEY_derive_init_ex(), EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 +for success and 0 or a negative value for failure. +In particular a return value of -2 indicates the operation is not supported by +the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Derive shared secret (for example DH or EC keys): @@ -86,10 +100,12 @@ L, L, L, L, +L =head1 HISTORY -These functions were added in OpenSSL 1.0.0. +These functions were added in OpenSSL 1.0.0. The EVP_PKEY_derive_init_ex() +function was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_PKEY_encrypt.pod b/doc/man3/EVP_PKEY_encrypt.pod index 1e9742de..73ca8bae 100644 --- a/doc/man3/EVP_PKEY_encrypt.pod +++ b/doc/man3/EVP_PKEY_encrypt.pod @@ -41,7 +41,7 @@ EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Encrypt data using OAEP (for RSA keys). See also L or L for means to load a public key. You may also simply diff --git a/doc/man3/EVP_PKEY_sign.pod b/doc/man3/EVP_PKEY_sign.pod index b9211b83..f30affd4 100644 --- a/doc/man3/EVP_PKEY_sign.pod +++ b/doc/man3/EVP_PKEY_sign.pod @@ -2,12 +2,14 @@ =head1 NAME -EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm +EVP_PKEY_sign_init_ex, EVP_PKEY_sign_init, EVP_PKEY_sign +- sign using a public key algorithm =head1 SYNOPSIS #include + int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature); int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, @@ -15,8 +17,18 @@ EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm =head1 DESCRIPTION -The EVP_PKEY_sign_init() function initializes a public key algorithm -context using key B for a signing operation. +The EVP_PKEY_sign_init_ex() function initializes a public key algorithm +context for performing signing using the signature algorithm B. +The signature algorithm B should be fetched using a call to +L. +The EVP_PKEY object associated with B must be compatible with that +algorithm. +B may be NULL in which case the EVP_SIGNATURE algorithm is fetched +implicitly based on the type of EVP_PKEY associated with B. +See L for more information about implict fetches. + +The EVP_PKEY_sign_init() function is the same as EVP_PKEY_sign_init_ex() except +that the EVP_SIGNATURE algorithm is always implicitly fetched. The EVP_PKEY_sign() function performs a public key signing operation using B. The data to be signed is specified using the B and @@ -46,7 +58,7 @@ EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Sign data using RSA with PKCS#1 padding and SHA256 digest: @@ -101,6 +113,7 @@ L =head1 HISTORY +EVP_PKEY_sign_init_ex() was added in OpenSSL 3.0. These functions were added in OpenSSL 1.0.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_PKEY_supports_digest_nid.pod b/doc/man3/EVP_PKEY_supports_digest_nid.pod index 0dfc1163..b3f51346 100644 --- a/doc/man3/EVP_PKEY_supports_digest_nid.pod +++ b/doc/man3/EVP_PKEY_supports_digest_nid.pod @@ -39,7 +39,7 @@ L, =head1 HISTORY -The EVP_PKEY_supports_digest_nid() function was added in OpenSSL 3.0.0. +The EVP_PKEY_supports_digest_nid() function was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_PKEY_verify.pod b/doc/man3/EVP_PKEY_verify.pod index 5b0d15a7..1e04a85c 100644 --- a/doc/man3/EVP_PKEY_verify.pod +++ b/doc/man3/EVP_PKEY_verify.pod @@ -2,12 +2,14 @@ =head1 NAME -EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm +EVP_PKEY_verify_init_ex, EVP_PKEY_verify_init, EVP_PKEY_verify +- signature verification using a public key algorithm =head1 SYNOPSIS #include + int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature); int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, @@ -15,8 +17,19 @@ EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public ke =head1 DESCRIPTION -The EVP_PKEY_verify_init() function initializes a public key algorithm -context using key B for a signature verification operation. +The EVP_PKEY_verify_init_ex() function initializes a public key algorithm +context for performing signature verification using the signature algorithm +B. +The signature algorithm B should be fetched using a call to +L. +The EVP_PKEY object associated with B must be compatible with that +algorithm. +B may be NULL in which case the EVP_SIGNATURE algorithm is fetched +implicitly based on the type of EVP_PKEY associated with B. +See L for more information about implict fetches. + +The EVP_PKEY_verify_init() function is the same as EVP_PKEY_verify_init_ex() +except that the EVP_SIGNATURE algorithm is always implicitly fetched. The EVP_PKEY_verify() function performs a public key verification operation using B. The signature is specified using the B and @@ -44,7 +57,7 @@ A negative value indicates an error other that signature verification failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Verify signature using PKCS#1 and SHA256 digest: @@ -89,7 +102,8 @@ L =head1 HISTORY -These functions were added in OpenSSL 1.0.0. +EVP_PKEY_verify_init_ex() was added in OpenSSL 3.0. +All other functions were added in OpenSSL 1.0.0. =head1 COPYRIGHT diff --git a/doc/man3/EVP_PKEY_verify_recover.pod b/doc/man3/EVP_PKEY_verify_recover.pod index 22538fd0..737c372d 100644 --- a/doc/man3/EVP_PKEY_verify_recover.pod +++ b/doc/man3/EVP_PKEY_verify_recover.pod @@ -2,12 +2,15 @@ =head1 NAME -EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using a public key algorithm +EVP_PKEY_verify_recover_init_ex, EVP_PKEY_verify_recover_init, +EVP_PKEY_verify_recover - recover signature using a public key algorithm =head1 SYNOPSIS #include + int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx, + EVP_SIGNATURE *signature); int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, @@ -15,8 +18,20 @@ EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using =head1 DESCRIPTION -The EVP_PKEY_verify_recover_init() function initializes a public key algorithm -context using key B for a verify recover operation. +The EVP_PKEY_verify_recover_init_ex() function initializes a public key +algorithm context for performing signature signed data recovery using the +signature algorithm B. +The signature algorithm B should be fetched using a call to +L. +The EVP_PKEY object associated with B must be compatible with that +algorithm. +B may be NULL in which case the EVP_SIGNATURE algorithm is fetched +implicitly based on the type of EVP_PKEY associated with B. +See L for more information about implict fetches. + +The EVP_PKEY_verify_recover_init() function is the same as +EVP_PKEY_verify_recover_init_ex() except that the EVP_SIGNATURE algorithm is +always implicitly fetched. The EVP_PKEY_verify_recover() function recovers signed data using B. The signature is specified using the B and @@ -49,7 +64,7 @@ EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for succes and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. -=head1 EXAMPLE +=head1 EXAMPLES Recover digest originally signed using PKCS#1 and SHA256 digest: diff --git a/doc/man3/EVP_SIGNATURE_free.pod b/doc/man3/EVP_SIGNATURE_free.pod new file mode 100644 index 00000000..3e39b915 --- /dev/null +++ b/doc/man3/EVP_SIGNATURE_free.pod @@ -0,0 +1,64 @@ +=pod + +=head1 NAME + +EVP_SIGNATURE_fetch, EVP_SIGNATURE_free, EVP_SIGNATURE_up_ref, +EVP_SIGNATURE_provider +- Functions to manage EVP_SIGNATURE algorithm objects + +=head1 SYNOPSIS + + #include + + EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm, + const char *properties); + void EVP_SIGNATURE_free(EVP_SIGNATURE *signature); + int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature); + OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature); + +=head1 DESCRIPTION + +EVP_SIGNATURE_fetch() fetches the implementation for the given +B from any provider offering it, within the criteria given +by the B. +The algorithm will be one offering functions for performing signature related +tasks such as signing and verifying. +See L for further information. + +The returned value must eventually be freed with EVP_SIGNATURE_free(). + +EVP_SIGNATURE_free() decrements the reference count for the B +structure. Typically this structure will have been obtained from an earlier call +to EVP_SIGNATURE_fetch(). If the reference count drops to 0 then the +structure is freed. + +EVP_SIGNATURE_up_ref() increments the reference count for an B +structure. + +EVP_SIGNATURE_provider() returns the provider that I was fetched from. + +=head1 RETURN VALUES + +EVP_SIGNATURE_fetch() returns a pointer to an B for success +or B for failure. + +EVP_SIGNATURE_up_ref() returns 1 for success or 0 otherwise. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=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/man3/OCSP_REQUEST_new.pod b/doc/man3/OCSP_REQUEST_new.pod index db670dca..e9d260fe 100644 --- a/doc/man3/OCSP_REQUEST_new.pod +++ b/doc/man3/OCSP_REQUEST_new.pod @@ -75,7 +75,7 @@ corresponding to each certificate. OCSP_request_onereq_count() and OCSP_request_onereq_get0() are mainly used by OCSP responders. -=head1 EXAMPLE +=head1 EXAMPLES Create an B structure for certificate B with issuer B: diff --git a/doc/man3/OPENSSL_CTX.pod b/doc/man3/OPENSSL_CTX.pod index 1893c923..d574a374 100644 --- a/doc/man3/OPENSSL_CTX.pod +++ b/doc/man3/OPENSSL_CTX.pod @@ -38,7 +38,7 @@ OPENSSL_CTX_free() doesn't return any value. =head1 HISTORY OPENSSL_CTX, OPENSSL_CTX_new() and OPENSSL_CTX_free() -were added in OpenSSL 3.0.0. +were added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OPENSSL_hexchar2int.pod b/doc/man3/OPENSSL_hexchar2int.pod new file mode 100644 index 00000000..930b32b6 --- /dev/null +++ b/doc/man3/OPENSSL_hexchar2int.pod @@ -0,0 +1,74 @@ +=pod + +=head1 NAME + +OPENSSL_hexchar2int, +OPENSSL_hexstr2buf_ex, OPENSSL_hexstr2buf, +OPENSSL_buf2hexstr_ex, OPENSSL_buf2hexstr +- Hex encoding and decoding functions + +=head1 SYNOPSIS + + #include + + int OPENSSL_hexchar2int(unsigned char c); + int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, long *buflen, + const char *str); + unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); + int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, + const unsigned char *buf, long buflen); + char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen); + +=head1 DESCRIPTION + +OPENSSL_hexchar2int() converts a hexadecimal character to its numeric +equivalent. + +OPENSSL_hexstr2buf_ex() decodes the hex string B and places the +resulting string of bytes in the given I. +I gives the size of the buffer. +If I is not NULL, it is filled in with the result length. +To find out how large the result will be, call this function with NULL +for I. +Colons between two-character hex "bytes" are accepted and ignored. +An odd number of hex digits is an error. + +OPENSSL_hexstr2buf() does the same thing as OPENSSL_hexstr2buf_ex(), +but allocates the space for the result, and returns the result. +The memory is allocated by calling OPENSSL_malloc() and should be +released by calling OPENSSL_free(). + +OPENSSL_buf2hexstr_ex() encodes the contents of the given I with +length I and places the resulting hexadecimal character string +in the given I. +I gives the size of the of the string buffer. +If I is not NULL, it is filled in with the result length. +To find out how large the result will be, call this function with NULL +for I. + +OPENSSL_buf2hexstr() does the same thing as OPENSSL_buf2hexstr_ex(), +but allocates the space for the result, and returns the result. +The memory is allocated by calling OPENSSL_malloc() and should be +released by calling OPENSSL_free(). + +=head1 RETURN VALUES + +OPENSSL_hexchar2int returns the value of a decoded hex character, +or -1 on error. + +OPENSSL_buf2hexstr() and OPENSSL_hexstr2buf() +return a pointer to allocated memory, or NULL on error. + +OPENSSL_buf2hexstr_ex() and OPENSSL_hexstr2buf_ex() return 1 on +success, or 0 on error. + +=head1 COPYRIGHT + +Copyright 2016-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/man3/OPENSSL_init_crypto.pod b/doc/man3/OPENSSL_init_crypto.pod index e20fc8c9..d1a3fd5d 100644 --- a/doc/man3/OPENSSL_init_crypto.pod +++ b/doc/man3/OPENSSL_init_crypto.pod @@ -101,10 +101,12 @@ B will be ignored. =item OPENSSL_INIT_LOAD_CONFIG With this option an OpenSSL configuration file will be automatically loaded and -used by calling OPENSSL_config(). This is not a default option for libcrypto. -As of OpenSSL 1.1.1 this is a default option for libssl (see -L for further details about libssl initialisation). See the -description of OPENSSL_INIT_new(), below. +used by calling OPENSSL_config(). This is a default option. +Note that in OpenSSL 1.1.1 this was the default for libssl but not for +libcrypto (see L for further details about libssl +initialisation). +In OpenSSL 1.1.0 this was a non-default option for both libssl and libcrypto. +See the description of OPENSSL_INIT_new(), below. =item OPENSSL_INIT_NO_LOAD_CONFIG @@ -229,7 +231,7 @@ B, B and B flags. The filename, application name, and flags can be customized by providing a non-null B object. -The object can be allocated via B. +The object can be allocated via B. The B function can be used to specify a non-default filename, which is copied and need not refer to persistent storage. Similarly, OPENSSL_INIT_set_config_appname() can be used to specify a diff --git a/doc/man3/OPENSSL_malloc.pod b/doc/man3/OPENSSL_malloc.pod index f1de27a1..198251fc 100644 --- a/doc/man3/OPENSSL_malloc.pod +++ b/doc/man3/OPENSSL_malloc.pod @@ -8,7 +8,6 @@ OPENSSL_clear_realloc, OPENSSL_clear_free, OPENSSL_cleanse, CRYPTO_malloc, CRYPTO_zalloc, CRYPTO_realloc, CRYPTO_free, OPENSSL_strdup, OPENSSL_strndup, OPENSSL_memdup, OPENSSL_strlcpy, OPENSSL_strlcat, -OPENSSL_hexstr2buf, OPENSSL_buf2hexstr, OPENSSL_hexchar2int, CRYPTO_strdup, CRYPTO_strndup, OPENSSL_mem_debug_push, OPENSSL_mem_debug_pop, CRYPTO_mem_debug_push, CRYPTO_mem_debug_pop, @@ -40,10 +39,6 @@ OPENSSL_MALLOC_FD void OPENSSL_clear_free(void *str, size_t num) void OPENSSL_cleanse(void *ptr, size_t len); - unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); - char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); - int OPENSSL_hexchar2int(unsigned char c); - void *CRYPTO_malloc(size_t num, const char *file, int line) void *CRYPTO_zalloc(size_t num, const char *file, int line) void *CRYPTO_realloc(void *p, size_t num, const char *file, int line) @@ -72,17 +67,18 @@ OPENSSL_MALLOC_FD int CRYPTO_mem_ctrl(int mode); - int OPENSSL_mem_debug_push(const char *info) - int OPENSSL_mem_debug_pop(void); - - int CRYPTO_mem_debug_push(const char *info, const char *file, int line); - int CRYPTO_mem_debug_pop(void); - int CRYPTO_mem_leaks(BIO *b); int CRYPTO_mem_leaks_fp(FILE *fp); int CRYPTO_mem_leaks_cb(int (*cb)(const char *str, size_t len, void *u), void *u); +Deprecated: + + int OPENSSL_mem_debug_push(const char *info) + int OPENSSL_mem_debug_pop(void); + int CRYPTO_mem_debug_push(const char *info, const char *file, int line); + int CRYPTO_mem_debug_pop(void); + =head1 DESCRIPTION OpenSSL memory allocation is handled by the B API. These are @@ -118,20 +114,6 @@ OPENSSL_strlcpy(), OPENSSL_strlcat() and OPENSSL_strnlen() are equivalents of the common C library functions and are provided for portability. -OPENSSL_hexstr2buf() parses B as a hex string and returns a -pointer to the parsed value. The memory is allocated by calling -OPENSSL_malloc() and should be released by calling OPENSSL_free(). -If B is not NULL, it is filled in with the output length. -Colons between two-character hex "bytes" are ignored. -An odd number of hex digits is an error. - -OPENSSL_buf2hexstr() takes the specified buffer and length, and returns -a hex string for value, or NULL on error. -B cannot be NULL; if B is 0 an empty string is returned. - -OPENSSL_hexchar2int() converts a character to the hexadecimal equivalent, -or returns -1 on error. - If no allocations have been done, it is possible to "swap out" the default implementations for OPENSSL_malloc(), OPENSSL_realloc and OPENSSL_free() and replace them with alternate versions (hooks). @@ -155,15 +137,6 @@ the B. To disable tracking call CRYPTO_mem_ctrl() with a B argument of the B. -While checking memory, it can be useful to store additional context -about what is being done. -For example, identifying the field names when parsing a complicated -data structure. -OPENSSL_mem_debug_push() (which calls CRYPTO_mem_debug_push()) -attachs an identifying string to the allocation stack. -This must be a global or other static string; it is not copied. -OPENSSL_mem_debug_pop() removes identifying state from the stack. - At the end of the program, calling CRYPTO_mem_leaks() or CRYPTO_mem_leaks_fp() will report all "leaked" memory, writing it to the specified BIO B or FILE B. These functions return 1 if @@ -207,6 +180,9 @@ to use this (will not work on all platforms): export OPENSSL_MALLOC_FD ...app invocation... 3>/tmp/log$$ +OPENSSL_mem_debug_push(), OPENSSL_mem_debug_pop(), +CRYPTO_mem_debug_push(), and CRYPTO_mem_debug_pop() +have been deprecated and replaced with functions that only return zero. =head1 RETURN VALUES @@ -221,7 +197,6 @@ OPENSSL_malloc(), OPENSSL_zalloc(), OPENSSL_realloc(), OPENSSL_clear_realloc(), CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_realloc(), CRYPTO_clear_realloc(), -OPENSSL_buf2hexstr(), OPENSSL_hexstr2buf(), OPENSSL_strdup(), and OPENSSL_strndup() return a pointer to allocated memory or NULL on error. @@ -232,16 +207,19 @@ always because allocations have already happened). CRYPTO_mem_ctrl() returns -1 if an error occurred, otherwise the previous value of the mode. -OPENSSL_mem_debug_push() and OPENSSL_mem_debug_pop() -return 1 on success or 0 on failure. - =head1 NOTES While it's permitted to swap out only a few and not all the functions with CRYPTO_set_mem_functions(), it's recommended to swap them all out -at once. I C I +at once, especially if OpenSSL was built with the +configuration option> C. + +=head1 HISTORY + +OPENSSL_mem_debug_push(), OPENSSL_mem_debug_pop(), +CRYPTO_mem_debug_push(), and CRYPTO_mem_debug_pop() +were deprecated in OpenSSL 3.0. + =head1 COPYRIGHT diff --git a/doc/man3/OPENSSL_s390xcap.pod b/doc/man3/OPENSSL_s390xcap.pod index e45da446..1f4ee85f 100644 --- a/doc/man3/OPENSSL_s390xcap.pod +++ b/doc/man3/OPENSSL_s390xcap.pod @@ -72,6 +72,7 @@ the numbering is continuous across 64-bit mask boundaries. #134 1<<57 vector packed decimal facility #135 1<<56 vector enhancements facility 1 #146 1<<45 message-security assist extension 8 + #155 1<<36 message-security assist extension 9 kimd : # 1 1<<62 KIMD-SHA-1 diff --git a/doc/man3/OSSL_CMP_ITAV_set0.pod b/doc/man3/OSSL_CMP_ITAV_set0.pod index 082b0bfe..348f47f1 100644 --- a/doc/man3/OSSL_CMP_ITAV_set0.pod +++ b/doc/man3/OSSL_CMP_ITAV_set0.pod @@ -59,7 +59,7 @@ return the respective pointer or NULL if their input is NULL. OSSL_CMP_ITAV_push0_stack_item() returns 1 on success, 0 on error. -=head1 EXAMPLE +=head1 EXAMPLES The following code creates and sets a structure representing a generic InfoTypeAndValue sequence, using an OID created from text as type, and an diff --git a/doc/man3/OSSL_CRMF_pbmp_new.pod b/doc/man3/OSSL_CRMF_pbmp_new.pod index cdd30ffc..4ebfa69d 100644 --- a/doc/man3/OSSL_CRMF_pbmp_new.pod +++ b/doc/man3/OSSL_CRMF_pbmp_new.pod @@ -49,7 +49,7 @@ OSSL_CRMF_pbm_new() returns 1 on success, 0 on error. OSSL_CRMF_pbmp_new() returns a new and initialized OSSL_CRMF_PBMPARAMETER structure, or NULL on error. -=head1 EXAMPLE +=head1 EXAMPLES OSSL_CRMF_PBMPARAMETER *pbm = NULL; unsigned char *msg = "Hello"; diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod index fbe37b4b..361028fa 100644 --- a/doc/man3/OSSL_PARAM.pod +++ b/doc/man3/OSSL_PARAM.pod @@ -19,7 +19,7 @@ OSSL_PARAM - a structure to pass or request object parameters =head1 DESCRIPTION -C is a type that allows passing arbitrary data for some +B is a type that allows passing arbitrary data for some object between two parties that have no or very little shared knowledge about their respective internal structures for that object. @@ -27,65 +27,82 @@ A typical usage example could be an application that wants to set some parameters for an object, or wants to find out some parameters of an object. -Arrays of this type can be used for two purposes: +Arrays of this type can be used for the following purposes: =over 4 -=item * +=item * Setting parameters for some object -Setting parameters for some object. -The caller sets up the C array and calls some function +The caller sets up the B array and calls some function (the I) that has intimate knowledge about the object that can -take the data from the C array and assign them in a +take the data from the B array and assign them in a suitable form for the internal structure of the object. -=item * +=item * Request parameters of some object -Request parameters of some object. -The caller (the I) sets up the C array and +The caller (the I) sets up the B array and calls some function (the I) that has intimate knowledge about the object, which can take the internal data of the object and copy (possibly convert) that to the memory prepared by the -I and pointed at with the C C. +I and pointed at with the B I. + +=item * Request parameter descriptors + +The caller gets an array of constant B, which describe +available parameters and some of their properties; name, data type and +expected data size. +For a detailed description of each field for this use, see the field +descriptions below. + +The caller may then use the information from this descriptor array to +build up its own B array to pass down to a I or +I. =back -=head2 C fields +Normally, the order of the an B array is not relevant. +However, if the I can handle multiple elements with the +same key, those elements must be handled in the order they are in. + +=head2 B fields =over 4 -=item C +=item I The identity of the parameter in the form of a string. -=item C +=item I -=for comment It's still debated if this field should be present, or if -the type should always be implied by how it's used. -Either way, these data types will have to be passed together with the -names as an array of OSSL_ITEM, for discovery purposes. - -The C is a value that describes the type and organization of +The I is a value that describes the type and organization of the data. See L below for a description of the types. -=item C +=item I -=item C +=item I -C is a pointer to the memory where the parameter data is (when +I is a pointer to the memory where the parameter data is (when setting parameters) or shall (when requesting parameters) be stored, -and C is its size in bytes. +and I is its size in bytes. The organization of the data depends on the parameter type and flag. -=item C +When the B is used as a parameter descriptor, I +should be ignored. +If I is zero, it means that an arbitrary data size is +accepted, otherwise it specifies the maximum size allowed. -When an array of C is used to request data, the +=item I + +When an array of B is used to request data, the I must set this field to indicate the actual size of the parameter data. -In case the C is too small for the data, the I +In case the I is too small for the data, the I must still set this field to indicate the minimum data size required. +When the B is used as a parameter descriptor, +I should be ignored. + =back B @@ -98,75 +115,75 @@ except for the pointer form of strings (see data type descriptions below). Entities that want to set or request parameters need to know what those keys are and of what type, any functionality between those two -entities should remain oblivious and just pass the C array +entities should remain oblivious and just pass the B array along. =head2 Supported types -The C field can be one of the following types: +The I field can be one of the following types: =over 4 -=item C +=item B -=item C +=item B The parameter data is an integer (signed or unsigned) of arbitrary length, organized in native form, i.e. most significant byte first on Big-Endian systems, and least significant byte first on Little-Endian systems. -=item C +=item B The parameter data is a floating point value in native form. -=item C +=item B The parameter data is a printable string. -=item C +=item B The parameter data is an arbitrary string of bytes. -=item C +=item B The parameter data is a pointer to a printable string. -The difference between this and C is that C +The difference between this and B is that I doesn't point directly at the data, but to a pointer that points to the data. This is used to indicate that constant data is or will be passed, and there is therefore no need to copy the data that is passed, just the pointer to it. -C must be set to the size of the data, not the size of the +I must be set to the size of the data, not the size of the pointer to the data. If this is used in a parameter request, -C is not relevant. However, the I will set -C to the size of the data. +I is not relevant. However, the I will set +I to the size of the data. Note that the use of this type is B and can only be safely used for data that remains constant and in a constant location for a long enough duration (such as the life-time of the entity that offers these parameters). -=item C +=item B The parameter data is a pointer to an arbitrary string of bytes. -The difference between this and C is that -C doesn't point directly at the data, but to a pointer that +The difference between this and B is that +I doesn't point directly at the data, but to a pointer that points to the data. This is used to indicate that constant data is or will be passed, and there is therefore no need to copy the data that is passed, just the pointer to it. -C must be set to the size of the data, not the size of the +I must be set to the size of the data, not the size of the pointer to the data. If this is used in a parameter request, -C is not relevant. However, the I will set -C to the size of the data. +I is not relevant. However, the I will set +I to the size of the data. Note that the use of this type is B and can only be safely used for data that remains constant and in a constant location for a @@ -196,10 +213,10 @@ enough set of data, that call should succeed. =item * -Apart from the C, a I must never change the fields -of an C. +Apart from the I, a I must never change the fields +of an B. To return a value, it should change the contents of the memory that -C points at. +I points at. =item * @@ -209,14 +226,14 @@ the called function may return an error. The called function may also try to convert the data to a suitable form (for example, it's plausible to pass a large number as an octet string, so even though a given key is defined as an -C, is plausible to pass the value as an -C), but this is in no way mandatory. +B, is plausible to pass the value as an +B), but this is in no way mandatory. =item * If a I finds that some data sizes are too small for the -requested data, it must set C for each such -C item to the required size, and eventually return an +requested data, it must set I for each such +B item to the required size, and eventually return an error. =back @@ -233,7 +250,7 @@ txt =head1 EXAMPLES -A couple of examples to just show how C arrays could be +A couple of examples to just show how B arrays could be set up. =head3 Example 1 @@ -265,7 +282,7 @@ This example is for requesting parameters on some object: { NULL, 0, NULL, 0, NULL } }; -A I that receives this array (as C in this example) +A I that receives this array (as I in this example) could fill in the parameters like this: /* OSSL_PARAM *params */ @@ -285,11 +302,11 @@ could fill in the parameters like this: =head1 SEE ALSO -L, L +L, L =head1 HISTORY -C was added in OpenSSL 3.0. +B was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OSSL_PARAM_construct_from_text.pod b/doc/man3/OSSL_PARAM_construct_from_text.pod new file mode 100644 index 00000000..6c7ff81e --- /dev/null +++ b/doc/man3/OSSL_PARAM_construct_from_text.pod @@ -0,0 +1,169 @@ +=pod + +=head1 NAME + +OSSL_PARAM_construct_from_text, OSSL_PARAM_allocate_from_text +- OSSL_PARAM construction utilities + +=head1 SYNOPSIS + + #include + + int OSSL_PARAM_construct_from_text(OSSL_PARAM *to, + const OSSL_PARAM *paramdefs, + const char *key, const char *value, + size_t value_n, + void *buf, size_t *buf_n) + int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, + const OSSL_PARAM *paramdefs, + const char *key, const char *value, + size_t value_n); + +=head1 DESCRIPTION + +With OpenSSL before version 3.0, parameters were passed down to or +retrieved from algorithm implementations via control functions. +Some of these control functions existed in variants that took string +parameters, for example L. + +OpenSSL 3.0 introduces a new mechanism to do the same thing with an +array of parameters that contain name, value, value type and value +size (see L for more information). + +OSSL_PARAM_construct_from_text() takes a control I, I and +value size I, and given a parameter descriptor array +I, it converts the value to something suitable for +L and stores that in the buffer I, and modifies +the parameter I to match. +I, if not NULL, will be assigned the number of bytes used in +I. +If I is NULL, only I will be modified, everything else is +left untouched, allowing a caller to find out how large the buffer +should be. +I needs to be correctly aligned for the type of the B +I. + +OSSL_PARAM_allocate_from_text() works like OSSL_PARAM_construct_from_text(), +except it allocates the buffer internally. +The caller must remember to free the data of I when it's not +useful any more. + +For parameters having the type B, +B, or B, both +functions will interpret the I differently if the key starts +with "hex". +In that case, the value is decoded first, and the result will be used +as parameter value. + +=head1 RETURN VALUES + +OSSL_PARAM_construct_from_text() and OSSL_PARAM_allocate_from_text() +returns 1 on success, and 0 on error. + +=head1 NOTES + +The parameter descriptor array comes from functions dedicated to +return them. +The following B attributes are used: + +=over 4 + +=item I + +=item I + +=item I + +=back + +All other attributes are ignored. + +The I attribute can be zero, meaning that the parameter it +describes expects arbitrary length data. + +=head1 EXAMPLES + +Code that looked like this: + + int mac_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) + { + int rv; + char *stmp, *vtmp = NULL; + + stmp = OPENSSL_strdup(value); + if (stmp == NULL) + return -1; + vtmp = strchr(stmp, ':'); + if (vtmp != NULL) + *vtmp++ = '\0'; + rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp); + OPENSSL_free(stmp); + return rv; + } + + ... + + + for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { + char *macopt = sk_OPENSSL_STRING_value(macopts, i); + + if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { + BIO_printf(bio_err, + "MAC parameter error \"%s\"\n", macopt); + ERR_print_errors(bio_err); + goto mac_end; + } + } + +Can be written like this instead: + + OSSL_PARAM *params = + OPENSSL_zalloc(sizeof(*params) + * (sk_OPENSSL_STRING_num(opts) + 1)); + const OSSL_PARAM *paramdefs = EVP_MAC_CTX_settable_params(mac); + size_t params_n; + char *opt = ""; + + for (params_n = 0; params_n < (size_t)sk_OPENSSL_STRING_num(opts); + params_n++) { + char *stmp, *vtmp = NULL; + + opt = sk_OPENSSL_STRING_value(opts, (int)params_n); + if ((stmp = OPENSSL_strdup(opt)) == NULL + || (vtmp = strchr(stmp, ':')) == NULL) + goto err; + + *vtmp++ = '\0'; + if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], + paramdefs, stmp, + vtmp, strlen(vtmp))) + goto err; + } + params[params_n] = OSSL_PARAM_construct_end(); + if (!EVP_MAC_CTX_set_params(ctx, params)) + goto err; + while (params_n-- > 0) + OPENSSL_free(params[params_n].data); + OPENSSL_free(params); + /* ... */ + return; + + err: + BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); + ERR_print_errors(bio_err); + + +=head1 SEE ALSO + +L, 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/man3/OSSL_PARAM_int.pod b/doc/man3/OSSL_PARAM_int.pod index 3aa6141f..742e8d57 100644 --- a/doc/man3/OSSL_PARAM_int.pod +++ b/doc/man3/OSSL_PARAM_int.pod @@ -6,25 +6,27 @@ OSSL_PARAM_double, OSSL_PARAM_int, OSSL_PARAM_int32, OSSL_PARAM_int64, OSSL_PARAM_long, OSSL_PARAM_size_t, OSSL_PARAM_uint, OSSL_PARAM_uint32, OSSL_PARAM_uint64, OSSL_PARAM_ulong, OSSL_PARAM_BN, OSSL_PARAM_utf8_string, OSSL_PARAM_octet_string, OSSL_PARAM_utf8_ptr, OSSL_PARAM_octet_ptr, -OSSL_PARAM_END, OSSL_PARAM_construct_BN, OSSL_PARAM_construct_double, -OSSL_PARAM_construct_int, OSSL_PARAM_construct_int32, -OSSL_PARAM_construct_int64, OSSL_PARAM_construct_long, -OSSL_PARAM_construct_size_t, OSSL_PARAM_construct_uint, -OSSL_PARAM_construct_uint32, OSSL_PARAM_construct_uint64, -OSSL_PARAM_construct_ulong, OSSL_PARAM_END, OSSL_PARAM_construct_BN, -OSSL_PARAM_construct_utf8_string, OSSL_PARAM_construct_utf8_ptr, -OSSL_PARAM_construct_octet_string, OSSL_PARAM_construct_octet_ptr, -OSSL_PARAM_construct_end, OSSL_PARAM_locate, OSSL_PARAM_locate_const, +OSSL_PARAM_END, +OSSL_PARAM_construct_double, OSSL_PARAM_construct_int, +OSSL_PARAM_construct_int32, OSSL_PARAM_construct_int64, +OSSL_PARAM_construct_long, OSSL_PARAM_construct_size_t, +OSSL_PARAM_construct_uint, OSSL_PARAM_construct_uint32, +OSSL_PARAM_construct_uint64, OSSL_PARAM_construct_ulong, +OSSL_PARAM_construct_BN, OSSL_PARAM_construct_utf8_string, +OSSL_PARAM_construct_utf8_ptr, OSSL_PARAM_construct_octet_string, +OSSL_PARAM_construct_octet_ptr, OSSL_PARAM_construct_end, +OSSL_PARAM_locate, OSSL_PARAM_locate_const, OSSL_PARAM_get_double, OSSL_PARAM_get_int, OSSL_PARAM_get_int32, OSSL_PARAM_get_int64, OSSL_PARAM_get_long, OSSL_PARAM_get_size_t, OSSL_PARAM_get_uint, OSSL_PARAM_get_uint32, OSSL_PARAM_get_uint64, -OSSL_PARAM_get_ulong, OSSL_PARAM_set_double, OSSL_PARAM_set_int, -OSSL_PARAM_set_int32, OSSL_PARAM_set_int64, OSSL_PARAM_set_long, -OSSL_PARAM_set_size_t, OSSL_PARAM_set_uint, OSSL_PARAM_set_uint32, -OSSL_PARAM_set_uint64, OSSL_PARAM_set_ulong, OSSL_PARAM_get_BN, -OSSL_PARAM_set_BN, OSSL_PARAM_get_utf8_string, OSSL_PARAM_set_utf8_string, -OSSL_PARAM_get_octet_string, OSSL_PARAM_set_octet_string, -OSSL_PARAM_get_utf8_ptr, OSSL_PARAM_set_utf8_ptr, OSSL_PARAM_get_octet_ptr, +OSSL_PARAM_get_ulong, OSSL_PARAM_get_BN, OSSL_PARAM_get_utf8_string, +OSSL_PARAM_get_octet_string, OSSL_PARAM_get_utf8_ptr, +OSSL_PARAM_get_octet_ptr, +OSSL_PARAM_set_double, OSSL_PARAM_set_int, OSSL_PARAM_set_int32, +OSSL_PARAM_set_int64, OSSL_PARAM_set_long, OSSL_PARAM_set_size_t, +OSSL_PARAM_set_uint, OSSL_PARAM_set_uint32, OSSL_PARAM_set_uint64, +OSSL_PARAM_set_ulong, OSSL_PARAM_set_BN, OSSL_PARAM_set_utf8_string, +OSSL_PARAM_set_octet_string, OSSL_PARAM_set_utf8_ptr, OSSL_PARAM_set_octet_ptr - OSSL_PARAM helpers @@ -34,15 +36,23 @@ OSSL_PARAM_set_octet_ptr #include + /* + * TYPE in function names is one of: + * double, int, int32, int64, long, size_t, uint, uint32, uint64, ulong + * Corresponding TYPE in function arguments is one of: + * double, int, int32_t, int64_t, long, size_t, unsigned int, uint32_t, + * uint64_t, unsigned long + */ + #define OSSL_PARAM_TYPE(key, address) + #define OSSL_PARAM_BN(key, address, size) #define OSSL_PARAM_utf8_string(key, address, size) #define OSSL_PARAM_octet_string(key, address, size) #define OSSL_PARAM_utf8_ptr(key, address, size) #define OSSL_PARAM_octet_ptr(key, address, size) - #define OSSL_PARAM_BN(key, address, size) #define OSSL_PARAM_END - OSSL_PARAM OSSL_PARAM_construct_TYPE(const char *key, TYPE *buf, size_t *ret); + OSSL_PARAM OSSL_PARAM_construct_TYPE(const char *key, TYPE *buf); OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, size_t bsize); OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, @@ -59,11 +69,11 @@ OSSL_PARAM_set_octet_ptr const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *array, const char *key); - int OSSL_PARAM_get_TYPE(const OSSL_PARAM *p, const char *key, TYPE *val); - int OSSL_PARAM_set_TYPE(OSSL_PARAM *p, const char *key, TYPE val); + int OSSL_PARAM_get_TYPE(const OSSL_PARAM *p, TYPE *val); + int OSSL_PARAM_set_TYPE(OSSL_PARAM *p, TYPE val); - int OSSL_PARAM_get_BN(const OSSL_PARAM *p, const char *key, BIGNUM **val); - int OSSL_PARAM_set_BN(OSSL_PARAM *p, const char *key, const BIGNUM *val); + int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val); + int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val); int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len); @@ -73,12 +83,13 @@ OSSL_PARAM_set_octet_ptr size_t max_len, size_t *used_len); int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, size_t len); - int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, char **val); - int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, char *val); + int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val); + int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val); - int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, void **val, + int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, size_t *used_len); - int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, void *val, size_t used_len); + int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, + size_t used_len); =head1 DESCRIPTION @@ -155,23 +166,22 @@ size B is created. OSSL_PARAM_construct_utf8_string() is a function that constructs a UTF8 string OSSL_PARAM structure. -A parameter with name B, storage B, size B and return -size B is created. +A parameter with name B, storage B and size B is created. +If B is zero, the string length is determined using strlen(3). OSSL_PARAM_construct_octet_string() is a function that constructs an OCTET string OSSL_PARAM structure. -A parameter with name B, storage B, size B and return -size B is created. +A parameter with name B, storage B and size B is created. OSSL_PARAM_construct_utf8_ptr() is a function that constructes a UTF string pointer OSSL_PARAM structure. -A parameter with name B, storage pointer B<*buf>, size B and -return size B is created. +A parameter with name B, storage pointer B<*buf> and size B +is created. OSSL_PARAM_construct_octet_ptr() is a function that constructes an OCTET string pointer OSSL_PARAM structure. -A parameter with name B, storage pointer B<*buf>, size B and -return size B is created. +A parameter with name B, storage pointer B<*buf> and size B +is created. OSSL_PARAM_construct_end() is a function that constructs the terminating OSSL_PARAM structure. @@ -312,7 +322,7 @@ L, L =head1 HISTORY -These APIs were introduced in OpenSSL 3.0.0. +These APIs were introduced in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 9fe2e18a..f4f8a3bd 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -3,8 +3,9 @@ =head1 NAME OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_unload, -OSSL_PROVIDER_get_param_types, OSSL_PROVIDER_get_params, -OSSL_PROVIDER_add_builtin - provider routines +OSSL_PROVIDER_available, +OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params, +OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines =head1 SYNOPSIS @@ -12,15 +13,18 @@ OSSL_PROVIDER_add_builtin - provider routines typedef struct ossl_provider_st OSSL_PROVIDER; - OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name); + OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); + int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name); - const OSSL_ITEM *OSSL_PROVIDER_get_param_types(OSSL_PROVIDER *prov); + const OSSL_PARAM *OSSL_PROVIDER_gettable_params(OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]); - int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *, const char *name, + int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, ossl_provider_init_fn *init_fn); + const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov); + =head1 DESCRIPTION B is a type that holds internal information about @@ -30,6 +34,9 @@ A provider can be built in to the application or the OpenSSL libraries, or can be a loadable module. The functions described here handle both forms. +Some of these functions operate within a library context, please see +L for further details. + =head2 Functions OSSL_PROVIDER_add_builtin() is used to add a built in provider to @@ -47,18 +54,20 @@ OSSL_PROVIDER_unload() unloads the given provider. For a provider added with OSSL_PROVIDER_add_builtin(), this simply runs its teardown function. -OSSL_PROVIDER_get_param_types() is used to get a provider parameter -descriptor set as an B array. -Each element is a tuple of an B parameter type and a name -in form of a C string. -See L for more information on B and -parameter types. +OSSL_PROVIDER_available() checks if a named provider is available +for use. + +OSSL_PROVIDER_gettable_params() is used to get a provider parameter +descriptor set as a constant B array. +See L for more information. OSSL_PROVIDER_get_params() is used to get provider parameter values. The caller must prepare the B array before calling this function, and the variables acting as buffers for this parameter array should be filled with data when it returns successfully. +OSSL_PROVIDER_name() returns the name of the given provider. + =head1 RETURN VALUES OSSL_PROVIDER_add() returns 1 on success, or 0 on error. @@ -68,8 +77,11 @@ success, or B on error. OSSL_PROVIDER_unload() returns 1 on success, or 0 on error. -OSSL_PROVIDER_get_param_types() returns a pointer to a constant array -of B, or NULL if none is provided. +OSSL_PROVIDER_available() returns 1 if the named provider is available, +otherwise 0. + +OSSL_PROVIDER_gettable_params() returns a pointer to an array +of constant B, or NULL if none is provided. OSSL_PROVIDER_get_params() returns 1 on success, or 0 on error. @@ -94,7 +106,7 @@ its build number. =head1 SEE ALSO -L, L +L, L, L =head1 HISTORY diff --git a/doc/man3/OSSL_trace_enabled.pod b/doc/man3/OSSL_trace_enabled.pod index 958e8b06..2ced3d41 100644 --- a/doc/man3/OSSL_trace_enabled.pod +++ b/doc/man3/OSSL_trace_enabled.pod @@ -278,7 +278,7 @@ otherwise C. =head1 HISTORY -The OpenSSL Tracing API was added ino OpenSSL 3.0.0. +The OpenSSL Tracing API was added ino OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OSSL_trace_get_category_num.pod b/doc/man3/OSSL_trace_get_category_num.pod index 886d0f15..5ab05a3a 100644 --- a/doc/man3/OSSL_trace_get_category_num.pod +++ b/doc/man3/OSSL_trace_get_category_num.pod @@ -30,7 +30,7 @@ C is a recognised category number, otherwise NULL. =head1 HISTORY -The OpenSSL Tracing API was added ino OpenSSL 3.0.0. +The OpenSSL Tracing API was added ino OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OSSL_trace_set_channel.pod b/doc/man3/OSSL_trace_set_channel.pod index cb349674..f214abdb 100644 --- a/doc/man3/OSSL_trace_set_channel.pod +++ b/doc/man3/OSSL_trace_set_channel.pod @@ -1,5 +1,7 @@ =pod +=for comment foreign manuals: atexit(3) + =head1 NAME OSSL_trace_set_channel, OSSL_trace_set_prefix, OSSL_trace_set_suffix, @@ -212,7 +214,7 @@ the following: BIO_dump(trc_out, bar, sizeof(bar)); } OSSL_TRACE_END(TLS); -=head1 Simple example +=head2 Simple example An example with just a channel and constant prefix / suffix. @@ -297,7 +299,7 @@ functions described here are inoperational, i.e. will do nothing. OSSL_trace_set_channel(), OSSL_trace_set_prefix(), OSSL_trace_set_suffix(), and OSSL_trace_set_callback() were all added -in OpenSSL 3.0.0. +in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/OpenSSL_version.pod b/doc/man3/OpenSSL_version.pod index c1ced643..66abd3e4 100644 --- a/doc/man3/OpenSSL_version.pod +++ b/doc/man3/OpenSSL_version.pod @@ -125,6 +125,20 @@ if available or "OPENSSLDIR: N/A" otherwise. The "ENGINESDIR" setting of the library build in the form "ENGINESDIR: "..."" if available or "ENGINESDIR: N/A" otherwise. +=item OPENSSL_MODULES_DIR + +The "MODULESDIR" setting of the library build in the form "MODULESDIR: "..."" +if available or "MODULESDIR: N/A" otherwise. + +=item OPENSSL_CPU_INFO + +The current OpenSSL cpu settings. +This is the current setting of the cpu capability flags. It is usually +automatically configured but may be set via an environment variable. +The value has the same syntax as the environment variable. +For x86 the string looks like "CPUINFO: OPENSSL_ia32cap=0x123:0x456". +Or "CPUINFO: N/A" if not available, e.g. no-asm build. + =back For an unknown B, the text "not available" is returned. @@ -166,6 +180,14 @@ value of the environment variable C<$PATH> on Unix (where the separator is ":") or C<%PATH%> on Windows (where the separator is ";"). +=item OPENSSL_INFO_CPU_SETTINGS + +The current OpenSSL cpu settings. +This is the current setting of the cpu capability flags. It is usually +automatically configured but may be set via an environment variable. +The value has the same syntax as the environment variable. +For x86 the string looks like "OPENSSL_ia32cap=0x123:0x456". + =back For an unknown B, NULL is returned. @@ -219,12 +241,12 @@ L =head1 HISTORY -The macros and functions described here were added in OpenSSL 3.0.0, +The macros and functions described here were added in OpenSSL 3.0, with the exception of the L ones. =head1 COPYRIGHT -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 diff --git a/doc/man3/PKCS12_newpass.pod b/doc/man3/PKCS12_newpass.pod index 14cfcdf1..52d349e7 100644 --- a/doc/man3/PKCS12_newpass.pod +++ b/doc/man3/PKCS12_newpass.pod @@ -17,8 +17,6 @@ PKCS12_newpass() changes the password of a PKCS12 structure. B is a pointer to a PKCS12 structure. B is the existing password and B is the new password. -=head1 NOTES - Each of B and B is independently interpreted as a string in the UTF-8 encoding. If it is not valid UTF-8, it is assumed to be ISO8859-1 instead. @@ -29,12 +27,21 @@ use. This may include passwords from local text files, or input from the terminal or command line. Refer to the documentation of L, for example. +If the PKCS#12 structure does not have a password, then you must use the empty +string "" for B. Using NULL for B will result in a +PKCS12_newpass() failure. + +If the wrong password is used for B then the function will fail, +with a MAC verification error. In rare cases the PKCS12 structure does not +contain a MAC: in this case it will usually fail with a decryption padding +error. + =head1 RETURN VALUES PKCS12_newpass() returns 1 on success or 0 on failure. Applications can retrieve the most recent error from PKCS12_newpass() with ERR_get_error(). -=head1 EXAMPLE +=head1 EXAMPLES This example loads a PKCS#12 file, changes its password and writes out the result to a new file. @@ -83,17 +90,6 @@ the result to a new file. } -=head1 NOTES - -If the PKCS#12 structure does not have a password, then you must use the empty -string "" for B. Using NULL for B will result in a -PKCS12_newpass() failure. - -If the wrong password is used for B then the function will fail, -with a MAC verification error. In rare cases the PKCS12 structure does not -contain a MAC: in this case it will usually fail with a decryption padding -error. - =head1 BUGS The password format is a NULL terminated ASCII string which is converted to diff --git a/doc/man3/PKCS7_encrypt.pod b/doc/man3/PKCS7_encrypt.pod index 44b985e7..b2d07e8e 100644 --- a/doc/man3/PKCS7_encrypt.pod +++ b/doc/man3/PKCS7_encrypt.pod @@ -17,8 +17,6 @@ PKCS7_encrypt() creates and returns a PKCS#7 envelopedData structure. B is a list of recipient certificates. B is the content to be encrypted. B is the symmetric cipher to use. B is an optional set of flags. -=head1 NOTES - Only RSA keys are supported in PKCS#7 and envelopedData so the recipient certificates supplied to this function must all contain RSA public keys, though they do not have to be signed using the RSA algorithm. @@ -52,8 +50,6 @@ B is ignored. If the B flag is set a partial B structure is output suitable for streaming I/O: no data is read from the BIO B. -=head1 NOTES - If the flag B is set the returned B structure is B complete and outputting its contents via a function that does not properly finalize the B structure will give unpredictable diff --git a/doc/man3/PKCS7_sign.pod b/doc/man3/PKCS7_sign.pod index 4a14aac7..f53e7b4c 100644 --- a/doc/man3/PKCS7_sign.pod +++ b/doc/man3/PKCS7_sign.pod @@ -22,8 +22,6 @@ The data to be signed is read from BIO B. B is an optional set of flags. -=head1 NOTES - Any of the following flags (ored together) can be passed in the B parameter. @@ -66,8 +64,6 @@ way data can be signed in a single pass. If the B flag is set a partial B structure is output to which additional signers and capabilities can be added before finalization. -=head1 NOTES - If the flag B is set the returned B structure is B complete and outputting its contents via a function that does not properly finalize the B structure will give unpredictable results. diff --git a/doc/man3/RAND_DRBG_generate.pod b/doc/man3/RAND_DRBG_generate.pod index e0778ea2..def98a96 100644 --- a/doc/man3/RAND_DRBG_generate.pod +++ b/doc/man3/RAND_DRBG_generate.pod @@ -76,7 +76,7 @@ L The RAND_DRBG functions were added in OpenSSL 1.1.1. -Prediction resistance is supported from OpenSSL 3.0.0. +Prediction resistance is supported from OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/RAND_DRBG_reseed.pod b/doc/man3/RAND_DRBG_reseed.pod index 40375603..b73f35fb 100644 --- a/doc/man3/RAND_DRBG_reseed.pod +++ b/doc/man3/RAND_DRBG_reseed.pod @@ -104,7 +104,7 @@ L The RAND_DRBG functions were added in OpenSSL 1.1.1. -Prediction resistance is supported from OpenSSL 3.0.0. +Prediction resistance is supported from OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/RAND_set_rand_method.pod b/doc/man3/RAND_set_rand_method.pod index e1320f6d..26188d28 100644 --- a/doc/man3/RAND_set_rand_method.pod +++ b/doc/man3/RAND_set_rand_method.pod @@ -10,7 +10,7 @@ RAND_set_rand_method, RAND_get_rand_method, RAND_OpenSSL - select RAND method RAND_METHOD *RAND_OpenSSL(void); - void RAND_set_rand_method(const RAND_METHOD *meth); + int RAND_set_rand_method(const RAND_METHOD *meth); const RAND_METHOD *RAND_get_rand_method(void); @@ -48,8 +48,9 @@ Each pointer may be NULL if the function is not implemented. =head1 RETURN VALUES -RAND_set_rand_method() returns no value. RAND_get_rand_method() and -RAND_OpenSSL() return pointers to the respective methods. +RAND_set_rand_method() returns 1 on success and 0 on failue. +RAND_get_rand_method() and RAND_OpenSSL() return pointers to the respective +methods. =head1 SEE ALSO diff --git a/doc/man3/RSA_padding_add_PKCS1_type_1.pod b/doc/man3/RSA_padding_add_PKCS1_type_1.pod index 40eb8f94..6e679bba 100644 --- a/doc/man3/RSA_padding_add_PKCS1_type_1.pod +++ b/doc/man3/RSA_padding_add_PKCS1_type_1.pod @@ -123,7 +123,7 @@ The RSA_padding_check_xxx() functions return the length of the recovered data, -1 on error. Error codes can be obtained by calling L. -=head1 WARNING +=head1 WARNINGS The result of RSA_padding_check_PKCS1_type_2() is a very sensitive information which can potentially be used to mount a Bleichenbacher diff --git a/doc/man3/RSA_public_encrypt.pod b/doc/man3/RSA_public_encrypt.pod index 9c75944c..09f26ebc 100644 --- a/doc/man3/RSA_public_encrypt.pod +++ b/doc/man3/RSA_public_encrypt.pod @@ -81,7 +81,7 @@ means only that the plaintext was empty. On error, -1 is returned; the error codes can be obtained by L. -=head1 WARNING +=head1 WARNINGS Decryption failures in the RSA_PKCS1_PADDING mode leak information which can potentially be used to mount a Bleichenbacher padding oracle diff --git a/doc/man3/SRP_VBASE_new.pod b/doc/man3/SRP_VBASE_new.pod index d780cf24..0a7b117c 100644 --- a/doc/man3/SRP_VBASE_new.pod +++ b/doc/man3/SRP_VBASE_new.pod @@ -83,7 +83,7 @@ L =head1 HISTORY -The SRP_VBASE_add0_user() function was added in OpenSSL 3.0.0. +The SRP_VBASE_add0_user() function was added in OpenSSL 3.0. All other functions were added in OpenSSL 1.0.1. diff --git a/doc/man3/SRP_user_pwd_new.pod b/doc/man3/SRP_user_pwd_new.pod index b1799d17..9d9e11d9 100644 --- a/doc/man3/SRP_user_pwd_new.pod +++ b/doc/man3/SRP_user_pwd_new.pod @@ -56,7 +56,7 @@ L =head1 HISTORY -These functions were made public in OpenSSL 3.0.0. +These functions were made public in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_config.pod b/doc/man3/SSL_CTX_config.pod index a05009e5..dfdc3d21 100644 --- a/doc/man3/SSL_CTX_config.pod +++ b/doc/man3/SSL_CTX_config.pod @@ -33,7 +33,7 @@ file syntax. SSL_CTX_config() and SSL_config() return 1 for success or 0 if an error occurred. -=head1 EXAMPLE +=head1 EXAMPLES If the file "config.cnf" contains the following: diff --git a/doc/man3/SSL_CTX_dane_enable.pod b/doc/man3/SSL_CTX_dane_enable.pod index f051c5a3..c43d6f90 100644 --- a/doc/man3/SSL_CTX_dane_enable.pod +++ b/doc/man3/SSL_CTX_dane_enable.pod @@ -181,7 +181,7 @@ The functions SSL_CTX_dane_set_flags(), SSL_CTX_dane_clear_flags(), SSL_dane_set_flags() and SSL_dane_clear_flags() return the B in effect before they were called. -=head1 EXAMPLE +=head1 EXAMPLES Suppose "smtp.example.com" is the MX host of the domain "example.com", and has DNSSEC-validated TLSA records. diff --git a/doc/man3/SSL_CTX_get0_param.pod b/doc/man3/SSL_CTX_get0_param.pod index ff970645..19e7f189 100644 --- a/doc/man3/SSL_CTX_get0_param.pod +++ b/doc/man3/SSL_CTX_get0_param.pod @@ -29,13 +29,6 @@ Typically parameters are retrieved from an B or B structure using SSL_CTX_get0_param() or SSL_get0_param() and an application modifies them to suit its needs: for example to add a hostname check. -=head1 EXAMPLE - -Check hostname matches "www.foo.com" in peer certificate: - - X509_VERIFY_PARAM *vpm = SSL_get0_param(ssl); - X509_VERIFY_PARAM_set1_host(vpm, "www.foo.com", 0); - =head1 RETURN VALUES SSL_CTX_get0_param() and SSL_get0_param() return a pointer to an @@ -44,6 +37,13 @@ B structure. SSL_CTX_set1_param() and SSL_set1_param() return 1 for success and 0 for failure. +=head1 EXAMPLES + +Check hostname matches "www.foo.com" in peer certificate: + + X509_VERIFY_PARAM *vpm = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set1_host(vpm, "www.foo.com", 0); + =head1 SEE ALSO L diff --git a/doc/man3/SSL_CTX_set1_curves.pod b/doc/man3/SSL_CTX_set1_curves.pod index bb58a4db..13b1c0e4 100644 --- a/doc/man3/SSL_CTX_set1_curves.pod +++ b/doc/man3/SSL_CTX_set1_curves.pod @@ -4,8 +4,8 @@ SSL_CTX_set1_groups, SSL_CTX_set1_groups_list, SSL_set1_groups, SSL_set1_groups_list, SSL_get1_groups, SSL_get_shared_group, -SSL_CTX_set1_curves, SSL_CTX_set1_curves_list, SSL_set1_curves, -SSL_set1_curves_list, SSL_get1_curves, SSL_get_shared_curve +SSL_get_negotiated_group, SSL_CTX_set1_curves, SSL_CTX_set1_curves_list, +SSL_set1_curves, SSL_set1_curves_list, SSL_get1_curves, SSL_get_shared_curve - EC supported curve functions =head1 SYNOPSIS @@ -20,6 +20,7 @@ SSL_set1_curves_list, SSL_get1_curves, SSL_get_shared_curve int SSL_get1_groups(SSL *ssl, int *groups); int SSL_get_shared_group(SSL *s, int n); + int SSL_get_negotiated_group(SSL *s); int SSL_CTX_set1_curves(SSL_CTX *ctx, int *clist, int clistlen); int SSL_CTX_set1_curves_list(SSL_CTX *ctx, char *list); @@ -68,6 +69,9 @@ most applications will only be interested in the first shared group so B is normally set to zero. If the value B is out of range, NID_undef is returned. +SSL_get_negotiated_group() returns the negotiated group on a TLSv1.3 connection +for key exchange. This can be called by either client or server. + All these functions are implemented as macros. The curve functions are synonyms for the equivalently named group functions and @@ -96,6 +100,10 @@ is -1. When called on a client B, SSL_get_shared_group() has no meaning and returns -1. +SSL_get_negotiated_group() returns the NID of the negotiated group on a +TLSv1.3 connection for key exchange. Or it returns NID_undef if no negotiated +group. + =head1 SEE ALSO L @@ -103,7 +111,8 @@ L =head1 HISTORY The curve functions were added in OpenSSL 1.0.2. The equivalent group -functions were added in OpenSSL 1.1.1. +functions were added in OpenSSL 1.1.1. The SSL_get_negotiated_group() function +was added in OpenSSL 3.0.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_cipher_list.pod b/doc/man3/SSL_CTX_set_cipher_list.pod index 18524054..c602ac0d 100644 --- a/doc/man3/SSL_CTX_set_cipher_list.pod +++ b/doc/man3/SSL_CTX_set_cipher_list.pod @@ -96,7 +96,7 @@ and the handshake will fail. OSSL_default_cipher_list() and OSSL_default_ciphersuites() replace SSL_DEFAULT_CIPHER_LIST and TLS_DEFAULT_CIPHERSUITES, respectively. The -cipher list defines are deprecated as of 3.0.0. +cipher list defines are deprecated as of 3.0. =head1 RETURN VALUES @@ -115,7 +115,7 @@ L =head1 HISTORY -OSSL_default_cipher_list() and OSSL_default_ciphersites() are new in 3.0.0. +OSSL_default_cipher_list() and OSSL_default_ciphersites() are new in 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_mode.pod b/doc/man3/SSL_CTX_set_mode.pod index a4997c96..f1f6c7a5 100644 --- a/doc/man3/SSL_CTX_set_mode.pod +++ b/doc/man3/SSL_CTX_set_mode.pod @@ -150,7 +150,7 @@ L, L =head1 HISTORY SSL_MODE_ASYNC was added in OpenSSL 1.1.0. -SSL_MODE_NO_KTLS_TX was added in OpenSSL 3.0.0. +SSL_MODE_NO_KTLS_TX was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 7626bd33..82dd64fe 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -313,7 +313,7 @@ unaware of the unpatched nature of the client. If the option B is set then renegotiation B succeeds. -=head2 Patched OpenSSL client and unpatched server. +=head2 Patched OpenSSL client and unpatched server If the option B or B is set then initial connections @@ -374,7 +374,7 @@ OpenSSL 0.9.8m. The B and B options were added in OpenSSL 1.1.1. -The B option was added in OpenSSL 3.0.0. +The B option was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_session_id_context.pod b/doc/man3/SSL_CTX_set_session_id_context.pod index a77bf8e6..ccc10a7e 100644 --- a/doc/man3/SSL_CTX_set_session_id_context.pod +++ b/doc/man3/SSL_CTX_set_session_id_context.pod @@ -42,7 +42,7 @@ OpenSSL clients will check the session id context returned by the server when reusing a session. The maximum length of the B is limited to -B. +B. =head1 WARNINGS @@ -67,7 +67,7 @@ return the following values: =item Z<>0 The length B of the session id context B exceeded -the maximum allowed length of B. The error +the maximum allowed length of B. The error is logged to the error stack. =item Z<>1 diff --git a/doc/man3/SSL_CTX_use_psk_identity_hint.pod b/doc/man3/SSL_CTX_use_psk_identity_hint.pod index ac8636b4..2335dc40 100644 --- a/doc/man3/SSL_CTX_use_psk_identity_hint.pod +++ b/doc/man3/SSL_CTX_use_psk_identity_hint.pod @@ -85,8 +85,6 @@ check to see if a callback has been set via SSL_CTX_set_psk_server_callback() or SSL_set_psk_server_callback() and use that. In this case the handshake digest will default to SHA-256 for any returned PSK. -=head1 NOTES - A connection established via a TLSv1.3 PSK will appear as if session resumption has occurred so that L will return true. diff --git a/doc/man3/SSL_library_init.pod b/doc/man3/SSL_library_init.pod index ff49a83e..1b56c3b8 100644 --- a/doc/man3/SSL_library_init.pod +++ b/doc/man3/SSL_library_init.pod @@ -25,7 +25,7 @@ implemented as a macro. SSL_library_init() must be called before any other action takes place. SSL_library_init() is not reentrant. -=head1 WARNING +=head1 WARNINGS SSL_library_init() adds ciphers and digests used directly and indirectly by SSL/TLS. diff --git a/doc/man3/SSL_set1_host.pod b/doc/man3/SSL_set1_host.pod index 3fc6ec37..98bc6fd4 100644 --- a/doc/man3/SSL_set1_host.pod +++ b/doc/man3/SSL_set1_host.pod @@ -71,7 +71,7 @@ applicable (as with RFC7671 DANE-EE(3)), or no trusted peername was matched. Otherwise, it returns the matched peername. To determine whether verification succeeded call L. -=head1 EXAMPLE +=head1 EXAMPLES Suppose "smtp.example.com" is the MX host of the domain "example.com". The calls below will arrange to match either the MX hostname or the diff --git a/doc/man3/SSL_set_async_callback.pod b/doc/man3/SSL_set_async_callback.pod index 5e7f61ea..24cf02c1 100644 --- a/doc/man3/SSL_set_async_callback.pod +++ b/doc/man3/SSL_set_async_callback.pod @@ -82,7 +82,7 @@ SSL_get_async_status() return 1 on success or 0 on error. SSL_CTX_set_async_callback(), SSL_CTX_set_async_callback_arg(), SSL_set_async_callback(), SSL_set_async_callback_arg() and -SSL_get_async_status() were first added to OpenSSL 3.0.0. +SSL_get_async_status() were first added to OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_shutdown.pod b/doc/man3/SSL_shutdown.pod index 6e470a1a..608cd719 100644 --- a/doc/man3/SSL_shutdown.pod +++ b/doc/man3/SSL_shutdown.pod @@ -15,8 +15,6 @@ SSL_shutdown - shut down a TLS/SSL connection SSL_shutdown() shuts down an active TLS/SSL connection. It sends the close_notify shutdown alert to the peer. -=head1 NOTES - SSL_shutdown() tries to send the close_notify shutdown alert to the peer. Whether the operation succeeds or not, the SSL_SENT_SHUTDOWN flag is set and a currently open session is considered closed and good and will be kept in the @@ -52,6 +50,32 @@ SSL_shutdown() only closes the write direction. It is not possible to call SSL_write() after calling SSL_shutdown(). The read direction is closed by the peer. +The behaviour of SSL_shutdown() additionally depends on the underlying BIO. +If the underlying BIO is B, SSL_shutdown() will only return once the +handshake step has been finished or an error occurred. + +If the underlying BIO is B, SSL_shutdown() will also return +when the underlying BIO could not satisfy the needs of SSL_shutdown() +to continue the handshake. In this case a call to SSL_get_error() with the +return value of SSL_shutdown() will yield B or +B. The calling process then must repeat the call after +taking appropriate action to satisfy the needs of SSL_shutdown(). +The action depends on the underlying BIO. When using a non-blocking socket, +nothing is to be done, but select() can be used to check for the required +condition. When using a buffering BIO, like a BIO pair, data must be written +into or retrieved out of the BIO before being able to continue. + +After SSL_shutdown() returned 0, it is possible to call SSL_shutdown() again +to wait for the peer's close_notify alert. +SSL_shutdown() will return 1 in that case. +However, it is recommended to wait for it using SSL_read() instead. + +SSL_shutdown() can be modified to only set the connection to "shutdown" +state but not actually send the close_notify alert messages, +see L. +When "quiet shutdown" is enabled, SSL_shutdown() will always succeed +and return 1. + =head2 First to close the connection When the application is the first party to send the close_notify @@ -89,34 +113,6 @@ If successful, SSL_shutdown() will return 1. Whether SSL_RECEIVED_SHUTDOWN is already set can be checked using the SSL_get_shutdown() (see also L call. -=head1 NOTES - -The behaviour of SSL_shutdown() additionally depends on the underlying BIO. -If the underlying BIO is B, SSL_shutdown() will only return once the -handshake step has been finished or an error occurred. - -If the underlying BIO is B, SSL_shutdown() will also return -when the underlying BIO could not satisfy the needs of SSL_shutdown() -to continue the handshake. In this case a call to SSL_get_error() with the -return value of SSL_shutdown() will yield B or -B. The calling process then must repeat the call after -taking appropriate action to satisfy the needs of SSL_shutdown(). -The action depends on the underlying BIO. When using a non-blocking socket, -nothing is to be done, but select() can be used to check for the required -condition. When using a buffering BIO, like a BIO pair, data must be written -into or retrieved out of the BIO before being able to continue. - -After SSL_shutdown() returned 0, it is possible to call SSL_shutdown() again -to wait for the peer's close_notify alert. -SSL_shutdown() will return 1 in that case. -However, it is recommended to wait for it using SSL_read() instead. - -SSL_shutdown() can be modified to only set the connection to "shutdown" -state but not actually send the close_notify alert messages, -see L. -When "quiet shutdown" is enabled, SSL_shutdown() will always succeed -and return 1. - =head1 RETURN VALUES The following return values can occur: diff --git a/doc/man3/SSL_write.pod b/doc/man3/SSL_write.pod index a1ceb202..56a8c8b1 100644 --- a/doc/man3/SSL_write.pod +++ b/doc/man3/SSL_write.pod @@ -66,7 +66,7 @@ operation is considered completed. The bytes are sent and a new write call with a new buffer (with the already sent bytes removed) must be started. A partial write is performed with the size of a message block, which is 16kB. -=head1 WARNING +=head1 WARNINGS When a write function call has to be repeated because L returned B or B, it must be repeated @@ -141,7 +141,7 @@ L, L =head1 HISTORY The SSL_write_ex() function was added in OpenSSL 1.1.1. -The SSL_sendfile() function was added in OpenSSL 3.0.0. +The SSL_sendfile() function was added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/X509_PUBKEY_new.pod b/doc/man3/X509_PUBKEY_new.pod index 2d65be6b..551031b8 100644 --- a/doc/man3/X509_PUBKEY_new.pod +++ b/doc/man3/X509_PUBKEY_new.pod @@ -2,8 +2,9 @@ =head1 NAME -X509_PUBKEY_new, X509_PUBKEY_free, X509_PUBKEY_set, X509_PUBKEY_get0, -X509_PUBKEY_get, d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_bio, d2i_PUBKEY_fp, +X509_PUBKEY_new, X509_PUBKEY_free, X509_PUBKEY_dup, +X509_PUBKEY_set, X509_PUBKEY_get0, X509_PUBKEY_get, +d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_bio, d2i_PUBKEY_fp, i2d_PUBKEY_fp, i2d_PUBKEY_bio, X509_PUBKEY_set0_param, X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions @@ -13,6 +14,7 @@ X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions X509_PUBKEY *X509_PUBKEY_new(void); void X509_PUBKEY_free(X509_PUBKEY *a); + X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a); int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); diff --git a/doc/man3/X509_STORE_CTX_get_error.pod b/doc/man3/X509_STORE_CTX_get_error.pod index 5c6779a6..6c75bee9 100644 --- a/doc/man3/X509_STORE_CTX_get_error.pod +++ b/doc/man3/X509_STORE_CTX_get_error.pod @@ -101,8 +101,8 @@ the operation was successful. =item B -the issuer certificate could not be found: this occurs if the issuer certificate -of an untrusted certificate cannot be found. +the issuer certificate of a locally looked up certificate could not be found. +This normally means the list of trusted certificates is not complete. =item B @@ -180,8 +180,8 @@ the root could not be found locally. =item B -the issuer certificate of a locally looked up certificate could not be found. -This normally means the list of trusted certificates is not complete. +the issuer certificate could not be found: this occurs if the issuer certificate +of an untrusted certificate cannot be found. =item B diff --git a/doc/man3/X509_STORE_CTX_new.pod b/doc/man3/X509_STORE_CTX_new.pod index 89e548dc..db8416fa 100644 --- a/doc/man3/X509_STORE_CTX_new.pod +++ b/doc/man3/X509_STORE_CTX_new.pod @@ -28,7 +28,7 @@ X509_STORE_CTX_verify_fn void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x); - STACK_OF(X509) *X509_STORE_CTX_get0_chain(X609_STORE_CTX *ctx); + STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *chain); void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); diff --git a/doc/man3/X509_STORE_CTX_set_verify_cb.pod b/doc/man3/X509_STORE_CTX_set_verify_cb.pod index 6e462467..64ccefa7 100644 --- a/doc/man3/X509_STORE_CTX_set_verify_cb.pod +++ b/doc/man3/X509_STORE_CTX_set_verify_cb.pod @@ -76,7 +76,7 @@ from the corresponding B, please see L for more information. -=head1 WARNING +=head1 WARNINGS In general a verification callback should B unconditionally return 1 in all circumstances because this will allow verification to succeed no matter diff --git a/doc/man3/X509_STORE_add_cert.pod b/doc/man3/X509_STORE_add_cert.pod index 8e6ecfa7..c0940b96 100644 --- a/doc/man3/X509_STORE_add_cert.pod +++ b/doc/man3/X509_STORE_add_cert.pod @@ -55,7 +55,9 @@ operate on pointers to B objects, though. X509_STORE_add_cert() and X509_STORE_add_crl() add the respective object to the B's local storage. Untrusted objects should not be -added in this way. +added in this way. The added object's reference count is incremented by one, +hence the caller retains ownership of the object and needs to free it when it +is no longer needed. X509_STORE_set_depth(), X509_STORE_set_flags(), X509_STORE_set_purpose(), X509_STORE_set_trust(), and X509_STORE_set1_param() set the default values @@ -90,7 +92,7 @@ L =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-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 diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod index d8ee7f67..1b5aaa62 100644 --- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod +++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod @@ -346,7 +346,7 @@ If CRLs checking is enable CRLs are expected to be available in the corresponding B structure. No attempt is made to download CRLs from the CRL distribution points extension. -=head1 EXAMPLE +=head1 EXAMPLES Enable CRL checking when performing certificate verification during SSL connections associated with an B structure B: diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod index 526a6d68..e6ee557e 100644 --- a/doc/man3/X509_dup.pod +++ b/doc/man3/X509_dup.pod @@ -52,12 +52,18 @@ EDIPARTYNAME_new, ESS_CERT_ID_dup, ESS_CERT_ID_free, ESS_CERT_ID_new, +ESS_CERT_ID_V2_dup, +ESS_CERT_ID_V2_free, +ESS_CERT_ID_V2_new, ESS_ISSUER_SERIAL_dup, ESS_ISSUER_SERIAL_free, ESS_ISSUER_SERIAL_new, ESS_SIGNING_CERT_dup, ESS_SIGNING_CERT_free, ESS_SIGNING_CERT_new, +ESS_SIGNING_CERT_V2_dup, +ESS_SIGNING_CERT_V2_free, +ESS_SIGNING_CERT_V2_new, EXTENDED_KEY_USAGE_free, EXTENDED_KEY_USAGE_new, GENERAL_NAMES_free, @@ -118,8 +124,8 @@ OCSP_SINGLERESP_free, OCSP_SINGLERESP_new, OSSL_CMP_ITAV_free, OSSL_CMP_MSG_dup, -OSSL_CMP_MSG_it, OSSL_CMP_MSG_free, +OSSL_CMP_MSG_it, OSSL_CMP_PKIHEADER_free, OSSL_CMP_PKIHEADER_it, OSSL_CMP_PKIHEADER_new, @@ -199,10 +205,10 @@ POLICY_CONSTRAINTS_free, POLICY_CONSTRAINTS_new, POLICY_MAPPING_free, POLICY_MAPPING_new, -PROFESSION_INFO_free, -PROFESSION_INFO_new, PROFESSION_INFOS_free, PROFESSION_INFOS_new, +PROFESSION_INFO_free, +PROFESSION_INFO_new, PROXY_CERT_INFO_EXTENSION_free, PROXY_CERT_INFO_EXTENSION_new, PROXY_POLICY_free, @@ -246,10 +252,13 @@ X509_ALGOR_new, X509_ATTRIBUTE_dup, X509_ATTRIBUTE_free, X509_ATTRIBUTE_new, +X509_CERT_AUX_dup, X509_CERT_AUX_free, X509_CERT_AUX_new, +X509_CINF_dup, X509_CINF_free, X509_CINF_new, +X509_CRL_INFO_dup, X509_CRL_INFO_free, X509_CRL_INFO_new, X509_CRL_dup, @@ -264,6 +273,7 @@ X509_NAME_ENTRY_new, X509_NAME_dup, X509_NAME_free, X509_NAME_new, +X509_REQ_INFO_dup, X509_REQ_INFO_free, X509_REQ_INFO_new, X509_REQ_dup, @@ -272,6 +282,7 @@ X509_REQ_new, X509_REVOKED_dup, X509_REVOKED_free, X509_REVOKED_new, +X509_SIG_dup, X509_SIG_free, X509_SIG_new, X509_VAL_free, diff --git a/doc/man3/X509_get_extension_flags.pod b/doc/man3/X509_get_extension_flags.pod index 0c807962..34f811c7 100644 --- a/doc/man3/X509_get_extension_flags.pod +++ b/doc/man3/X509_get_extension_flags.pod @@ -4,6 +4,8 @@ X509_get0_subject_key_id, X509_get0_authority_key_id, +X509_get0_authority_issuer, +X509_get0_authority_serial, X509_get_pathlen, X509_get_extension_flags, X509_get_key_usage, @@ -22,6 +24,8 @@ X509_get_proxy_pathlen - retrieve certificate extension data uint32_t X509_get_extended_key_usage(X509 *x); const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x); const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x); + const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x); + const ASN1_INTEGER *X509_get0_authority_serial(X509 *x); void X509_set_proxy_flag(X509 *x); void X509_set_proxy_pathlen(int l); long X509_get_proxy_pathlen(X509 *x); @@ -115,6 +119,14 @@ X509_get0_authority_key_id() returns an internal pointer to the authority key identifier of B as an B or B if the extension is not present or cannot be parsed. +X509_get0_authority_issuer() returns an internal pointer to the authority +certificate issuer of B as a stack of B structures or +B if the extension is not present or cannot be parsed. + +X509_get0_authority_serial() returns an internal pointer to the authority +certificate serial number of B as an B or B if the +extension is not present or cannot be parsed. + X509_set_proxy_flag() marks the certificate with the B flag. This is for the users who need to mark non-RFC3820 proxy certificates as such, as OpenSSL only detects RFC3820 compliant ones. diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index 36a5e8f6..dcd4ce71 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -53,6 +53,7 @@ d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY_fp, d2i_DSA_SIG, d2i_DSAparams, +d2i_ECDSA_SIG, d2i_ECPKParameters, d2i_ECParameters, d2i_ECPrivateKey, @@ -63,8 +64,10 @@ d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY_fp, d2i_EDIPARTYNAME, d2i_ESS_CERT_ID, +d2i_ESS_CERT_ID_V2, d2i_ESS_ISSUER_SERIAL, d2i_ESS_SIGNING_CERT, +d2i_ESS_SIGNING_CERT_V2, d2i_EXTENDED_KEY_USAGE, d2i_GENERAL_NAME, d2i_GENERAL_NAMES, @@ -239,6 +242,7 @@ i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY_fp, i2d_DSA_SIG, i2d_DSAparams, +i2d_ECDSA_SIG, i2d_ECPKParameters, i2d_ECParameters, i2d_ECPrivateKey, @@ -249,8 +253,10 @@ i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY_fp, i2d_EDIPARTYNAME, i2d_ESS_CERT_ID, +i2d_ESS_CERT_ID_V2, i2d_ESS_ISSUER_SERIAL, i2d_ESS_SIGNING_CERT, +i2d_ESS_SIGNING_CERT_V2, i2d_EXTENDED_KEY_USAGE, i2d_GENERAL_NAME, i2d_GENERAL_NAMES, @@ -494,6 +500,10 @@ Represents a DSA public key using a B structure. Use a non-standard OpenSSL format and should be avoided; use B, B, or similar instead. +=item B + +Represents an ECDSA signature. + =item B Represents a PKCS#1 RSA public key structure. diff --git a/doc/man5/config.pod b/doc/man5/config.pod index cac4ef67..5e950d74 100644 --- a/doc/man5/config.pod +++ b/doc/man5/config.pod @@ -40,7 +40,8 @@ It is strongly recommended to use absolute paths with the B<.include> directive. Relative paths are evaluated based on the application current working directory so unless the configuration file containing the B<.include> directive is application specific the inclusion will not -work as expected. +work as expected. The environment variable B can also be +used to specify the path to prepend to all .include paths. There can be optional B<=> character and whitespace characters between B<.include> directive and the path which can be useful in cases the @@ -487,6 +488,10 @@ Ignored in set-user-ID and set-group-ID programs. The path to the directory with OpenSSL modules, such as providers. Ignored in set-user-ID and set-group-ID programs. +=item B + +The optional path to prepend to all .include paths. + =back =head1 BUGS @@ -504,7 +509,7 @@ file. =head1 SEE ALSO -L, L, L +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod new file mode 100644 index 00000000..7f08fd06 --- /dev/null +++ b/doc/man5/fips_config.pod @@ -0,0 +1,71 @@ +=pod + +=head1 NAME + +OPENSSL FIPS CONFIGURATION + +=head1 DESCRIPTION + +A separate configuration file containing data related to FIPS 'self tests' is +written to during installation time. +This data is used for 2 purposes when the fips module is loaded: + +=over 4 + +=item - Verify the module's checksum each time the fips module loads. + +=item - Run the startup FIPS self test KATS (known answer tests). +This only needs to be run once during installation. + +=back + +The supported options are: + +=over 4 + +=item B + +The calculated MAC of the module file + +=item B + +A version number for the fips install process. Should be 1. + +=item B + +The install status indicator description that will be verified. +If this field is not present the FIPS self tests will run when the fips module +loads. +This value should only be written to after the FIPS module has +successfully passed its self tests during installation. + +=item B + +The calculated MAC of the install status indicator. +It is initially empty and is written to at the same time as the install_status. + +=back + +For example: + + [fips_install] + + install-version = 1 + module-checksum = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC + install-checksum = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C + install-status = INSTALL_SELF_TEST_KATS_RUN + +=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/man5/x509v3_config.pod b/doc/man5/x509v3_config.pod index b8fc00ed..5a84be53 100644 --- a/doc/man5/x509v3_config.pod +++ b/doc/man5/x509v3_config.pod @@ -56,7 +56,7 @@ must be used, see the L section fo The following sections describe each supported extension in detail. -=head2 Basic Constraints. +=head2 Basic Constraints This is a multi valued extension which indicates whether a certificate is a CA certificate. The first (mandatory) name is B followed by B or @@ -81,7 +81,7 @@ below this one in a chain. So if you have a CA with a pathlen of zero it can only be used to sign end user certificates and not further CAs. -=head2 Key Usage. +=head2 Key Usage Key usage is a multi valued extension consisting of a list of names of the permitted key usages. @@ -97,7 +97,7 @@ Examples: keyUsage=critical, keyCertSign -=head2 Extended Key Usage. +=head2 Extended Key Usage This extensions consists of a list of usages indicating purposes for which the certificate public key can be used for, @@ -126,7 +126,7 @@ Examples: extendedKeyUsage=serverAuth,clientAuth -=head2 Subject Key Identifier. +=head2 Subject Key Identifier This is really a string extension and can take two possible values. Either the word B which will automatically follow the guidelines in RFC3280 @@ -138,7 +138,7 @@ Example: subjectKeyIdentifier=hash -=head2 Authority Key Identifier. +=head2 Authority Key Identifier The authority key identifier extension permits two options. keyid and issuer: both can take the optional value "always". @@ -156,7 +156,7 @@ Example: authorityKeyIdentifier=keyid,issuer -=head2 Subject Alternative Name. +=head2 Subject Alternative Name The subject alternative name extension allows various literal values to be included in the configuration file. These include B (an email address) @@ -195,7 +195,7 @@ Examples: CN=My Name -=head2 Issuer Alternative Name. +=head2 Issuer Alternative Name The issuer alternative name option supports all the literal options of subject alternative name. It does B support the email:copy option because @@ -208,7 +208,7 @@ Example: issuerAltName = issuer:copy -=head2 Authority Info Access. +=head2 Authority Info Access The authority information access extension gives details about how to access certain information relating to the CA. Its syntax is accessOID;location @@ -300,7 +300,7 @@ Example: CN=Some Name -=head2 Certificate Policies. +=head2 Certificate Policies This is a I extension. All the fields of this extension can be set by using the appropriate syntax. @@ -424,7 +424,7 @@ Example: The following extensions are non standard, Netscape specific and largely obsolete. Their use in new applications is discouraged. -=head2 Netscape String extensions. +=head2 Netscape String extensions Netscape Comment (B) is a string extension containing a comment which will be displayed when the certificate is viewed in some browsers. @@ -483,7 +483,7 @@ For example: basicConstraints=critical,DER:00:01:02:03 -=head1 WARNING +=head1 WARNINGS There is no guarantee that a specific implementation will process a given extension. It may therefore be sometimes possible to use certificates for @@ -493,7 +493,6 @@ not recognize or honour the values of the relevant extensions. The DER and ASN1 options should be used with caution. It is possible to create totally invalid extensions if they are not used carefully. - =head1 NOTES If an extension is multi-value and a field value must contain a comma the long diff --git a/doc/man7/EVP_KDF-HKDF.pod b/doc/man7/EVP_KDF-HKDF.pod new file mode 100644 index 00000000..ce623039 --- /dev/null +++ b/doc/man7/EVP_KDF-HKDF.pod @@ -0,0 +1,154 @@ +=pod + +=head1 NAME + +EVP_KDF-HKDF - The HKDF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B KDF through the B API. + +The EVP_KDF-HKDF algorithm implements the HKDF key derivation function. +HKDF follows the "extract-then-expand" paradigm, where the KDF logically +consists of two modules. The first stage takes the input keying material +and "extracts" from it a fixed-length pseudorandom key K. The second stage +"expands" the key K into several additional pseudorandom keys (the output +of the KDF). + +=head2 Identity + +"HKDF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. + +=head2 Supported parameters + +The supported parameters are: + +=over 4 + +=item B ("properties") + +=item B ("digest") + +=item B ("key") + +=item B ("salt") + +These parameters work as described in L. + +=item B ("info") + +This parameter sets the info value. +The length of the context info buffer cannot exceed 1024 bytes; +this should be more than enough for any normal use of HKDF. + +=item B ("mode") or + +This parameter sets the mode for the HKDF operation. +There are three modes that are currently defined: + +=over 4 + +=item B "EXTRACT_AND_EXPAND" + +This is the default mode. Calling L on an EVP_KDF_CTX set +up for HKDF will perform an extract followed by an expand operation in one go. +The derived key returned will be the result after the expand operation. The +intermediate fixed-length pseudorandom key K is not returned. + +In this mode the digest, key, salt and info values must be set before a key is +derived otherwise an error will occur. + +=item B "EXTRACT_ONLY" + +In this mode calling L will just perform the extract +operation. The value returned will be the intermediate fixed-length pseudorandom +key K. The C parameter must match the size of K, which can be looked +up by calling EVP_KDF_size() after setting the mode and digest. + +The digest, key and salt values must be set before a key is derived otherwise +an error will occur. + +=item B "EXPAND_ONLY" + +In this mode calling L will just perform the expand +operation. The input key should be set to the intermediate fixed-length +pseudorandom key K returned from a previous extract operation. + +The digest, key and info values must be set before a key is derived otherwise +an error will occur. + +=back + +=back + +=head1 NOTES + +A context for HKDF can be obtained by calling: + + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "HKDF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + +The output length of an HKDF expand operation is specified via the C +parameter to the L function. When using +EVP_KDF_HKDF_MODE_EXTRACT_ONLY the C parameter must equal the size of +the intermediate fixed-length pseudorandom key otherwise an error will occur. +For that mode, the fixed output size can be looked up by calling EVP_KDF_size() +after setting the mode and digest on the C. + +=head1 EXAMPLES + +This example derives 10 bytes using SHA-256 with the secret key "secret", +salt value "salt" and info value "label": + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[5], *p = params; + + kdf = EVP_KDF_fetch(NULL, "HKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + "label", (size_t)5); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + "salt", (size_t)4); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 5869 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2016-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/man7/EVP_KDF_PBKDF2.pod b/doc/man7/EVP_KDF-PBKDF2.pod similarity index 63% rename from doc/man7/EVP_KDF_PBKDF2.pod rename to doc/man7/EVP_KDF-PBKDF2.pod index c3d3f275..f90029bf 100644 --- a/doc/man7/EVP_KDF_PBKDF2.pod +++ b/doc/man7/EVP_KDF-PBKDF2.pod @@ -2,46 +2,45 @@ =head1 NAME -EVP_KDF_PBKDF2 - The PBKDF2 EVP_KDF implementation +EVP_KDF-PBKDF2 - The PBKDF2 EVP_KDF implementation =head1 DESCRIPTION Support for computing the B password-based KDF through the B API. -The EVP_KDF_PBKDF2 algorithm implements the PBKDF2 password-based key +The EVP_KDF-PBKDF2 algorithm implements the PBKDF2 password-based key derivation function, as described in SP800-132; it derives a key from a password using a salt and iteration count. -=head2 Numeric identity +=head2 Identity -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. +"PBKDF2" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. -=head2 Supported controls +=head2 Supported parameters -The supported controls are: +The supported parameters are: =over 4 -=item B +=item B ("pass") -=item B +=item B ("salt") -=item B +=item B ("iter") -This control has a default value of 2048. +This parameter has a default value of 2048. -=item B +=item B ("properties") -These controls work as described in L. +=item B ("digest") -=item B +These parameters work as described in L. -This control expects one argument: C - -This control can be used to enable or disable SP800-132 compliance checks. +=item B ("pkcs5") +This parameter can be used to enable or disable SP800-132 compliance checks. Setting the mode to 0 enables the compliance checks. The checks performed are: @@ -59,8 +58,6 @@ The checks performed are: The default provider uses a default mode of 1 for backwards compatibility, and the fips provider uses a default mode of 0. -EVP_KDF_ctrl_str() type string: "pkcs5" - The value string is expected to be a decimal number 0 or 1. =back @@ -84,16 +81,16 @@ SP800-132 =head1 SEE ALSO -L, -L, +L, +L, L, -L, +L, L, -L +L =head1 HISTORY -This functionality was added to OpenSSL 3.0.0. +This functionality was added to OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man7/EVP_KDF_SCRYPT.pod b/doc/man7/EVP_KDF-SCRYPT.pod similarity index 60% rename from doc/man7/EVP_KDF_SCRYPT.pod rename to doc/man7/EVP_KDF-SCRYPT.pod index a44dc63d..706237f6 100644 --- a/doc/man7/EVP_KDF_SCRYPT.pod +++ b/doc/man7/EVP_KDF-SCRYPT.pod @@ -2,14 +2,14 @@ =head1 NAME -EVP_KDF_SCRYPT - The scrypt EVP_KDF implementation +EVP_KDF-SCRYPT - The scrypt EVP_KDF implementation =head1 DESCRIPTION Support for computing the B password-based KDF through the B API. -The EVP_KDF_SCRYPT algorithm implements the scrypt password-based key +The EVP_KDF-SCRYPT algorithm implements the scrypt password-based key derivation function, as described in RFC 7914. It is memory-hard in the sense that it deliberately requires a significant amount of RAM for efficient computation. The intention of this is to render brute forcing of passwords on @@ -32,40 +32,32 @@ GHz), this computation takes about 3 seconds. When N, r or p are not specified, they default to 1048576, 8, and 1, respectively. The maximum amount of RAM that may be used by scrypt defaults to 1025 MiB. -=head2 Numeric identity +=head2 Identity -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. +"ID-SCRYPT" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. -=head2 Supported controls +=head2 Supported parameters -The supported controls are: +The supported parameters are: =over 4 -=item B +=item B ("pass") -=item B +=item B ("salt") -These controls work as described in L. +These parameters work as described in L. -=item B +=item B ("n") -=item B +=item B ("r") -=item B +=item B ("p") -B expects one argument: C - -B expects one argument: C - -B expects one argument: C - -These controls configure the scrypt work factors N, r and p. - -EVP_KDF_ctrl_str() type strings: "N", "r" and "p", respectively. - -The corresponding value strings are expected to be decimal numbers. +These parameters configure the scrypt work factors N, r and p. +N is a parameter of type uint64_t. +Both r and p are parameters of type uint32_t. =back @@ -73,35 +65,36 @@ The corresponding value strings are expected to be decimal numbers. A context for scrypt can be obtained by calling: - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "ID-SCRYPT", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); The output length of an scrypt key derivation is specified via the -B parameter to the L function. +B parameter to the L function. -=head1 EXAMPLE +=head1 EXAMPLES This example derives a 64-byte long test vector using scrypt with the password "password", salt "NaCl" and N = 1024, r = 8, p = 16. + EVP_KDF *kdf; EVP_KDF_CTX *kctx; unsigned char out[64]; + OSSL_PARAM params[6], *p = params; - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + kdf = EVP_KDF_fetch(NULL, "ID-SCRYPT", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { - error("EVP_KDF_CTRL_SET_PASS"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) { - error("EVP_KDF_CTRL_SET_SALT"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) { - error("EVP_KDF_CTRL_SET_SCRYPT_N"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) { - error("EVP_KDF_CTRL_SET_SCRYPT_R"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) { - error("EVP_KDF_CTRL_SET_SCRYPT_P"); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + "password", (size_t)8); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + "NaCl", (size_t)4); + *p++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, (uint64_t)1024); + *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_R, (uint32_t)8); + *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_P, (uint32_t)16); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); @@ -130,16 +123,16 @@ RFC 7914 =head1 SEE ALSO -L, -L, +L, +L, L, -L, +L, L, -L +L =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-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 diff --git a/doc/man7/EVP_KDF-SS.pod b/doc/man7/EVP_KDF-SS.pod new file mode 100644 index 00000000..160e12ac --- /dev/null +++ b/doc/man7/EVP_KDF-SS.pod @@ -0,0 +1,197 @@ +=pod + +=head1 NAME + +EVP_KDF-SS - The Single Step / One Step EVP_KDF implementation + +=head1 DESCRIPTION + +The EVP_KDF-SS algorithm implements the Single Step key derivation function (SSKDF). +SSKDF derives a key using input such as a shared secret key (that was generated +during the execution of a key establishment scheme) and fixedinfo. +SSKDF is also informally referred to as 'Concat KDF'. + +=head2 Auxiliary function + +The implementation uses a selectable auxiliary function H, which can be one of: + +=over 4 + +=item B + +=item B + +=item B + +=back + +Both the HMAC and KMAC implementations set the key using the 'salt' value. +The hash and HMAC also require the digest to be set. + +=head2 Identity + +"SSKDF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. + +=head2 Supported parameters + +The supported parameters are: + +=over 4 + +=item B ("properties") + +=item B ("digest") + +=item B ("mac") + +=item B ("maclen") + +=item B ("salt") + +These parameters work as described in L. + +=item B ("key") + +This parameter set the shared secret that is used for key derivation. + +=item B ("info") + +This parameter sets an optional value for fixedinfo, also known as otherinfo. + +=back + +=head1 NOTES + +A context for SSKDF can be obtained by calling: + + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + +The output length of an SSKDF is specified via the C +parameter to the L function. + +=head1 EXAMPLES + +This example derives 10 bytes using H(x) = SHA-256, with the secret key "secret" +and fixedinfo value "label": + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[4], *p = params; + + kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + "label", (size_t)5); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +This example derives 10 bytes using H(x) = HMAC(SHA-256), with the secret key "secret", +fixedinfo value "label" and salt "salt": + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[6], *p = params; + + kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, + SN_hmac, strlen(SN_hmac)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(EVP_KDF_CTRL_SET_KEY, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + "label", (size_t)5); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + "salt", (size_t)4); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +This example derives 10 bytes using H(x) = KMAC128(x,salt,outlen), with the secret key "secret" +fixedinfo value "label", salt of "salt" and KMAC outlen of 20: + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[7], *p = params; + + kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, + SN_kmac128, strlen(SN_kmac128)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(EVP_KDF_CTRL_SET_KEY, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + "label", (size_t)5); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + "salt", (size_t)4); + *p++ = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_MAC_SIZE, (size_t)20); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +NIST SP800-56Cr1. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. Copyright +(c) 2019, Oracle and/or its affiliates. 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/man7/EVP_KDF_SSHKDF.pod b/doc/man7/EVP_KDF-SSHKDF.pod similarity index 51% rename from doc/man7/EVP_KDF_SSHKDF.pod rename to doc/man7/EVP_KDF-SSHKDF.pod index e233e86f..7649f70c 100644 --- a/doc/man7/EVP_KDF_SSHKDF.pod +++ b/doc/man7/EVP_KDF-SSHKDF.pod @@ -2,69 +2,49 @@ =head1 NAME -EVP_KDF_SSHKDF - The SSHKDF EVP_KDF implementation +EVP_KDF-SSHKDF - The SSHKDF EVP_KDF implementation =head1 DESCRIPTION Support for computing the B KDF through the B API. -The EVP_KDF_SSHKDF algorithm implements the SSHKDF key derivation function. +The EVP_KDF-SSHKDF algorithm implements the SSHKDF key derivation function. It is defined in RFC 4253, section 7.2 and is used by SSH to derive IVs, encryption keys and integrity keys. Five inputs are required to perform key derivation: The hashing function (for example SHA256), the Initial Key, the Exchange Hash, the Session ID, and the derivation key type. -=head2 Numeric identity +=head2 Identity -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. +"SSHKDF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. -=head2 Supported controls +=head2 Supported parameters -The supported controls are: +The supported parameters are: =over 4 -=item B +=item B ("properties") -=item B +=item B ("digest") -These controls work as described in L. +=item B ("key") -=item B +These parameters work as described in L. -=item B +=item B ("xcghash") -These controls expect two arguments: C, C +=item B ("session_id") -They set the respective values to the first B bytes of the buffer -B. If a value is already set, the contents are replaced. +These parameters set the respective values for the KDF. +If a value is already set, the contents are replaced. -EVP_KDF_ctrl_str() takes two type strings for these controls: +=item B ("type") -=over 4 - -=item "xcghash" - -=item "session_id" - -The value string is used as is. - -=item "hexxcghash" - -=item "hexsession_id" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects one argument: C - -Sets the type for the SSHHKDF operation. There are six supported types: +This parameter sets the type for the SSHHKDF operation. +There are six supported types: =over 4 @@ -100,50 +80,54 @@ A single char of value 70 (ASCII char 'F'). =back -EVP_KDF_ctrl_str() type string: "type" - -The value is a string of length one character. The only valid values -are the numerical values of the ASCII characters: "A" (65) to "F" (70). - =back =head1 NOTES A context for SSHKDF can be obtained by calling: - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); The output length of the SSHKDF derivation is specified via the C -parameter to the L function. -Since the SSHKDF output length is variable, calling L +parameter to the L function. +Since the SSHKDF output length is variable, calling L to obtain the requisite length is not meaningful. The caller must allocate a buffer of the desired length, and pass that buffer to the -L function along with the desired length. +L function along with the desired length. -=head1 EXAMPLE +=head1 EXAMPLES This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate "xcghash" and "session_id" values: + EVP_KDF *kdf; EVP_KDF_CTX *kctx; unsigned char key[1024] = "01234..."; unsigned char xcghash[32] = "012345..."; unsigned char session_id[32] = "012345..."; unsigned char out[8]; size_t outlen = sizeof(out); - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); + OSSL_PARAM params[6], *p = params; - if (EVP_KDF_CTX_set_md(kctx, EVP_sha256()) <= 0) - /* Error */ - if (EVP_KDF_CTX_set1_key(kctx, key, 1024) <= 0) - /* Error */ - if (EVP_KDF_CTX_set1_sshkdf_xcghash(kctx, xcghash, 32) <= 0) - /* Error */ - if (EVP_KDF_CTX_set1_sshkdf_session_id(kctx, session_id, 32) <= 0) - /* Error */ - if (EVP_KDF_CTX_set_sshkdf_type(kctx, - EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV) <= 0) + kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + key, (size_t)1024); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, + xcghash, (size_t)32); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + session_id, (size_t)32); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_SSHKDF_TYPE, + EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) /* Error */ + if (EVP_KDF_derive(kctx, out, &outlen) <= 0) /* Error */ @@ -154,17 +138,17 @@ RFC 4253 =head1 SEE ALSO -L, -L, +L, +L, L, -L, +L, L, L, -L +L =head1 COPYRIGHT -Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_KDF-TLS1_PRF.pod b/doc/man7/EVP_KDF-TLS1_PRF.pod new file mode 100644 index 00000000..58625a76 --- /dev/null +++ b/doc/man7/EVP_KDF-TLS1_PRF.pod @@ -0,0 +1,113 @@ +=pod + +=head1 NAME + +EVP_KDF-TLS1_PRF - The TLS1 PRF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B PRF through the B API. + +The EVP_KDF-TLS1_PRF algorithm implements the PRF used by TLS versions up to +and including TLS 1.2. + +=head2 Identity + +"TLS1-PRF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. + +=head2 Supported parameters + +The supported parameters are: + +=over 4 + +=item B ("properties") + +=item B ("digest") + +These parameters work as described in L. + +The C parameter is used to set the message digest +associated with the TLS PRF. +EVP_md5_sha1() is treated as a special case which uses the +PRF algorithm using both B and B as used in TLS 1.0 and 1.1. + +=item B ("secret") + +This parameter sets the secret value of the TLS PRF. +Any existing secret value is replaced. + +=item B ("seed") + +This parameter sets the context seed. +The length of the context seed cannot exceed 1024 bytes; +this should be more than enough for any normal use of the TLS PRF. + +=back + +=head1 NOTES + +A context for the TLS PRF can be obtained by calling: + + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + +The digest, secret value and seed must be set before a key is derived otherwise +an error will occur. + +The output length of the PRF is specified by the C parameter to the +EVP_KDF_derive() function. + +=head1 EXAMPLES + +This example derives 10 bytes using SHA-256 with the secret key "secret" +and seed value "seed": + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[4], *p = params; + + kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + "seed", (size_t)4); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 2246, RFC 5246 and NIST SP 800-135 r1 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_KDF-X942.pod b/doc/man7/EVP_KDF-X942.pod new file mode 100644 index 00000000..06cafc30 --- /dev/null +++ b/doc/man7/EVP_KDF-X942.pod @@ -0,0 +1,122 @@ +=pod + +=head1 NAME + +EVP_KDF-X942 - The X9.42-2001 asn1 EVP_KDF implementation + +=head1 DESCRIPTION + +The EVP_KDF-X942 algorithm implements the key derivation function (X942KDF). +X942KDF is used by Cryptographic Message Syntax (CMS) for DH KeyAgreement, to +derive a key using input such as a shared secret key and other info. The other +info is DER encoded data that contains a 32 bit counter. + +=head2 Identity + +"X942KDF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. + +=head2 Supported parameters + +The supported parameters are: + +=over 4 + +=item B ("properties") + +=item B ("digest") + +These parameters work as described in L. + +=item B ("key") + +The shared secret used for key derivation. This parameter sets the secret. + +=item B ("ukm") + +This parameter is an optional random string that is provided +by the sender called "partyAInfo". +In CMS this is the user keying material. + +=item B ("cekalg") + +This parameter sets the CEK wrapping algorithm name. + +=back + +=head1 NOTES + +A context for X942KDF can be obtained by calling: + + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "X942KDF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + +The output length of an X942KDF is specified via the C +parameter to the L function. + +=head1 EXAMPLES + +This example derives 24 bytes, with the secret key "secret" and a random user +keying material: + + EVP_KDF_CTX *kctx; + EVP_KDF_CTX *kctx; + unsigned char out[192/8]; + unsignred char ukm[64]; + OSSL_PARAM params[5], *p = params; + + if (RAND_bytes(ukm, sizeof(ukm)) <= 0) + error("RAND_bytes"); + + kdf = EVP_KDF_fetch(NULL, "X942KDF", NULL); + if (kctx == NULL) + error("EVP_KDF_fetch"); + kctx = EVP_KDF_CTX_new(kdf); + if (kctx == NULL) + error("EVP_KDF_CTX_new"); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, ukm, sizeof(ukm)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + SN_id_smime_alg_CMS3DESwrap, + strlen(SN_id_smime_alg_CMS3DESwrap)); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) + error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) + error("EVP_KDF_derive"); + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 2631 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=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/man7/EVP_KDF-X963.pod b/doc/man7/EVP_KDF-X963.pod new file mode 100644 index 00000000..36dc2bab --- /dev/null +++ b/doc/man7/EVP_KDF-X963.pod @@ -0,0 +1,111 @@ +=pod + +=head1 NAME + +EVP_KDF-X963 - The X9.63-2001 EVP_KDF implementation + +=head1 DESCRIPTION + +The EVP_KDF-X963 algorithm implements the key derivation function (X963KDF). +X963KDF is used by Cryptographic Message Syntax (CMS) for EC KeyAgreement, to +derive a key using input such as a shared secret key and shared info. + +=head2 Identity + +"X963KDF" is the name for this implementation; it +can be used with the EVP_KDF_fetch() function. + +=head2 Supported parameters + +The supported parameters are: + +=over 4 + +=item B ("properties") + +=item B ("digest") + +These parameters work as described in L. + +=item B ("key") + +The shared secret used for key derivation. +This parameter sets the secret. + +=item B ("info") + +This parameter specifies an optional value for shared info. + +=back + +=head1 NOTES + +X963KDF is very similar to the SSKDF that uses a digest as the auxiliary function, +X963KDF appends the counter to the secret, whereas SSKDF prepends the counter. + +A context for X963KDF can be obtained by calling: + + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "X963KDF", NULL); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + +The output length of an X963KDF is specified via the C +parameter to the L function. + +=head1 EXAMPLES + +This example derives 10 bytes, with the secret key "secret" and sharedinfo +value "label": + + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + OSSL_PARAM params[4], *p = params; + + kdf = EVP_KDF_fetch(NULL, "X963KDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + "secret", (size_t)6); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + "label", (size_t)5); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + error("EVP_KDF_CTX_set_params"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +"SEC 1: Elliptic Curve Cryptography" + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=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/man7/EVP_KDF_HKDF.pod b/doc/man7/EVP_KDF_HKDF.pod deleted file mode 100644 index 2188b136..00000000 --- a/doc/man7/EVP_KDF_HKDF.pod +++ /dev/null @@ -1,180 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF_HKDF - The HKDF EVP_KDF implementation - -=head1 DESCRIPTION - -Support for computing the B KDF through the B API. - -The EVP_KDF_HKDF algorithm implements the HKDF key derivation function. -HKDF follows the "extract-then-expand" paradigm, where the KDF logically -consists of two modules. The first stage takes the input keying material -and "extracts" from it a fixed-length pseudorandom key K. The second stage -"expands" the key K into several additional pseudorandom keys (the output -of the KDF). - -=head2 Numeric identity - -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -=item B - -=item B - -These controls work as described in L. - -=item B - -This control does not expect any arguments. - -Resets the context info buffer to zero length. - -=item B - -This control expects two arguments: C, C - -Sets the info value to the first B bytes of the buffer B. If a -value is already set, the contents of the buffer are appended to the existing -value. - -The total length of the context info buffer cannot exceed 1024 bytes; -this should be more than enough for any normal use of HKDF. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "info" - -The value string is used as is. - -=item "hexinfo" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects one argument: C - -Sets the mode for the HKDF operation. There are three modes that are currently -defined: - -=over 4 - -=item EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND - -This is the default mode. Calling L on an EVP_KDF_CTX set -up for HKDF will perform an extract followed by an expand operation in one go. -The derived key returned will be the result after the expand operation. The -intermediate fixed-length pseudorandom key K is not returned. - -In this mode the digest, key, salt and info values must be set before a key is -derived otherwise an error will occur. - -=item EVP_KDF_HKDF_MODE_EXTRACT_ONLY - -In this mode calling L will just perform the extract -operation. The value returned will be the intermediate fixed-length pseudorandom -key K. The C parameter must match the size of K, which can be looked -up by calling EVP_KDF_size() after setting the mode and digest. - -The digest, key and salt values must be set before a key is derived otherwise -an error will occur. - -=item EVP_KDF_HKDF_MODE_EXPAND_ONLY - -In this mode calling L will just perform the expand -operation. The input key should be set to the intermediate fixed-length -pseudorandom key K returned from a previous extract operation. - -The digest, key and info values must be set before a key is derived otherwise -an error will occur. - -=back - -EVP_KDF_ctrl_str() type string: "mode" - -The value string is expected to be one of: "EXTRACT_AND_EXPAND", "EXTRACT_ONLY" -or "EXPAND_ONLY". - -=back - -=head1 NOTES - -A context for HKDF can be obtained by calling: - - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); - -The output length of an HKDF expand operation is specified via the C -parameter to the L function. When using -EVP_KDF_HKDF_MODE_EXTRACT_ONLY the C parameter must equal the size of -the intermediate fixed-length pseudorandom key otherwise an error will occur. -For that mode, the fixed output size can be looked up by calling EVP_KDF_size() -after setting the mode and digest on the C. - -=head1 EXAMPLE - -This example derives 10 bytes using SHA-256 with the secret key "secret", -salt value "salt" and info value "label": - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { - error("EVP_KDF_CTRL_SET_SALT"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_KEY"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, "label", (size_t)5) <= 0) { - error("EVP_KDF_CTRL_ADD_HKDF_INFO"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - - EVP_KDF_CTX_free(kctx); - -=head1 CONFORMING TO - -RFC 5869 - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L - -=head1 COPYRIGHT - -Copyright 2016-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 -L. - -=cut diff --git a/doc/man7/EVP_KDF_SS.pod b/doc/man7/EVP_KDF_SS.pod deleted file mode 100644 index b3de26a4..00000000 --- a/doc/man7/EVP_KDF_SS.pod +++ /dev/null @@ -1,226 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF_SS - The Single Step / One Step EVP_KDF implementation - -=head1 DESCRIPTION - -The EVP_KDF_SS algorithm implements the Single Step key derivation function (SSKDF). -SSKDF derives a key using input such as a shared secret key (that was generated -during the execution of a key establishment scheme) and fixedinfo. -SSKDF is also informally referred to as 'Concat KDF'. - -=head2 Auxiliary function - -The implementation uses a selectable auxiliary function H, which can be one of: - -=over 4 - -=item B - -=item B - -=item B - -=back - -Both the HMAC and KMAC implementations set the key using the 'salt' value. -The hash and HMAC also require the digest to be set. - -=head2 Numeric identity - -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -=item B - -=item B - -=item B - -These controls work as described in L. - -=item B - -This control expects two arguments: C, C - -The shared secret used for key derivation. This control sets the secret. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "secret" - -The value string is used as is. - -=item "hexsecret" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects two arguments: C, C - -An optional value for fixedinfo, also known as otherinfo. This control sets the fixedinfo. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "info" - -The value string is used as is. - -=item "hexinfo" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=back - -=head1 NOTES - -A context for SSKDF can be obtained by calling: - -EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS); - -The output length of an SSKDF is specified via the C -parameter to the L function. - -=head1 EXAMPLE - -This example derives 10 bytes using H(x) = SHA-256, with the secret key "secret" -and fixedinfo value "label": - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_KEY"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, "label", (size_t)5) <= 0) { - error("EVP_KDF_CTRL_SET_SSKDF_INFO"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - - EVP_KDF_CTX_free(kctx); - -=head1 EXAMPLE - -This example derives 10 bytes using H(x) = HMAC(SHA-256), with the secret key "secret", -fixedinfo value "label" and salt "salt": - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, EVP_get_macbyname("HMAC")) <= 0) { - error("EVP_KDF_CTRL_SET_MAC"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_KEY"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, "label", (size_t)5) <= 0) { - error("EVP_KDF_CTRL_SET_SSKDF_INFO"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { - error("EVP_KDF_CTRL_SET_SALT"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - - EVP_KDF_CTX_free(kctx); - -=head1 EXAMPLE - -This example derives 10 bytes using H(x) = KMAC128(x,salt,outlen), with the secret key "secret" -fixedinfo value "label", salt of "salt" and KMAC outlen of 20: - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, EVP_get_macbyname("KMAC128")) <= 0) { - error("EVP_KDF_CTRL_SET_MAC"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_KEY"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, "label", (size_t)5) <= 0) { - error("EVP_KDF_CTRL_SET_SSKDF_INFO"); - } - /* If not specified the salt will be set to a default value */ - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { - error("EVP_KDF_CTRL_SET_SALT"); - } - /* If not specified the default size will be the size of the derived key */ - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC_SIZE, (size_t)20) <= 0) { - error("EVP_KDF_CTRL_SET_MAC_SIZE"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - - EVP_KDF_CTX_free(kctx); - - -=head1 CONFORMING TO - -NIST SP800-56Cr1. - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L - -=head1 HISTORY - -This functionality was added to OpenSSL 3.0.0. - -=head1 COPYRIGHT - -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. Copyright -(c) 2019, Oracle and/or its affiliates. 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/man7/EVP_KDF_TLS1_PRF.pod b/doc/man7/EVP_KDF_TLS1_PRF.pod deleted file mode 100644 index 4c731395..00000000 --- a/doc/man7/EVP_KDF_TLS1_PRF.pod +++ /dev/null @@ -1,146 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF_TLS1_PRF - The TLS1 PRF EVP_KDF implementation - -=head1 DESCRIPTION - -Support for computing the B PRF through the B API. - -The EVP_KDF_TLS1_PRF algorithm implements the PRF used by TLS versions up to -and including TLS 1.2. - -=head2 Numeric identity - -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -This control works as described in L. - -The C control is used to set the message digest associated -with the TLS PRF. EVP_md5_sha1() is treated as a special case which uses the -PRF algorithm using both B and B as used in TLS 1.0 and 1.1. - -=item B - -This control expects two arguments: C, C - -Sets the secret value of the TLS PRF to B bytes of the buffer B. -Any existing secret value is replaced. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "secret" - -The value string is used as is. - -=item "hexsecret" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control does not expect any arguments. - -Resets the context seed buffer to zero length. - -=item B - -This control expects two arguments: C, C - -Sets the seed to B bytes of B. If a seed is already set it is -appended to the existing value. - -The total length of the context seed buffer cannot exceed 1024 bytes; -this should be more than enough for any normal use of the TLS PRF. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "seed" - -The value string is used as is. - -=item "hexseed" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=back - -=head1 NOTES - -A context for the TLS PRF can be obtained by calling: - - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF, NULL); - -The digest, secret value and seed must be set before a key is derived otherwise -an error will occur. - -The output length of the PRF is specified by the C parameter to the -EVP_KDF_derive() function. - -=head1 EXAMPLE - -This example derives 10 bytes using SHA-256 with the secret key "secret" -and seed value "seed": - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF); - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, - "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_TLS_SECRET"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) { - error("EVP_KDF_CTRL_ADD_TLS_SEED"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - EVP_KDF_CTX_free(kctx); - -=head1 CONFORMING TO - -RFC 2246, RFC 5246 and NIST SP 800-135 r1 - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_KDF_X942.pod b/doc/man7/EVP_KDF_X942.pod deleted file mode 100644 index 306ab2e4..00000000 --- a/doc/man7/EVP_KDF_X942.pod +++ /dev/null @@ -1,150 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF_X942 - The X9.42-2001 asn1 EVP_KDF implementation - -=head1 DESCRIPTION - -The EVP_KDF_X942 algorithm implements the key derivation function (X942KDF). -X942KDF is used by Cryptographic Message Syntax (CMS) for DH KeyAgreement, to -derive a key using input such as a shared secret key and other info. The other -info is DER encoded data that contains a 32 bit counter. - -=head2 Numeric identity - -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -This control works as described in L. - -=item B - -This control expects two arguments: C, C - -The shared secret used for key derivation. This control sets the secret. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "secret" - -The value string is used as is. - -=item "hexsecret" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects two arguments: C, C - -An optional random string that is provided by the sender called "partyAInfo". -In CMS this is the user keying material. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "ukm" - -The value string is used as is. - -=item "hexukm" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects one argument: C - -The CEK wrapping algorithm name. - -EVP_KDF_ctrl_str() type string: "cekalg" - -The value string is used as is. - -=back - -=head1 NOTES - -A context for X942KDF can be obtained by calling: - -EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_X942); - -The output length of an X942KDF is specified via the C -parameter to the L function. - -=head1 EXAMPLE - -This example derives 24 bytes, with the secret key "secret" and a random user -keying material: - - EVP_KDF_CTX *kctx; - unsigned char out[192/8]; - unsignred char ukm[64]; - - if (RAND_bytes(ukm, sizeof(ukm)) <= 0) - error("RAND_bytes"); - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_X942); - if (kctx == NULL) - error("EVP_KDF_CTX_new_id"); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) - error("EVP_KDF_CTRL_SET_MD"); - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) - error("EVP_KDF_CTRL_SET_KEY"); - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_UKM, ukm, sizeof(ukm)) <= 0) - error("EVP_KDF_CTRL_SET_UKM"); - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_CEK_ALG, - SN_id_smime_alg_CMS3DESwrap) <= 0) - error("EVP_KDF_CTRL_SET_CEK_ALG"); - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) - error("EVP_KDF_derive"); - - EVP_KDF_CTX_free(kctx); - -=head1 CONFORMING TO - -RFC 2631 - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L - -=head1 HISTORY - -This functionality was added to OpenSSL 3.0.0. - -=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/man7/EVP_KDF_X963.pod b/doc/man7/EVP_KDF_X963.pod deleted file mode 100644 index eaea6da2..00000000 --- a/doc/man7/EVP_KDF_X963.pod +++ /dev/null @@ -1,136 +0,0 @@ -=pod - -=head1 NAME - -EVP_KDF_X963 - The X9.63-2001 EVP_KDF implementation - -=head1 DESCRIPTION - -The EVP_KDF_X963 algorithm implements the key derivation function (X963KDF). -X963KDF is used by Cryptographic Message Syntax (CMS) for EC KeyAgreement, to -derive a key using input such as a shared secret key and shared info. - -=head2 Numeric identity - -B is the numeric identity for this implementation; it -can be used with the EVP_KDF_CTX_new_id() function. - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -This control works as described in L. - -=item B - -This control expects two arguments: C, C - -The shared secret used for key derivation. This control sets the secret. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "secret" - -The value string is used as is. - -=item "hexsecret" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=item B - -This control expects two arguments: C, C - -An optional value for shared info. This control sets the shared info. - -EVP_KDF_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "info" - -The value string is used as is. - -=item "hexinfo" - -The value string is expected to be a hexadecimal number, which will be -decoded before being passed on as the control value. - -=back - -=back - -=head1 NOTES - -X963KDF is very similar to the SSKDF that uses a digest as the auxiliary function, -X963KDF appends the counter to the secret, whereas SSKDF prepends the counter. - -A context for X963KDF can be obtained by calling: - -EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_X963); - -The output length of an X963KDF is specified via the C -parameter to the L function. - -=head1 EXAMPLE - -This example derives 10 bytes, with the secret key "secret" and sharedinfo -value "label": - - EVP_KDF_CTX *kctx; - unsigned char out[10]; - - kctx = EVP_KDF_CTX_new_id(EVP_KDF_X963); - - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { - error("EVP_KDF_CTRL_SET_MD"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { - error("EVP_KDF_CTRL_SET_KEY"); - } - if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, "label", (size_t)5) <= 0) { - error("EVP_KDF_CTRL_SET_SHARED_INFO"); - } - if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { - error("EVP_KDF_derive"); - } - - EVP_KDF_CTX_free(kctx); - -=head1 CONFORMING TO - -"SEC 1: Elliptic Curve Cryptography" - -=head1 SEE ALSO - -L, -L, -L, -L, -L, -L, -L - -=head1 HISTORY - -This functionality was added to OpenSSL 3.0.0. - -=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/man7/EVP_MAC-BLAKE2.pod b/doc/man7/EVP_MAC-BLAKE2.pod new file mode 100644 index 00000000..21be5223 --- /dev/null +++ b/doc/man7/EVP_MAC-BLAKE2.pod @@ -0,0 +1,79 @@ +=pod + +=head1 NAME + +EVP_MAC-BLAKE2, EVP_MAC-BLAKE2BMAC, EVP_MAC-BLAKE2SMAC +- The BLAKE2 EVP_MAC implementations + +=head1 DESCRIPTION + +Support for computing BLAKE2 MACs through the B API. + +=head2 Identity + +These implementations are identified with one of these names and +properties, to be used with EVP_MAC_fetch(): + +=over 4 + +=item "BLAKE2BMAC", "default=yes" + +=item "BLAKE2SMAC", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +All these parameters can be set with EVP_MAC_CTX_set_params(). +Furthermore, the "size" parameter can be retrieved with +EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). + +=over 4 + +=item B ("key") + +This may be at most 64 bytes for BLAKE2BMAC or 32 for BLAKE2SMAC and +at least 1 byte in both cases. + +=item B ("custom") + +This is an optional value of at most 16 bytes for BLAKE2BMAC or 8 for +BLAKE2SMAC. +It is empty by default. + +=item B ("salt") + +This is an optional value of at most 16 bytes for BLAKE2BMAC or 8 for +BLAKE2SMAC. +It is empty by default. + +=item B ("size") + +When set, this can be any number between between 1 and 32 for +EVP_MAC_BLAKE2S or 64 for EVP_MAC_BLAKE2B. +It is 32 and 64 respectively by default. + +=back + +=head1 SEE ALSO + +L, L, +L, L + +=head1 HISTORY + +The macros and functions described here were added to OpenSSL 3.0. + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-CMAC.pod b/doc/man7/EVP_MAC-CMAC.pod new file mode 100644 index 00000000..05d198a7 --- /dev/null +++ b/doc/man7/EVP_MAC-CMAC.pod @@ -0,0 +1,66 @@ +=pod + +=head1 NAME + +EVP_MAC-CMAC - The CMAC EVP_MAC implementation + +=head1 DESCRIPTION + +Support for computing CMAC MACs through the B API. + +=head2 Identity + +This implementation is identified with this name and properties, to be +used with EVP_MAC_fetch(): + +=over 4 + +=item "CMAC", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +The following parameter can be set with EVP_MAC_CTX_set_params(): + +=over 4 + +=item B ("key") + +=item B ("engine") + +=item B ("cipher") + +=item B ("properties") + +=back + +The following parameters can be retrieved with +EVP_MAC_CTX_get_params(): + +=over 4 + +=item B ("size") + +=back + +The "size" parameter can also be retrieved with with EVP_MAC_size(). + +=head1 SEE ALSO + +L, L, +L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-GMAC.pod b/doc/man7/EVP_MAC-GMAC.pod new file mode 100644 index 00000000..49532219 --- /dev/null +++ b/doc/man7/EVP_MAC-GMAC.pod @@ -0,0 +1,68 @@ +=pod + +=head1 NAME + +EVP_MAC-GMAC - The GMAC EVP_MAC implementation + +=head1 DESCRIPTION + +Support for computing GMAC MACs through the B API. + +=head2 Identity + +This implementation is identified with this name and properties, to be +used with EVP_MAC_fetch(): + +=over 4 + +=item "GMAC", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +The following parameter can be set with EVP_MAC_CTX_set_params(): + +=over 4 + +=item B ("key") + +=item B ("iv") + +=item B ("engine") + +=item B ("cipher") + +=item B ("properties") + +=back + +The following parameters can be retrieved with +EVP_MAC_CTX_get_params(): + +=over 4 + +=item B ("size") + +=back + +The "size" parameter can also be retrieved with EVP_MAC_size(). + +=head1 SEE ALSO + +L, L, +L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-HMAC.pod b/doc/man7/EVP_MAC-HMAC.pod new file mode 100644 index 00000000..6e9e74dd --- /dev/null +++ b/doc/man7/EVP_MAC-HMAC.pod @@ -0,0 +1,70 @@ +=pod + +=head1 NAME + +EVP_MAC-HMAC - The HMAC EVP_MAC implementation + +=head1 DESCRIPTION + +Support for computing HMAC MACs through the B API. + +=head2 Identity + +This implementation is identified with this name and properties, to be +used with EVP_MAC_fetch(): + +=over 4 + +=item "HMAC", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +The following parameter can be set with EVP_MAC_CTX_set_params(): + +=over 4 + +=item B ("key") + +=item B ("flags") + +=item B ("engine") + +=item B ("digest") + +=item B ("properties") + +=back + +The "flags" parameter is passed directly to HMAC_CTX_set_flags(). + +The following parameters can be retrieved with +EVP_MAC_CTX_get_params(): + +=over 4 + +=item B ("size") + +=back + +The "size" parameter can also be retrieved with EVP_MAC_size(). + +=head1 SEE ALSO + +L, L, +L, L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-KMAC.pod b/doc/man7/EVP_MAC-KMAC.pod new file mode 100644 index 00000000..d2414144 --- /dev/null +++ b/doc/man7/EVP_MAC-KMAC.pod @@ -0,0 +1,64 @@ +=pod + +=head1 NAME + +EVP_MAC-KMAC, EVP_MAC-KMAC256, EVP_MAC-KMAC256 +- The KMAC EVP_MAC implementations + +=head1 DESCRIPTION + +Support for computing KMAC MACs through the B API. + +=head2 Identity + +These implementations are identified with one of these names and +properties, to be used with EVP_MAC_fetch(): + +=over 4 + +=item "KMAC128", "default=yes" + +=item "KMAC256", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +All these parameters can be set with EVP_MAC_CTX_set_params(). +Furthermore, the "size" parameter can be retrieved with +EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). + +=over 4 + +=item B ("key") + +=item B ("custom") + +=item B ("size") + +=item B + +=back + +The "xof" parameter value is exptect to be 1 or 0. Use 1 to enable XOF +mode. If XOF is enabled then the output len that is encoded as part of +the input stream is set to zero. + +=head1 SEE ALSO + +L, L, +L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-Poly1305.pod b/doc/man7/EVP_MAC-Poly1305.pod new file mode 100644 index 00000000..5f606d66 --- /dev/null +++ b/doc/man7/EVP_MAC-Poly1305.pod @@ -0,0 +1,60 @@ +=pod + +=head1 NAME + +EVP_MAC-Poly1305 - The Poly1305 EVP_MAC implementation + +=head1 DESCRIPTION + +Support for computing Poly1305 MACs through the B API. + +=head2 Identity + +This implementation is identified with this name and properties, to be +used with EVP_MAC_fetch(): + +=over 4 + +=item "Poly1305", "default=yes" + +=back + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +The following parameter can be set with EVP_MAC_CTX_set_params(): + +=over 4 + +=item B ("key") + +=back + +The following parameters can be retrieved with +EVP_MAC_CTX_get_params(): + +=over 4 + +=item B ("size") + +=back + +The "size" parameter can also be retrieved with with EVP_MAC_size(). + +=head1 SEE ALSO + +L, L, +L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-Siphash.pod b/doc/man7/EVP_MAC-Siphash.pod new file mode 100644 index 00000000..f82a6688 --- /dev/null +++ b/doc/man7/EVP_MAC-Siphash.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +EVP_MAC-Siphash - The SipHash EVP_MAC implementation + +=head1 DESCRIPTION + +Support for computing SipHash MACs through the B API. + +=head2 Identity + +This implementation is identified with this name and properties, to be +used with EVP_MAC_fetch(): + +=over 4 + +=item "Siphash", "default=yes" + +=back + + +=head2 Supported parameters + +The general description of these parameters can be found in +L. + +All these parameters can be set with EVP_MAC_CTX_set_params(). +Furthermore, the "size" parameter can be retrieved with +EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). + +=over 4 + +=item B ("key") + +=item B ("size") + +=back + +=head1 SEE ALSO + +L, L, +L, L + +=head1 COPYRIGHT + +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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC_BLAKE2.pod b/doc/man7/EVP_MAC_BLAKE2.pod deleted file mode 100644 index 58b4f993..00000000 --- a/doc/man7/EVP_MAC_BLAKE2.pod +++ /dev/null @@ -1,114 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_BLAKE2 - The BLAKE2 EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing BLAKE2 MACs through the B API. - -=head2 Numeric identity - -B and B are the numeric identities for this -implementation, and can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -This is a string value of at most 64 bytes for EVP_MAC_BLAKE2B -or 32 for EVP_MAC_BLAKE2S and at least 1 byte in both cases. -This must be set before calling EVP_MAC_init(). - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -This is an optional string value of at most 16 bytes for EVP_MAC_BLAKE2B -or 8 for EVP_MAC_BLAKE2S, set to all-NULL by default. -If used this must be set before calling EVP_MAC_init(). - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "custom" - -The value string is used as is. - -=item "hexcustom" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -This is an optional string value of at most 16 bytes for EVP_MAC_BLAKE2B -or 8 for EVP_MAC_BLAKE2S, set to all-NULL by default. -If used this must be set before calling EVP_MAC_init(). - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "salt" - -The value string is used as is. - -=item "hexsalt" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -EVP_MAC_ctrl_str() type string: "outlen" - -This is an optional value string containing a decimal number between 1 and -32 for EVP_MAC_BLAKE2S or 64 for EVP_MAC_BLAKE2B. -If it is not set it uses the default digest size of 32 and 64 respectively. -If used this must be set before calling EVP_MAC_init(). - -=back - -=head1 SEE ALSO - -L, L - -=head1 HISTORY - -The macros and functions described here were added to OpenSSL 3.0.0. - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_CMAC.pod b/doc/man7/EVP_MAC_CMAC.pod deleted file mode 100644 index cda3f3f5..00000000 --- a/doc/man7/EVP_MAC_CMAC.pod +++ /dev/null @@ -1,65 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_CMAC - The CMAC EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing CMAC MACs through the B API. - -=head2 Numeric identity - -B is the numeric identity for this implementation, and -can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -=item B - -These work as described in L. - -EVP_MAC_ctrl_str() type string for B: "cipher" - -The value is expected to be the name of a cipher. - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_GMAC.pod b/doc/man7/EVP_MAC_GMAC.pod deleted file mode 100644 index 6e4ba1a7..00000000 --- a/doc/man7/EVP_MAC_GMAC.pod +++ /dev/null @@ -1,83 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_GMAC - The GMAC EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing GMAC MACs through the B API. - -=head2 Numeric identity - -B is the numeric identity for this implementation, and -can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "iv" - -The value string is used as is. - -=item "hexiv" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -=item B - -These work as described in L with the restriction that the -cipher must be an AEAD one. - -EVP_MAC_ctrl_str() type string for B: "cipher" - -The value is expected to be the name of a cipher. - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_HMAC.pod b/doc/man7/EVP_MAC_HMAC.pod deleted file mode 100644 index c8aa0475..00000000 --- a/doc/man7/EVP_MAC_HMAC.pod +++ /dev/null @@ -1,71 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_HMAC - The HMAC EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing HMAC MACs through the B API. - -=head2 Numeric identity - -B is the numeric identity for this implementation, and -can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -Sets HMAC flags. This is passed directly to HMAC_CTX_set_flags(). - -There are no corresponding string control types. - -=item B - -=item B - -These work as described in L. - -EVP_MAC_ctrl_str() type string for B: "digest" - -The value is expected to be the name of a cipher. - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_KMAC.pod b/doc/man7/EVP_MAC_KMAC.pod deleted file mode 100644 index 4ccaabe6..00000000 --- a/doc/man7/EVP_MAC_KMAC.pod +++ /dev/null @@ -1,94 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_KMAC - The KMAC EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing KMAC MACs through the B API. - -=head2 Numeric identity - -B and B are the numeric identities for this -implementation, and can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -This must be set before calling EVP_MAC_init(). - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -This is an optional string value that can be set before calling EVP_MAC_init(). -If it is not set it uses the default value "". - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "custom" - -The value string is used as is. - -=item "hexcustom" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=item B - -EVP_MAC_ctrl_str() type string: "outlen" - -This is an optional value string containing a decimal number. If it is not set -it uses the default value of 32 for EVP_MAC_KMAC128 and 64 for EVP_MAC_KMAC256. -This can be called any time before EVP_MAC_final(). - -=item B - -EVP_MAC_ctrl_str() type string: "xof" - -The value string is expected to be an integer value of 1 or 0. Use 1 to enable -XOF mode. If XOF is enabled then the output len that is encoded as part of the -input stream is set to zero. -This can be called any time before EVP_MAC_final(). - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_POLY1305.pod b/doc/man7/EVP_MAC_POLY1305.pod deleted file mode 100644 index 89234b74..00000000 --- a/doc/man7/EVP_MAC_POLY1305.pod +++ /dev/null @@ -1,55 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_POLY1305 - The Poly1305 EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing Poly1305 MACs through the B API. - -=head2 Numeric identity - -B is the numeric identity for this implementation, -and can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/EVP_MAC_SIPHASH.pod b/doc/man7/EVP_MAC_SIPHASH.pod deleted file mode 100644 index eeb0cfd1..00000000 --- a/doc/man7/EVP_MAC_SIPHASH.pod +++ /dev/null @@ -1,61 +0,0 @@ -=pod - -=head1 NAME - -EVP_MAC_SIPHASH - The SipHash EVP_MAC implementation - -=head1 DESCRIPTION - -Support for computing SipHash MACs through the B API. - -=head2 Numeric identity - -B is the numeric identity for this implementation, -and can be used in functions like EVP_MAC_CTX_new_id() and -EVP_get_macbynid(). - -=head2 Supported controls - -The supported controls are: - -=over 4 - -=item B - -EVP_MAC_ctrl_str() type string: "digestsize" - -The value string is expected to contain a decimal number. - -=item B - -EVP_MAC_ctrl_str() takes two type strings for this control: - -=over 4 - -=item "key" - -The value string is used as is. - -=item "hexkey" - -The value string is expected to be a hexadecimal number, which will be -decoded before passing on as control value. - -=back - -=back - -=head1 SEE ALSO - -L, L - -=head1 COPYRIGHT - -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 -L. - -=cut diff --git a/doc/man7/Ed25519.pod b/doc/man7/Ed25519.pod index 12bc64b3..8269f2fe 100644 --- a/doc/man7/Ed25519.pod +++ b/doc/man7/Ed25519.pod @@ -53,7 +53,7 @@ Ed25519 and Ed448 can be tested within L application since version 1.1 Valid algorithm names are B, B and B. If B is specified, then both Ed25519 and Ed448 are benchmarked. -=head1 EXAMPLE +=head1 EXAMPLES This example generates an B private key and writes it to standard output in PEM format: diff --git a/doc/man7/RAND_DRBG.pod b/doc/man7/RAND_DRBG.pod index c51b8cb2..467a544d 100644 --- a/doc/man7/RAND_DRBG.pod +++ b/doc/man7/RAND_DRBG.pod @@ -209,7 +209,7 @@ The last feature has been added to support the common practice used with previous OpenSSL versions to call RAND_add() before calling RAND_bytes(). -=head2 Entropy Input vs. Additional Data +=head2 Entropy Input and Additional Data The DRBG distinguishes two different types of random input: I, which comes from a trusted source, and I', diff --git a/doc/man7/SM2.pod b/doc/man7/SM2.pod index 05c8a345..31f58db4 100644 --- a/doc/man7/SM2.pod +++ b/doc/man7/SM2.pod @@ -41,7 +41,7 @@ done by calling: And normally there is no need to pass a B parameter to EVP_DigestSignInit() or EVP_DigestVerifyInit() in such a scenario. -=head1 EXAMPLE +=head1 EXAMPLES This example demonstrates the calling sequence for using an B to verify a message with the SM2 signature algorithm and the SM3 hash algorithm: diff --git a/doc/man7/X25519.pod b/doc/man7/X25519.pod index 7f0bdff2..6af40c6a 100644 --- a/doc/man7/X25519.pod +++ b/doc/man7/X25519.pod @@ -37,7 +37,7 @@ X25519 or X448 public keys can be set directly using L or loaded from a SubjectPublicKeyInfo structure in a PEM file using L (or similar function). -=head1 EXAMPLE +=head1 EXAMPLES This example generates an B private key and writes it to standard output in PEM format: diff --git a/doc/man7/bio.pod b/doc/man7/bio.pod index 18f11250..bc1fb1e4 100644 --- a/doc/man7/bio.pod +++ b/doc/man7/bio.pod @@ -52,7 +52,7 @@ pointer to a BIO_METHOD. There is a naming convention for such functions: a source/sink BIO is normally called BIO_s_*() and a filter BIO BIO_f_*(); -=head1 EXAMPLE +=head1 EXAMPLES Create a memory BIO: diff --git a/doc/man7/openssl-core.h.pod b/doc/man7/openssl-core.h.pod index 7fd4dfb2..737293d7 100644 --- a/doc/man7/openssl-core.h.pod +++ b/doc/man7/openssl-core.h.pod @@ -69,8 +69,8 @@ It's normally passed in arrays, where the array is terminated with an element where all fields are zero (for non-pointers) or C (for pointers). -These arrays can be used both to set parameters for some object, and -to request parameters. +These arrays can be used to set parameters for some object, to request +parameters, and to describe parameters. C is further described in L diff --git a/doc/man7/openssl_user_macros.pod.in b/doc/man7/openssl_user_macros.pod.in index 17c2d2e1..7a2387c3 100644 --- a/doc/man7/openssl_user_macros.pod.in +++ b/doc/man7/openssl_user_macros.pod.in @@ -60,7 +60,7 @@ However, it is recommended to start using the second form instead: =item C This form is a simple number that represents the major version number -and is supported for version 3.0.0 and up. For extra convenience, +and is supported for version 3.0 and up. For extra convenience, these numbers are also available: =over 4 diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod new file mode 100644 index 00000000..1b4b47d0 --- /dev/null +++ b/doc/man7/provider-base.pod @@ -0,0 +1,493 @@ +=pod + +=head1 NAME + +provider-base +- The basic OpenSSL library E-E provider functions + +=head1 SYNOPSIS + + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Functions offered by libcrypto to the providers */ + const OSSL_ITEM *core_gettable_params(const OSSL_PROVIDER *prov); + int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); + int core_thread_start(const OSSL_PROVIDER *prov, + OSSL_thread_stop_handler_fn handfn); + OPENSSL_CTX *core_get_library_context(const OSSL_PROVIDER *prov); + void core_new_error(const OSSL_PROVIDER *prov); + void core_set_error_debug(const OSSL_PROVIDER *prov, + const char *file, int line, const char *func); + void core_vset_error(const OSSL_PROVIDER *prov, + uint32_t reason, const char *fmt, va_list args); + + /* + * Some OpenSSL functionality is directly offered to providers via + * dispatch + */ + void *CRYPTO_malloc(size_t num, const char *file, int line); + void *CRYPTO_zalloc(size_t num, const char *file, int line); + void *CRYPTO_memdup(const void *str, size_t siz, + const char *file, int line); + char *CRYPTO_strdup(const char *str, const char *file, int line); + char *CRYPTO_strndup(const char *str, size_t s, + const char *file, int line); + void CRYPTO_free(void *ptr, const char *file, int line); + void CRYPTO_clear_free(void *ptr, size_t num, + const char *file, int line); + void *CRYPTO_realloc(void *addr, size_t num, + const char *file, int line); + void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, + const char *file, int line); + void *CRYPTO_secure_malloc(size_t num, const char *file, int line); + void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); + void CRYPTO_secure_free(void *ptr, const char *file, int line); + void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); + int CRYPTO_secure_allocated(const void *ptr); + void OPENSSL_cleanse(void *ptr, size_t len); + unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); + + /* Functions offered by the provider to libcrypto */ + void provider_teardown(void *provctx); + const OSSL_ITEM *provider_gettable_params(void *provctx); + int provider_get_params(void *provctx, OSSL_PARAM params[]); + const OSSL_ALGORITHM *provider_query_operation(void *provctx, + int operation_id, + const int *no_store); + const OSSL_ITEM *provider_get_reason_strings(void *provctx); + +=head1 DESCRIPTION + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays, in the call +of the provider initialization function. See L +for a description of the initialization function. + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from a B element named +B. +For example, the "function" core_gettable_params() has these: + + typedef OSSL_ITEM * + (OSSL_core_gettable_params_fn)(const OSSL_PROVIDER *prov); + static ossl_inline OSSL_NAME_core_gettable_params_fn + OSSL_get_core_gettable_params(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + +For I (the B array passed from F to the +provider): + + core_gettable_params OSSL_FUNC_CORE_GETTABLE_PARAMS + core_get_params OSSL_FUNC_CORE_GET_PARAMS + core_thread_start OSSL_FUNC_CORE_THREAD_START + core_get_library_context OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT + core_new_error OSSL_FUNC_CORE_NEW_ERROR + core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG + core_set_error OSSL_FUNC_CORE_SET_ERROR + CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC + CRYPTO_zalloc OSSL_FUNC_CRYPTO_ZALLOC + CRYPTO_memdup OSSL_FUNC_CRYPTO_MEMDUP + CRYPTO_strdup OSSL_FUNC_CRYPTO_STRDUP + CRYPTO_strndup OSSL_FUNC_CRYPTO_STRNDUP + CRYPTO_free OSSL_FUNC_CRYPTO_FREE + CRYPTO_clear_free OSSL_FUNC_CRYPTO_CLEAR_FREE + CRYPTO_realloc OSSL_FUNC_CRYPTO_REALLOC + CRYPTO_clear_realloc OSSL_FUNC_CRYPTO_CLEAR_REALLOC + CRYPTO_secure_malloc OSSL_FUNC_CRYPTO_SECURE_MALLOC + CRYPTO_secure_zalloc OSSL_FUNC_CRYPTO_SECURE_ZALLOC + CRYPTO_secure_free OSSL_FUNC_CRYPTO_SECURE_FREE + CRYPTO_secure_clear_free OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE + CRYPTO_secure_allocated OSSL_FUNC_CRYPTO_SECURE_ALLOCATED + BIO_new_file OSSL_FUNC_BIO_NEW_FILE + BIO_new_mem_buf OSSL_FUNC_BIO_NEW_MEMBUF + BIO_read_ex OSSL_FUNC_BIO_READ_EX + BIO_free OSSL_FUNC_BIO_FREE + OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE + OPENSSL_hexstr2buf OSSL_FUNC_OPENSSL_HEXSTR2BUF + +For I<*out> (the B array passed from the provider to +F): + + provider_teardown OSSL_FUNC_PROVIDER_TEARDOWN + provider_gettable_params OSSL_FUNC_PROVIDER_GETTABLE_PARAMS + provider_get_params OSSL_FUNC_PROVIDER_GET_PARAMS + provider_query_operation OSSL_FUNC_PROVIDER_QUERY_OPERATION + provider_get_reason_strings OSSL_FUNC_PROVIDER_GET_REASON_STRINGS + +=head2 Core functions + +core_gettable_params() returns a constant array of descriptor +B, for parameters that core_get_params() can handle. + +core_get_params() retrieves I parameters from the core. +See L below for a description of currently known +parameters. + +=for comment core_thread_start() TBA + +core_get_library_context() retrieves the library context in which the +B object I is stored. +This may sometimes be useful if the provider wishes to store a +reference to its context in the same library context. + +core_new_error(), core_set_error_debug() and core_set_error() are +building blocks for reporting an error back to the core, with +reference to the provider object I. + +=over 4 + +=item core_new_error() + +allocates a new thread specific error record. + +This corresponds to the OpenSSL function L. + +=item core_set_error_debug() + +sets debugging information in the current thread specific error +record. +The debugging information includes the name of the file I, the +line I and the function name I where the error occured. + +This corresponds to the OpenSSL function L. + +=item core_set_error() + +sets the I for the error, along with any addition data. +The I is a number defined by the provider and used to index +the reason strings table that's returned by +provider_get_reason_strings(). +The additional data is given as a format string I and a set of +arguments I, which are treated in the same manner as with +BIO_vsnprintf(). +I and I may also be passed to indicate exactly where the +error occured or was reported. + +This corresponds to the OpenSSL function L. + +=back + +CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_memdup(), CRYPTO_strdup(), +CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(), +CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(), +CRYPTO_secure_zalloc(), CRYPTO_secure_free(), +CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(), +BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_free(), +OPENSSL_cleanse(), and OPENSSL_hexstr2buf() correspond exactly to the +public functions with the same name. +As a matter of fact, the pointers in the B array are +direct pointers to those public functions. + +=head2 Provider functions + +provider_teardown() is called when a provider is shut down and removed +from the core's provider store. +It must free the passed I. + +provider_gettable_params() should return a constant array of +descriptor B, for parameters that provider_get_params() +can handle. + +provider_get_params() should process the B array +I, setting the values of the parameters it understands. + +provider_query_operation() should return a constant B +that corresponds to the given I. +It should indicate if the core may store a reference to this array by +setting I<*no_store> to 0 (core may store a reference) or 1 (core may +not store a reference). + +provider_get_reason_strings() should return a constant B +array that provides reason strings for reason codes the provider may +use when reporting errors using core_put_error(). + +None of these functions are mandatory, but a provider is fairly +useless without at least provider_query_operation(), and +provider_gettable_params() is fairly useless if not accompanied by +provider_get_params(). + +=head2 Core parameters + +core_get_params() understands the following known parameters: + +=over 4 + +=item "openssl-version" + +This is a B type of parameter, pointing at the +OpenSSL libraries' full version string, i.e. the string expanded from +the macro B. + +=item "provider-name" + +This is a B type of parameter, pointing at the +OpenSSL libraries' idea of what the calling provider is called. + +=back + +Additionally, provider specific configuration parameters from the +config file are available, in dotted name form. +The dotted name form is a concatenation of section names and final +config command name separated by periods. + +For example, let's say we have the following config example: + + openssl_conf = openssl_init + + [openssl_init] + providers = providers_sect + + [providers_sect] + foo = foo_sect + + [foo_sect] + activate = 1 + data1 = 2 + data2 = str + more = foo_more + + [foo_more] + data3 = foo,bar + +The provider will have these additional parameters available: + +=over 4 + +=item "activate" + +pointing at the string "1" + +=item "data1" + +pointing at the string "2" + +=item "data2" + +pointing at the string "str" + +=item "more.data3" + +pointing at the string "foo,bar" + +=back + +For more information on handling parameters, see L as +L. + +=head1 EXAMPLES + +This is an example of a simple provider made available as a +dynamically loadable module. +It implements the fictitious algorithm C for the fictitious +operation C. + + #include + #include + #include + + /* Errors used in this provider */ + #define E_MALLOC 1 + + static const OSSL_ITEM reasons[] = { + { E_MALLOC, "memory allocation failure" }. + { 0, NULL } /* Termination */ + }; + + /* + * To ensure we get the function signature right, forward declare + * them using function types provided by openssl/core_numbers.h + */ + OSSL_OP_bar_newctx_fn foo_newctx; + OSSL_OP_bar_freectx_fn foo_freectx; + OSSL_OP_bar_init_fn foo_init; + OSSL_OP_bar_update_fn foo_update; + OSSL_OP_bar_final_fn foo_final; + + OSSL_provider_query_operation_fn p_query; + OSSL_provider_get_reason_strings_fn p_reasons; + OSSL_provider_teardown_fn p_teardown; + + OSSL_provider_init_fn OSSL_provider_init; + + OSSL_core_put_error *c_put_error = NULL; + + /* Provider context */ + struct prov_ctx_st { + OSSL_PROVIDER *prov; + } + + /* operation context for the algorithm FOO */ + struct foo_ctx_st { + struct prov_ctx_st *provctx; + int b; + }; + + static void *foo_newctx(void *provctx) + { + struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx)); + + if (fooctx != NULL) + fooctx->provctx = provctx; + else + c_put_error(provctx->prov, E_MALLOC, __FILE__, __LINE__); + return fooctx; + } + + static void foo_freectx(void *fooctx) + { + free(fooctx); + } + + static int foo_init(void *vfooctx) + { + struct foo_ctx_st *fooctx = vfooctx; + + fooctx->b = 0x33; + } + + static int foo_update(void *vfooctx, unsigned char *in, size_t inl) + { + struct foo_ctx_st *fooctx = vfooctx; + + /* did you expect something serious? */ + if (inl == 0) + return 1; + for (; inl-- > 0; in++) + *in ^= fooctx->b; + return 1; + } + + static int foo_final(void *vfooctx) + { + struct foo_ctx_st *fooctx = vfooctx; + + fooctx->b = 0x66; + } + + static const OSSL_DISPATCH foo_fns[] = { + { OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx }, + { OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx }, + { OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init }, + { OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update }, + { OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final }, + { 0, NULL } + }; + + static const OSSL_ALGORITHM bars[] = { + { "FOO", "provider=chumbawamba", foo_fns }, + { NULL, NULL, NULL } + }; + + static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id, + int *no_store) + { + switch (operation_id) { + case OSSL_OP_BAR: + return bars; + } + return NULL; + } + + static const OSSL_ITEM *p_reasons(void *provctx) + { + return reasons; + } + + static void p_teardown(void *provctx) + { + free(provctx); + } + + static const OSSL_DISPATCH prov_fns[] = { + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown }, + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query }, + { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons }, + { 0, NULL } + }; + + int OSSL_provider_init(const OSSL_PROVIDER *provider, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) + { + struct prov_ctx_st *pctx = NULL; + + for (; in->function_id != 0; in++) + switch (in->function_id) { + case OSSL_FUNC_CORE_PUT_ERROR: + c_put_error = OSSL_get_core_put_error(in); + break; + } + + *out = prov_fns; + + if ((pctx = malloc(sizeof(*pctx))) == NULL) { + /* + * ALEA IACTA EST, if the core retrieves the reason table + * regardless, that string will be displayed, otherwise not. + */ + c_put_error(provider, E_MALLOC, __FILE__, __LINE__); + return 0; + } + return 1; + } + +This relies on a few things existing in F: + + #define OSSL_OP_BAR 4711 + + #define OSSL_FUNC_BAR_NEWCTX 1 + typedef void *(OSSL_OP_bar_newctx_fn)(void *provctx); + static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf) + { return (OSSL_OP_bar_newctx_fn *)opf->function; } + + #define OSSL_FUNC_BAR_FREECTX 2 + typedef void (OSSL_OP_bar_freectx_fn)(void *ctx); + static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf) + { return (OSSL_OP_bar_freectx_fn *)opf->function; } + + #define OSSL_FUNC_BAR_INIT 3 + typedef void *(OSSL_OP_bar_init_fn)(void *ctx); + static ossl_inline OSSL_get_bar_init(const OSSL_DISPATCH *opf) + { return (OSSL_OP_bar_init_fn *)opf->function; } + + #define OSSL_FUNC_BAR_UPDATE 4 + typedef void *(OSSL_OP_bar_update_fn)(void *ctx, + unsigned char *in, size_t inl); + static ossl_inline OSSL_get_bar_update(const OSSL_DISPATCH *opf) + { return (OSSL_OP_bar_update_fn *)opf->function; } + + #define OSSL_FUNC_BAR_FINAL 5 + typedef void *(OSSL_OP_bar_final_fn)(void *ctx); + static ossl_inline OSSL_get_bar_final(const OSSL_DISPATCH *opf) + { return (OSSL_OP_bar_final_fn *)opf->function; } + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The concept of providers and everything surrounding them was +introduced in OpenSSL 3.0. + +=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/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod new file mode 100644 index 00000000..d5d2f133 --- /dev/null +++ b/doc/man7/provider-cipher.pod @@ -0,0 +1,349 @@ +=pod + +=head1 NAME + +provider-cipher - The cipher library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Context management */ + void *OP_cipher_newctx(void *provctx); + void OP_cipher_freectx(void *cctx); + void *OP_cipher_dupctx(void *cctx); + + /* Encryption/decryption */ + int OP_cipher_encrypt_init(void *cctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen); + int OP_cipher_decrypt_init(void *cctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen); + int OP_cipher_update(void *cctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl); + int OP_cipher_final(void *cctx, unsigned char *out, size_t *outl, + size_t outsize); + int OP_cipher_cipher(void *cctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl); + + /* Cipher parameter descriptors */ + const OSSL_PARAM *OP_cipher_gettable_params(void); + + /* Cipher operation parameter descriptors */ + const OSSL_PARAM *OP_cipher_gettable_ctx_params(void); + const OSSL_PARAM *OP_cipher_settable_ctx_params(void); + + /* Cipher parameters */ + int OP_cipher_get_params(OSSL_PARAM params[]); + + /* Cipher operation parameters */ + int OP_cipher_get_ctx_params(void *cctx, OSSL_PARAM params[]); + int OP_cipher_set_ctx_params(void *cctx, const OSSL_PARAM params[]); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The CIPHER operation enables providers to implement cipher algorithms and make +them available to applications via the API functions L, +L and L (as well as the decrypt +equivalents and other related functions). + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_cipher_newctx() has these: + + typedef void *(OSSL_OP_cipher_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_cipher_newctx_fn + OSSL_get_OP_cipher_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_cipher_newctx OSSL_FUNC_CIPHER_NEWCTX + OP_cipher_freectx OSSL_FUNC_CIPHER_FREECTX + OP_cipher_dupctx OSSL_FUNC_CIPHER_DUPCTX + + OP_cipher_encrypt_init OSSL_FUNC_CIPHER_ENCRYPT_INIT + OP_cipher_decrypt_init OSSL_FUNC_CIPHER_DECRYPT_INIT + OP_cipher_update OSSL_FUNC_CIPHER_UPDATE + OP_cipher_final OSSL_FUNC_CIPHER_FINAL + OP_cipher_cipher OSSL_FUNC_CIPHER_CIPHER + + OP_cipher_get_params OSSL_FUNC_CIPHER_GET_PARAMS + OP_cipher_get_ctx_params OSSL_FUNC_CIPHER_GET_CTX_PARAMS + OP_cipher_set_ctx_params OSSL_FUNC_CIPHER_SET_CTX_PARAMS + + OP_cipher_gettable_params OSSL_FUNC_CIPHER_GETTABLE_PARAMS + OP_cipher_gettable_ctx_params OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS + OP_cipher_settable_ctx_params OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS + +A cipher algorithm implementation may not implement all of these functions. +In order to be a consistent set of functions there must at least be a complete +set of "encrypt" functions, or a complete set of "decrypt" functions, or a +single "cipher" function. +In all cases both the OP_cipher_newctx and OP_cipher_freectx functions must be +present. +All other functions are optional. + +=head2 Context Management Functions + +OP_cipher_newctx() should create and return a pointer to a provider side +structure for holding context information during a cipher operation. +A pointer to this context will be passed back in a number of the other cipher +operation function calls. +The parameter B is the provider context generated during provider +initialisation (see L). + +OP_cipher_freectx() is passed a pointer to the provider side cipher context in +the B parameter. +This function should free any resources associated with that context. + +OP_cipher_dupctx() should duplicate the provider side cipher context in the +B parameter and return the duplicate copy. + +=head2 Encryption/Decryption Functions + +OP_cipher_encrypt_init() initialises a cipher operation for encryption given a +newly created provider side cipher context in the B parameter. +The key to be used is given in B which is B bytes long. +The IV to be used is given in B which is B bytes long. + +OP_cipher_decrypt_init() is the same as OP_cipher_encrypt_init() except that it +initialises the context for a decryption operation. + +OP_cipher_update() is called to supply data to be encrypted/decrypted as part of +a previously initialised cipher operation. +The B parameter contains a pointer to a previously initialised provider +side context. +OP_cipher_update() should encrypt/decrypt B bytes of data at the location +pointed to by B. +The encrypted data should be stored in B and the amount of data written to +B<*outl> which should not exceed B bytes. +OP_cipher_update() may be called multiple times for a single cipher operation. +It is the responsibility of the cipher implementation to handle input lengths +that are not multiples of the block length. +In such cases a cipher implementation will typically cache partial blocks of +input data until a complete block is obtained. +B may be the same location as B but it should not partially overlap. +The same expectations apply to B as documented for +L and L. + +OP_cipher_final() completes an encryption or decryption started through previous +OP_cipher_encrypt_init() or OP_cipher_decrypt_init(), and OP_cipher_update() +calls. +The B parameter contains a pointer to the provider side context. +Any final encryption/decryption output should be written to B and the +amount of data written to B<*outl> which should not exceed B bytes. +The same expectations apply to B as documented for +L and L. + +OP_cipher_cipher() performs encryption/decryption using the provider side cipher +context in the B parameter that should have been previously initialised via +a call to OP_cipher_encrypt_init() or OP_cipher_decrypt_init. +This should call the raw underlying cipher function without any padding. +This will be invoked in the provider as a result of the application calling +L. +The application is responsible for ensuring that the input is a multiple of the +block length. +The data to be encrypted/decrypted will be in B, and it will be B bytes +in length. +The output from the encryption/decryption should be stored in B and the +amount of data stored should be put in B<*outl> which should be no more than +B bytes. + +=head2 Cipher Parameters + +See L for further details on the parameters structure used by +these functions. + +OP_cipher_get_params() gets details of the algorithm implementation +and stores them in B. + +OP_cipher_set_ctx_params() sets cipher operation parameters for the +provider side cipher context B to B. +Any parameter settings are additional to any that were previously set. + +OP_cipher_get_ctx_params() gets cipher operation details details from +the given provider side cipher context B and stores them in B. + +OP_cipher_gettable_params(), OP_cipher_gettable_ctx_params(), and +OP_cipher_settable_ctx_params() all return constant B arrays +as descriptors of the parameters that OP_cipher_get_params(), +OP_cipher_get_ctx_params(), and OP_cipher_set_ctx_params() can handle, +respectively. + +Parameters currently recognised by built-in ciphers are as follows. Not all +parameters are relevant to, or are understood by all ciphers: + +=over 4 + +=item B (uint) + +Sets the padding mode for the associated cipher ctx. +Setting a value of 1 will turn padding on. +Setting a value of 0 will turn padding off. + +=item B (uint) + +Gets the mode for the associated cipher algorithm. +See L for a list of valid modes. + +=item B (size_t) + +Gets the block size for the associated cipher algorithm. +The block size should be 1 for stream ciphers. +Note that the block size for a cipher may be different to the block size for +the underlying encryption/decryption primitive. +For example AES in CTR mode has a block size of 1 (because it operates like a +stream cipher), even though AES has a block size of 16. + +=item B (ulong) + +Gets any flags for the associated cipher algorithm. +See L for a list of currently defined cipher +flags. + +=item B (size_t) + +Gets the key length for the associated cipher algorithm. +This can also be used to get or set the key length for the associated cipher +ctx. + +=item B (size_t) + +Gets the IV length for the associated cipher algorithm. + +=item B (octet_string OR octet_ptr) + +Gets the IV for the associated cipher ctx. + +=item B (uint) + +Gets or sets the cipher specific "num" parameter for the associated cipher ctx. +Built-in ciphers typically use this to track how much of the current underlying +block has been "used" already. + +=item B (octet_string) + +Gets or sets the AEAD tag for the associated cipher ctx. +See L. + +=item B (size_t) + +Gets the tag length to be used for an AEAD cipher for the associated cipher ctx. +It returns a default value if it has not been set. + +=item B (octet_string) + +=for comment TODO(3.0): Consider changing this interface so that all ciphers +use the standard AEAD interface - rather than having this special purpose +interface for TLS + +Sets TLSv1.2 AAD information for the associated cipher ctx. +TLSv1.2 AAD information is always 13 bytes in length and is as defined for the +"additional_data" field described in section 6.2.3.3 of RFC5246. + +=item B (size_t) + +Gets the length of the tag that will be added to a TLS record for the AEAD +tag for the associated cipher ctx. + +=item B (octet_string) + +=for comment TODO(3.0): This interface needs completely redesigning! + +Sets the fixed portion of an IV for an AEAD cipher used in a TLS record +encryption/ decryption for the associated cipher ctx. +TLS record encryption/decryption always occurs "in place" so that the input and +output buffers are always the same memory location. +AEAD IVs in TLSv1.2 consist of an implicit "fixed" part and an explicit part +that varies with every record. +Setting a TLS fixed IV changes a cipher to encrypt/decrypt TLS records. +TLS records are encrypted/decrypted using a single OP_cipher_cipher call per +record. +For a record decryption the first bytes of the input buffer will be the explict +part of the IV and the final bytes of the input buffer will be the AEAD tag. +The length of the explicit part of the IV and the tag length will depend on the +cipher in use and will be defined in the RFC for the relevant ciphersuite. +In order to allow for "in place" decryption the plaintext output should be +written to the same location in the output buffer that the ciphertext payload +was read from, i.e. immediately after the explicit IV. + +When encrypting a record the first bytes of the input buffer will be empty to +allow space for the explicit IV, as will the final bytes where the tag will +be written. +The length of the input buffer will include the length of the explicit IV, the +payload, and the tag bytes. +The cipher implementation should generate the explicit IV and write it to the +beginning of the output buffer, do "in place" encryption of the payload and +write that to the output buffer, and finally add the tag onto the end of the +output buffer. + +Whether encrypting or decrypting the value written to B<*outl> in the +OP_cipher_cipher call should be the length of the payload excluding the explicit +IV length and the tag length. + +=item B (size_t) + +Sets the IV length to be used for an AEAD cipher for the associated cipher ctx. + +=item B (octet_string) + +Gets a implementation specific randomly generated key for the associated +cipher ctx. This is currently only supported by 3DES (which sets the key to +odd parity). + +=back + +=head1 RETURN VALUES + +OP_cipher_newctx() and OP_cipher_dupctx() should return the newly created +provider side cipher context, or NULL on failure. + +OP_cipher_encrypt_init(), OP_cipher_decrypt_init(), OP_cipher_update(), +OP_cipher_final(), OP_cipher_cipher(), OP_cipher_get_params(), +OP_cipher_get_ctx_params() and OP_cipher_set_ctx_params() should return 1 for +success or 0 on error. + +OP_cipher_gettable_params(), OP_cipher_gettable_ctx_params() and +OP_cipher_settable_ctx_params() should return a constant B +array, or NULL if none is offered. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider CIPHER interface was introduced in OpenSSL 3.0. + +=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/man7/provider-digest.pod b/doc/man7/provider-digest.pod new file mode 100644 index 00000000..3d780845 --- /dev/null +++ b/doc/man7/provider-digest.pod @@ -0,0 +1,293 @@ +=pod + +=head1 NAME + +provider-digest - The digest library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * Digests support the following function signatures in OSSL_DISPATCH arrays. + * (The function signatures are not actual functions). + */ + + /* Context management */ + void *OP_digest_newctx(void *provctx); + void OP_digest_freectx(void *dctx); + void *OP_digest_dupctx(void *dctx); + + /* Digest generation */ + int OP_digest_init(void *dctx); + int OP_digest_update(void *dctx, const unsigned char *in, size_t inl); + int OP_digest_final(void *dctx, unsigned char *out, size_t *outl, + size_t outsz); + int OP_digest_digest(void *provctx, const unsigned char *in, size_t inl, + unsigned char *out, size_t *outl, size_t outsz); + + /* Digest parameter descriptors */ + const OSSL_PARAM *OP_cipher_gettable_params(void); + + /* Digest operation parameter descriptors */ + const OSSL_PARAM *OP_cipher_gettable_ctx_params(void); + const OSSL_PARAM *OP_cipher_settable_ctx_params(void); + + /* Digest parameters */ + int OP_digest_get_params(OSSL_PARAM params[]); + + /* Digest operation parameters */ + int OP_digest_set_ctx_params(void *dctx, const OSSL_PARAM params[]); + int OP_digest_get_ctx_params(void *dctx, OSSL_PARAM params[]); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The DIGEST operation enables providers to implement digest algorithms and make +them available to applications via the API functions L, +L and L (and other related functions). + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_digest_newctx() has these: + + typedef void *(OSSL_OP_digest_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_digest_newctx_fn + OSSL_get_OP_digest_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_digest_newctx OSSL_FUNC_DIGEST_NEWCTX + OP_digest_freectx OSSL_FUNC_DIGEST_FREECTX + OP_digest_dupctx OSSL_FUNC_DIGEST_DUPCTX + + OP_digest_init OSSL_FUNC_DIGEST_INIT + OP_digest_update OSSL_FUNC_DIGEST_UPDATE + OP_digest_final OSSL_FUNC_DIGEST_FINAL + OP_digest_digest OSSL_FUNC_DIGEST_DIGEST + + OP_digest_get_params OSSL_FUNC_DIGEST_GET_PARAMS + OP_digest_get_ctx_params OSSL_FUNC_DIGEST_GET_CTX_PARAMS + OP_digest_set_ctx_params OSSL_FUNC_DIGEST_SET_CTX_PARAMS + + OP_digest_gettable_params OSSL_FUNC_DIGEST_GETTABLE_PARAMS + OP_digest_gettable_ctx_params OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS + OP_digest_settable_ctx_params OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS + +A digest algorithm implementation may not implement all of these functions. +In order to be usable all or none of OP_digest_newctx, OP_digest_freectx, +OP_digest_init, OP_digest_update and OP_digest_final should be implemented. +All other functions are optional. + +=head2 Context Management Functions + +OP_digest_newctx() should create and return a pointer to a provider side +structure for holding context information during a digest operation. +A pointer to this context will be passed back in a number of the other digest +operation function calls. +The parameter B is the provider context generated during provider +initialisation (see L). + +OP_digest_freectx() is passed a pointer to the provider side digest context in +the B parameter. +This function should free any resources associated with that context. + +OP_digest_dupctx() should duplicate the provider side digest context in the +B parameter and return the duplicate copy. + +=head2 Digest Generation Functions + +OP_digest_init() initialises a digest operation given a newly created +provider side digest context in the B parameter. + +OP_digest_update() is called to supply data to be digested as part of a +previously initialised digest operation. +The B parameter contains a pointer to a previously initialised provider +side context. +OP_digest_update() should digest B bytes of data at the location pointed to +by B. +OP_digest_update() may be called multiple times for a single digest operation. + +OP_digest_final() generates a digest started through previous OP_digest_init() +and OP_digest_update() calls. +The B parameter contains a pointer to the provider side context. +The digest should be written to B<*out> and the length of the digest to +B<*outl>. +The digest should not exceed B bytes. + +OP_digest_digest() is a "oneshot" digest function. +No provider side digest context is used. +Instead the provider context that was created during provider initialisation is +passed in the B parameter (see L). +B bytes at B should be digested and the result should be stored at +B. The length of the digest should be stored in B<*outl> which should not +exceed B bytes. + +=head2 Digest Parameters + +See L for further details on the parameters structure used by +these functions. + +OP_digest_get_params() gets details of the algorithm implementation +and stores them in B. + +OP_digest_set_ctx_params() sets digest operation parameters for the +provider side digest context B to B. +Any parameter settings are additional to any that were previously set. + +OP_digest_get_ctx_params() gets digest operation details details from +the given provider side digest context B and stores them in B. + +OP_digest_gettable_params(), OP_digest_gettable_ctx_params(), and +OP_digest_settable_ctx_params() all return constant B arrays +as descriptors of the parameters that OP_digest_get_params(), +OP_digest_get_ctx_params(), and OP_digest_set_ctx_params() can handle, +respectively. + +Parameters currently recognised by built-in digests with this function +are as follows. Not all parameters are relevant to, or are understood +by all digests: + +=over 4 + +=item B (size_t) + +The digest block size. + +=item B (size_t) + +The digest output size. + +=item B (unsigned long) + +Diverse flags that describe exceptional behaviour for the digest: + +=over 4 + +=item B + +This digest method can only handle one block of input. + +=item B + +This digest method is an extensible-output function (XOF) and supports +setting the B parameter. + +=item B + +When setting up a DigestAlgorithmIdentifier, this flag will have the +parameter set to NULL by default. Use this for PKCS#1. I + +=item B + +When setting up a DigestAlgorithmIdentifier, this flag will have the +parameter be left absent by default. I + +=item B + +Custom DigestAlgorithmIdentifier handling via ctrl, with +B as default. I +Currently unused. + +=back + +=back + +=head2 Digest Context Parameters + +OP_digest_set_ctx_params() sets digest parameters associated with the +given provider side digest context B to B. +Any parameter settings are additional to any that were previously set. +See L for further details on the parameters structure. + +OP_digest_get_ctx_params() gets details of currently set parameters +values associated with the give provider side digest context B +and stores them in B. +See L for further details on the parameters structure. + +Parameters currently recognised by built-in digests are as follows. Not all +parameters are relevant to, or are understood by all digests: + +=over 4 + +=item B (size_t) + +Sets the digest length for extendable output functions. + +=item B (octet string) + +This parameter is set by libssl in order to calculate a signature hash for an +SSLv3 CertificateVerify message as per RFC6101. +It is only set after all handshake messages have already been digested via +OP_digest_update() calls. +The parameter provides the master secret value to be added to the digest. +The digest implementation should calculate the complete digest as per RFC6101 +section 5.6.8. +The next call after setting this parameter will be OP_digest_final(). +This is only relevant for implementations of SHA1 or MD5_SHA1. + +=item B (uint) + +Sets the pad type to be used. +The only built-in digest that uses this is MDC2. +Normally the final MDC2 block is padded with 0s. +If the pad type is set to 2 then the final block is padded with 0x80 followed by +0s. + +=item B (utf8 string) + +Gets the digest Message Integrity Check algorithm string. +This is used when creating S/MIME multipart/signed messages, as specified in +RFC 5751. + +=back + +=head1 RETURN VALUES + +OP_digest_newctx() and OP_digest_dupctx() should return the newly created +provider side digest context, or NULL on failure. + +OP_digest_init(), OP_digest_update(), OP_digest_final(), OP_digest_digest(), +OP_digest_set_params() and OP_digest_get_params() should return 1 for success or +0 on error. + +OP_digest_size() should return the digest size. + +OP_digest_block_size() should return the block size of the underlying digest +algorithm. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider DIGEST interface was introduced in OpenSSL 3.0. + +=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/man7/provider-keyexch.pod b/doc/man7/provider-keyexch.pod new file mode 100644 index 00000000..9ef29439 --- /dev/null +++ b/doc/man7/provider-keyexch.pod @@ -0,0 +1,185 @@ +=pod + +=head1 NAME + +provider-keyexch - The keyexch library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Context management */ + void *OP_keyexch_newctx(void *provctx); + void OP_keyexch_freectx(void *ctx); + void *OP_keyexch_dupctx(void *ctx); + + /* Shared secret derivation */ + int OP_keyexch_init(void *ctx, void *provkey); + int OP_keyexch_set_peer(void *ctx, void *provkey); + int OP_keyexch_derive(void *ctx, unsigned char *secret, size_t *secretlen, + size_t outlen); + + /* Key Exchange parameters */ + int OP_keyexch_set_ctx_params(void *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *OP_keyexch_settable_ctx_params(void); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The key exchange (OSSL_OP_KEYEXCH) operation enables providers to implement key +exchange algorithms and make them available to applications via the API +functions L, and L (as well as +other related functions). + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_keyexch_newctx() has these: + + typedef void *(OSSL_OP_keyexch_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_keyexch_newctx_fn + OSSL_get_OP_keyexch_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_keyexch_newctx OSSL_FUNC_KEYEXCH_NEWCTX + OP_keyexch_freectx OSSL_FUNC_KEYEXCH_FREECTX + OP_keyexch_dupctx OSSL_FUNC_KEYEXCH_DUPCTX + + OP_keyexch_init OSSL_FUNC_KEYEXCH_INIT + OP_keyexch_set_peer OSSL_FUNC_KEYEXCH_SET_PEER + OP_keyexch_derive OSSL_FUNC_KEYEXCH_DERIVE + + OP_keyexch_set_ctx_params OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS + OP_keyexch_settable_ctx_params OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS + +A key exchange algorithm implementation may not implement all of these functions. +In order to be a consistent set of functions a provider must implement +OP_keyexch_newctx, OP_keyexch_freectx, OP_keyexch_init and OP_keyexch_derive. +All other functions are optional. + +A key exchange algorithm must also implement some mechanism for generating, +loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation. +See L for further details. + +=head2 Context Management Functions + +OP_keyexch_newctx() should create and return a pointer to a provider side +structure for holding context information during a key exchange operation. +A pointer to this context will be passed back in a number of the other key +exchange operation function calls. +The paramater B is the provider context generated during provider +initialisation (see L). + +OP_keyexch_freectx() is passed a pointer to the provider side key exchange +context in the B parameter. +This function should free any resources associated with that context. + +OP_keyexch_dupctx() should duplicate the provider side key exchange context in +the B parameter and return the duplicate copy. + +=head2 Shared Secret Derivation Functions + +OP_keyexch_init() initialises a key exchange operation given a provider side key +exchange context in the B paramter, and a pointer to a provider key object +in the B parameter. The key object should have been previously +generated, loaded or imported into the provider using the key management +(OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)>. + +OP_keyexch_set_peer() is called to supply the peer's public key (in the +B parameter) to be used when deriving the shared secret. +It is also passed a previously initialised key exchange context in the B +parameter. +The key object should have been previously generated, loaded or imported into +the provider using the key management (OSSL_OP_KEYMGMT) operation (see +provider-keymgmt(7)>. + +OP_keyexch_derive() performs the actual key exchange itself by deriving a shared +secret. +A previously initialised key exchange context is passed in the B +parameter. +The derived secret should be written to the location B which should not +exceed B bytes. +The length of the shared secret should be written to B<*secretlen>. +If B is NULL then the maximum length of the shared secret should be +written to B<*secretlen>. + +=head2 Key Exchange Parameters + +See L for further details on the parameters structure used by +the OP_keyexch_set_params() function. + +OP_keyexch_set_ctx_params() sets key exchange parameters associated with the +given provider side key exchange context B to B. +Any parameter settings are additional to any that were previously set. + +Parameters currently recognised by built-in key exchange algorithms are as +follows. +Not all parameters are relevant to, or are understood by all key exchange +algorithms: + +=over 4 + +=item B (uint) + +Sets the padding mode for the associated key exchange ctx. +Setting a value of 1 will turn padding on. +Setting a vlue of 0 will turn padding off. +If padding is off then the derived shared secret may be smaller than the largest +possible secret size. +If padding is on then the derived shared secret will have its first bytes filled +with 0s where necessary to make the shared secret the same size as the largest +possible secret size. + +=back + +OP_keyexch_settable_ctx_params() gets a constant B array that +decribes the settable parameters, i.e. parameters that can be used with +OP_signature_set_ctx_params(). +See L for the use of B as parameter descriptor. + +=head1 RETURN VALUES + +OP_keyexch_newctx() and OP_keyexch_dupctx() should return the newly created +provider side key exchange context, or NULL on failure. + +OP_keyexch_init(), OP_keyexch_set_peer(), OP_keyexch_derive() and +OP_keyexch_set_params() should return 1 for success or 0 on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider KEYEXCH interface was introduced in OpenSSL 3.0. + +=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/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod new file mode 100644 index 00000000..40f1ad63 --- /dev/null +++ b/doc/man7/provider-keymgmt.pod @@ -0,0 +1,178 @@ +=pod + +=head1 NAME + +provider-keymgmt - The KEYMGMT library E-E provider functions + +=head1 SYNOPSIS + + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Key domain parameter creation and destruction */ + void *OP_keymgmt_importdomparams(void *provctx, const OSSL_PARAM params[]); + void *OP_keymgmt_gendomparams(void *provctx, const OSSL_PARAM params[]); + void OP_keymgmt_freedomparams(void *domparams); + + /* Key domain parameter export */ + int OP_keymgmt_exportdomparams(void *domparams, OSSL_PARAM params[]); + + /* Key domain parameter discovery */ + const OSSL_PARAM *OP_keymgmt_importdomparam_types(void); + const OSSL_PARAM *OP_keymgmt_exportdomparam_types(void); + + /* Key creation and destruction */ + void *OP_keymgmt_importkey(void *provctx, const OSSL_PARAM params[]); + void *OP_keymgmt_genkey(void *provctx, + void *domparams, const OSSL_PARAM genkeyparams[]); + void *OP_keymgmt_loadkey(void *provctx, void *id, size_t idlen); + void OP_keymgmt_freekey(void *key); + + /* Key export */ + int OP_keymgmt_exportkey(void *key, OSSL_PARAM params[]); + + /* Key discovery */ + const OSSL_PARAM *OP_keymgmt_importkey_types(void); + const OSSL_PARAM *OP_keymgmt_exportkey_types(void); + +=head1 DESCRIPTION + +The KEYMGMT operation doesn't have much public visibility in OpenSSL +libraries, it's rather an internal operation that's designed to work +in tandem with operations that use private/public key pairs. + +Because the KEYMGMT operation shares knowledge with the operations it +works with in tandem, they must belong to the same provider. +The OpenSSL libraries will ensure that they do. + +The primary responsibility of the KEYMGMT operation is to hold the +provider side domain parameters and keys for the OpenSSL library +EVP_PKEY structure. + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from a B element named +B. +For example, the "function" OP_keymgmt_importdomparams() has these: + + typedef void * + (OSSL_OP_keymgmt_importdomparams_fn)(void *provctx, + const OSSL_PARAM params[]); + static ossl_inline OSSL_OP_keymgmt_importdomparams_fn + OSSL_get_OP_keymgmt_importdomparams(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_keymgmt_importdomparams OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS + OP_keymgmt_gendomparams OSSL_FUNC_KEYMGMT_GENDOMPARAMS + OP_keymgmt_freedomparams OSSL_FUNC_KEYMGMT_FREEDOMPARAMS + OP_keymgmt_exportdomparams OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS + OP_keymgmt_importdomparam_types OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES + OP_keymgmt_exportdomparam_types OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES + + OP_keymgmt_importkey OSSL_FUNC_KEYMGMT_IMPORTKEY + OP_keymgmt_genkey OSSL_FUNC_KEYMGMT_GENKEY + OP_keymgmt_loadkey OSSL_FUNC_KEYMGMT_LOADKEY + OP_keymgmt_freekey OSSL_FUNC_KEYMGMT_FREEKEY + OP_keymgmt_exportkey OSSL_FUNC_KEYMGMT_EXPORTKEY + OP_keymgmt_importkey_types OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES + OP_keymgmt_exportkey_types OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES + +=head2 Domain Parameter Functions + +OP_keymgmt_importdomparams() should create a provider side structure +for domain parameters, with values taken from the passed B +array I. + +OP_keymgmt_gendomparams() should generate domain parameters and create +a provider side structure for them. +Values of the passed B array I should be used as +input for parameter generation. + +OP_keymgmt_freedomparams() should free the passed provider side domain +parameter structure I. + +OP_keymgmt_exportdomparams() should extract values from the passed +provider side domain parameter structure I into the passed +B I. +Only the values specified in I should be extracted. + +OP_keymgmt_importdomparam_types() should return a constant array of +descriptor B, for parameters that OP_keymgmt_importdomparams() +can handle. + +=for comment There should be one corresponding to OP_keymgmt_gendomparams() +as well... + +OP_keymgmt_exportdomparam_types() should return a constant array of +descriptor B, for parameters that can be exported with +OP_keymgmt_exportdomparams(). + +=head2 Key functions + +OP_keymgmt_importkey() should create a provider side structure +for keys, with values taken from the passed B array +I. + +OP_keymgmt_genkey() should generate keys and create a provider side +structure for them. +Values from the passed domain parameters I as well as from +the passed B array I should be used as input for +key generation. + +OP_keymgmt_loadkey() should return a provider side key structure with +a key loaded from a location known only to the provider, identitified +with the identity I of size I. +This identity is internal to the provider and is retrieved from the +provider through other means. + +=for comment Right now, OP_keymgmt_loadkey is useless, but will be +useful as soon as we have a OSSL_STORE interface + +OP_keymgmt_freekey() should free the passed I. + +OP_keymgmt_exportkey() should extract values from the passed +provider side key I into the passed B I. +Only the values specified in I should be extracted. + +OP_keymgmt_importkey_types() should return a constant array of +descriptor B, for parameters that OP_keymgmt_importkey() +can handle. + +=for comment There should be one corresponding to OP_keymgmt_genkey() +as well... + +OP_keymgmt_exportkey_types() should return a constant array of +descriptor B, for parameters that can be exported with +OP_keymgmt_exportkeys(). + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The KEYMGMT interface was introduced in OpenSSL 3.0. + +=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/man7/provider-mac.pod b/doc/man7/provider-mac.pod new file mode 100644 index 00000000..14fb3afb --- /dev/null +++ b/doc/man7/provider-mac.pod @@ -0,0 +1,244 @@ +=pod + +=head1 NAME + +provider-mac - The mac library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Context management */ + void *OP_mac_newctx(void *provctx); + void OP_mac_freectx(void *mctx); + void *OP_mac_dupctx(void *src); + + /* Encryption/decryption */ + int OP_mac_init(void *mctx); + int OP_mac_update(void *mctx, const unsigned char *in, size_t inl); + int OP_mac_final(void *mctx, unsigned char *out, size_t *outl, size_t outsize); + + /* MAC parameter descriptors */ + const OSSL_PARAM *OP_mac_get_params(void); + const OSSL_PARAM *OP_mac_get_ctx_params(void); + const OSSL_PARAM *OP_mac_set_ctx_params(void); + + /* MAC parameters */ + int OP_mac_get_params(OSSL_PARAM params[]); + int OP_mac_get_ctx_params(void *mctx, OSSL_PARAM params[]); + int OP_mac_set_ctx_params(void *mctx, const OSSL_PARAM params[]); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The MAC operation enables providers to implement mac algorithms and make +them available to applications via the API functions L, +L and L. + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_mac_newctx() has these: + + typedef void *(OSSL_OP_mac_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_mac_newctx_fn + OSSL_get_OP_mac_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_mac_newctx OSSL_FUNC_MAC_NEWCTX + OP_mac_freectx OSSL_FUNC_MAC_FREECTX + OP_mac_dupctx OSSL_FUNC_MAC_DUPCTX + + OP_mac_init OSSL_FUNC_MAC_INIT + OP_mac_update OSSL_FUNC_MAC_UPDATE + OP_mac_final OSSL_FUNC_MAC_FINAL + + OP_mac_get_params OSSL_FUNC_MAC_GET_PARAMS + OP_mac_get_ctx_params OSSL_FUNC_MAC_GET_CTX_PARAMS + OP_mac_set_ctx_params OSSL_FUNC_MAC_SET_CTX_PARAMS + + OP_mac_gettable_params OSSL_FUNC_MAC_GETTABLE_PARAMS + OP_mac_gettable_ctx_params OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS + OP_mac_settable_ctx_params OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS + +A mac algorithm implementation may not implement all of these functions. +In order to be a consistent set of functions, at least the following functions +must be implemented: OP_mac_newctx(), OP_mac_freectx(), OP_mac_init(), +OP_mac_update(), OP_mac_final(). +All other functions are optional. + +=head2 Context Management Functions + +OP_mac_newctx() should create and return a pointer to a provider side +structure for holding context information during a mac operation. +A pointer to this context will be passed back in a number of the other mac +operation function calls. +The paramater I is the provider context generated during provider +initialisation (see L). + +OP_mac_freectx() is passed a pointer to the provider side mac context in +the I parameter. +If it receives NULL as I value, it should not do anything other than +return. +This function should free any resources associated with that context. + +OP_mac_dupctx() should duplicate the provider side mac context in the +I parameter and return the duplicate copy. + +=head2 Encryption/Decryption Functions + +OP_mac_init() initialises a mac operation given a newly created provider +side mac context in the I paramter. + +OP_mac_update() is called to supply data for MAC computation of a previously +initialised mac operation. +The I parameter contains a pointer to a previously initialised provider +side context. +OP_mac_update() may be called multiple times for a single mac operation. + +OP_mac_final() completes the MAC computation started through previous +OP_mac_init() and OP_mac_update() calls. +The I parameter contains a pointer to the provider side context. +The resulting MAC should be written to I and the amount of data written +to I<*outl>, which should not exceed I bytes. +The same expectations apply to I as documented for +L. + +=head2 Mac Parameters + +See L for further details on the parameters structure used by +these functions. + +OP_mac_get_params() gets details of parameter values associated with the +provider algorithm and stores them in I. + +OP_mac_set_ctx_params() sets mac parameters associated with the given +provider side mac context I to I. +Any parameter settings are additional to any that were previously set. + +OP_mac_get_ctx_params() gets details of currently set parameter values +associated with the given provider side mac context I and stores them +in I. + +OP_mac_gettable_params(), OP_mac_gettable_ctx_params(), and +OP_mac_settable_ctx_params() all return constant B arrays +as descriptors of the parameters that OP_mac_get_params(), +OP_mac_get_ctx_params(), and OP_mac_set_ctx_params() can handle, +respectively. + +Parameters currently recognised by built-in macs are as follows. Not all +parameters are relevant to, or are understood by all macs: + +=over 4 + +=item B (octet string) + +Sets the key in the associated MAC ctx. + +=item B (octet string) + +Sets the IV of the underlying cipher, when applicable. + +=item B (utf8 string) + +Sets the custom string in the associated MAC ctx. + +=item B (octet string) + +Sets the salt of the underlying cipher, when applicable. + +=item B (int) + +Sets XOF mode in the associated MAC ctx. +0 means no XOF mode, 1 means XOF mode. + +=item B (int) + +Gets flags associated with the MAC. + +=for comment We need to investigate if this is the right approach + +=item B (utf8 string) + +=item B (utf8 string) + +Sets the name of the underlying cipher or digest to be used. +It must name a suitable algorithm for the MAC that's being used. + +=item B (utf8 string) + +Sets the name of an engine that implements the underlying algorithm. +This must be given together with the algorithm naming parameter to be +considered valid. + +=item B (utf8 string) + +Sets the properties to be queried when trying to fetch the underlying algorithm. +This must be given together with the algorithm naming parameter to be +considered valid. + +Note that both this and B can be given at the same time. +If the underlying algorithm ends up being fetched from a provider, offered by +and engine, or a built in legacy function depends on what is available. + +=item B (int) + +Can be used to get the resulting MAC size. + +With some MAC algorithms, it can also be used to set the size that the +resulting MAC should have. +Allowable sizes are decided within each implementation. + +=back + +=head1 RETURN VALUES + +OP_mac_newctx() and OP_mac_dupctx() should return the newly created +provider side mac context, or NULL on failure. + +OP_mac_init(), OP_mac_update(), OP_mac_final(), OP_mac_get_params(), +OP_mac_get_ctx_params() and OP_mac_set_ctx_params() should return 1 for +success or 0 on error. + +OP_mac_gettable_params(), OP_mac_gettable_ctx_params() and +OP_mac_settable_ctx_params() should return a constant B +array, or NULL if none is offered. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider MAC interface was introduced in OpenSSL 3.0. + +=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/man7/provider-signature.pod b/doc/man7/provider-signature.pod new file mode 100644 index 00000000..1ab48310 --- /dev/null +++ b/doc/man7/provider-signature.pod @@ -0,0 +1,239 @@ +=pod + +=head1 NAME + +provider-signature - The signature library E-E provider functions + +=head1 SYNOPSIS + +=for comment multiple includes + + #include + #include + + /* + * None of these are actual functions, but are displayed like this for + * the function signatures for functions that are offered as function + * pointers in OSSL_DISPATCH arrays. + */ + + /* Context management */ + void *OP_signature_newctx(void *provctx); + void OP_signature_freectx(void *ctx); + void *OP_signature_dupctx(void *ctx); + + /* Signing */ + int OP_signature_sign_init(void *ctx, void *provkey); + int OP_signature_sign(void *ctx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen); + + /* Verifying */ + int OP_signature_verify_init(void *ctx, void *provkey); + int OP_signature_verify(void *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + + /* Verify Recover */ + int OP_signature_verify_recover_init(void *ctx, void *provkey); + int OP_signature_verify_recover(void *ctx, unsigned char *rout, + size_t *routlen, size_t routsize, + const unsigned char *sig, size_t siglen); + + /* Signature parameters */ + int OP_signature_get_ctx_params(void *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *OP_signature_gettable_ctx_params(void); + int OP_signature_set_ctx_params(void *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *OP_signature_settable_ctx_params(void); + +=head1 DESCRIPTION + +This documentation is primarily aimed at provider authors. See L +for further information. + +The signature (OSSL_OP_SIGNATURE) operation enables providers to implement +signature algorithms and make them available to applications via the API +functions L, L, +L, L, +L and L (as well +as other related functions). + +All "functions" mentioned here are passed as function pointers between +F and the provider in B arrays via +B arrays that are returned by the provider's +provider_query_operation() function +(see L). + +All these "functions" have a corresponding function type definition +named B, and a helper function to retrieve the +function pointer from an B element named +B. +For example, the "function" OP_signature_newctx() has these: + + typedef void *(OSSL_OP_signature_newctx_fn)(void *provctx); + static ossl_inline OSSL_OP_signature_newctx_fn + OSSL_get_OP_signature_newctx(const OSSL_DISPATCH *opf); + +B arrays are indexed by numbers that are provided as +macros in L, as follows: + + OP_signature_newctx OSSL_FUNC_SIGNATURE_NEWCTX + OP_signature_freectx OSSL_FUNC_SIGNATURE_FREECTX + OP_signature_dupctx OSSL_FUNC_SIGNATURE_DUPCTX + + OP_signature_sign_init OSSL_FUNC_SIGNATURE_SIGN_INIT + OP_signature_sign OSSL_FUNC_SIGNATURE_SIGN + + OP_signature_verify_init OSSL_FUNC_SIGNATURE_VERIFY_INIT + OP_signature_verify OSSL_FUNC_SIGNATURE_VERIFY + + OP_signature_verify_recover_init OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT + OP_signature_verify_recover OSSL_FUNC_SIGNATURE_VERIFY_RECOVER + + OP_signature_get_ctx_params OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS + OP_signature_gettable_ctx_params OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS + OP_signature_set_ctx_params OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS + OP_signature_settable_ctx_params OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS + +A signature algorithm implementation may not implement all of these functions. +In order to be a consistent set of functions a provider must implement +OP_signature_newctx and OP_signature_freectx. +It must also implement both of OP_signature_sign_init and OP_signature_sign, +or both of OP_signature_verify_init and OP_signature_verify, or both of +OP_signature_verify_recover_init and OP_signature_verify_recover. +All other functions are optional. + +A signature algorithm must also implement some mechanism for generating, +loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation. +See L for further details. + +=head2 Context Management Functions + +OP_signature_newctx() should create and return a pointer to a provider side +structure for holding context information during a signature operation. +A pointer to this context will be passed back in a number of the other signature +operation function calls. +The parameter B is the provider context generated during provider +initialisation (see L). + +OP_signature_freectx() is passed a pointer to the provider side signature +context in the B parameter. +This function should free any resources associated with that context. + +OP_signature_dupctx() should duplicate the provider side signature context in +the B parameter and return the duplicate copy. + +=head2 Signing Functions + +OP_signature_sign_init() initialises a context for signing given a provider side +signature context in the B parameter, and a pointer to a provider key object +in the B parameter. +The key object should have been previously generated, loaded or imported into +the provider using the key management (OSSL_OP_KEYMGMT) operation (see +provider-keymgmt(7)>. + +OP_signature_sign() performs the actual signing itself. +A previously initialised signature context is passed in the B +parameter. +The data to be signed is pointed to be the B parameter which is B +bytes long. +Unless B is NULL, the signature should be written to the location pointed +to by the B parameter and it should not exceed B bytes in length. +The length of the signature should be written to B<*siglen>. +If B is NULL then the maximum length of the signature should be written to +B<*siglen>. + +=head2 Verify Functions + +OP_signature_verify_init() initialises a context for verifying a signature given +a provider side signature context in the B parameter, and a pointer to a +provider key object in the B parameter. +The key object should have been previously generated, loaded or imported into +the provider using the key management (OSSL_OP_KEYMGMT) operation (see +provider-keymgmt(7)>. + +OP_signature_verify() performs the actual verification itself. +A previously initialised signature context is passed in the B parameter. +The data that the signature covers is pointed to be the B parameter which +is B bytes long. +The signature is pointed to by the B parameter which is B bytes +long. + +=head2 Verify Recover Functions + +OP_signature_verify_recover_init() initialises a context for recovering the +signed data given a provider side signature context in the B parameter, and +a pointer to a provider key object in the B parameter. +The key object should have been previously generated, loaded or imported into +the provider using the key management (OSSL_OP_KEYMGMT) operation (see +provider-keymgmt(7)>. + +OP_signature_verify_recover() performs the actual verify recover itself. +A previously initialised signature context is passed in the B parameter. +The signature is pointed to by the B parameter which is B bytes +long. +Unless B is NULL, the recovered data should be written to the location +pointed to by B which should not exceed B bytes in length. +The length of the recovered data should be written to B<*routlen>. +If B is B then the maximum size of the output buffer is written to +the B parameter. + +=head2 Signature Parameters + +See L for further details on the parameters structure used by +the OP_signature_get_ctx_params() and OP_signature_set_ctx_params() functions. + +OP_signature_get_ctx_params() gets signature parameters associated with the +given provider side signature context B and stored them in B. +OP_signature_set_ctx_params() sets the signature parameters associated with the +given provider side signature context B to B. +Any parameter settings are additional to any that were previously set. + +Parameters currently recognised by built-in signature algorithms are as +follows. +Not all parameters are relevant to, or are understood by all signature +algorithms: + +=over 4 + +=item "digest" (B) + +Get or sets the name of the digest algorithm used for the input to the signature +functions. + +=item "digest-size" (B) + +Gets or sets the output size of the digest algorithm used for the input to the +signature functions. + +=back + +OP_signature_gettable_ctx_params() and OP_signature_settable_ctx_params() get a +constant B array that decribes the gettable and settable parameters, +i.e. parameters that can be used with OP_signature_get_ctx_params() and +OP_signature_set_ctx_params() respectively. +See L for the use of B as parameter descriptor. + +=head1 RETURN VALUES + +OP_signature_newctx() and OP_signature_dupctx() should return the newly created +provider side signature, or NULL on failure. + +All other functions should return 1 for success or 0 on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The provider SIGNATURE interface was introduced in OpenSSL 3.0. + +=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/man7/provider.pod b/doc/man7/provider.pod new file mode 100644 index 00000000..f92d111e --- /dev/null +++ b/doc/man7/provider.pod @@ -0,0 +1,401 @@ +=pod + +=head1 NAME + +provider - OpenSSL operation implementation providers + +=head1 SYNOPSIS + +=for comment generic + +#include + +=head1 DESCRIPTION + +=head2 General + +A I, in OpenSSL terms, is a unit of code that provides one +or more implementations for various operations for diverse algorithms +that one might want to perform. + +An I is something one wants to do, such as encryption and +decryption, key derivation, MAC calculation, signing and verification, +etc. + +An I is a named method to perform an operation. +Very often, the algorithms revolve around cryptographic operations, +but may also revolve around other types of operation, such as managing +certain types of objects. + +=head2 Provider + +I + +A I offers an initialization function, as a set of base +functions in the form of an B array, and by extension, +a set of Bs (see L). +It may be a dynamically loadable module, or may be built-in, in +OpenSSL libraries or in the application. +If it's a dynamically loadable module, the initialization function +must be named C and must be exported. +If it's built-in, the initialization function may have any name. + +The initialization function must have the following signature: + + int NAME(const OSSL_PROVIDER *provider, + const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, + void **provctx); + +I is the OpenSSL library object for the provider, and works +as a handle for everything the OpenSSL libraries need to know about +the provider. +For the provider itself, it may hold some interesting information, +and is also passed to some of the functions given in the dispatch +array I. + +I is a dispatch array of base functions offered by the OpenSSL +libraries, and the available functions are further described in +L. + +I<*out> must be assigned a dispatch array of base functions that the +provider offers to the OpenSSL libraries. +The functions that may be offered are further described in +L, and they are the central means of communication +between the OpenSSL libraries and the provider. + +I<*provctx> should be assigned a provider specific context to allow +the provider multiple simultaneous uses. +This pointer will be passed to various operation functions offered by +the provider. + +One of the functions the provider offers to the OpenSSL libraries is +the central mechanism for the OpenSSL libraries to get access to +operation implementations for diverse algorithms. +Its referred to with the number B +and has the following signature: + + const OSSL_ALGORITHM *provider_query_operation(void *provctx, + int operation_id, + const int *no_store); + +I is the provider specific context that was passed back by +the initialization function. + +I is an operation identity (see L below). + +I is a flag back to the OpenSSL libraries which, when +non-zero, signifies that the OpenSSL libraries will not store a +reference to the returned data in their internal store of +implementations. + +The returned B is the foundation of any OpenSSL +library API that uses providers for their implementation, most +commonly in the I type of functions +(see L below). + +=head2 Operations + +I + +Operations are referred to with numbers, via macros with names +starting with C. + +With each operation comes a set of defined function types that a +provider may or may not offer, depending on its needs. + +Currently available operations are: + +=over 4 + +=item Digests + +In the OpenSSL libraries, the corresponding method object is +B. +The number for this operation is B. +The functions the provider can offer are described in +L + +=item Symmetric ciphers + +In the OpenSSL libraries, the corresponding method object is +B. +The number for this operation is B. +The functions the provider can offer are described in +L + +=begin comment NOT AVAILABLE YET + +=item Message Authentication Code (MAC) + +In the OpenSSL libraries, the corresponding method object is +B. +The number for this operation is B. +The functions the provider can offer are described in +L + +=end comment + +=begin comment NOT AVAILABLE YET + +=item Key Derivation Function (KDF) + +In the OpenSSL libraries, the corresponding method object is +B. +The number for this operation is B. +The functions the provider can offer are described in +L + +=end comment + +=item Key Exchange + +In the OpenSSL libraries, the corresponding method object is +B. +The number for this operation is B. +The functions the provider can offer are described in +L + +=back + +=head2 Fetching algorithms + +=head3 Explicit fetch + +I + +Users of the OpenSSL libraries never query the provider directly for +its diverse implementations and dispatch tables. +Instead, the diverse OpenSSL APIs often have fetching functions that +do the work, and they return an appropriate method object back to the +user. +These functions usually have the name C, where +C is the name of the API, for example L. + +These fetching functions follow a fairly common pattern, where three +arguments are passed: + +=over 4 + +=item The library context + +See L for a more detailed description. +This may be NULL to signify the default (global) library context, or a +context created by the user. +Only providers loaded in this library context (see +L) will be considered by the fetching +function. + +=item An identifier + +This is most commonly an algorithm name (this is the case for all EVP +methods), but may also be called something else. + +=for comment For example, an OSSL_STORE implementation would use the +URI scheme as an identifier. + +=item A property query string + +See L for a more detailed description. +This is used to select more exactly which providers will get to offer +an implementation. + +=back + +The method object that is fetched can then be used with diverse other +functions that use them, for example L. + +=head3 Implicit fetch + +I + +OpenSSL has a number of functions that return a method object with no +associated implementation, such as L, +L or L, which are present for +compatibility with OpenSSL before version 3.0. + +When they are used with functions like L or +L, the actual implementation to be used is +fetched implicitly using default search criteria. + +Implicit fetching can also occur with functions such as +L where a NULL algorithm parameter is +supplied. +In this case an algorithm implementation is implicitly fetched using +default search criteria and an algorithm name that is consistent with +the type of EVP_PKEY being used. + +=head1 OPENSSL PROVIDERS + +OpenSSL comes with a set of providers. +All the algorithm names mentioned can be used as an algorithm +identifier to the appropriate fetching function. + +=head2 Default provider + +The default provider is built in as part of the F library. +Should it be needed (if other providers are loaded and offer +implementations of the same algorithms), the property "default=yes" +can be used as a search criterion for these implementations. + +It currently offers the following named algorithms: + +=over 4 + +=item Digests + +SHA1, SHA224, SHA256, SHA384, SHA512, SHA512-224, SHA512-256, +SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256, SM3, +BLAKE2b512, BLAKE2s256, KMAC128, KMAC256, MD5, MD5-SHA1 + +=item Symmetric ciphers + +AES-256-ECB, AES-192-ECB, AES-128-ECB, AES-256-CBC, AES-192-CBC, +AES-128-CBC, AES-256-OFB, AES-192-OFB, AES-128-OFB, AES-256-CFB, +AES-192-CFB, AES-128-CFB, AES-256-CFB1, AES-192-CFB1, AES-128-CFB1, +AES-256-CFB8, AES-192-CFB8, AES-128-CFB8, AES-256-CTR, AES-192-CTR, +AES-128-CTR, id-aes256-GCM, id-aes192-GCM, id-aes128-GCM + +=item Key Exchange + +dhKeyAgreement + +=back + +=head2 FIPS provider + +The FIPS provider is a dynamically loadable module, and must therefore +be loaded explicitly, either in code or through OpenSSL configuration +(see L). +Should it be needed (if other providers are loaded and offer +implementations of the same algorithms), the property "fips=yes" can +be used as a search criterion for these implementations. + +It currently offers the following FIPS approved named algorithms: + +=over 4 + +=item Digests + +SHA1, SHA224, SHA256, SHA384, SHA512, SHA512-224, SHA512-256, +SHA3-224, SHA3-256, SHA3-384, SHA3-512, KMAC128, KMAC256 + +=item Symmetric ciphers + +AES-256-ECB, AES-192-ECB, AES-128-ECB, AES-256-CBC, AES-192-CBC, +AES-128-CBC, AES-256-CTR, AES-192-CTR, AES-128-CTR + +=back + +=head2 Legacy provider + +The legacy provider is a dynamically loadable module, and must therefore +be loaded explicitly, either in code or through OpenSSL configuration +(see L). +Should it be needed (if other providers are loaded and offer +implementations of the same algorithms), the property "legacy=yes" can be +used as a search criterion for these implementations. + +It currently offers the following named algorithms: + +=over 4 + +=item Digest algorithms: + +RIPEMD160, MD2, MD4, MDC2, whirlpool. + +=back + +=head1 EXAMPLES + +=head2 Fetching + +Fetch any available implementation of SHA256 in the default context: + + EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", NULL); + ... + EVP_MD_meth_free(md); + +Fetch any available implementation of AES-128-CBC in the default context: + + EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", NULL); + ... + EVP_CIPHER_meth_free(cipher); + +Fetch an implementation of SHA256 from the default provider in the default +context: + + EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", "default=yes"); + ... + EVP_MD_meth_free(md); + +Fetch an implementation of SHA256 that is not from the default provider in the +default context: + + EVP_MD *md = EVP_MD_fetch(NULL, "SHA256", "default=no"); + ... + EVP_MD_meth_free(md); + +Fetch an implementation of SHA256 from the default provider in the specified +context: + + EVP_MD *md = EVP_MD_fetch(ctx, "SHA256", "default=yes"); + ... + EVP_MD_meth_free(md); + +Load the legacy provider into the default context and then fetch an +implementation of whirlpool from it: + + /* This only needs to be done once - usually at application start up */ + OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy"); + + EVP_MD *md = EVP_MD_fetch(NULL, "whirlpool", "legacy=yes"); + ... + EVP_MD_meth_free(md); + +Note that in the above example the property string "legacy=yes" is optional +since, assuming no other providers have been loaded, the only implementation of +the "whirlpool" algorithm is in the "legacy" provider. Also note that the +default provider should be explicitly loaded if it is required in addition to +other providers: + + /* This only needs to be done once - usually at application start up */ + OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy"); + OSSL_PROVIDER *default = OSSL_PROVIDER_load(NULL, "default"); + + EVP_MD *md_whirlpool = EVP_MD_fetch(NULL, "whirlpool", NULL); + EVP_MD *md_sha256 = EVP_MD_fetch(NULL, "SHA256", NULL); + ... + EVP_MD_meth_free(md_whirlpool); + EVP_MD_meth_free(md_sha256); + + +=head1 SEE ALSO + +L, L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +The concept of providers and everything surrounding them was +introduced in OpenSSL 3.0. + +=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/man7/x509.pod b/doc/man7/x509.pod index 2d4edaa2..095203c9 100644 --- a/doc/man7/x509.pod +++ b/doc/man7/x509.pod @@ -58,7 +58,6 @@ L, L, L, L, -L, L =head1 COPYRIGHT diff --git a/e_os.h b/e_os.h index 5c887d42..6cd74762 100644 --- a/e_os.h +++ b/e_os.h @@ -28,6 +28,35 @@ * default, we will try to read at least one of these files */ # define DEVRANDOM "/dev/urandom", "/dev/random", "/dev/hwrng", "/dev/srandom" +# if defined(__linux) && !defined(__ANDROID__) +# ifndef DEVRANDOM_WAIT +# define DEVRANDOM_WAIT "/dev/random" +# endif +/* + * Linux kernels 4.8 and later changes how their random device works and there + * is no reliable way to tell that /dev/urandom has been seeded -- getentropy(2) + * should be used instead. + */ +# ifndef DEVRANDOM_SAFE_KERNEL +# define DEVRANDOM_SAFE_KERNEL 4, 8 +# endif +/* + * Some operating systems do not permit select(2) on their random devices, + * defining this to zero will force the used of read(2) to extract one byte + * from /dev/random. + */ +# ifndef DEVRANDM_WAIT_USE_SELECT +# define DEVRANDM_WAIT_USE_SELECT 1 +# endif +/* + * Define the shared memory identifier used to indicate if the operating + * system has properly seeded the DEVRANDOM source. + */ +# ifndef OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID +# define OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID 114 +# endif + +# endif # endif # if !defined(OPENSSL_NO_EGD) && !defined(DEVRANDOM_EGD) /* diff --git a/engines/asm/e_padlock-x86.pl b/engines/asm/e_padlock-x86.pl index 73e72e61..f579a4d9 100644 --- a/engines/asm/e_padlock-x86.pl +++ b/engines/asm/e_padlock-x86.pl @@ -42,8 +42,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../crypto/perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/engines/asm/e_padlock-x86_64.pl b/engines/asm/e_padlock-x86_64.pl index 63a05320..7982f199 100644 --- a/engines/asm/e_padlock-x86_64.pl +++ b/engines/asm/e_padlock-x86_64.pl @@ -19,9 +19,10 @@ # Assembler helpers for Padlock engine. See even e_padlock-x86.pl for # details. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $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 +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -30,7 +31,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../crypto/perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code=".text\n"; diff --git a/engines/build.info b/engines/build.info index 77aab6d5..fca41358 100644 --- a/engines/build.info +++ b/engines/build.info @@ -86,7 +86,6 @@ IF[{- !$disabled{"engine"} -}] GENERATE[ossltest.ld]=../util/engines.num ENDIF ENDIF - GENERATE[e_padlock-x86.s]=asm/e_padlock-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) - GENERATE[e_padlock-x86_64.s]=asm/e_padlock-x86_64.pl $(PERLASM_SCHEME) + GENERATE[e_padlock-x86.s]=asm/e_padlock-x86.pl + GENERATE[e_padlock-x86_64.s]=asm/e_padlock-x86_64.pl ENDIF diff --git a/engines/e_afalg.c b/engines/e_afalg.c index c3f622e7..99516cb1 100644 --- a/engines/e_afalg.c +++ b/engines/e_afalg.c @@ -63,9 +63,6 @@ void engine_load_afalg_int(void) # define ALG_OP_TYPE unsigned int # define ALG_OP_LEN (sizeof(ALG_OP_TYPE)) -#define ALG_MAX_SALG_NAME 64 -#define ALG_MAX_SALG_TYPE 14 - # ifdef OPENSSL_NO_DYNAMIC_ENGINE void engine_load_afalg_int(void); # endif @@ -128,7 +125,23 @@ static ossl_inline int io_getevents(aio_context_t ctx, long min, long max, struct io_event *events, struct timespec *timeout) { +#if defined(__NR_io_getevents) return syscall(__NR_io_getevents, ctx, min, max, events, timeout); +#elif defined(__NR_io_pgetevents_time64) + /* Let's only support the 64 suffix syscalls for 64-bit time_t. + * This simplifies the code for us as we don't need to use a 64-bit + * version of timespec with a 32-bit time_t and handle converting + * between 64-bit and 32-bit times and check for overflows. + */ + if (sizeof(timeout->tv_sec) == 8) + return syscall(__NR_io_pgetevents_time64, ctx, min, max, events, timeout, NULL); + else { + errno = ENOSYS; + return -1; + } +#else +# error "We require either the io_getevents syscall or __NR_io_pgetevents_time64." +#endif } static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, @@ -371,10 +384,8 @@ static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, memset(&sa, 0, sizeof(sa)); sa.salg_family = AF_ALG; - strncpy((char *) sa.salg_type, ciphertype, ALG_MAX_SALG_TYPE); - sa.salg_type[ALG_MAX_SALG_TYPE-1] = '\0'; - strncpy((char *) sa.salg_name, ciphername, ALG_MAX_SALG_NAME); - sa.salg_name[ALG_MAX_SALG_NAME-1] = '\0'; + OPENSSL_strlcpy((char *) sa.salg_type, ciphertype, sizeof(sa.salg_type)); + OPENSSL_strlcpy((char *) sa.salg_name, ciphername, sizeof(sa.salg_name)); actx->bfd = socket(AF_ALG, SOCK_SEQPACKET, 0); if (actx->bfd == -1) { @@ -503,7 +514,7 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, int ciphertype; int ret; afalg_ctx *actx; - char ciphername[ALG_MAX_SALG_NAME]; + const char *ciphername; if (ctx == NULL || key == NULL) { ALG_WARN("%s(%d): Null Parameter\n", __FILE__, __LINE__); @@ -526,14 +537,13 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, case NID_aes_128_cbc: case NID_aes_192_cbc: case NID_aes_256_cbc: - strncpy(ciphername, "cbc(aes)", ALG_MAX_SALG_NAME); + ciphername = "cbc(aes)"; break; default: ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__, ciphertype); return 0; } - ciphername[ALG_MAX_SALG_NAME-1]='\0'; if (ALG_AES_IV_LEN != EVP_CIPHER_CTX_iv_length(ctx)) { ALG_WARN("%s(%d): Unsupported IV length :%d\n", __FILE__, __LINE__, diff --git a/engines/e_afalg.txt b/engines/e_afalg.txt index e32c880b..7de1fe98 100644 --- a/engines/e_afalg.txt +++ b/engines/e_afalg.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-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 diff --git a/engines/e_afalg_err.c b/engines/e_afalg_err.c index cd5b7b2f..4db6d660 100644 --- a/engines/e_afalg_err.c +++ b/engines/e_afalg_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,17 +13,6 @@ #ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA AFALG_str_functs[] = { - {ERR_PACK(0, AFALG_F_AFALG_CHK_PLATFORM, 0), "afalg_chk_platform"}, - {ERR_PACK(0, AFALG_F_AFALG_CREATE_SK, 0), "afalg_create_sk"}, - {ERR_PACK(0, AFALG_F_AFALG_INIT_AIO, 0), "afalg_init_aio"}, - {ERR_PACK(0, AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, 0), - "afalg_setup_async_event_notification"}, - {ERR_PACK(0, AFALG_F_AFALG_SET_KEY, 0), "afalg_set_key"}, - {ERR_PACK(0, AFALG_F_BIND_AFALG, 0), "bind_afalg"}, - {0, NULL} -}; - static ERR_STRING_DATA AFALG_str_reasons[] = { {ERR_PACK(0, 0, AFALG_R_EVENTFD_FAILED), "eventfd failed"}, {ERR_PACK(0, 0, AFALG_R_FAILED_TO_GET_PLATFORM_INFO), @@ -56,7 +45,6 @@ static int ERR_load_AFALG_strings(void) if (!error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, AFALG_str_functs); ERR_load_strings(lib_code, AFALG_str_reasons); #endif error_loaded = 1; @@ -68,7 +56,6 @@ static void ERR_unload_AFALG_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, AFALG_str_functs); ERR_unload_strings(lib_code, AFALG_str_reasons); #endif error_loaded = 0; @@ -79,5 +66,6 @@ static void ERR_AFALG_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_afalg_err.h b/engines/e_afalg_err.h index bd1dd154..27cdcd3e 100644 --- a/engines/e_afalg_err.h +++ b/engines/e_afalg_err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -11,18 +11,24 @@ #ifndef HEADER_AFALGERR_H # define HEADER_AFALGERR_H -# define AFALGerr(f, r) ERR_AFALG_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +# include +# include + + +# define AFALGerr(f, r) ERR_AFALG_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) /* * AFALG function codes. */ -# define AFALG_F_AFALG_CHK_PLATFORM 100 -# define AFALG_F_AFALG_CREATE_SK 101 -# define AFALG_F_AFALG_INIT_AIO 102 -# define AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION 103 -# define AFALG_F_AFALG_SET_KEY 104 -# define AFALG_F_BIND_AFALG 105 +# if !OPENSSL_API_3 +# define AFALG_F_AFALG_CHK_PLATFORM 0 +# define AFALG_F_AFALG_CREATE_SK 0 +# define AFALG_F_AFALG_INIT_AIO 0 +# define AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION 0 +# define AFALG_F_AFALG_SET_KEY 0 +# define AFALG_F_BIND_AFALG 0 +# endif /* * AFALG reason codes. diff --git a/engines/e_capi.txt b/engines/e_capi.txt index 29724e63..303a1ed5 100644 --- a/engines/e_capi.txt +++ b/engines/e_capi.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-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 diff --git a/engines/e_capi_err.c b/engines/e_capi_err.c index 923723ad..e2b1f756 100644 --- a/engines/e_capi_err.c +++ b/engines/e_capi_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,30 +13,6 @@ #ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA CAPI_str_functs[] = { - {ERR_PACK(0, CAPI_F_CAPI_CERT_GET_FNAME, 0), "capi_cert_get_fname"}, - {ERR_PACK(0, CAPI_F_CAPI_CTRL, 0), "capi_ctrl"}, - {ERR_PACK(0, CAPI_F_CAPI_CTX_NEW, 0), "capi_ctx_new"}, - {ERR_PACK(0, CAPI_F_CAPI_CTX_SET_PROVNAME, 0), "capi_ctx_set_provname"}, - {ERR_PACK(0, CAPI_F_CAPI_DSA_DO_SIGN, 0), "capi_dsa_do_sign"}, - {ERR_PACK(0, CAPI_F_CAPI_GET_KEY, 0), "capi_get_key"}, - {ERR_PACK(0, CAPI_F_CAPI_GET_PKEY, 0), "capi_get_pkey"}, - {ERR_PACK(0, CAPI_F_CAPI_GET_PROVNAME, 0), "capi_get_provname"}, - {ERR_PACK(0, CAPI_F_CAPI_GET_PROV_INFO, 0), "capi_get_prov_info"}, - {ERR_PACK(0, CAPI_F_CAPI_INIT, 0), "capi_init"}, - {ERR_PACK(0, CAPI_F_CAPI_LIST_CONTAINERS, 0), "capi_list_containers"}, - {ERR_PACK(0, CAPI_F_CAPI_LOAD_PRIVKEY, 0), "capi_load_privkey"}, - {ERR_PACK(0, CAPI_F_CAPI_OPEN_STORE, 0), "capi_open_store"}, - {ERR_PACK(0, CAPI_F_CAPI_RSA_PRIV_DEC, 0), "capi_rsa_priv_dec"}, - {ERR_PACK(0, CAPI_F_CAPI_RSA_PRIV_ENC, 0), "capi_rsa_priv_enc"}, - {ERR_PACK(0, CAPI_F_CAPI_RSA_SIGN, 0), "capi_rsa_sign"}, - {ERR_PACK(0, CAPI_F_CAPI_VTRACE, 0), "capi_vtrace"}, - {ERR_PACK(0, CAPI_F_CERT_SELECT_DIALOG, 0), "cert_select_dialog"}, - {ERR_PACK(0, CAPI_F_CLIENT_CERT_SELECT, 0), ""}, - {ERR_PACK(0, CAPI_F_WIDE_TO_ASC, 0), "wide_to_asc"}, - {0, NULL} -}; - static ERR_STRING_DATA CAPI_str_reasons[] = { {ERR_PACK(0, 0, CAPI_R_CANT_CREATE_HASH_OBJECT), "cant create hash object"}, {ERR_PACK(0, 0, CAPI_R_CANT_FIND_CAPI_CONTEXT), "cant find capi context"}, @@ -92,7 +68,6 @@ static int ERR_load_CAPI_strings(void) if (!error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, CAPI_str_functs); ERR_load_strings(lib_code, CAPI_str_reasons); #endif error_loaded = 1; @@ -104,7 +79,6 @@ static void ERR_unload_CAPI_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, CAPI_str_functs); ERR_unload_strings(lib_code, CAPI_str_reasons); #endif error_loaded = 0; @@ -115,5 +89,6 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_capi_err.h b/engines/e_capi_err.h index 544f7fe3..a9389ecf 100644 --- a/engines/e_capi_err.h +++ b/engines/e_capi_err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -11,32 +11,38 @@ #ifndef HEADER_CAPIERR_H # define HEADER_CAPIERR_H -# define CAPIerr(f, r) ERR_CAPI_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +# include +# include + + +# define CAPIerr(f, r) ERR_CAPI_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) /* * CAPI function codes. */ -# define CAPI_F_CAPI_CERT_GET_FNAME 99 -# define CAPI_F_CAPI_CTRL 100 -# define CAPI_F_CAPI_CTX_NEW 101 -# define CAPI_F_CAPI_CTX_SET_PROVNAME 102 -# define CAPI_F_CAPI_DSA_DO_SIGN 114 -# define CAPI_F_CAPI_GET_KEY 103 -# define CAPI_F_CAPI_GET_PKEY 115 -# define CAPI_F_CAPI_GET_PROVNAME 104 -# define CAPI_F_CAPI_GET_PROV_INFO 105 -# define CAPI_F_CAPI_INIT 106 -# define CAPI_F_CAPI_LIST_CONTAINERS 107 -# define CAPI_F_CAPI_LOAD_PRIVKEY 108 -# define CAPI_F_CAPI_OPEN_STORE 109 -# define CAPI_F_CAPI_RSA_PRIV_DEC 110 -# define CAPI_F_CAPI_RSA_PRIV_ENC 111 -# define CAPI_F_CAPI_RSA_SIGN 112 -# define CAPI_F_CAPI_VTRACE 118 -# define CAPI_F_CERT_SELECT_DIALOG 117 -# define CAPI_F_CLIENT_CERT_SELECT 116 -# define CAPI_F_WIDE_TO_ASC 113 +# if !OPENSSL_API_3 +# define CAPI_F_CAPI_CERT_GET_FNAME 0 +# define CAPI_F_CAPI_CTRL 0 +# define CAPI_F_CAPI_CTX_NEW 0 +# define CAPI_F_CAPI_CTX_SET_PROVNAME 0 +# define CAPI_F_CAPI_DSA_DO_SIGN 0 +# define CAPI_F_CAPI_GET_KEY 0 +# define CAPI_F_CAPI_GET_PKEY 0 +# define CAPI_F_CAPI_GET_PROVNAME 0 +# define CAPI_F_CAPI_GET_PROV_INFO 0 +# define CAPI_F_CAPI_INIT 0 +# define CAPI_F_CAPI_LIST_CONTAINERS 0 +# define CAPI_F_CAPI_LOAD_PRIVKEY 0 +# define CAPI_F_CAPI_OPEN_STORE 0 +# define CAPI_F_CAPI_RSA_PRIV_DEC 0 +# define CAPI_F_CAPI_RSA_PRIV_ENC 0 +# define CAPI_F_CAPI_RSA_SIGN 0 +# define CAPI_F_CAPI_VTRACE 0 +# define CAPI_F_CERT_SELECT_DIALOG 0 +# define CAPI_F_CLIENT_CERT_SELECT 0 +# define CAPI_F_WIDE_TO_ASC 0 +# endif /* * CAPI reason codes. diff --git a/engines/e_dasync.txt b/engines/e_dasync.txt index 9a7b4989..819ff6fe 100644 --- a/engines/e_dasync.txt +++ b/engines/e_dasync.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-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 diff --git a/engines/e_dasync_err.c b/engines/e_dasync_err.c index f71f6fed..a2e6c0dc 100644 --- a/engines/e_dasync_err.c +++ b/engines/e_dasync_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,22 +13,6 @@ #ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA DASYNC_str_functs[] = { - {ERR_PACK(0, DASYNC_F_BIND_DASYNC, 0), "bind_dasync"}, - {ERR_PACK(0, DASYNC_F_CIPHER_AES_128_CBC_CODE, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_AES128_CBC_HMAC_SHA1_INIT_KEY, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_AES128_INIT_KEY, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_BN_MOD_EXP, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER, 0), - "dasync_cipher_init_key_helper"}, - {ERR_PACK(0, DASYNC_F_DASYNC_MOD_EXP, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_PRIVATE_DECRYPT, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_PRIVATE_ENCRYPT, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_PUBLIC_DECRYPT, 0), ""}, - {ERR_PACK(0, DASYNC_F_DASYNC_PUBLIC_ENCRYPT, 0), ""}, - {0, NULL} -}; - static ERR_STRING_DATA DASYNC_str_reasons[] = { {ERR_PACK(0, 0, DASYNC_R_INIT_FAILED), "init failed"}, {0, NULL} @@ -46,7 +30,6 @@ static int ERR_load_DASYNC_strings(void) if (!error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, DASYNC_str_functs); ERR_load_strings(lib_code, DASYNC_str_reasons); #endif error_loaded = 1; @@ -58,7 +41,6 @@ static void ERR_unload_DASYNC_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, DASYNC_str_functs); ERR_unload_strings(lib_code, DASYNC_str_reasons); #endif error_loaded = 0; @@ -69,5 +51,6 @@ static void ERR_DASYNC_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_dasync_err.h b/engines/e_dasync_err.h index 844615e9..907ba88c 100644 --- a/engines/e_dasync_err.h +++ b/engines/e_dasync_err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -11,23 +11,29 @@ #ifndef HEADER_DASYNCERR_H # define HEADER_DASYNCERR_H -# define DASYNCerr(f, r) ERR_DASYNC_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +# include +# include + + +# define DASYNCerr(f, r) ERR_DASYNC_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) /* * DASYNC function codes. */ -# define DASYNC_F_BIND_DASYNC 107 -# define DASYNC_F_CIPHER_AES_128_CBC_CODE 100 -# define DASYNC_F_DASYNC_AES128_CBC_HMAC_SHA1_INIT_KEY 109 -# define DASYNC_F_DASYNC_AES128_INIT_KEY 108 -# define DASYNC_F_DASYNC_BN_MOD_EXP 101 -# define DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER 110 -# define DASYNC_F_DASYNC_MOD_EXP 102 -# define DASYNC_F_DASYNC_PRIVATE_DECRYPT 103 -# define DASYNC_F_DASYNC_PRIVATE_ENCRYPT 104 -# define DASYNC_F_DASYNC_PUBLIC_DECRYPT 105 -# define DASYNC_F_DASYNC_PUBLIC_ENCRYPT 106 +# if !OPENSSL_API_3 +# define DASYNC_F_BIND_DASYNC 0 +# define DASYNC_F_CIPHER_AES_128_CBC_CODE 0 +# define DASYNC_F_DASYNC_AES128_CBC_HMAC_SHA1_INIT_KEY 0 +# define DASYNC_F_DASYNC_AES128_INIT_KEY 0 +# define DASYNC_F_DASYNC_BN_MOD_EXP 0 +# define DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER 0 +# define DASYNC_F_DASYNC_MOD_EXP 0 +# define DASYNC_F_DASYNC_PRIVATE_DECRYPT 0 +# define DASYNC_F_DASYNC_PRIVATE_ENCRYPT 0 +# define DASYNC_F_DASYNC_PUBLIC_DECRYPT 0 +# define DASYNC_F_DASYNC_PUBLIC_ENCRYPT 0 +# endif /* * DASYNC reason codes. diff --git a/engines/e_devcrypto.c b/engines/e_devcrypto.c index f51b5019..489109a8 100644 --- a/engines/e_devcrypto.c +++ b/engines/e_devcrypto.c @@ -72,7 +72,7 @@ void engine_load_devcrypto_int(void); static int clean_devcrypto_session(struct session_op *sess) { if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } memset(sess, 0, sizeof(struct session_op)); @@ -208,7 +208,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; cipher_ctx->blocksize = cipher_d->blocksize; if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } @@ -260,7 +260,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, #endif if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } @@ -704,7 +704,7 @@ static int digest_init(EVP_MD_CTX *ctx) memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); digest_ctx->sess.mac = digest_d->devcryptoid; if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } return 1; @@ -743,7 +743,7 @@ static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) return 1; } - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } @@ -758,7 +758,7 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx)); } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } @@ -777,14 +777,14 @@ static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) return 1; if (!digest_init(to)) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } cphash.src_ses = digest_from->sess.ses; cphash.dst_ses = digest_to->sess.ses; if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { - SYSerr(SYS_F_IOCTL, errno); + ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); return 0; } return 1; diff --git a/engines/e_ossltest.txt b/engines/e_ossltest.txt index b16c4aa5..f40e60cf 100644 --- a/engines/e_ossltest.txt +++ b/engines/e_ossltest.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-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 diff --git a/engines/e_ossltest_err.c b/engines/e_ossltest_err.c index 57c71e3d..d9ee80cb 100644 --- a/engines/e_ossltest_err.c +++ b/engines/e_ossltest_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -13,12 +13,6 @@ #ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA OSSLTEST_str_functs[] = { - {ERR_PACK(0, OSSLTEST_F_BIND_OSSLTEST, 0), "bind_ossltest"}, - {ERR_PACK(0, OSSLTEST_F_OSSLTEST_AES128_INIT_KEY, 0), ""}, - {0, NULL} -}; - static ERR_STRING_DATA OSSLTEST_str_reasons[] = { {ERR_PACK(0, 0, OSSLTEST_R_INIT_FAILED), "init failed"}, {0, NULL} @@ -36,7 +30,6 @@ static int ERR_load_OSSLTEST_strings(void) if (!error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, OSSLTEST_str_functs); ERR_load_strings(lib_code, OSSLTEST_str_reasons); #endif error_loaded = 1; @@ -48,7 +41,6 @@ static void ERR_unload_OSSLTEST_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, OSSLTEST_str_functs); ERR_unload_strings(lib_code, OSSLTEST_str_reasons); #endif error_loaded = 0; @@ -59,5 +51,6 @@ static void ERR_OSSLTEST_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_ossltest_err.h b/engines/e_ossltest_err.h index 03f7bfb8..b575a80a 100644 --- a/engines/e_ossltest_err.h +++ b/engines/e_ossltest_err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 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 @@ -11,14 +11,20 @@ #ifndef HEADER_OSSLTESTERR_H # define HEADER_OSSLTESTERR_H -# define OSSLTESTerr(f, r) ERR_OSSLTEST_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +# include +# include + + +# define OSSLTESTerr(f, r) ERR_OSSLTEST_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) /* * OSSLTEST function codes. */ -# define OSSLTEST_F_BIND_OSSLTEST 100 -# define OSSLTEST_F_OSSLTEST_AES128_INIT_KEY 101 +# if !OPENSSL_API_3 +# define OSSLTEST_F_BIND_OSSLTEST 0 +# define OSSLTEST_F_OSSLTEST_AES128_INIT_KEY 0 +# endif /* * OSSLTEST reason codes. diff --git a/external/perl/Downloaded.txt b/external/perl/Downloaded.txt index af0c20a3..dfb1f052 100644 --- a/external/perl/Downloaded.txt +++ b/external/perl/Downloaded.txt @@ -3,11 +3,12 @@ Intro If we find a useful Perl module that isn't one of the core Perl modules, we may choose to bundle it with the OpenSSL source. +They remain unmodified and retain their copyright and license. -Here, we simply list those modules and where we downloaded them from. +Here, we simply list those modules and where we got them from. Downloaded and bundled Perl modules ----------------------------------- -Text::Template 1.46 was downloaded from -http://search.cpan.org/CPAN/authors/id/M/MJ/MJD/Text-Template-1.46.tar.gz +Text::Template 1.56 was downloaded from +https://cpan.metacpan.org/authors/id/M/MS/MSCHOUT/Text-Template-1.56.tar.gz diff --git a/external/perl/MODULES.txt b/external/perl/MODULES.txt new file mode 100644 index 00000000..799357f4 --- /dev/null +++ b/external/perl/MODULES.txt @@ -0,0 +1 @@ +Text-Template-1.56/lib diff --git a/external/perl/Text-Template-1.46/Artistic b/external/perl/Text-Template-1.46/Artistic deleted file mode 100644 index 5f221241..00000000 --- a/external/perl/Text-Template-1.46/Artistic +++ /dev/null @@ -1,131 +0,0 @@ - - - - - The "Artistic License" - - Preamble - -The intent of this document is to state the conditions under which a -Package may be copied, such that the Copyright Holder maintains some -semblance of artistic control over the development of the package, -while giving the users of the package the right to use and distribute -the Package in a more-or-less customary fashion, plus the right to make -reasonable modifications. - -Definitions: - - "Package" refers to the collection of files distributed by the - Copyright Holder, and derivatives of that collection of files - created through textual modification. - - "Standard Version" refers to such a Package if it has not been - modified, or has been modified in accordance with the wishes - of the Copyright Holder as specified below. - - "Copyright Holder" is whoever is named in the copyright or - copyrights for the package. - - "You" is you, if you're thinking about copying or distributing - this Package. - - "Reasonable copying fee" is whatever you can justify on the - basis of media cost, duplication charges, time of people involved, - and so on. (You will not be required to justify it to the - Copyright Holder, but only to the computing community at large - as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item - itself, though there may be fees involved in handling the item. - It also means that recipients of the item may redistribute it - under the same conditions they received it. - -1. You may make and give away verbatim copies of the source form of the -Standard Version of this Package without restriction, provided that you -duplicate all of the original copyright notices and associated disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications -derived from the Public Domain or from the Copyright Holder. A Package -modified in such a way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided -that you insert a prominent notice in each changed file stating how and -when you changed that file, and provided that you do at least ONE of the -following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or - an equivalent medium, or placing the modifications on a major archive - site such as uunet.uu.net, or by allowing the Copyright Holder to include - your modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided, and provide - a separate manual page for each non-standard executable that clearly - documents how it differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or -executable form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where - to get the Standard Version. - - b) accompany the distribution with the machine-readable source of - the Package with your modifications. - - c) give non-standard executables non-standard names, and clearly - document the differences in manual pages (or equivalent), together - with instructions on where to get the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -5. You may charge a reasonable copying fee for any distribution of this -Package. You may charge any fee you choose for support of this -Package. You may not charge a fee for this Package itself. However, -you may distribute this Package in aggregate with other (possibly -commercial) programs as part of a larger (possibly commercial) software -distribution provided that you do not advertise this Package as a -product of your own. You may embed this Package's interpreter within -an executable of yours (by linking); this shall be construed as a mere -form of aggregation, provided that the complete Standard Version of the -interpreter is so embedded. - -6. The scripts and library files supplied as input to or produced as -output from the programs of this Package do not automatically fall -under the copyright of this Package, but belong to whoever generated -them, and may be sold commercially, and may be aggregated with this -Package. If such scripts or library files are aggregated with this -Package via the so-called "undump" or "unexec" methods of producing a -binary executable image, then distribution of such an image shall -neither be construed as a distribution of this Package nor shall it -fall under the restrictions of Paragraphs 3 and 4, provided that you do -not represent such an executable image as a Standard Version of this -Package. - -7. C subroutines (or comparably compiled subroutines in other -languages) supplied by you and linked into this Package in order to -emulate subroutines and variables of the language defined by this -Package shall not be considered part of this Package, but are the -equivalent of input as in Paragraph 6, provided these subroutines do -not change the language in any way that would cause it to fail the -regression tests for the language. - -8. Aggregation of this Package with a commercial distribution is always -permitted provided that the use of this Package is embedded; that is, -when no overt attempt is made to make this Package's interfaces visible -to the end user of the commercial distribution. Such use shall not be -construed as a distribution of this Package. - -9. The name of the Copyright Holder may not be used to endorse or promote -products derived from this software without specific prior written permission. - -10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - The End diff --git a/external/perl/Text-Template-1.46/COPYING b/external/perl/Text-Template-1.46/COPYING deleted file mode 100644 index a3f6b12e..00000000 --- a/external/perl/Text-Template-1.46/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/external/perl/Text-Template-1.46/MANIFEST b/external/perl/Text-Template-1.46/MANIFEST deleted file mode 100644 index 22460fe8..00000000 --- a/external/perl/Text-Template-1.46/MANIFEST +++ /dev/null @@ -1,25 +0,0 @@ -MANIFEST -COPYING -Artistic -Makefile.PL -INSTALL -README -lib/Text/Template.pm -lib/Text/Template/Preprocess.pm -t/00-version.t -t/01-basic.t -t/02-hash.t -t/03-out.t -t/04-safe.t -t/05-safe2.t -t/06-ofh.t -t/07-safe3.t -t/08-exported.t -t/09-error.t -t/10-delimiters.t -t/11-prepend.t -t/12-preprocess.t -t/13-taint.t -t/14-broken.t -META.yml Module meta-data (added by MakeMaker) -META.json Module JSON meta-data (added by MakeMaker) diff --git a/external/perl/Text-Template-1.46/META.json b/external/perl/Text-Template-1.46/META.json deleted file mode 100644 index 6b335eb9..00000000 --- a/external/perl/Text-Template-1.46/META.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "abstract" : "unknown", - "author" : [ - "unknown" - ], - "dynamic_config" : 1, - "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120630", - "license" : [ - "unknown" - ], - "meta-spec" : { - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", - "version" : "2" - }, - "name" : "Text-Template", - "no_index" : { - "directory" : [ - "t", - "inc" - ] - }, - "prereqs" : { - "build" : { - "requires" : { - "ExtUtils::MakeMaker" : "0" - } - }, - "configure" : { - "requires" : { - "ExtUtils::MakeMaker" : "0" - } - }, - "runtime" : { - "requires" : {} - } - }, - "release_status" : "stable", - "version" : "1.46" -} diff --git a/external/perl/Text-Template-1.46/META.yml b/external/perl/Text-Template-1.46/META.yml deleted file mode 100644 index a2e27159..00000000 --- a/external/perl/Text-Template-1.46/META.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -abstract: unknown -author: - - unknown -build_requires: - ExtUtils::MakeMaker: 0 -configure_requires: - ExtUtils::MakeMaker: 0 -dynamic_config: 1 -generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120630' -license: unknown -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.4.html - version: 1.4 -name: Text-Template -no_index: - directory: - - t - - inc -requires: {} -version: 1.46 diff --git a/external/perl/Text-Template-1.46/Makefile.PL b/external/perl/Text-Template-1.46/Makefile.PL deleted file mode 100644 index 491e03cb..00000000 --- a/external/perl/Text-Template-1.46/Makefile.PL +++ /dev/null @@ -1,7 +0,0 @@ -use ExtUtils::MakeMaker; -WriteMakefile( - NAME => 'Text::Template', - VERSION_FROM => 'lib/Text/Template.pm', -# 'linkext' => {LINKTYPE => ''}, - 'dist' => {COMPRESS => 'gzip', SUFFIX => 'gz'}, -); diff --git a/external/perl/Text-Template-1.46/README b/external/perl/Text-Template-1.46/README deleted file mode 100644 index e184d8cd..00000000 --- a/external/perl/Text-Template-1.46/README +++ /dev/null @@ -1,339 +0,0 @@ - -Text::Template v1.46 - -This is a library for generating form letters, building HTML pages, or -filling in templates generally. A `template' is a piece of text that -has little Perl programs embedded in it here and there. When you -`fill in' a template, you evaluate the little programs and replace -them with their values. - -Here's an example of a template: - - Dear {$title} {$lastname}, - - It has come to our attention that you are delinquent in your - {$monthname[$last_paid_month]} payment. Please remit - ${sprintf("%.2f", $amount)} immediately, or your patellae may - be needlessly endangered. - - Love, - - Mark "{nickname(rand 20)}" Dominus - - -The result of filling in this template is a string, which might look -something like this: - - Dear Mr. Gates, - - It has come to our attention that you are delinquent in your - February payment. Please remit - $392.12 immediately, or your patellae may - be needlessly endangered. - - - Love, - - Mark "Vizopteryx" Dominus - -You can store a template in a file outside your program. People can -modify the template without modifying the program. You can separate -the formatting details from the main code, and put the formatting -parts of the program into the template. That prevents code bloat and -encourages functional separation. - -You can fill in the template in a `Safe' compartment. This means that -if you don't trust the person who wrote the code in the template, you -won't have to worry that they are tampering with your program when you -execute it. - ----------------------------------------------------------------- - -Text::Template was originally released some time in late 1995 or early -1996. After three years of study and investigation, I rewrote it from -scratch in January 1999. The new version, 1.0, was much faster, -delivered better functionality and was almost 100% backward-compatible -with the previous beta versions. - -I have added a number of useful features and conveniences since the -1.0 release, while still retaining backward compatibility. With one -merely cosmetic change, the current version of Text::Template passes -the test suite that the old beta versions passed. - -Questions or comments should be addressed to -mjd-perl-template+@plover.com. This address goes directly to me, and -not to anyone else; it is not a mailing list address. - -To receive occasional announcements of new versions of T::T, send an -empty note to mjd-perl-template-request@plover.com. This mailing list -is not for discussion; it is for announcements only. Therefore, there -is no address for sending messages to the list. - -You can get the most recent version of Text::Template, news, comments, -and other collateral information from -. - ----------------------------------------------------------------- - -What's new in v1.46 since v1.44: - - Thanks to Rik Signes, there is a new - Text::Template->append_text_to_output method, which - Text::Template always uses whenever it wants to emit output. - You can subclass this to get control over the output, for - example for postprocessing. - - A spurious warning is no longer emitted when the TYPE - parameter to ->new is omitted. - ----------------------------------------------------------------- -What's new in v1.44 since v1.43: - -This is a maintentance release. There are no feature changes. - - _scrubpkg, which was responsible for eptying out temporary - packages after the module had done with them, wasn't always - working; the result was memory-leaks in long-running - applications. This should be fixed now, and there is a test - in the test suite for it. - - Minor changes to the test suite to prevent spurious errors. - - Minor documentation changes. - ----------------------------------------------------------------- -What's new in v1.43 since v1.42: - - The ->new method now fails immediately and sets - $Text::Template::ERROR if the file that is named by a filename - argument does not exist or cannot be opened for some other - reason. Formerly, the constructor would succeed and the - ->fill_in call would fail. - ----------------------------------------------------------------- - -What's new in v1.42 since v1.41: - -This is a maintentance release. There are no feature changes. - - Fixed a bug relating to use of UNTAINT under perl 5.005_03 and - possibly other versions. - - Taint-related tests are now more comprehensive. ----------------------------------------------------------------- - -What's new in v1.41 since v1.40: - -This is a maintentance release. There are no feature changes. - - Tests now work correctly on Windows systems and possibly on - other non-unix systems. - ----------------------------------------------------------------- - -What's new in v1.40 since v1.31: - - New UNTAINT option tells the module that it is safe to 'eval' - code even though it has come from a file or filehandle. - - Code added to prevent memory leaks when filling many - templates. Thanks to Itamar Almeida de Carvalho. - - Bug fix: $OUT was not correctly initialized when used in - conjunction with SAFE. - - You may now use a glob ref when passing a filehandle to the - ->new funcion. Formerly, a glob was reuqired. - - New subclass: Text::Template::Preprocess. Just like - Text::Template, but you may supply a PREPROCESS option in the - constructor or the fill_in call; this is a function which - receives each code fragment prior to evaluation, and which may - modify and return the fragment; the modified fragment is what - is evaluated. - - Error messages passed to BROKEN subroutines will now report - the correct line number of the template at which the error - occurred: - - Illegal division by zero at template line 37. - - If the template comes from a file, the filename will be - reported as well: - - Illegal division by zero at catalog.tmpl line 37. - - - INCOMPATIBLE CHANGE: - - The format of the default error message has changed. It used - to look like: - - Program fragment at line 30 delivered error ``Illegal division by zero'' - - It now looks like: - - Program fragment delivered error ``Illegal division by zero at catalog.tmpl line 37'' - - Note that the default message used to report the line number - at which the program fragment began; it now reports the line - number at which the error actually occurred. - ----------------------------------------------------------------- -What's new in v1.31 since v1.23: - - Just bug fixes---fill_in_string was failing. Thanks to - Donald L. Greer Jr. for the test case. - ----------------------------------------------------------------- -What's new in v1.23 since v1.22: - - Small bug fix: DELIMITER and other arguments were being - ignored in calls to fill_in_file and fill_this_in. (Thanks to - Jonathan Roy for reporting this.) - ----------------------------------------------------------------- -What's new in v1.22 since v1.20: - - You can now specify that certain Perl statements be prepended - to the beginning of every program fragment in a template, - either per template, or for all templates, or for the duration - of only one call to fill_in. This is useful, for example, if - you want to enable `strict' checks in your templates but you - don't want to manually add `use strict' to the front of every - program fragment everywhere. - ----------------------------------------------------------------- -What's new in v1.20 since v1.12: - - You can now specify that the program fragment delimiters are - strings other than { and }. This has three interesting - effects: First, it changes the delimiter strings. Second, it - disables the special meaning of \, so you have to be really, - really sure that the delimiters will not appear in your - templates. And third, because of the simplifications - introduced by the elimination of \ processing, template - parsing is 20-25% faster. - - See the manual section on `Alternative Delimiters'. - - Fixed bug having to do with undefined values in HASH options. - In particular, Text::Template no longer generates a warning if - you try to give a variable an undefined value. - ----------------------------------------------------------------- - -What's new in v1.12 since v1.11: - - I forgot to say that Text::Template ISA Exporter, so the - exported functions never got exported. Duhhh! - - Template TYPEs are now case-insensitive. The `new' method now - diagnoses attempts to use an invalid TYPE. - - More tests for these things. - ----------------------------------------------------------------- - -What's new in v1.11 since v1.10: - - Fixed a bug in the way backslashes were processed. The 1.10 - behavior was incompatible with the beta versions and was also - inconvenient. (`\n' in templates was replaced with `n' before - it was given to Perl for evaluation.) The new behavior is - also incompatible with the beta versions, but it is only a - little bit incompatible, and it is probbaly better. - - Documentation for the new behavior, and tests for the bug. - ----------------------------------------------------------------- - -What's new in v1.10 since v1.03: - - New OUTPUT option delivers template results directly to a - filehandle instead of making them into a string. Saves space - and time. - - PACKAGE and HASH now work intelligently with SAFE. - - Fragments may now output data directly to the template, rather - than having to arrange to return it as a return value at the - end. This means that where you used to have to write this: - - { my $blist = ''; - foreach $i (@items) { - $blist .= qq{ * $i\n}; - } - $blist; - } - - You can now write this instead, because $OUT is special. - - { foreach $i (@items) { - $OUT.= " * $i\n"; - } - } - - (`A spoonful of sugar makes the medicine go down.') - - Fixed some small bugs. Worked around a bug in Perl that does - the wrong thing with $x = when $x contains a glob. - - More documentation. Errors fixed. - - Lots more tests. - ----------------------------------------------------------------- - -What's new in v1.03 since v1.0: - - Code added to support HASH option to fill_in. - (Incl. `_gensym' function.) - - Documentation for HASH. - - New test file for HASH. - - Note about failure of lexical variables to propagate into - templates. Why does this surprise people? - - Bug fix: program fragments are evaluated in an environment with - `no strict' by default. Otherwise, you get a lot of `Global - symbol "$v" requires explicit package name' failures. Why didn't - the test program pick this up? Because the only variable the test - program ever used was `$a', which is exempt. Duhhhhh. - - Fixed the test program. - - Various minor documentation fixes. - - - ----------------------------------------------------------------- - -Improvements of 1.0 over the old 0.1beta: - -New features: - - At least twice as fast - - Better support for filling out the same template more than once - - Now supports evaluation of program fragments in Safe - compartments. (Thanks, Jonathan!) - - Better argument syntax - - More convenience functions - - The parser is much better and simpler. - - Once a template is parsed, the parsed version is stored so that - it needn't be parsed again. - - BROKEN function behavior is rationalized. You can now pass an - arbitrary argument to your BROKEN function, or return a value - from it to the main program. - - Documentation overhauled. - diff --git a/external/perl/Text-Template-1.46/t/00-version.t b/external/perl/Text-Template-1.46/t/00-version.t deleted file mode 100644 index 5f9560f8..00000000 --- a/external/perl/Text-Template-1.46/t/00-version.t +++ /dev/null @@ -1,11 +0,0 @@ -#!perl - -use Text::Template; -print "1..1\n"; - -if ($Text::Template::VERSION == 1.46) { - print "ok 1\n"; -} else { - print "not ok 1\n"; -} - diff --git a/external/perl/Text-Template-1.46/t/01-basic.t b/external/perl/Text-Template-1.46/t/01-basic.t deleted file mode 100644 index be43390c..00000000 --- a/external/perl/Text-Template-1.46/t/01-basic.t +++ /dev/null @@ -1,266 +0,0 @@ -#!perl -# -# Tests of basic, essential functionality -# - -use Text::Template; -$X::v = $Y::v = 0; # Suppress `var used only once' - -print "1..31\n"; - -$n=1; - -$template_1 = < {\$v} -We will evaluate 1+1 here -> {1 + 1} -EOM - -# (1) Construct temporary template file for testing -# file operations -$TEMPFILE = "tt$$"; -open(TMP, "> $TEMPFILE") or print "not ok $n\n" && &abort("Couldn\'t write tempfile $TEMPFILE: $!"); -print TMP $template_1; -close TMP; -print "ok $n\n"; $n++; - -# (2) Build template from file -$template = new Text::Template ('type' => 'FILE', 'source' => $TEMPFILE); -if (defined($template)) { - print "ok $n\n"; -} else { - print "not ok $n $Text::Template::ERROR\n"; -} -$n++; - -# (3) Fill in template from file -$X::v = "abc"; -$resultX = < abc -We will evaluate 1+1 here -> 2 -EOM -$Y::v = "ABC"; -$resultY = < ABC -We will evaluate 1+1 here -> 2 -EOM - -$text = $template->fill_in('package' => X); -if ($text eq $resultX) { - print "ok $n\n"; -} else { - print "not ok $n\n"; -} -$n++; - -# (4) Fill in same template again -$text = $template->fill_in('package' => Y); -if ($text eq $resultY) { - print "ok $n\n"; -} else { - print "not ok $n\n"; -} -$n++; - - - -# (5) Simple test of `fill_this_in' -$text = Text::Template->fill_this_in( $template_1, 'package' => X); -if ($text eq $resultX) { - print "ok $n\n"; -} else { - print "not ok $n\n"; -} -$n++; - -# (6) test creation of template from filehandle -if (open (TMPL, "< $TEMPFILE")) { - $template = new Text::Template ('type' => 'FILEHANDLE', - 'source' => *TMPL); - if (defined($template)) { - print "ok $n\n"; - } else { - print "not ok $n $Text::Template::ERROR\n"; - } - $n++; - -# (7) test filling in of template from filehandle - $text = $template->fill_in('package' => X); - if ($text eq $resultX) { - print "ok $n\n"; - } else { - print "not ok $n\n"; - } - $n++; - -# (8) test second fill_in on same template object - $text = $template->fill_in('package' => Y); - if ($text eq $resultY) { - print "ok $n\n"; - } else { - print "not ok $n\n"; - } - $n++; - close TMPL; -} else { - print "not ok $n\n"; $n++; - print "not ok $n\n"; $n++; - print "not ok $n\n"; $n++; -} - - -# (9) test creation of template from array -$template = new Text::Template - ('type' => 'ARRAY', - 'source' => [ - 'We will put value of $v (which is "abc") here -> {$v}', - "\n", - 'We will evaluate 1+1 here -> {1+1}', - "\n", - ]); -if (defined($template)) { - print "ok $n\n"; -} else { - print "not ok $n $Text::Template::ERROR\n"; -} -$n++; - -# (10) test filling in of template from array -$text = $template->fill_in('package' => X); -if ($text eq $resultX) { - print "ok $n\n"; -} else { - print "not ok $n\n"; -} -$n++; - -# (11) test second fill_in on same array template object -$text = $template->fill_in('package' => Y); -if ($text eq $resultY) { - print "ok $n\n"; -} else { - print "not ok $n\n"; - print STDERR "$resultX\n---\n$text"; - unless (!defined($text)) { print STDERR "ERROR: $Text::Template::ERROR\n"}; -} -$n++; - - - -# (12) Make sure \ is working properly -# Test added for version 1.11 -my $tmpl = Text::Template->new(TYPE => 'STRING', - SOURCE => 'B{"\\}"}C{"\\{"}D', - ); -# This should fail if the \ are not interpreted properly. -my $text = $tmpl->fill_in(); -print +($text eq "B}C{D" ? '' : 'not '), "ok $n\n"; -$n++; - -# (13) Make sure \ is working properly -# Test added for version 1.11 -$tmpl = Text::Template->new(TYPE => 'STRING', - SOURCE => qq{A{"\t"}B}, - ); -# Symptom of old problem: ALL \ were special in templates, so -# The lexer would return (A, PROGTEXT("t"), B), and the -# result text would be AtB instead of A(tab)B. -$text = $tmpl->fill_in(); - -print +($text eq "A\tB" ? '' : 'not '), "ok $n\n"; -$n++; - -# (14-27) Make sure \ is working properly -# Test added for version 1.11 -# This is a sort of general test. -my @tests = ('{""}' => '', # (14) - '{"}"}' => undef, # (15) - '{"\\}"}' => '}', # One backslash - '{"\\\\}"}' => undef, # Two backslashes - '{"\\\\\\}"}' => '}', # Three backslashes - '{"\\\\\\\\}"}' => undef, # Four backslashes - '{"\\\\\\\\\\}"}' => '\}', # Five backslashes (20) - '{"x20"}' => 'x20', - '{"\\x20"}' => ' ', # One backslash - '{"\\\\x20"}' => '\\x20', # Two backslashes - '{"\\\\\\x20"}' => '\\ ', # Three backslashes - '{"\\\\\\\\x20"}' => '\\\\x20', # Four backslashes (25) - '{"\\\\\\\\\\x20"}' => '\\\\ ', # Five backslashes - '{"\\x20\\}"}' => ' }', # (27) - ); - -my $i; -for ($i=0; $i<@tests; $i+=2) { - my $tmpl = Text::Template->new(TYPE => 'STRING', - SOURCE => $tests[$i], - ); - my $text = $tmpl->fill_in; - my $result = $tests[$i+1]; - my $ok = (! defined $text && ! defined $result - || $text eq $result); - unless ($ok) { - print STDERR "($n) expected .$result., got .$text.\n"; - } - print +($ok ? '' : 'not '), "ok $n\n"; - $n++; -} - - -# (28-30) I discovered that you can't pass a glob ref as your filehandle. -# MJD 20010827 -# (28) test creation of template from filehandle -if (open (TMPL, "< $TEMPFILE")) { - $template = new Text::Template ('type' => 'FILEHANDLE', - 'source' => \*TMPL); - if (defined($template)) { - print "ok $n\n"; - } else { - print "not ok $n $Text::Template::ERROR\n"; - } - $n++; - -# (29) test filling in of template from filehandle - $text = $template->fill_in('package' => X); - if ($text eq $resultX) { - print "ok $n\n"; - } else { - print "not ok $n\n"; - } - $n++; - -# (30) test second fill_in on same template object - $text = $template->fill_in('package' => Y); - if ($text eq $resultY) { - print "ok $n\n"; - } else { - print "not ok $n\n"; - } - $n++; - close TMPL; -} else { - print "not ok $n\n"; $n++; - print "not ok $n\n"; $n++; - print "not ok $n\n"; $n++; -} - -# (31) Test _scrubpkg for leakiness -$Text::Template::GEN0::test = 1; -Text::Template::_scrubpkg('Text::Template::GEN0'); -if ($Text::Template::GEN0::test) { - print "not ok $n\n"; -} else { - print "ok $n\n"; -} -$n++; - - -END {unlink $TEMPFILE;} - -exit; - - - - -sub abort { - unlink $TEMPFILE; - die $_[0]; -} diff --git a/external/perl/Text-Template-1.46/t/02-hash.t b/external/perl/Text-Template-1.46/t/02-hash.t deleted file mode 100644 index 29ba51a4..00000000 --- a/external/perl/Text-Template-1.46/t/02-hash.t +++ /dev/null @@ -1,111 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - - -print "1..12\n"; - -$n=1; - -$template = 'We will put value of $v (which is "good") here -> {$v}'; - -$v = 'oops (main)'; -$Q::v = 'oops (Q)'; - -$vars = { 'v' => \'good' }; - -# (1) Build template from string -$template = new Text::Template ('type' => 'STRING', 'source' => $template); -print +($template ? '' : 'not '), "ok $n\n"; -$n++; - -# (2) Fill in template in anonymous package -$result2 = 'We will put value of $v (which is "good") here -> good'; -$text = $template->fill_in(HASH => $vars); -print +($text eq $result2 ? '' : 'not '), "ok $n\n"; -$n++; - -# (3) Did we clobber the main variable? -print +($v eq 'oops (main)' ? '' : 'not '), "ok $n\n"; -$n++; - -# (4) Fill in same template again -$result4 = 'We will put value of $v (which is "good") here -> good'; -$text = $template->fill_in(HASH => $vars); -print +($text eq $result4 ? '' : 'not '), "ok $n\n"; -$n++; - -# (5) Now with a package -$result5 = 'We will put value of $v (which is "good") here -> good'; -$text = $template->fill_in(HASH => $vars, PACKAGE => 'Q'); -print +($text eq $result5 ? '' : 'not '), "ok $n\n"; -$n++; - -# (6) We expect to have clobbered the Q variable. -print +($Q::v eq 'good' ? '' : 'not '), "ok $n\n"; -$n++; - -# (7) Now let's try it without a package -$result7 = 'We will put value of $v (which is "good") here -> good'; -$text = $template->fill_in(HASH => $vars); -print +($text eq $result7 ? '' : 'not '), "ok $n\n"; -$n++; - -# (8-11) Now what does it do when we pass a hash with undefined values? -# Roy says it does something bad. (Added for 1.20.) -my $WARNINGS = 0; -{ - local $SIG{__WARN__} = sub {$WARNINGS++}; - local $^W = 1; # Make sure this is on for this test - $template8 = 'We will put value of $v (which is "good") here -> {defined $v ? "bad" : "good"}'; - $result8 = 'We will put value of $v (which is "good") here -> good'; - my $template = - new Text::Template ('type' => 'STRING', 'source' => $template8); - my $text = $template->fill_in(HASH => {'v' => undef}); - # (8) Did we generate a warning? - print +($WARNINGS == 0 ? '' : 'not '), "ok $n\n"; - $n++; - - # (9) Was the output correct? - print +($text eq $result8 ? '' : 'not '), "ok $n\n"; - $n++; - - # (10-11) Let's try that again, with a twist this time - $WARNINGS = 0; - $text = $template->fill_in(HASH => [{'v' => 17}, {'v' => undef}]); - # (10) Did we generate a warning? - print +($WARNINGS == 0 ? '' : 'not '), "ok $n\n"; - $n++; - - # (11) Was the output correct? - if ($] < 5.005) { - print "ok $n # skipped -- not supported before 5.005\n"; - } else { - print +($text eq $result8 ? '' : 'not '), "ok $n\n"; - } - $n++; -} - - -# (12) Now we'll test the multiple-hash option (Added for 1.20.) -$text = Text::Template::fill_in_string(q{$v: {$v}. @v: [{"@v"}].}, - HASH => [{'v' => 17}, - {'v' => ['a', 'b', 'c']}, - {'v' => \23}, - ]); -$result = q{$v: 23. @v: [a b c].}; -print +($text eq $result ? '' : 'not '), "ok $n\n"; -$n++; - - -exit; - diff --git a/external/perl/Text-Template-1.46/t/03-out.t b/external/perl/Text-Template-1.46/t/03-out.t deleted file mode 100644 index 0ba65a54..00000000 --- a/external/perl/Text-Template-1.46/t/03-out.t +++ /dev/null @@ -1,56 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. -# - -use Text::Template; - -die "This is the test program for Text::Template version 1.46 -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..1\n"; - -$n=1; - -$template = q{ -This line should have a 3: {1+2} - -This line should have several numbers: -{ $t = ''; foreach $n (1 .. 20) { $t .= $n . ' ' } $t } -}; - -$templateOUT = q{ -This line should have a 3: { $OUT = 1+2 } - -This line should have several numbers: -{ foreach $n (1 .. 20) { $OUT .= $n . ' ' } } -}; - -# Build templates from string -$template = new Text::Template ('type' => 'STRING', 'source' => $template) - or die; -$templateOUT = new Text::Template ('type' => 'STRING', 'source' => $templateOUT) - or die; - -# Fill in templates -$text = $template->fill_in() - or die; -$textOUT = $templateOUT->fill_in() - or die; - -# (1) They should be the same -print +($text eq $textOUT ? '' : 'not '), "ok $n\n"; -$n++; - -# Missing: Test this feature in Safe compartments; -# it's a totally different code path. -# Decision: Put that into safe.t, because that file should -# be skipped when Safe.pm is unavailable. - - -exit; - diff --git a/external/perl/Text-Template-1.46/t/04-safe.t b/external/perl/Text-Template-1.46/t/04-safe.t deleted file mode 100644 index 4c07121b..00000000 --- a/external/perl/Text-Template-1.46/t/04-safe.t +++ /dev/null @@ -1,161 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template; - -BEGIN { - eval "use Safe"; - if ($@) { - print "1..0\n"; - exit 0; - } -} - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..16\n"; - -if ($^O eq 'MacOS') { - $BADOP = qq{}; - $FAILURE = q{}; -} else { - $BADOP = qq{kill 0}; - $FAILURE = q{Program fragment at line 1 delivered error ``kill trapped by operation mask''}; -} - -$n=1; -$v = $v = 119; - -$c = new Safe or die; - -$goodtemplate = q{This should succeed: { $v }}; -$goodoutput = q{This should succeed: 119}; - -$template1 = new Text::Template ('type' => 'STRING', 'source' => $goodtemplate) - or die; -$template2 = new Text::Template ('type' => 'STRING', 'source' => $goodtemplate) - or die; - -$text1 = $template1->fill_in(); -$text2 = $template1->fill_in(SAFE => $c); -$ERR2 = $@; -$text3 = $template2->fill_in(SAFE => $c); -$ERR3 = $@; - -# (1)(2)(3) None of these should have failed. -print +(defined $text1 ? '' : 'not '), "ok $n\n"; -$n++; -print +(defined $text2 ? '' : 'not '), "ok $n\n"; -$n++; -print +(defined $text3 ? '' : 'not '), "ok $n\n"; -$n++; - -# (4) Safe and non-safe fills of different template objects with the -# same template text should yield the same result. -# print +($text1 eq $text3 ? '' : 'not '), "ok $n\n"; -# (4) voided this test: it's not true, because the unsafe fill -# uses package main, while the safe fill uses the secret safe package. -# We could alias the secret safe package to be identical to main, -# but that wouldn't be safe. If you want the aliasing, you have to -# request it explicitly with `PACKAGE'. -print "ok $n\n"; -$n++; - -# (5) Safe and non-safe fills of the same template object -# should yield the same result. -# (5) voided this test for the same reason as #4. -# print +($text1 eq $text2 ? '' : 'not '), "ok $n\n"; -print "ok $n\n"; -$n++; - -# (6) Make sure the output was actually correct -print +($text1 eq $goodoutput ? '' : 'not '), "ok $n\n"; -$n++; - - -$badtemplate = qq{This should fail: { $BADOP; 'NOFAIL' }}; -$badnosafeoutput = q{This should fail: NOFAIL}; -$badsafeoutput = q{This should fail: Program fragment delivered error ``kill trapped by operation mask at template line 1.''}; - -$template1 = new Text::Template ('type' => 'STRING', 'source' => $badtemplate) - or die; -$template2 = new Text::Template ('type' => 'STRING', 'source' => $badtemplate) - or die; - -$text1 = $template1->fill_in(); -$text2 = $template1->fill_in(SAFE => $c); -$ERR2 = $@; -$text3 = $template2->fill_in(SAFE => $c); -$ERR3 = $@; -$text4 = $template1->fill_in(); - -# (7)(8)(9)(10) None of these should have failed. -print +(defined $text1 ? '' : 'not '), "ok $n\n"; -$n++; -print +(defined $text2 ? '' : 'not '), "ok $n\n"; -$n++; -print +(defined $text3 ? '' : 'not '), "ok $n\n"; -$n++; -print +(defined $text4 ? '' : 'not '), "ok $n\n"; -$n++; - -# (11) text1 and text4 should be the same (using safe in between -# didn't change anything.) -print +($text1 eq $text4 ? '' : 'not '), "ok $n\n"; -$n++; - -# (12) text2 and text3 should be the same (same template text in different -# objects -print +($text2 eq $text3 ? '' : 'not '), "ok $n\n"; -$n++; - -# (13) text1 should yield badnosafeoutput -print +($text1 eq $badnosafeoutput ? '' : 'not '), "ok $n\n"; -$n++; - -# (14) text2 should yield badsafeoutput -$text2 =~ s/'kill'/kill/; # 5.8.1 added quote marks around the op name -print "# expected: <$badsafeoutput>\n# got : <$text2>\n"; -print +($text2 eq $badsafeoutput ? '' : 'not '), "ok $n\n"; -$n++; - - -$template = q{{$x=1}{$x+1}}; - -$template1 = new Text::Template ('type' => 'STRING', 'source' => $template) - or die; -$template2 = new Text::Template ('type' => 'STRING', 'source' => $template) - or die; - -$text1 = $template1->fill_in(); -$text2 = $template1->fill_in(SAFE => new Safe); - -# (15) Do effects persist in safe compartments? -print +($text1 eq $text2 ? '' : 'not '), "ok $n\n"; -$n++; - -# (16) Try the BROKEN routine in safe compartments -sub my_broken { - my %a = @_; $a{error} =~ s/ at.*//s; - "OK! text:$a{text} error:$a{error} lineno:$a{lineno} arg:$a{arg}" ; -} -$templateB = new Text::Template (TYPE => 'STRING', SOURCE => '{die}') - or die; -$text1 = $templateB->fill_in(BROKEN => \&my_broken, - BROKEN_ARG => 'barg', - SAFE => new Safe, - ); -$result1 = qq{OK! text:die error:Died lineno:1 arg:barg}; -print +($text1 eq $result1 ? '' : 'not '), "ok $n\n"; -$n++; - - - -exit; - diff --git a/external/perl/Text-Template-1.46/t/05-safe2.t b/external/perl/Text-Template-1.46/t/05-safe2.t deleted file mode 100644 index 03534770..00000000 --- a/external/perl/Text-Template-1.46/t/05-safe2.t +++ /dev/null @@ -1,105 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template; - -BEGIN { - eval "use Safe"; - if ($@) { - print "1..0\n"; - exit 0; - } -} - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..12\n"; -$n = 1; - -$c = new Safe or die; - -# Test handling of packages and importing. -$c->reval('$P = "safe root"'); -$P = $P = 'main'; -$Q::P = $Q::P = 'Q'; - -# How to effectively test the gensymming? - -$t = new Text::Template TYPE => 'STRING', SOURCE => 'package is {$P}' - or die; - -# (1) Default behavior: Inherit from calling package, `main' in this case. -$text = $t->fill_in(); -print +($text eq 'package is main' ? '' : 'not '), "ok $n\n"; -$n++; - -# (2) When a package is specified, we should use that package instead. -$text = $t->fill_in(PACKAGE => 'Q'); -print +($text eq 'package is Q' ? '' : 'not '), "ok $n\n"; -$n++; - -# (3) When no package is specified in safe mode, we should use the -# default safe root. -$text = $t->fill_in(SAFE => $c); -print +($text eq 'package is safe root' ? '' : 'not '), "ok $n\n"; -$n++; - -# (4) When a package is specified in safe mode, we should use the -# default safe root, after aliasing to the specified package -$text = $t->fill_in(SAFE => $c, PACKAGE => Q); -print +($text eq 'package is Q' ? '' : 'not '), "ok $n\n"; -$n++; - -# Now let's see if hash vars are installed properly into safe templates -$t = new Text::Template TYPE => 'STRING', SOURCE => 'hash is {$H}' - or die; - -# (5) First in default mode -$text = $t->fill_in(HASH => {H => 'good5'} ); -print +($text eq 'hash is good5' ? '' : 'not '), "ok $n\n"; -$n++; - -# (6) Now in packages -$text = $t->fill_in(HASH => {H => 'good6'}, PACKAGE => 'Q' ); -print +($text eq 'hash is good6' ? '' : 'not '), "ok $n\n"; -$n++; - -# (7) Now in the default root of the safe compartment -$text = $t->fill_in(HASH => {H => 'good7'}, SAFE => $c ); -print +($text eq 'hash is good7' ? '' : 'not '), "ok $n\n"; -$n++; - -# (8) Now in the default root after aliasing to a package that -# got the hash stuffed in -$text = $t->fill_in(HASH => {H => 'good8'}, SAFE => $c, PACKAGE => 'Q2' ); -print +($text eq 'hash is good8' ? '' : 'not '), "ok $n\n"; -$n++; - -# Now let's make sure that none of the packages leaked on each other. -# (9) This var should NOT have been installed into the main package -print +(defined $H ? 'not ' : ''), "ok $n\n"; -$H=$H; -$n++; - -# (10) good6 was overwritten in test 7, so there's nothing to test for here. -print "ok $n\n"; -$n++; - -# (11) this value overwrote the one from test 6. -print +($Q::H eq 'good7' ? '' : 'not '), "ok $n\n"; -$Q::H = $Q::H; -$n++; - -# (12) -print +($Q2::H eq 'good8' ? '' : 'not '), "ok $n\n"; -$Q2::H = $Q2::H; -$n++; - - - diff --git a/external/perl/Text-Template-1.46/t/06-ofh.t b/external/perl/Text-Template-1.46/t/06-ofh.t deleted file mode 100644 index 6865ad19..00000000 --- a/external/perl/Text-Template-1.46/t/06-ofh.t +++ /dev/null @@ -1,39 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..2\n"; - -$n=1; - -$template = new Text::Template TYPE => STRING, SOURCE => q{My process ID is {$$}}; -$of = "t$$"; -END { unlink $of } -open O, "> $of" or die; - -$text = $template->fill_in(OUTPUT => \*O); - -# (1) No $text should have been constructed. Return value should be true. -print +($text eq '1' ? '' : 'not '), "ok $n\n"; -$n++; - -close O or die; -open I, "< $of" or die; -{ local $/; $t = } -close I; - -# (2) The text should have been printed to the file -print +($t eq "My process ID is $$" ? '' : 'not '), "ok $n\n"; -$n++; - -exit; - diff --git a/external/perl/Text-Template-1.46/t/07-safe3.t b/external/perl/Text-Template-1.46/t/07-safe3.t deleted file mode 100644 index 5f438f61..00000000 --- a/external/perl/Text-Template-1.46/t/07-safe3.t +++ /dev/null @@ -1,91 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module - -use Text::Template; - -BEGIN { - eval "use Safe"; - if ($@) { - print "1..0\n"; - exit 0; - } -} - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..3\n"; - -$n=1; - -# Test the OUT feature with safe compartments - -$template = q{ -This line should have a 3: {1+2} - -This line should have several numbers: -{ $t = ''; foreach $n (1 .. 20) { $t .= $n . ' ' } $t } -}; - -$templateOUT = q{ -This line should have a 3: { $OUT = 1+2 } - -This line should have several numbers: -{ foreach $n (1 .. 20) { $OUT .= $n . ' ' } } -}; - -$c = new Safe; - -# Build templates from string -$template = new Text::Template ('type' => 'STRING', 'source' => $template, - SAFE => $c) - or die; -$templateOUT = new Text::Template ('type' => 'STRING', 'source' => $templateOUT, - SAFE => $c) - or die; - -# Fill in templates -$text = $template->fill_in() - or die; -$textOUT = $templateOUT->fill_in() - or die; - -# (1) They should be the same -print +($text eq $textOUT ? '' : 'not '), "ok $n\n"; -$n++; - -# (2-3) "Joel Appelbaum" <000701c0ac2c$aed1d6e0$0201a8c0@prime> -# "Contrary to the documentation the $OUT variable is not always -# undefined at the start of each program fragment. The $OUT variable -# is never undefined after it is used once if you are using the SAFE -# option. The result is that every fragment after the fragment that -# $OUT was used in is replaced by the old $OUT value instead of the -# result of the fragment. This holds true even after the -# Text::Template object goes out of scope and a new one is created!" -# -# Also reported by Daini Xie. - -{ - my $template = q{{$OUT = 'x'}y{$OUT .= 'z'}}; - my $expected = "xyz"; - my $s = Safe->new; - my $o = Text::Template->new(type => 'string', - source => $template, - ); - for (1..2) { - my $r = $o->fill_in(SAFE => $s); - if ($r ne $expected) { - print "not ok $n # <$r>\n"; - } else { - print "ok $n\n"; - } - $n++; - } -} - -exit; - diff --git a/external/perl/Text-Template-1.46/t/08-exported.t b/external/perl/Text-Template-1.46/t/08-exported.t deleted file mode 100644 index ef9cfafd..00000000 --- a/external/perl/Text-Template-1.46/t/08-exported.t +++ /dev/null @@ -1,75 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template 'fill_in_file', 'fill_in_string'; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..6\n"; - -$n=1; -$Q::n = $Q::n = 119; - -# (1) Test fill_in_string -$out = fill_in_string('The value of $n is {$n}.', PACKAGE => 'Q' ); -print +($out eq 'The value of $n is 119.' ? '' : 'not '), "ok $n\n"; -$n++; - -# (2) Test fill_in_file -$TEMPFILE = "tt$$"; -open F, "> $TEMPFILE" or die "Couldn't open test file: $!; aborting"; -print F 'The value of $n is {$n}.', "\n"; -close F or die "Couldn't write test file: $!; aborting"; -$R::n = $R::n = 8128; - -$out = fill_in_file($TEMPFILE, PACKAGE => 'R'); -print +($out eq "The value of \$n is 8128.\n" ? '' : 'not '), "ok $n\n"; -$n++; - -# (3) Jonathan Roy reported this bug: -open F, "> $TEMPFILE" or die "Couldn't open test file: $!; aborting"; -print F "With a message here? [% \$var %]\n"; -close F or die "Couldn't close test file: $!; aborting"; -$out = fill_in_file($TEMPFILE, DELIMITERS => ['[%', '%]'], - HASH => { "var" => \"It is good!" }); -print +($out eq "With a message here? It is good!\n" ? '' : 'not '), "ok $n\n"; -$n++; - -# (4) It probably occurs in fill_this_in also: -$out = - Text::Template->fill_this_in("With a message here? [% \$var %]\n", - DELIMITERS => ['[%', '%]'], - HASH => { "var" => \"It is good!" }); -print +($out eq "With a message here? It is good!\n" ? '' : 'not '), "ok $n\n"; -$n++; - -# (5) This test failed in 1.25. It was supplied by Donald L. Greer Jr. -# Note that it's different from (1) in that there's no explicit -# package=> argument. -use vars qw($string $foo $r); -$string='Hello {$foo}'; -$foo="Don"; -$r = fill_in_string($string); -print (($r eq 'Hello Don' ? '' : 'not '), 'ok ', $n++, "\n"); - -# (6) This test failed in 1.25. It's a variation on (5) -package Q2; -use Text::Template 'fill_in_string'; -use vars qw($string $foo $r); -$string='Hello {$foo}'; -$foo="Don"; -$r = fill_in_string($string); -print (($r eq 'Hello Don' ? '' : 'not '), 'ok ', $main::n++, "\n"); - -package main; - -END { $TEMPFILE && unlink $TEMPFILE } - -exit; - diff --git a/external/perl/Text-Template-1.46/t/09-error.t b/external/perl/Text-Template-1.46/t/09-error.t deleted file mode 100644 index 40f9fac6..00000000 --- a/external/perl/Text-Template-1.46/t/09-error.t +++ /dev/null @@ -1,63 +0,0 @@ -#!perl -# -# test apparatus for Text::Template module -# still incomplete. - -use Text::Template; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..5\n"; -$n = 1; - -# (1-2) Missing source -eval { - Text::Template->new(); -}; -unless ($@ =~ /^\QUsage: Text::Template::new(TYPE => ..., SOURCE => ...)/) { - print STDERR $@; - print "not "; -} -print "ok $n\n"; -$n++; - -eval { - Text::Template->new(TYPE => 'FILE'); -}; -if ($@ =~ /^\QUsage: Text::Template::new(TYPE => ..., SOURCE => ...)/) { - print "ok $n\n"; -} else { - print STDERR $@; - print "not ok $n\n"; -} -$n++; - -# (3) Invalid type -eval { - Text::Template->new(TYPE => 'wlunch', SOURCE => 'fish food'); -}; -if ($@ =~ /^\QIllegal value `WLUNCH' for TYPE parameter/) { - print "ok $n\n"; -} else { - print STDERR $@; - print "not ok $n\n"; -} -$n++; - -# (4-5) File does not exist -my $o = Text::Template->new(TYPE => 'file', - SOURCE => 'this file does not exist'); -print $o ? "not ok $n\n" : "ok $n\n"; -$n++; -print defined($Text::Template::ERROR) - && $Text::Template::ERROR =~ /^Couldn't open file/ - ? "ok $n\n" : "not ok $n\n"; -$n++; - - -exit; - diff --git a/external/perl/Text-Template-1.46/t/10-delimiters.t b/external/perl/Text-Template-1.46/t/10-delimiters.t deleted file mode 100644 index f74d591c..00000000 --- a/external/perl/Text-Template-1.46/t/10-delimiters.t +++ /dev/null @@ -1,99 +0,0 @@ -#!perl -# -# Tests for user-specified delimiter functions -# These tests first appeared in version 1.20. - -use Text::Template; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..18\n"; -$n = 1; - -# (1) Try a simple delimiter: <<..>> -# First with the delimiters specified at object creation time -$V = $V = 119; -$template = q{The value of $V is <<$V>>.}; -$result = q{The value of $V is 119.}; -$template1 = Text::Template->new(TYPE => STRING, - SOURCE => $template, - DELIMITERS => ['<<', '>>'] - ) - or die "Couldn't construct template object: $Text::Template::ERROR; aborting"; -$text = $template1->fill_in(); -print +($text eq $result ? '' : 'not '), "ok $n\n"; -$n++; - -# (2) Now with delimiter choice deferred until fill-in time. -$template1 = Text::Template->new(TYPE => STRING, SOURCE => $template); -$text = $template1->fill_in(DELIMITERS => ['<<', '>>']); -print +($text eq $result ? '' : 'not '), "ok $n\n"; -$n++; - -# (3) Now we'll try using regex metacharacters -# First with the delimiters specified at object creation time -$template = q{The value of $V is [$V].}; -$template1 = Text::Template->new(TYPE => STRING, - SOURCE => $template, - DELIMITERS => ['[', ']'] - ) - or die "Couldn't construct template object: $Text::Template::ERROR; aborting"; -$text = $template1->fill_in(); -print +($text eq $result ? '' : 'not '), "ok $n\n"; -$n++; - -# (4) Now with delimiter choice deferred until fill-in time. -$template1 = Text::Template->new(TYPE => STRING, SOURCE => $template); -$text = $template1->fill_in(DELIMITERS => ['[', ']']); -print +($text eq $result ? '' : 'not '), "ok $n\n"; -$n++; - - - -# (5-18) Make sure \ is working properly -# (That is to say, it is ignored.) -# These tests are similar to those in 01-basic.t. -my @tests = ('{""}' => '', # (5) - - # Backslashes don't matter - '{"}"}' => undef, - '{"\\}"}' => undef, # One backslash - '{"\\\\}"}' => undef, # Two backslashes - '{"\\\\\\}"}' => undef, # Three backslashes - '{"\\\\\\\\}"}' => undef, # Four backslashes (10) - '{"\\\\\\\\\\}"}' => undef, # Five backslashes - - # Backslashes are always passed directly to Perl - '{"x20"}' => 'x20', - '{"\\x20"}' => ' ', # One backslash - '{"\\\\x20"}' => '\\x20', # Two backslashes - '{"\\\\\\x20"}' => '\\ ', # Three backslashes (15) - '{"\\\\\\\\x20"}' => '\\\\x20', # Four backslashes - '{"\\\\\\\\\\x20"}' => '\\\\ ', # Five backslashes - '{"\\x20\\}"}' => undef, # (18) - ); - -my $i; -for ($i=0; $i<@tests; $i+=2) { - my $tmpl = Text::Template->new(TYPE => 'STRING', - SOURCE => $tests[$i], - DELIMITERS => ['{', '}'], - ); - my $text = $tmpl->fill_in; - my $result = $tests[$i+1]; - my $ok = (! defined $text && ! defined $result - || $text eq $result); - unless ($ok) { - print STDERR "($n) expected .$result., got .$text.\n"; - } - print +($ok ? '' : 'not '), "ok $n\n"; - $n++; -} - - -exit; - diff --git a/external/perl/Text-Template-1.46/t/11-prepend.t b/external/perl/Text-Template-1.46/t/11-prepend.t deleted file mode 100644 index fe242e58..00000000 --- a/external/perl/Text-Template-1.46/t/11-prepend.t +++ /dev/null @@ -1,94 +0,0 @@ -#!perl -# -# Tests for PREPEND features -# These tests first appeared in version 1.22. - -use Text::Template; - -die "This is the test program for Text::Template version 1.46 -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -print "1..9\n"; -my $n = 1; - -@Emptyclass1::ISA = 'Text::Template'; -@Emptyclass2::ISA = 'Text::Template'; - -my $tin = q{The value of $foo is: {$foo}}; - -Text::Template->always_prepend(q{$foo = "global"}); - -$tmpl1 = Text::Template->new(TYPE => 'STRING', - SOURCE => $tin, - ); - -$tmpl2 = Text::Template->new(TYPE => 'STRING', - SOURCE => $tin, - PREPEND => q{$foo = "template"}, - ); - -$tmpl1->compile; -$tmpl2->compile; - -$t1 = $tmpl1->fill_in(PACKAGE => 'T1'); -$t2 = $tmpl2->fill_in(PACKAGE => 'T2'); -$t3 = $tmpl2->fill_in(PREPEND => q{$foo = "fillin"}, PACKAGE => 'T3'); - -($t1 eq 'The value of $foo is: global') or print "not "; -print "ok $n\n"; $n++; -($t2 eq 'The value of $foo is: template') or print "not "; -print "ok $n\n"; $n++; -($t3 eq 'The value of $foo is: fillin') or print "not "; -print "ok $n\n"; $n++; - -Emptyclass1->always_prepend(q{$foo = 'Emptyclass global';}); -$tmpl1 = Emptyclass1->new(TYPE => 'STRING', - SOURCE => $tin, - ); - -$tmpl2 = Emptyclass1->new(TYPE => 'STRING', - SOURCE => $tin, - PREPEND => q{$foo = "template"}, - ); - -$tmpl1->compile; -$tmpl2->compile; - -$t1 = $tmpl1->fill_in(PACKAGE => 'T4'); -$t2 = $tmpl2->fill_in(PACKAGE => 'T5'); -$t3 = $tmpl2->fill_in(PREPEND => q{$foo = "fillin"}, PACKAGE => 'T6'); - -($t1 eq 'The value of $foo is: Emptyclass global') or print "not "; -print "ok $n\n"; $n++; -($t2 eq 'The value of $foo is: template') or print "not "; -print "ok $n\n"; $n++; -($t3 eq 'The value of $foo is: fillin') or print "not "; -print "ok $n\n"; $n++; - -$tmpl1 = Emptyclass2->new(TYPE => 'STRING', - SOURCE => $tin, - ); - -$tmpl2 = Emptyclass2->new(TYPE => 'STRING', - SOURCE => $tin, - PREPEND => q{$foo = "template"}, - ); - -$tmpl1->compile; -$tmpl2->compile; - -$t1 = $tmpl1->fill_in(PACKAGE => 'T4'); -$t2 = $tmpl2->fill_in(PACKAGE => 'T5'); -$t3 = $tmpl2->fill_in(PREPEND => q{$foo = "fillin"}, PACKAGE => 'T6'); - -($t1 eq 'The value of $foo is: global') or print "not "; -print "ok $n\n"; $n++; -($t2 eq 'The value of $foo is: template') or print "not "; -print "ok $n\n"; $n++; -($t3 eq 'The value of $foo is: fillin') or print "not "; -print "ok $n\n"; $n++; - - diff --git a/external/perl/Text-Template-1.46/t/12-preprocess.t b/external/perl/Text-Template-1.46/t/12-preprocess.t deleted file mode 100644 index 60b6b0c6..00000000 --- a/external/perl/Text-Template-1.46/t/12-preprocess.t +++ /dev/null @@ -1,52 +0,0 @@ -#!perl -# -# Tests for PREPROCESSOR features -# These tests first appeared in version 1.25. - -use Text::Template::Preprocess; - -die "This is the test program for Text::Template::Preprocess version 1.46. -You are using version $Text::Template::Preprocess::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::Preprocess::VERSION == 1.46; - -$TMPFILE = "tt$$"; - -print "1..8\n"; -my $n = 1; - -my $py = sub { tr/x/y/ }; -my $pz = sub { tr/x/z/ }; - -my $t = 'xxx The value of $x is {$x}'; -my $outx = 'xxx The value of $x is 119'; -my $outy = 'yyy The value of $y is 23'; -my $outz = 'zzz The value of $z is 5'; -open TF, "> $TMPFILE" or die "Couldn't open test file: $!; aborting"; -print TF $t; -close TF; - -@result = ($outx, $outy, $outz, $outz); -for my $trial (1, 0) { - for my $test (0 .. 3) { - my $tmpl; - if ($trial == 0) { - $tmpl = new Text::Template::Preprocess - (TYPE => 'STRING', SOURCE => $t) or die; - } else { - open TF, "< $TMPFILE" or die "Couldn't open test file: $!; aborting"; - $tmpl = new Text::Template::Preprocess - (TYPE => 'FILEHANDLE', SOURCE => \*TF) or die; - } - $tmpl->preprocessor($py) if ($test & 1) == 1; - my @args = ((($test & 2) == 2) ? (PREPROCESSOR => $pz) : ()); - my $o = $tmpl->fill_in(@args, - HASH => {x => 119, 'y' => 23, z => 5}); -# print STDERR "$o/$result[$test]\n"; - print +(($o eq $result[$test]) ? '' : 'not '), "ok $n\n"; - $n++; - } -} - -unlink $TMPFILE; diff --git a/external/perl/Text-Template-1.46/t/13-taint.t b/external/perl/Text-Template-1.46/t/13-taint.t deleted file mode 100644 index d92a3746..00000000 --- a/external/perl/Text-Template-1.46/t/13-taint.t +++ /dev/null @@ -1,119 +0,0 @@ -#!perl -T -# Tests for taint-mode features - -use lib 'blib/lib'; -use Text::Template; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -my $r = int(rand(10000)); -my $file = "tt$r"; - -# makes its arguments tainted -sub taint { - for (@_) { - $_ .= substr($0,0,0); # LOD - } -} - - -print "1..21\n"; - -my $n =1; -print "ok ", $n++, "\n"; - -my $template = 'The value of $n is {$n}.'; - -open T, "> $file" or die "Couldn't write temporary file $file: $!"; -print T $template, "\n"; -close T or die "Couldn't finish temporary file $file: $!"; - -sub should_fail { - my $obj = Text::Template->new(@_); - eval {$obj->fill_in()}; - if ($@) { - print "ok $n # $@\n"; - } else { - print "not ok $n # (didn't fail)\n"; - } - $n++; -} - -sub should_work { - my $obj = Text::Template->new(@_); - eval {$obj->fill_in()}; - if ($@) { - print "not ok $n # $@\n"; - } else { - print "ok $n\n"; - } - $n++; -} - -sub should_be_tainted { - if (Text::Template::_is_clean($_[0])) { - print "not ok $n\n"; $n++; return; - } - print "ok $n\n"; $n++; return; -} - -sub should_be_clean { - unless (Text::Template::_is_clean($_[0])) { - print "not ok $n\n"; $n++; return; - } - print "ok $n\n"; $n++; return; -} - -# Tainted filename should die with and without UNTAINT option -# untainted filename should die without UNTAINT option -# filehandle should die without UNTAINT option -# string and array with tainted data should die either way - -# (2)-(7) -my $tfile = $file; -taint($tfile); -should_be_tainted($tfile); -should_be_clean($file); -should_fail TYPE => 'file', SOURCE => $tfile; -should_fail TYPE => 'file', SOURCE => $tfile, UNTAINT => 1; -should_fail TYPE => 'file', SOURCE => $file; -should_work TYPE => 'file', SOURCE => $file, UNTAINT => 1; - -# (8-9) -open H, "< $file" or die "Couldn't open $file for reading: $!; aborting"; -should_fail TYPE => 'filehandle', SOURCE => \*H; -close H; -open H, "< $file" or die "Couldn't open $file for reading: $!; aborting"; -should_work TYPE => 'filehandle', SOURCE => \*H, UNTAINT => 1; -close H; - -# (10-15) -my $ttemplate = $template; -taint($ttemplate); -should_be_tainted($ttemplate); -should_be_clean($template); -should_fail TYPE => 'string', SOURCE => $ttemplate; -should_fail TYPE => 'string', SOURCE => $ttemplate, UNTAINT => 1; -should_work TYPE => 'string', SOURCE => $template; -should_work TYPE => 'string', SOURCE => $template, UNTAINT => 1; - -# (16-19) -my $array = [ $template ]; -my $tarray = [ $ttemplate ]; -should_fail TYPE => 'array', SOURCE => $tarray; -should_fail TYPE => 'array', SOURCE => $tarray, UNTAINT => 1; -should_work TYPE => 'array', SOURCE => $array; -should_work TYPE => 'array', SOURCE => $array, UNTAINT => 1; - -# (20-21) Test _unconditionally_untaint utility function -Text::Template::_unconditionally_untaint($ttemplate); -should_be_clean($ttemplate); -Text::Template::_unconditionally_untaint($tfile); -should_be_clean($tfile); - -END { unlink $file } - diff --git a/external/perl/Text-Template-1.46/t/14-broken.t b/external/perl/Text-Template-1.46/t/14-broken.t deleted file mode 100644 index d362395c..00000000 --- a/external/perl/Text-Template-1.46/t/14-broken.t +++ /dev/null @@ -1,82 +0,0 @@ -#!perl -# test apparatus for Text::Template module - -use Text::Template; - -print "1..5\n"; - -$n=1; - -die "This is the test program for Text::Template version 1.46. -You are using version $Text::Template::VERSION instead. -That does not make sense.\n -Aborting" - unless $Text::Template::VERSION == 1.46; - -# (1) basic error delivery -{ my $r = Text::Template->new(TYPE => 'string', - SOURCE => '{1/0}', - )->fill_in(); - if ($r eq q{Program fragment delivered error ``Illegal division by zero at template line 1.''}) { - print "ok $n\n"; - } else { - print "not ok $n\n# $r\n"; - } - $n++; -} - -# (2) BROKEN sub called in ->new? -{ my $r = Text::Template->new(TYPE => 'string', - SOURCE => '{1/0}', - BROKEN => sub {'---'}, - )->fill_in(); - if ($r eq q{---}) { - print "ok $n\n"; - } else { - print "not ok $n\n# $r\n"; - } - $n++; -} - -# (3) BROKEN sub called in ->fill_in? -{ my $r = Text::Template->new(TYPE => 'string', - SOURCE => '{1/0}', - )->fill_in(BROKEN => sub {'---'}); - if ($r eq q{---}) { - print "ok $n\n"; - } else { - print "not ok $n\n# $r\n"; - } - $n++; -} - -# (4) BROKEN sub passed correct args when called in ->new? -{ my $r = Text::Template->new(TYPE => 'string', - SOURCE => '{1/0}', - BROKEN => sub { my %a = @_; - qq{$a{lineno},$a{error},$a{text}} - }, - )->fill_in(); - if ($r eq qq{1,Illegal division by zero at template line 1.\n,1/0}) { - print "ok $n\n"; - } else { - print "not ok $n\n# $r\n"; - } - $n++; -} - -# (5) BROKEN sub passed correct args when called in ->fill_in? -{ my $r = Text::Template->new(TYPE => 'string', - SOURCE => '{1/0}', - )->fill_in(BROKEN => - sub { my %a = @_; - qq{$a{lineno},$a{error},$a{text}} - }); - if ($r eq qq{1,Illegal division by zero at template line 1.\n,1/0}) { - print "ok $n\n"; - } else { - print "not ok $n\n# $r\n"; - } - $n++; -} - diff --git a/external/perl/Text-Template-1.56/Changes b/external/perl/Text-Template-1.56/Changes new file mode 100644 index 00000000..3c50179a --- /dev/null +++ b/external/perl/Text-Template-1.56/Changes @@ -0,0 +1,301 @@ +Revision history for Text::Template + +1.56 2019-07-09 + - Fix typos in Changes + +1.55 2019-02-25 + - Improve AppVeyor tests for older Perls (Thanks Roy Ivy) + - Check for Test::More 0.94 and skip tests if not installed where + done_testing() is used (Thanks Roy Ivy). + - Improve workaround for broken Win32 File::Temp taint failure (Thanks Roy Ivy). + - Skip/todo tests which fail under Devel::Cover (Thanks Roy Ivy) + - Add checks and skip_all checks for non-core test modules (Thanks Roy Ivy) + +1.54 2019-01-13 + - Fix tempfile creation during tests on Win32 + +1.53 2018-05-02 + - Add support for decoding template files via ENCODING constructor arg + [github #11] + - Docs cleanup: replace indirect-object style examples and use class method + style constructor calls in the POD docs + - Docs cleanup: remove hard tabs from POD, replace dated, unfair synopsis + [github #5], convert "THANKS" section to a POD list + +1.52 2018-03-19 + - Fix possible 'Subroutine ... redefined' warning (Github #10) + +1.51 2018-03-04 + - Add test for nested tags breakage that happened in v1.46 + - Turn off strict+warnings in sections where template code is eval'ed + [github #9] + +1.50 2018-02-10 + *** Revert support for identical start/end delimiters (e.g.: @@foo@@, XXfooXX) + due to breakage with nested tags (see + https://github.com/mschout/perl-text-template/issues/8). Will revisit + this in a future release. + +1.49 2018-02-07 + - Fix failing tests in v1.48 under perl < 5.8.9 + +1.48 2018-02-07 + - remove COPYING and Artistic files from the dist. These are replaced by + the Dist::Zilla generated LICENSE file. + - use strict/warnings (thanks Mohammad S Anwar) + - remove $VERSION checks from tests. This makes it easier to run the test + with Dist::Zilla and avoids maintenance issue of updating the tests for + each release (Thanks Andrew Ruder). + - Allow precompiled templates to work with preprocessing [#29928] (Thanks + Nik LaBelle) + - Add "strict" option to fill_in(). This adds "use strict" and "use vars + (...)" to the prepend section, and only the keys of the HASH option are + allowed in the template. (Thanks Desmond Daignault, Kivanc Yazan, CJM) + [55696] + - Fix templates with inline comments without newline after comment for perl + < 5.18 [34292] + - Don't use bareword file handles + - use three arg form of open() + - Fix BROKEN behaviour so that it returns the text accumulated so far on + undef as documented [28974] + - Source code cleanups + - Minimum perl version is now 5.8.0 + - Allow start/end delimiters to be identical (e.g.: @@foo@@, XXfooXX) + (Thanks mirod) [46639] + - Fix + document the FILENAME parameter to fill_in() (Thanks VDB) [106093] + - Test suite cleanups: + + turn on strict/warnings for all tests + + run tests through perltidy and formatting cleanup + + remove number prefixes from test names + + use Test::More instead of generating TAP by hand + + use three-arg form of open() + + don't use indirect object syntax + + don't use bareword file handles + + use File::Temp to generate temporary files + +1.47 2017-02-27 + - Fix longstanding memory leak in _scrubpkg() [#22031] + - Fix various spelling errors [#86872] + +NOTE: Changes for versions prior to 1.47 have been imported from README + +1.46 2013-02-11 + - Thanks to Rik Signes, there is a new + Text::Template->append_text_to_output method, which Text::Template always + uses whenever it wants to emit output. You can subclass this to get + control over the output, for example for postprocessing. + - A spurious warning is no longer emitted when the TYPE parameter to ->new + is omitted. + +1.45 2008-04-16 + +1.44 2003-04-29 + - This is a maintenance release. There are no feature changes. + - _scrubpkg, which was responsible for eptying out temporary packages after + the module had done with them, wasn't always working; the result was + memory leaks in long-running applications. This should be fixed now, and + there is a test in the test suite for it. + - Minor changes to the test suite to prevent spurious errors. + - Minor documentation changes. + +1.43 2002-03-25 + - The ->new method now fails immediately and sets $Text::Template::ERROR if + the file that is named by a filename argument does not exist or cannot be + opened for some other reason. Formerly, the constructor would succeed + and the ->fill_in call would fail. + +1.42 2001-11-05 + - This is a maintenance release. There are no feature changes. + - Fixed a bug relating to use of UNTAINT under perl 5.005_03 and possibly + other versions. + - Taint-related tests are now more comprehensive. + +1.41 2001-09-04 + - This is a maintenance release. There are no feature changes. + - Tests now work correctly on Windows systems and possibly on other + non-unix systems. + +1.40 2001-08-30 + *** INCOMPATIBLE CHANGE *** + - The format of the default error message has changed. It used to look + like: + + Program fragment at line 30 delivered error ``Illegal division by zero'' + + It now looks like: + + Program fragment delivered error ``Illegal division by zero at catalog.tmpl line 37'' + + Note that the default message used to report the line number at which the + program fragment began; it now reports the line number at which the error + actually occurred. + + *** INCOMPATIBLE CHANGE *** + - The format of the default error message has changed. It used to look like: + + Program fragment at line 30 delivered error ``Illegal division by zero'' + + It now looks like: + + Program fragment delivered error ``Illegal division by zero at catalog.tmpl line 37'' + + - Note that the default message used to report the line number at which the + program fragment began; it now reports the line number at which the error + actually occurred. + - New UNTAINT option tells the module that it is safe to 'eval' code even + though it has come from a file or filehandle. + - Code added to prevent memory leaks when filling many templates. Thanks + to Itamar Almeida de Carvalho. + - Bug fix: $OUT was not correctly initialized when used in conjunction + with SAFE. + - You may now use a glob ref when passing a filehandle to the ->new + function. Formerly, a glob was required. + - New subclass: Text::Template::Preprocess. Just like Text::Template, but + you may supply a PREPROCESS option in the constructor or the fill_in + call; this is a function which receives each code fragment prior to + evaluation, and which may modify and return the fragment; the modified + fragment is what is evaluated. + - Error messages passed to BROKEN subroutines will now report the correct + line number of the template at which the error occurred: + + Illegal division by zero at template line 37. + + - If the template comes from a file, the filename will be reported as well: + + Illegal division by zero at catalog.tmpl line 37. + + - New UNTAINT option tells the module that it is safe to eval template code + even if it has come from a file or filehandle, disabling taint checking + in these cases. + - Code added to prevent memory leaks when filling many templates. Thanks to + Itamar Almeida de Carvalho. + - Bug fix: $OUT was not always correctly initialized when used in + conjunction with SAFE. + - You may now use a glob ref when passing a filehandle to the new function. + Formerly, a glob was required. + - Error messages passed to BROKEN subroutines will now report the correct + line number of the template at which the error occurred: + + Illegal division by zero at template line 37. + + If the template comes from a file, the filename will be reported as well: + + Illegal division by zero at catalog.tmpl line 37. + + - New subclass: Text::Template::Preprocess. Just like Text::Template, but + you may supply a PREPROCESS option in the fill_in call; this is a + function which receives each code fragment prior to evaluation, and which + may modify and return the fragment; the modified fragment is what is + evaluated. + +1.31 2001-02-05 + - Maintenance and bug fix release + - fill_in_string was failing. Thanks to Donald L. Greer Jr. for the test case. + +1.23 1999-12-21 + - Small bug fix: DELIMITER and other arguments were being ignored in calls + to fill_in_file and fill_this_in. (Thanks to Jonathan Roy for reporting + this.) + +1.22 + - You can now specify that certain Perl statements be prepended to the + beginning of every program fragment in a template, either per template, + or for all templates, or for the duration of only one call to fill_in. + This is useful, for example, if you want to enable `strict' checks in + your templates but you don't want to manually add `use strict' to the + front of every program fragment everywhere. + +1.20 1999-03-08 + - You can now specify that the program fragment delimiters are strings + other than { and }. This has three interesting effects: First, it + changes the delimiter strings. Second, it disables the special meaning + of \, so you have to be really, really sure that the delimiters will not + appear in your templates. And third, because of the simplifications + introduced by the elimination of \ processing, template parsing is 20-25% + faster. See the manual section on `Alternative Delimiters'. + - Fixed bug having to do with undefined values in HASH options. In + particular, Text::Template no longer generates a warning if you try to + give a variable an undefined value. + +1.12 1999-02-28 + - I forgot to say that Text::Template ISA Exporter, so the exported + functions never got exported. Duhhh! + - Template TYPEs are now case-insensitive. The `new' method now diagnoses + attempts to use an invalid TYPE. + - More tests for these things. + +1.11 1999-02-25 + - Fixed a bug in the way backslashes were processed. The 1.10 behavior was + incompatible with the beta versions and was also inconvenient. (`\n' in + templates was replaced with `n' before it was given to Perl for + evaluation.) The new behavior is also incompatible with the beta + versions, but it is only a little bit incompatible, and it is probably + better. + - Documentation for the new behavior, and tests for the bug. + +1.10 1999-02-13 + - New OUTPUT option delivers template results directly to a filehandle + instead of making them into a string. Saves space and time. + - PACKAGE and HASH now work intelligently with SAFE. + - Fragments may now output data directly to the template, rather than + having to arrange to return it as a return value at the end. This means + that where you used to have to write this: + + { my $blist = ''; + foreach $i (@items) { + $blist .= qq{ * $i\n}; + } + $blist; + } + + You can now write this instead, because $OUT is special. + + { foreach $i (@items) { + $OUT.= " * $i\n"; + } + } + + (`A spoonful of sugar makes the medicine go down.') + - Fixed some small bugs. Worked around a bug in Perl that does the wrong + thing with $x = when $x contains a glob. + - More documentation. Errors fixed. + - Lots more tests. + +1.03 1999-02-06 + - Code added to support HASH option to fill_in. (Incl. `_gensym' + function.) + - Documentation for HASH. + - New test file for HASH. + - Note about failure of lexical variables to propagate into templates. Why + does this surprise people? + - Bug fix: program fragments are evaluated in an environment with `no + strict' by default. Otherwise, you get a lot of `Global symbol "$v" + requires explicit package name' failures. Why didn't the test program + pick this up? Because the only variable the test program ever used was + `$a', which is exempt. Duhhhhh. + - Fixed the test program. + - Various minor documentation fixes. + +1.00 1999-02-05 + This is a complete rewrite. The new version delivers better functionality + but is only 2/3 as long, which I think is a good sign. It is supposed to be + 100% backward-compatible with the previous versions. With one cosmetic + change, it passes the test suite that the previous versions passed. If you + have compatibility problems, please mail me immediately. + + - At least twice as fast + - Better support for filling out the same template more than once + - Now supports evaluation of program fragments in Safe compartments. + (Thanks, Jonathan!) + - Better argument syntax + - More convenience functions + - The parser is much better and simpler + - Once a template is parsed, the parsed version is stored so that + it needn't be parsed again. + - BROKEN function behavior is rationalized. You can now pass an + arbitrary argument to your BROKEN function, or return a value + from it to the main program. + - Documentation overhauled. + +Previous Versions + - Maintained by Mark Jason Dominus (MJD) diff --git a/external/perl/Text-Template-1.46/INSTALL b/external/perl/Text-Template-1.56/INSTALL similarity index 100% rename from external/perl/Text-Template-1.46/INSTALL rename to external/perl/Text-Template-1.56/INSTALL diff --git a/external/perl/Text-Template-1.56/LICENSE b/external/perl/Text-Template-1.56/LICENSE new file mode 100644 index 00000000..718b860a --- /dev/null +++ b/external/perl/Text-Template-1.56/LICENSE @@ -0,0 +1,379 @@ +This software is copyright (c) 2013 by Mark Jason Dominus . + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +Terms of the Perl programming language system itself + +a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or +b) the "Artistic License" + +--- The GNU General Public License, Version 1, February 1989 --- + +This software is Copyright (c) 2013 by Mark Jason Dominus . + +This is free software, licensed under: + + The GNU General Public License, Version 1, February 1989 + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! + + +--- The Artistic License 1.0 --- + +This software is Copyright (c) 2013 by Mark Jason Dominus . + +This is free software, licensed under: + + The Artistic License 1.0 + +The Artistic License + +Preamble + +The intent of this document is to state the conditions under which a Package +may be copied, such that the Copyright Holder maintains some semblance of +artistic control over the development of the package, while giving the users of +the package the right to use and distribute the Package in a more-or-less +customary fashion, plus the right to make reasonable modifications. + +Definitions: + + - "Package" refers to the collection of files distributed by the Copyright + Holder, and derivatives of that collection of files created through + textual modification. + - "Standard Version" refers to such a Package if it has not been modified, + or has been modified in accordance with the wishes of the Copyright + Holder. + - "Copyright Holder" is whoever is named in the copyright or copyrights for + the package. + - "You" is you, if you're thinking about copying or distributing this Package. + - "Reasonable copying fee" is whatever you can justify on the basis of media + cost, duplication charges, time of people involved, and so on. (You will + not be required to justify it to the Copyright Holder, but only to the + computing community at large as a market that must bear the fee.) + - "Freely Available" means that no fee is charged for the item itself, though + there may be fees involved in handling the item. It also means that + recipients of the item may redistribute it under the same conditions they + received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications derived +from the Public Domain or from the Copyright Holder. A Package modified in such +a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided that +you insert a prominent notice in each changed file stating how and when you +changed that file, and provided that you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or an + equivalent medium, or placing the modifications on a major archive site + such as ftp.uu.net, or by allowing the Copyright Holder to include your + modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict with + standard executables, which must also be provided, and provide a separate + manual page for each non-standard executable that clearly documents how it + differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or executable +form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where to + get the Standard Version. + + b) accompany the distribution with the machine-readable source of the Package + with your modifications. + + c) accompany any non-standard executables with their corresponding Standard + Version executables, giving the non-standard executables non-standard + names, and clearly documenting the differences in manual pages (or + equivalent), together with instructions on where to get the Standard + Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this Package. You +may not charge a fee for this Package itself. However, you may distribute this +Package in aggregate with other (possibly commercial) programs as part of a +larger (possibly commercial) software distribution provided that you do not +advertise this Package as a product of your own. + +6. The scripts and library files supplied as input to or produced as output +from the programs of this Package do not automatically fall under the copyright +of this Package, but belong to whomever generated them, and may be sold +commercially, and may be aggregated with this Package. + +7. C or perl subroutines supplied by you and linked into this Package shall not +be considered part of this Package. + +8. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +The End + diff --git a/external/perl/Text-Template-1.56/MANIFEST b/external/perl/Text-Template-1.56/MANIFEST new file mode 100644 index 00000000..7f07faaa --- /dev/null +++ b/external/perl/Text-Template-1.56/MANIFEST @@ -0,0 +1,34 @@ +# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.012. +Changes +INSTALL +LICENSE +MANIFEST +META.json +META.yml +Makefile.PL +README +SIGNATURE +lib/Text/Template.pm +lib/Text/Template/Preprocess.pm +t/author-pod-syntax.t +t/author-signature.t +t/basic.t +t/broken.t +t/delimiters.t +t/error.t +t/exported.t +t/hash.t +t/inline-comment.t +t/nested-tags.t +t/ofh.t +t/out.t +t/prepend.t +t/preprocess.t +t/rt29928.t +t/safe.t +t/safe2.t +t/safe3.t +t/strict.t +t/taint.t +t/template-encoding.t +t/warnings.t diff --git a/external/perl/Text-Template-1.56/META.json b/external/perl/Text-Template-1.56/META.json new file mode 100644 index 00000000..2d41ada9 --- /dev/null +++ b/external/perl/Text-Template-1.56/META.json @@ -0,0 +1,83 @@ +{ + "abstract" : "Expand template text with embedded Perl", + "author" : [ + "Michael Schout " + ], + "dynamic_config" : 0, + "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "Text-Template", + "prereqs" : { + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0", + "perl" : "5.008" + } + }, + "develop" : { + "requires" : { + "Dist::Zilla" : "5", + "Dist::Zilla::PluginBundle::MSCHOUT" : "0", + "Software::License::Perl_5" : "0", + "Test::Pod" : "1.41", + "Test::Signature" : "0" + } + }, + "runtime" : { + "requires" : { + "Carp" : "0", + "Encode" : "0", + "Exporter" : "0", + "base" : "0", + "perl" : "5.008", + "strict" : "0", + "warnings" : "0" + } + }, + "test" : { + "requires" : { + "File::Temp" : "0", + "Safe" : "0", + "Test::More" : "0", + "Test::More::UTF8" : "0", + "Test::Warnings" : "0", + "lib" : "0", + "perl" : "5.008", + "utf8" : "0", + "vars" : "0" + } + } + }, + "provides" : { + "Text::Template" : { + "file" : "lib/Text/Template.pm", + "version" : "1.56" + }, + "Text::Template::Preprocess" : { + "file" : "lib/Text/Template/Preprocess.pm", + "version" : "1.56" + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "web" : "https://github.com/mschout/perl-text-template/issues" + }, + "homepage" : "https://github.com/mschout/perl-text-template", + "repository" : { + "type" : "git", + "url" : "https://github.com/mschout/perl-text-template.git", + "web" : "https://github.com/mschout/perl-text-template" + } + }, + "version" : "1.56", + "x_generated_by_perl" : "v5.26.2", + "x_serialization_backend" : "Cpanel::JSON::XS version 4.04" +} + diff --git a/external/perl/Text-Template-1.56/META.yml b/external/perl/Text-Template-1.56/META.yml new file mode 100644 index 00000000..0310ce6e --- /dev/null +++ b/external/perl/Text-Template-1.56/META.yml @@ -0,0 +1,46 @@ +--- +abstract: 'Expand template text with embedded Perl' +author: + - 'Michael Schout ' +build_requires: + File::Temp: '0' + Safe: '0' + Test::More: '0' + Test::More::UTF8: '0' + Test::Warnings: '0' + lib: '0' + perl: '5.008' + utf8: '0' + vars: '0' +configure_requires: + ExtUtils::MakeMaker: '0' + perl: '5.008' +dynamic_config: 0 +generated_by: 'Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: Text-Template +provides: + Text::Template: + file: lib/Text/Template.pm + version: '1.56' + Text::Template::Preprocess: + file: lib/Text/Template/Preprocess.pm + version: '1.56' +requires: + Carp: '0' + Encode: '0' + Exporter: '0' + base: '0' + perl: '5.008' + strict: '0' + warnings: '0' +resources: + bugtracker: https://github.com/mschout/perl-text-template/issues + homepage: https://github.com/mschout/perl-text-template + repository: https://github.com/mschout/perl-text-template.git +version: '1.56' +x_generated_by_perl: v5.26.2 +x_serialization_backend: 'YAML::Tiny version 1.73' diff --git a/external/perl/Text-Template-1.56/Makefile.PL b/external/perl/Text-Template-1.56/Makefile.PL new file mode 100644 index 00000000..15b421be --- /dev/null +++ b/external/perl/Text-Template-1.56/Makefile.PL @@ -0,0 +1,71 @@ +# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.012. +use strict; +use warnings; + +use 5.008; + +use ExtUtils::MakeMaker; + +my %WriteMakefileArgs = ( + "ABSTRACT" => "Expand template text with embedded Perl", + "AUTHOR" => "Michael Schout ", + "CONFIGURE_REQUIRES" => { + "ExtUtils::MakeMaker" => 0 + }, + "DISTNAME" => "Text-Template", + "LICENSE" => "perl", + "MIN_PERL_VERSION" => "5.008", + "NAME" => "Text::Template", + "PREREQ_PM" => { + "Carp" => 0, + "Encode" => 0, + "Exporter" => 0, + "base" => 0, + "strict" => 0, + "warnings" => 0 + }, + "TEST_REQUIRES" => { + "File::Temp" => 0, + "Safe" => 0, + "Test::More" => 0, + "Test::More::UTF8" => 0, + "Test::Warnings" => 0, + "lib" => 0, + "utf8" => 0, + "vars" => 0 + }, + "VERSION" => "1.56", + "test" => { + "TESTS" => "t/*.t" + } +); + + +my %FallbackPrereqs = ( + "Carp" => 0, + "Encode" => 0, + "Exporter" => 0, + "File::Temp" => 0, + "Safe" => 0, + "Test::More" => 0, + "Test::More::UTF8" => 0, + "Test::Warnings" => 0, + "base" => 0, + "lib" => 0, + "strict" => 0, + "utf8" => 0, + "vars" => 0, + "warnings" => 0 +); + + +unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { + delete $WriteMakefileArgs{TEST_REQUIRES}; + delete $WriteMakefileArgs{BUILD_REQUIRES}; + $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; + +WriteMakefile(%WriteMakefileArgs); diff --git a/external/perl/Text-Template-1.56/README b/external/perl/Text-Template-1.56/README new file mode 100644 index 00000000..5f62ac71 --- /dev/null +++ b/external/perl/Text-Template-1.56/README @@ -0,0 +1,62 @@ + +Text::Template v1.46 + +This is a library for generating form letters, building HTML pages, or +filling in templates generally. A `template' is a piece of text that +has little Perl programs embedded in it here and there. When you +`fill in' a template, you evaluate the little programs and replace +them with their values. + +Here's an example of a template: + + Dear {$title} {$lastname}, + + It has come to our attention that you are delinquent in your + {$monthname[$last_paid_month]} payment. Please remit + ${sprintf("%.2f", $amount)} immediately, or your patellae may + be needlessly endangered. + + Love, + + Mark "{nickname(rand 20)}" Dominus + + +The result of filling in this template is a string, which might look +something like this: + + Dear Mr. Gates, + + It has come to our attention that you are delinquent in your + February payment. Please remit + $392.12 immediately, or your patellae may + be needlessly endangered. + + + Love, + + Mark "Vizopteryx" Dominus + +You can store a template in a file outside your program. People can +modify the template without modifying the program. You can separate +the formatting details from the main code, and put the formatting +parts of the program into the template. That prevents code bloat and +encourages functional separation. + +You can fill in the template in a `Safe' compartment. This means that +if you don't trust the person who wrote the code in the template, you +won't have to worry that they are tampering with your program when you +execute it. + +---------------------------------------------------------------- + +Text::Template was originally released some time in late 1995 or early +1996. After three years of study and investigation, I rewrote it from +scratch in January 1999. The new version, 1.0, was much faster, +delivered better functionality and was almost 100% backward-compatible +with the previous beta versions. + +I have added a number of useful features and conveniences since the +1.0 release, while still retaining backward compatibility. With one +merely cosmetic change, the current version of Text::Template passes +the test suite that the old beta versions passed. + diff --git a/external/perl/Text-Template-1.56/SIGNATURE b/external/perl/Text-Template-1.56/SIGNATURE new file mode 100644 index 00000000..c7cb7d3f --- /dev/null +++ b/external/perl/Text-Template-1.56/SIGNATURE @@ -0,0 +1,65 @@ +This file contains message digests of all files listed in MANIFEST, +signed via the Module::Signature module, version 0.81. + +To verify the content in this distribution, first make sure you have +Module::Signature installed, then type: + + % cpansign -v + +It will check each file's integrity, as well as the signature's +validity. If "==> Signature verified OK! <==" is not displayed, +the distribution may already have been compromised, and you should +not run its Makefile.PL or Build.PL. + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +SHA1 8ba1381d3fc8d81457c35e5aff52b8e55d57be7c Changes +SHA1 b457bd56a70b838ccc55d183ab09de64b6996958 INSTALL +SHA1 f12894289cb0f379f24b8d63e2e761dbcba1b216 LICENSE +SHA1 2c21cb13f53da41c4b30011aca9014db2de46862 MANIFEST +SHA1 ea82a70dfcffe05202868dfe02826aaf1f6e0229 META.json +SHA1 9ad7419fb6209e81652da42967995c8fb8f1826b META.yml +SHA1 f7634b46dde2cf8c6f31fe46327d15151d654a2c Makefile.PL +SHA1 b94aaad0a0bf2c323061bfefb9cf1fd532f14e7b README +SHA1 090d77972c087a8905fa85522854afbf4ccc999b lib/Text/Template.pm +SHA1 ca5251a021e46b60603f10e757d689e52fde1feb lib/Text/Template/Preprocess.pm +SHA1 8efad25309730a4d501fb40fc03eda4697303372 t/author-pod-syntax.t +SHA1 19cc343f8a85c6805bbeb02580487483a6283887 t/author-signature.t +SHA1 ae085010c9f08576ef8584f224e38e6a98c1c178 t/basic.t +SHA1 006feb1a0b1e5780db52aa79bd38933664a8339a t/broken.t +SHA1 dee8cef1fcd43ce5de462018f8539d4a0fbc460f t/delimiters.t +SHA1 304955c4280159ec3a4c0f2717dcff9c887bb487 t/error.t +SHA1 c862dfc08e00e76b3f2aee953583d3cc8e5524a2 t/exported.t +SHA1 50ef92bda3b6b5cbd5a9307e6f17ce49ee8f245c t/hash.t +SHA1 d5dc210684aec8bb2c4817af96597c86047169c1 t/inline-comment.t +SHA1 31ff85f423178f2d6638d35edf859d73f63dd5c7 t/nested-tags.t +SHA1 62ae0720aa86146bccfa23d2c903fa142cb86d50 t/ofh.t +SHA1 68093417d49a2afdfcd4642bacea04466039b734 t/out.t +SHA1 a8b21fdca0f1d243775a00758105e0fcc58022aa t/prepend.t +SHA1 4e7e00eccede7c3231e93ef0f3cb011423be4eb5 t/preprocess.t +SHA1 a52d61ef92e6a88d694db0be4893b88417a72f9c t/rt29928.t +SHA1 5186ff459c6042af11bca92decd271887c7b2eae t/safe.t +SHA1 aa0c9ff96d66c1f74fc7ac73ce173c9f741f552e t/safe2.t +SHA1 b50a51577c0f2c13c9a48113dc7f061385a02219 t/safe3.t +SHA1 16d3abf7588da4c0056c6c6b7818470c8601577c t/strict.t +SHA1 f325ebf739e2aec3ae62427aef0c4e86de58ad29 t/taint.t +SHA1 4dac28585388482f1719f404cc357991af77e345 t/template-encoding.t +SHA1 ce1da9bf88d6ea62d7c756f0d730dfb3c5888b6e t/warnings.t +-----BEGIN PGP SIGNATURE----- + +iQJFBAEBCAAvFiEE2EtuRfhGgngE8PsARAzvLrlUzY4FAl0kljYRHG1zY2hvdXRA +Y3Bhbi5vcmcACgkQRAzvLrlUzY6BdRAAlu/LI+71ax6OJfn6O6SslZCKdIfef1+P +UQ3eQCzbUOK1hP9p6TNOMFv0xPew7a1jSsM/wLjryXKLqGIclonBopRisZjCSaFa +DSH+5k4A9TWKo7n08C3nydVZPTfHXLEO6tHIH2umDHjMyC1gDkApjvSqH53OCtoV +vUTqQn9c6MxmuIWus1gjVynTvXWtBmaqrvTuQENFUXsGH5gVVbEr0VNIyt6Ip3p5 +HnRe8UdykFJZvfhEhH1pbt2j513m9Bqce0eSb/eshraFugx7coD3gk2EXqp8eVzK +84vPEcNC8Moii8+qg48VDh9wBq1u/cba2U7PcVjj3lRk/pAni31XnlXLPWJ0dZLF +fR4glE86ESTGSyI2wGDxyEdev+e64sk7geYmL388kqtpqkKWvALmQkKUJg0T0ppp +LYv31DrsP4QM1duv46y3wVbqUPeQlKBOU81vfyAonrD02tRZjwRpCD67CZ9WSgZu +el85yPneIIijYEOzV8GYHKNiiZKpu2uidKCe+MFGxBtXe9hyi9x95tuyi9/pu2FB +YjbGJ8Wb4xhS7zdDWZb/axfwbcGMVml6a6xA98jVkwjHhPvKsf3qWVZZPtWneeN0 +pGNpMta73wQxrp5/W1GfvBfPVlsker6SAARg2NMwS9Wmp+ZuD6gdJ+aN0/PPtNUd +HQJJFjr/xo4= +=nx9E +-----END PGP SIGNATURE----- diff --git a/external/perl/Text-Template-1.46/lib/Text/Template.pm b/external/perl/Text-Template-1.56/lib/Text/Template.pm similarity index 60% rename from external/perl/Text-Template-1.46/lib/Text/Template.pm rename to external/perl/Text-Template-1.56/lib/Text/Template.pm index dc4f3bac..be38c73c 100644 --- a/external/perl/Text-Template-1.46/lib/Text/Template.pm +++ b/external/perl/Text-Template-1.56/lib/Text/Template.pm @@ -5,486 +5,613 @@ # # Copyright 2013 M. J. Dominus. # You may copy and distribute this program under the -# same terms as Perl iteself. +# same terms as Perl itself. # If in doubt, write to mjd-perl-template+@plover.com for a license. # -# Version 1.46 package Text::Template; -require 5.004; -use Exporter; -@ISA = qw(Exporter); -@EXPORT_OK = qw(fill_in_file fill_in_string TTerror); -use vars '$ERROR'; -use strict; +$Text::Template::VERSION = '1.56'; +# ABSTRACT: Expand template text with embedded Perl + +use strict; +use warnings; + +require 5.008; + +use base 'Exporter'; + +our @EXPORT_OK = qw(fill_in_file fill_in_string TTerror); +our $ERROR; -$Text::Template::VERSION = '1.46'; my %GLOBAL_PREPEND = ('Text::Template' => ''); sub Version { - $Text::Template::VERSION; + $Text::Template::VERSION; } sub _param { - my $kk; - my ($k, %h) = @_; - for $kk ($k, "\u$k", "\U$k", "-$k", "-\u$k", "-\U$k") { - return $h{$kk} if exists $h{$kk}; - } - return; + my ($k, %h) = @_; + + for my $kk ($k, "\u$k", "\U$k", "-$k", "-\u$k", "-\U$k") { + return $h{$kk} if exists $h{$kk}; + } + + return undef; } -sub always_prepend -{ - my $pack = shift; - my $old = $GLOBAL_PREPEND{$pack}; - $GLOBAL_PREPEND{$pack} = shift; - $old; -} - -{ - my %LEGAL_TYPE; - BEGIN { - %LEGAL_TYPE = map {$_=>1} qw(FILE FILEHANDLE STRING ARRAY); - } - sub new { +sub always_prepend { my $pack = shift; - my %a = @_; - my $stype = uc(_param('type', %a) || "FILE"); - my $source = _param('source', %a); - my $untaint = _param('untaint', %a); - my $prepend = _param('prepend', %a); - my $alt_delim = _param('delimiters', %a); - my $broken = _param('broken', %a); - unless (defined $source) { - require Carp; - Carp::croak("Usage: $ {pack}::new(TYPE => ..., SOURCE => ...)"); - } - unless ($LEGAL_TYPE{$stype}) { - require Carp; - Carp::croak("Illegal value `$stype' for TYPE parameter"); - } - my $self = {TYPE => $stype, - PREPEND => $prepend, - UNTAINT => $untaint, - BROKEN => $broken, - (defined $alt_delim ? (DELIM => $alt_delim) : ()), - }; - # Under 5.005_03, if any of $stype, $prepend, $untaint, or $broken - # are tainted, all the others become tainted too as a result of - # sharing the expression with them. We install $source separately - # to prevent it from acquiring a spurious taint. - $self->{SOURCE} = $source; - bless $self => $pack; - return unless $self->_acquire_data; - - $self; - } + my $old = $GLOBAL_PREPEND{$pack}; + + $GLOBAL_PREPEND{$pack} = shift; + + $old; +} + +{ + my %LEGAL_TYPE; + + BEGIN { + %LEGAL_TYPE = map { $_ => 1 } qw(FILE FILEHANDLE STRING ARRAY); + } + + sub new { + my ($pack, %a) = @_; + + my $stype = uc(_param('type', %a) || "FILE"); + my $source = _param('source', %a); + my $untaint = _param('untaint', %a); + my $prepend = _param('prepend', %a); + my $alt_delim = _param('delimiters', %a); + my $broken = _param('broken', %a); + my $encoding = _param('encoding', %a); + + unless (defined $source) { + require Carp; + Carp::croak("Usage: $ {pack}::new(TYPE => ..., SOURCE => ...)"); + } + + unless ($LEGAL_TYPE{$stype}) { + require Carp; + Carp::croak("Illegal value `$stype' for TYPE parameter"); + } + + my $self = { + TYPE => $stype, + PREPEND => $prepend, + UNTAINT => $untaint, + BROKEN => $broken, + ENCODING => $encoding, + (defined $alt_delim ? (DELIM => $alt_delim) : ()) + }; + + # Under 5.005_03, if any of $stype, $prepend, $untaint, or $broken + # are tainted, all the others become tainted too as a result of + # sharing the expression with them. We install $source separately + # to prevent it from acquiring a spurious taint. + $self->{SOURCE} = $source; + + bless $self => $pack; + return unless $self->_acquire_data; + + $self; + } } # Convert template objects of various types to type STRING, # in which the template data is embedded in the object itself. sub _acquire_data { - my ($self) = @_; - my $type = $self->{TYPE}; - if ($type eq 'STRING') { - # nothing necessary - } elsif ($type eq 'FILE') { - my $data = _load_text($self->{SOURCE}); - unless (defined $data) { - # _load_text already set $ERROR - return undef; + my $self = shift; + + my $type = $self->{TYPE}; + + if ($type eq 'STRING') { + # nothing necessary } - if ($self->{UNTAINT} && _is_clean($self->{SOURCE})) { - _unconditionally_untaint($data); + elsif ($type eq 'FILE') { + my $data = _load_text($self->{SOURCE}); + unless (defined $data) { + + # _load_text already set $ERROR + return undef; + } + + if ($self->{UNTAINT} && _is_clean($self->{SOURCE})) { + _unconditionally_untaint($data); + } + + if (defined $self->{ENCODING}) { + require Encode; + $data = Encode::decode($self->{ENCODING}, $data, &Encode::FB_CROAK); + } + + $self->{TYPE} = 'STRING'; + $self->{FILENAME} = $self->{SOURCE}; + $self->{SOURCE} = $data; } - $self->{TYPE} = 'STRING'; - $self->{FILENAME} = $self->{SOURCE}; - $self->{SOURCE} = $data; - } elsif ($type eq 'ARRAY') { - $self->{TYPE} = 'STRING'; - $self->{SOURCE} = join '', @{$self->{SOURCE}}; - } elsif ($type eq 'FILEHANDLE') { - $self->{TYPE} = 'STRING'; - local $/; - my $fh = $self->{SOURCE}; - my $data = <$fh>; # Extra assignment avoids bug in Solaris perl5.00[45]. - if ($self->{UNTAINT}) { - _unconditionally_untaint($data); + elsif ($type eq 'ARRAY') { + $self->{TYPE} = 'STRING'; + $self->{SOURCE} = join '', @{ $self->{SOURCE} }; } - $self->{SOURCE} = $data; - } else { - # This should have been caught long ago, so it represents a - # drastic `can't-happen' sort of failure - my $pack = ref $self; - die "Can only acquire data for $pack objects of subtype STRING, but this is $type; aborting"; - } - $self->{DATA_ACQUIRED} = 1; + elsif ($type eq 'FILEHANDLE') { + $self->{TYPE} = 'STRING'; + local $/; + my $fh = $self->{SOURCE}; + my $data = <$fh>; # Extra assignment avoids bug in Solaris perl5.00[45]. + if ($self->{UNTAINT}) { + _unconditionally_untaint($data); + } + $self->{SOURCE} = $data; + } + else { + # This should have been caught long ago, so it represents a + # drastic `can't-happen' sort of failure + my $pack = ref $self; + die "Can only acquire data for $pack objects of subtype STRING, but this is $type; aborting"; + } + + $self->{DATA_ACQUIRED} = 1; } sub source { - my ($self) = @_; - $self->_acquire_data unless $self->{DATA_ACQUIRED}; - return $self->{SOURCE}; + my $self = shift; + + $self->_acquire_data unless $self->{DATA_ACQUIRED}; + + return $self->{SOURCE}; } sub set_source_data { - my ($self, $newdata) = @_; - $self->{SOURCE} = $newdata; - $self->{DATA_ACQUIRED} = 1; - $self->{TYPE} = 'STRING'; - 1; + my ($self, $newdata, $type) = @_; + + $self->{SOURCE} = $newdata; + $self->{DATA_ACQUIRED} = 1; + $self->{TYPE} = $type || 'STRING'; + + 1; } sub compile { - my $self = shift; + my $self = shift; - return 1 if $self->{TYPE} eq 'PREPARSED'; + return 1 if $self->{TYPE} eq 'PREPARSED'; - return undef unless $self->_acquire_data; - unless ($self->{TYPE} eq 'STRING') { - my $pack = ref $self; - # This should have been caught long ago, so it represents a - # drastic `can't-happen' sort of failure - die "Can only compile $pack objects of subtype STRING, but this is $self->{TYPE}; aborting"; - } + return undef unless $self->_acquire_data; - my @tokens; - my $delim_pats = shift() || $self->{DELIM}; + unless ($self->{TYPE} eq 'STRING') { + my $pack = ref $self; - - - my ($t_open, $t_close) = ('{', '}'); - my $DELIM; # Regex matches a delimiter if $delim_pats - if (defined $delim_pats) { - ($t_open, $t_close) = @$delim_pats; - $DELIM = "(?:(?:\Q$t_open\E)|(?:\Q$t_close\E))"; - @tokens = split /($DELIM|\n)/, $self->{SOURCE}; - } else { - @tokens = split /(\\\\(?=\\*[{}])|\\[{}]|[{}\n])/, $self->{SOURCE}; - } - my $state = 'TEXT'; - my $depth = 0; - my $lineno = 1; - my @content; - my $cur_item = ''; - my $prog_start; - while (@tokens) { - my $t = shift @tokens; - next if $t eq ''; - if ($t eq $t_open) { # Brace or other opening delimiter - if ($depth == 0) { - push @content, [$state, $cur_item, $lineno] if $cur_item ne ''; - $cur_item = ''; - $state = 'PROG'; - $prog_start = $lineno; - } else { - $cur_item .= $t; - } - $depth++; - } elsif ($t eq $t_close) { # Brace or other closing delimiter - $depth--; - if ($depth < 0) { - $ERROR = "Unmatched close brace at line $lineno"; - return undef; - } elsif ($depth == 0) { - push @content, [$state, $cur_item, $prog_start] if $cur_item ne ''; - $state = 'TEXT'; - $cur_item = ''; - } else { - $cur_item .= $t; - } - } elsif (!$delim_pats && $t eq '\\\\') { # precedes \\\..\\\{ or \\\..\\\} - $cur_item .= '\\'; - } elsif (!$delim_pats && $t =~ /^\\([{}])$/) { # Escaped (literal) brace? - $cur_item .= $1; - } elsif ($t eq "\n") { # Newline - $lineno++; - $cur_item .= $t; - } else { # Anything else - $cur_item .= $t; + # This should have been caught long ago, so it represents a + # drastic `can't-happen' sort of failure + die "Can only compile $pack objects of subtype STRING, but this is $self->{TYPE}; aborting"; } - } - if ($state eq 'PROG') { - $ERROR = "End of data inside program text that began at line $prog_start"; - return undef; - } elsif ($state eq 'TEXT') { - push @content, [$state, $cur_item, $lineno] if $cur_item ne ''; - } else { - die "Can't happen error #1"; - } - - $self->{TYPE} = 'PREPARSED'; - $self->{SOURCE} = \@content; - 1; + my @tokens; + my $delim_pats = shift() || $self->{DELIM}; + + my ($t_open, $t_close) = ('{', '}'); + my $DELIM; # Regex matches a delimiter if $delim_pats + + if (defined $delim_pats) { + ($t_open, $t_close) = @$delim_pats; + $DELIM = "(?:(?:\Q$t_open\E)|(?:\Q$t_close\E))"; + @tokens = split /($DELIM|\n)/, $self->{SOURCE}; + } + else { + @tokens = split /(\\\\(?=\\*[{}])|\\[{}]|[{}\n])/, $self->{SOURCE}; + } + + my $state = 'TEXT'; + my $depth = 0; + my $lineno = 1; + my @content; + my $cur_item = ''; + my $prog_start; + + while (@tokens) { + my $t = shift @tokens; + + next if $t eq ''; + + if ($t eq $t_open) { # Brace or other opening delimiter + if ($depth == 0) { + push @content, [ $state, $cur_item, $lineno ] if $cur_item ne ''; + $cur_item = ''; + $state = 'PROG'; + $prog_start = $lineno; + } + else { + $cur_item .= $t; + } + $depth++; + } + elsif ($t eq $t_close) { # Brace or other closing delimiter + $depth--; + if ($depth < 0) { + $ERROR = "Unmatched close brace at line $lineno"; + return undef; + } + elsif ($depth == 0) { + push @content, [ $state, $cur_item, $prog_start ] if $cur_item ne ''; + $state = 'TEXT'; + $cur_item = ''; + } + else { + $cur_item .= $t; + } + } + elsif (!$delim_pats && $t eq '\\\\') { # precedes \\\..\\\{ or \\\..\\\} + $cur_item .= '\\'; + } + elsif (!$delim_pats && $t =~ /^\\([{}])$/) { # Escaped (literal) brace? + $cur_item .= $1; + } + elsif ($t eq "\n") { # Newline + $lineno++; + $cur_item .= $t; + } + else { # Anything else + $cur_item .= $t; + } + } + + if ($state eq 'PROG') { + $ERROR = "End of data inside program text that began at line $prog_start"; + return undef; + } + elsif ($state eq 'TEXT') { + push @content, [ $state, $cur_item, $lineno ] if $cur_item ne ''; + } + else { + die "Can't happen error #1"; + } + + $self->{TYPE} = 'PREPARSED'; + $self->{SOURCE} = \@content; + + 1; } sub prepend_text { - my ($self) = @_; - my $t = $self->{PREPEND}; - unless (defined $t) { - $t = $GLOBAL_PREPEND{ref $self}; + my $self = shift; + + my $t = $self->{PREPEND}; + unless (defined $t) { - $t = $GLOBAL_PREPEND{'Text::Template'}; + $t = $GLOBAL_PREPEND{ ref $self }; + unless (defined $t) { + $t = $GLOBAL_PREPEND{'Text::Template'}; + } } - } - $self->{PREPEND} = $_[1] if $#_ >= 1; - return $t; + + $self->{PREPEND} = $_[1] if $#_ >= 1; + + return $t; } sub fill_in { - my $fi_self = shift; - my %fi_a = @_; + my ($fi_self, %fi_a) = @_; - unless ($fi_self->{TYPE} eq 'PREPARSED') { - my $delims = _param('delimiters', %fi_a); - my @delim_arg = (defined $delims ? ($delims) : ()); - $fi_self->compile(@delim_arg) - or return undef; - } - - my $fi_varhash = _param('hash', %fi_a); - my $fi_package = _param('package', %fi_a) ; - my $fi_broken = - _param('broken', %fi_a) || $fi_self->{BROKEN} || \&_default_broken; - my $fi_broken_arg = _param('broken_arg', %fi_a) || []; - my $fi_safe = _param('safe', %fi_a); - my $fi_ofh = _param('output', %fi_a); - my $fi_eval_package; - my $fi_scrub_package = 0; - my $fi_filename = _param('filename') || $fi_self->{FILENAME} || 'template'; - - my $fi_prepend = _param('prepend', %fi_a); - unless (defined $fi_prepend) { - $fi_prepend = $fi_self->prepend_text; - } - - if (defined $fi_safe) { - $fi_eval_package = 'main'; - } elsif (defined $fi_package) { - $fi_eval_package = $fi_package; - } elsif (defined $fi_varhash) { - $fi_eval_package = _gensym(); - $fi_scrub_package = 1; - } else { - $fi_eval_package = caller; - } - - my $fi_install_package; - if (defined $fi_varhash) { - if (defined $fi_package) { - $fi_install_package = $fi_package; - } elsif (defined $fi_safe) { - $fi_install_package = $fi_safe->root; - } else { - $fi_install_package = $fi_eval_package; # The gensymmed one + unless ($fi_self->{TYPE} eq 'PREPARSED') { + my $delims = _param('delimiters', %fi_a); + my @delim_arg = (defined $delims ? ($delims) : ()); + $fi_self->compile(@delim_arg) + or return undef; } - _install_hash($fi_varhash => $fi_install_package); - } - if (defined $fi_package && defined $fi_safe) { - no strict 'refs'; - # Big fat magic here: Fix it so that the user-specified package - # is the default one available in the safe compartment. - *{$fi_safe->root . '::'} = \%{$fi_package . '::'}; # LOD - } + my $fi_varhash = _param('hash', %fi_a); + my $fi_package = _param('package', %fi_a); + my $fi_broken = _param('broken', %fi_a) || $fi_self->{BROKEN} || \&_default_broken; + my $fi_broken_arg = _param('broken_arg', %fi_a) || []; + my $fi_safe = _param('safe', %fi_a); + my $fi_ofh = _param('output', %fi_a); + my $fi_filename = _param('filename', %fi_a) || $fi_self->{FILENAME} || 'template'; + my $fi_strict = _param('strict', %fi_a); + my $fi_prepend = _param('prepend', %fi_a); - my $fi_r = ''; - my $fi_item; - foreach $fi_item (@{$fi_self->{SOURCE}}) { - my ($fi_type, $fi_text, $fi_lineno) = @$fi_item; - if ($fi_type eq 'TEXT') { - $fi_self->append_text_to_output( - text => $fi_text, - handle => $fi_ofh, - out => \$fi_r, - type => $fi_type, - ); - } elsif ($fi_type eq 'PROG') { - no strict; - my $fi_lcomment = "#line $fi_lineno $fi_filename"; - my $fi_progtext = - "package $fi_eval_package; $fi_prepend;\n$fi_lcomment\n$fi_text;"; - my $fi_res; - my $fi_eval_err = ''; - if ($fi_safe) { - $fi_safe->reval(q{undef $OUT}); - $fi_res = $fi_safe->reval($fi_progtext); - $fi_eval_err = $@; - my $OUT = $fi_safe->reval('$OUT'); - $fi_res = $OUT if defined $OUT; - } else { - my $OUT; - $fi_res = eval $fi_progtext; - $fi_eval_err = $@; - $fi_res = $OUT if defined $OUT; - } + my $fi_eval_package; + my $fi_scrub_package = 0; - # If the value of the filled-in text really was undef, - # change it to an explicit empty string to avoid undefined - # value warnings later. - $fi_res = '' unless defined $fi_res; - - if ($fi_eval_err) { - $fi_res = $fi_broken->(text => $fi_text, - error => $fi_eval_err, - lineno => $fi_lineno, - arg => $fi_broken_arg, - ); - if (defined $fi_res) { - $fi_self->append_text_to_output( - text => $fi_res, - handle => $fi_ofh, - out => \$fi_r, - type => $fi_type, - ); - } else { - return $fi_res; # Undefined means abort processing - } - } else { - $fi_self->append_text_to_output( - text => $fi_res, - handle => $fi_ofh, - out => \$fi_r, - type => $fi_type, - ); - } - } else { - die "Can't happen error #2"; + unless (defined $fi_prepend) { + $fi_prepend = $fi_self->prepend_text; } - } - _scrubpkg($fi_eval_package) if $fi_scrub_package; - defined $fi_ofh ? 1 : $fi_r; + if (defined $fi_safe) { + $fi_eval_package = 'main'; + } + elsif (defined $fi_package) { + $fi_eval_package = $fi_package; + } + elsif (defined $fi_varhash) { + $fi_eval_package = _gensym(); + $fi_scrub_package = 1; + } + else { + $fi_eval_package = caller; + } + + my @fi_varlist; + my $fi_install_package; + + if (defined $fi_varhash) { + if (defined $fi_package) { + $fi_install_package = $fi_package; + } + elsif (defined $fi_safe) { + $fi_install_package = $fi_safe->root; + } + else { + $fi_install_package = $fi_eval_package; # The gensymmed one + } + @fi_varlist = _install_hash($fi_varhash => $fi_install_package); + if ($fi_strict) { + $fi_prepend = "use vars qw(@fi_varlist);$fi_prepend" if @fi_varlist; + $fi_prepend = "use strict;$fi_prepend"; + } + } + + if (defined $fi_package && defined $fi_safe) { + no strict 'refs'; + + # Big fat magic here: Fix it so that the user-specified package + # is the default one available in the safe compartment. + *{ $fi_safe->root . '::' } = \%{ $fi_package . '::' }; # LOD + } + + my $fi_r = ''; + my $fi_item; + foreach $fi_item (@{ $fi_self->{SOURCE} }) { + my ($fi_type, $fi_text, $fi_lineno) = @$fi_item; + if ($fi_type eq 'TEXT') { + $fi_self->append_text_to_output( + text => $fi_text, + handle => $fi_ofh, + out => \$fi_r, + type => $fi_type,); + } + elsif ($fi_type eq 'PROG') { + no strict; + + my $fi_lcomment = "#line $fi_lineno $fi_filename"; + my $fi_progtext = "package $fi_eval_package; $fi_prepend;\n$fi_lcomment\n$fi_text;\n;"; + my $fi_res; + my $fi_eval_err = ''; + + if ($fi_safe) { + no strict; + no warnings; + + $fi_safe->reval(q{undef $OUT}); + $fi_res = $fi_safe->reval($fi_progtext); + $fi_eval_err = $@; + my $OUT = $fi_safe->reval('$OUT'); + $fi_res = $OUT if defined $OUT; + } + else { + no strict; + no warnings; + + my $OUT; + $fi_res = eval $fi_progtext; + $fi_eval_err = $@; + $fi_res = $OUT if defined $OUT; + } + + # If the value of the filled-in text really was undef, + # change it to an explicit empty string to avoid undefined + # value warnings later. + $fi_res = '' unless defined $fi_res; + + if ($fi_eval_err) { + $fi_res = $fi_broken->( + text => $fi_text, + error => $fi_eval_err, + lineno => $fi_lineno, + arg => $fi_broken_arg,); + if (defined $fi_res) { + $fi_self->append_text_to_output( + text => $fi_res, + handle => $fi_ofh, + out => \$fi_r, + type => $fi_type,); + } + else { + return $fi_r; # Undefined means abort processing + } + } + else { + $fi_self->append_text_to_output( + text => $fi_res, + handle => $fi_ofh, + out => \$fi_r, + type => $fi_type,); + } + } + else { + die "Can't happen error #2"; + } + } + + _scrubpkg($fi_eval_package) if $fi_scrub_package; + + defined $fi_ofh ? 1 : $fi_r; } sub append_text_to_output { - my ($self, %arg) = @_; + my ($self, %arg) = @_; - if (defined $arg{handle}) { - print { $arg{handle} } $arg{text}; - } else { - ${ $arg{out} } .= $arg{text}; - } + if (defined $arg{handle}) { + print { $arg{handle} } $arg{text}; + } + else { + ${ $arg{out} } .= $arg{text}; + } - return; + return; } sub fill_this_in { - my $pack = shift; - my $text = shift; - my $templ = $pack->new(TYPE => 'STRING', SOURCE => $text, @_) - or return undef; - $templ->compile or return undef; - my $result = $templ->fill_in(@_); - $result; + my ($pack, $text) = splice @_, 0, 2; + + my $templ = $pack->new(TYPE => 'STRING', SOURCE => $text, @_) + or return undef; + + $templ->compile or return undef; + + my $result = $templ->fill_in(@_); + + $result; } sub fill_in_string { - my $string = shift; - my $package = _param('package', @_); - push @_, 'package' => scalar(caller) unless defined $package; - Text::Template->fill_this_in($string, @_); + my $string = shift; + + my $package = _param('package', @_); + + push @_, 'package' => scalar(caller) unless defined $package; + + Text::Template->fill_this_in($string, @_); } sub fill_in_file { - my $fn = shift; - my $templ = Text::Template->new(TYPE => 'FILE', SOURCE => $fn, @_) - or return undef; - $templ->compile or return undef; - my $text = $templ->fill_in(@_); - $text; + my $fn = shift; + my $templ = Text::Template->new(TYPE => 'FILE', SOURCE => $fn, @_) or return undef; + + $templ->compile or return undef; + + my $text = $templ->fill_in(@_); + + $text; } sub _default_broken { - my %a = @_; - my $prog_text = $a{text}; - my $err = $a{error}; - my $lineno = $a{lineno}; - chomp $err; -# $err =~ s/\s+at .*//s; - "Program fragment delivered error ``$err''"; + my %a = @_; + + my $prog_text = $a{text}; + my $err = $a{error}; + my $lineno = $a{lineno}; + + chomp $err; + + # $err =~ s/\s+at .*//s; + "Program fragment delivered error ``$err''"; } sub _load_text { - my $fn = shift; - local *F; - unless (open F, $fn) { - $ERROR = "Couldn't open file $fn: $!"; - return undef; - } - local $/; - ; + my $fn = shift; + + open my $fh, '<', $fn or do { + $ERROR = "Couldn't open file $fn: $!"; + return undef; + }; + + local $/; + + <$fh>; } sub _is_clean { - my $z; - eval { ($z = join('', @_)), eval '#' . substr($z,0,0); 1 } # LOD + my $z; + + eval { ($z = join('', @_)), eval '#' . substr($z, 0, 0); 1 } # LOD } sub _unconditionally_untaint { - for (@_) { - ($_) = /(.*)/s; - } + for (@_) { + ($_) = /(.*)/s; + } } { - my $seqno = 0; - sub _gensym { - __PACKAGE__ . '::GEN' . $seqno++; - } - sub _scrubpkg { - my $s = shift; - $s =~ s/^Text::Template:://; - no strict 'refs'; - my $hash = $Text::Template::{$s."::"}; - foreach my $key (keys %$hash) { - undef $hash->{$key}; + my $seqno = 0; + + sub _gensym { + __PACKAGE__ . '::GEN' . $seqno++; + } + + sub _scrubpkg { + my $s = shift; + + $s =~ s/^Text::Template:://; + + no strict 'refs'; + + my $hash = $Text::Template::{ $s . "::" }; + + foreach my $key (keys %$hash) { + undef $hash->{$key}; + } + + %$hash = (); + + delete $Text::Template::{ $s . "::" }; } - } } - + # Given a hashful of variables (or a list of such hashes) # install the variables into the specified package, # overwriting whatever variables were there before. sub _install_hash { - my $hashlist = shift; - my $dest = shift; - if (UNIVERSAL::isa($hashlist, 'HASH')) { - $hashlist = [$hashlist]; - } - my $hash; - foreach $hash (@$hashlist) { - my $name; - foreach $name (keys %$hash) { - my $val = $hash->{$name}; - no strict 'refs'; - local *SYM = *{"$ {dest}::$name"}; - if (! defined $val) { - delete ${"$ {dest}::"}{$name}; - } elsif (ref $val) { - *SYM = $val; - } else { - *SYM = \$val; - } + my $hashlist = shift; + my $dest = shift; + + if (UNIVERSAL::isa($hashlist, 'HASH')) { + $hashlist = [$hashlist]; } - } + + my @varlist; + + for my $hash (@$hashlist) { + for my $name (keys %$hash) { + my $val = $hash->{$name}; + + no strict 'refs'; + no warnings 'redefine'; + + local *SYM = *{"$ {dest}::$name"}; + + if (!defined $val) { + delete ${"$ {dest}::"}{$name}; + my $match = qr/^.\Q$name\E$/; + @varlist = grep { $_ !~ $match } @varlist; + } + elsif (ref $val) { + *SYM = $val; + push @varlist, do { + if (UNIVERSAL::isa($val, 'ARRAY')) { '@' } + elsif (UNIVERSAL::isa($val, 'HASH')) { '%' } + else { '$' } + } + . $name; + } + else { + *SYM = \$val; + push @varlist, '$' . $name; + } + } + } + + @varlist; } sub TTerror { $ERROR } 1; +__END__ -=head1 NAME +=pod + +=encoding UTF-8 + +=head1 NAME Text::Template - Expand template text with embedded Perl =head1 VERSION -This file documents C version B<1.46> +version 1.56 =head1 SYNOPSIS @@ -510,8 +637,8 @@ This file documents C version B<1.46> # Pass many variables explicitly $hash = { recipient => 'Abed-Nego', friends => [ 'me', 'you' ], - enemies => { loathsome => 'Bill Gates', - fearsome => 'Larry Ellison' }, + enemies => { loathsome => 'Saruman', + fearsome => 'Sauron' }, }; $text = $template->fill_in(HASH => $hash, ...); # $recipient is Abed-Nego, @@ -568,56 +695,53 @@ encourages functional separation. Here's an example of a template, which we'll suppose is stored in the file C: - Dear {$title} {$lastname}, + Dear {$title} {$lastname}, - It has come to our attention that you are delinquent in your - {$monthname[$last_paid_month]} payment. Please remit - ${sprintf("%.2f", $amount)} immediately, or your patellae may - be needlessly endangered. + It has come to our attention that you are delinquent in your + {$monthname[$last_paid_month]} payment. Please remit + ${sprintf("%.2f", $amount)} immediately, or your patellae may + be needlessly endangered. - Love, - - Mark "Vizopteryx" Dominus + Love, + Mark "Vizopteryx" Dominus The result of filling in this template is a string, which might look something like this: - Dear Mr. Gates, + Dear Mr. Smith, - It has come to our attention that you are delinquent in your - February payment. Please remit - $392.12 immediately, or your patellae may - be needlessly endangered. + It has come to our attention that you are delinquent in your + February payment. Please remit + $392.12 immediately, or your patellae may + be needlessly endangered. - Love, + Love, - Mark "Vizopteryx" Dominus + Mark "Vizopteryx" Dominus Here is a complete program that transforms the example template into the example result, and prints it out: - use Text::Template; + use Text::Template; - my $template = Text::Template->new(SOURCE => 'formletter.tmpl') - or die "Couldn't construct template: $Text::Template::ERROR"; + my $template = Text::Template->new(SOURCE => 'formletter.tmpl') + or die "Couldn't construct template: $Text::Template::ERROR"; - my @monthname = qw(January February March April May June - July August September October November December); - my %vars = (title => 'Mr.', - firstname => 'Bill', - lastname => 'Gates', - last_paid_month => 1, # February - amount => 392.12, - monthname => \@monthname, - ); + my @monthname = qw(January February March April May June + July August September October November December); + my %vars = (title => 'Mr.', + firstname => 'John', + lastname => 'Smith', + last_paid_month => 1, # February + amount => 392.12, + monthname => \@monthname); - my $result = $template->fill_in(HASH => \%vars); - - if (defined $result) { print $result } - else { die "Couldn't fill in template: $Text::Template::ERROR" } + my $result = $template->fill_in(HASH => \%vars); + if (defined $result) { print $result } + else { die "Couldn't fill in template: $Text::Template::ERROR" } =head2 Philosophy @@ -654,18 +778,18 @@ A backslash C<\> in front of a brace (or another backslash that is in front of a brace) escapes its special meaning. The result of filling out this template: - \{ The sum of 1 and 2 is {1+2} \} + \{ The sum of 1 and 2 is {1+2} \} is - { The sum of 1 and 2 is 3 } + { The sum of 1 and 2 is 3 } If you have an unmatched brace, C will return a failure code and a warning about where the problem is. Backslashes that do not precede a brace are passed through unchanged. If you have a template like this: - { "String that ends in a newline.\n" } + { "String that ends in a newline.\n" } The backslash inside the string is passed through to Perl unchanged, so the C<\n> really does turn into a newline. See the note at the end @@ -675,37 +799,37 @@ C option. (See L<"Alternative Delimiters">, below.) Each program fragment should be a sequence of Perl statements, which are evaluated the usual way. The result of the last statement -executed will be evaluted in scalar context; the result of this +executed will be evaluated in scalar context; the result of this statement is a string, which is interpolated into the template in place of the program fragment itself. The fragments are evaluated in order, and side effects from earlier fragments will persist into later fragments: - {$x = @things; ''}The Lord High Chamberlain has gotten {$x} - things for me this year. - { $diff = $x - 17; - $more = 'more' - if ($diff == 0) { - $diff = 'no'; - } elsif ($diff < 0) { - $more = 'fewer'; - } - ''; - } - That is {$diff} {$more} than he gave me last year. + {$x = @things; ''}The Lord High Chamberlain has gotten {$x} + things for me this year. + { $diff = $x - 17; + $more = 'more' + if ($diff == 0) { + $diff = 'no'; + } elsif ($diff < 0) { + $more = 'fewer'; + } + ''; + } + That is {$diff} {$more} than he gave me last year. The value of C<$x> set in the first line will persist into the next fragment that begins on the third line, and the values of C<$diff> and C<$more> set in the second fragment will persist and be interpolated into the last line. The output will look something like this: - The Lord High Chamberlain has gotten 42 - things for me this year. + The Lord High Chamberlain has gotten 42 + things for me this year. - That is 25 more than he gave me last year. + That is 25 more than he gave me last year. -That is all the syntax there is. +That is all the syntax there is. =head2 The C<$OUT> variable @@ -714,21 +838,21 @@ motivation for it: Suppose you are going to pass an array, C<@items>, into the template, and you want the template to generate a bulleted list with a header, like this: - Here is a list of the things I have got for you since 1907: - * Ivory - * Apes - * Peacocks - * ... + Here is a list of the things I have got for you since 1907: + * Ivory + * Apes + * Peacocks + * ... One way to do it is with a template like this: - Here is a list of the things I have got for you since 1907: - { my $blist = ''; - foreach $i (@items) { - $blist .= qq{ * $i\n}; - } - $blist; - } + Here is a list of the things I have got for you since 1907: + { my $blist = ''; + foreach $i (@items) { + $blist .= qq{ * $i\n}; + } + $blist; + } Here we construct the list in a variable called C<$blist>, which we return at the end. This is a little cumbersome. There is a shortcut. @@ -740,11 +864,11 @@ behavior, of replacing the fragment with its return value, is disabled; instead the fragment is replaced with the value of C<$OUT>. This means that you can write the template above like this: - Here is a list of the things I have got for you since 1907: - { foreach $i (@items) { - $OUT .= " * $i\n"; - } - } + Here is a list of the things I have got for you since 1907: + { foreach $i (@items) { + $OUT .= " * $i\n"; + } + } C<$OUT> is reinitialized to the empty string at the start of each program fragment. It is private to C, so @@ -758,11 +882,11 @@ variable C<$Text::Template::ERROR> to contain an explanation of what went wrong. For example, if you try to create a template from a file that does not exist, C<$Text::Template::ERROR> will contain something like: - Couldn't open file xyz.tmpl: No such file or directory + Couldn't open file xyz.tmpl: No such file or directory =head2 C - $template = new Text::Template ( TYPE => ..., SOURCE => ... ); + $template = Text::Template->new( TYPE => ..., SOURCE => ... ); This creates and returns a new template object. C returns C and sets C<$Text::Template::ERROR> if it can't create the @@ -771,7 +895,7 @@ come from. C says what kind of object the source is. The most common type of source is a file: - new Text::Template ( TYPE => 'FILE', SOURCE => $filename ); + Text::Template->new( TYPE => 'FILE', SOURCE => $filename ); This reads the template from the specified file. The filename is opened with the Perl C command, so it can be a pipe or anything @@ -780,18 +904,18 @@ else that makes sense with C. The C can also be C, in which case the C should be a string: - new Text::Template ( TYPE => 'STRING', - SOURCE => "This is the actual template!" ); + Text::Template->new( TYPE => 'STRING', + SOURCE => "This is the actual template!" ); The C can be C, in which case the source should be a reference to an array of strings. The concatenation of these strings is the template: - new Text::Template ( TYPE => 'ARRAY', - SOURCE => [ "This is ", "the actual", + Text::Template->new( TYPE => 'ARRAY', + SOURCE => [ "This is ", "the actual", " template!", ] - ); + ); The C can be FILEHANDLE, in which case the source should be an open filehandle (such as you got from the C or C @@ -799,22 +923,21 @@ packages, or a glob, or a reference to a glob). In this case C will read the text from the filehandle up to end-of-file, and that text is the template: - # Read template source code from STDIN: - new Text::Template ( TYPE => 'FILEHANDLE', - SOURCE => \*STDIN ); - + # Read template source code from STDIN: + Text::Template->new ( TYPE => 'FILEHANDLE', + SOURCE => \*STDIN ); If you omit the C attribute, it's taken to be C. C is required. If you omit it, the program will abort. The words C and C can be spelled any of the following ways: - TYPE SOURCE - Type Source - type source - -TYPE -SOURCE - -Type -Source - -type -source + TYPE SOURCE + Type Source + type source + -TYPE -SOURCE + -Type -Source + -type -source Pick a style you like and stick with it. @@ -828,6 +951,18 @@ string is the string that signals the beginning of each program fragment, and the second string is the string that signals the end of each program fragment. See L<"Alternative Delimiters">, below. +=item C + +You may also add a C option. If this option is present, and the +C is a C, then the data will be decoded from the given encoding +using the L module. You can use any encoding that L recognizes. +E.g.: + + Text::Template->new( + TYPE => 'FILE', + ENCODING => 'UTF-8', + SOURCE => 'xyz.tmpl'); + =item C If your program is running in taint mode, you may have problems if @@ -865,7 +1000,7 @@ overridden in the arguments to C. See L> below. =head2 C - $template->compile() + $template->compile() Loads all the template text from the template's source, parses and compiles it. If successful, returns true; otherwise returns false and @@ -881,7 +1016,7 @@ Delimiters">, below. =head2 C - $template->fill_in(OPTIONS); + $template->fill_in(OPTIONS); Fills in a template. Returns the resulting text if successful. Otherwise, returns C and sets C<$Text::Template::ERROR>. @@ -891,17 +1026,17 @@ write the key names in any of the six usual styles as above; this means that where this manual says C (for example) you can actually use any of - PACKAGE Package package -PACKAGE -Package -package + PACKAGE Package package -PACKAGE -Package -package Pick a style you like and stick with it. The all-lowercase versions may yield spurious warnings about - Ambiguous use of package => resolved to "package" + Ambiguous use of package => resolved to "package" so you might like to avoid them and use the capitalized versions. At present, there are eight legal options: C, C, -C, C, C, C, and C. +C, C, C, C, C, and C. =over 4 @@ -911,7 +1046,7 @@ C specifies the name of a package in which the program fragments should be evaluated. The default is to use the package from which C was called. For example, consider this template: - The value of the variable x is {$x}. + The value of the variable x is {$x}. If you use C<$template-Efill_in(PACKAGE =E 'R')> , then the C<$x> in the template is actually replaced with the value of C<$R::x>. If you @@ -927,26 +1062,25 @@ See the section at the end on `Security'. Here's an example of using C: - Your Royal Highness, + Your Royal Highness, - Enclosed please find a list of things I have gotten - for you since 1907: + Enclosed please find a list of things I have gotten + for you since 1907: - { foreach $item (@items) { + { foreach $item (@items) { $item_no++; - $OUT .= " $item_no. \u$item\n"; - } - } + $OUT .= " $item_no. \u$item\n"; + } + } - Signed, - Lord High Chamberlain + Signed, + Lord High Chamberlain We want to pass in an array which will be assigned to the array C<@items>. Here's how to do that: - - @items = ('ivory', 'apes', 'peacocks', ); - $template->fill_in(); + @items = ('ivory', 'apes', 'peacocks', ); + $template->fill_in(); This is not very safe. The reason this isn't as safe is that if you had a variable named C<$item_no> in scope in your program at the point @@ -963,8 +1097,8 @@ are safe. But if you use the C option, you will probably be safe even if the template does I declare its variables with C: - @Q::items = ('ivory', 'apes', 'peacocks', ); - $template->fill_in(PACKAGE => 'Q'); + @Q::items = ('ivory', 'apes', 'peacocks', ); + $template->fill_in(PACKAGE => 'Q'); In this case the template will clobber the variable C<$Q::item_no>, which is not related to the one your program was using. @@ -982,10 +1116,13 @@ C provides an alternative. The value for C should be a reference to a hash that maps variable names to values. For example, - $template->fill_in(HASH => { recipient => "The King", - items => ['gold', 'frankincense', 'myrrh'], - object => \$self, - }); + $template->fill_in( + HASH => { + recipient => "The King", + items => ['gold', 'frankincense', 'myrrh'], + object => \$self, + } + ); will fill out the template and use C<"The King"> as the value of C<$recipient> and the list of items as the value of C<@items>. Note @@ -1024,11 +1161,11 @@ that array. If the I is a reference to a hash, then C<%key> is set to that hash. Similarly if I is any other kind of reference. This means that - var => "foo" + var => "foo" and - var => \"foo" + var => \"foo" have almost exactly the same effect. (The difference is that in the former case, the value is copied, and in the latter case it is @@ -1039,7 +1176,7 @@ aliased.) In particular, if you want the template to get an object or any kind, you must pass a reference to it: - $template->fill_in(HASH => { database_handle => \$dbh, ... }); + $template->fill_in(HASH => { database_handle => \$dbh, ... }); If you do this, the template will have a variable C<$database_handle> which is the database handle object. If you leave out the C<\>, the @@ -1065,16 +1202,18 @@ of variables. For example, one set of variables might be the defaults for a fill-in form, and the second set might be the user inputs, which override the defaults when they are present: - $template->fill_in(HASH => [\%defaults, \%user_input]); + $template->fill_in(HASH => [\%defaults, \%user_input]); You can also use this to set two variables with the same name: - $template->fill_in(HASH => [{ v => "The King" }, - { v => [1,2,3] }, - ] - ); + $template->fill_in( + HASH => [ + { v => "The King" }, + { v => [1,2,3] } + ] + ); -This sets C<$v> to C<"The King"> and C<@v> to C<(1,2,3)>. +This sets C<$v> to C<"The King"> and C<@v> to C<(1,2,3)>. =item C @@ -1100,19 +1239,19 @@ fragment that cased the error. If you don't specify a C function, C supplies a default one that returns something like - Program fragment delivered error ``Illegal division by 0 at - template line 37'' + Program fragment delivered error ``Illegal division by 0 at + template line 37'' (Note that the format of this message has changed slightly since version 1.31.) The return value of the C function is interpolated into the template at the place the error occurred, so that this template: - (3+4)*5 = { 3+4)*5 } + (3+4)*5 = { 3+4)*5 } yields this result: - (3+4)*5 = Program fragment delivered error ``syntax error at template line 1'' + (3+4)*5 = Program fragment delivered error ``syntax error at template line 1'' If you specify a value for the C attribute, it should be a reference to a function that C can call instead of the @@ -1156,23 +1295,24 @@ The C function could also use the C as a reference to store an error message or some other information that it wants to communicate back to the caller. For example: - $error = ''; + $error = ''; - sub my_broken { - my %args = @_; - my $err_ref = $args{arg}; - ... - $$err_ref = "Some error message"; - return undef; - } + sub my_broken { + my %args = @_; + my $err_ref = $args{arg}; + ... + $$err_ref = "Some error message"; + return undef; + } - $template->fill_in(BROKEN => \&my_broken, - BROKEN_ARG => \$error, - ); + $template->fill_in( + BROKEN => \&my_broken, + BROKEN_ARG => \$error + ); - if ($error) { - die "It didn't work: $error"; - } + if ($error) { + die "It didn't work: $error"; + } If one of the program fragments in the template fails, it will call the C function, C, and pass it the C, @@ -1181,6 +1321,29 @@ message into C<$error> this way. Then the function that called C can see if C has left an error message for it to find, and proceed accordingly. +=item C + +If you give C a C option, then this is the file name that +you loaded the template source from. This only affects the error message that +is given for template errors. If you loaded the template from C for +example, and pass C as the C parameter, errors will look +like C<... at foo.txt line N> rather than C<... at template line N>. + +Note that this does NOT have anything to do with loading a template from the +given filename. See C for that. + +For example: + + my $template = Text::Template->new( + TYPE => 'string', + SOURCE => 'The value is {1/0}'); + + $template->fill_in(FILENAME => 'foo.txt') or die $Text::Template::ERROR; + +will die with an error that contains + + Illegal division by zero at at foo.txt line 1 + =item C If you give C a C option, its value should be a safe @@ -1213,7 +1376,7 @@ the C option to C, the value should be a filehandle. The generated text will be printed to this filehandle as it is constructed. For example: - $template->fill_in(OUTPUT => \*STDOUT, ...); + $template->fill_in(OUTPUT => \*STDOUT, ...); fills in the C<$template> as usual, but the results are immediately printed to STDOUT. This may result in the output appearing more @@ -1260,17 +1423,17 @@ any results. An example: - $Q::name = 'Donald'; - $Q::amount = 141.61; - $Q::part = 'hyoid bone'; + $Q::name = 'Donald'; + $Q::amount = 141.61; + $Q::part = 'hyoid bone'; - $text = Text::Template->fill_this_in( <<'EOM', PACKAGE => Q); - Dear {$name}, - You owe me \\${sprintf('%.2f', $amount)}. - Pay or I will break your {$part}. - Love, - Grand Vizopteryx of Irkutsk. - EOM + $text = Text::Template->fill_this_in( <<'EOM', PACKAGE => Q); + Dear {$name}, + You owe me \\${sprintf('%.2f', $amount)}. + Pay or I will break your {$part}. + Love, + Grand Vizopteryx of Irkutsk. + EOM Notice how we included the template in-line in the program by using a `here document' with the CE> notation. @@ -1290,14 +1453,14 @@ four years ago and it is too late to change it. C is exactly like C except that it is not a method and you can omit the C> and just say - print fill_in_string(<<'EOM', ...); - Dear {$name}, - ... - EOM + print fill_in_string(<<'EOM', ...); + Dear {$name}, + ... + EOM To use C, you need to say - use Text::Template 'fill_in_string'; + use Text::Template 'fill_in_string'; at the top of your program. You should probably use C instead of C. @@ -1306,7 +1469,7 @@ C instead of C. If you import C, you can say - $text = fill_in_file(filename, ...); + $text = fill_in_file(filename, ...); The C<...> are passed to C as above. The filename is the name of the file that contains the template you want to fill in. It @@ -1323,7 +1486,7 @@ People always ask for this. ``Why don't you have an include function?'' they want to know. The short answer is this is Perl, and Perl already has an include function. If you want it, you can just put - {qx{cat filename}} + {qx{cat filename}} into your template. VoilE. @@ -1331,19 +1494,19 @@ If you don't want to use C, you can write a little four-line function that opens a file and dumps out its contents, and call it from the template. I wrote one for you. In the template, you can say - {Text::Template::_load_text(filename)} + {Text::Template::_load_text(filename)} If that is too verbose, here is a trick. Suppose the template package that you are going to be mentioning in the C call is package C. Then in the main program, write - *Q::include = \&Text::Template::_load_text; + *Q::include = \&Text::Template::_load_text; This imports the C<_load_text> function into package C with the name C. From then on, any template that you fill in with package C can say - {include(filename)} + {include(filename)} to insert the text from the named file at that point. If you are using the C option instead, just put C @@ -1354,7 +1517,7 @@ Suppose you don't want to insert a plain text file, but rather you want to include one template within another? Just use C in the template itself: - {Text::Template::fill_in_file(filename)} + {Text::Template::fill_in_file(filename)} You can do the same importing trick if this is too much to type. @@ -1364,8 +1527,8 @@ You can do the same importing trick if this is too much to type. People are frequently surprised when this doesn't work: - my $recipient = 'The King'; - my $text = fill_in_file('formletter.tmpl'); + my $recipient = 'The King'; + my $text = fill_in_file('formletter.tmpl'); The text C doesn't get into the form letter. Why not? Because C<$recipient> is a C variable, and the whole point of @@ -1378,13 +1541,12 @@ private variable, and in this case you don't want the variable to be private. Put the variables into package variables in some other package, and use the C option to C: - $Q::recipient = $recipient; - my $text = fill_in_file('formletter.tmpl', PACKAGE => 'Q'); - + $Q::recipient = $recipient; + my $text = fill_in_file('formletter.tmpl', PACKAGE => 'Q'); or pass the names and values in a hash with the C option: - my $text = fill_in_file('formletter.tmpl', HASH => { recipient => $recipient }); + my $text = fill_in_file('formletter.tmpl', HASH => { recipient => $recipient }); =head2 Security Matters @@ -1397,19 +1559,19 @@ rest of your program and wreck something. Nevertheless, there's really no way (except with C) to protect against a template that says - { $Important::Secret::Security::Enable = 0; - # Disable security checks in this program - } + { $Important::Secret::Security::Enable = 0; + # Disable security checks in this program + } or - { $/ = "ho ho ho"; # Sabotage future uses of . - # $/ is always a global variable - } + { $/ = "ho ho ho"; # Sabotage future uses of . + # $/ is always a global variable + } or even - { system("rm -rf /") } + { system("rm -rf /") } so B go filling in templates unless you're sure you know what's in them. If you're worried, or you can't trust the person who wrote @@ -1437,7 +1599,7 @@ an alternative set of delimiters with the C option. For example, if you would like code fragments to be delimited by C<[@--> and C<--@]> instead of C<{> and C<}>, use - ... DELIMITERS => [ '[@--', '--@]' ], ... + ... DELIMITERS => [ '[@--', '--@]' ], ... Note that these delimiters are I, not regexes. (I tried for regexes, but it complicates the lexical analysis too much.) @@ -1450,16 +1612,16 @@ as they nest properly. This means that if for some reason you absolutely must have a program fragment that mentions one of the delimiters, like this: - [@-- - print "Oh no, a delimiter: --@]\n" - --@] + [@-- + print "Oh no, a delimiter: --@]\n" + --@] you may be able to make it work by doing this instead: - [@-- - # Fake matching delimiter in a comment: [@-- - print "Oh no, a delimiter: --@]\n" - --@] + [@-- + # Fake matching delimiter in a comment: [@-- + print "Oh no, a delimiter: --@]\n" + --@] It may be safer to choose delimiters that begin with a newline character. @@ -1476,22 +1638,22 @@ undeclared variables and the like. But each code fragment is a separate lexical scope, so you have to turn on C at the top of each and every code fragment: - { use strict; - use vars '$foo'; - $foo = 14; - ... - } + { use strict; + use vars '$foo'; + $foo = 14; + ... + } - ... + ... - { # we forgot to put `use strict' here - my $result = $boo + 12; # $boo is misspelled and should be $foo - # No error is raised on `$boo' - } + { # we forgot to put `use strict' here + my $result = $boo + 12; # $boo is misspelled and should be $foo + # No error is raised on `$boo' + } Because we didn't put C at the top of the second fragment, it was only active in the first fragment, and we didn't get any -C checking in the second fragment. Then we mispelled C<$foo> +C checking in the second fragment. Then we misspelled C<$foo> and the error wasn't caught. C version 1.22 and higher has a new feature to make @@ -1500,44 +1662,71 @@ added to the beginning of each program fragment. When you make a call to C, you can specify a - PREPEND => 'some perl statements here' + PREPEND => 'some perl statements here' option; the statements will be prepended to each program fragment for that one call only. Suppose that the C call included a - PREPEND => 'use strict;' + PREPEND => 'use strict;' option, and that the template looked like this: - { use vars '$foo'; - $foo = 14; - ... - } + { use vars '$foo'; + $foo = 14; + ... + } - ... + ... - { my $result = $boo + 12; # $boo is misspelled and should be $foo - ... - } + { my $result = $boo + 12; # $boo is misspelled and should be $foo + ... + } The code in the second fragment would fail, because C<$boo> has not been declared. C was implied, even though you did not write it explicitly, because the C option added it for you automatically. -There are two other ways to do this. At the time you create the +There are three other ways to do this. At the time you create the template object with C, you can also supply a C option, in which case the statements will be prepended each time you fill in that template. If the C call has its own C option, this overrides the one specified at the time you created the template. Finally, you can make the class method call - Text::Template->always_prepend('perl statements'); + Text::Template->always_prepend('perl statements'); If you do this, then call calls to C for I template will attach the perl statements to the beginning of each program fragment, except where overridden by C options to C or C. +An alternative to adding "use strict;" to the PREPEND option, you can +pass STRICT => 1 to fill_in when also passing the HASH option. + +Suppose that the C call included both + + HASH => {$foo => ''} and + STRICT => 1 + +options, and that the template looked like this: + + { + $foo = 14; + ... + } + + ... + + { my $result = $boo + 12; # $boo is misspelled and should be $foo + ... + } + +The code in the second fragment would fail, because C<$boo> has not +been declared. C was implied, even though you did not +write it explicitly, because the C option added it for you +automatically. Any variable referenced in the template that is not in the +C option will be an error. + =head2 Prepending in Derived Classes This section is technical, and you should skip it on the first few @@ -1553,7 +1742,7 @@ first one that it finds. In a subclass of C, this last possibility is ambiguous. Suppose C is a subclass of C. Should - Text::Template->always_prepend(...); + Text::Template->always_prepend(...); affect objects in class C? The answer is that you can have it either way. @@ -1567,11 +1756,11 @@ which the template object belongs. If it doesn't find any value, it looks in C<$GLOBAL_PREPEND{'Text::Template'}>. This means that objects in class C I be affected by - Text::Template->always_prepend(...); + Text::Template->always_prepend(...); I there is also a call to - Derived->always_prepend(...); + Derived->always_prepend(...); So when you're designing your derived class, you can arrange to have your objects ignore C calls by simply @@ -1586,8 +1775,8 @@ method to get an arbitrary effect. Jennifer D. St Clair asks: - > Most of my pages contain JavaScript and Stylesheets. - > How do I change the template identifier? + > Most of my pages contain JavaScript and Stylesheets. + > How do I change the template identifier? Jennifer is worried about the braces in the JavaScript being taken as the delimiters of the Perl program fragments. Of course, disaster @@ -1600,61 +1789,60 @@ some reason, there are two easy workarounds: 1. You can put C<\> in front of C<{>, C<}>, or C<\> to remove its special meaning. So, for example, instead of - if (br== "n3") { - // etc. - } + if (br== "n3") { + // etc. + } you can put - if (br== "n3") \{ - // etc. - \} + if (br== "n3") \{ + // etc. + \} and it'll come out of the template engine the way you want. But here is another method that is probably better. To see how it works, first consider what happens if you put this into a template: - { 'foo' } + { 'foo' } Since it's in braces, it gets evaluated, and obviously, this is going to turn into - foo + foo So now here's the trick: In Perl, C is the same as C<'...'>. So if we wrote - {q{foo}} + {q{foo}} it would turn into - foo + foo So for your JavaScript, just write - {q{if (br== "n3") { - // etc. - }} - } + {q{if (br== "n3") { + // etc. + }} + } and it'll come out as - if (br== "n3") { - // etc. - } + if (br== "n3") { + // etc. + } which is what you want. - -=head2 Shut Up! +head2 Shut Up! People sometimes try to put an initialization section at the top of their templates, like this: - { ... - $var = 17; - } + { ... + $var = 17; + } Then they complain because there is a C<17> at the top of the output that they didn't want to have there. @@ -1667,18 +1855,18 @@ and have the recipient filled in. To prevent the 17 from appearing in the output is very simple: - { ... - $var = 17; - ''; - } + { ... + $var = 17; + ''; + } Now the last expression evaluated yields the empty string, which is invisible. If you don't like the way this looks, use - { ... - $var = 17; - ($SILENTLY); - } + { ... + $var = 17; + ($SILENTLY); + } instead. Presumably, C<$SILENTLY> has no value, so nothing will be interpolated. This is what is known as a `trick'. @@ -1727,29 +1915,28 @@ C<\}> signal a literal brace. Examples: - \{ foo \} + \{ foo \} is I evaluated, because the C<\> before the braces signals that they should be taken literally. The result in the output looks like this: - { foo } - + { foo } This is a syntax error: - { "foo}" } + { "foo}" } because C thinks that the code ends at the first C<}>, and then gets upset when it sees the second one. To make this work correctly, use - { "foo\}" } + { "foo\}" } This passes C<"foo}"> to Perl for evaluation. Note there's no C<\> in the evaluated code. If you really want a C<\> in the evaluated code, use - { "foo\\\}" } + { "foo\\\}" } This passes C<"foo\}"> to Perl for evaluation. @@ -1769,20 +1956,20 @@ If it really, really bothers you, you can import a function called C that returns the current value of the C<$ERROR> variable. So you can say: - use Text::Template 'TTerror'; + use Text::Template 'TTerror'; - my $template = new Text::Template (SOURCE => $filename); - unless ($template) { - my $err = TTerror; - die "Couldn't make template: $err; aborting"; - } + my $template = Text::Template->new(SOURCE => $filename); + unless ($template) { + my $err = TTerror; + die "Couldn't make template: $err; aborting"; + } I don't see what benefit this has over just doing this: - use Text::Template; + use Text::Template; - my $template = new Text::Template (SOURCE => $filename) - or die "Couldn't make template: $Text::Template::ERROR; aborting"; + my $template = Text::Template->new(SOURCE => $filename) + or die "Couldn't make template: $Text::Template::ERROR; aborting"; But if it makes you happy to do it that way, go ahead. @@ -1796,12 +1983,12 @@ into their template output. It's totally straightforward. Just call the C functions from inside the template: - { $q->checkbox_group(NAME => 'toppings', - LINEBREAK => true, - COLUMNS => 3, - VALUES => \@toppings, - ); - } + { $q->checkbox_group(NAME => 'toppings', + LINEBREAK => true, + COLUMNS => 3, + VALUES => \@toppings, + ); + } =head2 Automatic preprocessing of program fragments @@ -1819,124 +2006,302 @@ method. It is passed a list of pairs with these entries: text - the text that will be appended type - where the text came from: TEXT for literal text, PROG for code -=head2 Author +=head1 HISTORY -Mark Jason Dominus, Plover Systems - -Please send questions and other remarks about this software to -C - -You can join a very low-volume (E10 messages per year) mailing -list for announcements about this package. Send an empty note to -C to join. - -For updates, visit C. - -=head2 Support? - -This software is version 1.46. It may have bugs. Suggestions and bug -reports are always welcome. Send them to -C. (That is my address, not the address -of the mailing list. The mailing list address is a secret.) - -=head1 LICENSE - - Text::Template version 1.46 - Copyright 2013 Mark Jason Dominus - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. You may also can - redistribute it and/or modify it under the terms of the Perl - Artistic License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received copies of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Originally written by Mark Jason Dominus, Plover Systems (versions 0.01 - 1.46) +Maintainership transferred to Michael Schout Emschout@cpan.orgE in version +1.47 =head1 THANKS Many thanks to the following people for offering support, encouragement, advice, bug reports, and all the other good stuff. -David H. Adler / -Joel Appelbaum / -Klaus Arnhold / -AntEnio AragEo / -Kevin Atteson / -Chris.Brezil / -Mike Brodhead / -Tom Brown / -Dr. Frank Bucolo / -Tim Bunce / -Juan E. Camacho / -Itamar Almeida de Carvalho / -Joseph Cheek / -Gene Damon / -San Deng / -Bob Dougherty / -Marek Grac / -Dan Franklin / -gary at dls.net / -Todd A. Green / -Donald L. Greer Jr. / -Michelangelo Grigni / -Zac Hansen / -Tom Henry / -Jarko Hietaniemi / -Matt X. Hunter / -Robert M. Ioffe / -Daniel LaLiberte / -Reuven M. Lerner / -Trip Lilley / -Yannis Livassof / -Val Luck / -Kevin Madsen / -David Marshall / -James Mastros / -Joel Meulenberg / -Jason Moore / -Sergey Myasnikov / -Chris Nandor / -Bek Oberin / -Steve Palincsar / -Ron Pero / -Hans Persson / -Sean Roehnelt / -Jonathan Roy / -Shabbir J. Safdar / -Jennifer D. St Clair / -Uwe Schneider / -Randal L. Schwartz / -Michael G Schwern / -Yonat Sharon / -Brian C. Shensky / -Niklas Skoglund / -Tom Snee / -Fred Steinberg / -Hans Stoop / -Michael J. Suzio / -Dennis Taylor / -James H. Thompson / -Shad Todd / -Lieven Tomme / -Lorenzo Valdettaro / -Larry Virden / -Andy Wardley / -Archie Warnock / -Chris Wesley / -Matt Womer / -Andrew G Wood / -Daini Xie / +=over 4 + +=item * + +Andrew G Wood + +=item * + +Andy Wardley + +=item * + +António Aragão + +=item * + +Archie Warnock + +=item * + +Bek Oberin + +=item * + +Bob Dougherty + +=item * + +Brian C. Shensky + +=item * + +Chris Nandor + +=item * + +Chris Wesley + +=item * + +Chris.Brezil + +=item * + +Daini Xie + +=item * + +Dan Franklin + +=item * + +Daniel LaLiberte + +=item * + +David H. Adler + +=item * + +David Marshall + +=item * + +Dennis Taylor + +=item * + +Donald L. Greer Jr. + +=item * + +Dr. Frank Bucolo + +=item * + +Fred Steinberg + +=item * + +Gene Damon + +=item * + +Hans Persson + +=item * + +Hans Stoop + +=item * + +Itamar Almeida de Carvalho + +=item * + +James H. Thompson + +=item * + +James Mastros + +=item * + +Jarko Hietaniemi + +=item * + +Jason Moore + +=item * + +Jennifer D. St Clair + +=item * + +Joel Appelbaum + +=item * + +Joel Meulenberg + +=item * + +Jonathan Roy + +=item * + +Joseph Cheek + +=item * + +Juan E. Camacho + +=item * + +Kevin Atteson + +=item * + +Kevin Madsen + +=item * + +Klaus Arnhold + +=item * + +Larry Virden + +=item * + +Lieven Tomme + +=item * + +Lorenzo Valdettaro + +=item * + +Marek Grac + +=item * + +Matt Womer + +=item * + +Matt X. Hunter + +=item * + +Michael G Schwern + +=item * + +Michael J. Suzio + +=item * + Michaely Yeung +=item * + +Michelangelo Grigni + +=item * + +Mike Brodhead + +=item * + +Niklas Skoglund + +=item * + +Randal L. Schwartz + +=item * + +Reuven M. Lerner + +=item * + +Robert M. Ioffe + +=item * + +Ron Pero + +=item * + +San Deng + +=item * + +Sean Roehnelt + +=item * + +Sergey Myasnikov + +=item * + +Shabbir J. Safdar + +=item * + +Shad Todd + +=item * + +Steve Palincsar + +=item * + +Tim Bunce + +=item * + +Todd A. Green + +=item * + +Tom Brown + +=item * + +Tom Henry + +=item * + +Tom Snee + +=item * + +Trip Lilley + +=item * + +Uwe Schneider + +=item * + +Val Luck + +=item * + +Yannis Livassof + +=item * + +Yonat Sharon + +=item * + +Zac Hansen + +=item * + +gary at dls.net + +=back + Special thanks to: =over 2 @@ -1970,4 +2335,29 @@ use it as if it were a regular variable. There are not quite enough tests in the test suite. +=head1 SOURCE + +The development version is on github at L +and may be cloned from L + +=head1 BUGS + +Please report any bugs or feature requests on the bugtracker website +L + +When submitting a bug or request, please include a test-file or a +patch to an existing test-file that illustrates the bug or desired +feature. + +=head1 AUTHOR + +Michael Schout + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2013 by Mark Jason Dominus . + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + =cut diff --git a/external/perl/Text-Template-1.46/lib/Text/Template/Preprocess.pm b/external/perl/Text-Template-1.56/lib/Text/Template/Preprocess.pm similarity index 64% rename from external/perl/Text-Template-1.46/lib/Text/Template/Preprocess.pm rename to external/perl/Text-Template-1.56/lib/Text/Template/Preprocess.pm index 1e41037b..4fea67b3 100644 --- a/external/perl/Text-Template-1.46/lib/Text/Template/Preprocess.pm +++ b/external/perl/Text-Template-1.56/lib/Text/Template/Preprocess.pm @@ -1,40 +1,59 @@ package Text::Template::Preprocess; +$Text::Template::Preprocess::VERSION = '1.56'; +# ABSTRACT: Expand template text with embedded Perl + +use strict; +use warnings; + use Text::Template; -@ISA = qw(Text::Template); -$Text::Template::Preprocess::VERSION = 1.46; +our @ISA = qw(Text::Template); sub fill_in { - my $self = shift; - my (%args) = @_; - my $pp = $args{PREPROCESSOR} || $self->{PREPROCESSOR} ; - if ($pp) { - local $_ = $self->source(); -# print "# fill_in: before <$_>\n"; - &$pp; -# print "# fill_in: after <$_>\n"; - $self->set_source_data($_); - } - $self->SUPER::fill_in(@_); + my $self = shift; + my (%args) = @_; + + my $pp = $args{PREPROCESSOR} || $self->{PREPROCESSOR}; + + if ($pp) { + local $_ = $self->source(); + my $type = $self->{TYPE}; + + # print "# fill_in: before <$_>\n"; + &$pp; + + # print "# fill_in: after <$_>\n"; + $self->set_source_data($_, $type); + } + + $self->SUPER::fill_in(@_); } sub preprocessor { - my ($self, $pp) = @_; - my $old_pp = $self->{PREPROCESSOR}; - $self->{PREPROCESSOR} = $pp if @_ > 1; # OK to pass $pp=undef - $old_pp; + my ($self, $pp) = @_; + + my $old_pp = $self->{PREPROCESSOR}; + + $self->{PREPROCESSOR} = $pp if @_ > 1; # OK to pass $pp=undef + + $old_pp; } 1; +__END__ -=head1 NAME +=pod + +=encoding UTF-8 + +=head1 NAME Text::Template::Preprocess - Expand template text with embedded Perl =head1 VERSION -This file documents C version B<1.46> +version 1.56 =head1 SYNOPSIS @@ -78,7 +97,6 @@ C. One possible purpose: If your files contain a lot of JavaScript, like this: - Plain text here... { perl code }