Latest update.
This commit is contained in:
@@ -9,6 +9,12 @@
|
||||
|
||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||
|
||||
*) Change the default RSA, DSA and DH size to 2048 bit instead of 1024.
|
||||
This changes the size when using the genpkey app when no size is given. It
|
||||
fixes an omission in earlier changes that changed all RSA, DSA and DH
|
||||
generation apps to use 2048 bits by default.
|
||||
[Kurt Roeckx]
|
||||
|
||||
*) Added command 'openssl kdf' that uses the EVP_KDF API.
|
||||
[Shane Lontis]
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ require platform::BASE;
|
||||
use configdata;
|
||||
|
||||
sub binext { $target{exe_extension} || '' }
|
||||
sub dsoext { $target{dso_extension} || '.so' }
|
||||
sub dsoext { $target{dso_extension} || platform->shlibextsimple()
|
||||
|| '.so' }
|
||||
# Because these are also used in scripts and not just Makefile, we must
|
||||
# convert $(SHLIB_VERSION_NUMBER) to the actual number.
|
||||
sub shlibext { (my $x = $target{shared_extension}
|
||||
|
||||
@@ -33,9 +33,10 @@ my %shared_info;
|
||||
%{$shared_info{'gnu-shared'}},
|
||||
shared_defflag => '-Wl,--version-script=',
|
||||
dso_ldflags =>
|
||||
$disabled{asan} && $disabled{msan} && $disabled{ubsan}
|
||||
? '-z defs'
|
||||
: '',
|
||||
(grep /(?:^|\s)-fsanitize/,
|
||||
@{$config{CFLAGS}}, @{$config{cflags}})
|
||||
? ''
|
||||
: '-z defs',
|
||||
};
|
||||
},
|
||||
'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
|
||||
|
||||
@@ -206,6 +206,7 @@ AS={- $config{AS} -}
|
||||
ASFLAGS={- join(' ', @{$config{ASFLAGS}}) -}
|
||||
|
||||
RC={- $config{RC} -}
|
||||
RCFLAGS={- join(' ', @{$config{RCFLAGS}}) -}
|
||||
|
||||
ECHO="$(PERL)" "$(SRCDIR)\util\echo.pl"
|
||||
|
||||
@@ -630,7 +631,7 @@ EOF
|
||||
my $res = platform->res($args{obj});
|
||||
return <<"EOF";
|
||||
$res: $deps
|
||||
\$(RC) \$(RCOUTFLAG)\$\@ $srcs
|
||||
\$(RC) \$(RCFLAGS) \$(RCOUTFLAG)\$\@ $srcs
|
||||
EOF
|
||||
}
|
||||
my $obj = platform->obj($args{obj});
|
||||
|
||||
@@ -345,9 +345,9 @@ my @disablables = (
|
||||
"cast",
|
||||
"chacha",
|
||||
"cmac",
|
||||
"cmp",
|
||||
"cms",
|
||||
"comp",
|
||||
"crmf",
|
||||
"crypto-mdebug",
|
||||
"crypto-mdebug-backtrace",
|
||||
"ct",
|
||||
@@ -433,6 +433,14 @@ foreach my $proto ((@tls, @dtls))
|
||||
push(@disablables, "$proto-method") unless $proto eq "tls1_3";
|
||||
}
|
||||
|
||||
# Internal disablables, for aliasing purposes. They serve no special
|
||||
# purpose here, but allow scripts to get to know them through configdata.pm,
|
||||
# where these are merged with @disablables.
|
||||
# The actual aliasing mechanism is done via %disable_cascades
|
||||
my @disablables_int = qw(
|
||||
crmf
|
||||
);
|
||||
|
||||
my %deprecated_disablables = (
|
||||
"ssl2" => undef,
|
||||
"buf-freelists" => undef,
|
||||
@@ -534,6 +542,8 @@ my @disable_cascades = (
|
||||
|
||||
sub { $disabled{cmac}; } => [ "siv" ],
|
||||
"legacy" => [ "md2" ],
|
||||
|
||||
"cmp" => [ "crmf" ],
|
||||
);
|
||||
|
||||
# Avoid protocol support holes. Also disable all versions below N, if version
|
||||
@@ -594,7 +604,7 @@ my %user = (
|
||||
PERL => env('PERL') || ($^O ne "VMS" ? $^X : "perl"),
|
||||
RANLIB => env('RANLIB'),
|
||||
RC => env('RC') || env('WINDRES'),
|
||||
RCFLAGS => [],
|
||||
RCFLAGS => [ env('RCFLAGS') || () ],
|
||||
RM => undef,
|
||||
);
|
||||
# Info about what "make variables" may be prefixed with the cross compiler
|
||||
@@ -611,6 +621,7 @@ my %useradd = (
|
||||
CXXFLAGS => [],
|
||||
LDFLAGS => [],
|
||||
LDLIBS => [],
|
||||
RCFLAGS => [],
|
||||
);
|
||||
|
||||
my %user_synonyms = (
|
||||
@@ -1110,44 +1121,6 @@ foreach (keys %target_attr_translate) {
|
||||
|
||||
%target = ( %{$table{DEFAULTS}}, %target );
|
||||
|
||||
# Make the flags to build DSOs the same as for shared libraries unless they
|
||||
# are already defined
|
||||
$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags};
|
||||
$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags};
|
||||
$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags};
|
||||
{
|
||||
my $shared_info_pl =
|
||||
catfile(dirname($0), "Configurations", "shared-info.pl");
|
||||
my %shared_info = read_eval_file($shared_info_pl);
|
||||
push @{$target{_conf_fname_int}}, $shared_info_pl;
|
||||
my $si = $target{shared_target};
|
||||
while (ref $si ne "HASH") {
|
||||
last if ! defined $si;
|
||||
if (ref $si eq "CODE") {
|
||||
$si = $si->();
|
||||
} else {
|
||||
$si = $shared_info{$si};
|
||||
}
|
||||
}
|
||||
|
||||
# Some of the 'shared_target' values don't have any entried in
|
||||
# %shared_info. That's perfectly fine, AS LONG AS the build file
|
||||
# template knows how to handle this. That is currently the case for
|
||||
# Windows and VMS.
|
||||
if (defined $si) {
|
||||
# Just as above, copy certain shared_* attributes to the corresponding
|
||||
# module_ attribute unless the latter is already defined
|
||||
$si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags};
|
||||
$si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags};
|
||||
$si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags};
|
||||
foreach (sort keys %$si) {
|
||||
$target{$_} = defined $target{$_}
|
||||
? add($si->{$_})->($target{$_})
|
||||
: $si->{$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
|
||||
$config{conf_files} = [ sort keys %conf_files ];
|
||||
|
||||
@@ -1687,7 +1660,48 @@ unless ($disabled{ktls}) {
|
||||
|
||||
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
|
||||
|
||||
# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
|
||||
# Get the extra flags used when building shared libraries and modules. We
|
||||
# do this late because some of them depend on %disabled.
|
||||
|
||||
# Make the flags to build DSOs the same as for shared libraries unless they
|
||||
# are already defined
|
||||
$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags};
|
||||
$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags};
|
||||
$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags};
|
||||
{
|
||||
my $shared_info_pl =
|
||||
catfile(dirname($0), "Configurations", "shared-info.pl");
|
||||
my %shared_info = read_eval_file($shared_info_pl);
|
||||
push @{$target{_conf_fname_int}}, $shared_info_pl;
|
||||
my $si = $target{shared_target};
|
||||
while (ref $si ne "HASH") {
|
||||
last if ! defined $si;
|
||||
if (ref $si eq "CODE") {
|
||||
$si = $si->();
|
||||
} else {
|
||||
$si = $shared_info{$si};
|
||||
}
|
||||
}
|
||||
|
||||
# Some of the 'shared_target' values don't have any entries in
|
||||
# %shared_info. That's perfectly fine, AS LONG AS the build file
|
||||
# template knows how to handle this. That is currently the case for
|
||||
# Windows and VMS.
|
||||
if (defined $si) {
|
||||
# Just as above, copy certain shared_* attributes to the corresponding
|
||||
# module_ attribute unless the latter is already defined
|
||||
$si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags};
|
||||
$si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags};
|
||||
$si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags};
|
||||
foreach (sort keys %$si) {
|
||||
$target{$_} = defined $target{$_}
|
||||
? add($si->{$_})->($target{$_})
|
||||
: $si->{$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
|
||||
|
||||
# If we use the unified build, collect information from build.info files
|
||||
my %unified_info = ();
|
||||
@@ -2411,7 +2425,7 @@ use warnings;
|
||||
use Exporter;
|
||||
#use vars qw(\@ISA \@EXPORT);
|
||||
our \@ISA = qw(Exporter);
|
||||
our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
|
||||
our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables \@disablables_int);
|
||||
|
||||
EOF
|
||||
print OUT "our %config = (\n";
|
||||
@@ -2472,6 +2486,15 @@ foreach (@disablables) {
|
||||
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) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* NOTES.WIN (any supported Windows)
|
||||
* NOTES.DJGPP (DOS platform with DJGPP)
|
||||
* NOTES.ANDROID (obviously Android [NDK])
|
||||
* NOTES.VALGRIND (testing with Valgrind)
|
||||
|
||||
Notational conventions in this document
|
||||
---------------------------------------
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@
|
||||
---------------------------------
|
||||
|
||||
There are a number of ways to install a perl module. In all
|
||||
descriptions below, Text::Template will server as an example.
|
||||
descriptions below, Text::Template will serve as an example.
|
||||
|
||||
1. for Linux users, the easiest is to install with the use of your
|
||||
favorite package manager. Usually, all you need to do is search
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
|
||||
NOTES FOR VALGRIND
|
||||
==================
|
||||
|
||||
Valgrind is a test harness that includes many tools such as memcheck,
|
||||
which is commonly used to check for memory leaks, etc. The default tool
|
||||
run by Valgrind is memcheck. There are other tools available, but this
|
||||
will focus on memcheck.
|
||||
|
||||
Valgrind runs programs in a virtual machine, this means OpenSSL unit
|
||||
tests run under Valgrind will take longer than normal.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
1. Platform supported by Valgrind
|
||||
See: http://valgrind.org/info/platforms.html
|
||||
2. Valgrind installed on the platform
|
||||
See: http://valgrind.org/downloads/current.html
|
||||
3. OpensSSL compiled
|
||||
See: INSTALL
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
Test behavior can be modified by adjusting environment variables.
|
||||
|
||||
EXE_SHELL
|
||||
|
||||
This variable is used to specify the shell used to execute OpenSSL test
|
||||
programs. The default program (util/shlib_wrap.sh) initializes the
|
||||
environment to allow programs to find shared libraries. The variable can
|
||||
be modified to specify a different executable environment.
|
||||
|
||||
EXE_SHELL="`/bin/pwd`/util/shlib_wrap.sh valgrind --error-exitcode=1 --leak-check=full -q"
|
||||
|
||||
This will start up Valgrind with the default checker (memcheck).
|
||||
The --error-exitcode=1 option specifies that Valgrind should exit with an
|
||||
error code of 1 when memory leaks occur.
|
||||
The --leak-check=full option specifies extensive memory checking.
|
||||
The -q option prints only error messages.
|
||||
Additional Valgrind options may be added to the EXE_SHELL variable.
|
||||
|
||||
OPENSSL_ia32cap
|
||||
|
||||
This variable controls the processor-specific code on Intel processors.
|
||||
By default, OpenSSL will attempt to figure out the capabilities of a
|
||||
processor, and use it to its fullest capability. This variable can be
|
||||
used to control what capabilities OpenSSL uses.
|
||||
|
||||
As of valgrind-3.15.0 on Linux/x86_64, instructions up to AVX2 are
|
||||
supported. Setting the following disables instructions beyond AVX2:
|
||||
|
||||
OPENSSL_ia32cap=":0"
|
||||
|
||||
This variable may need to be set to something different based on the
|
||||
processor and Valgrind version you are running tests on. More information
|
||||
may be found in docs/man3/OPENSSL_ia32cap.pod.
|
||||
|
||||
Additional variables (i.e. VERBOSE and TESTS) are described in the
|
||||
INSTALL file in the root of the OpenSSL source tree.
|
||||
|
||||
Example command line:
|
||||
|
||||
make test EXE_SHELL="`/bin/pwd`/util/shlib_wrap.sh valgrind --error-exitcode=1 --leak-check=full -q" OPENSSL_ia32cap=":0"
|
||||
|
||||
If an error occurs, you can then run the specific test via the TESTS
|
||||
variable with the VERBOSE option to gather additional information.
|
||||
|
||||
make test VERBOSE=1 TESTS=test_test EXE_SHELL="`/bin/pwd`/util/shlib_wrap.sh valgrind --error-exitcode=1 --leak-check=full -q" OPENSSL_ia32cap=":0"
|
||||
@@ -640,6 +640,7 @@ int cms_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
}
|
||||
} else if (!operation) {
|
||||
BIO_printf(bio_err, "No operation option (-encrypt|-decrypt|-sign|-verify|...) specified.\n");
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
|
||||
+16
-4
@@ -25,12 +25,15 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
static int dsa_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
|
||||
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM
|
||||
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE,
|
||||
OPT_R_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS dsaparam_options[] = {
|
||||
@@ -47,6 +50,7 @@ const OPTIONS dsaparam_options[] = {
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
|
||||
# endif
|
||||
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -107,6 +111,9 @@ int dsaparam_main(int argc, char **argv)
|
||||
case OPT_NOOUT:
|
||||
noout = 1;
|
||||
break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -145,9 +152,11 @@ int dsaparam_main(int argc, char **argv)
|
||||
BIO_printf(bio_err, "Error allocating DSA object\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
|
||||
num);
|
||||
BIO_printf(bio_err, "This could take some time\n");
|
||||
if (verbose) {
|
||||
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
|
||||
num);
|
||||
BIO_printf(bio_err, "This could take some time\n");
|
||||
}
|
||||
if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, DSA key generation failed\n");
|
||||
@@ -251,6 +260,9 @@ static int dsa_cb(int p, int n, BN_GENCB *cb)
|
||||
static const char symbols[] = ".+*\n";
|
||||
char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';
|
||||
|
||||
if (!verbose)
|
||||
return 1;
|
||||
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void)BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
|
||||
+8
-3
@@ -27,7 +27,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER,
|
||||
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE,
|
||||
OPT_R_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
@@ -42,6 +42,7 @@ const OPTIONS gendsa_options[] = {
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -54,7 +55,7 @@ int gendsa_main(int argc, char **argv)
|
||||
char *dsaparams = NULL;
|
||||
char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog;
|
||||
OPTION_CHOICE o;
|
||||
int ret = 1, private = 0;
|
||||
int ret = 1, private = 0, verbose = 0;
|
||||
const BIGNUM *p = NULL;
|
||||
|
||||
prog = opt_init(argc, argv, gendsa_options);
|
||||
@@ -86,6 +87,9 @@ int gendsa_main(int argc, char **argv)
|
||||
if (!opt_cipher(opt_unknown(), &enc))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -124,7 +128,8 @@ int gendsa_main(int argc, char **argv)
|
||||
" Your key size is %d! Larger key size may behave not as expected.\n",
|
||||
OPENSSL_DSA_MAX_MODULUS_BITS, BN_num_bits(p));
|
||||
|
||||
BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
|
||||
if (verbose)
|
||||
BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
|
||||
if (!DSA_generate_key(dsa))
|
||||
goto end;
|
||||
|
||||
|
||||
+14
-4
@@ -30,12 +30,14 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# define DEFBITS 2048
|
||||
# define DEFPRIMES 2
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
static int genrsa_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_3, OPT_F4, OPT_ENGINE,
|
||||
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES,
|
||||
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE,
|
||||
OPT_R_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
@@ -52,6 +54,7 @@ const OPTIONS genrsa_options[] = {
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
{"primes", OPT_PRIMES, 'p', "Specify number of primes"},
|
||||
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -115,6 +118,9 @@ opthelp:
|
||||
if (!opt_int(opt_arg(), &primes))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -143,8 +149,9 @@ opthelp:
|
||||
if (out == NULL)
|
||||
goto end;
|
||||
|
||||
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
|
||||
num, primes);
|
||||
if (verbose)
|
||||
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
|
||||
num, primes);
|
||||
rsa = eng ? RSA_new_method(eng) : RSA_new();
|
||||
if (rsa == NULL)
|
||||
goto end;
|
||||
@@ -156,7 +163,7 @@ opthelp:
|
||||
RSA_get0_key(rsa, NULL, &e, NULL);
|
||||
hexe = BN_bn2hex(e);
|
||||
dece = BN_bn2dec(e);
|
||||
if (hexe && dece) {
|
||||
if (hexe && dece && verbose) {
|
||||
BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
|
||||
}
|
||||
OPENSSL_free(hexe);
|
||||
@@ -186,6 +193,9 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
|
||||
if (!verbose)
|
||||
return 1;
|
||||
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
|
||||
+1
-2
@@ -42,8 +42,7 @@ int info_main(int argc, char **argv)
|
||||
prog = opt_init(argc, argv, info_options);
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
default:
|
||||
opthelp:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto end;
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
|
||||
OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
|
||||
OPT_RSA_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
|
||||
OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
|
||||
OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM,
|
||||
OPT_R_ENUM
|
||||
@@ -46,7 +46,7 @@ const OPTIONS rsautl_options[] = {
|
||||
{"pubin", OPT_PUBIN, '-', "Input is an RSA public"},
|
||||
{"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
|
||||
{"ssl", OPT_SSL, '-', "Use SSL v2 padding"},
|
||||
{"raw", OPT_RAW, '-', "Use no padding"},
|
||||
{"raw", OPT_RSA_RAW, '-', "Use no padding"},
|
||||
{"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"},
|
||||
{"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"},
|
||||
{"sign", OPT_SIGN, '-', "Sign with private key"},
|
||||
@@ -112,7 +112,7 @@ int rsautl_main(int argc, char **argv)
|
||||
case OPT_HEXDUMP:
|
||||
hexdump = 1;
|
||||
break;
|
||||
case OPT_RAW:
|
||||
case OPT_RSA_RAW:
|
||||
pad = RSA_NO_PADDING;
|
||||
break;
|
||||
case OPT_OAEP:
|
||||
|
||||
+11
-2
@@ -123,6 +123,8 @@ static SSL_SESSION *psksess = NULL;
|
||||
static char *psk_identity = "Client_identity";
|
||||
char *psk_key = NULL; /* by default PSK is not used */
|
||||
|
||||
static char http_server_binmode = 0; /* for now: 0/1 = default/binary */
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
static unsigned int psk_server_cb(SSL *ssl, const char *identity,
|
||||
unsigned char *psk,
|
||||
@@ -752,6 +754,7 @@ typedef enum OPTION_choice {
|
||||
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
||||
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
|
||||
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
|
||||
OPT_HTTP_SERVER_BINMODE,
|
||||
OPT_R_ENUM,
|
||||
OPT_S_ENUM,
|
||||
OPT_V_ENUM,
|
||||
@@ -966,6 +969,7 @@ const OPTIONS s_server_options[] = {
|
||||
"The number of TLSv1.3 session tickets that a server will automatically issue" },
|
||||
{"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"},
|
||||
{"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"},
|
||||
{"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"},
|
||||
{NULL, OPT_EOF, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -1595,6 +1599,9 @@ int s_server_main(int argc, char *argv[])
|
||||
if (max_early_data == -1)
|
||||
max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
|
||||
break;
|
||||
case OPT_HTTP_SERVER_BINMODE:
|
||||
http_server_binmode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -2956,6 +2963,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||
#endif
|
||||
int width;
|
||||
fd_set readfds;
|
||||
const char *opmode;
|
||||
|
||||
/* Set width for a select call if needed */
|
||||
width = s + 1;
|
||||
@@ -3249,9 +3257,10 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((file = BIO_new_file(p, "r")) == NULL) {
|
||||
opmode = (http_server_binmode == 1) ? "rb" : "r";
|
||||
if ((file = BIO_new_file(p, opmode)) == NULL) {
|
||||
BIO_puts(io, text);
|
||||
BIO_printf(io, "Error opening '%s'\r\n", p);
|
||||
BIO_printf(io, "Error opening '%s' mode='%s'\r\n", p, opmode);
|
||||
ERR_print_errors(io);
|
||||
break;
|
||||
}
|
||||
|
||||
+10
-15
@@ -122,35 +122,30 @@ opthelp:
|
||||
if (!dirty)
|
||||
version = 1;
|
||||
|
||||
if (version) {
|
||||
if (strcmp(OpenSSL_version(OPENSSL_FULL_VERSION_STRING),
|
||||
OPENSSL_FULL_VERSION_STR) == 0)
|
||||
printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
|
||||
else
|
||||
printf("%s (Library: %s)\n",
|
||||
OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
|
||||
}
|
||||
if (version)
|
||||
printf("%s (Library: %s)\n",
|
||||
OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
|
||||
if (date)
|
||||
printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
|
||||
if (platform)
|
||||
printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM));
|
||||
if (options) {
|
||||
printf("options: ");
|
||||
printf("%s ", BN_options());
|
||||
printf("options: ");
|
||||
printf(" %s", BN_options());
|
||||
#ifndef OPENSSL_NO_MD2
|
||||
printf("%s ", MD2_options());
|
||||
printf(" %s", MD2_options());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
printf("%s ", RC4_options());
|
||||
printf(" %s", RC4_options());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
printf("%s ", DES_options());
|
||||
printf(" %s", DES_options());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
printf("%s ", IDEA_options());
|
||||
printf(" %s", IDEA_options());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BF
|
||||
printf("%s ", BF_options());
|
||||
printf(" %s", BF_options());
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||
uint64_t p, r, N;
|
||||
size_t saltlen;
|
||||
size_t keylen = 0;
|
||||
int rv = 0;
|
||||
int t, rv = 0;
|
||||
SCRYPT_PARAMS *sparam = NULL;
|
||||
|
||||
if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
|
||||
@@ -234,7 +234,12 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||
goto err;
|
||||
}
|
||||
|
||||
keylen = EVP_CIPHER_CTX_key_length(ctx);
|
||||
t = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (t < 0) {
|
||||
EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
|
||||
goto err;
|
||||
}
|
||||
keylen = t;
|
||||
|
||||
/* Now check the parameters of sparam */
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
const void *ossl_bsearch(const void *key, const void *base, int num,
|
||||
int size, int (*cmp) (const void *, const void *),
|
||||
int flags)
|
||||
{
|
||||
const char *base_ = base;
|
||||
int l, h, i = 0, c = 0;
|
||||
const char *p = NULL;
|
||||
|
||||
if (num == 0)
|
||||
return NULL;
|
||||
l = 0;
|
||||
h = num;
|
||||
while (l < h) {
|
||||
i = (l + h) / 2;
|
||||
p = &(base_[i * size]);
|
||||
c = (*cmp) (key, p);
|
||||
if (c < 0)
|
||||
h = i;
|
||||
else if (c > 0)
|
||||
l = i + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (c != 0 && !(flags & OSSL_BSEARCH_VALUE_ON_NOMATCH))
|
||||
p = NULL;
|
||||
else if (c == 0 && (flags & OSSL_BSEARCH_FIRST_VALUE_ON_MATCH)) {
|
||||
while (i > 0 && (*cmp) (key, &(base_[(i - 1) * size])) == 0)
|
||||
i--;
|
||||
p = &(base_[i * size]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
+3
-3
@@ -10,7 +10,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
||||
LIBS=../libcrypto
|
||||
# The Core
|
||||
SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \
|
||||
core_fetch.c
|
||||
core_fetch.c core_namemap.c
|
||||
|
||||
# Central utilities
|
||||
SOURCE[../libcrypto]=\
|
||||
@@ -18,12 +18,12 @@ SOURCE[../libcrypto]=\
|
||||
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
|
||||
threads_pthread.c threads_win.c threads_none.c getenv.c \
|
||||
o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
|
||||
trace.c provider.c params.c \
|
||||
trace.c provider.c params.c bsearch.c \
|
||||
{- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}
|
||||
|
||||
# FIPS module
|
||||
SOURCE[../providers/fips]=\
|
||||
cryptlib.c mem.c mem_clr.c params.c
|
||||
cryptlib.c mem.c mem_clr.c params.c bsearch.c
|
||||
|
||||
|
||||
DEPEND[cversion.o]=buildinf.h
|
||||
|
||||
+194
-22
@@ -10,38 +10,106 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/thread_once.h"
|
||||
|
||||
struct openssl_ctx_onfree_list_st {
|
||||
openssl_ctx_onfree_fn *fn;
|
||||
struct openssl_ctx_onfree_list_st *next;
|
||||
};
|
||||
|
||||
struct openssl_ctx_st {
|
||||
CRYPTO_RWLOCK *lock;
|
||||
CRYPTO_EX_DATA data;
|
||||
|
||||
/*
|
||||
* For most data in the OPENSSL_CTX we just use ex_data to store it. But
|
||||
* that doesn't work for ex_data itself - so we store that directly.
|
||||
*/
|
||||
OSSL_EX_DATA_GLOBAL global;
|
||||
|
||||
/* Map internal static indexes to dynamically created indexes */
|
||||
int dyn_indexes[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];
|
||||
struct openssl_ctx_onfree_list_st *onfreelist;
|
||||
};
|
||||
|
||||
static OPENSSL_CTX default_context;
|
||||
#ifndef FIPS_MODE
|
||||
static OPENSSL_CTX default_context_int;
|
||||
#endif
|
||||
|
||||
/* Always points at default_context_int if it has been initialised */
|
||||
static OPENSSL_CTX *default_context = NULL;
|
||||
|
||||
static int context_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
return (ctx->lock = CRYPTO_THREAD_lock_new()) != NULL
|
||||
&& CRYPTO_new_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
|
||||
&ctx->data);
|
||||
size_t i;
|
||||
|
||||
ctx->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ctx->lock == NULL)
|
||||
return 0;
|
||||
|
||||
ctx->oncelock = CRYPTO_THREAD_lock_new();
|
||||
if (ctx->oncelock == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++)
|
||||
ctx->dyn_indexes[i] = -1;
|
||||
|
||||
if (!do_ex_data_init(ctx))
|
||||
goto err;
|
||||
|
||||
if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
|
||||
&ctx->data)) {
|
||||
crypto_cleanup_all_ex_data_int(ctx);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 1;
|
||||
err:
|
||||
CRYPTO_THREAD_lock_free(ctx->oncelock);
|
||||
CRYPTO_THREAD_lock_free(ctx->lock);
|
||||
ctx->lock = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_deinit(OPENSSL_CTX *ctx)
|
||||
{
|
||||
struct openssl_ctx_onfree_list_st *tmp, *onfree;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 1;
|
||||
|
||||
onfree = ctx->onfreelist;
|
||||
while (onfree != NULL) {
|
||||
onfree->fn(ctx);
|
||||
tmp = onfree;
|
||||
onfree = onfree->next;
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data);
|
||||
crypto_cleanup_all_ex_data_int(ctx);
|
||||
CRYPTO_THREAD_lock_free(ctx->oncelock);
|
||||
CRYPTO_THREAD_lock_free(ctx->lock);
|
||||
ctx->lock = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
static void do_default_context_deinit(void)
|
||||
#ifndef FIPS_MODE
|
||||
void openssl_ctx_default_deinit(void)
|
||||
{
|
||||
context_deinit(&default_context);
|
||||
context_deinit(default_context);
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_default_context_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& context_init(&default_context)
|
||||
&& OPENSSL_atexit(do_default_context_deinit);
|
||||
if (context_init(&default_context_int))
|
||||
default_context = &default_context_int;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
OPENSSL_CTX *OPENSSL_CTX_new(void)
|
||||
{
|
||||
@@ -66,7 +134,7 @@ static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
|
||||
long argl_ign, void *argp)
|
||||
{
|
||||
const OPENSSL_CTX_METHOD *meth = argp;
|
||||
void *ptr = meth->new_func();
|
||||
void *ptr = meth->new_func(crypto_ex_data_get_openssl_ctx(ad));
|
||||
|
||||
if (ptr != NULL)
|
||||
CRYPTO_set_ex_data(ad, index, ptr);
|
||||
@@ -79,32 +147,136 @@ static void openssl_ctx_generic_free(void *parent_ign, void *ptr,
|
||||
|
||||
meth->free_func(ptr);
|
||||
}
|
||||
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth)
|
||||
{
|
||||
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_OPENSSL_CTX, 0, (void *)meth,
|
||||
openssl_ctx_generic_new, NULL,
|
||||
openssl_ctx_generic_free);
|
||||
}
|
||||
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index)
|
||||
/* Non-static so we can use it in context_internal_test */
|
||||
static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index,
|
||||
const OPENSSL_CTX_METHOD *meth)
|
||||
{
|
||||
void *data = NULL;
|
||||
int idx;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL) {
|
||||
if (!RUN_ONCE(&default_context_init, do_default_context_init))
|
||||
return 0;
|
||||
ctx = &default_context;
|
||||
ctx = default_context;
|
||||
}
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, 0,
|
||||
(void *)meth,
|
||||
openssl_ctx_generic_new,
|
||||
NULL, openssl_ctx_generic_free);
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
|
||||
ctx->dyn_indexes[static_index] = idx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
|
||||
const OPENSSL_CTX_METHOD *meth)
|
||||
{
|
||||
void *data = NULL;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL) {
|
||||
if (!RUN_ONCE(&default_context_init, do_default_context_init))
|
||||
return NULL;
|
||||
ctx = default_context;
|
||||
}
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
CRYPTO_THREAD_read_lock(ctx->lock);
|
||||
|
||||
if (ctx->dyn_indexes[index] == -1
|
||||
&& !openssl_ctx_init_index(ctx, index, meth)) {
|
||||
CRYPTO_THREAD_unlock(ctx->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The alloc call ensures there's a value there */
|
||||
if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
|
||||
&ctx->data, index))
|
||||
data = CRYPTO_get_ex_data(&ctx->data, index);
|
||||
&ctx->data, ctx->dyn_indexes[index]))
|
||||
data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
|
||||
|
||||
CRYPTO_THREAD_unlock(ctx->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx)
|
||||
{
|
||||
/*
|
||||
* The default context code is not needed in FIPS_MODE and ctx should never
|
||||
* be NULL in the FIPS provider. However we compile this code out to ensure
|
||||
* we fail immediately if ctx == NULL in FIPS_MODE
|
||||
*/
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL) {
|
||||
if (!RUN_ONCE(&default_context_init, do_default_context_init))
|
||||
return NULL;
|
||||
ctx = default_context;
|
||||
}
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
return &ctx->global;
|
||||
}
|
||||
|
||||
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
|
||||
openssl_ctx_run_once_fn run_once_fn)
|
||||
{
|
||||
int done = 0, ret = 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL) {
|
||||
if (!RUN_ONCE(&default_context_init, do_default_context_init))
|
||||
return 0;
|
||||
ctx = default_context;
|
||||
}
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
CRYPTO_THREAD_read_lock(ctx->oncelock);
|
||||
done = ctx->run_once_done[idx];
|
||||
if (done)
|
||||
ret = ctx->run_once_ret[idx];
|
||||
CRYPTO_THREAD_unlock(ctx->oncelock);
|
||||
|
||||
if (done)
|
||||
return ret;
|
||||
|
||||
CRYPTO_THREAD_write_lock(ctx->oncelock);
|
||||
if (ctx->run_once_done[idx]) {
|
||||
ret = ctx->run_once_ret[idx];
|
||||
CRYPTO_THREAD_unlock(ctx->oncelock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = run_once_fn(ctx);
|
||||
ctx->run_once_done[idx] = 1;
|
||||
ctx->run_once_ret[idx] = ret;
|
||||
CRYPTO_THREAD_unlock(ctx->oncelock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn)
|
||||
{
|
||||
struct openssl_ctx_onfree_list_st *newonfree
|
||||
= OPENSSL_malloc(sizeof(*newonfree));
|
||||
|
||||
if (newonfree == NULL)
|
||||
return 0;
|
||||
|
||||
newonfree->fn = onfreefn;
|
||||
newonfree->next = ctx->onfreelist;
|
||||
ctx->onfreelist = newonfree;
|
||||
|
||||
return 1;
|
||||
}
|
||||
+10
-9
@@ -56,14 +56,14 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
* If we haven't been told not to store,
|
||||
* add to the global store
|
||||
*/
|
||||
data->mcm->put(data->libctx, NULL,
|
||||
thismap->property_definition,
|
||||
method, data->mcm_data);
|
||||
data->mcm->put(data->libctx, NULL, method,
|
||||
thismap->algorithm_name,
|
||||
thismap->property_definition, data->mcm_data);
|
||||
}
|
||||
|
||||
data->mcm->put(data->libctx, data->store,
|
||||
thismap->property_definition,
|
||||
method, data->mcm_data);
|
||||
data->mcm->put(data->libctx, data->store, method,
|
||||
thismap->algorithm_name, thismap->property_definition,
|
||||
data->mcm_data);
|
||||
|
||||
/* refcnt-- because we're dropping the reference */
|
||||
data->mcm->destruct(method, data->mcm_data);
|
||||
@@ -79,14 +79,15 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
|
||||
{
|
||||
void *method = NULL;
|
||||
|
||||
if ((method = mcm->get(libctx, NULL, propquery, mcm_data)) == NULL) {
|
||||
if ((method =
|
||||
mcm->get(libctx, NULL, name, propquery, mcm_data)) == NULL) {
|
||||
struct construct_data_st cbdata;
|
||||
|
||||
/*
|
||||
* We have a temporary store to be able to easily search among new
|
||||
* items, or items that should find themselves in the global store.
|
||||
*/
|
||||
if ((cbdata.store = mcm->alloc_tmp_store()) == NULL)
|
||||
if ((cbdata.store = mcm->alloc_tmp_store(libctx)) == NULL)
|
||||
goto fin;
|
||||
|
||||
cbdata.libctx = libctx;
|
||||
@@ -97,7 +98,7 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
|
||||
ossl_provider_forall_loaded(libctx, ossl_method_construct_this,
|
||||
&cbdata);
|
||||
|
||||
method = mcm->get(libctx, cbdata.store, propquery, mcm_data);
|
||||
method = mcm->get(libctx, cbdata.store, name, propquery, mcm_data);
|
||||
mcm->dealloc_tmp_store(cbdata.store);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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/namemap.h"
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
/* The namemap entry */
|
||||
typedef struct {
|
||||
int number;
|
||||
const char *name;
|
||||
char body[1]; /* Sized appropriately to contain the name */
|
||||
} NAMEMAP_ENTRY;
|
||||
|
||||
DEFINE_LHASH_OF(NAMEMAP_ENTRY);
|
||||
DEFINE_STACK_OF(NAMEMAP_ENTRY)
|
||||
|
||||
/* The namemap, which provides for bidirectional indexing */
|
||||
|
||||
struct ossl_namemap_st {
|
||||
/* Flags */
|
||||
unsigned int stored:1; /* If 1, it's stored in a library context */
|
||||
|
||||
CRYPTO_RWLOCK *lock;
|
||||
LHASH_OF(NAMEMAP_ENTRY) *namenum; /* Name->number mapping */
|
||||
STACK_OF(NAMEMAP_ENTRY) *numname; /* Number->name mapping */
|
||||
};
|
||||
|
||||
/* LHASH callbacks */
|
||||
|
||||
static unsigned long namemap_hash(const NAMEMAP_ENTRY *n)
|
||||
{
|
||||
return OPENSSL_LH_strhash(n->name);
|
||||
}
|
||||
|
||||
static int namemap_cmp(const NAMEMAP_ENTRY *a, const NAMEMAP_ENTRY *b)
|
||||
{
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static void namemap_free(NAMEMAP_ENTRY *n)
|
||||
{
|
||||
OPENSSL_free(n);
|
||||
}
|
||||
|
||||
/* OPENSSL_CTX_METHOD functions for a namemap stored in a library context */
|
||||
|
||||
static void *stored_namemap_new(OPENSSL_CTX *libctx)
|
||||
{
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_new();
|
||||
|
||||
if (namemap != NULL)
|
||||
namemap->stored = 1;
|
||||
|
||||
return namemap;
|
||||
}
|
||||
|
||||
static void stored_namemap_free(void *vnamemap)
|
||||
{
|
||||
OSSL_NAMEMAP *namemap = vnamemap;
|
||||
|
||||
/* Pretend it isn't stored, or ossl_namemap_free() will do nothing */
|
||||
namemap->stored = 0;
|
||||
ossl_namemap_free(namemap);
|
||||
}
|
||||
|
||||
static const OPENSSL_CTX_METHOD stored_namemap_method = {
|
||||
stored_namemap_new,
|
||||
stored_namemap_free,
|
||||
};
|
||||
|
||||
/* API functions */
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx)
|
||||
{
|
||||
return openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX,
|
||||
&stored_namemap_method);
|
||||
}
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_new(void)
|
||||
{
|
||||
OSSL_NAMEMAP *namemap;
|
||||
|
||||
if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL
|
||||
&& (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL
|
||||
&& (namemap->numname = sk_NAMEMAP_ENTRY_new_null()) != NULL
|
||||
&& (namemap->namenum =
|
||||
lh_NAMEMAP_ENTRY_new(namemap_hash, namemap_cmp)) != NULL) {
|
||||
return namemap;
|
||||
}
|
||||
|
||||
ossl_namemap_free(namemap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ossl_namemap_free(OSSL_NAMEMAP *namemap)
|
||||
{
|
||||
if (namemap == NULL || namemap->stored)
|
||||
return;
|
||||
|
||||
/* The elements will be freed by sk_NAMEMAP_ENTRY_pop_free() */
|
||||
lh_NAMEMAP_ENTRY_free(namemap->namenum);
|
||||
|
||||
sk_NAMEMAP_ENTRY_pop_free(namemap->numname, namemap_free);
|
||||
|
||||
CRYPTO_THREAD_lock_free(namemap->lock);
|
||||
OPENSSL_free(namemap);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) It isn't currently possible to have a default namemap in the
|
||||
* FIPS module because if init and cleanup constraints, so we currently
|
||||
* disable the code that would allow it when FIPS_MODE is defined.
|
||||
*/
|
||||
|
||||
const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number)
|
||||
{
|
||||
NAMEMAP_ENTRY *entry;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (namemap == NULL)
|
||||
namemap = ossl_namemap_stored(NULL);
|
||||
#endif
|
||||
|
||||
if (namemap == NULL || number == 0)
|
||||
return NULL;
|
||||
|
||||
CRYPTO_THREAD_read_lock(namemap->lock);
|
||||
entry = sk_NAMEMAP_ENTRY_value(namemap->numname, number);
|
||||
CRYPTO_THREAD_unlock(namemap->lock);
|
||||
|
||||
if (entry != NULL)
|
||||
return entry->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name)
|
||||
{
|
||||
NAMEMAP_ENTRY *entry, template;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (namemap == NULL)
|
||||
namemap = ossl_namemap_stored(NULL);
|
||||
#endif
|
||||
|
||||
if (namemap == NULL)
|
||||
return 0;
|
||||
|
||||
template.name = name;
|
||||
CRYPTO_THREAD_read_lock(namemap->lock);
|
||||
entry = lh_NAMEMAP_ENTRY_retrieve(namemap->namenum, &template);
|
||||
CRYPTO_THREAD_unlock(namemap->lock);
|
||||
|
||||
if (entry == NULL)
|
||||
return 0;
|
||||
|
||||
return entry->number;
|
||||
}
|
||||
|
||||
int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name)
|
||||
{
|
||||
NAMEMAP_ENTRY *entry;
|
||||
int number;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (namemap == NULL)
|
||||
namemap = ossl_namemap_stored(NULL);
|
||||
#endif
|
||||
|
||||
if (name == NULL || namemap == NULL)
|
||||
return 0;
|
||||
|
||||
if ((number = ossl_namemap_number(namemap, name)) != 0)
|
||||
return number; /* Pretend success */
|
||||
|
||||
if ((entry = OPENSSL_zalloc(sizeof(*entry) + strlen(name))) == NULL)
|
||||
goto err;
|
||||
|
||||
strcpy(entry->body, name);
|
||||
entry->name = entry->body;
|
||||
|
||||
CRYPTO_THREAD_write_lock(namemap->lock);
|
||||
|
||||
entry->number = sk_NAMEMAP_ENTRY_push(namemap->numname, entry);
|
||||
|
||||
if (entry->number == 0)
|
||||
goto err;
|
||||
|
||||
(void)lh_NAMEMAP_ENTRY_insert(namemap->namenum, entry);
|
||||
if (lh_NAMEMAP_ENTRY_error(namemap->namenum))
|
||||
goto err;
|
||||
|
||||
CRYPTO_THREAD_unlock(namemap->lock);
|
||||
|
||||
return entry->number;
|
||||
|
||||
err:
|
||||
if (entry != NULL) {
|
||||
if (entry->number != 0)
|
||||
(void)sk_NAMEMAP_ENTRY_pop(namemap->numname);
|
||||
lh_NAMEMAP_ENTRY_delete(namemap->namenum, entry);
|
||||
CRYPTO_THREAD_unlock(namemap->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+6
-2
@@ -21,9 +21,13 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
|
||||
"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),
|
||||
@@ -46,10 +50,10 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
|
||||
{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_ADD_BUILTIN, 0),
|
||||
"OSSL_PROVIDER_add_builtin"},
|
||||
{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),
|
||||
|
||||
@@ -54,7 +54,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx)
|
||||
DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
dctx->prime_len = 1024;
|
||||
dctx->prime_len = 2048;
|
||||
dctx->subprime_len = -1;
|
||||
dctx->generator = 2;
|
||||
dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
|
||||
|
||||
@@ -190,6 +190,12 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reject obviously invalid parameters */
|
||||
if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) {
|
||||
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
k = BN_new();
|
||||
l = BN_new();
|
||||
if (k == NULL || l == NULL)
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
typedef struct {
|
||||
/* Parameter gen parameters */
|
||||
int nbits; /* size of p in bits (default: 1024) */
|
||||
int qbits; /* size of q in bits (default: 160) */
|
||||
int nbits; /* size of p in bits (default: 2048) */
|
||||
int qbits; /* size of q in bits (default: 224) */
|
||||
const EVP_MD *pmd; /* MD for parameter generation */
|
||||
/* Keygen callback info */
|
||||
int gentmp[2];
|
||||
@@ -35,8 +35,8 @@ static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
|
||||
|
||||
if (dctx == NULL)
|
||||
return 0;
|
||||
dctx->nbits = 1024;
|
||||
dctx->qbits = 160;
|
||||
dctx->nbits = 2048;
|
||||
dctx->qbits = 224;
|
||||
dctx->pmd = NULL;
|
||||
dctx->md = NULL;
|
||||
|
||||
@@ -138,7 +138,11 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
|
||||
DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,11 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+15
-49
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -10,62 +10,28 @@
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
/* Key derivation function from X9.63/SECG */
|
||||
/* Way more than we will ever need */
|
||||
#define ECDH_KDF_MAX (1 << 30)
|
||||
|
||||
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
const unsigned char *Z, size_t Zlen,
|
||||
const unsigned char *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md)
|
||||
{
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
int rv = 0;
|
||||
unsigned int i;
|
||||
size_t mdlen;
|
||||
unsigned char ctr[4];
|
||||
if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
|
||||
|| Zlen > ECDH_KDF_MAX)
|
||||
return 0;
|
||||
mctx = EVP_MD_CTX_new();
|
||||
if (mctx == NULL)
|
||||
return 0;
|
||||
mdlen = EVP_MD_size(md);
|
||||
for (i = 1;; i++) {
|
||||
unsigned char mtmp[EVP_MAX_MD_SIZE];
|
||||
if (!EVP_DigestInit_ex(mctx, md, NULL))
|
||||
goto err;
|
||||
ctr[3] = i & 0xFF;
|
||||
ctr[2] = (i >> 8) & 0xFF;
|
||||
ctr[1] = (i >> 16) & 0xFF;
|
||||
ctr[0] = (i >> 24) & 0xFF;
|
||||
if (!EVP_DigestUpdate(mctx, Z, Zlen))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
|
||||
goto err;
|
||||
if (outlen >= mdlen) {
|
||||
if (!EVP_DigestFinal(mctx, out, NULL))
|
||||
goto err;
|
||||
outlen -= mdlen;
|
||||
if (outlen == 0)
|
||||
break;
|
||||
out += mdlen;
|
||||
} else {
|
||||
if (!EVP_DigestFinal(mctx, mtmp, NULL))
|
||||
goto err;
|
||||
memcpy(out, mtmp, outlen);
|
||||
OPENSSL_cleanse(mtmp, mdlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
int ret;
|
||||
EVP_KDF_CTX *kctx = 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;
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
|
||||
@@ -189,12 +189,15 @@ typedef struct {
|
||||
static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
const int n = EVP_CIPHER_CTX_key_length(ctx);
|
||||
|
||||
# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
|
||||
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
|
||||
# endif
|
||||
memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
|
||||
RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
|
||||
test(ctx)->key);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
memcpy(&test(ctx)->key[0], key, n);
|
||||
RC4_set_key(&test(ctx)->ks, n, test(ctx)->key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ int err_load_crypto_strings_int(void)
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
ERR_load_CMS_strings() == 0 ||
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_CMP
|
||||
# ifndef OPENSSL_NO_CRMF
|
||||
ERR_load_CRMF_strings() == 0 ||
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_CT
|
||||
|
||||
@@ -374,8 +374,10 @@ CRYPTO_F_CMAC_CTX_NEW:120:CMAC_CTX_new
|
||||
CRYPTO_F_CRYPTO_DUP_EX_DATA:110:CRYPTO_dup_ex_data
|
||||
CRYPTO_F_CRYPTO_FREE_EX_DATA:111:CRYPTO_free_ex_data
|
||||
CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX:100:CRYPTO_get_ex_new_index
|
||||
CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX:141:crypto_get_ex_new_index_ex
|
||||
CRYPTO_F_CRYPTO_MEMDUP:115:CRYPTO_memdup
|
||||
CRYPTO_F_CRYPTO_NEW_EX_DATA:112:CRYPTO_new_ex_data
|
||||
CRYPTO_F_CRYPTO_NEW_EX_DATA_EX:142:crypto_new_ex_data_ex
|
||||
CRYPTO_F_CRYPTO_OCB128_COPY_CTX:121:CRYPTO_ocb128_copy_ctx
|
||||
CRYPTO_F_CRYPTO_OCB128_INIT:122:CRYPTO_ocb128_init
|
||||
CRYPTO_F_CRYPTO_SET_EX_DATA:102:CRYPTO_set_ex_data
|
||||
@@ -800,6 +802,7 @@ 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_MAC_CTRL:209:EVP_MAC_ctrl
|
||||
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
|
||||
@@ -922,6 +925,7 @@ 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_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
|
||||
@@ -1434,6 +1438,7 @@ SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate
|
||||
SSL_F_SSL_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated
|
||||
SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:*
|
||||
SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:*
|
||||
SSL_F_SSL_SENDFILE:639:SSL_sendfile
|
||||
SSL_F_SSL_SESSION_DUP:348:ssl_session_dup
|
||||
SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new
|
||||
SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp
|
||||
@@ -2396,6 +2401,7 @@ EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
|
||||
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
|
||||
EVP_R_INVALID_DIGEST:152:invalid digest
|
||||
EVP_R_INVALID_FIPS_MODE:168:invalid fips mode
|
||||
EVP_R_INVALID_IV_LENGTH:194:invalid iv length
|
||||
EVP_R_INVALID_KEY:163:invalid key
|
||||
EVP_R_INVALID_KEY_LENGTH:130:invalid key length
|
||||
EVP_R_INVALID_OPERATION:148:invalid operation
|
||||
@@ -2459,6 +2465,7 @@ KDF_R_MISSING_SEED:106:missing seed
|
||||
KDF_R_MISSING_SESSION_ID:113:missing session id
|
||||
KDF_R_MISSING_TYPE:114:missing type
|
||||
KDF_R_MISSING_XCGHASH:115:missing xcghash
|
||||
KDF_R_NOT_SUPPORTED:118:not supported
|
||||
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
|
||||
KDF_R_UNSUPPORTED_MAC_TYPE:117:unsupported mac type
|
||||
KDF_R_VALUE_ERROR:108:value error
|
||||
|
||||
@@ -10,7 +10,7 @@ SOURCE[../../libcrypto]=\
|
||||
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
||||
c_allc.c c_alld.c evp_lib.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 \
|
||||
pkey_kdf.c c_allkdf.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 cmeth_lib.c \
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 <openssl/evp.h>
|
||||
#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);
|
||||
}
|
||||
+23
-14
@@ -172,7 +172,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
|
||||
ctx->digest = type;
|
||||
if (ctx->provctx == NULL) {
|
||||
ctx->provctx = ctx->digest->newctx();
|
||||
ctx->provctx = ctx->digest->newctx(ossl_provider_ctx(type->prov));
|
||||
if (ctx->provctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
@@ -494,13 +494,14 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *evp_md_from_dispatch(int mdtype, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_MD *md = NULL;
|
||||
int fncnt = 0;
|
||||
|
||||
if ((md = EVP_MD_meth_new(mdtype, NID_undef)) == NULL)
|
||||
/* EVP_MD_fetch() will set the legacy NID if available */
|
||||
if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
@@ -587,17 +588,25 @@ static void evp_md_free(void *md)
|
||||
EVP_MD_meth_free(md);
|
||||
}
|
||||
|
||||
static int evp_md_nid(void *vmd)
|
||||
{
|
||||
EVP_MD *md = vmd;
|
||||
|
||||
return md->type;
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
||||
evp_md_from_dispatch, evp_md_upref,
|
||||
evp_md_free, evp_md_nid);
|
||||
EVP_MD *md =
|
||||
evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
||||
evp_md_from_dispatch, evp_md_upref,
|
||||
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;
|
||||
}
|
||||
+22
-17
@@ -15,6 +15,7 @@
|
||||
#include <assert.h>
|
||||
#include <openssl/aes.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "modes_lcl.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/cmac.h>
|
||||
@@ -22,7 +23,7 @@
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
block128_f block;
|
||||
@@ -34,7 +35,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks; /* AES key schedule to use */
|
||||
int key_set; /* Set if key initialised */
|
||||
@@ -52,7 +53,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks1, ks2; /* AES key schedules to use */
|
||||
XTS128_CONTEXT xts;
|
||||
@@ -64,7 +65,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks; /* AES key schedule to use */
|
||||
int key_set; /* Set if key initialised */
|
||||
@@ -80,11 +81,11 @@ typedef struct {
|
||||
#ifndef OPENSSL_NO_OCB
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ksenc; /* AES key schedule to use for encryption */
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ksdec; /* AES key schedule to use for decryption */
|
||||
int key_set; /* Set if key initialised */
|
||||
@@ -1008,7 +1009,7 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* KM-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-06)
|
||||
@@ -1023,7 +1024,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* KMO-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-08)
|
||||
@@ -1041,7 +1042,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* KMF-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-08)
|
||||
@@ -1059,7 +1060,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* KMA-GCM-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-11)
|
||||
@@ -1108,7 +1109,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* Padding is chosen so that ccm.kmac_param.k overlaps with key.k and
|
||||
* ccm.fc with key.k.rounds. Remember that on s390x, an AES_KEY's
|
||||
@@ -2263,9 +2264,6 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
if (!cctx->aes.ccm.iv_set)
|
||||
return -1;
|
||||
|
||||
if (!enc && !cctx->aes.ccm.tag_set)
|
||||
return -1;
|
||||
|
||||
if (out == NULL) {
|
||||
/* Update(): Pass message length. */
|
||||
if (in == NULL) {
|
||||
@@ -2284,6 +2282,10 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return len;
|
||||
}
|
||||
|
||||
/* The tag must be set before actually decrypting data */
|
||||
if (!enc && !cctx->aes.ccm.tag_set)
|
||||
return -1;
|
||||
|
||||
/* Update(): Process message. */
|
||||
|
||||
if (!cctx->aes.ccm.len_set) {
|
||||
@@ -3791,8 +3793,6 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
if (!cctx->iv_set)
|
||||
return -1;
|
||||
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
|
||||
return -1;
|
||||
if (!out) {
|
||||
if (!in) {
|
||||
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
@@ -3807,6 +3807,11 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
CRYPTO_ccm128_aad(ccm, in, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* The tag must be set before actually decrypting data */
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
|
||||
return -1;
|
||||
|
||||
/* If not set length yet do it */
|
||||
if (!cctx->len_set) {
|
||||
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
@@ -3853,7 +3858,7 @@ BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
/* Indicates if IV has been set */
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
@@ -27,7 +27,7 @@ typedef struct {
|
||||
/* ARIA GCM context */
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
ARIA_KEY ks;
|
||||
} ks; /* ARIA subkey to use */
|
||||
int key_set; /* Set if key initialised */
|
||||
@@ -43,7 +43,7 @@ typedef struct {
|
||||
/* ARIA CCM context */
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
ARIA_KEY ks;
|
||||
} ks; /* ARIA key schedule to use */
|
||||
int key_set; /* Set if key initialised */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
|
||||
OSSL_UNION_ALIGN; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
|
||||
unsigned int d[CHACHA_KEY_SIZE / 4];
|
||||
} key;
|
||||
unsigned int counter[CHACHA_CTR_SIZE / 4];
|
||||
|
||||
+2
-2
@@ -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
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
DES_key_schedule ks;
|
||||
} ks;
|
||||
union {
|
||||
|
||||
+7
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
OSSL_UNION_ALIGN;
|
||||
DES_key_schedule ks[3];
|
||||
} ks;
|
||||
union {
|
||||
@@ -280,15 +280,17 @@ static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
|
||||
DES_cblock *deskey = ptr;
|
||||
int kl;
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_RAND_KEY:
|
||||
if (RAND_priv_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
|
||||
kl = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (kl < 0 || RAND_priv_bytes(ptr, kl) <= 0)
|
||||
return 0;
|
||||
DES_set_odd_parity(deskey);
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 16)
|
||||
if (kl >= 16)
|
||||
DES_set_odd_parity(deskey + 1);
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 24)
|
||||
if (kl >= 24)
|
||||
DES_set_odd_parity(deskey + 2);
|
||||
return 1;
|
||||
|
||||
|
||||
+67
-34
@@ -206,7 +206,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
|
||||
ctx->cipher = cipher;
|
||||
if (ctx->provctx == NULL) {
|
||||
ctx->provctx = ctx->cipher->newctx();
|
||||
ctx->provctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
|
||||
if (ctx->provctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
@@ -338,6 +338,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
skip_to_init:
|
||||
#endif
|
||||
if (ctx->cipher == NULL)
|
||||
return 0;
|
||||
|
||||
/* we assume block size is a power of 2 in *cryptUpdate */
|
||||
OPENSSL_assert(ctx->cipher->block_size == 1
|
||||
|| ctx->cipher->block_size == 8
|
||||
@@ -492,11 +495,6 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
||||
|
||||
bl = ctx->cipher->block_size;
|
||||
|
||||
if (inl <= 0) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
/* If block size > 1 then the cipher will have to do this check */
|
||||
if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||
@@ -512,6 +510,10 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (inl <= 0) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
@@ -587,11 +589,14 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
inl + (blocksize == 1 ? 0 : blocksize), in,
|
||||
(size_t)inl);
|
||||
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
if (ret) {
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
*outl = soutl;
|
||||
}
|
||||
*outl = soutl;
|
||||
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
@@ -620,7 +625,11 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
if (ctx->cipher == NULL) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
@@ -633,11 +642,13 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
|
||||
blocksize == 1 ? 0 : blocksize);
|
||||
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
if (ret) {
|
||||
if (soutl > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
*outl = soutl;
|
||||
}
|
||||
*outl = soutl;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -695,7 +706,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
|
||||
if (ctx->cipher == NULL) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->cipher->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
@@ -726,11 +741,6 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||
cmpl = (cmpl + 7) / 8;
|
||||
|
||||
if (inl <= 0) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
@@ -746,6 +756,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (inl <= 0) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||
|
||||
@@ -832,6 +847,10 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
legacy:
|
||||
|
||||
*outl = 0;
|
||||
if (ctx->cipher == NULL) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
|
||||
@@ -949,9 +968,11 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
|
||||
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);
|
||||
if (RAND_priv_bytes(key, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
|
||||
kl = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -1022,13 +1043,17 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
|
||||
static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
int fnciphcnt = 0, fnctxcnt = 0;
|
||||
|
||||
if ((cipher = EVP_CIPHER_meth_new(nid, 0, 0)) == NULL)
|
||||
/*
|
||||
* 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)
|
||||
return NULL;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
@@ -1145,17 +1170,25 @@ static void evp_cipher_free(void *cipher)
|
||||
EVP_CIPHER_meth_free(cipher);
|
||||
}
|
||||
|
||||
static int evp_cipher_nid(void *vcipher)
|
||||
{
|
||||
EVP_CIPHER *cipher = vcipher;
|
||||
|
||||
return cipher->nid;
|
||||
}
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
|
||||
evp_cipher_from_dispatch, evp_cipher_upref,
|
||||
evp_cipher_free, evp_cipher_nid);
|
||||
EVP_CIPHER *cipher =
|
||||
evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
|
||||
evp_cipher_from_dispatch, evp_cipher_upref,
|
||||
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;
|
||||
}
|
||||
@@ -74,6 +74,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
{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"},
|
||||
@@ -248,6 +249,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"invalid custom length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
|
||||
|
||||
+40
-76
@@ -13,23 +13,20 @@
|
||||
#include <openssl/core.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/property.h"
|
||||
#include "internal/core.h"
|
||||
#include "internal/namemap.h"
|
||||
#include "internal/evp_int.h" /* evp_locl.h needs it */
|
||||
#include "evp_locl.h"
|
||||
|
||||
/* The OpenSSL library context index for the default method store */
|
||||
static int default_method_store_index = -1;
|
||||
|
||||
static void default_method_store_free(void *vstore)
|
||||
{
|
||||
ossl_method_store_free(vstore);
|
||||
}
|
||||
|
||||
static void *default_method_store_new(void)
|
||||
static void *default_method_store_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
return ossl_method_store_new();
|
||||
return ossl_method_store_new(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,39 +35,23 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
|
||||
default_method_store_free,
|
||||
};
|
||||
|
||||
static int default_method_store_init(void)
|
||||
{
|
||||
default_method_store_index =
|
||||
openssl_ctx_new_index(&default_method_store_method);
|
||||
|
||||
return default_method_store_index != -1;
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE default_method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_default_method_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& default_method_store_init();
|
||||
}
|
||||
|
||||
/* Data to be passed through ossl_method_construct() */
|
||||
struct method_data_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
const char *name;
|
||||
int nid;
|
||||
int id;
|
||||
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
|
||||
void *(*method_from_dispatch)(int nid, const OSSL_DISPATCH *,
|
||||
OSSL_PROVIDER *);
|
||||
void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
|
||||
int (*refcnt_up_method)(void *method);
|
||||
void (*destruct_method)(void *method);
|
||||
int (*nid_method)(void *method);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic routines to fetch / create EVP methods with ossl_method_construct()
|
||||
*/
|
||||
static void *alloc_tmp_method_store(void)
|
||||
static void *alloc_tmp_method_store(OPENSSL_CTX *ctx)
|
||||
{
|
||||
return ossl_method_store_new();
|
||||
return ossl_method_store_new(ctx);
|
||||
}
|
||||
|
||||
static void dealloc_tmp_method_store(void *store)
|
||||
@@ -81,23 +62,28 @@ static void *alloc_tmp_method_store(void)
|
||||
|
||||
static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
|
||||
{
|
||||
if (!RUN_ONCE(&default_method_store_init_flag,
|
||||
do_default_method_store_init))
|
||||
return NULL;
|
||||
return openssl_ctx_get_data(libctx, default_method_store_index);
|
||||
return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX,
|
||||
&default_method_store_method);
|
||||
}
|
||||
|
||||
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
|
||||
const char *propquery, void *data)
|
||||
const char *name, const char *propquery,
|
||||
void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
void *method = NULL;
|
||||
OSSL_NAMEMAP *namemap;
|
||||
int id;
|
||||
|
||||
if (store == NULL
|
||||
&& (store = get_default_method_store(libctx)) == NULL)
|
||||
return NULL;
|
||||
|
||||
(void)ossl_method_store_fetch(store, methdata->nid, propquery, &method);
|
||||
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|
||||
|| (id = ossl_namemap_add(namemap, name)) == 0)
|
||||
return NULL;
|
||||
|
||||
(void)ossl_method_store_fetch(store, id, propquery, &method);
|
||||
|
||||
if (method != NULL
|
||||
&& !methdata->refcnt_up_method(method)) {
|
||||
@@ -107,13 +93,15 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
|
||||
}
|
||||
|
||||
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
|
||||
const char *propdef,
|
||||
void *method, void *data)
|
||||
void *method, const char *name,
|
||||
const char *propdef, void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
int nid = methdata->nid_method(method);
|
||||
OSSL_NAMEMAP *namemap;
|
||||
int id;
|
||||
|
||||
if (nid == NID_undef)
|
||||
if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
|
||||
|| (id = ossl_namemap_add(namemap, name)) == 0)
|
||||
return 0;
|
||||
|
||||
if (store == NULL
|
||||
@@ -121,41 +109,18 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
|
||||
return 0;
|
||||
|
||||
if (methdata->refcnt_up_method(method)
|
||||
&& ossl_method_store_add(store, nid, propdef, method,
|
||||
&& ossl_method_store_add(store, id, propdef, method,
|
||||
methdata->destruct_method))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *construct_method(const char *algorithm_name,
|
||||
const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
|
||||
void *data)
|
||||
static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
void *method = NULL;
|
||||
int nid = OBJ_sn2nid(algorithm_name);
|
||||
|
||||
if (nid == NID_undef) {
|
||||
/* Create a new NID for that name on the fly */
|
||||
ASN1_OBJECT tmpobj;
|
||||
|
||||
/* This is the same as OBJ_create() but without requiring a OID */
|
||||
tmpobj.nid = OBJ_new_nid(1);
|
||||
tmpobj.sn = tmpobj.ln = methdata->name;
|
||||
tmpobj.flags = ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
tmpobj.length = 0;
|
||||
tmpobj.data = NULL;
|
||||
|
||||
nid = OBJ_add_object(&tmpobj);
|
||||
}
|
||||
|
||||
if (nid == NID_undef)
|
||||
return NULL;
|
||||
|
||||
method = methdata->method_from_dispatch(nid, fns, prov);
|
||||
if (method == NULL)
|
||||
return NULL;
|
||||
return method;
|
||||
return methdata->method_from_dispatch(fns, prov);
|
||||
}
|
||||
|
||||
static void destruct_method(void *method, void *data)
|
||||
@@ -166,22 +131,22 @@ static void destruct_method(void *method, void *data)
|
||||
}
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
int (*nid_method)(void *))
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
|
||||
int nid = OBJ_sn2nid(algorithm);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
int id;
|
||||
void *method = NULL;
|
||||
|
||||
if (store == NULL)
|
||||
if (store == NULL || namemap == NULL)
|
||||
return NULL;
|
||||
|
||||
if (nid == NID_undef
|
||||
|| !ossl_method_store_cache_get(store, nid, properties, &method)) {
|
||||
if ((id = ossl_namemap_number(namemap, name)) == 0
|
||||
|| !ossl_method_store_cache_get(store, id, properties, &method)) {
|
||||
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
|
||||
alloc_tmp_method_store,
|
||||
dealloc_tmp_method_store,
|
||||
@@ -192,17 +157,16 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
};
|
||||
struct method_data_st mcmdata;
|
||||
|
||||
mcmdata.nid = nid;
|
||||
mcmdata.mcm = &mcm;
|
||||
mcmdata.libctx = libctx;
|
||||
mcmdata.method_from_dispatch = new_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
mcmdata.refcnt_up_method = upref_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
mcmdata.nid_method = nid_method;
|
||||
method = ossl_method_construct(libctx, operation_id, algorithm,
|
||||
method = ossl_method_construct(libctx, operation_id, name,
|
||||
properties, 0 /* !force_cache */,
|
||||
&mcm, &mcmdata);
|
||||
ossl_method_store_cache_set(store, nid, properties, method);
|
||||
ossl_method_store_cache_set(store, id, properties, method);
|
||||
} else {
|
||||
upref_method(method);
|
||||
}
|
||||
|
||||
@@ -232,8 +232,14 @@ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, unsigned int inl)
|
||||
{
|
||||
if (ctx->cipher->prov != NULL) {
|
||||
size_t outl = 0; /* ignored */
|
||||
int blocksize = EVP_CIPHER_CTX_block_size(ctx);
|
||||
|
||||
if (ctx->cipher->ccipher != NULL)
|
||||
return ctx->cipher->ccipher(ctx->provctx, out, in, (size_t)inl);
|
||||
return
|
||||
ctx->cipher->ccipher(ctx->provctx, out, &outl,
|
||||
inl + (blocksize == 1 ? 0 : blocksize),
|
||||
in, (size_t)inl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ struct evp_mac_ctx_st {
|
||||
} /* EVP_MAC_CTX */;
|
||||
|
||||
struct evp_kdf_ctx_st {
|
||||
const EVP_KDF_METHOD *kmeth;
|
||||
const EVP_KDF *meth; /* Method structure */
|
||||
EVP_KDF_IMPL *impl; /* Algorithm-specific data */
|
||||
} /* EVP_KDF_CTX */ ;
|
||||
|
||||
@@ -91,8 +91,7 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
int (*nid_method)(void *));
|
||||
void (*free_method)(void *));
|
||||
+33
-65
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -20,70 +20,39 @@
|
||||
#include "internal/numbers.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
||||
|
||||
/* This array needs to be in order of NIDs */
|
||||
static const EVP_KDF_METHOD *standard_methods[] = {
|
||||
&pbkdf2_kdf_meth,
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
&scrypt_kdf_meth,
|
||||
#endif
|
||||
&tls1_prf_kdf_meth,
|
||||
&hkdf_kdf_meth,
|
||||
&sshkdf_kdf_meth,
|
||||
&ss_kdf_meth
|
||||
};
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
|
||||
kmeth);
|
||||
|
||||
static int kmeth_cmp(const EVP_KDF_METHOD *const *a,
|
||||
const EVP_KDF_METHOD *const *b)
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
|
||||
{
|
||||
return ((*a)->type - (*b)->type);
|
||||
}
|
||||
EVP_KDF_CTX *ctx = NULL;
|
||||
|
||||
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
|
||||
kmeth);
|
||||
|
||||
static const EVP_KDF_METHOD *kdf_meth_find(int type)
|
||||
{
|
||||
EVP_KDF_METHOD tmp;
|
||||
const EVP_KDF_METHOD *t = &tmp, **ret;
|
||||
|
||||
tmp.type = type;
|
||||
ret = OBJ_bsearch_kmeth(&t, standard_methods,
|
||||
OSSL_NELEM(standard_methods));
|
||||
if (ret == NULL || *ret == NULL)
|
||||
if (kdf == NULL)
|
||||
return NULL;
|
||||
|
||||
return *ret;
|
||||
ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
|
||||
if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ctx);
|
||||
ctx = NULL;
|
||||
} else {
|
||||
ctx->meth = kdf;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
|
||||
{
|
||||
EVP_KDF_CTX *ret;
|
||||
const EVP_KDF_METHOD *kmeth;
|
||||
const EVP_KDF *kdf = EVP_get_kdfbynid(id);
|
||||
|
||||
kmeth = kdf_meth_find(id);
|
||||
if (kmeth == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
return EVP_KDF_CTX_new(kdf);
|
||||
}
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
int EVP_KDF_nid(const EVP_KDF *kdf)
|
||||
{
|
||||
return kdf->type;
|
||||
}
|
||||
|
||||
if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) {
|
||||
EVP_KDF_CTX_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->kmeth = kmeth;
|
||||
return ret;
|
||||
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
return ctx->meth;
|
||||
}
|
||||
|
||||
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
@@ -91,7 +60,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
ctx->kmeth->free(ctx->impl);
|
||||
ctx->meth->free(ctx->impl);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
@@ -100,8 +69,8 @@ void EVP_KDF_reset(EVP_KDF_CTX *ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
if (ctx->kmeth->reset != NULL)
|
||||
ctx->kmeth->reset(ctx->impl);
|
||||
if (ctx->meth->reset != NULL)
|
||||
ctx->meth->reset(ctx->impl);
|
||||
}
|
||||
|
||||
int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...)
|
||||
@@ -124,7 +93,7 @@ int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
return ctx->kmeth->ctrl(ctx->impl, cmd, args);
|
||||
return ctx->meth->ctrl(ctx->impl, cmd, args);
|
||||
}
|
||||
|
||||
int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
|
||||
@@ -134,12 +103,12 @@ int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx->kmeth->ctrl_str == NULL) {
|
||||
if (ctx->meth->ctrl_str == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
ret = ctx->kmeth->ctrl_str(ctx->impl, type, value);
|
||||
ret = ctx->meth->ctrl_str(ctx->impl, type, value);
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
|
||||
@@ -151,10 +120,10 @@ size_t EVP_KDF_size(EVP_KDF_CTX *ctx)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx->kmeth->size == NULL)
|
||||
if (ctx->meth->size == NULL)
|
||||
return SIZE_MAX;
|
||||
|
||||
return ctx->kmeth->size(ctx->impl);
|
||||
return ctx->meth->size(ctx->impl);
|
||||
}
|
||||
|
||||
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
|
||||
@@ -162,6 +131,5 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
return ctx->kmeth->derive(ctx->impl, key, keylen);
|
||||
return ctx->meth->derive(ctx->impl, key, keylen);
|
||||
}
|
||||
|
||||
+32
-1
@@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "internal/objects.h"
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.h"
|
||||
@@ -71,6 +72,23 @@ int EVP_add_mac(const EVP_MAC *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;
|
||||
@@ -104,9 +122,22 @@ const EVP_MAC *EVP_get_macbyname(const char *name)
|
||||
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);
|
||||
/*
|
||||
@@ -207,6 +238,7 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
|
||||
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,
|
||||
@@ -250,4 +282,3 @@ void EVP_MAC_do_all_sorted(void (*fn)
|
||||
dc.arg = arg;
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
|
||||
}
|
||||
|
||||
+14
-6
@@ -28,7 +28,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
|
||||
EVP_MD_CTX *ctx;
|
||||
unsigned char md_tmp[EVP_MAX_MD_SIZE];
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
|
||||
int i;
|
||||
int i, ivl, kl;
|
||||
PBEPARAM *pbe;
|
||||
int saltlen, iter;
|
||||
unsigned char *salt;
|
||||
@@ -48,6 +48,17 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl = EVP_CIPHER_iv_length(cipher);
|
||||
if (ivl < 0 || ivl > 16) {
|
||||
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
kl = EVP_CIPHER_key_length(cipher);
|
||||
if (kl < 0 || kl > (int)sizeof(md_tmp)) {
|
||||
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pbe->iter)
|
||||
iter = 1;
|
||||
else
|
||||
@@ -86,11 +97,8 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
|
||||
if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
|
||||
memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
|
||||
OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
|
||||
memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
|
||||
EVP_CIPHER_iv_length(cipher));
|
||||
memcpy(key, md_tmp, kl);
|
||||
memcpy(iv, md_tmp + (16 - ivl), ivl);
|
||||
if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
|
||||
goto err;
|
||||
OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
|
||||
|
||||
@@ -134,7 +134,7 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||
const EVP_CIPHER *c, const EVP_MD *md, int en_de)
|
||||
{
|
||||
unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
|
||||
int saltlen, iter;
|
||||
int saltlen, iter, t;
|
||||
int rv = 0;
|
||||
unsigned int keylen = 0;
|
||||
int prf_nid, hmac_md_nid;
|
||||
@@ -157,7 +157,12 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||
goto err;
|
||||
}
|
||||
|
||||
keylen = EVP_CIPHER_CTX_key_length(ctx);
|
||||
t = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (t < 0) {
|
||||
EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH);
|
||||
goto err;
|
||||
}
|
||||
keylen = t;
|
||||
|
||||
/* Now check the parameters of the kdf */
|
||||
|
||||
|
||||
+99
-65
@@ -10,58 +10,33 @@
|
||||
#include "internal/cryptlib_int.h"
|
||||
#include "internal/thread_once.h"
|
||||
|
||||
/*
|
||||
* Each structure type (sometimes called a class), that supports
|
||||
* exdata has a stack of callbacks for each instance.
|
||||
*/
|
||||
struct ex_callback_st {
|
||||
long argl; /* Arbitrary long */
|
||||
void *argp; /* Arbitrary void * */
|
||||
CRYPTO_EX_new *new_func;
|
||||
CRYPTO_EX_free *free_func;
|
||||
CRYPTO_EX_dup *dup_func;
|
||||
};
|
||||
|
||||
/*
|
||||
* The state for each class. This could just be a typedef, but
|
||||
* a structure allows future changes.
|
||||
*/
|
||||
typedef struct ex_callbacks_st {
|
||||
STACK_OF(EX_CALLBACK) *meth;
|
||||
} EX_CALLBACKS;
|
||||
|
||||
static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
|
||||
|
||||
static CRYPTO_RWLOCK *ex_data_lock = NULL;
|
||||
static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
|
||||
DEFINE_RUN_ONCE_STATIC(do_ex_data_init)
|
||||
int do_ex_data_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (!OPENSSL_init_crypto(0, NULL))
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
ex_data_lock = CRYPTO_THREAD_lock_new();
|
||||
return ex_data_lock != NULL;
|
||||
|
||||
global->ex_data_lock = CRYPTO_THREAD_lock_new();
|
||||
return global->ex_data_lock != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
|
||||
* a given class. On success, *holds the lock.*
|
||||
*/
|
||||
static EX_CALLBACKS *get_and_lock(int class_index)
|
||||
static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index)
|
||||
{
|
||||
EX_CALLBACKS *ip;
|
||||
OSSL_EX_DATA_GLOBAL *global = NULL;
|
||||
|
||||
if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
|
||||
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
|
||||
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ex_data_lock == NULL) {
|
||||
global = openssl_ctx_get_ex_data_global(ctx);
|
||||
if (global->ex_data_lock == NULL) {
|
||||
/*
|
||||
* This can happen in normal operation when using CRYPTO_mem_leaks().
|
||||
* The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans
|
||||
@@ -74,8 +49,8 @@ static EX_CALLBACKS *get_and_lock(int class_index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ip = &ex_data[class_index];
|
||||
CRYPTO_THREAD_write_lock(ex_data_lock);
|
||||
ip = &global->ex_data[class_index];
|
||||
CRYPTO_THREAD_write_lock(global->ex_data_lock);
|
||||
return ip;
|
||||
}
|
||||
|
||||
@@ -90,19 +65,23 @@ static void cleanup_cb(EX_CALLBACK *funcs)
|
||||
* called under potential race-conditions anyway (it's for program shutdown
|
||||
* after all).
|
||||
*/
|
||||
void crypto_cleanup_all_ex_data_int(void)
|
||||
void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx)
|
||||
{
|
||||
int i;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) {
|
||||
EX_CALLBACKS *ip = &ex_data[i];
|
||||
EX_CALLBACKS *ip = &global->ex_data[i];
|
||||
|
||||
sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb);
|
||||
ip->meth = NULL;
|
||||
}
|
||||
|
||||
CRYPTO_THREAD_lock_free(ex_data_lock);
|
||||
ex_data_lock = NULL;
|
||||
CRYPTO_THREAD_lock_free(global->ex_data_lock);
|
||||
global->ex_data_lock = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,12 +106,17 @@ static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_free_ex_index(int class_index, int idx)
|
||||
int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx)
|
||||
{
|
||||
EX_CALLBACKS *ip = get_and_lock(class_index);
|
||||
EX_CALLBACKS *ip = get_and_lock(ctx, class_index);
|
||||
EX_CALLBACK *a;
|
||||
int toret = 0;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
|
||||
@@ -145,21 +129,32 @@ int CRYPTO_free_ex_index(int class_index, int idx)
|
||||
a->free_func = dummy_free;
|
||||
toret = 1;
|
||||
err:
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
return toret;
|
||||
}
|
||||
|
||||
int CRYPTO_free_ex_index(int class_index, int idx)
|
||||
{
|
||||
return crypto_free_ex_index_ex(NULL, class_index, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a new index.
|
||||
*/
|
||||
int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func)
|
||||
int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl,
|
||||
void *argp, CRYPTO_EX_new *new_func,
|
||||
CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func)
|
||||
{
|
||||
int toret = -1;
|
||||
EX_CALLBACK *a;
|
||||
EX_CALLBACKS *ip = get_and_lock(class_index);
|
||||
EX_CALLBACKS *ip;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return -1;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
|
||||
@@ -169,14 +164,14 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
* "app_data" routines use ex_data index zero. See RT 3710. */
|
||||
if (ip->meth == NULL
|
||||
|| !sk_EX_CALLBACK_push(ip->meth, NULL)) {
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a));
|
||||
if (a == NULL) {
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
a->argl = argl;
|
||||
@@ -186,7 +181,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
a->free_func = free_func;
|
||||
|
||||
if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(a);
|
||||
goto err;
|
||||
}
|
||||
@@ -194,10 +189,18 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
(void)sk_EX_CALLBACK_set(ip->meth, toret, a);
|
||||
|
||||
err:
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
return toret;
|
||||
}
|
||||
|
||||
int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func)
|
||||
{
|
||||
return crypto_get_ex_new_index_ex(NULL, class_index, argl, argp, new_func,
|
||||
dup_func, free_func);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
|
||||
* calling new() callbacks for each index in the class used by this variable
|
||||
@@ -205,17 +208,24 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
|
||||
* in the lock, then using them outside the lock. Note this only applies
|
||||
* to the global "ex_data" state (ie. class definitions), not 'ad' itself.
|
||||
*/
|
||||
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
|
||||
CRYPTO_EX_DATA *ad)
|
||||
{
|
||||
int mx, i;
|
||||
void *ptr;
|
||||
EX_CALLBACK **storage = NULL;
|
||||
EX_CALLBACK *stack[10];
|
||||
EX_CALLBACKS *ip = get_and_lock(class_index);
|
||||
EX_CALLBACKS *ip;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
|
||||
ad->ctx = ctx;
|
||||
ad->sk = NULL;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
@@ -228,10 +238,10 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
for (i = 0; i < mx; i++)
|
||||
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
|
||||
}
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
|
||||
if (mx > 0 && storage == NULL) {
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
|
||||
CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < mx; i++) {
|
||||
@@ -246,6 +256,11 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
{
|
||||
return crypto_new_ex_data_ex(NULL, class_index, obj, ad);
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
|
||||
* for each index in the class used by this variable
|
||||
@@ -259,11 +274,16 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
|
||||
EX_CALLBACK **storage = NULL;
|
||||
EX_CALLBACKS *ip;
|
||||
int toret = 0;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(from->ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
to->ctx = from->ctx;
|
||||
if (from->sk == NULL)
|
||||
/* Nothing to copy over */
|
||||
return 1;
|
||||
if ((ip = get_and_lock(class_index)) == NULL)
|
||||
if ((ip = get_and_lock(from->ctx, class_index)) == NULL)
|
||||
return 0;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
@@ -279,7 +299,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
|
||||
for (i = 0; i < mx; i++)
|
||||
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
|
||||
}
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
|
||||
if (mx == 0)
|
||||
return 1;
|
||||
@@ -325,8 +345,12 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
EX_CALLBACK *f;
|
||||
EX_CALLBACK *stack[10];
|
||||
EX_CALLBACK **storage = NULL;
|
||||
OSSL_EX_DATA_GLOBAL *global;
|
||||
|
||||
if ((ip = get_and_lock(class_index)) == NULL)
|
||||
if ((ip = get_and_lock(ad->ctx, class_index)) == NULL)
|
||||
goto err;
|
||||
global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
if (global == NULL)
|
||||
goto err;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
@@ -339,15 +363,15 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
for (i = 0; i < mx; i++)
|
||||
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
|
||||
}
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
|
||||
for (i = 0; i < mx; i++) {
|
||||
if (storage != NULL)
|
||||
f = storage[i];
|
||||
else {
|
||||
CRYPTO_THREAD_write_lock(ex_data_lock);
|
||||
CRYPTO_THREAD_write_lock(global->ex_data_lock);
|
||||
f = sk_EX_CALLBACK_value(ip->meth, i);
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
}
|
||||
if (f != NULL && f->free_func != NULL) {
|
||||
ptr = CRYPTO_get_ex_data(ad, i);
|
||||
@@ -360,6 +384,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
err:
|
||||
sk_void_free(ad->sk);
|
||||
ad->sk = NULL;
|
||||
ad->ctx = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -372,6 +397,10 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
||||
EX_CALLBACK *f;
|
||||
EX_CALLBACKS *ip;
|
||||
void *curval;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
curval = CRYPTO_get_ex_data(ad, idx);
|
||||
|
||||
@@ -379,11 +408,11 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
||||
if (curval != NULL)
|
||||
return 1;
|
||||
|
||||
ip = get_and_lock(class_index);
|
||||
ip = get_and_lock(ad->ctx, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
f = sk_EX_CALLBACK_value(ip->meth, idx);
|
||||
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||
CRYPTO_THREAD_unlock(global->ex_data_lock);
|
||||
|
||||
/*
|
||||
* This should end up calling CRYPTO_set_ex_data(), which allocates
|
||||
@@ -432,3 +461,8 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
|
||||
return NULL;
|
||||
return sk_void_value(ad->sk, idx);
|
||||
}
|
||||
|
||||
OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad)
|
||||
{
|
||||
return ad->ctx;
|
||||
}
|
||||
@@ -151,10 +151,11 @@ const EVP_MD *evp_keccak_kmac256(void);
|
||||
* 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;
|
||||
typedef struct {
|
||||
struct evp_kdf_st {
|
||||
int type;
|
||||
EVP_KDF_IMPL *(*new) (void);
|
||||
void (*free) (EVP_KDF_IMPL *impl);
|
||||
@@ -163,14 +164,15 @@ typedef struct {
|
||||
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);
|
||||
} EVP_KDF_METHOD;
|
||||
};
|
||||
|
||||
extern const EVP_KDF_METHOD pbkdf2_kdf_meth;
|
||||
extern const EVP_KDF_METHOD scrypt_kdf_meth;
|
||||
extern const EVP_KDF_METHOD tls1_prf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD hkdf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD sshkdf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD ss_kdf_meth;
|
||||
extern const EVP_KDF pbkdf2_kdf_meth;
|
||||
extern const EVP_KDF scrypt_kdf_meth;
|
||||
extern const EVP_KDF tls1_prf_kdf_meth;
|
||||
extern const EVP_KDF hkdf_kdf_meth;
|
||||
extern const EVP_KDF sshkdf_kdf_meth;
|
||||
extern const EVP_KDF ss_kdf_meth;
|
||||
extern const EVP_KDF x963_kdf_meth;
|
||||
|
||||
struct evp_md_st {
|
||||
/* nid */
|
||||
@@ -528,6 +530,7 @@ struct evp_pkey_st {
|
||||
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);
|
||||
|
||||
|
||||
+43
-3
@@ -293,6 +293,26 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs)
|
||||
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;
|
||||
@@ -468,6 +488,11 @@ void OPENSSL_cleanup(void)
|
||||
OPENSSL_INIT_STOP *currhandler, *lasthandler;
|
||||
CRYPTO_THREAD_LOCAL key;
|
||||
|
||||
/*
|
||||
* TODO(3.0): This function needs looking at with a view to moving most/all
|
||||
* of this into onfree handlers in OPENSSL_CTX.
|
||||
*/
|
||||
|
||||
/* If we've not been inited then no need to deinit */
|
||||
if (!base_inited)
|
||||
return;
|
||||
@@ -526,7 +551,7 @@ void OPENSSL_cleanup(void)
|
||||
* - rand_cleanup_int could call an ENGINE's RAND cleanup function so
|
||||
* must be called before engine_cleanup_int()
|
||||
* - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
|
||||
* before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
|
||||
* before the ex data handlers are wiped during default openssl_ctx deinit.
|
||||
* - conf_modules_free_int() can end up in ENGINE code so must be called
|
||||
* before engine_cleanup_int()
|
||||
* - ENGINEs and additional EVP algorithms might use added OIDs names so
|
||||
@@ -540,6 +565,7 @@ void OPENSSL_cleanup(void)
|
||||
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: conf_modules_free_int()\n");
|
||||
conf_modules_free_int();
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
|
||||
engine_cleanup_int();
|
||||
@@ -547,8 +573,8 @@ void OPENSSL_cleanup(void)
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
|
||||
ossl_store_cleanup_int();
|
||||
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: crypto_cleanup_all_ex_data_int()\n");
|
||||
crypto_cleanup_all_ex_data_int();
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n");
|
||||
openssl_ctx_default_deinit();
|
||||
|
||||
OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
|
||||
bio_cleanup();
|
||||
@@ -578,6 +604,11 @@ void OPENSSL_cleanup(void)
|
||||
*/
|
||||
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
||||
{
|
||||
/*
|
||||
* TODO(3.0): This function needs looking at with a view to moving most/all
|
||||
* of this into OPENSSL_CTX.
|
||||
*/
|
||||
|
||||
if (stopped) {
|
||||
if (!(opts & OPENSSL_INIT_BASE_ONLY))
|
||||
CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
|
||||
@@ -655,6 +686,15 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
||||
&& !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;
|
||||
|
||||
+1
-1
@@ -229,7 +229,7 @@ static int kdf_hkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD hkdf_kdf_meth = {
|
||||
const EVP_KDF hkdf_kdf_meth = {
|
||||
EVP_KDF_HKDF,
|
||||
kdf_hkdf_new,
|
||||
kdf_hkdf_free,
|
||||
|
||||
@@ -65,6 +65,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||
{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_X963KDF_DERIVE, 0), "x963kdf_derive"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -84,6 +85,7 @@ static const ERR_STRING_DATA KDF_str_reasons[] = {
|
||||
{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_MAC_TYPE),
|
||||
|
||||
+1
-1
@@ -180,7 +180,7 @@ static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
impl->md, key, keylen);
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD pbkdf2_kdf_meth = {
|
||||
const EVP_KDF pbkdf2_kdf_meth = {
|
||||
EVP_KDF_PBKDF2,
|
||||
kdf_pbkdf2_new,
|
||||
kdf_pbkdf2_free,
|
||||
|
||||
+1
-1
@@ -266,7 +266,7 @@ static int kdf_scrypt_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
impl->maxmem_bytes, key, keylen);
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD scrypt_kdf_meth = {
|
||||
const EVP_KDF scrypt_kdf_meth = {
|
||||
EVP_KDF_SCRYPT,
|
||||
kdf_scrypt_new,
|
||||
kdf_scrypt_free,
|
||||
|
||||
+4
-1
@@ -125,6 +125,9 @@ static int kdf_sshkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||
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);
|
||||
|
||||
@@ -200,7 +203,7 @@ static int kdf_sshkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
impl->type, key, keylen);
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD sshkdf_kdf_meth = {
|
||||
const EVP_KDF sshkdf_kdf_meth = {
|
||||
EVP_KDF_SSHKDF,
|
||||
kdf_sshkdf_new,
|
||||
kdf_sshkdf_free,
|
||||
|
||||
+42
-3
@@ -66,10 +66,16 @@ static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
|
||||
/*
|
||||
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
|
||||
* Section 4. One-Step Key Derivation using H(x) = hash(x)
|
||||
* Note: X9.63 also uses this code with the only difference being that the
|
||||
* counter is appended to the secret 'z'.
|
||||
* i.e.
|
||||
* result[i] = Hash(counter || z || info) for One Step OR
|
||||
* result[i] = Hash(z || counter || info) for X9.63.
|
||||
*/
|
||||
static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
|
||||
const unsigned char *z, size_t z_len,
|
||||
const unsigned char *info, size_t info_len,
|
||||
unsigned int append_ctr,
|
||||
unsigned char *derived_key, size_t derived_key_len)
|
||||
{
|
||||
int ret = 0, hlen;
|
||||
@@ -104,8 +110,9 @@ static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
|
||||
c[3] = (unsigned char)(counter & 0xff);
|
||||
|
||||
if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
|
||||
&& EVP_DigestUpdate(ctx, c, sizeof(c))
|
||||
&& (append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
|
||||
&& EVP_DigestUpdate(ctx, z, z_len)
|
||||
&& (!append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
|
||||
&& EVP_DigestUpdate(ctx, info, info_len)))
|
||||
goto end;
|
||||
if (len >= out_len) {
|
||||
@@ -468,11 +475,32 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
|
||||
return 0;
|
||||
}
|
||||
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
|
||||
impl->info, impl->info_len, key, keylen);
|
||||
impl->info, impl->info_len, 0, key, keylen);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD ss_kdf_meth = {
|
||||
static int x963kdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
|
||||
{
|
||||
if (impl->secret == NULL) {
|
||||
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_SECRET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (impl->mac != NULL) {
|
||||
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_NOT_SUPPORTED);
|
||||
return 0;
|
||||
} else {
|
||||
/* H(x) = hash */
|
||||
if (impl->md == NULL) {
|
||||
KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
|
||||
impl->info, impl->info_len, 1, key, keylen);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_KDF ss_kdf_meth = {
|
||||
EVP_KDF_SS,
|
||||
sskdf_new,
|
||||
sskdf_free,
|
||||
@@ -482,3 +510,14 @@ const EVP_KDF_METHOD ss_kdf_meth = {
|
||||
sskdf_size,
|
||||
sskdf_derive
|
||||
};
|
||||
|
||||
const EVP_KDF x963_kdf_meth = {
|
||||
EVP_KDF_X963,
|
||||
sskdf_new,
|
||||
sskdf_free,
|
||||
sskdf_reset,
|
||||
sskdf_ctrl,
|
||||
sskdf_ctrl_str,
|
||||
sskdf_size,
|
||||
x963kdf_derive
|
||||
};
|
||||
@@ -157,7 +157,7 @@ static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
key, keylen);
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD tls1_prf_kdf_meth = {
|
||||
const EVP_KDF tls1_prf_kdf_meth = {
|
||||
EVP_KDF_TLS1_PRF,
|
||||
kdf_tls1_prf_new,
|
||||
kdf_tls1_prf_free,
|
||||
|
||||
+1
-1
@@ -33,8 +33,8 @@
|
||||
# include <linux/mman.h>
|
||||
# include <errno.h>
|
||||
# endif
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# include <sys/param.h>
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
@@ -585,52 +585,32 @@ const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
|
||||
return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
|
||||
}
|
||||
|
||||
const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
|
||||
const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
|
||||
int size,
|
||||
int (*cmp) (const void *, const void *),
|
||||
int flags)
|
||||
{
|
||||
const char *base = base_;
|
||||
int l, h, i = 0, c = 0;
|
||||
const char *p = NULL;
|
||||
const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
|
||||
|
||||
if (num == 0)
|
||||
return NULL;
|
||||
l = 0;
|
||||
h = num;
|
||||
while (l < h) {
|
||||
i = (l + h) / 2;
|
||||
p = &(base[i * size]);
|
||||
c = (*cmp) (key, p);
|
||||
if (c < 0)
|
||||
h = i;
|
||||
else if (c > 0)
|
||||
l = i + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#ifdef CHARSET_EBCDIC
|
||||
/*
|
||||
* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
|
||||
* don't have perl (yet), we revert to a *LINEAR* search when the object
|
||||
* wasn't found in the binary search.
|
||||
*/
|
||||
if (c != 0) {
|
||||
if (p == NULL) {
|
||||
const char *base_ = base;
|
||||
int l, h, i = 0, c = 0;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
p = &(base[i * size]);
|
||||
p = &(base_[i * size]);
|
||||
c = (*cmp) (key, p);
|
||||
if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
|
||||
if (c == 0
|
||||
|| (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
|
||||
p = NULL;
|
||||
else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
|
||||
while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
|
||||
i--;
|
||||
p = &(base[i * size]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@@ -1070,7 +1070,7 @@ static const unsigned char so[7775] = {
|
||||
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01, /* [ 7684] OBJ_id_tc26_wrap_gostr3412_2015_magma */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7692] OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02, /* [ 7701] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7709] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02,0x01, /* [ 7709] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x02, /* [ 7718] OBJ_id_tc26_gost_3410_2012_256_paramSetB */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x03, /* [ 7727] OBJ_id_tc26_gost_3410_2012_256_paramSetC */
|
||||
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */
|
||||
@@ -1080,7 +1080,7 @@ static const unsigned char so[7775] = {
|
||||
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7766] OBJ_SM2_with_SM3 */
|
||||
};
|
||||
|
||||
#define NUM_NID 1207
|
||||
#define NUM_NID 1208
|
||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"UNDEF", "undefined", NID_undef},
|
||||
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
||||
@@ -2288,10 +2288,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"SSHKDF", "sshkdf", NID_sshkdf},
|
||||
{"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7766]},
|
||||
{"SSKDF", "sskdf", NID_sskdf},
|
||||
{"X963KDF", "x963kdf", NID_x963kdf},
|
||||
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft},
|
||||
};
|
||||
|
||||
#define NUM_SN 1198
|
||||
#define NUM_SN 1199
|
||||
static const unsigned int sn_objs[NUM_SN] = {
|
||||
364, /* "AD_DVCS" */
|
||||
419, /* "AES-128-CBC" */
|
||||
@@ -2414,7 +2415,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
417, /* "CSPName" */
|
||||
1019, /* "ChaCha20" */
|
||||
1018, /* "ChaCha20-Poly1305" */
|
||||
1206, /* "ChaCha20-Poly1305-D" */
|
||||
1207, /* "ChaCha20-Poly1305-D" */
|
||||
367, /* "CrlID" */
|
||||
391, /* "DC" */
|
||||
31, /* "DES-CBC" */
|
||||
@@ -2593,6 +2594,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
378, /* "X500algorithms" */
|
||||
12, /* "X509" */
|
||||
184, /* "X9-57" */
|
||||
1206, /* "X963KDF" */
|
||||
185, /* "X9cm" */
|
||||
125, /* "ZLIB" */
|
||||
478, /* "aRecord" */
|
||||
@@ -3493,7 +3495,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
1093, /* "x509ExtAdmission" */
|
||||
};
|
||||
|
||||
#define NUM_LN 1198
|
||||
#define NUM_LN 1199
|
||||
static const unsigned int ln_objs[NUM_LN] = {
|
||||
363, /* "AD Time Stamping" */
|
||||
405, /* "ANSI X9.62" */
|
||||
@@ -3878,7 +3880,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
883, /* "certificateRevocationList" */
|
||||
1019, /* "chacha20" */
|
||||
1018, /* "chacha20-poly1305" */
|
||||
1206, /* "chacha20-poly1305-draft" */
|
||||
1207, /* "chacha20-poly1305-draft" */
|
||||
54, /* "challengePassword" */
|
||||
407, /* "characteristic-two-field" */
|
||||
395, /* "clearance" */
|
||||
@@ -4692,6 +4694,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
503, /* "x500UniqueIdentifier" */
|
||||
158, /* "x509Certificate" */
|
||||
160, /* "x509Crl" */
|
||||
1206, /* "x963kdf" */
|
||||
125, /* "zlib compression" */
|
||||
};
|
||||
|
||||
@@ -5404,7 +5407,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
|
||||
1177, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1 2 643 7 1 1 5 2 1 */
|
||||
1178, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1 2 643 7 1 1 5 2 2 */
|
||||
1181, /* OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 1 2 643 7 1 1 7 1 1 */
|
||||
1183, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1 2 643 7 1 1 7 1 1 */
|
||||
1183, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */
|
||||
1148, /* OBJ_id_tc26_gost_3410_2012_256_paramSetA 1 2 643 7 1 2 1 1 1 */
|
||||
1184, /* OBJ_id_tc26_gost_3410_2012_256_paramSetB 1 2 643 7 1 2 1 1 2 */
|
||||
1185, /* OBJ_id_tc26_gost_3410_2012_256_paramSetC 1 2 643 7 1 2 1 1 3 */
|
||||
|
||||
@@ -1203,4 +1203,5 @@ blake2smac 1202
|
||||
sshkdf 1203
|
||||
SM2_with_SM3 1204
|
||||
sskdf 1205
|
||||
chacha20_poly1305_draft 1206
|
||||
x963kdf 1206
|
||||
chacha20_poly1305_draft 1207
|
||||
@@ -1369,7 +1369,7 @@ id-tc26-algorithms 7 : id-tc26-wrap
|
||||
id-tc26-wrap 1 : id-tc26-wrap-gostr3412-2015-magma
|
||||
id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-magma-kexp15
|
||||
id-tc26-wrap 2 : id-tc26-wrap-gostr3412-2015-kuznyechik
|
||||
id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
|
||||
id-tc26-wrap-gostr3412-2015-kuznyechik 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
|
||||
|
||||
id-tc26 2 : id-tc26-constants
|
||||
|
||||
@@ -1618,6 +1618,9 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
|
||||
# NID for SSKDF
|
||||
: SSKDF : sskdf
|
||||
|
||||
# NID for X963-2001 KDF
|
||||
: X963KDF : x963kdf
|
||||
|
||||
# RFC 4556
|
||||
1 3 6 1 5 2 3 : id-pkinit
|
||||
id-pkinit 4 : pkInitClientAuth : PKINIT Client Auth
|
||||
|
||||
+393
-82
@@ -156,12 +156,54 @@ OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
|
||||
|
||||
int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
|
||||
{
|
||||
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
|
||||
int64_t i64;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
double d;
|
||||
|
||||
if (val == NULL || p == NULL )
|
||||
return 0;
|
||||
|
||||
if (p->data_size == sizeof(int32_t)) {
|
||||
*val = *(const int32_t *)p->data;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
*val = *(const int32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
i64 = *(const int64_t *)p->data;
|
||||
if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
|
||||
*val = (int32_t)i64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
u32 = *(const uint32_t *)p->data;
|
||||
if (u32 <= INT32_MAX) {
|
||||
*val = (int32_t)u32;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
u64 = *(const uint64_t *)p->data;
|
||||
if (u64 <= INT32_MAX) {
|
||||
*val = (int32_t)u64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
d = *(const double *)p->data;
|
||||
if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
|
||||
*val = (int32_t)d;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -171,19 +213,35 @@ int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = val;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
*(int32_t *)p->data = val;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
*(double *)p->data = (double)val;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -197,35 +255,96 @@ OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
|
||||
|
||||
int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
|
||||
{
|
||||
if (val == NULL
|
||||
|| p == NULL
|
||||
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
double d;
|
||||
|
||||
if (val == NULL || p == NULL)
|
||||
return 0;
|
||||
|
||||
if (p->data_size == sizeof(uint32_t)) {
|
||||
*val = *(const uint32_t *)p->data;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*val = *(const uint32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
u64 = *(const uint64_t *)p->data;
|
||||
if (u64 <= UINT32_MAX) {
|
||||
*val = (uint32_t)u64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
i32 = *(const int32_t *)p->data;
|
||||
if (i32 >= 0) {
|
||||
*val = i32;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
i64 = *(const int64_t *)p->data;
|
||||
if (i64 >= 0 && i64 <= UINT32_MAX) {
|
||||
*val = (uint32_t)i64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
d = *(const double *)p->data;
|
||||
if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
|
||||
*val = (uint32_t)d;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
|
||||
{
|
||||
if (p == NULL) return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = val;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*(uint32_t *)p->data = val;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
if (val <= INT32_MAX) {
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
*(double *)p->data = (double)val;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -239,34 +358,94 @@ OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
|
||||
|
||||
int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
|
||||
{
|
||||
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
|
||||
uint64_t u64;
|
||||
double d;
|
||||
|
||||
if (val == NULL || p == NULL )
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
*val = (int64_t)*(const int32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
*val = *(const int64_t *)p->data;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
*val = *(const int32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
*val = *(const int64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*val = *(const uint32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
u64 = *(const uint64_t *)p->data;
|
||||
if (u64 <= INT64_MAX) {
|
||||
*val = (int64_t)u64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
d = *(const double *)p->data;
|
||||
if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
|
||||
*val = (int64_t)d;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
|
||||
{
|
||||
uint64_t u64;
|
||||
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = val;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
if (val >= INT32_MIN && val <= INT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
*(int64_t *)p->data = val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
if (val <= UINT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
u64 = val < 0 ? -val : val;
|
||||
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
|
||||
*(double *)p->data = (double)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -280,18 +459,49 @@ OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
|
||||
|
||||
int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
|
||||
{
|
||||
if (val == NULL
|
||||
|| p == NULL
|
||||
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
double d;
|
||||
|
||||
if (val == NULL || p == NULL)
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*val = (uint64_t)*(const uint32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
*val = *(const uint64_t *)p->data;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*val = *(const uint32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
*val = *(const uint64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
i32 = *(const int32_t *)p->data;
|
||||
if (i32 >= 0) {
|
||||
*val = (uint64_t)i32;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
i64 = *(const int64_t *)p->data;
|
||||
if (i64 >= 0) {
|
||||
*val = (uint64_t)i64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
d = *(const double *)p->data;
|
||||
if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
|
||||
*val = (uint64_t)d;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -301,15 +511,48 @@ int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = val;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
if (val <= UINT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
*(uint64_t *)p->data = val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
if (val <= INT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
if (val <= INT64_MAX) {
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_REAL) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
|
||||
*(double *)p->data = (double)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -402,13 +645,45 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
|
||||
|
||||
int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
|
||||
{
|
||||
if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
|
||||
if (val == NULL || p == NULL)
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
*val = *(const double *)p->data;
|
||||
return 1;
|
||||
if (p->data_type == OSSL_PARAM_REAL) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
*val = *(const double *)p->data;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
*val = *(const uint32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(uint64_t):
|
||||
u64 = *(const uint64_t *)p->data;
|
||||
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
|
||||
*val = (double)u64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER) {
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
*val = *(const int32_t *)p->data;
|
||||
return 1;
|
||||
case sizeof(int64_t):
|
||||
i64 = *(const int64_t *)p->data;
|
||||
u64 = i64 < 0 ? -i64 : i64;
|
||||
if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
|
||||
*val = 0.0 + i64;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -418,14 +693,50 @@ int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_REAL)
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
if (p->data_type == OSSL_PARAM_REAL) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
*(double *)p->data = val;
|
||||
return 1;
|
||||
switch (p->data_size) {
|
||||
case sizeof(double):
|
||||
*(double *)p->data = val;
|
||||
return 1;
|
||||
}
|
||||
} else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
|
||||
&& val == (uintmax_t)val) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(uint32_t):
|
||||
if (val >= 0 && val <= UINT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
if (val >= 0 && val <= UINT64_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break; }
|
||||
} else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) {
|
||||
SET_RETURN_SIZE(p, sizeof(double));
|
||||
switch (p->data_size) {
|
||||
case sizeof(int32_t):
|
||||
if (val >= INT32_MIN && val <= INT32_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case sizeof(int64_t):
|
||||
if (val >= INT64_MIN && val <= INT64_MAX) {
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-2
@@ -323,6 +323,7 @@ void OPENSSL_cpuid_setup(void)
|
||||
#ifdef OSSL_IMPLEMENT_GETAUXVAL
|
||||
{
|
||||
unsigned long hwcap = getauxval(HWCAP);
|
||||
unsigned long hwcap2 = getauxval(HWCAP2);
|
||||
|
||||
if (hwcap & HWCAP_FPU) {
|
||||
OPENSSL_ppccap_P |= PPC_FPU;
|
||||
@@ -341,11 +342,11 @@ void OPENSSL_cpuid_setup(void)
|
||||
if (hwcap & HWCAP_ALTIVEC) {
|
||||
OPENSSL_ppccap_P |= PPC_ALTIVEC;
|
||||
|
||||
if ((hwcap & HWCAP_VSX) && (getauxval(HWCAP2) & HWCAP_VEC_CRYPTO))
|
||||
if ((hwcap & HWCAP_VSX) && (hwcap2 & HWCAP_VEC_CRYPTO))
|
||||
OPENSSL_ppccap_P |= PPC_CRYPTO207;
|
||||
}
|
||||
|
||||
if (hwcap & HWCAP_ARCH_3_00) {
|
||||
if (hwcap2 & HWCAP_ARCH_3_00) {
|
||||
OPENSSL_ppccap_P |= PPC_MADD300;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@ typedef struct {
|
||||
|
||||
DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM);
|
||||
|
||||
static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL;
|
||||
|
||||
static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a)
|
||||
{
|
||||
return OPENSSL_LH_strhash(a->prop);
|
||||
@@ -48,35 +46,52 @@ static void property_defn_free(PROPERTY_DEFN_ELEM *elem)
|
||||
OPENSSL_free(elem);
|
||||
}
|
||||
|
||||
int ossl_prop_defn_init(void)
|
||||
static void property_defns_free(void *vproperty_defns)
|
||||
{
|
||||
property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash,
|
||||
&property_defn_cmp);
|
||||
return property_defns != NULL;
|
||||
}
|
||||
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns;
|
||||
|
||||
void ossl_prop_defn_cleanup(void)
|
||||
{
|
||||
if (property_defns != NULL) {
|
||||
lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free);
|
||||
lh_PROPERTY_DEFN_ELEM_doall(property_defns,
|
||||
&property_defn_free);
|
||||
lh_PROPERTY_DEFN_ELEM_free(property_defns);
|
||||
property_defns = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop)
|
||||
static void *property_defns_new(OPENSSL_CTX *ctx) {
|
||||
return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp);
|
||||
}
|
||||
|
||||
static const OPENSSL_CTX_METHOD property_defns_method = {
|
||||
property_defns_new,
|
||||
property_defns_free,
|
||||
};
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop)
|
||||
{
|
||||
PROPERTY_DEFN_ELEM elem, *r;
|
||||
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
|
||||
|
||||
property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX,
|
||||
&property_defns_method);
|
||||
if (property_defns == NULL)
|
||||
return NULL;
|
||||
|
||||
elem.prop = prop;
|
||||
r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
|
||||
return r != NULL ? r->defn : NULL;
|
||||
}
|
||||
|
||||
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl)
|
||||
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
|
||||
OSSL_PROPERTY_LIST *pl)
|
||||
{
|
||||
PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
|
||||
size_t len;
|
||||
LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
|
||||
|
||||
property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX,
|
||||
&property_defns_method);
|
||||
if (property_defns == NULL)
|
||||
return 0;
|
||||
|
||||
if (prop == NULL)
|
||||
return 1;
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
|
||||
Definition
|
||||
::= PropertyName ( '=' Value )? ( ',' PropertyName ( '=' Value )? )*
|
||||
Query ::= ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value )
|
||||
( ',' ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) )*
|
||||
Query ::= PropertyQuery ( ',' PropertyQuery )*
|
||||
PropertyQuery ::= '-'? PropertyName
|
||||
| '?' ( PropertyName (( '=' | '!=' ) Value)?)
|
||||
Value ::= NumberLiteral
|
||||
| StringLiteral
|
||||
StringLiteral ::= QuotedString | UnquotedString
|
||||
QuotedString ::= '"' [^"]* '"'
|
||||
| "'" [^']* "'"
|
||||
| "'" [^']* "'"
|
||||
UnquotedString ::= [^{space},]+
|
||||
NumberLiteral
|
||||
::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ )
|
||||
| '-'? [1-9] [0-9]+
|
||||
| '-'? [1-9] [0-9]+
|
||||
PropertyName
|
||||
::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*
|
||||
Regular → Executable
+76
-28
@@ -2,7 +2,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
<meta name="generator" content="Railroad Diagram Generator 1.56.1774" />
|
||||
<meta name="generator" content="Railroad Diagram Generator 1.59.1797" />
|
||||
<style type="text/css">
|
||||
::-moz-selection
|
||||
{
|
||||
@@ -133,7 +133,7 @@
|
||||
display: block;
|
||||
padding: 10px;
|
||||
background: #FFF6D1;
|
||||
width: 1000px;
|
||||
width: 992px;
|
||||
}
|
||||
#divs div.grammar
|
||||
{
|
||||
@@ -268,7 +268,7 @@
|
||||
<div><a href="#Definition" title="Definition">Definition</a></div>
|
||||
<div> ::= <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? ( ',' <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? )*</div></xhtml:code></xhtml:div>
|
||||
</xhtml:p>
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Query">Query:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="419" height="201">
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Query">Query:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="211" height="81">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
@namespace "http://www.w3.org/2000/svg";
|
||||
@@ -299,33 +299,81 @@
|
||||
</style>
|
||||
</defs>
|
||||
<polygon points="9 61 1 57 1 65"/>
|
||||
<polygon points="17 61 9 57 9 65"/>
|
||||
<rect x="91" y="79" width="26" height="32" rx="10"/>
|
||||
<rect x="89" y="77" width="26" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="99" y="97">-</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||
<rect x="157" y="47" width="110" height="32"/>
|
||||
<rect x="155" y="45" width="110" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="165" y="65">PropertyName</text></a><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||
<rect x="71" y="123" width="110" height="32"/>
|
||||
<rect x="69" y="121" width="110" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="79" y="141">PropertyName</text></a><rect x="221" y="123" width="30" height="32" rx="10"/>
|
||||
<rect x="219" y="121" width="30" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="229" y="141">=</text>
|
||||
<rect x="221" y="167" width="34" height="32" rx="10"/>
|
||||
<rect x="219" y="165" width="34" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="229" y="185">!=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
|
||||
<rect x="295" y="123" width="56" height="32"/>
|
||||
<rect x="293" y="121" width="56" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="303" y="141">Value</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
|
||||
<polygon points="17 61 9 57 9 65"/><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyQuery" xlink:title="PropertyQuery">
|
||||
<rect x="51" y="47" width="112" height="32"/>
|
||||
<rect x="49" y="45" width="112" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="59" y="65">PropertyQuery</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
|
||||
<rect x="49" y="1" width="24" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="59" y="21">,</text>
|
||||
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m60 0 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m110 0 h10 m0 0 h84 m-320 0 h20 m300 0 h20 m-340 0 q10 0 10 10 m320 0 q0 -10 10 -10 m-330 10 v56 m320 0 v-56 m-320 56 q0 10 10 10 m300 0 q10 0 10 -10 m-310 10 h10 m110 0 h10 m20 0 h10 m30 0 h10 m0 0 h4 m-74 0 h20 m54 0 h20 m-94 0 q10 0 10 10 m74 0 q0 -10 10 -10 m-84 10 v24 m74 0 v-24 m-74 24 q0 10 10 10 m54 0 q10 0 10 -10 m-64 10 h10 m34 0 h10 m20 -44 h10 m56 0 h10 m-340 -76 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m340 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-340 0 h10 m24 0 h10 m0 0 h296 m23 44 h-3"/>
|
||||
<polygon points="409 61 417 57 417 65"/>
|
||||
<polygon points="409 61 401 57 401 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m20 0 h10 m112 0 h10 m-152 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m132 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-132 0 h10 m24 0 h10 m0 0 h88 m23 44 h-3"/>
|
||||
<polygon points="201 61 209 57 209 65"/>
|
||||
<polygon points="201 61 193 57 193 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
<xhtml:div class="ebnf"><xhtml:code>
|
||||
<div><a href="#Query" title="Query">Query</a> ::= ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) ( ',' ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) )*</div></xhtml:code></xhtml:div>
|
||||
<div><a href="#Query" title="Query">Query</a> ::= <a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a> ( ',' <a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a> )*</div></xhtml:code></xhtml:div>
|
||||
</xhtml:p>
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Value">Value:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="81">
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="PropertyQuery">PropertyQuery:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="465" height="189">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
@namespace "http://www.w3.org/2000/svg";
|
||||
.line {fill: none; stroke: #332900;}
|
||||
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||
.filled {fill: #332900; stroke: none;}
|
||||
text.terminal {font-family: Verdana, Sans-serif;
|
||||
font-size: 12px;
|
||||
fill: #141000;
|
||||
font-weight: bold;
|
||||
}
|
||||
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||
font-size: 12px;
|
||||
fill: #1A1400;
|
||||
font-weight: normal;
|
||||
}
|
||||
text.regexp {font-family: Verdana, Sans-serif;
|
||||
font-size: 12px;
|
||||
fill: #1F1800;
|
||||
font-weight: normal;
|
||||
}
|
||||
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||
rect.text {fill: none; stroke: none;}
|
||||
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||
</style>
|
||||
</defs>
|
||||
<polygon points="9 17 1 13 1 21"/>
|
||||
<polygon points="17 17 9 13 9 21"/>
|
||||
<rect x="71" y="35" width="26" height="32" rx="10"/>
|
||||
<rect x="69" y="33" width="26" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="79" y="53">-</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||
<rect x="137" y="3" width="110" height="32"/>
|
||||
<rect x="135" y="1" width="110" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="145" y="21">PropertyName</text></a><rect x="51" y="79" width="26" height="32" rx="10"/>
|
||||
<rect x="49" y="77" width="26" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="59" y="97">?</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||
<rect x="97" y="79" width="110" height="32"/>
|
||||
<rect x="95" y="77" width="110" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="105" y="97">PropertyName</text></a><rect x="267" y="111" width="30" height="32" rx="10"/>
|
||||
<rect x="265" y="109" width="30" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="275" y="129">=</text>
|
||||
<rect x="267" y="155" width="34" height="32" rx="10"/>
|
||||
<rect x="265" y="153" width="34" height="32" class="terminal" rx="10"/>
|
||||
<text class="terminal" x="275" y="173">!=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
|
||||
<rect x="341" y="111" width="56" height="32"/>
|
||||
<rect x="339" y="109" width="56" height="32" class="nonterminal"/>
|
||||
<text class="nonterminal" x="349" y="129">Value</text></a><svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 17 h2 m40 0 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m110 0 h10 m0 0 h170 m-406 0 h20 m386 0 h20 m-426 0 q10 0 10 10 m406 0 q0 -10 10 -10 m-416 10 v56 m406 0 v-56 m-406 56 q0 10 10 10 m386 0 q10 0 10 -10 m-396 10 h10 m26 0 h10 m0 0 h10 m110 0 h10 m20 0 h10 m0 0 h160 m-190 0 h20 m170 0 h20 m-210 0 q10 0 10 10 m190 0 q0 -10 10 -10 m-200 10 v12 m190 0 v-12 m-190 12 q0 10 10 10 m170 0 q10 0 10 -10 m-160 10 h10 m30 0 h10 m0 0 h4 m-74 0 h20 m54 0 h20 m-94 0 q10 0 10 10 m74 0 q0 -10 10 -10 m-84 10 v24 m74 0 v-24 m-74 24 q0 10 10 10 m54 0 q10 0 10 -10 m-64 10 h10 m34 0 h10 m20 -44 h10 m56 0 h10 m43 -108 h-3"/>
|
||||
<polygon points="455 17 463 13 463 21"/>
|
||||
<polygon points="455 17 447 13 447 21"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
<xhtml:div class="ebnf"><xhtml:code>
|
||||
<div><a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</a></div>
|
||||
<div> ::= '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a></div>
|
||||
<div> | '?' <a href="#PropertyName" title="PropertyName">PropertyName</a> ( ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> )?</div></xhtml:code></xhtml:div>
|
||||
</xhtml:p>
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||
<xhtml:ul>
|
||||
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
|
||||
</xhtml:ul>
|
||||
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Value">Value:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="81">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
@namespace "http://www.w3.org/2000/svg";
|
||||
@@ -372,7 +420,7 @@
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||
<xhtml:ul>
|
||||
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
|
||||
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
|
||||
<xhtml:li><xhtml:a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</xhtml:a></xhtml:li>
|
||||
</xhtml:ul>
|
||||
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="StringLiteral">StringLiteral:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="219" height="81">
|
||||
<defs>
|
||||
@@ -659,7 +707,7 @@
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||
<xhtml:ul>
|
||||
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
|
||||
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
|
||||
<xhtml:li><xhtml:a href="#PropertyQuery" title="PropertyQuery">PropertyQuery</xhtml:a></xhtml:li>
|
||||
</xhtml:ul>
|
||||
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:hr xmlns:xhtml="http://www.w3.org/1999/xhtml" />
|
||||
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
|
||||
+27
-34
@@ -47,6 +47,7 @@ typedef struct {
|
||||
} ALGORITHM;
|
||||
|
||||
struct ossl_method_store_st {
|
||||
OPENSSL_CTX *ctx;
|
||||
size_t nelem;
|
||||
SPARSE_ARRAY_OF(ALGORITHM) *algs;
|
||||
OSSL_PROPERTY_LIST *global_properties;
|
||||
@@ -82,29 +83,10 @@ int ossl_property_unlock(OSSL_METHOD_STORE *p)
|
||||
return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0;
|
||||
}
|
||||
|
||||
int ossl_method_store_init(void)
|
||||
static openssl_ctx_run_once_fn do_method_store_init;
|
||||
int do_method_store_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (ossl_property_string_init()
|
||||
&& ossl_prop_defn_init()
|
||||
&& ossl_property_parse_init())
|
||||
return 1;
|
||||
|
||||
ossl_method_store_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ossl_method_store_cleanup(void)
|
||||
{
|
||||
ossl_property_string_cleanup();
|
||||
ossl_prop_defn_cleanup();
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_method_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& ossl_method_store_init()
|
||||
&& OPENSSL_atexit(&ossl_method_store_cleanup);
|
||||
return ossl_property_parse_init(ctx);
|
||||
}
|
||||
|
||||
static unsigned long query_hash(const QUERY *a)
|
||||
@@ -141,15 +123,22 @@ static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a)
|
||||
}
|
||||
}
|
||||
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(void)
|
||||
/*
|
||||
* The OPENSSL_CTX param here allows access to underlying property data needed
|
||||
* for computation
|
||||
*/
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
OSSL_METHOD_STORE *res;
|
||||
|
||||
if (!RUN_ONCE(&method_store_init_flag, do_method_store_init))
|
||||
return 0;
|
||||
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;
|
||||
if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) {
|
||||
OPENSSL_free(res);
|
||||
return NULL;
|
||||
@@ -212,10 +201,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store,
|
||||
*/
|
||||
ossl_property_write_lock(store);
|
||||
ossl_method_cache_flush(store, nid);
|
||||
if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) {
|
||||
if ((impl->properties = ossl_parse_property(properties)) == NULL)
|
||||
if ((impl->properties = ossl_prop_defn_get(store->ctx, properties)) == NULL) {
|
||||
impl->properties = ossl_parse_property(store->ctx, properties);
|
||||
if (impl->properties == NULL)
|
||||
goto err;
|
||||
ossl_prop_defn_set(properties, impl->properties);
|
||||
ossl_prop_defn_set(store->ctx, properties, impl->properties);
|
||||
}
|
||||
|
||||
alg = ossl_method_store_retrieve(store, nid);
|
||||
@@ -287,7 +277,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
IMPLEMENTATION *impl;
|
||||
OSSL_PROPERTY_LIST *pq = NULL, *p2;
|
||||
int ret = 0;
|
||||
int j;
|
||||
int j, best = -1, score, optional;
|
||||
|
||||
if (nid <= 0 || method == NULL || store == NULL)
|
||||
return 0;
|
||||
@@ -310,7 +300,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
}
|
||||
goto fin;
|
||||
}
|
||||
pq = ossl_parse_query(prop_query);
|
||||
pq = ossl_parse_query(store->ctx, prop_query);
|
||||
if (pq == NULL)
|
||||
goto fin;
|
||||
if (store->global_properties != NULL) {
|
||||
@@ -320,13 +310,16 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||
ossl_property_free(pq);
|
||||
pq = p2;
|
||||
}
|
||||
optional = ossl_property_has_optional(pq);
|
||||
for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) {
|
||||
impl = sk_IMPLEMENTATION_value(alg->impls, j);
|
||||
|
||||
if (ossl_property_match(pq, impl->properties)) {
|
||||
score = ossl_property_match_count(pq, impl->properties);
|
||||
if (score > best) {
|
||||
*method = impl->method;
|
||||
ret = 1;
|
||||
goto fin;
|
||||
if (!optional)
|
||||
goto fin;
|
||||
best = score;
|
||||
}
|
||||
}
|
||||
fin:
|
||||
@@ -350,7 +343,7 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
|
||||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
}
|
||||
store->global_properties = ossl_parse_query(prop_query);
|
||||
store->global_properties = ossl_parse_query(store->ctx, prop_query);
|
||||
ret = store->global_properties != NULL;
|
||||
ossl_property_unlock(store);
|
||||
return ret;
|
||||
|
||||
@@ -14,35 +14,31 @@
|
||||
typedef struct ossl_property_list_st OSSL_PROPERTY_LIST;
|
||||
typedef int OSSL_PROPERTY_IDX;
|
||||
|
||||
/* Initialisation and finalisation for subsystem */
|
||||
int ossl_method_store_init(void);
|
||||
void ossl_method_store_cleanup(void);
|
||||
|
||||
/* Property string functions */
|
||||
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create);
|
||||
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create);
|
||||
int ossl_property_string_init(void);
|
||||
void ossl_property_string_cleanup(void);
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
|
||||
int create);
|
||||
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
|
||||
int create);
|
||||
|
||||
/* Property list functions */
|
||||
int ossl_property_parse_init(void);
|
||||
int ossl_property_parse_init(OPENSSL_CTX *ctx);
|
||||
void ossl_property_free(OSSL_PROPERTY_LIST *p);
|
||||
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn);
|
||||
int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query);
|
||||
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn);
|
||||
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||
const OSSL_PROPERTY_LIST *b);
|
||||
|
||||
/* Property definition functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(const char *s);
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property query functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s);
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property definition cache functions */
|
||||
int ossl_prop_defn_init(void);
|
||||
void ossl_prop_defn_cleanup(void);
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop);
|
||||
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl);
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop);
|
||||
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
|
||||
OSSL_PROPERTY_LIST *pl);
|
||||
|
||||
/* Property cache lock / unlock */
|
||||
int ossl_property_write_lock(OSSL_METHOD_STORE *);
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct {
|
||||
OSSL_PROPERTY_IDX name_idx;
|
||||
PROPERTY_TYPE type;
|
||||
PROPERTY_OPER oper;
|
||||
unsigned int optional : 1;
|
||||
union {
|
||||
int64_t int_val; /* Signed integer */
|
||||
OSSL_PROPERTY_IDX str_val; /* String */
|
||||
@@ -40,6 +41,7 @@ typedef struct {
|
||||
|
||||
struct ossl_property_list_st {
|
||||
int n;
|
||||
unsigned int has_optional : 1;
|
||||
PROPERTY_DEFINITION properties[1];
|
||||
};
|
||||
|
||||
@@ -78,7 +80,8 @@ static int match(const char *t[], const char m[], size_t m_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
|
||||
static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
|
||||
OSSL_PROPERTY_IDX *idx)
|
||||
{
|
||||
char name[100];
|
||||
int err = 0;
|
||||
@@ -109,7 +112,7 @@ static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
|
||||
name[i] = '\0';
|
||||
*t = skip_space(s);
|
||||
if (!err) {
|
||||
*idx = ossl_property_name(name, user_name && create);
|
||||
*idx = ossl_property_name(ctx, name, user_name && create);
|
||||
return 1;
|
||||
}
|
||||
PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG);
|
||||
@@ -180,8 +183,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
|
||||
const int create)
|
||||
static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
|
||||
PROPERTY_DEFINITION *res, const int create)
|
||||
{
|
||||
char v[1000];
|
||||
const char *s = *t;
|
||||
@@ -205,13 +208,13 @@ static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
|
||||
if (err)
|
||||
PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG);
|
||||
else
|
||||
res->v.str_val = ossl_property_value(v, create);
|
||||
res->v.str_val = ossl_property_value(ctx, v, create);
|
||||
res->type = PROPERTY_TYPE_STRING;
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
|
||||
const int create)
|
||||
static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[],
|
||||
PROPERTY_DEFINITION *res, const int create)
|
||||
{
|
||||
char v[1000];
|
||||
const char *s = *t;
|
||||
@@ -236,19 +239,20 @@ static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
|
||||
if (err)
|
||||
PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG);
|
||||
else
|
||||
res->v.str_val = ossl_property_value(v, create);
|
||||
res->v.str_val = ossl_property_value(ctx, v, create);
|
||||
res->type = PROPERTY_TYPE_STRING;
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
|
||||
static int parse_value(OPENSSL_CTX *ctx, const char *t[],
|
||||
PROPERTY_DEFINITION *res, int create)
|
||||
{
|
||||
const char *s = *t;
|
||||
int r = 0;
|
||||
|
||||
if (*s == '"' || *s == '\'') {
|
||||
s++;
|
||||
r = parse_string(&s, s[-1], res, create);
|
||||
r = parse_string(ctx, &s, s[-1], res, create);
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
r = parse_number(&s, res);
|
||||
@@ -265,7 +269,7 @@ static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
|
||||
} else if (ossl_isdigit(*s)) {
|
||||
return parse_number(t, res);
|
||||
} else if (ossl_isalpha(*s))
|
||||
return parse_unquoted(t, res, create);
|
||||
return parse_unquoted(ctx, t, res, create);
|
||||
if (r)
|
||||
*t = s;
|
||||
return r;
|
||||
@@ -305,14 +309,17 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
|
||||
if (r != NULL) {
|
||||
sk_PROPERTY_DEFINITION_sort(sk);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
r->has_optional = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i);
|
||||
r->has_optional |= r->properties[i].optional;
|
||||
}
|
||||
r->n = n;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
|
||||
{
|
||||
PROPERTY_DEFINITION *prop = NULL;
|
||||
OSSL_PROPERTY_LIST *res = NULL;
|
||||
@@ -330,7 +337,8 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
||||
if (prop == NULL)
|
||||
goto err;
|
||||
memset(&prop->v, 0, sizeof(prop->v));
|
||||
if (!parse_name(&s, 1, &prop->name_idx))
|
||||
prop->optional = 0;
|
||||
if (!parse_name(ctx, &s, 1, &prop->name_idx))
|
||||
goto err;
|
||||
prop->oper = PROPERTY_OPER_EQ;
|
||||
if (prop->name_idx == 0) {
|
||||
@@ -338,7 +346,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
||||
goto err;
|
||||
}
|
||||
if (match_ch(&s, '=')) {
|
||||
if (!parse_value(&s, prop, 1)) {
|
||||
if (!parse_value(ctx, &s, prop, 1)) {
|
||||
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE);
|
||||
goto err;
|
||||
}
|
||||
@@ -365,7 +373,7 @@ err:
|
||||
return res;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s)
|
||||
{
|
||||
STACK_OF(PROPERTY_DEFINITION) *sk;
|
||||
OSSL_PROPERTY_LIST *res = NULL;
|
||||
@@ -385,11 +393,13 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
||||
|
||||
if (match_ch(&s, '-')) {
|
||||
prop->oper = PROPERTY_OVERRIDE;
|
||||
if (!parse_name(&s, 0, &prop->name_idx))
|
||||
prop->optional = 0;
|
||||
if (!parse_name(ctx, &s, 0, &prop->name_idx))
|
||||
goto err;
|
||||
goto skip_value;
|
||||
}
|
||||
if (!parse_name(&s, 0, &prop->name_idx))
|
||||
prop->optional = match_ch(&s, '?');
|
||||
if (!parse_name(ctx, &s, 0, &prop->name_idx))
|
||||
goto err;
|
||||
|
||||
if (match_ch(&s, '=')) {
|
||||
@@ -403,7 +413,7 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
||||
prop->v.str_val = ossl_property_true;
|
||||
goto skip_value;
|
||||
}
|
||||
if (!parse_value(&s, prop, 0))
|
||||
if (!parse_value(ctx, &s, prop, 0))
|
||||
prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
|
||||
|
||||
skip_value:
|
||||
@@ -424,12 +434,22 @@ err:
|
||||
return res;
|
||||
}
|
||||
|
||||
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn)
|
||||
/* Does a property query have any optional clauses */
|
||||
int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query)
|
||||
{
|
||||
return query->has_optional ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare a query against a definition.
|
||||
* Return the number of clauses matched or -1 if a mandatory clause is false.
|
||||
*/
|
||||
int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn)
|
||||
{
|
||||
const PROPERTY_DEFINITION *const q = query->properties;
|
||||
const PROPERTY_DEFINITION *const d = defn->properties;
|
||||
int i = 0, j = 0;
|
||||
int i = 0, j = 0, matches = 0;
|
||||
PROPERTY_OPER oper;
|
||||
|
||||
while (i < query->n) {
|
||||
@@ -446,9 +466,11 @@ int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||
const int eq = q[i].type == d[j].type
|
||||
&& memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0;
|
||||
|
||||
if ((eq && oper != PROPERTY_OPER_EQ)
|
||||
|| (!eq && oper != PROPERTY_OPER_NE))
|
||||
return 0;
|
||||
if ((eq && oper == PROPERTY_OPER_EQ)
|
||||
|| (!eq && oper == PROPERTY_OPER_NE))
|
||||
matches++;
|
||||
else if (!q[i].optional)
|
||||
return -1;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
@@ -461,18 +483,23 @@ int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||
* the latter is treated as a comparison against the Boolean false.
|
||||
*/
|
||||
if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
|
||||
if (oper != PROPERTY_OPER_NE)
|
||||
return 0;
|
||||
if (oper == PROPERTY_OPER_NE)
|
||||
matches++;
|
||||
else if (!q[i].optional)
|
||||
return -1;
|
||||
} else if (q[i].type != PROPERTY_TYPE_STRING
|
||||
|| (oper == PROPERTY_OPER_EQ
|
||||
&& q[i].v.str_val != ossl_property_false)
|
||||
|| (oper == PROPERTY_OPER_NE
|
||||
&& q[i].v.str_val == ossl_property_false)) {
|
||||
return 0;
|
||||
if (!q[i].optional)
|
||||
return -1;
|
||||
} else {
|
||||
matches++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
return matches;
|
||||
}
|
||||
|
||||
void ossl_property_free(OSSL_PROPERTY_LIST *p)
|
||||
@@ -519,7 +546,7 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||
return r;
|
||||
}
|
||||
|
||||
int ossl_property_parse_init(void)
|
||||
int ossl_property_parse_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
static const char *const predefined_names[] = {
|
||||
"default", /* Being provided by the default built-in provider */
|
||||
@@ -532,12 +559,12 @@ int ossl_property_parse_init(void)
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(predefined_names); i++)
|
||||
if (ossl_property_name(predefined_names[i], 1) == 0)
|
||||
if (ossl_property_name(ctx, predefined_names[i], 1) == 0)
|
||||
goto err;
|
||||
|
||||
/* Pre-populate the two Boolean values */
|
||||
if ((ossl_property_true = ossl_property_value("yes", 1)) == 0
|
||||
|| (ossl_property_false = ossl_property_value("no", 1)) == 0)
|
||||
if ((ossl_property_true = ossl_property_value(ctx, "yes", 1)) == 0
|
||||
|| (ossl_property_false = ossl_property_value(ctx, "no", 1)) == 0)
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -34,10 +34,12 @@ typedef struct {
|
||||
DEFINE_LHASH_OF(PROPERTY_STRING);
|
||||
typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
|
||||
|
||||
static PROP_TABLE *prop_names;
|
||||
static PROP_TABLE *prop_values;
|
||||
static OSSL_PROPERTY_IDX prop_name_idx = 0;
|
||||
static OSSL_PROPERTY_IDX prop_value_idx = 0;
|
||||
typedef struct {
|
||||
PROP_TABLE *prop_names;
|
||||
PROP_TABLE *prop_values;
|
||||
OSSL_PROPERTY_IDX prop_name_idx;
|
||||
OSSL_PROPERTY_IDX prop_value_idx;
|
||||
} PROPERTY_STRING_DATA;
|
||||
|
||||
static unsigned long property_hash(const PROPERTY_STRING *a)
|
||||
{
|
||||
@@ -65,6 +67,48 @@ static void property_table_free(PROP_TABLE **pt)
|
||||
}
|
||||
}
|
||||
|
||||
static void property_string_data_free(void *vpropdata)
|
||||
{
|
||||
PROPERTY_STRING_DATA *propdata = vpropdata;
|
||||
|
||||
if (propdata == NULL)
|
||||
return;
|
||||
|
||||
property_table_free(&propdata->prop_names);
|
||||
property_table_free(&propdata->prop_values);
|
||||
propdata->prop_name_idx = propdata->prop_value_idx = 0;
|
||||
|
||||
OPENSSL_free(propdata);
|
||||
}
|
||||
|
||||
static void *property_string_data_new(OPENSSL_CTX *ctx) {
|
||||
PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata));
|
||||
|
||||
if (propdata == NULL)
|
||||
return NULL;
|
||||
|
||||
propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash,
|
||||
&property_cmp);
|
||||
if (propdata->prop_names == NULL)
|
||||
goto err;
|
||||
|
||||
propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash,
|
||||
&property_cmp);
|
||||
if (propdata->prop_values == NULL)
|
||||
goto err;
|
||||
|
||||
return propdata;
|
||||
|
||||
err:
|
||||
property_string_data_free(propdata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const OPENSSL_CTX_METHOD property_string_data_method = {
|
||||
property_string_data_new,
|
||||
property_string_data_free,
|
||||
};
|
||||
|
||||
static PROPERTY_STRING *new_property_string(const char *s,
|
||||
OSSL_PROPERTY_IDX *pidx)
|
||||
{
|
||||
@@ -103,35 +147,30 @@ static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
|
||||
return ps != NULL ? ps->idx : 0;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create)
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s);
|
||||
}
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create)
|
||||
{
|
||||
return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s);
|
||||
}
|
||||
|
||||
int ossl_property_string_init(void)
|
||||
{
|
||||
prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||
if (prop_names == NULL)
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
|
||||
prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||
if (prop_values == NULL)
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ossl_property_string_cleanup();
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_names,
|
||||
create ? &propdata->prop_name_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
||||
void ossl_property_string_cleanup(void)
|
||||
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
property_table_free(&prop_names);
|
||||
property_table_free(&prop_values);
|
||||
prop_name_idx = prop_value_idx = 0;
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_values,
|
||||
create ? &propdata->prop_value_idx : NULL,
|
||||
s);
|
||||
}
|
||||
+20
-21
@@ -54,6 +54,9 @@ struct ossl_provider_st {
|
||||
OSSL_provider_get_param_types_fn *get_param_types;
|
||||
OSSL_provider_get_params_fn *get_params;
|
||||
OSSL_provider_query_operation_fn *query_operation;
|
||||
|
||||
/* Provider side data */
|
||||
void *provctx;
|
||||
};
|
||||
DEFINE_STACK_OF(OSSL_PROVIDER)
|
||||
|
||||
@@ -76,7 +79,6 @@ struct provider_store_st {
|
||||
CRYPTO_RWLOCK *lock;
|
||||
unsigned int use_fallbacks:1;
|
||||
};
|
||||
static int provider_store_index = -1;
|
||||
|
||||
static void provider_store_free(void *vstore)
|
||||
{
|
||||
@@ -89,7 +91,7 @@ static void provider_store_free(void *vstore)
|
||||
OPENSSL_free(store);
|
||||
}
|
||||
|
||||
static void *provider_store_new(void)
|
||||
static void *provider_store_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
|
||||
const struct predefined_providers_st *p = NULL;
|
||||
@@ -131,23 +133,12 @@ static const OPENSSL_CTX_METHOD provider_store_method = {
|
||||
provider_store_free,
|
||||
};
|
||||
|
||||
static CRYPTO_ONCE provider_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_provider_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& (provider_store_index =
|
||||
openssl_ctx_new_index(&provider_store_method)) != -1;
|
||||
}
|
||||
|
||||
|
||||
static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx)
|
||||
{
|
||||
struct provider_store_st *store = NULL;
|
||||
|
||||
if (!RUN_ONCE(&provider_store_init_flag, do_provider_store_init))
|
||||
return NULL;
|
||||
|
||||
store = openssl_ctx_get_data(libctx, provider_store_index);
|
||||
store = openssl_ctx_get_data(libctx, OPENSSL_CTX_PROVIDER_STORE_INDEX,
|
||||
&provider_store_method);
|
||||
if (store == NULL)
|
||||
CRYPTOerr(CRYPTO_F_GET_PROVIDER_STORE, ERR_R_INTERNAL_ERROR);
|
||||
return store;
|
||||
@@ -275,7 +266,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
|
||||
*/
|
||||
if (ref < 2 && prov->flag_initialized) {
|
||||
if (prov->teardown != NULL)
|
||||
prov->teardown();
|
||||
prov->teardown(prov->provctx);
|
||||
prov->flag_initialized = 0;
|
||||
}
|
||||
|
||||
@@ -401,7 +392,8 @@ static int provider_activate(OSSL_PROVIDER *prov)
|
||||
}
|
||||
|
||||
if (prov->init_function == NULL
|
||||
|| !prov->init_function(prov, core_dispatch, &provider_dispatch)) {
|
||||
|| !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);
|
||||
DSO_free(prov->module);
|
||||
@@ -448,6 +440,11 @@ int ossl_provider_activate(OSSL_PROVIDER *prov)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
|
||||
{
|
||||
return prov->provctx;
|
||||
}
|
||||
|
||||
|
||||
static int provider_forall_loaded(struct provider_store_st *store,
|
||||
int *found_activated,
|
||||
@@ -573,18 +570,20 @@ const char *ossl_provider_module_path(OSSL_PROVIDER *prov)
|
||||
void ossl_provider_teardown(const OSSL_PROVIDER *prov)
|
||||
{
|
||||
if (prov->teardown != NULL)
|
||||
prov->teardown();
|
||||
prov->teardown(prov->provctx);
|
||||
}
|
||||
|
||||
const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov)
|
||||
{
|
||||
return prov->get_param_types == NULL ? NULL : prov->get_param_types(prov);
|
||||
return prov->get_param_types == NULL
|
||||
? NULL : prov->get_param_types(prov->provctx);
|
||||
}
|
||||
|
||||
int ossl_provider_get_params(const OSSL_PROVIDER *prov,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
return prov->get_params == NULL ? 0 : prov->get_params(prov, params);
|
||||
return prov->get_params == NULL
|
||||
? 0 : prov->get_params(prov->provctx, params);
|
||||
}
|
||||
|
||||
|
||||
@@ -592,7 +591,7 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
|
||||
int operation_id,
|
||||
int *no_cache)
|
||||
{
|
||||
return prov->query_operation(prov, operation_id, no_cache);
|
||||
return prov->query_operation(prov->provctx, operation_id, no_cache);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
randfile.c rand_lib.c rand_err.c rand_crng_test.c rand_egd.c \
|
||||
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c \
|
||||
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c rand_vxworks.c \
|
||||
drbg_hash.c drbg_hmac.c
|
||||
|
||||
+12
-2
@@ -1101,6 +1101,17 @@ static int drbg_add(const void *buf, int num, double randomness)
|
||||
|
||||
buflen = (size_t)num;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
/*
|
||||
* NIST SP-800-90A mandates that entropy *shall not* be provided
|
||||
* by the consuming application. By setting the randomness to zero,
|
||||
* we ensure that the buffer contents will be added to the internal
|
||||
* state of the DRBG only as additional data.
|
||||
*
|
||||
* (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
|
||||
*/
|
||||
randomness = 0.0;
|
||||
#endif
|
||||
if (buflen < seedlen || randomness < (double) seedlen) {
|
||||
#if defined(OPENSSL_RAND_SEED_NONE)
|
||||
/*
|
||||
@@ -1117,7 +1128,7 @@ static int drbg_add(const void *buf, int num, double randomness)
|
||||
return ret;
|
||||
#else
|
||||
/*
|
||||
* If an os entropy source is avaible then we declare the buffer content
|
||||
* If an os entropy source is available then we declare the buffer content
|
||||
* as additional data by setting randomness to zero and trigger a regular
|
||||
* reseeding.
|
||||
*/
|
||||
@@ -1125,7 +1136,6 @@ static int drbg_add(const void *buf, int num, double randomness)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (randomness > (double)seedlen) {
|
||||
/*
|
||||
* The purpose of this check is to bound |randomness| by a
|
||||
|
||||
@@ -13,45 +13,52 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/rand_int.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "rand_lcl.h"
|
||||
|
||||
static RAND_POOL *crngt_pool;
|
||||
static unsigned char *crngt_prev;
|
||||
static unsigned char crngt_prev[EVP_MAX_MD_SIZE];
|
||||
|
||||
int (*crngt_get_entropy)(unsigned char *) = &rand_crngt_get_entropy_cb;
|
||||
int (*crngt_get_entropy)(unsigned char *, unsigned char *, unsigned int *)
|
||||
= &rand_crngt_get_entropy_cb;
|
||||
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf)
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size)
|
||||
{
|
||||
int r;
|
||||
size_t n;
|
||||
unsigned char *p;
|
||||
|
||||
while ((n = rand_pool_acquire_entropy(crngt_pool)) != 0)
|
||||
if (n >= CRNGT_BUFSIZ) {
|
||||
p = rand_pool_detach(crngt_pool);
|
||||
n = rand_pool_acquire_entropy(crngt_pool);
|
||||
if (n >= CRNGT_BUFSIZ) {
|
||||
p = rand_pool_detach(crngt_pool);
|
||||
r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
|
||||
if (r != 0)
|
||||
memcpy(buf, p, CRNGT_BUFSIZ);
|
||||
rand_pool_reattach(crngt_pool, p);
|
||||
return 1;
|
||||
}
|
||||
rand_pool_reattach(crngt_pool, p);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void rand_crngt_cleanup(void)
|
||||
{
|
||||
rand_pool_free(crngt_pool);
|
||||
OPENSSL_secure_free(crngt_prev);
|
||||
crngt_pool = NULL;
|
||||
crngt_prev = NULL;
|
||||
}
|
||||
|
||||
int rand_crngt_init(void)
|
||||
{
|
||||
unsigned char buf[CRNGT_BUFSIZ];
|
||||
|
||||
if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
|
||||
return 0;
|
||||
if ((crngt_prev = OPENSSL_secure_malloc(CRNGT_BUFSIZ)) != NULL
|
||||
&& crngt_get_entropy(crngt_prev))
|
||||
if (crngt_get_entropy(buf, crngt_prev, NULL)) {
|
||||
OPENSSL_cleanse(buf, sizeof(buf));
|
||||
return 1;
|
||||
}
|
||||
rand_crngt_cleanup();
|
||||
return 0;
|
||||
}
|
||||
@@ -74,7 +81,8 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
|
||||
int entropy, size_t min_len, size_t max_len,
|
||||
int prediction_resistance)
|
||||
{
|
||||
unsigned char buf[CRNGT_BUFSIZ];
|
||||
unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
|
||||
unsigned int sz;
|
||||
RAND_POOL *pool;
|
||||
size_t q, r = 0, s, t = 0;
|
||||
int attempts = 3;
|
||||
@@ -87,17 +95,18 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
|
||||
|
||||
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
|
||||
s = q > sizeof(buf) ? sizeof(buf) : q;
|
||||
if (!crngt_get_entropy(buf)
|
||||
|| memcmp(crngt_prev, buf, CRNGT_BUFSIZ) == 0
|
||||
if (!crngt_get_entropy(buf, md, &sz)
|
||||
|| memcmp(crngt_prev, md, sz) == 0
|
||||
|| !rand_pool_add(pool, buf, s, s * 8))
|
||||
goto err;
|
||||
memcpy(crngt_prev, buf, CRNGT_BUFSIZ);
|
||||
memcpy(crngt_prev, md, sz);
|
||||
t += s;
|
||||
attempts++;
|
||||
}
|
||||
r = t;
|
||||
*pout = rand_pool_detach(pool);
|
||||
err:
|
||||
OPENSSL_cleanse(buf, sizeof(buf));
|
||||
rand_pool_free(pool);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -334,8 +334,10 @@ int drbg_hmac_init(RAND_DRBG *drbg);
|
||||
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
|
||||
* These need to be exposed for the unit tests.
|
||||
*/
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf);
|
||||
extern int (*crngt_get_entropy)(unsigned char *);
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size);
|
||||
extern int (*crngt_get_entropy)(unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size);
|
||||
int rand_crngt_init(void);
|
||||
void rand_crngt_cleanup(void);
|
||||
|
||||
|
||||
+6
-26
@@ -30,7 +30,8 @@
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
|
||||
#if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
|
||||
|| defined(__DJGPP__)
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
@@ -88,30 +89,8 @@ static uint64_t get_timer_bits(void);
|
||||
# undef OPENSSL_RAND_SEED_EGD
|
||||
#endif
|
||||
|
||||
#if (defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)) && \
|
||||
!defined(OPENSSL_RAND_SEED_NONE)
|
||||
# error "UEFI and VXWorks only support seeding NONE"
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_VXWORKS)
|
||||
/* empty implementation */
|
||||
int rand_pool_init(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rand_pool_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void rand_pool_keep_random_devices_open(int keep)
|
||||
{
|
||||
}
|
||||
|
||||
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
{
|
||||
return rand_pool_entropy_available(pool);
|
||||
}
|
||||
#if defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_RAND_SEED_NONE)
|
||||
# error "UEFI only supports seeding NONE"
|
||||
#endif
|
||||
|
||||
#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) \
|
||||
@@ -608,7 +587,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
|
||||
#if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
|
||||
|| defined(__DJGPP__)
|
||||
int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
{
|
||||
struct {
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_SYS_VXWORKS
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
# include <openssl/rand.h>
|
||||
# include "rand_lcl.h"
|
||||
# include "internal/rand_int.h"
|
||||
# include "internal/cryptlib.h"
|
||||
# include <version.h>
|
||||
# include <taskLib.h>
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_NONE)
|
||||
/* none means none */
|
||||
# undef OPENSSL_RAND_SEED_OS
|
||||
# endif
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_OS)
|
||||
# if _WRS_VXWORKS_MAJOR >= 7
|
||||
# define RAND_SEED_VXRANDLIB
|
||||
# else
|
||||
# error "VxWorks <7 only support RAND_SEED_NONE"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(RAND_SEED_VXRANDLIB)
|
||||
# include <randomNumGen.h>
|
||||
# endif
|
||||
|
||||
/* Macro to convert two thirty two bit values into a sixty four bit one */
|
||||
# define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b))
|
||||
|
||||
static uint64_t get_time_stamp(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
||||
return TWO32TO64(ts.tv_sec, ts.tv_nsec);
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
static uint64_t get_timer_bits(void)
|
||||
{
|
||||
uint64_t res = OPENSSL_rdtsc();
|
||||
struct timespec ts;
|
||||
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
return TWO32TO64(ts.tv_sec, ts.tv_nsec);
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* empty implementation
|
||||
* vxworks does not need to init/cleanup or keep open the random lib
|
||||
*/
|
||||
int rand_pool_init(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rand_pool_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void rand_pool_keep_random_devices_open(int keep)
|
||||
{
|
||||
}
|
||||
|
||||
int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
{
|
||||
struct {
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add some noise from the thread id and a high resolution timer.
|
||||
* The thread id adds a little randomness if the drbg is accessed
|
||||
* concurrently (which is the case for the <master> drbg).
|
||||
*/
|
||||
data.tid = CRYPTO_THREAD_get_current_id();
|
||||
data.time = get_timer_bits();
|
||||
|
||||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
{
|
||||
struct {
|
||||
pid_t pid;
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp to
|
||||
* ensure that the nonce is unique with high probability for
|
||||
* different process instances.
|
||||
*/
|
||||
data.pid = getpid();
|
||||
data.tid = CRYPTO_THREAD_get_current_id();
|
||||
data.time = get_time_stamp();
|
||||
|
||||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
{
|
||||
# if defined(RAND_SEED_VXRANDLIB)
|
||||
/* vxRandLib based entropy method */
|
||||
size_t bytes_needed;
|
||||
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
if (bytes_needed > 0)
|
||||
{
|
||||
int retryCount = 0;
|
||||
STATUS result = ERROR;
|
||||
unsigned char *buffer;
|
||||
|
||||
buffer = rand_pool_add_begin(pool, bytes_needed);
|
||||
while ((result != OK) && (retryCount < 10)) {
|
||||
RANDOM_NUM_GEN_STATUS status = randStatus();
|
||||
|
||||
if ((status == RANDOM_NUM_GEN_ENOUGH_ENTROPY)
|
||||
|| (status == RANDOM_NUM_GEN_MAX_ENTROPY) ) {
|
||||
result = randBytes(buffer, bytes_needed);
|
||||
if (result == OK)
|
||||
rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
|
||||
/*
|
||||
* no else here: randStatus said ok, if randBytes failed
|
||||
* it will result in another loop or no entropy
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* give a minimum delay here to allow OS to collect more
|
||||
* entropy. taskDelay duration will depend on the system tick,
|
||||
* this is by design as the sw-random lib uses interrupts
|
||||
* which will at least happen during ticks
|
||||
*/
|
||||
taskDelay(5);
|
||||
}
|
||||
retryCount++;
|
||||
}
|
||||
}
|
||||
return rand_pool_entropy_available(pool);
|
||||
# else
|
||||
/*
|
||||
* SEED_NONE means none, without randlib we dont have entropy and
|
||||
* rely on it being added externally
|
||||
*/
|
||||
return rand_pool_entropy_available(pool);
|
||||
# endif /* defined(RAND_SEED_VXRANDLIB) */
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_SYS_VXWORKS */
|
||||
@@ -25,11 +25,9 @@ int RSA_check_key(const RSA *key)
|
||||
int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
|
||||
{
|
||||
#ifdef FIPS_MODE
|
||||
if (!(rsa_sp800_56b_check_public(key)
|
||||
&& rsa_sp800_56b_check_private(key)
|
||||
&& rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key))
|
||||
return 0;
|
||||
|
||||
return rsa_sp800_56b_check_public(key)
|
||||
&& rsa_sp800_56b_check_private(key)
|
||||
&& rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key));
|
||||
#else
|
||||
BIGNUM *i, *j, *k, *l, *m;
|
||||
BN_CTX *ctx;
|
||||
|
||||
@@ -56,7 +56,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
|
||||
|
||||
if (rctx == NULL)
|
||||
return 0;
|
||||
rctx->nbits = 1024;
|
||||
rctx->nbits = 2048;
|
||||
rctx->primes = RSA_DEFAULT_PRIME_NUM;
|
||||
if (pkey_ctx_is_pss(ctx))
|
||||
rctx->pad_mode = RSA_PKCS1_PSS_PADDING;
|
||||
@@ -89,6 +89,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
dctx->pad_mode = sctx->pad_mode;
|
||||
dctx->md = sctx->md;
|
||||
dctx->mgf1md = sctx->mgf1md;
|
||||
dctx->saltlen = sctx->saltlen;
|
||||
if (sctx->oaep_label) {
|
||||
OPENSSL_free(dctx->oaep_label);
|
||||
dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/numbers.h"
|
||||
#include <openssl/stack.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/e_os2.h> /* For ossl_inline */
|
||||
|
||||
@@ -307,20 +306,20 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
|
||||
}
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
|
||||
ret_val_options);
|
||||
r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
|
||||
ret_val_options);
|
||||
|
||||
return r == NULL ? -1 : (int)((const void **)r - st->data);
|
||||
}
|
||||
|
||||
int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
|
||||
{
|
||||
return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
|
||||
return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);
|
||||
}
|
||||
|
||||
int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
|
||||
{
|
||||
return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
|
||||
return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH);
|
||||
}
|
||||
|
||||
int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
|
||||
|
||||
@@ -15,10 +15,10 @@ ossl_method_store_cache_get, ossl_method_store_cache_set
|
||||
|
||||
typedef struct ossl_method_store_st OSSL_METHOD_STORE;
|
||||
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(void);
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx);
|
||||
void ossl_method_store_free(OSSL_METHOD_STORE *store);
|
||||
int ossl_method_store_init(void);
|
||||
void ossl_method_store_cleanup(void);
|
||||
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 *));
|
||||
@@ -51,12 +51,14 @@ separately (see L</Cache Functions> below).
|
||||
|
||||
=head2 Store Functions
|
||||
|
||||
ossl_method_store_init() initialises the method store subsystem.
|
||||
ossl_method_store_init() initialises the method store subsystem in the scope of
|
||||
the library context B<ctx>.
|
||||
|
||||
ossl_method_store_cleanup() cleans up and shuts down the implementation method
|
||||
store subsystem.
|
||||
store subsystem in the scope of the library context B<ctx>.
|
||||
|
||||
ossl_method_store_new() create a new empty method store.
|
||||
ossl_method_store_new() create a new empty method store using the supplied
|
||||
B<ctx> to allow access to the required underlying property data.
|
||||
|
||||
ossl_method_store_free() frees resources allocated to B<store>.
|
||||
|
||||
|
||||
@@ -10,17 +10,16 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP
|
||||
#include "evp_locl.h"
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
int (*nid_method)(void *));
|
||||
void (*free_method)(void *));
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
evp_generic_fetch() calls ossl_method_construct() with the given
|
||||
C<libctx>, C<operation_id>, C<algorithm>, and C<properties> and uses
|
||||
C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
|
||||
it to create an EVP method with the help of the functions
|
||||
C<new_method>, C<upref_method>, and C<free_method>.
|
||||
|
||||
@@ -42,10 +41,6 @@ one.
|
||||
|
||||
frees the given method.
|
||||
|
||||
=item nid_method()
|
||||
|
||||
returns the nid associated with the given method.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUES
|
||||
@@ -80,7 +75,6 @@ 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 nid;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
OSSL_OP_foo_newctx_fn *newctx;
|
||||
OSSL_OP_foo_init_fn *init;
|
||||
@@ -93,7 +87,7 @@ 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(int foo_type, const OSSL_DISPATCH *fns,
|
||||
EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_FOO *foo = NULL;
|
||||
@@ -120,7 +114,6 @@ And here's the implementation of the FOO method fetcher:
|
||||
break;
|
||||
}
|
||||
}
|
||||
foo->nid = foo_type;
|
||||
foo->prov = prov;
|
||||
if (prov)
|
||||
ossl_provider_upref(prov);
|
||||
@@ -138,10 +131,10 @@ And here's the implementation of the FOO method fetcher:
|
||||
}
|
||||
}
|
||||
|
||||
static void *foo_from_dispatch(int nid, const OSSL_DISPATCH *fns,
|
||||
static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
return EVP_FOO_meth_from_dispatch(nid, fns, prov);
|
||||
return EVP_FOO_meth_from_dispatch(fns, prov);
|
||||
}
|
||||
|
||||
static int foo_upref(void *vfoo)
|
||||
@@ -159,11 +152,21 @@ And here's the implementation of the FOO method fetcher:
|
||||
}
|
||||
|
||||
EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
|
||||
const char *algorithm,
|
||||
const char *name,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_FOO, algorithm, properties,
|
||||
foo_from_dispatch, foo_upref, foo_free);
|
||||
EVP_FOO *foo =
|
||||
evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
|
||||
foo_from_dispatch, foo_upref, foo_free);
|
||||
|
||||
/*
|
||||
* If this method exists in legacy form, with a constant NID for the
|
||||
* given |name|, this is the spot to find that NID and set it in
|
||||
* the newly constructed EVP_FOO instance.
|
||||
*/
|
||||
|
||||
return foo;
|
||||
|
||||
}
|
||||
|
||||
And finally, the library functions:
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
openssl_ctx_new_index, openssl_ctx_get_data - internal OPENSSL_CTX routines
|
||||
openssl_ctx_get_data, openssl_ctx_run_once, openssl_ctx_onfree
|
||||
- internal OPENSSL_CTX routines
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@@ -10,12 +11,16 @@ openssl_ctx_new_index, openssl_ctx_get_data - internal OPENSSL_CTX routines
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
typedef struct openssl_ctx_method {
|
||||
void *(*new_func)(void);
|
||||
void *(*new_func)(OPENSSL_CTX *ctx);
|
||||
void (*free_func)(void *);
|
||||
} OPENSSL_CTX_METHOD;
|
||||
|
||||
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth);
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index);
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
|
||||
const OPENSSL_CTX_METHOD *meth);
|
||||
|
||||
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
|
||||
openssl_ctx_run_once_fn run_once_fn);
|
||||
int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -23,27 +28,33 @@ Internally, the OpenSSL library context C<OPENSSL_CTX> is implemented
|
||||
as a C<CRYPTO_EX_DATA>, which allows data from diverse parts of the
|
||||
library to be added and removed dynamically.
|
||||
Each such data item must have a corresponding CRYPTO_EX_DATA index
|
||||
associated with it.
|
||||
associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes
|
||||
to identify data items. These are mapped transparetnly to CRYPTO_EX_DATA dynamic
|
||||
indexes internally to the implementation.
|
||||
See the example further down to see how that's done.
|
||||
|
||||
openssl_ctx_new_index() allocates a new library context index, and
|
||||
associates it with the functions given through C<meth>.
|
||||
The functions given through that method are used to create or free
|
||||
items that are stored at that index whenever a library context is
|
||||
created or freed, meaning that the code that use a data item of that
|
||||
openssl_ctx_get_data() is used to retrieve a pointer to the data in
|
||||
the library context C<ctx> associated with the given C<index>. An
|
||||
OPENSSL_CTX_METHOD must be defined and given in the C<meth> parameter. The index
|
||||
for it should be defined in cryptlib.h. The functions through the method are
|
||||
used to create or free items that are stored at that index whenever a library
|
||||
context is created or freed, meaning that the code that use a data item of that
|
||||
index doesn't have to worry about that, just use the data available.
|
||||
|
||||
Deallocation of an index happens automatically when the library
|
||||
context is freed.
|
||||
|
||||
openssl_ctx_get_data() is used to retrieve a pointer to the data in
|
||||
the library context C<ctx> associated with the given C<index>.
|
||||
openssl_ctx_run_once is used to run some initialisation routine C<run_once_fn>
|
||||
exactly once per library context C<ctx> object. Each initialisation routine
|
||||
should be allocate a unique run once index in cryptlib.h.
|
||||
|
||||
Any resources allocated via a run once initialisation routine can be cleaned up
|
||||
using openssl_ctx_onfree. This associates an "on free" routine C<onfreefn> with
|
||||
the library context C<ctx>. When C<ctx> is freed all associated "on free"
|
||||
routines are called.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
openssl_ctx_new_index() returns -1 on error, otherwise the allocated
|
||||
index number.
|
||||
|
||||
openssl_ctx_get_data() returns a pointer on success, or C<NULL> on
|
||||
failure.
|
||||
|
||||
@@ -53,17 +64,14 @@ failure.
|
||||
|
||||
For a type C<FOO> that should end up in the OpenSSL library context, a
|
||||
small bit of initialization is needed, i.e. to associate a constructor
|
||||
and a destructor to a new index.
|
||||
|
||||
/* The index will always be entirely global, and dynamically allocated */
|
||||
static int foo_index = -1;
|
||||
and a destructor to an index.
|
||||
|
||||
typedef struct foo_st {
|
||||
int i;
|
||||
void *data;
|
||||
} FOO;
|
||||
|
||||
static void *foo_new(void)
|
||||
static void *foo_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
FOO *ptr = OPENSSL_zalloc(sizeof(*foo));
|
||||
if (ptr != NULL)
|
||||
@@ -74,27 +82,49 @@ and a destructor to a new index.
|
||||
{
|
||||
OPENSSL_free(ptr);
|
||||
}
|
||||
static const OPENSSL_CTX_METHOD foo_method = {
|
||||
|
||||
/*
|
||||
* Include a reference to this in the methods table in context.c
|
||||
* OPENSSL_CTX_FOO_INDEX should be added to internal/cryptlib.h
|
||||
*/
|
||||
const OPENSSL_CTX_METHOD foo_method = {
|
||||
foo_new,
|
||||
foo_free
|
||||
};
|
||||
|
||||
static int foo_init(void)
|
||||
{
|
||||
foo_index = openssl_ctx_new_index(foo_method);
|
||||
|
||||
return foo_index != -1;
|
||||
}
|
||||
|
||||
=head2 Usage
|
||||
|
||||
To get and use the data stored in the library context, simply do this:
|
||||
|
||||
/*
|
||||
* ctx is received from a caller,
|
||||
* foo_index comes from the example above
|
||||
*/
|
||||
FOO *data = openssl_ctx_get_data(ctx, foo_index);
|
||||
FOO *data = openssl_ctx_get_data(ctx, OPENSSL_CTX_FOO_INDEX, &foo_method);
|
||||
|
||||
=head2 Run Once
|
||||
|
||||
void foo_cleanup(OPENSSL_CTX *ctx)
|
||||
{
|
||||
/* Free foo resources associated with ctx */
|
||||
}
|
||||
|
||||
static openssl_ctx_run_once_fn do_foo_init;
|
||||
static int do_foo_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
/* Allocate and initialise some foo resources and associated with ctx */
|
||||
return openssl_ctx_onfree(ctx, &foo_cleanup)
|
||||
}
|
||||
|
||||
int foo_some_function(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (!openssl_ctx_run_once(ctx,
|
||||
OPENSSL_CTX_FOO_RUN_ONCE_INDEX,
|
||||
do_foo_init))
|
||||
return 0;
|
||||
|
||||
/* Do some work using foo resources in ctx */
|
||||
}
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
|
||||
|
||||
struct ossl_method_construct_method_st {
|
||||
/* Create store */
|
||||
void *(*alloc_tmp_store)(void);
|
||||
void *(*alloc_tmp_store)(OPENSSL_CTX *ctx);
|
||||
/* Remove a store */
|
||||
void (*dealloc_tmp_store)(void *store);
|
||||
/* Get an already existing method from a store */
|
||||
void *(*get)(OPENSSL_CTX *libctx, void *store, const char *propquery,
|
||||
void *data);
|
||||
void *(*get)(OPENSSL_CTX *libctx, void *store, const char *name,
|
||||
const char *propquery, void *data);
|
||||
/* Store a method in a store */
|
||||
int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef,
|
||||
void *method, void *data);
|
||||
int (*put)(OPENSSL_CTX *libctx, void *store, void *method,
|
||||
const char *name, const char *propdef, void *data);
|
||||
/* Construct a new method */
|
||||
void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns,
|
||||
void *(*construct)(const char *name, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *data);
|
||||
/* Destruct a method */
|
||||
void (*destruct)(void *method);
|
||||
@@ -33,6 +33,7 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
|
||||
int force_cache,
|
||||
OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data);
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
All libcrypto sub-systems that want to create their own methods based
|
||||
@@ -65,7 +66,7 @@ function pointers:
|
||||
|
||||
=item alloc_tmp_store()
|
||||
|
||||
Create a temporary method store.
|
||||
Create a temporary method store in the scope of the library context C<ctx>.
|
||||
This store is used to temporarily store methods for easier lookup, for
|
||||
when the provider doesn't want its dispatch table stored in a longer
|
||||
term cache.
|
||||
@@ -76,14 +77,15 @@ Remove a temporary store.
|
||||
|
||||
=item get()
|
||||
|
||||
Look up an already existing method from a store.
|
||||
Look up an already existing method from a store by name.
|
||||
|
||||
The store may be given with C<store>.
|
||||
B<NULL> 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 C<libctx>.
|
||||
|
||||
The method to be looked up should be identified with data from C<data>
|
||||
The method to be looked up should be identified with the given C<name> and
|
||||
data from C<data>
|
||||
(which is the C<mcm_data> that was passed to ossl_construct_method())
|
||||
and the provided property query C<propquery>.
|
||||
|
||||
@@ -99,15 +101,15 @@ B<NULL> 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 C<libctx>.
|
||||
|
||||
The method should be associated with the given property definition
|
||||
C<propdef> and any identification data given through C<data> (which is
|
||||
The method should be associated with the given C<name> and property definition
|
||||
C<propdef> as well as any identification data given through C<data> (which is
|
||||
the C<mcm_data> that was passed to ossl_construct_method()).
|
||||
|
||||
This function is expected to increment the C<method>'s reference count.
|
||||
|
||||
=item construct()
|
||||
|
||||
Constructs a sub-system method for the given C<algorithm_name> and the given
|
||||
Constructs a sub-system method for the given C<name> and the given
|
||||
dispatch table C<fns>.
|
||||
|
||||
The associated I<provider object> C<prov> is passed as well, to make
|
||||
@@ -132,7 +134,7 @@ B<NULL> on error.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
This functionality was added to OpenSSL 3.0.0.
|
||||
This functionality was added to OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored,
|
||||
ossl_namemap_add, ossl_namemap_name, ossl_namemap_number
|
||||
- internal number E<lt>-E<gt> name map
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx);
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_new(void);
|
||||
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
|
||||
|
||||
int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name);
|
||||
const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number);
|
||||
int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A B<OSSL_NAMEMAP> is a simple number E<lt>-E<gt> name map, which can
|
||||
be used to give any arbitrary name (any string) a unique dynamic
|
||||
identity that is valid throughout the lifetime of the associated
|
||||
library context.
|
||||
|
||||
ossl_namemap_new() and ossl_namemap_free() construct and destruct a
|
||||
new B<OSSL_NAMEMAP>.
|
||||
This is suitable to use when the B<OSSL_NAMEMAP> is embedded in other
|
||||
structures, or should be independent for any reason.
|
||||
|
||||
ossl_namemap_stored() finds or auto-creates the default namemap in the
|
||||
given library context.
|
||||
The returned B<OSSL_NAMEMAP> can't be destructed using
|
||||
ossl_namemap_free().
|
||||
|
||||
ossl_namemap_add() adds a new name to the namemap if it's not already
|
||||
present.
|
||||
|
||||
ossl_namemap_name() finds the name corresponding to the given number.
|
||||
|
||||
ossl_namemap_number() finds the number corresponding to the given
|
||||
name.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
|
||||
B<OSSL_NAMEMAP>, or NULL on error.
|
||||
|
||||
ossl_namemap_add() returns the number associated with the added
|
||||
string, or zero on error.
|
||||
|
||||
ossl_namemap_name() returns a pointer to the name corresponding to the
|
||||
given number, or NULL if it's undefined in the given B<OSSL_NAMEMAP>.
|
||||
|
||||
ossl_namemap_number() returns the number corresponding to the given
|
||||
name, or 0 if it's undefined in the given B<OSSL_NAMEMAP>.
|
||||
|
||||
=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<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
||||
@@ -5,7 +5,7 @@
|
||||
ossl_provider_find, ossl_provider_new, ossl_provider_upref,
|
||||
ossl_provider_free, ossl_provider_add_module_location,
|
||||
ossl_provider_set_fallback, ossl_provider_activate,
|
||||
ossl_provider_forall_loaded,
|
||||
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,
|
||||
@@ -29,6 +29,9 @@ ossl_provider_get_params, ossl_provider_query_operation
|
||||
/* Load and initialize the Provider */
|
||||
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
||||
|
||||
/* Return pointer to the provider's context */
|
||||
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
||||
|
||||
/* Iterate over all loaded providers */
|
||||
int ossl_provider_forall_loaded(OPENSSL_CTX *,
|
||||
int (*cb)(OSSL_PROVIDER *provider,
|
||||
@@ -121,6 +124,10 @@ be located in that module, and called.
|
||||
|
||||
=back
|
||||
|
||||
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.
|
||||
|
||||
ossl_provider_forall_loaded() iterates over all the currently
|
||||
"activated" providers, and calls C<cb> for each of them.
|
||||
If no providers have been "activated" yet, it tries to activate all
|
||||
|
||||
+11
-6
@@ -20,6 +20,7 @@ B<openssl dsaparam>
|
||||
[B<-writerand file>]
|
||||
[B<-genkey>]
|
||||
[B<-engine id>]
|
||||
[B<-verbose>]
|
||||
[B<numbits>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -89,12 +90,6 @@ all others.
|
||||
Writes random data to the specified I<file> upon exit.
|
||||
This can be used with a subsequent B<-rand> flag.
|
||||
|
||||
=item B<numbits>
|
||||
|
||||
This option specifies that a parameter set should be generated of size
|
||||
B<numbits>. It must be the last option. If this option is included then
|
||||
the input file (if any) is ignored.
|
||||
|
||||
=item B<-engine id>
|
||||
|
||||
Specifying an engine (by its unique B<id> string) will cause B<dsaparam>
|
||||
@@ -102,6 +97,16 @@ to attempt to obtain a functional reference to the specified engine,
|
||||
thus initialising it if needed. The engine will then be set as the default
|
||||
for all available algorithms.
|
||||
|
||||
=item B<-verbose>
|
||||
|
||||
Print extra details about the operations being performed.
|
||||
|
||||
=item B<numbits>
|
||||
|
||||
This option specifies that a parameter set should be generated of size
|
||||
B<numbits>. It must be the last option. If this option is included then
|
||||
the input file (if any) is ignored.
|
||||
|
||||
=back
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
@@ -25,6 +25,7 @@ B<openssl> B<gendsa>
|
||||
[B<-rand file...>]
|
||||
[B<-writerand file>]
|
||||
[B<-engine id>]
|
||||
[B<-verbose>]
|
||||
[B<paramfile>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -71,6 +72,10 @@ to attempt to obtain a functional reference to the specified engine,
|
||||
thus initialising it if needed. The engine will then be set as the default
|
||||
for all available algorithms.
|
||||
|
||||
=item B<-verbose>
|
||||
|
||||
Print extra details about the operations being performed.
|
||||
|
||||
=item B<paramfile>
|
||||
|
||||
This option specifies the DSA parameter file to use. The parameters in this
|
||||
|
||||
@@ -118,7 +118,7 @@ or ED448 algorithms.
|
||||
|
||||
=item B<rsa_keygen_bits:numbits>
|
||||
|
||||
The number of bits in the generated key. If not specified 1024 is used.
|
||||
The number of bits in the generated key. If not specified 2048 is used.
|
||||
|
||||
=item B<rsa_keygen_primes:numprimes>
|
||||
|
||||
@@ -185,12 +185,12 @@ below.
|
||||
|
||||
=item B<dsa_paramgen_bits:numbits>
|
||||
|
||||
The number of bits in the generated prime. If not specified 1024 is used.
|
||||
The number of bits in the generated prime. If not specified 2048 is used.
|
||||
|
||||
=item B<dsa_paramgen_q_bits:numbits>
|
||||
|
||||
The number of bits in the q parameter. Must be one of 160, 224 or 256. If not
|
||||
specified 160 is used.
|
||||
specified 224 is used.
|
||||
|
||||
=item B<dsa_paramgen_md:digest>
|
||||
|
||||
@@ -209,7 +209,7 @@ or B<sha256> if it is 256.
|
||||
|
||||
=item B<dh_paramgen_prime_len:numbits>
|
||||
|
||||
The number of bits in the prime parameter B<p>. The default is 1024.
|
||||
The number of bits in the prime parameter B<p>. The default is 2048.
|
||||
|
||||
=item B<dh_paramgen_subprime_len:numbits>
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ B<openssl> B<genrsa>
|
||||
[B<-writerand file>]
|
||||
[B<-engine id>]
|
||||
[B<-primes num>]
|
||||
[B<-verbose>]
|
||||
[B<numbits>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -91,6 +92,10 @@ parameter must be a positive integer that is greater than 1 and less than 16.
|
||||
If B<num> is greater than 2, then the generated key is called a 'multi-prime'
|
||||
RSA key, which is defined in RFC 8017.
|
||||
|
||||
=item B<-verbose>
|
||||
|
||||
Print extra details about the operations being performed.
|
||||
|
||||
=item B<numbits>
|
||||
|
||||
The size of the private key to generate in bits. This must be the last option
|
||||
|
||||
@@ -184,6 +184,7 @@ B<openssl> B<s_server>
|
||||
[B<-early_data>]
|
||||
[B<-anti_replay>]
|
||||
[B<-no_anti_replay>]
|
||||
[B<-http_server_binmode>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -743,6 +744,11 @@ has been negotiated, and early data is enabled on the server. A full handshake
|
||||
is forced if a session ticket is used a second or subsequent time. Any early
|
||||
data that was sent will be rejected.
|
||||
|
||||
=item B<-http_server_binmode>
|
||||
|
||||
When acting as web-server (using option B<-WWW> or B<-HTTP>) open files requested
|
||||
by the client in binary mode.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CONNECTED COMMANDS
|
||||
|
||||
@@ -412,7 +412,9 @@ The following I<ctrl>s are supported in CCM mode.
|
||||
This call is made to set the expected B<CCM> tag value when decrypting or
|
||||
the length of the tag (with the C<tag> parameter set to NULL) when encrypting.
|
||||
The tag length is often referred to as B<M>. If not set a default value is
|
||||
used (12 for AES).
|
||||
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<AEAD Interface>).
|
||||
|
||||
=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, ivlen, NULL)
|
||||
|
||||
|
||||
+61
-16
@@ -2,17 +2,21 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
EVP_KDF_CTX, EVP_KDF_CTX_new_id, EVP_KDF_CTX_free, EVP_KDF_reset,
|
||||
EVP_KDF_ctrl, EVP_KDF_vctrl, EVP_KDF_ctrl_str, EVP_KDF_size,
|
||||
EVP_KDF_derive - EVP KDF routines
|
||||
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 <openssl/kdf.h>
|
||||
|
||||
typedef struct evp_kdf_st EVP_KDF;
|
||||
typedef struct evp_kdf_ctx_st EVP_KDF_CTX;
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id);
|
||||
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, ...);
|
||||
@@ -20,29 +24,40 @@ EVP_KDF_derive - EVP KDF routines
|
||||
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<EVP_KDF_CTX> for the required algorithm using
|
||||
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.
|
||||
After creating a C<EVP_KDF_CTX> 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<EVP_KDF> is a type that holds the implementation of a KDF.
|
||||
|
||||
B<EVP_KDF_CTX> is a context type that holds the algorithm inputs.
|
||||
|
||||
=head2 Context manipulation functions
|
||||
|
||||
EVP_KDF_CTX_new_id() creates a KDF context for the algorithm identified by the
|
||||
specified NID.
|
||||
EVP_KDF_CTX_new() creates a new context for the KDF type C<kdf>.
|
||||
|
||||
EVP_KDF_CTX_new_id() creates a new context for the numerical KDF identity C<nid>.
|
||||
|
||||
EVP_KDF_CTX_free() frees up the context C<ctx>. If C<ctx> is C<NULL>, nothing
|
||||
is done.
|
||||
|
||||
EVP_KDF_CTX_kdf() returns the B<EVP_KDF> associated with the context
|
||||
C<ctx>.
|
||||
|
||||
=head2 Computing functions
|
||||
|
||||
EVP_KDF_reset() resets the context to the default state as if the context
|
||||
@@ -61,15 +76,32 @@ EVP_KDF_ctrl_str() allows an application to send an algorithm specific control
|
||||
operation to a context C<ctx> 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<keylen> bytes of key material and places it in the
|
||||
C<key> buffer. If the algorithm produces a fixed amount of output then an
|
||||
error will occur unless the C<keylen> 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<SIZE_MAX> 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_derive() derives C<keylen> bytes of key material and places it in the
|
||||
C<key> buffer. If the algorithm produces a fixed amount of output then an
|
||||
error will occur unless the C<keylen> parameter is equal to that output size,
|
||||
as returned by EVP_KDF_size().
|
||||
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
|
||||
|
||||
@@ -213,14 +245,26 @@ The value string is expected to be a decimal number.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
EVP_KDF_CTX_new_id() returns either the newly allocated C<EVP_KDF_CTX>
|
||||
structure or C<NULL> if an error occurred.
|
||||
EVP_KDF_CTX_new() and EVP_KDF_CTX_new_id() return either the newly allocated
|
||||
C<EVP_KDF_CTX> structure or C<NULL> 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<SIZE_MAX> 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<kdf>.
|
||||
|
||||
EVP_KDF_name() returns the name for the given C<kdf>, if it has been
|
||||
added to the object database.
|
||||
|
||||
EVP_add_kdf() returns 1 if the given C<kdf> 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<NULL>.
|
||||
|
||||
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.
|
||||
@@ -233,6 +277,7 @@ L<EVP_KDF_PBKDF2(7)>
|
||||
L<EVP_KDF_HKDF(7)>
|
||||
L<EVP_KDF_SS(7)>
|
||||
L<EVP_KDF_SSHKDF(7)>
|
||||
L<EVP_KDF_X963(7)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ L<EVP_PKEY_verify_recover_init(3)> and L<EVP_PKEY_verify_recover(3)>.
|
||||
|
||||
The signctx_init() and signctx() methods are used to sign a digest present by
|
||||
a B<EVP_MD_CTX> object. They are called by the EVP_DigestSign functions. See
|
||||
L<EVP_DigestSignInit(3)> for detail.
|
||||
L<EVP_DigestSignInit(3)> for details.
|
||||
|
||||
int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
|
||||
int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
|
||||
@@ -294,7 +294,7 @@ L<EVP_DigestSignInit(3)> for detail.
|
||||
|
||||
The verifyctx_init() and verifyctx() methods are used to verify a signature
|
||||
against the data in a B<EVP_MD_CTX> object. They are called by the various
|
||||
EVP_DigestVerify functions. See L<EVP_DigestVerifyInit(3)> for detail.
|
||||
EVP_DigestVerify functions. See L<EVP_DigestVerifyInit(3)> for details.
|
||||
|
||||
int (*encrypt_init) (EVP_PKEY_CTX *ctx);
|
||||
int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
|
||||
@@ -321,7 +321,7 @@ L<EVP_PKEY_derive_init(3)> and L<EVP_PKEY_derive(3)>.
|
||||
int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
|
||||
|
||||
The ctrl() and ctrl_str() methods are used to adjust algorithm-specific
|
||||
settings. See L<EVP_PKEY_CTX_ctrl(3)> and related functions for detail.
|
||||
settings. See L<EVP_PKEY_CTX_ctrl(3)> and related functions for details.
|
||||
|
||||
int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen);
|
||||
@@ -330,7 +330,7 @@ settings. See L<EVP_PKEY_CTX_ctrl(3)> and related functions for detail.
|
||||
size_t tbslen);
|
||||
|
||||
The digestsign() and digestverify() methods are used to generate or verify
|
||||
a signature in a one-shot mode. They could be called by L<EVP_DigetSign(3)>
|
||||
a signature in a one-shot mode. They could be called by L<EVP_DigestSign(3)>
|
||||
and L<EVP_DigestVerify(3)>.
|
||||
|
||||
int (*check) (EVP_PKEY *pkey);
|
||||
|
||||
@@ -250,7 +250,8 @@ All other functions return B<1> on success and B<0> on failure.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
Integral types will be widened and sign extended as required.
|
||||
Native types will be converted as required only if the value is exactly
|
||||
representable by the target type or parameter.
|
||||
Apart from that, the functions must be used appropriately for the
|
||||
expected type of the parameter.
|
||||
|
||||
|
||||
@@ -55,6 +55,11 @@ The content of B<buf> cannot be recovered from subsequent random generator outpu
|
||||
Applications that intend to save and restore random state in an external file
|
||||
should consider using L<RAND_load_file(3)> instead.
|
||||
|
||||
NOTE: In FIPS mode, random data provided by the application is not considered to
|
||||
be a trusted entropy source. It is mixed into the internal state of the RNG as
|
||||
additional data only and this does not count as a full reseed.
|
||||
For more details, see L<RAND_DRBG(7)>.
|
||||
|
||||
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>.
|
||||
|
||||
RAND_keep_random_devices_open() is used to control file descriptor
|
||||
@@ -86,6 +91,7 @@ L<RAND_bytes(3)>,
|
||||
L<RAND_egd(3)>,
|
||||
L<RAND_load_file(3)>,
|
||||
L<RAND(7)>
|
||||
L<RAND_DRBG(7)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ SSL_session_reused - query whether a reused session was negotiated during handsh
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
int SSL_session_reused(SSL *ssl);
|
||||
int SSL_session_reused(const SSL *ssl);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
+29
-2
@@ -2,12 +2,13 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SSL_write_ex, SSL_write - write bytes to a TLS/SSL connection
|
||||
SSL_write_ex, SSL_write, SSL_sendfile - write bytes to a TLS/SSL connection
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags);
|
||||
int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written);
|
||||
int SSL_write(SSL *ssl, const void *buf, int num);
|
||||
|
||||
@@ -17,6 +18,14 @@ SSL_write_ex() and SSL_write() write B<num> bytes from the buffer B<buf> into
|
||||
the specified B<ssl> connection. On success SSL_write_ex() will store the number
|
||||
of bytes written in B<*written>.
|
||||
|
||||
SSL_sendfile() writes B<size> bytes from offset B<offset> in the file
|
||||
descriptor B<fd> to the specified SSL connection B<s>. This function provides
|
||||
efficient zero-copy semantics. SSL_sendfile() is available only when
|
||||
Kernel TLS is enabled, which can be checked by calling BIO_get_ktls_send().
|
||||
It is provided here to allow users to maintain the same interface.
|
||||
The meaning of B<flags> is platform dependent.
|
||||
Currently, under Linux it is ignored.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
In the paragraphs below a "write function" is defined as one of either
|
||||
@@ -104,17 +113,35 @@ You should instead call SSL_get_error() to find out if it's retryable.
|
||||
|
||||
=back
|
||||
|
||||
For SSL_sendfile(), the following return values can occur:
|
||||
|
||||
=over 4
|
||||
|
||||
=item Z<>>= 0
|
||||
|
||||
The write operation was successful, the return value is the number
|
||||
of bytes of the file written to the TLS/SSL connection.
|
||||
|
||||
=item E<lt> 0
|
||||
|
||||
The write operation was not successful, because either the connection was
|
||||
closed, an error occured or action must be taken by the calling process.
|
||||
Call SSL_get_error() with the return value to find out the reason.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<SSL_get_error(3)>, L<SSL_read_ex(3)>, L<SSL_read(3)>
|
||||
L<SSL_CTX_set_mode(3)>, L<SSL_CTX_new(3)>,
|
||||
L<SSL_connect(3)>, L<SSL_accept(3)>
|
||||
L<SSL_set_connect_state(3)>,
|
||||
L<SSL_set_connect_state(3)>, L<BIO_ctrl(3)>,
|
||||
L<ssl(7)>, L<bio(7)>
|
||||
|
||||
=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.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user