Latest update (add quic)
This commit is contained in:
+78
-11
@@ -23,6 +23,68 @@ OpenSSL 3.0
|
||||
|
||||
### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
|
||||
|
||||
* Handshake now fails if Extended Master Secret extension is dropped
|
||||
on renegotiation.
|
||||
|
||||
*Tomas Mraz*
|
||||
|
||||
* Dropped interactive mode from the 'openssl' program. From now on,
|
||||
the `openssl` command without arguments is equivalent to `openssl
|
||||
help`.
|
||||
|
||||
*Richard Levitte*
|
||||
|
||||
* Renamed EVP_PKEY_cmp() to EVP_PKEY_eq() and
|
||||
EVP_PKEY_cmp_parameters() to EVP_PKEY_parameters_eq().
|
||||
While the old function names have been retained for backward compatibility
|
||||
they should not be used in new developments
|
||||
because their return values are confusing: Unlike other `_cmp()` functions
|
||||
they do not return 0 in case their arguments are equal.
|
||||
|
||||
*David von Oheimb*
|
||||
|
||||
* Deprecated EC_METHOD_get_field_type(). Applications should switch to
|
||||
EC_GROUP_get_field_type().
|
||||
|
||||
*Billy Bob Brumley*
|
||||
|
||||
* Deprecated EC_GFp_simple_method(), EC_GFp_mont_method(),
|
||||
EC_GF2m_simple_method(), EC_GFp_nist_method(), EC_GFp_nistp224_method()
|
||||
EC_GFp_nistp256_method(), and EC_GFp_nistp521_method().
|
||||
Applications should rely on the library automatically assigning a suitable
|
||||
EC_METHOD internally upon EC_GROUP construction.
|
||||
|
||||
*Billy Bob Brumley*
|
||||
|
||||
* Deprecated EC_GROUP_new(), EC_GROUP_method_of(), and EC_POINT_method_of().
|
||||
EC_METHOD is now an internal-only concept and a suitable EC_METHOD is
|
||||
assigned internally without application intervention.
|
||||
Users of EC_GROUP_new() should switch to a different suitable constructor.
|
||||
|
||||
*Billy Bob Brumley*
|
||||
|
||||
* Add CAdES-BES signature verification support, mostly derived
|
||||
from ESSCertIDv2 TS (RFC 5816) contribution by Marek Klein.
|
||||
|
||||
*Filipe Raimundo da Silva*
|
||||
|
||||
* Add CAdES-BES signature scheme and attributes support (RFC 5126) to CMS API.
|
||||
|
||||
*Antonio Iacono*
|
||||
|
||||
* Deprecated EC_POINT_make_affine() and EC_POINTs_make_affine(). These
|
||||
functions are not widely used and now OpenSSL automatically perform this
|
||||
conversion when needed.
|
||||
|
||||
*Billy Bob Brumley*
|
||||
|
||||
* Deprecated EC_GROUP_precompute_mult(), EC_GROUP_have_precompute_mult(), and
|
||||
EC_KEY_precompute_mult(). These functions are not widely used and
|
||||
applications should instead switch to named curves which OpenSSL has
|
||||
hardcoded lookup tables for.
|
||||
|
||||
*Billy Bob Brumley*
|
||||
|
||||
* Deprecated EC_POINTs_mul(). This function is not widely used and applications
|
||||
should instead use the L<EC_POINT_mul(3)> function.
|
||||
|
||||
@@ -35,6 +97,12 @@ OpenSSL 3.0
|
||||
|
||||
*Shane Lontis*
|
||||
|
||||
* The SSL option SSL_OP_IGNORE_UNEXPECTED_EOF is introduced. If that option
|
||||
is set, an unexpected EOF is ignored, it pretends a close notify was received
|
||||
instead and so the returned error becomes SSL_ERROR_ZERO_RETURN.
|
||||
|
||||
*Dmitry Belyavskiy*
|
||||
|
||||
* Deprecated EC_POINT_set_Jprojective_coordinates_GFp() and
|
||||
EC_POINT_get_Jprojective_coordinates_GFp(). These functions are not widely
|
||||
used and applications should instead use the
|
||||
@@ -109,6 +177,12 @@ OpenSSL 3.0
|
||||
|
||||
*David von Oheimb*
|
||||
|
||||
* BIO_do_connect and BIO_do_handshake have been extended:
|
||||
If domain name resolution yields multiple IP addresses all of them are tried
|
||||
after connect() failures.
|
||||
|
||||
*David von Oheimb*
|
||||
|
||||
* All of the low level RSA functions have been deprecated including:
|
||||
|
||||
RSA_new_method, RSA_size, RSA_security_bits, RSA_get0_pss_params,
|
||||
@@ -287,8 +361,8 @@ OpenSSL 3.0
|
||||
and HMAC_CTX_get_md.
|
||||
|
||||
Use of these low level functions has been informally discouraged for a long
|
||||
time. Instead applications should use L<EVP_MAC_CTX_new(3)>,
|
||||
L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
|
||||
time. Instead applications should use L<EVP_MAC_new_ctx(3)>,
|
||||
L<EVP_MAC_free_ctx(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
|
||||
and L<EVP_MAC_final(3)>.
|
||||
|
||||
*Paul Dale*
|
||||
@@ -311,8 +385,8 @@ OpenSSL 3.0
|
||||
CMAC_CTX_copy, CMAC_Init, CMAC_Update, CMAC_Final and CMAC_resume.
|
||||
|
||||
Use of these low level functions has been informally discouraged for a long
|
||||
time. Instead applications should use L<EVP_MAC_CTX_new(3)>,
|
||||
L<EVP_MAC_CTX_free(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
|
||||
time. Instead applications should use L<EVP_MAC_new_ctx(3)>,
|
||||
L<EVP_MAC_free_ctx(3)>, L<EVP_MAC_init(3)>, L<EVP_MAC_update(3)>
|
||||
and L<EVP_MAC_final(3)>.
|
||||
|
||||
*Paul Dale*
|
||||
@@ -514,13 +588,6 @@ OpenSSL 3.0
|
||||
- SSL_CTX_load_verify_dir()
|
||||
- SSL_CTX_load_verify_store()
|
||||
|
||||
Also, the following functions are now deprecated:
|
||||
|
||||
- X509_STORE_load_locations() (use X509_STORE_load_file(),
|
||||
X509_STORE_load_path() or X509_STORE_load_store() instead)
|
||||
- SSL_CTX_load_verify_locations() (use SSL_CTX_load_verify_file(),
|
||||
SSL_CTX_load_verify_dir() or SSL_CTX_load_verify_store() instead)
|
||||
|
||||
*Richard Levitte*
|
||||
|
||||
* Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY.
|
||||
|
||||
@@ -1004,7 +1004,6 @@ my %targets = (
|
||||
CFLAGS => add(picker(release => "-fomit-frame-pointer")),
|
||||
lib_cppflags => add("-DL_ENDIAN"),
|
||||
bn_ops => "BN_LLONG",
|
||||
shared_target => "bsd-shared",
|
||||
asm_arch => 'x86',
|
||||
perlasm_scheme => "a.out",
|
||||
},
|
||||
|
||||
@@ -40,12 +40,6 @@ my %shared_info;
|
||||
};
|
||||
},
|
||||
'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
|
||||
'bsd-shared' => sub {
|
||||
return $shared_info{'gnu-shared'} if detect_gnu_ld();
|
||||
return {
|
||||
shared_ldflag => '-shared -nostdlib',
|
||||
};
|
||||
},
|
||||
'darwin-shared' => {
|
||||
module_ldflags => '-bundle',
|
||||
shared_ldflag => '-dynamiclib -current_version $(SHLIB_VERSION_NUMBER) -compatibility_version $(SHLIB_VERSION_NUMBER)',
|
||||
|
||||
@@ -423,6 +423,7 @@ my @disablables = (
|
||||
"poly1305",
|
||||
"posix-io",
|
||||
"psk",
|
||||
"quic",
|
||||
"rc2",
|
||||
"rc4",
|
||||
"rc5",
|
||||
@@ -579,6 +580,7 @@ my @disable_cascades = (
|
||||
"legacy" => [ "md2" ],
|
||||
|
||||
"cmp" => [ "crmf" ],
|
||||
"tls1_3" => [ "quic" ],
|
||||
|
||||
# Padlock engine uses low-level AES APIs which are deprecated
|
||||
sub { $disabled{"deprecated-3.0"} }
|
||||
@@ -1124,6 +1126,9 @@ if (scalar(@seed_sources) == 0) {
|
||||
print "Using os-specific seed configuration\n";
|
||||
push @seed_sources, 'os';
|
||||
}
|
||||
if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
|
||||
delete $disabled{'egd'};
|
||||
}
|
||||
if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
|
||||
die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
|
||||
warn <<_____ if scalar(@seed_sources) == 1;
|
||||
|
||||
@@ -20,6 +20,7 @@ OpenSSL 3.0
|
||||
|
||||
### Major changes between OpenSSL 1.1.1 and OpenSSL 3.0 [under development]
|
||||
|
||||
* Interactive mode is removed from the 'openssl' program.
|
||||
* The X25519, X448, Ed25519, Ed448 and SHAKE256 algorithms are included in
|
||||
the FIPS provider. None have the "fips=yes" property set and, as such,
|
||||
will not be accidentially used.
|
||||
|
||||
+5
-3
@@ -35,9 +35,11 @@
|
||||
MinGW and Cygwin. The key recommendation is to use "matching" Perl,
|
||||
one that matches build environment. For example, if you will build
|
||||
on Cygwin be sure to use the Cygwin package manager to install Perl.
|
||||
For MSYS builds use the MSYS provided Perl. For VC-* builds we
|
||||
recommend ActiveState Perl, available from
|
||||
http://www.activestate.com/ActivePerl.
|
||||
For MSYS builds use the MSYS provided Perl.
|
||||
For VC-* builds we recommend Strawberry Perl, from http://strawberryperl.com.
|
||||
An alternative is ActiveState Perl, from http://www.activestate.com/ActivePerl
|
||||
for which you may need to explicitly select the Perl module Win32/Console.pm
|
||||
available via https://platform.activestate.com/ActiveState.
|
||||
|
||||
Notes on Perl on VMS
|
||||
--------------------
|
||||
|
||||
@@ -1,58 +1,74 @@
|
||||
|
||||
NOTES FOR THE WINDOWS PLATFORMS
|
||||
===============================
|
||||
NOTES FOR WINDOWS PLATFORMS
|
||||
===========================
|
||||
|
||||
Windows targets can be classified as "native", ones that use Windows API
|
||||
directly, and "hosted" which rely on POSIX-compatible layer. "Native"
|
||||
targets are VC-* (where "VC" stems from abbreviating Microsoft Visual C
|
||||
compiler) and mingw[64]. "Hosted" platforms are Cygwin and MSYS[2]. Even
|
||||
though the latter is not directly supported by OpenSSL Team, it's #1
|
||||
popular choice for building MinGW targets. In the nutshell MinGW builds
|
||||
are always cross-compiled. On Linux and Cygwin they look exactly as such
|
||||
and require --cross-compile-prefix option. While on MSYS[2] it's solved
|
||||
rather by placing gcc that produces "MinGW binary" code 1st on $PATH.
|
||||
This is customarily source of confusion. "Hosted" applications "live" in
|
||||
emulated file system name space with POSIX-y root, mount points, /dev
|
||||
and even /proc. Confusion is intensified by the fact that MSYS2 shell
|
||||
(or rather emulated execve(2) call) examines the binary it's about to
|
||||
start, and if it's found *not* to be linked with MSYS2 POSIX-y thing,
|
||||
command line arguments that look like file names get translated from
|
||||
emulated name space to "native". For example '/c/some/where' becomes
|
||||
'c:\some\where', '/dev/null' - 'nul'. This creates an illusion that
|
||||
there is no difference between MSYS2 shell and "MinGW binary", but
|
||||
there is. Just keep in mind that "MinGW binary" "experiences" Windows
|
||||
system in exactly same way as one produced by VC, and in its essence
|
||||
is indistinguishable from the latter. (Which by the way is why
|
||||
it's referred to in quotes here, as "MinGW binary", it's just as
|
||||
"native" as it can get.)
|
||||
There are various options to build and run OpenSSL on the Windows platforms.
|
||||
|
||||
Visual C++ builds, a.k.a. VC-*
|
||||
==============================
|
||||
"Native" OpenSSL uses the Windows APIs directly at run time.
|
||||
To build a native OpenSSL you can either use:
|
||||
|
||||
Microsoft Visual C++ (MSVC) C compiler on the command line
|
||||
or
|
||||
MinGW cross compiler
|
||||
run on the GNU-like development environment MSYS2
|
||||
or run on Linux or Cygwin
|
||||
|
||||
"Hosted" OpenSSL relies on an external POSIX compatibility layer
|
||||
for building (using GNU/Unix shell, compiler, and tools) and at run time.
|
||||
For this option you can use Cygwin.
|
||||
|
||||
|
||||
Visual C++ native builds, a.k.a. VC-*
|
||||
=====================================
|
||||
|
||||
Requirement details
|
||||
-------------------
|
||||
|
||||
In addition to the requirements and instructions listed in INSTALL,
|
||||
In addition to the requirements and instructions listed in INSTALL.md,
|
||||
these are required as well:
|
||||
|
||||
- Perl. We recommend ActiveState Perl, available from
|
||||
https://www.activestate.com/ActivePerl. Another viable alternative
|
||||
appears to be Strawberry Perl, http://strawberryperl.com.
|
||||
You also need the perl module Text::Template, available on CPAN.
|
||||
Please read NOTES.PERL for more information.
|
||||
- Perl.
|
||||
We recommend Strawberry Perl, available from http://strawberryperl.com/
|
||||
Please read NOTES.PERL for more information, including the use of CPAN.
|
||||
An alternative is ActiveState Perl, https://www.activestate.com/ActivePerl
|
||||
for which you may need to explicitly build the Perl module Win32/Console.pm
|
||||
via https://platform.activestate.com/ActiveState and then download it.
|
||||
|
||||
- Microsoft Visual C compiler. Since we can't test them all, there is
|
||||
unavoidable uncertainty about which versions are supported. Latest
|
||||
version along with couple of previous are certainly supported. On
|
||||
the other hand oldest one is known not to work. Everything between
|
||||
falls into best-effort category.
|
||||
- Microsoft Visual C compiler.
|
||||
Since these are proprietary and ever-changing we cannot test them all.
|
||||
Older versions may not work. Use a recent version wherever possible.
|
||||
|
||||
- Netwide Assembler, a.k.a. NASM, available from https://www.nasm.us,
|
||||
is required. Note that NASM is the only supported assembler. Even
|
||||
though Microsoft provided assembler is NOT supported, contemporary
|
||||
64-bit version is exercised through continuous integration of
|
||||
VC-WIN64A-masm target.
|
||||
- Netwide Assembler (NASM), available from https://www.nasm.us
|
||||
Note that NASM is the only supported assembler.
|
||||
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
1. Install Perl
|
||||
|
||||
2. Install NASM
|
||||
|
||||
3. Make sure both Perl and NASM are on your %PATH%
|
||||
|
||||
4. Use Visual Studio Developer Command Prompt with administrative privileges,
|
||||
choosing one of its variants depending on the intended architecture.
|
||||
Or run "cmd" and execute "vcvarsall.bat" with one of the options x86,
|
||||
x86_amd64, x86_arm, x86_arm64, amd64, amd64_x86, amd64_arm, or amd64_arm64.
|
||||
This sets up the environment variables needed for nmake.exe, cl.exe, etc.
|
||||
See also https://docs.microsoft.com/cpp/build/building-on-the-command-line
|
||||
|
||||
5. From the root of the OpenSSL source directory enter
|
||||
perl Configure VC-WIN32 if you want 32-bit OpenSSL or
|
||||
perl Configure VC-WIN64A if you want 64-bit OpenSSL
|
||||
|
||||
6. nmake
|
||||
|
||||
7. nmake test
|
||||
|
||||
8. nmake install
|
||||
|
||||
For the full installation instructions, or if anything goes wrong at any stage,
|
||||
check the INSTALL.md file.
|
||||
|
||||
Installation directories
|
||||
------------------------
|
||||
@@ -83,7 +99,6 @@
|
||||
is, of course, to choose a different set of directories by using
|
||||
--prefix and --openssldir when configuring.
|
||||
|
||||
|
||||
Special notes for Universal Windows Platform builds, a.k.a. VC-*-UWP
|
||||
--------------------------------------------------------------------
|
||||
|
||||
@@ -91,33 +106,56 @@
|
||||
|
||||
- You should define the platform type to "uwp" and the target arch via
|
||||
"vcvarsall.bat" before you compile. For example, if you want to build
|
||||
"arm64" builds, you should type "vcvarsall.bat x86_arm64 uwp".
|
||||
"arm64" builds, you should run "vcvarsall.bat x86_arm64 uwp".
|
||||
|
||||
mingw and mingw64
|
||||
=================
|
||||
|
||||
* MSYS2 shell and development environment installation:
|
||||
Native OpenSSL built using MinGW
|
||||
================================
|
||||
|
||||
Download MSYS2 from https://msys2.github.io/ and follow installation
|
||||
instructions. Once up and running install even make, perl, (git if
|
||||
needed,) mingw-w64-i686-gcc and/or mingw-w64-x86_64-gcc. You should
|
||||
have corresponding MinGW items on your start menu, use *them*, not
|
||||
generic MSYS2. As implied in opening note, difference between them
|
||||
is which compiler is found 1st on $PATH. At this point ./config
|
||||
should recognize correct target, roll as if it was Unix...
|
||||
MinGW offers an alternative way to build native OpenSSL, by cross compilation.
|
||||
|
||||
* It is also possible to build mingw[64] on Linux or Cygwin by
|
||||
configuring with corresponding --cross-compile-prefix= option. For
|
||||
example
|
||||
* Usually the build is done on Windows in a GNU-like environment called MSYS2.
|
||||
|
||||
MSYS2 provides GNU tools, a Unix-like command prompt,
|
||||
and a UNIX compatibility layer for applications.
|
||||
However in this context it is only used for building OpenSSL.
|
||||
The resulting OpenSSL does not rely on MSYS2 to run and is fully native.
|
||||
|
||||
Requirement details
|
||||
|
||||
- MSYS2 shell, from https://www.msys2.org/
|
||||
|
||||
- Perl, at least version 5.10.0, which usually comes pre-installed with MSYS2
|
||||
|
||||
- make, installed using "pacman -S make" into the MSYS2 environment
|
||||
|
||||
- MinGW[64] compiler: mingw-w64-i686-gcc and/or mingw-w64-x86_64-gcc.
|
||||
These compilers must be on your MSYS2 $PATH.
|
||||
A common error is to not have these on your $PATH.
|
||||
The MSYS2 version of gcc will not work correctly here.
|
||||
|
||||
In the MSYS2 shell do the configuration depending on the target architecture:
|
||||
|
||||
./Configure mingw ...
|
||||
or
|
||||
./Configure mingw64 ...
|
||||
or
|
||||
./config ...
|
||||
for the default architecture.
|
||||
|
||||
Apart from that, follow the Unix / Linux instructions in INSTALL.md.
|
||||
|
||||
* It is also possible to build mingw[64] on Linux or Cygwin.
|
||||
|
||||
In this case configure with the corresponding --cross-compile-prefix= option.
|
||||
For example
|
||||
|
||||
./Configure mingw --cross-compile-prefix=i686-w64-mingw32- ...
|
||||
|
||||
or
|
||||
|
||||
./Configure mingw64 --cross-compile-prefix=x86_64-w64-mingw32- ...
|
||||
|
||||
This naturally implies that you've installed corresponding add-on
|
||||
packages.
|
||||
This requires that you've installed the necessary add-on packages for
|
||||
mingw[64] cross compilation.
|
||||
|
||||
Linking your application
|
||||
========================
|
||||
@@ -146,28 +184,29 @@
|
||||
}
|
||||
|
||||
If you link with OpenSSL .DLLs, then you're expected to include into
|
||||
your application code small "shim" snippet, which provides glue between
|
||||
OpenSSL BIO layer and your compiler run-time. See the OPENSSL_Applink
|
||||
manual page for further details.
|
||||
your application code a small "shim" snippet, which provides
|
||||
the glue between the OpenSSL BIO layer and your compiler run-time.
|
||||
See also the OPENSSL_Applink manual page.
|
||||
|
||||
Cygwin, "hosted" environment
|
||||
============================
|
||||
|
||||
Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of the
|
||||
Windows subsystem and provides a bash shell and GNU tools environment.
|
||||
Consequently, a make of OpenSSL with Cygwin is virtually identical to the
|
||||
Hosted OpenSSL built using Cygwin
|
||||
=================================
|
||||
|
||||
Cygwin implements a POSIX/Unix runtime system (cygwin1.dll) on top of the
|
||||
Windows subsystem and provides a Bash shell and GNU tools environment.
|
||||
Consequently, a build of OpenSSL with Cygwin is virtually identical to the
|
||||
Unix procedure.
|
||||
|
||||
To build OpenSSL using Cygwin, you need to:
|
||||
|
||||
* Install Cygwin (see https://cygwin.com/)
|
||||
* Install Cygwin, see https://cygwin.com/
|
||||
|
||||
* Install Cygwin Perl and ensure it is in the path. Recall that
|
||||
as least 5.10.0 is required.
|
||||
* Install Cygwin Perl, at least version 5.10.0
|
||||
and ensure it is in the $PATH
|
||||
|
||||
* Run the Cygwin bash shell
|
||||
* Run the Cygwin Bash shell
|
||||
|
||||
Apart from that, follow the Unix instructions in INSTALL.
|
||||
Apart from that, follow the Unix / Linux instructions in INSTALL.md.
|
||||
|
||||
NOTE: "make test" and normal file operations may fail in directories
|
||||
mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
MAJOR=3
|
||||
MINOR=0
|
||||
PATCH=0
|
||||
PRE_RELEASE_TAG=alpha3-dev
|
||||
PRE_RELEASE_TAG=alpha4-dev
|
||||
BUILD_METADATA=
|
||||
RELEASE_DATE=""
|
||||
SHLIB_VERSION=3
|
||||
+5
-2
@@ -14,8 +14,8 @@ $OPENSSLSRC=\
|
||||
openssl.c progs.c \
|
||||
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c \
|
||||
enc.c errstr.c \
|
||||
genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c \
|
||||
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c \
|
||||
genpkey.c kdf.c mac.c nseq.c passwd.c pkcs7.c \
|
||||
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \
|
||||
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \
|
||||
spkac.c verify.c version.c x509.c rehash.c storeutl.c \
|
||||
list.c info.c provider.c fipsinstall.c
|
||||
@@ -43,6 +43,9 @@ ENDIF
|
||||
IF[{- !$disabled{'engine'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC engine.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'rsa'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC rsa.c genrsa.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'cmp'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC cmp.c cmp_mock_srv.c
|
||||
ENDIF
|
||||
|
||||
+29
-11
@@ -347,16 +347,16 @@ const OPTIONS cmp_options[] = {
|
||||
|
||||
OPT_SECTION("Server authentication"),
|
||||
{"trusted", OPT_TRUSTED, 's',
|
||||
"Trusted certs used for CMP server authentication when verifying responses"},
|
||||
"Certificates to trust as chain roots when verifying signed CMP responses"},
|
||||
{OPT_MORE_STR, 0, 0, "unless -srvcert is given"},
|
||||
{"untrusted", OPT_UNTRUSTED, 's',
|
||||
"Intermediate certs for chain construction verifying CMP/TLS/enrolled certs"},
|
||||
"Intermediate CA certs for chain construction for CMP/TLS/enrolled certs"},
|
||||
{"srvcert", OPT_SRVCERT, 's',
|
||||
"Specific CMP server cert to use and trust directly when verifying responses"},
|
||||
"Server cert to pin and trust directly when verifying signed CMP responses"},
|
||||
{"recipient", OPT_RECIPIENT, 's',
|
||||
"Distinguished Name (DN) of the recipient to use unless -srvcert is given"},
|
||||
"Distinguished Name (DN) to use as msg recipient; see man page for defaults"},
|
||||
{"expect_sender", OPT_EXPECT_SENDER, 's',
|
||||
"DN of expected response sender. Defaults to DN of -srvcert, if provided"},
|
||||
"DN of expected sender of responses. Defaults to subject of -srvcert, if any"},
|
||||
{"ignore_keyusage", OPT_IGNORE_KEYUSAGE, '-',
|
||||
"Ignore CMP signer cert key usage, else 'digitalSignature' must be allowed"},
|
||||
{"unprotected_errors", OPT_UNPROTECTED_ERRORS, '-',
|
||||
@@ -1637,8 +1637,7 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, ENGINE *e)
|
||||
|
||||
/*
|
||||
* Any further certs and any untrusted certs are used for constructing
|
||||
* the client cert chain to be provided along with the TLS client cert
|
||||
* to the TLS server.
|
||||
* the chain to be provided with the TLS client cert to the TLS server.
|
||||
*/
|
||||
if (!SSL_CTX_set0_chain(ssl_ctx, certs)) {
|
||||
CMP_err("could not set TLS client cert chain");
|
||||
@@ -2097,9 +2096,12 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *e)
|
||||
goto oom;
|
||||
if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy))
|
||||
goto oom;
|
||||
if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy))
|
||||
goto oom;
|
||||
(void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s%s%s/%s",
|
||||
opt_tls_used ? "s" : "", opt_server,
|
||||
server_port == 0 ? "" : ":", server_port_s,
|
||||
opt_path == NULL ? "" :
|
||||
opt_path[0] == '/' ? opt_path + 1 : opt_path);
|
||||
|
||||
if (opt_proxy != NULL)
|
||||
@@ -2221,7 +2223,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *e)
|
||||
if (!set_name(opt_recipient, OSSL_CMP_CTX_set1_recipient, ctx, "recipient")
|
||||
|| !set_name(opt_expect_sender, OSSL_CMP_CTX_set1_expected_sender,
|
||||
ctx, "expected sender"))
|
||||
goto oom;
|
||||
goto err;
|
||||
|
||||
if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
|
||||
goto err;
|
||||
@@ -2977,12 +2979,13 @@ int cmp_main(int argc, char **argv)
|
||||
if ((acbio = http_server_init_bio(prog, opt_port)) == NULL)
|
||||
goto err;
|
||||
while (opt_max_msgs <= 0 || msgs < opt_max_msgs) {
|
||||
char *path = NULL;
|
||||
OSSL_CMP_MSG *req = NULL;
|
||||
OSSL_CMP_MSG *resp = NULL;
|
||||
|
||||
ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
(ASN1_VALUE **)&req, &cbio, acbio,
|
||||
prog, 0, 0);
|
||||
(ASN1_VALUE **)&req, &path,
|
||||
&cbio, acbio, prog, 0, 0);
|
||||
if (ret == 0)
|
||||
continue;
|
||||
if (ret++ == -1)
|
||||
@@ -2991,17 +2994,32 @@ int cmp_main(int argc, char **argv)
|
||||
ret = 0;
|
||||
msgs++;
|
||||
if (req != NULL) {
|
||||
if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) {
|
||||
(void)http_server_send_status(cbio, 404, "Not Found");
|
||||
CMP_err1("Expecting empty path or 'pkix/' but got '%s'",
|
||||
path);
|
||||
OPENSSL_free(path);
|
||||
OSSL_CMP_MSG_free(req);
|
||||
goto cont;
|
||||
}
|
||||
OPENSSL_free(path);
|
||||
resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req);
|
||||
OSSL_CMP_MSG_free(req);
|
||||
if (resp == NULL)
|
||||
if (resp == NULL) {
|
||||
(void)http_server_send_status(cbio,
|
||||
500, "Internal Server Error");
|
||||
break; /* treated as fatal error */
|
||||
}
|
||||
ret = http_server_send_asn1_resp(cbio, "application/pkixcmp",
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
(const ASN1_VALUE *)resp);
|
||||
OSSL_CMP_MSG_free(resp);
|
||||
if (!ret)
|
||||
break; /* treated as fatal error */
|
||||
} else {
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
}
|
||||
cont:
|
||||
BIO_free_all(cbio);
|
||||
cbio = NULL;
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
}
|
||||
if (ctx->certOut != NULL
|
||||
&& (*certOut = X509_dup(ctx->certOut)) == NULL)
|
||||
/* TODO better return a cert produced from data in request template */
|
||||
goto err;
|
||||
if (ctx->chainOut != NULL
|
||||
&& (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
|
||||
|
||||
+10
-3
@@ -670,12 +670,18 @@ int cms_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
if (flags & CMS_CADES) {
|
||||
if (flags & CMS_NOATTR) {
|
||||
if ((flags & CMS_CADES) != 0) {
|
||||
if ((flags & CMS_NOATTR) != 0) {
|
||||
BIO_puts(bio_err, "Incompatible options: "
|
||||
"CAdES required signed attributes\n");
|
||||
goto opthelp;
|
||||
}
|
||||
if (operation == SMIME_VERIFY
|
||||
&& (flags & (CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY)) != 0) {
|
||||
BIO_puts(bio_err, "Incompatible options: CAdES validation require"
|
||||
" certs and signed attributes validations\n");
|
||||
goto opthelp;
|
||||
}
|
||||
}
|
||||
|
||||
if (operation & SMIME_SIGNERS) {
|
||||
@@ -1115,7 +1121,8 @@ int cms_main(int argc, char **argv)
|
||||
goto end;
|
||||
} else if (operation == SMIME_VERIFY) {
|
||||
if (CMS_verify(cms, other, store, indata, out, flags) > 0) {
|
||||
BIO_printf(bio_err, "Verification successful\n");
|
||||
BIO_printf(bio_err, "%s Verification successful\n",
|
||||
(flags & CMS_CADES) ? "CAdES" : "CMS");
|
||||
} else {
|
||||
BIO_printf(bio_err, "Verification failure\n");
|
||||
if (verify_retcode)
|
||||
|
||||
+20
-30
@@ -84,7 +84,7 @@ const OPTIONS dhparam_options[] = {
|
||||
int dhparam_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
DH *dh = NULL;
|
||||
DH *dh = NULL, *alloc_dh = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
char *infile = NULL, *outfile = NULL, *prog;
|
||||
@@ -177,7 +177,7 @@ int dhparam_main(int argc, char **argv)
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
if (dsaparam && g) {
|
||||
BIO_printf(bio_err,
|
||||
"generator may not be chosen for DSA parameters\n");
|
||||
"Error, generator may not be chosen for DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
@@ -198,10 +198,8 @@ int dhparam_main(int argc, char **argv)
|
||||
DSA *dsa = DSA_new();
|
||||
BN_GENCB *cb = BN_GENCB_new();
|
||||
|
||||
if (cb == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
if (cb == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
BN_GENCB_set(cb, dh_cb, bio_err);
|
||||
|
||||
@@ -212,23 +210,20 @@ int dhparam_main(int argc, char **argv)
|
||||
cb)) {
|
||||
DSA_free(dsa);
|
||||
BN_GENCB_free(cb);
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to generate DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
dh = DSA_dup_DH(dsa);
|
||||
dh = alloc_dh = DSA_dup_DH(dsa);
|
||||
DSA_free(dsa);
|
||||
BN_GENCB_free(cb);
|
||||
if (dh == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
if (dh == NULL)
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, DH key generation context allocation failed\n");
|
||||
goto end;
|
||||
@@ -242,20 +237,18 @@ int dhparam_main(int argc, char **argv)
|
||||
if (!EVP_PKEY_paramgen_init(ctx)) {
|
||||
BIO_printf(bio_err,
|
||||
"Error, unable to initialise DH param generation\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, num)) {
|
||||
BIO_printf(bio_err, "Error, unable to set DH prime length\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_paramgen(ctx, &pkey)) {
|
||||
BIO_printf(bio_err, "Error, DH generation failed\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
dh = EVP_PKEY_get0_DH(pkey);
|
||||
}
|
||||
} else {
|
||||
in = bio_open_default(infile, 'r', informat);
|
||||
@@ -272,17 +265,14 @@ int dhparam_main(int argc, char **argv)
|
||||
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
|
||||
|
||||
if (dsa == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to load DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
dh = DSA_dup_DH(dsa);
|
||||
dh = alloc_dh = DSA_dup_DH(dsa);
|
||||
DSA_free(dsa);
|
||||
if (dh == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
if (dh == NULL)
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -291,18 +281,17 @@ int dhparam_main(int argc, char **argv)
|
||||
* We have no PEM header to determine what type of DH params it
|
||||
* is. We'll just try both.
|
||||
*/
|
||||
dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, in, NULL);
|
||||
dh = alloc_dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, in, NULL);
|
||||
/* BIO_reset() returns 0 for success for file BIOs only!!! */
|
||||
if (dh == NULL && BIO_reset(in) == 0)
|
||||
dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, in, NULL);
|
||||
dh = alloc_dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, in, NULL);
|
||||
} else {
|
||||
/* informat == FORMAT_PEM */
|
||||
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
dh = alloc_dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (dh == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to load DH parameters\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -314,8 +303,7 @@ int dhparam_main(int argc, char **argv)
|
||||
|
||||
if (check) {
|
||||
if (!EVP_PKEY_param_check(ctx) /* DH_check(dh, &i) */) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "ERROR: Invalid parameters generated\n");
|
||||
BIO_printf(bio_err, "Error, invalid parameters generated\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_err, "DH parameters appear to be ok.\n");
|
||||
@@ -324,7 +312,7 @@ int dhparam_main(int argc, char **argv)
|
||||
* We have generated parameters but DH_check() indicates they are
|
||||
* invalid! This should never happen!
|
||||
*/
|
||||
BIO_printf(bio_err, "ERROR: Invalid parameters generated\n");
|
||||
BIO_printf(bio_err, "Error, invalid parameters generated\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -382,13 +370,15 @@ int dhparam_main(int argc, char **argv)
|
||||
i = PEM_write_bio_DHparams(out, dh);
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to write DH parameters\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
DH_free(alloc_dh);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
+23
-56
@@ -66,9 +66,8 @@ const OPTIONS dsaparam_options[] = {
|
||||
int dsaparam_main(int argc, char **argv)
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
DSA *dsa = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY *params = NULL, *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
int numbits = -1, num = 0, genkey = 0;
|
||||
int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
|
||||
@@ -150,7 +149,6 @@ int dsaparam_main(int argc, char **argv)
|
||||
|
||||
ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, DSA parameter generation context allocation failed\n");
|
||||
goto end;
|
||||
@@ -170,62 +168,41 @@ int dsaparam_main(int argc, char **argv)
|
||||
BIO_printf(bio_err, "This could take some time\n");
|
||||
}
|
||||
if (EVP_PKEY_paramgen_init(ctx) <= 0) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, DSA key generation paramgen init failed\n");
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num)) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, DSA key generation setting bit length failed\n");
|
||||
goto end;
|
||||
}
|
||||
if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
|
||||
ERR_print_errors(bio_err);
|
||||
if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) {
|
||||
BIO_printf(bio_err, "Error, DSA key generation failed\n");
|
||||
goto end;
|
||||
}
|
||||
dsa = EVP_PKEY_get1_DSA(pkey);
|
||||
if (dsa == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, DSA key extraction failed\n");
|
||||
goto end;
|
||||
}
|
||||
} else if (informat == FORMAT_ASN1) {
|
||||
dsa = d2i_DSAparams_bio(in, NULL);
|
||||
params = d2i_KeyParams_bio(EVP_PKEY_DSA, NULL, in);
|
||||
} else {
|
||||
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
|
||||
params = PEM_read_bio_Parameters(in, NULL);
|
||||
}
|
||||
if (dsa == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
if (params == NULL) {
|
||||
BIO_printf(bio_err, "Error, unable to load DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (pkey == NULL) {
|
||||
pkey = EVP_PKEY_new();
|
||||
if (pkey == NULL) {
|
||||
BIO_printf(bio_err, "Error, unable to allocate PKEY object\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
|
||||
BIO_printf(bio_err, "Error, unable to set DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (text) {
|
||||
EVP_PKEY_print_params(out, pkey, 0, NULL);
|
||||
EVP_PKEY_print_params(out, params, 0, NULL);
|
||||
}
|
||||
|
||||
if (C) {
|
||||
const BIGNUM *p = NULL, *q = NULL, *g = NULL;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL;
|
||||
unsigned char *data;
|
||||
int len, bits_p;
|
||||
|
||||
DSA_get0_pqg(dsa, &p, &q, &g);
|
||||
EVP_PKEY_get_bn_param(params, "p", &p);
|
||||
EVP_PKEY_get_bn_param(params, "q", &q);
|
||||
EVP_PKEY_get_bn_param(params, "g", &g);
|
||||
len = BN_num_bytes(p);
|
||||
bits_p = BN_num_bits(p);
|
||||
|
||||
@@ -261,56 +238,46 @@ int dsaparam_main(int argc, char **argv)
|
||||
|
||||
if (!noout) {
|
||||
if (outformat == FORMAT_ASN1)
|
||||
i = i2d_DSAparams_bio(out, dsa);
|
||||
i = i2d_KeyParams_bio(out, params);
|
||||
else
|
||||
i = PEM_write_bio_DSAparams(out, dsa);
|
||||
i = PEM_write_bio_Parameters(out, params);
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to write DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (genkey) {
|
||||
DSA *dsakey;
|
||||
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
|
||||
ctx = EVP_PKEY_CTX_new(params, NULL);
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, DSA key generation context allocation failed\n");
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_keygen_init(ctx)) {
|
||||
BIO_printf(bio_err, "unable to initialise for key generation\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err,
|
||||
"Error, unable to initialise for key generation\n");
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_keygen(ctx, &pkey)) {
|
||||
BIO_printf(bio_err, "unable to generate key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
dsakey = EVP_PKEY_get0_DSA(pkey);
|
||||
if (dsakey == NULL) {
|
||||
BIO_printf(bio_err, "unable to extract generated key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, unable to generate key\n");
|
||||
goto end;
|
||||
}
|
||||
assert(private);
|
||||
if (outformat == FORMAT_ASN1)
|
||||
i = i2d_DSAPrivateKey_bio(out, dsakey);
|
||||
i = i2d_PrivateKey_bio(out, pkey);
|
||||
else
|
||||
i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL,
|
||||
NULL);
|
||||
i = PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL);
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
DSA_free(dsa);
|
||||
EVP_PKEY_free(params);
|
||||
release_engine(e);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+1
-2
@@ -305,7 +305,6 @@ int ecparam_main(int argc, char **argv)
|
||||
size_t buf_len = 0, tmp_len = 0;
|
||||
const EC_POINT *point;
|
||||
int is_prime, len = 0;
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(group);
|
||||
|
||||
if ((ec_p = BN_new()) == NULL
|
||||
|| (ec_a = BN_new()) == NULL
|
||||
@@ -317,7 +316,7 @@ int ecparam_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
|
||||
is_prime = (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field);
|
||||
if (!is_prime) {
|
||||
BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
|
||||
goto end;
|
||||
|
||||
+5
-5
@@ -366,7 +366,7 @@ opthelp:
|
||||
goto end;
|
||||
}
|
||||
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
ctx = EVP_MAC_new_ctx(mac);
|
||||
if (ctx == NULL) {
|
||||
BIO_printf(bio_err, "Unable to create MAC CTX for module check\n");
|
||||
goto end;
|
||||
@@ -380,7 +380,7 @@ opthelp:
|
||||
if (params == NULL)
|
||||
goto end;
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(ctx, params)) {
|
||||
if (!EVP_MAC_set_ctx_params(ctx, params)) {
|
||||
BIO_printf(bio_err, "MAC parameter error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
ok = 0;
|
||||
@@ -390,7 +390,7 @@ opthelp:
|
||||
goto end;
|
||||
}
|
||||
|
||||
ctx2 = EVP_MAC_CTX_dup(ctx);
|
||||
ctx2 = EVP_MAC_dup_ctx(ctx);
|
||||
if (ctx2 == NULL) {
|
||||
BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n");
|
||||
goto end;
|
||||
@@ -450,8 +450,8 @@ cleanup:
|
||||
BIO_free(module_bio);
|
||||
sk_OPENSSL_STRING_free(opts);
|
||||
EVP_MAC_free(mac);
|
||||
EVP_MAC_CTX_free(ctx2);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free_ctx(ctx2);
|
||||
EVP_MAC_free_ctx(ctx);
|
||||
OPENSSL_free(read_buffer);
|
||||
free_config_and_unload(conf);
|
||||
return ret;
|
||||
|
||||
+34
-52
@@ -29,11 +29,14 @@
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
static int genrsa_cb(EVP_PKEY_CTX *ctx);
|
||||
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,
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
OPT_3,
|
||||
#endif
|
||||
OPT_F4, OPT_ENGINE,
|
||||
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE,
|
||||
OPT_R_ENUM, OPT_PROV_ENUM
|
||||
} OPTION_CHOICE;
|
||||
@@ -48,9 +51,11 @@ const OPTIONS genrsa_options[] = {
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"3", OPT_3, '-', "Use 3 for the E value"},
|
||||
{"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
|
||||
{"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
{"3", OPT_3, '-', "(deprecated) Use 3 for the E value"},
|
||||
#endif
|
||||
{"F4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"},
|
||||
{"f4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"},
|
||||
|
||||
OPT_SECTION("Output"),
|
||||
{"out", OPT_OUT, '>', "Output the key to specified file"},
|
||||
@@ -70,24 +75,24 @@ const OPTIONS genrsa_options[] = {
|
||||
int genrsa_main(int argc, char **argv)
|
||||
{
|
||||
BN_GENCB *cb = BN_GENCB_new();
|
||||
PW_CB_DATA cb_data;
|
||||
ENGINE *eng = NULL;
|
||||
BIGNUM *bn = BN_new();
|
||||
RSA *rsa;
|
||||
BIO *out = NULL;
|
||||
const BIGNUM *e;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
RSA *rsa = NULL;
|
||||
const EVP_CIPHER *enc = NULL;
|
||||
int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES;
|
||||
unsigned long f4 = RSA_F4;
|
||||
char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
|
||||
char *prog, *hexe, *dece;
|
||||
OPTION_CHOICE o;
|
||||
unsigned char *ebuf = NULL;
|
||||
|
||||
if (bn == NULL || cb == NULL)
|
||||
goto end;
|
||||
|
||||
BN_GENCB_set(cb, genrsa_cb, bio_err);
|
||||
|
||||
prog = opt_init(argc, argv, genrsa_options);
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
@@ -100,9 +105,11 @@ opthelp:
|
||||
ret = 0;
|
||||
opt_help(genrsa_options);
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
case OPT_3:
|
||||
f4 = RSA_3;
|
||||
f4 = 3;
|
||||
break;
|
||||
#endif
|
||||
case OPT_F4:
|
||||
f4 = RSA_F4;
|
||||
break;
|
||||
@@ -162,74 +169,49 @@ opthelp:
|
||||
if (out == NULL)
|
||||
goto end;
|
||||
|
||||
if (!init_gen_str(&ctx, "RSA", eng, 0))
|
||||
goto end;
|
||||
|
||||
EVP_PKEY_CTX_set_cb(ctx, genrsa_cb);
|
||||
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
|
||||
|
||||
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, num) <= 0) {
|
||||
BIO_printf(bio_err, "Error setting RSA length\n");
|
||||
goto end;
|
||||
}
|
||||
if (!BN_set_word(bn, f4)) {
|
||||
BIO_printf(bio_err, "Error allocating RSA public exponent\n");
|
||||
goto end;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, bn) <= 0) {
|
||||
BIO_printf(bio_err, "Error setting RSA public exponent\n");
|
||||
goto end;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) <= 0) {
|
||||
BIO_printf(bio_err, "Error setting number of primes\n");
|
||||
goto end;
|
||||
}
|
||||
if (verbose)
|
||||
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
|
||||
num, primes);
|
||||
if (!EVP_PKEY_keygen(ctx, &pkey)) {
|
||||
BIO_printf(bio_err, "Error generating RSA key\n");
|
||||
rsa = eng ? RSA_new_method(eng) : RSA_new();
|
||||
if (rsa == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
|
||||
RSA_get0_key(rsa, NULL, &e, NULL);
|
||||
} else {
|
||||
BIO_printf(bio_err, "Error cannot access RSA e\n");
|
||||
if (!BN_set_word(bn, f4)
|
||||
|| !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb))
|
||||
goto end;
|
||||
}
|
||||
|
||||
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);
|
||||
OPENSSL_free(dece);
|
||||
}
|
||||
if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout))
|
||||
cb_data.password = passout;
|
||||
cb_data.prompt_info = outfile;
|
||||
assert(private);
|
||||
if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
|
||||
(pem_password_cb *)password_callback,
|
||||
&cb_data))
|
||||
goto end;
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
BN_free(bn);
|
||||
BN_GENCB_free(cb);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
RSA_free(rsa);
|
||||
BIO_free_all(out);
|
||||
release_engine(eng);
|
||||
OPENSSL_free(passout);
|
||||
OPENSSL_free(ebuf);
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int genrsa_cb(EVP_PKEY_CTX *ctx)
|
||||
static int genrsa_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
|
||||
int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
|
||||
|
||||
if (!verbose)
|
||||
return 1;
|
||||
@@ -242,7 +224,7 @@ static int genrsa_cb(EVP_PKEY_CTX *ctx)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(b, &c, 1);
|
||||
(void)BIO_flush(b);
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void)BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
+2
-25
@@ -15,6 +15,7 @@
|
||||
# include "internal/sockets.h" /* for openssl_fdset() */
|
||||
# include <assert.h>
|
||||
|
||||
# include <stdarg.h>
|
||||
# include <sys/types.h>
|
||||
# ifndef OPENSSL_NO_POSIX_IO
|
||||
# include <sys/stat.h>
|
||||
@@ -29,7 +30,6 @@
|
||||
# include <openssl/txt_db.h>
|
||||
# include <openssl/engine.h>
|
||||
# include <openssl/ocsp.h>
|
||||
# include <openssl/http.h>
|
||||
# include <signal.h>
|
||||
# include "apps_ui.h"
|
||||
# include "opt.h"
|
||||
@@ -179,6 +179,7 @@ typedef struct ca_db_st {
|
||||
# endif
|
||||
} CA_DB;
|
||||
|
||||
void app_bail_out(char *fmt, ...);
|
||||
void* app_malloc(int sz, const char *what);
|
||||
BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai);
|
||||
int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
|
||||
@@ -227,30 +228,6 @@ void print_cert_checks(BIO *bio, X509 *x,
|
||||
|
||||
void store_setup_crl_download(X509_STORE *st);
|
||||
|
||||
typedef struct app_http_tls_info_st {
|
||||
const char *server;
|
||||
const char *port;
|
||||
int use_proxy;
|
||||
long timeout;
|
||||
SSL_CTX *ssl_ctx;
|
||||
} APP_HTTP_TLS_INFO;
|
||||
BIO *app_http_tls_cb(BIO *hbio, /* APP_HTTP_TLS_INFO */ void *arg,
|
||||
int connect, int detail);
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
long timeout, const char *expected_content_type,
|
||||
const ASN1_ITEM *it);
|
||||
ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
|
||||
const char *path, const char *proxy,
|
||||
const char *no_proxy, SSL_CTX *ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
long timeout, const ASN1_ITEM *rsp_it);
|
||||
# endif
|
||||
|
||||
# define EXT_COPY_NONE 0
|
||||
# define EXT_COPY_ADD 1
|
||||
# define EXT_COPY_ALL 2
|
||||
|
||||
@@ -60,23 +60,29 @@ void log_message(const char *prog, int level, const char *fmt, ...);
|
||||
* returns a BIO for accepting requests, NULL on error
|
||||
*/
|
||||
BIO *http_server_init_bio(const char *prog, const char *port);
|
||||
|
||||
/*-
|
||||
* Accept an ASN.1-formatted HTTP request
|
||||
* it: the expected request ASN.1 type
|
||||
* preq: pointer to variable where to place the parsed request
|
||||
* pcbio: pointer to variable where to place the BIO for sending the response to
|
||||
* ppath: pointer to variable where to place the request path, or NULL
|
||||
* acbio: the listening bio (typically as returned by http_server_init_bio())
|
||||
* prog: the name of the current app
|
||||
* accept_get: wheter to accept GET requests (in addition to POST requests)
|
||||
* accept_get: whether to accept GET requests (in addition to POST requests)
|
||||
* timeout: connection timeout (in seconds), or 0 for none/infinite
|
||||
* returns 0 in case caller should retry, then *preq == *pcbio == NULL
|
||||
* returns -1 on fatal error; also in this case *preq == *pcbio == NULL
|
||||
* returns 1 otherwise. In this case it is guaranteed that *pcbio != NULL
|
||||
* while *preq == NULL if and only if request is invalid
|
||||
* returns 0 in case caller should retry, then *preq == *ppath == *pcbio == NULL
|
||||
* returns -1 on fatal error; also then holds *preq == *ppath == *pcbio == NULL
|
||||
* returns 1 otherwise. In this case it is guaranteed that *pcbio != NULL while
|
||||
* *ppath == NULL and *preq == NULL if and only if the request is invalid,
|
||||
* On return value 1 the caller is responsible for sending an HTTP response,
|
||||
* using http_server_send_asn1_resp() or http_server_send_status().
|
||||
* The caller must free any non-NULL *preq, *ppath, and *pcbio pointers.
|
||||
*/
|
||||
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
BIO **pcbio, BIO *acbio,
|
||||
char **ppath, BIO **pcbio, BIO *acbio,
|
||||
const char *prog, int accept_get, int timeout);
|
||||
|
||||
/*-
|
||||
* Send an ASN.1-formatted HTTP response
|
||||
* cbio: destination BIO (typically as returned by http_server_get_asn1_req())
|
||||
@@ -89,6 +95,16 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
*/
|
||||
int http_server_send_asn1_resp(BIO *cbio, const char *content_type,
|
||||
const ASN1_ITEM *it, const ASN1_VALUE *resp);
|
||||
|
||||
/*-
|
||||
* Send a trivial HTTP response, typically to report an error or OK
|
||||
* cbio: destination BIO (typically as returned by http_server_get_asn1_req())
|
||||
* status: the status code to send
|
||||
* reason: the corresponding human-readable string
|
||||
* returns 1 on success, 0 on failure
|
||||
*/
|
||||
int http_server_send_status(BIO *cbio, int status, const char *reason);
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef HTTP_DAEMON
|
||||
|
||||
+3
-3
@@ -104,7 +104,7 @@ opthelp:
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
ctx = EVP_KDF_CTX_new(kdf);
|
||||
ctx = EVP_KDF_new_ctx(kdf);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -116,7 +116,7 @@ opthelp:
|
||||
if (params == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EVP_KDF_CTX_set_params(ctx, params)) {
|
||||
if (!EVP_KDF_set_ctx_params(ctx, params)) {
|
||||
BIO_printf(bio_err, "KDF parameter error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
ok = 0;
|
||||
@@ -161,7 +161,7 @@ err:
|
||||
OPENSSL_clear_free(dkm_bytes, dkm_len);
|
||||
sk_OPENSSL_STRING_free(opts);
|
||||
EVP_KDF_free(kdf);
|
||||
EVP_KDF_CTX_free(ctx);
|
||||
EVP_KDF_free_ctx(ctx);
|
||||
BIO_free(out);
|
||||
OPENSSL_free(hexout);
|
||||
return ret;
|
||||
|
||||
+22
-195
@@ -438,10 +438,6 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin,
|
||||
|
||||
if (desc == NULL)
|
||||
desc = "certificate";
|
||||
if (uri == NULL) {
|
||||
unbuffer(stdin);
|
||||
uri = "";
|
||||
}
|
||||
(void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL);
|
||||
if (cert == NULL) {
|
||||
BIO_printf(bio_err, "Unable to load %s\n", desc);
|
||||
@@ -453,7 +449,7 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin,
|
||||
/* the format parameter is meanwhile not needed anymore and thus ignored */
|
||||
X509 *load_cert(const char *uri, int format, const char *desc)
|
||||
{
|
||||
return load_cert_pass(uri, 0, NULL, desc);
|
||||
return load_cert_pass(uri, 1, NULL, desc);
|
||||
}
|
||||
|
||||
/* the format parameter is meanwhile not needed anymore and thus ignored */
|
||||
@@ -671,16 +667,24 @@ static int load_certs_crls(const char *file, int format,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void app_bail_out(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
BIO_vprintf(bio_err, fmt, args);
|
||||
va_end(args);
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void* app_malloc(int sz, const char *what)
|
||||
{
|
||||
void *vp = OPENSSL_malloc(sz);
|
||||
|
||||
if (vp == NULL) {
|
||||
BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
|
||||
if (vp == NULL)
|
||||
app_bail_out("%s: Could not allocate %d bytes for %s\n",
|
||||
opt_getprog(), sz, what);
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
return vp;
|
||||
}
|
||||
|
||||
@@ -1627,7 +1631,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (*cp) {
|
||||
while (*cp != '\0') {
|
||||
char *bp = work;
|
||||
char *typestr = bp;
|
||||
unsigned char *valstr;
|
||||
@@ -1636,7 +1640,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
nextismulti = 0;
|
||||
|
||||
/* Collect the type */
|
||||
while (*cp && *cp != '=')
|
||||
while (*cp != '\0' && *cp != '=')
|
||||
*bp++ = *cp++;
|
||||
if (*cp == '\0') {
|
||||
BIO_printf(bio_err,
|
||||
@@ -1649,7 +1653,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
|
||||
/* Collect the value. */
|
||||
valstr = (unsigned char *)bp;
|
||||
for (; *cp && *cp != '/'; *bp++ = *cp++) {
|
||||
for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) {
|
||||
if (canmulti && *cp == '+') {
|
||||
nextismulti = 1;
|
||||
break;
|
||||
@@ -1664,7 +1668,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
*bp++ = '\0';
|
||||
|
||||
/* If not at EOS (must be + or /), move forward. */
|
||||
if (*cp)
|
||||
if (*cp != '\0')
|
||||
++cp;
|
||||
|
||||
/* Parse */
|
||||
@@ -1683,6 +1687,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
|
||||
valstr, strlen((char *)valstr),
|
||||
-1, ismulti ? -1 : 0)) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "%s: Error adding name attribute \"/%s=%s\"\n",
|
||||
opt_getprog(), typestr ,valstr);
|
||||
goto err;
|
||||
@@ -1949,137 +1954,6 @@ void store_setup_crl_download(X509_STORE *st)
|
||||
X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
static const char *tls_error_hint(void)
|
||||
{
|
||||
unsigned long err = ERR_peek_error();
|
||||
|
||||
if (ERR_GET_LIB(err) != ERR_LIB_SSL)
|
||||
err = ERR_peek_last_error();
|
||||
if (ERR_GET_LIB(err) != ERR_LIB_SSL)
|
||||
return NULL;
|
||||
|
||||
switch (ERR_GET_REASON(err)) {
|
||||
case SSL_R_WRONG_VERSION_NUMBER:
|
||||
return "The server does not support (a suitable version of) TLS";
|
||||
case SSL_R_UNKNOWN_PROTOCOL:
|
||||
return "The server does not support HTTPS";
|
||||
case SSL_R_CERTIFICATE_VERIFY_FAILED:
|
||||
return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
|
||||
case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
|
||||
return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
|
||||
case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
|
||||
return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
|
||||
default: /* no error or no hint available for error */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* HTTP callback function that supports TLS connection also via HTTPS proxy */
|
||||
BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
|
||||
{
|
||||
APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
|
||||
SSL_CTX *ssl_ctx = info->ssl_ctx;
|
||||
SSL *ssl;
|
||||
BIO *sbio = NULL;
|
||||
|
||||
if (connect && detail) { /* connecting with TLS */
|
||||
if ((info->use_proxy
|
||||
&& !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
|
||||
NULL, NULL, /* no proxy credentials */
|
||||
info->timeout, bio_err, opt_getprog()))
|
||||
|| (sbio = BIO_new(BIO_f_ssl())) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) {
|
||||
BIO_free(sbio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSL_set_tlsext_host_name(ssl, info->server);
|
||||
|
||||
SSL_set_connect_state(ssl);
|
||||
BIO_set_ssl(sbio, ssl, BIO_CLOSE);
|
||||
|
||||
hbio = BIO_push(sbio, hbio);
|
||||
} else if (!connect && !detail) { /* disconnecting after error */
|
||||
const char *hint = tls_error_hint();
|
||||
if (hint != NULL)
|
||||
ERR_add_error_data(2, " : ", hint);
|
||||
/*
|
||||
* If we pop sbio and BIO_free() it this may lead to libssl double free.
|
||||
* Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
|
||||
*/
|
||||
}
|
||||
return hbio;
|
||||
}
|
||||
|
||||
ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
long timeout, const char *expected_content_type,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
APP_HTTP_TLS_INFO info;
|
||||
char *server;
|
||||
char *port;
|
||||
int use_ssl;
|
||||
ASN1_VALUE *resp = NULL;
|
||||
|
||||
if (url == NULL || it == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!OSSL_HTTP_parse_url(url, &server, &port, NULL /* ppath */, &use_ssl))
|
||||
return NULL;
|
||||
if (use_ssl && ssl_ctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
ERR_add_error_data(1, "missing SSL_CTX");
|
||||
goto end;
|
||||
}
|
||||
|
||||
info.server = server;
|
||||
info.port = port;
|
||||
info.use_proxy = proxy != NULL;
|
||||
info.timeout = timeout;
|
||||
info.ssl_ctx = ssl_ctx;
|
||||
resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy,
|
||||
NULL, NULL, app_http_tls_cb, &info,
|
||||
headers, 0 /* maxline */, 0 /* max_resp_len */,
|
||||
timeout, expected_content_type, it);
|
||||
end:
|
||||
OPENSSL_free(server);
|
||||
OPENSSL_free(port);
|
||||
return resp;
|
||||
|
||||
}
|
||||
|
||||
ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
|
||||
const char *path, const char *proxy,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
long timeout, const ASN1_ITEM *rsp_it)
|
||||
{
|
||||
APP_HTTP_TLS_INFO info;
|
||||
|
||||
info.server = host;
|
||||
info.port = port;
|
||||
info.use_proxy = proxy != NULL;
|
||||
info.timeout = timeout;
|
||||
info.ssl_ctx = ssl_ctx;
|
||||
return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
|
||||
proxy, no_proxy,
|
||||
NULL, NULL, app_http_tls_cb, &info,
|
||||
headers, content_type, req, req_it,
|
||||
0 /* maxline */,
|
||||
0 /* max_resp_len */, timeout, NULL, rsp_it);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform-specific sections
|
||||
*/
|
||||
@@ -2230,70 +2104,23 @@ double app_tminterval(int stop, int usertime)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(OPENSSL_SYSTEM_VMS)
|
||||
# include <time.h>
|
||||
# include <times.h>
|
||||
|
||||
double app_tminterval(int stop, int usertime)
|
||||
{
|
||||
static clock_t tmstart;
|
||||
double ret = 0;
|
||||
clock_t now;
|
||||
# ifdef __TMS
|
||||
struct tms rus;
|
||||
|
||||
now = times(&rus);
|
||||
if (usertime)
|
||||
now = rus.tms_utime;
|
||||
# else
|
||||
if (usertime)
|
||||
now = clock(); /* sum of user and kernel times */
|
||||
else {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
|
||||
(unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
|
||||
);
|
||||
}
|
||||
# endif
|
||||
if (stop == TM_START)
|
||||
tmstart = now;
|
||||
else
|
||||
ret = (now - tmstart) / (double)(CLK_TCK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
|
||||
# include <sys/times.h>
|
||||
|
||||
double app_tminterval(int stop, int usertime)
|
||||
{
|
||||
double ret = 0;
|
||||
clock_t now;
|
||||
static clock_t tmstart;
|
||||
long int tck = sysconf(_SC_CLK_TCK);
|
||||
# ifdef __TMS
|
||||
struct tms rus;
|
||||
clock_t now = times(&rus);
|
||||
static clock_t tmstart;
|
||||
|
||||
now = times(&rus);
|
||||
if (usertime)
|
||||
now = rus.tms_utime;
|
||||
# else
|
||||
if (usertime)
|
||||
now = clock(); /* sum of user and kernel times */
|
||||
else {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
now = (clock_t)((unsigned long long)tv.tv_sec * tck +
|
||||
(unsigned long long)tv.tv_usec * (1000000 / tck)
|
||||
);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (stop == TM_START) {
|
||||
tmstart = now;
|
||||
} else {
|
||||
long int tck = sysconf(_SC_CLK_TCK);
|
||||
ret = (now - tmstart) / (double)tck;
|
||||
}
|
||||
|
||||
|
||||
+76
-23
@@ -255,17 +255,19 @@ static int urldecode(char *p)
|
||||
}
|
||||
|
||||
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
BIO **pcbio, BIO *acbio,
|
||||
char **ppath, BIO **pcbio, BIO *acbio,
|
||||
const char *prog, int accept_get, int timeout)
|
||||
{
|
||||
BIO *cbio = NULL, *getbio = NULL, *b64 = NULL;
|
||||
int len;
|
||||
char reqbuf[2048], inbuf[2048];
|
||||
char *url, *end;
|
||||
char *meth, *url, *end;
|
||||
ASN1_VALUE *req;
|
||||
int ret = 1;
|
||||
|
||||
*preq = NULL;
|
||||
if (ppath != NULL)
|
||||
*ppath = NULL;
|
||||
*pcbio = NULL;
|
||||
|
||||
/* Connection loss before accept() is routine, ignore silently */
|
||||
@@ -275,6 +277,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
cbio = BIO_pop(acbio);
|
||||
*pcbio = cbio;
|
||||
if (cbio == NULL) {
|
||||
/* Cannot call http_server_send_status(cbio, ...) */
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -288,16 +291,26 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
|
||||
/* Read the request line. */
|
||||
len = BIO_gets(cbio, reqbuf, sizeof(reqbuf));
|
||||
if (len <= 0)
|
||||
if (len <= 0) {
|
||||
log_message(prog, LOG_INFO,
|
||||
"Request line read error or empty request");
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (accept_get && strncmp(reqbuf, "GET ", 4) == 0) {
|
||||
/* Expecting GET {sp} /URL {sp} HTTP/1.x */
|
||||
for (url = reqbuf + 4; *url == ' '; ++url)
|
||||
continue;
|
||||
meth = reqbuf;
|
||||
url = meth + 3;
|
||||
if ((accept_get && strncmp(meth, "GET ", 4) == 0)
|
||||
|| (url++, strncmp(meth, "POST ", 5) == 0)) {
|
||||
/* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
|
||||
*(url++) = '\0';
|
||||
while (*url == ' ')
|
||||
url++;
|
||||
if (*url != '/') {
|
||||
log_message(prog, LOG_INFO,
|
||||
"Invalid GET -- URL does not begin with '/': %s", url);
|
||||
"Invalid %s -- URL does not begin with '/': %s",
|
||||
meth, url);
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
url++;
|
||||
@@ -308,7 +321,9 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
break;
|
||||
if (strncmp(end, " HTTP/1.", 7) != 0) {
|
||||
log_message(prog, LOG_INFO,
|
||||
"Invalid GET -- bad HTTP/version string: %s", end + 1);
|
||||
"Invalid %s -- bad HTTP/version string: %s",
|
||||
meth, end + 1);
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
*end = '\0';
|
||||
@@ -318,39 +333,52 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
* 'url' was incremented above to point to the first byte *after*
|
||||
* the leading slash, so in case 'GET / ' it is now an empty string.
|
||||
*/
|
||||
if (url[0] == '\0')
|
||||
goto out;
|
||||
|
||||
len = urldecode(url);
|
||||
if (len <= 0) {
|
||||
log_message(prog, LOG_INFO,
|
||||
"Invalid GET request -- bad URL encoding: %s", url);
|
||||
if (strlen(meth) == 3 && url[0] == '\0') {
|
||||
(void)http_server_send_status(cbio, 200, "OK");
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = urldecode(url);
|
||||
if (len < 0) {
|
||||
log_message(prog, LOG_INFO,
|
||||
"Invalid %s request -- bad URL encoding: %s",
|
||||
meth, url);
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
if (strlen(meth) == 3) { /* GET */
|
||||
if ((getbio = BIO_new_mem_buf(url, len)) == NULL
|
||||
|| (b64 = BIO_new(BIO_f_base64())) == NULL) {
|
||||
log_message(prog, LOG_ERR,
|
||||
"Could not allocate base64 bio with size = %d", len);
|
||||
BIO_free_all(cbio);
|
||||
*pcbio = NULL;
|
||||
ret = -1;
|
||||
goto out;
|
||||
"Could not allocate base64 bio with size = %d",
|
||||
len);
|
||||
goto fatal;
|
||||
}
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
getbio = BIO_push(b64, getbio);
|
||||
} else if (strncmp(reqbuf, "POST ", 5) != 0) {
|
||||
}
|
||||
} else {
|
||||
log_message(prog, LOG_INFO,
|
||||
"HTTP request does not start with GET/POST: %s", reqbuf);
|
||||
/* TODO provide better diagnosis in case client tries TLS */
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* chop any further/duplicate leading or trailing '/' */
|
||||
while (*url == '/')
|
||||
url++;
|
||||
while (end >= url + 2 && end[-2] == '/' && end[-1] == '/')
|
||||
end--;
|
||||
*end = '\0';
|
||||
|
||||
/* Read and skip past the headers. */
|
||||
for (;;) {
|
||||
len = BIO_gets(cbio, inbuf, sizeof(inbuf));
|
||||
if (len <= 0) {
|
||||
log_message(prog, LOG_ERR,
|
||||
"Error skipping remaining HTTP headers");
|
||||
(void)http_server_send_status(cbio, 400, "Bad Request");
|
||||
goto out;
|
||||
}
|
||||
if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
|
||||
@@ -365,8 +393,14 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
|
||||
/* Try to read and parse request */
|
||||
req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL);
|
||||
if (req == NULL)
|
||||
if (req == NULL) {
|
||||
log_message(prog, LOG_ERR, "Error parsing request");
|
||||
} else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) {
|
||||
log_message(prog, LOG_ERR,
|
||||
"Out of memory allocating %d bytes", strlen(url) + 1);
|
||||
ASN1_item_free(req, it);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
*preq = req;
|
||||
|
||||
@@ -378,6 +412,17 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
|
||||
acfd = (int)INVALID_SOCKET;
|
||||
# endif
|
||||
return ret;
|
||||
|
||||
fatal:
|
||||
(void)http_server_send_status(cbio, 500, "Internal Server Error");
|
||||
if (ppath != NULL) {
|
||||
OPENSSL_free(*ppath);
|
||||
*ppath = NULL;
|
||||
}
|
||||
BIO_free_all(cbio);
|
||||
*pcbio = NULL;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* assumes that cbio does not do an encoding that changes the output length */
|
||||
@@ -392,4 +437,12 @@ int http_server_send_asn1_resp(BIO *cbio, const char *content_type,
|
||||
(void)BIO_flush(cbio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int http_server_send_status(BIO *cbio, int status, const char *reason)
|
||||
{
|
||||
int ret = BIO_printf(cbio, "HTTP/1.0 %d %s\r\n\r\n", status, reason) > 0;
|
||||
|
||||
(void)BIO_flush(cbio);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+9
-18
@@ -209,6 +209,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
|
||||
{
|
||||
switch (*s) {
|
||||
default:
|
||||
opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
|
||||
return 0;
|
||||
case 'D':
|
||||
case 'd':
|
||||
@@ -275,6 +276,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
|
||||
return opt_format_error(s, flags);
|
||||
*result = FORMAT_PKCS12;
|
||||
} else {
|
||||
opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -740,40 +742,29 @@ int opt_next(void)
|
||||
break;
|
||||
case 'p':
|
||||
case 'n':
|
||||
if (!opt_int(arg, &ival)
|
||||
|| (o->valtype == 'p' && ival <= 0)) {
|
||||
if (!opt_int(arg, &ival))
|
||||
return -1;
|
||||
if (o->valtype == 'p' && ival <= 0) {
|
||||
opt_printf_stderr("%s: Non-positive number \"%s\" for -%s\n",
|
||||
prog, arg, o->name);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
if (!opt_imax(arg, &imval)) {
|
||||
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
|
||||
prog, arg, o->name);
|
||||
if (!opt_imax(arg, &imval))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
if (!opt_umax(arg, &umval)) {
|
||||
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
|
||||
prog, arg, o->name);
|
||||
if (!opt_umax(arg, &umval))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (!opt_long(arg, &lval)) {
|
||||
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
|
||||
prog, arg, o->name);
|
||||
if (!opt_long(arg, &lval))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if (!opt_ulong(arg, &ulval)) {
|
||||
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
|
||||
prog, arg, o->name);
|
||||
if (!opt_ulong(arg, &ulval))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
case 'E':
|
||||
|
||||
+2
-2
@@ -787,7 +787,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
|
||||
BIO_printf(bio_err, "HMAC not found\n");
|
||||
goto end;
|
||||
}
|
||||
ctx = EVP_MAC_CTX_new(hmac);
|
||||
ctx = EVP_MAC_new_ctx(hmac);
|
||||
if (ctx == NULL) {
|
||||
BIO_printf(bio_err, "HMAC context allocation failed\n");
|
||||
goto end;
|
||||
@@ -796,7 +796,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, cookie_secret,
|
||||
COOKIE_SECRET_LENGTH);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (!EVP_MAC_CTX_set_params(ctx, params)) {
|
||||
if (!EVP_MAC_set_ctx_params(ctx, params)) {
|
||||
BIO_printf(bio_err, "HMAC context parameter setting failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
+3
-3
@@ -114,7 +114,7 @@ opthelp:
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
ctx = EVP_MAC_new_ctx(mac);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -126,7 +126,7 @@ opthelp:
|
||||
if (params == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(ctx, params)) {
|
||||
if (!EVP_MAC_set_ctx_params(ctx, params)) {
|
||||
BIO_printf(bio_err, "MAC parameter error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
ok = 0;
|
||||
@@ -199,7 +199,7 @@ err:
|
||||
sk_OPENSSL_STRING_free(opts);
|
||||
BIO_free(in);
|
||||
BIO_free(out);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free_ctx(ctx);
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
}
|
||||
+122
-13
@@ -83,6 +83,13 @@ static char *prog;
|
||||
static int index_changed(CA_DB *);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
|
||||
const char *path,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
OCSP_REQUEST *req, int req_timeout);
|
||||
#endif
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT,
|
||||
@@ -234,7 +241,7 @@ int ocsp_main(int argc, char **argv)
|
||||
int noCAfile = 0, noCApath = 0, noCAstore = 0;
|
||||
int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1;
|
||||
int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1;
|
||||
int req_text = 0, resp_text = 0, ret = 1;
|
||||
int req_text = 0, resp_text = 0, res, ret = 1;
|
||||
int req_timeout = -1;
|
||||
long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
|
||||
unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
|
||||
@@ -274,8 +281,7 @@ int ocsp_main(int argc, char **argv)
|
||||
OPENSSL_free(tport);
|
||||
OPENSSL_free(tpath);
|
||||
thost = tport = tpath = NULL;
|
||||
if (!OSSL_HTTP_parse_url(opt_arg(),
|
||||
&host, &port, &path, &use_ssl)) {
|
||||
if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) {
|
||||
BIO_printf(bio_err, "%s Error parsing URL\n", prog);
|
||||
goto end;
|
||||
}
|
||||
@@ -629,13 +635,17 @@ redo_accept:
|
||||
#endif
|
||||
|
||||
req = NULL;
|
||||
if (!do_responder(&req, &cbio, acbio, req_timeout))
|
||||
res = do_responder(&req, &cbio, acbio, req_timeout);
|
||||
if (res == 0)
|
||||
goto redo_accept;
|
||||
|
||||
if (req == NULL) {
|
||||
resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
|
||||
if (res == 1) {
|
||||
resp =
|
||||
OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
|
||||
NULL);
|
||||
send_ocsp_response(cbio, resp);
|
||||
}
|
||||
goto done_resp;
|
||||
}
|
||||
}
|
||||
@@ -1151,7 +1161,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
|
||||
{
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_RESPONSE),
|
||||
(ASN1_VALUE **)preq, pcbio, acbio,
|
||||
(ASN1_VALUE **)preq, NULL, pcbio, acbio,
|
||||
prog, 1 /* accept_get */, timeout);
|
||||
#else
|
||||
BIO_printf(bio_err,
|
||||
@@ -1175,34 +1185,133 @@ static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp)
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
|
||||
const char *path,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
OCSP_REQUEST *req, int req_timeout)
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
int i;
|
||||
int add_host = 1;
|
||||
OCSP_REQ_CTX *ctx = NULL;
|
||||
OCSP_RESPONSE *rsp = NULL;
|
||||
fd_set confds;
|
||||
struct timeval tv;
|
||||
|
||||
if (req_timeout != -1)
|
||||
BIO_set_nbio(cbio, 1);
|
||||
|
||||
rv = BIO_do_connect(cbio);
|
||||
|
||||
if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
|
||||
BIO_puts(bio_err, "Error connecting BIO\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BIO_get_fd(cbio, &fd) < 0) {
|
||||
BIO_puts(bio_err, "Can't get connection fd\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (req_timeout != -1 && rv <= 0) {
|
||||
FD_ZERO(&confds);
|
||||
openssl_fdset(fd, &confds);
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = req_timeout;
|
||||
rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
|
||||
if (rv == 0) {
|
||||
BIO_puts(bio_err, "Timeout on connect\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
|
||||
CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
|
||||
if (add_host == 1 && strcasecmp("host", hdr->name) == 0)
|
||||
add_host = 0;
|
||||
if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0)
|
||||
goto err;
|
||||
|
||||
if (!OCSP_REQ_CTX_set1_req(ctx, req))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
rv = OCSP_sendreq_nbio(&rsp, ctx);
|
||||
if (rv != -1)
|
||||
break;
|
||||
if (req_timeout == -1)
|
||||
continue;
|
||||
FD_ZERO(&confds);
|
||||
openssl_fdset(fd, &confds);
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = req_timeout;
|
||||
if (BIO_should_read(cbio)) {
|
||||
rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
|
||||
} else if (BIO_should_write(cbio)) {
|
||||
rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
|
||||
} else {
|
||||
BIO_puts(bio_err, "Unexpected retry condition\n");
|
||||
goto err;
|
||||
}
|
||||
if (rv == 0) {
|
||||
BIO_puts(bio_err, "Timeout on request\n");
|
||||
break;
|
||||
}
|
||||
if (rv == -1) {
|
||||
BIO_puts(bio_err, "Select error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
err:
|
||||
OCSP_REQ_CTX_free(ctx);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
|
||||
const char *host, const char *path,
|
||||
const char *port, int use_ssl,
|
||||
STACK_OF(CONF_VALUE) *headers,
|
||||
int req_timeout)
|
||||
{
|
||||
BIO *cbio = NULL;
|
||||
SSL_CTX *ctx = NULL;
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
|
||||
cbio = BIO_new_connect(host);
|
||||
if (cbio == NULL) {
|
||||
BIO_printf(bio_err, "Error creating connect BIO\n");
|
||||
goto end;
|
||||
}
|
||||
if (port != NULL)
|
||||
BIO_set_conn_port(cbio, port);
|
||||
if (use_ssl == 1) {
|
||||
BIO *sbio;
|
||||
ctx = SSL_CTX_new(TLS_client_method());
|
||||
if (ctx == NULL) {
|
||||
BIO_printf(bio_err, "Error creating SSL context.\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
sbio = BIO_new_ssl(ctx, 1);
|
||||
cbio = BIO_push(sbio, cbio);
|
||||
}
|
||||
|
||||
resp = (OCSP_RESPONSE *)
|
||||
app_http_post_asn1(host, port, path, NULL, NULL /* no proxy used */,
|
||||
ctx, headers, "application/ocsp-request",
|
||||
(ASN1_VALUE *)req, ASN1_ITEM_rptr(OCSP_REQUEST),
|
||||
req_timeout, ASN1_ITEM_rptr(OCSP_RESPONSE));
|
||||
|
||||
resp = query_responder(cbio, host, path, headers, req, req_timeout);
|
||||
if (resp == NULL)
|
||||
BIO_printf(bio_err, "Error querying OCSP responder\n");
|
||||
|
||||
end:
|
||||
BIO_free_all(cbio);
|
||||
SSL_CTX_free(ctx);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@@ -171,27 +171,9 @@ unstructuredName = An optional company name
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
@@ -206,13 +188,6 @@ authorityKeyIdentifier=keyid,issuer
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This is required for TSA certificates.
|
||||
# extendedKeyUsage = critical,timeStamping
|
||||
|
||||
@@ -242,9 +217,6 @@ basicConstraints = critical,CA:true
|
||||
# left out by default.
|
||||
# keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# Some might want this also
|
||||
# nsCertType = sslCA, emailCA
|
||||
|
||||
# Include email address in subject alt name: another PKIX recommendation
|
||||
# subjectAltName=email:copy
|
||||
# Copy issuer details
|
||||
@@ -272,27 +244,9 @@ authorityKeyIdentifier=keyid:always
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
@@ -307,13 +261,6 @@ authorityKeyIdentifier=keyid,issuer
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This really needs to be in place for it to be a proxy certificate.
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
||||
|
||||
|
||||
+12
-116
@@ -30,9 +30,6 @@
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
/* Special sentinel to exit the program. */
|
||||
#define EXIT_THE_PROGRAM (-1)
|
||||
|
||||
/*
|
||||
* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with
|
||||
* the base prototypes (we cast each variable inside the function to the
|
||||
@@ -80,27 +77,6 @@ static void apps_shutdown(void)
|
||||
destroy_ui_method();
|
||||
}
|
||||
|
||||
static char *make_config_name(void)
|
||||
{
|
||||
const char *t;
|
||||
size_t len;
|
||||
char *p;
|
||||
|
||||
if ((t = getenv("OPENSSL_CONF")) != NULL)
|
||||
return OPENSSL_strdup(t);
|
||||
|
||||
t = X509_get_default_cert_area();
|
||||
len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1;
|
||||
p = app_malloc(len, "config filename buffer");
|
||||
strcpy(p, t);
|
||||
#ifndef OPENSSL_SYS_VMS
|
||||
strcat(p, "/");
|
||||
#endif
|
||||
strcat(p, OPENSSL_CONF);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#ifndef OPENSSL_NO_TRACE
|
||||
typedef struct tracedata_st {
|
||||
@@ -233,17 +209,14 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
FUNCTION f, *fp;
|
||||
LHASH_OF(FUNCTION) *prog = NULL;
|
||||
char *p, *pname;
|
||||
char buf[1024];
|
||||
const char *prompt;
|
||||
char *pname;
|
||||
ARGS arg;
|
||||
int first, n, i, ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
arg.argv = NULL;
|
||||
arg.size = 0;
|
||||
|
||||
/* Set up some of the environment. */
|
||||
default_config_file = make_config_name();
|
||||
bio_in = dup_bio_in(FORMAT_TEXT);
|
||||
bio_out = dup_bio_out(FORMAT_TEXT);
|
||||
bio_err = dup_bio_err(FORMAT_TEXT);
|
||||
@@ -261,11 +234,6 @@ int main(int argc, char *argv[])
|
||||
setup_trace(getenv("OPENSSL_TRACE"));
|
||||
#endif
|
||||
|
||||
if (getenv("OPENSSL_FIPS")) {
|
||||
BIO_printf(bio_err, "FIPS mode not supported.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!apps_startup()) {
|
||||
BIO_printf(bio_err,
|
||||
"FATAL: Startup failure (dev note: apps_startup() failed)\n");
|
||||
@@ -284,92 +252,24 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
pname = opt_progname(argv[0]);
|
||||
|
||||
default_config_file = CONF_get1_default_config_file();
|
||||
if (default_config_file == NULL)
|
||||
app_bail_out("%s: could not get default config file\n", pname);
|
||||
|
||||
/* first check the program name */
|
||||
f.name = pname;
|
||||
fp = lh_FUNCTION_retrieve(prog, &f);
|
||||
if (fp != NULL) {
|
||||
argv[0] = pname;
|
||||
if (fp->deprecated_alternative != NULL)
|
||||
warn_deprecated(fp);
|
||||
ret = fp->func(argc, argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* If there is stuff on the command line, run with that. */
|
||||
if (argc != 1) {
|
||||
if (fp == NULL) {
|
||||
/* We assume we've been called as 'openssl cmd' */
|
||||
argc--;
|
||||
argv++;
|
||||
ret = do_cmd(prog, argc, argv);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* ok, lets enter interactive mode */
|
||||
for (;;) {
|
||||
ret = 0;
|
||||
/* Read a line, continue reading if line ends with \ */
|
||||
for (p = buf, n = sizeof(buf), i = 0, first = 1; n > 0; first = 0) {
|
||||
prompt = first ? "OpenSSL> " : "> ";
|
||||
p[0] = '\0';
|
||||
#ifndef READLINE
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
if (!fgets(p, n, stdin))
|
||||
goto end;
|
||||
if (p[0] == '\0')
|
||||
goto end;
|
||||
i = strlen(p);
|
||||
if (i <= 1)
|
||||
break;
|
||||
if (p[i - 2] != '\\')
|
||||
break;
|
||||
i -= 2;
|
||||
p += i;
|
||||
n -= i;
|
||||
#else
|
||||
{
|
||||
extern char *readline(const char *);
|
||||
extern void add_history(const char *cp);
|
||||
char *text;
|
||||
/* If there's a command, run with that, otherwise "help". */
|
||||
ret = argc > 0
|
||||
? do_cmd(prog, argc, argv)
|
||||
: help_main(argc, argv);
|
||||
|
||||
text = readline(prompt);
|
||||
if (text == NULL)
|
||||
goto end;
|
||||
i = strlen(text);
|
||||
if (i == 0 || i > n)
|
||||
break;
|
||||
if (text[i - 1] != '\\') {
|
||||
p += strlen(strcpy(p, text));
|
||||
free(text);
|
||||
add_history(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
text[i - 1] = '\0';
|
||||
p += strlen(strcpy(p, text));
|
||||
free(text);
|
||||
n -= i;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!chopup_args(&arg, buf)) {
|
||||
BIO_printf(bio_err, "Can't parse (no memory?)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = do_cmd(prog, arg.argc, arg.argv);
|
||||
if (ret == EXIT_THE_PROGRAM) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (ret != 0)
|
||||
BIO_printf(bio_err, "error in %s\n", arg.argv[0]);
|
||||
(void)BIO_flush(bio_out);
|
||||
(void)BIO_flush(bio_err);
|
||||
}
|
||||
ret = 1;
|
||||
end:
|
||||
app_providers_cleanup();
|
||||
OPENSSL_free(default_config_file);
|
||||
@@ -502,10 +402,6 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
|
||||
BIO_printf(bio_out, "%s\n", argv[0] + 3);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 ||
|
||||
strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0)
|
||||
/* Special value to mean "exit the program. */
|
||||
return EXIT_THE_PROGRAM;
|
||||
|
||||
BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
|
||||
argv[0]);
|
||||
|
||||
@@ -171,27 +171,9 @@ unstructuredName = An optional company name
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
@@ -206,13 +188,6 @@ authorityKeyIdentifier=keyid,issuer
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This is required for TSA certificates.
|
||||
# extendedKeyUsage = critical,timeStamping
|
||||
|
||||
@@ -242,9 +217,6 @@ basicConstraints = critical,CA:true
|
||||
# left out by default.
|
||||
# keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# Some might want this also
|
||||
# nsCertType = sslCA, emailCA
|
||||
|
||||
# Include email address in subject alt name: another PKIX recommendation
|
||||
# subjectAltName=email:copy
|
||||
# Copy issuer details
|
||||
@@ -272,27 +244,9 @@ authorityKeyIdentifier=keyid:always
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
@@ -307,13 +261,6 @@ authorityKeyIdentifier=keyid,issuer
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This really needs to be in place for it to be a proxy certificate.
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
||||
|
||||
|
||||
+1
-1
@@ -65,9 +65,9 @@ const OPTIONS rsa_options[] = {
|
||||
{"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
|
||||
{"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
|
||||
{"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
|
||||
#endif
|
||||
|
||||
OPT_PROV_OPTIONS,
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
||||
+173
-37
@@ -81,6 +81,7 @@ static void print_stuff(BIO *berr, SSL *con, int full);
|
||||
static int ocsp_resp_cb(SSL *s, void *arg);
|
||||
#endif
|
||||
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
|
||||
static char *base64encode (const void *buf, size_t len);
|
||||
static int is_dNS_name(const char *host);
|
||||
|
||||
static int saved_errno;
|
||||
@@ -576,7 +577,7 @@ typedef enum OPTION_choice {
|
||||
OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
|
||||
OPT_V_ENUM,
|
||||
OPT_X_ENUM,
|
||||
OPT_S_ENUM,
|
||||
OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF,
|
||||
OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS,
|
||||
OPT_DANE_TLSA_DOMAIN,
|
||||
#ifndef OPENSSL_NO_CT
|
||||
@@ -718,6 +719,8 @@ const OPTIONS s_client_options[] = {
|
||||
"Do not send the server name (SNI) extension in the ClientHello"},
|
||||
{"tlsextdebug", OPT_TLSEXTDEBUG, '-',
|
||||
"Hex dump of all TLS extensions received"},
|
||||
{"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-',
|
||||
"Do not treat lack of close_notify from a peer as an error"},
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
{"status", OPT_STATUS, '-', "Request certificate status from server"},
|
||||
#endif
|
||||
@@ -919,6 +922,7 @@ int s_client_main(int argc, char **argv)
|
||||
char *connectstr = NULL, *bindstr = NULL;
|
||||
char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
|
||||
char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL;
|
||||
char *thost = NULL, *tport = NULL;
|
||||
char *port = OPENSSL_strdup(PORT);
|
||||
char *bindhost = NULL, *bindport = NULL;
|
||||
char *passarg = NULL, *pass = NULL;
|
||||
@@ -934,7 +938,7 @@ int s_client_main(int argc, char **argv)
|
||||
int prexit = 0;
|
||||
int sdebug = 0;
|
||||
int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
|
||||
int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0;
|
||||
int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0;
|
||||
int sbuf_len, sbuf_off, cmdletters = 1;
|
||||
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
|
||||
int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
|
||||
@@ -1001,6 +1005,7 @@ int s_client_main(int argc, char **argv)
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
int sctp_label_bug = 0;
|
||||
#endif
|
||||
int ignore_unexpected_eof = 0;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
@@ -1180,6 +1185,9 @@ int s_client_main(int argc, char **argv)
|
||||
if (!args_excert(o, &exc))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_IGNORE_UNEXPECTED_EOF:
|
||||
ignore_unexpected_eof = 1;
|
||||
break;
|
||||
case OPT_PREXIT:
|
||||
prexit = 1;
|
||||
break;
|
||||
@@ -1593,29 +1601,12 @@ int s_client_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
}
|
||||
#endif
|
||||
if (proxystr != NULL) {
|
||||
|
||||
if (connectstr != NULL) {
|
||||
int res;
|
||||
char *tmp_host = host, *tmp_port = port;
|
||||
if (connectstr == NULL) {
|
||||
BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog);
|
||||
goto opthelp;
|
||||
}
|
||||
res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
|
||||
if (tmp_host != host)
|
||||
OPENSSL_free(tmp_host);
|
||||
if (tmp_port != port)
|
||||
OPENSSL_free(tmp_port);
|
||||
if (!res) {
|
||||
BIO_printf(bio_err,
|
||||
"%s: -proxy argument malformed or ambiguous\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
int res = 1;
|
||||
char *tmp_host = host, *tmp_port = port;
|
||||
if (connectstr != NULL)
|
||||
res = BIO_parse_hostserv(connectstr, &host, &port,
|
||||
BIO_PARSE_PRIO_HOST);
|
||||
|
||||
res = BIO_parse_hostserv(connectstr, &host, &port, BIO_PARSE_PRIO_HOST);
|
||||
if (tmp_host != host)
|
||||
OPENSSL_free(tmp_host);
|
||||
if (tmp_port != port)
|
||||
@@ -1628,6 +1619,35 @@ int s_client_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (proxystr != NULL) {
|
||||
int res;
|
||||
char *tmp_host = host, *tmp_port = port;
|
||||
|
||||
if (host == NULL || port == NULL) {
|
||||
BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog);
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
/* Retain the original target host:port for use in the HTTP proxy connect string */
|
||||
thost = OPENSSL_strdup(host);
|
||||
tport = OPENSSL_strdup(port);
|
||||
if (thost == NULL || tport == NULL) {
|
||||
BIO_printf(bio_err, "%s: out of memory\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
|
||||
if (tmp_host != host)
|
||||
OPENSSL_free(tmp_host);
|
||||
if (tmp_port != port)
|
||||
OPENSSL_free(tmp_port);
|
||||
if (!res) {
|
||||
BIO_printf(bio_err,
|
||||
"%s: -proxy argument malformed or ambiguous\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (bindstr != NULL) {
|
||||
int res;
|
||||
res = BIO_parse_hostserv(bindstr, &bindhost, &bindport,
|
||||
@@ -1776,6 +1796,9 @@ int s_client_main(int argc, char **argv)
|
||||
&& SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
|
||||
goto end;
|
||||
|
||||
if (ignore_unexpected_eof)
|
||||
SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
|
||||
|
||||
if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
|
||||
BIO_printf(bio_err, "Error setting verify params\n");
|
||||
ERR_print_errors(bio_err);
|
||||
@@ -2077,16 +2100,16 @@ int s_client_main(int argc, char **argv)
|
||||
}
|
||||
|
||||
re_start:
|
||||
if (init_client(&sock, host, port, bindhost, bindport, socket_family,
|
||||
if (init_client(&s, host, port, bindhost, bindport, socket_family,
|
||||
socket_type, protocol) == 0) {
|
||||
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
|
||||
BIO_closesocket(sock);
|
||||
BIO_closesocket(s);
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock);
|
||||
BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
|
||||
|
||||
if (c_nbio) {
|
||||
if (!BIO_socket_nbio(sock, 1)) {
|
||||
if (!BIO_socket_nbio(s, 1)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
@@ -2098,21 +2121,21 @@ int s_client_main(int argc, char **argv)
|
||||
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
if (protocol == IPPROTO_SCTP)
|
||||
sbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
|
||||
sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
|
||||
else
|
||||
#endif
|
||||
sbio = BIO_new_dgram(sock, BIO_NOCLOSE);
|
||||
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
|
||||
|
||||
if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
|
||||
BIO_printf(bio_err, "memory allocation failure\n");
|
||||
BIO_closesocket(sock);
|
||||
BIO_closesocket(s);
|
||||
goto end;
|
||||
}
|
||||
if (!BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
|
||||
if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
|
||||
BIO_printf(bio_err, "getsockname:errno=%d\n",
|
||||
get_last_socket_error());
|
||||
BIO_ADDR_free(peer_info.addr);
|
||||
BIO_closesocket(sock);
|
||||
BIO_closesocket(s);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -2149,7 +2172,7 @@ int s_client_main(int argc, char **argv)
|
||||
}
|
||||
} else
|
||||
#endif /* OPENSSL_NO_DTLS */
|
||||
sbio = BIO_new_socket(sock, BIO_NOCLOSE);
|
||||
sbio = BIO_new_socket(s, BIO_NOCLOSE);
|
||||
|
||||
if (nbio_test) {
|
||||
BIO *test;
|
||||
@@ -2380,9 +2403,83 @@ int s_client_main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case PROTO_CONNECT:
|
||||
if (!OSSL_HTTP_proxy_connect(sbio, host, port, proxyuser, proxypass,
|
||||
0 /* no timeout */, bio_err, prog))
|
||||
{
|
||||
enum {
|
||||
error_proto, /* Wrong protocol, not even HTTP */
|
||||
error_connect, /* CONNECT failed */
|
||||
success
|
||||
} foundit = error_connect;
|
||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||
|
||||
BIO_push(fbio, sbio);
|
||||
BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n", connectstr);
|
||||
/*
|
||||
* Workaround for broken proxies which would otherwise close
|
||||
* the connection when entering tunnel mode (eg Squid 2.6)
|
||||
*/
|
||||
BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n");
|
||||
|
||||
/* Support for basic (base64) proxy authentication */
|
||||
if (proxyuser != NULL) {
|
||||
size_t l;
|
||||
char *proxyauth, *proxyauthenc;
|
||||
|
||||
l = strlen(proxyuser);
|
||||
if (proxypass != NULL)
|
||||
l += strlen(proxypass);
|
||||
proxyauth = app_malloc(l + 2, "Proxy auth string");
|
||||
BIO_snprintf(proxyauth, l + 2, "%s:%s", proxyuser,
|
||||
(proxypass != NULL) ? proxypass : "");
|
||||
proxyauthenc = base64encode(proxyauth, strlen(proxyauth));
|
||||
BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n",
|
||||
proxyauthenc);
|
||||
OPENSSL_clear_free(proxyauth, strlen(proxyauth));
|
||||
OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
|
||||
}
|
||||
|
||||
/* Terminate the HTTP CONNECT request */
|
||||
BIO_printf(fbio, "\r\n");
|
||||
(void)BIO_flush(fbio);
|
||||
/*
|
||||
* The first line is the HTTP response. According to RFC 7230,
|
||||
* it's formatted exactly like this:
|
||||
*
|
||||
* HTTP/d.d ddd Reason text\r\n
|
||||
*/
|
||||
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||
if (mbuf_len < (int)strlen("HTTP/1.0 200")) {
|
||||
BIO_printf(bio_err,
|
||||
"%s: HTTP CONNECT failed, insufficient response "
|
||||
"from proxy (got %d octets)\n", prog, mbuf_len);
|
||||
(void)BIO_flush(fbio);
|
||||
BIO_pop(fbio);
|
||||
BIO_free(fbio);
|
||||
goto shut;
|
||||
}
|
||||
if (mbuf[8] != ' ') {
|
||||
BIO_printf(bio_err,
|
||||
"%s: HTTP CONNECT failed, incorrect response "
|
||||
"from proxy\n", prog);
|
||||
foundit = error_proto;
|
||||
} else if (mbuf[9] != '2') {
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog,
|
||||
&mbuf[9]);
|
||||
} else {
|
||||
foundit = success;
|
||||
}
|
||||
if (foundit != error_proto) {
|
||||
/* Read past all following headers */
|
||||
do {
|
||||
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||
} while (mbuf_len > 2);
|
||||
}
|
||||
(void)BIO_flush(fbio);
|
||||
BIO_pop(fbio);
|
||||
BIO_free(fbio);
|
||||
if (foundit != success) {
|
||||
goto shut;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROTO_IRC:
|
||||
{
|
||||
@@ -3100,8 +3197,8 @@ int s_client_main(int argc, char **argv)
|
||||
timeout.tv_usec = 500000; /* some extreme round-trip */
|
||||
do {
|
||||
FD_ZERO(&readfds);
|
||||
openssl_fdset(sock, &readfds);
|
||||
} while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
|
||||
openssl_fdset(s, &readfds);
|
||||
} while (select(s + 1, &readfds, NULL, NULL, &timeout) > 0
|
||||
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
|
||||
|
||||
BIO_closesocket(SSL_get_fd(con));
|
||||
@@ -3129,6 +3226,8 @@ int s_client_main(int argc, char **argv)
|
||||
OPENSSL_free(bindstr);
|
||||
OPENSSL_free(host);
|
||||
OPENSSL_free(port);
|
||||
OPENSSL_free(thost);
|
||||
OPENSSL_free(tport);
|
||||
X509_VERIFY_PARAM_free(vpm);
|
||||
ssl_excert_free(exc);
|
||||
sk_OPENSSL_STRING_free(ssl_args);
|
||||
@@ -3151,6 +3250,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
|
||||
X509 *peer = NULL;
|
||||
STACK_OF(X509) *sk;
|
||||
const SSL_CIPHER *c;
|
||||
EVP_PKEY *public_key;
|
||||
int i, istls13 = (SSL_version(s) == TLS1_3_VERSION);
|
||||
long verify_result;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
@@ -3176,6 +3276,19 @@ static void print_stuff(BIO *bio, SSL *s, int full)
|
||||
BIO_printf(bio, " i:");
|
||||
X509_NAME_print_ex(bio, X509_get_issuer_name(sk_X509_value(sk, i)), 0, get_nameopt());
|
||||
BIO_puts(bio, "\n");
|
||||
public_key = X509_get_pubkey(sk_X509_value(sk, i));
|
||||
if (public_key != NULL) {
|
||||
BIO_printf(bio, " a:PKEY: %s, %d (bit); sigalg: %s\n",
|
||||
OBJ_nid2sn(EVP_PKEY_base_id(public_key)),
|
||||
EVP_PKEY_bits(public_key),
|
||||
OBJ_nid2sn(X509_get_signature_nid(sk_X509_value(sk, i))));
|
||||
EVP_PKEY_free(public_key);
|
||||
}
|
||||
BIO_printf(bio, " v:NotBefore: ");
|
||||
ASN1_TIME_print(bio, X509_get0_notBefore(sk_X509_value(sk, i)));
|
||||
BIO_printf(bio, "; NotAfter: ");
|
||||
ASN1_TIME_print(bio, X509_get0_notAfter(sk_X509_value(sk, i)));
|
||||
BIO_puts(bio, "\n");
|
||||
if (c_showcerts)
|
||||
PEM_write_bio_X509(bio, sk_X509_value(sk, i));
|
||||
}
|
||||
@@ -3477,6 +3590,29 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* BASE64 encoder: used only for encoding basic proxy authentication credentials
|
||||
*/
|
||||
static char *base64encode (const void *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
size_t outl;
|
||||
char *out;
|
||||
|
||||
/* Calculate size of encoded data */
|
||||
outl = (len / 3);
|
||||
if (len % 3 > 0)
|
||||
outl++;
|
||||
outl <<= 2;
|
||||
out = app_malloc(outl + 1, "base64 encode buffer");
|
||||
|
||||
i = EVP_EncodeBlock((unsigned char *)out, buf, len);
|
||||
assert(i <= (int)outl);
|
||||
if (i < 0)
|
||||
*out = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Host dNS Name verifier: used for checking that the hostname is in dNS format
|
||||
* before setting it as SNI
|
||||
|
||||
+14
-5
@@ -534,7 +534,7 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
|
||||
x = SSL_get_certificate(s);
|
||||
aia = X509_get1_ocsp(x);
|
||||
if (aia != NULL) {
|
||||
if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
|
||||
if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
|
||||
&host, &port, &path, &use_ssl)) {
|
||||
BIO_puts(bio_err, "cert_status: can't parse AIA URL\n");
|
||||
goto err;
|
||||
@@ -761,7 +761,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_NOCANAMES,
|
||||
OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF,
|
||||
OPT_R_ENUM,
|
||||
OPT_S_ENUM,
|
||||
OPT_V_ENUM,
|
||||
@@ -850,6 +850,8 @@ const OPTIONS s_server_options[] = {
|
||||
"Disable caching and tickets if ephemeral (EC)DH is used"},
|
||||
{"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"},
|
||||
{"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"},
|
||||
{"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-',
|
||||
"Do not treat lack of close_notify from a peer as an error"},
|
||||
{"tlsextdebug", OPT_TLSEXTDEBUG, '-',
|
||||
"Hex dump of all TLS extensions received"},
|
||||
{"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"},
|
||||
@@ -1094,6 +1096,7 @@ int s_server_main(int argc, char *argv[])
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
int sctp_label_bug = 0;
|
||||
#endif
|
||||
int ignore_unexpected_eof = 0;
|
||||
|
||||
/* Init of few remaining global variables */
|
||||
local_argc = argc;
|
||||
@@ -1403,8 +1406,9 @@ int s_server_main(int argc, char *argv[])
|
||||
case OPT_STATUS_URL:
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
s_tlsextstatus = 1;
|
||||
if (!OSSL_HTTP_parse_url(opt_arg(),
|
||||
&tlscstatp.host, &tlscstatp.port,
|
||||
if (!OCSP_parse_url(opt_arg(),
|
||||
&tlscstatp.host,
|
||||
&tlscstatp.port,
|
||||
&tlscstatp.path, &tlscstatp.use_ssl)) {
|
||||
BIO_printf(bio_err, "Error parsing URL\n");
|
||||
goto end;
|
||||
@@ -1667,6 +1671,9 @@ int s_server_main(int argc, char *argv[])
|
||||
use_sendfile = 1;
|
||||
#endif
|
||||
break;
|
||||
case OPT_IGNORE_UNEXPECTED_EOF:
|
||||
ignore_unexpected_eof = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -1867,7 +1874,6 @@ int s_server_main(int argc, char *argv[])
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SCTP
|
||||
if (protocol == IPPROTO_SCTP && sctp_label_bug == 1)
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
|
||||
@@ -1911,6 +1917,9 @@ int s_server_main(int argc, char *argv[])
|
||||
SSL_CTX_set_options(ctx, SSL_OP_DISABLE_TLSEXT_CA_NAMES);
|
||||
}
|
||||
|
||||
if (ignore_unexpected_eof)
|
||||
SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
|
||||
|
||||
if (max_send_fragment > 0
|
||||
&& !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) {
|
||||
BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n",
|
||||
|
||||
+347
-10
@@ -16,6 +16,7 @@
|
||||
#define ECDH_SECONDS 10
|
||||
#define EdDSA_SECONDS 10
|
||||
#define SM2_SECONDS 10
|
||||
#define FFDH_SECONDS 10
|
||||
|
||||
/* We need to use some deprecated APIs */
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
@@ -98,6 +99,9 @@
|
||||
# include <openssl/rsa.h>
|
||||
# include "./testrsa.h"
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
# include <openssl/dh.h>
|
||||
#endif
|
||||
#include <openssl/x509.h>
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
# include <openssl/dsa.h>
|
||||
@@ -125,6 +129,7 @@
|
||||
#define MAX_MISALIGNMENT 63
|
||||
#define MAX_ECDH_SIZE 256
|
||||
#define MISALIGN 64
|
||||
#define MAX_FFDH_SIZE 1024
|
||||
|
||||
typedef struct openssl_speed_sec_st {
|
||||
int sym;
|
||||
@@ -134,6 +139,7 @@ typedef struct openssl_speed_sec_st {
|
||||
int ecdh;
|
||||
int eddsa;
|
||||
int sm2;
|
||||
int ffdh;
|
||||
} openssl_speed_sec_t;
|
||||
|
||||
static volatile int run = 0;
|
||||
@@ -435,6 +441,22 @@ static const OPT_PAIR rsa_choices[RSA_NUM] = {
|
||||
static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */
|
||||
#endif /* OPENSSL_NO_RSA */
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
enum ff_params_t {
|
||||
R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
|
||||
};
|
||||
|
||||
static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
|
||||
{"ffdh2048", R_FFDH_2048},
|
||||
{"ffdh3072", R_FFDH_3072},
|
||||
{"ffdh4096", R_FFDH_4096},
|
||||
{"ffdh6144", R_FFDH_6144},
|
||||
{"ffdh8192", R_FFDH_8192},
|
||||
};
|
||||
|
||||
static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
enum ec_curves_t {
|
||||
R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
|
||||
@@ -553,6 +575,7 @@ typedef struct loopargs_st {
|
||||
EC_KEY *ecdsa[ECDSA_NUM];
|
||||
EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
|
||||
EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
|
||||
EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
|
||||
# ifndef OPENSSL_NO_SM2
|
||||
EVP_MD_CTX *sm2_ctx[SM2_NUM];
|
||||
EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
|
||||
@@ -561,6 +584,11 @@ typedef struct loopargs_st {
|
||||
unsigned char *secret_a;
|
||||
unsigned char *secret_b;
|
||||
size_t outlen[EC_NUM];
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
|
||||
unsigned char *secret_ff_a;
|
||||
unsigned char *secret_ff_b;
|
||||
#endif
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
@@ -1067,6 +1095,24 @@ static int RSA_verify_loop(void *args)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static long ffdh_c[FFDH_NUM][1];
|
||||
|
||||
static int FFDH_derive_key_loop(void *args)
|
||||
{
|
||||
loopargs_t *tempargs = *(loopargs_t **) args;
|
||||
EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
|
||||
unsigned char *derived_secret = tempargs->secret_ff_a;
|
||||
size_t outlen = MAX_FFDH_SIZE;
|
||||
int count;
|
||||
|
||||
for (count = 0; COND(ffdh_c[testnum][0]); count++)
|
||||
EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
static long dsa_c[DSA_NUM][2];
|
||||
static int DSA_sign_loop(void *args)
|
||||
@@ -1197,7 +1243,7 @@ static int EdDSA_verify_loop(void *args)
|
||||
{
|
||||
loopargs_t *tempargs = *(loopargs_t **) args;
|
||||
unsigned char *buf = tempargs->buf;
|
||||
EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
|
||||
EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
|
||||
unsigned char *eddsasig = tempargs->buf2;
|
||||
size_t eddsasigsize = tempargs->sigsize;
|
||||
int ret, count;
|
||||
@@ -1463,7 +1509,8 @@ int speed_main(int argc, char **argv)
|
||||
#endif
|
||||
openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
|
||||
ECDSA_SECONDS, ECDH_SECONDS,
|
||||
EdDSA_SECONDS, SM2_SECONDS };
|
||||
EdDSA_SECONDS, SM2_SECONDS,
|
||||
FFDH_SECONDS };
|
||||
|
||||
/* What follows are the buffers and key material. */
|
||||
#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
@@ -1521,6 +1568,23 @@ int speed_main(int argc, char **argv)
|
||||
uint8_t rsa_doit[RSA_NUM] = { 0 };
|
||||
int primes = RSA_DEFAULT_PRIME_NUM;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
typedef struct ffdh_params_st {
|
||||
const char *name;
|
||||
unsigned int nid;
|
||||
unsigned int bits;
|
||||
} FFDH_PARAMS;
|
||||
|
||||
static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
|
||||
{"ffdh2048", NID_ffdhe2048, 2048},
|
||||
{"ffdh3072", NID_ffdhe3072, 3072},
|
||||
{"ffdh4096", NID_ffdhe4096, 4096},
|
||||
{"ffdh6144", NID_ffdhe6144, 6144},
|
||||
{"ffdh8192", NID_ffdhe8192, 8192}
|
||||
};
|
||||
uint8_t ffdh_doit[FFDH_NUM] = { 0 };
|
||||
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
|
||||
uint8_t dsa_doit[DSA_NUM] = { 0 };
|
||||
@@ -1718,7 +1782,7 @@ int speed_main(int argc, char **argv)
|
||||
case OPT_SECONDS:
|
||||
seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
|
||||
= seconds.ecdh = seconds.eddsa
|
||||
= seconds.sm2 = atoi(opt_arg());
|
||||
= seconds.sm2 = seconds.ffdh = atoi(opt_arg());
|
||||
break;
|
||||
case OPT_BYTES:
|
||||
lengths_single = atoi(opt_arg());
|
||||
@@ -1765,6 +1829,18 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
if (strncmp(algo, "ffdh", 4) == 0) {
|
||||
if (algo[4] == '\0') {
|
||||
memset(ffdh_doit, 1, sizeof(ffdh_doit));
|
||||
continue;
|
||||
}
|
||||
if (opt_found(algo, ffdh_choices, &i)) {
|
||||
ffdh_doit[i] = 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
if (strncmp(algo, "dsa", 3) == 0) {
|
||||
if (algo[3] == '\0') {
|
||||
@@ -1899,6 +1975,10 @@ int speed_main(int argc, char **argv)
|
||||
#ifndef OPENSSL_NO_EC
|
||||
loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
|
||||
loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
|
||||
loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1914,9 +1994,21 @@ int speed_main(int argc, char **argv)
|
||||
if (argc == 0 && !doit[D_EVP] && !doit[D_EVP_HMAC] && !doit[D_EVP_CMAC]) {
|
||||
memset(doit, 1, sizeof(doit));
|
||||
doit[D_EVP] = doit[D_EVP_HMAC] = doit[D_EVP_CMAC] = 0;
|
||||
#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
doit[D_MDC2] = 0;
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
doit[D_MD4] = 0;
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
doit[D_RMD160] = 0;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
memset(rsa_doit, 1, sizeof(rsa_doit));
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
memset(ffdh_doit, 1, sizeof(ffdh_doit));
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
memset(dsa_doit, 1, sizeof(dsa_doit));
|
||||
#endif
|
||||
@@ -2108,7 +2200,7 @@ int speed_main(int argc, char **argv)
|
||||
c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_RSA
|
||||
# if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
rsa_c[R_RSA_512][0] = count / 2000;
|
||||
rsa_c[R_RSA_512][1] = count / 400;
|
||||
for (i = 1; i < RSA_NUM; i++) {
|
||||
@@ -2258,6 +2350,19 @@ int speed_main(int argc, char **argv)
|
||||
# endif
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
|
||||
# ifndef OPENSSL_NO_DH
|
||||
ffdh_c[R_FFDH_2048][0] = count / 1000;
|
||||
for (i = R_FFDH_3072; i <= R_FFDH_8192; i++) {
|
||||
ffdh_c[i][0] = ffdh_c[i - 1][0] / 2;
|
||||
if (ffdh_doit[i] <= 1 && ffdh_c[i][0] == 0) {
|
||||
ffdh_doit[i] = 0;
|
||||
} else {
|
||||
if (ffdh_c[i][0] == 0)
|
||||
ffdh_c[i][0] = 1;
|
||||
}
|
||||
}
|
||||
# endif /* OPENSSL_NO_DH */
|
||||
|
||||
# else
|
||||
/* not worth fixing */
|
||||
# error "You cannot disable DES on systems without SIGALRM."
|
||||
@@ -3047,7 +3152,6 @@ int speed_main(int argc, char **argv)
|
||||
rsa_count = 1;
|
||||
} else {
|
||||
for (i = 0; i < loopargs_len; i++) {
|
||||
EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL);
|
||||
/* Perform ECDSA signature test */
|
||||
EC_KEY_generate_key(loopargs[i].ecdsa[testnum]);
|
||||
st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
|
||||
@@ -3284,6 +3388,11 @@ int speed_main(int argc, char **argv)
|
||||
st = 0;
|
||||
break;
|
||||
}
|
||||
loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
|
||||
if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
|
||||
st = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid, NULL))
|
||||
== NULL
|
||||
@@ -3301,6 +3410,13 @@ int speed_main(int argc, char **argv)
|
||||
EVP_PKEY_free(ed_pkey);
|
||||
break;
|
||||
}
|
||||
if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
|
||||
NULL, NULL, ed_pkey)) {
|
||||
st = 0;
|
||||
EVP_PKEY_free(ed_pkey);
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(ed_pkey);
|
||||
}
|
||||
if (st == 0) {
|
||||
@@ -3338,10 +3454,9 @@ int speed_main(int argc, char **argv)
|
||||
eddsa_results[testnum][0] = (double)count / d;
|
||||
rsa_count = count;
|
||||
}
|
||||
|
||||
/* Perform EdDSA verification test */
|
||||
for (i = 0; i < loopargs_len; i++) {
|
||||
st = EVP_DigestVerify(loopargs[i].eddsa_ctx[testnum],
|
||||
st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
|
||||
loopargs[i].buf2, loopargs[i].sigsize,
|
||||
loopargs[i].buf, 20);
|
||||
if (st != 1)
|
||||
@@ -3509,8 +3624,188 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
# endif /* OPENSSL_NO_SM2 */
|
||||
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
for (testnum = 0; testnum < FFDH_NUM; testnum++) {
|
||||
int ffdh_checks = 1;
|
||||
|
||||
if (!ffdh_doit[testnum])
|
||||
continue;
|
||||
|
||||
for (i = 0; i < loopargs_len; i++) {
|
||||
EVP_PKEY *pkey_A = NULL;
|
||||
EVP_PKEY *pkey_B = NULL;
|
||||
EVP_PKEY_CTX *ffdh_ctx = NULL;
|
||||
EVP_PKEY_CTX *test_ctx = NULL;
|
||||
size_t secret_size;
|
||||
size_t test_out;
|
||||
|
||||
/* Ensure that the error queue is empty */
|
||||
if (ERR_peek_error()) {
|
||||
BIO_printf(bio_err,
|
||||
"WARNING: the error queue contains previous unhandled errors.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
|
||||
pkey_A = EVP_PKEY_new();
|
||||
if (!pkey_A) {
|
||||
BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
pkey_B = EVP_PKEY_new();
|
||||
if (!pkey_B) {
|
||||
BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
|
||||
if (!ffdh_ctx) {
|
||||
BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
|
||||
BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
|
||||
BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
|
||||
EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
|
||||
BIO_printf(bio_err, "FFDH key generation failure.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_free(ffdh_ctx);
|
||||
|
||||
/* check if the derivation works correctly both ways so that
|
||||
* we know if future derive calls will fail, and we can skip
|
||||
* error checking in benchmarked code */
|
||||
ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
|
||||
if (!ffdh_ctx) {
|
||||
BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
|
||||
BIO_printf(bio_err, "FFDH derivation context init failure.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
|
||||
BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
|
||||
BIO_printf(bio_err, "Checking size of shared secret failed.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (secret_size > MAX_FFDH_SIZE) {
|
||||
BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (EVP_PKEY_derive(ffdh_ctx,
|
||||
loopargs[i].secret_ff_a,
|
||||
&secret_size) <= 0) {
|
||||
BIO_printf(bio_err, "Shared secret derive failure.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
/* Now check from side B */
|
||||
test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
|
||||
if (!test_ctx) {
|
||||
BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
if (!EVP_PKEY_derive_init(test_ctx) ||
|
||||
!EVP_PKEY_derive_set_peer(test_ctx, pkey_A) ||
|
||||
!EVP_PKEY_derive(test_ctx, NULL, &test_out) ||
|
||||
!EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) ||
|
||||
test_out != secret_size) {
|
||||
BIO_printf(bio_err, "FFDH computation failure.\n");
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* compare the computed secrets */
|
||||
if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
|
||||
loopargs[i].secret_ff_b, secret_size)) {
|
||||
BIO_printf(bio_err, "FFDH computations don't match.\n");
|
||||
ERR_print_errors(bio_err);
|
||||
rsa_count = 1;
|
||||
ffdh_checks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
|
||||
|
||||
EVP_PKEY_free(pkey_A);
|
||||
pkey_A = NULL;
|
||||
EVP_PKEY_free(pkey_B);
|
||||
pkey_B = NULL;
|
||||
EVP_PKEY_CTX_free(test_ctx);
|
||||
test_ctx = NULL;
|
||||
}
|
||||
if (ffdh_checks != 0) {
|
||||
pkey_print_message("", "ffdh", ffdh_c[testnum][0],
|
||||
ffdh_params[testnum].bits, seconds.ffdh);
|
||||
Time_F(START);
|
||||
count =
|
||||
run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
|
||||
d = Time_F(STOP);
|
||||
BIO_printf(bio_err,
|
||||
mr ? "+R12:%ld:%d:%.2f\n" :
|
||||
"%ld %u-bits FFDH ops in %.2fs\n", count,
|
||||
ffdh_params[testnum].bits, d);
|
||||
ffdh_results[testnum][0] = (double)count / d;
|
||||
rsa_count = count;
|
||||
};
|
||||
if (rsa_count <= 1) {
|
||||
/* if longer than 10s, don't do any more */
|
||||
stop_it(ffdh_doit, testnum);
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
#ifndef NO_FORK
|
||||
show_res:
|
||||
#endif
|
||||
@@ -3687,6 +3982,26 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
# endif
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
#ifndef OPENSSL_NO_DH
|
||||
testnum = 1;
|
||||
for (k = 0; k < FFDH_NUM; k++) {
|
||||
if (!ffdh_doit[k])
|
||||
continue;
|
||||
if (testnum && !mr) {
|
||||
printf("%23sop op/s\n", " ");
|
||||
testnum = 0;
|
||||
}
|
||||
if (mr)
|
||||
printf("+F8:%u:%u:%f:%f\n",
|
||||
k, ffdh_params[k].bits,
|
||||
ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
|
||||
|
||||
else
|
||||
printf("%4u bits ffdh %8.4fs %8.1f\n",
|
||||
ffdh_params[k].bits,
|
||||
1.0 / ffdh_results[k][0], ffdh_results[k][0]);
|
||||
}
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
|
||||
ret = 0;
|
||||
|
||||
@@ -3700,6 +4015,13 @@ int speed_main(int argc, char **argv)
|
||||
for (k = 0; k < RSA_NUM; k++)
|
||||
RSA_free(loopargs[i].rsa_key[k]);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
OPENSSL_free(loopargs[i].secret_ff_a);
|
||||
OPENSSL_free(loopargs[i].secret_ff_b);
|
||||
for (k = 0; k < FFDH_NUM; k++) {
|
||||
EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
|
||||
}
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
for (k = 0; k < DSA_NUM; k++)
|
||||
DSA_free(loopargs[i].dsa_key[k]);
|
||||
@@ -3709,8 +4031,10 @@ int speed_main(int argc, char **argv)
|
||||
EC_KEY_free(loopargs[i].ecdsa[k]);
|
||||
for (k = 0; k < EC_NUM; k++)
|
||||
EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
|
||||
for (k = 0; k < EdDSA_NUM; k++)
|
||||
for (k = 0; k < EdDSA_NUM; k++) {
|
||||
EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
|
||||
EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
|
||||
}
|
||||
# ifndef OPENSSL_NO_SM2
|
||||
for (k = 0; k < SM2_NUM; k++) {
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
@@ -3978,7 +4302,20 @@ static int do_multi(int multi, int size_num)
|
||||
sm2_results[k][1] += d;
|
||||
}
|
||||
# endif /* OPENSSL_NO_SM2 */
|
||||
# endif
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
# ifndef OPENSSL_NO_DH
|
||||
else if (strncmp(buf, "+F8:", 4) == 0) {
|
||||
int k;
|
||||
double d;
|
||||
|
||||
p = buf + 4;
|
||||
k = atoi(sstrsep(&p, sep));
|
||||
sstrsep(&p, sep);
|
||||
|
||||
d = atof(sstrsep(&p, sep));
|
||||
ffdh_results[k][0] += d;
|
||||
}
|
||||
# endif /* OPENSSL_NO_DH */
|
||||
|
||||
else if (strncmp(buf, "+H:", 3) == 0) {
|
||||
;
|
||||
|
||||
+2
-1
@@ -46,7 +46,8 @@ before_build:
|
||||
- cd ..
|
||||
- ps: >-
|
||||
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER`
|
||||
-or (&git log -2 | Select-String "\[extended tests\]") ) {
|
||||
-or (&git log -1 $env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT |
|
||||
Select-String "\[extended tests\]") ) {
|
||||
$env:EXTENDED_TESTS="yes"
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,6 @@
|
||||
#include <openssl/aes.h>
|
||||
#include "aes_local.h"
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
} aes_block_t;
|
||||
|
||||
/* XXX: probably some better way to do this */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 1
|
||||
@@ -30,6 +25,15 @@ typedef struct {
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 0
|
||||
#endif
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
#if defined(__GNUC__) && UNALIGNED_MEMOPS_ARE_FAST
|
||||
} aes_block_t __attribute((__aligned__(1)));
|
||||
#else
|
||||
} aes_block_t;
|
||||
#endif
|
||||
|
||||
#if UNALIGNED_MEMOPS_ARE_FAST
|
||||
# define load_block(d, s) (d) = *(const aes_block_t *)(s)
|
||||
# define store_block(d, s) *(aes_block_t *)(d) = (s)
|
||||
|
||||
@@ -277,7 +277,7 @@ void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
|
||||
|
||||
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pub_decode) (EVP_PKEY *pk,
|
||||
X509_PUBKEY *pub),
|
||||
const X509_PUBKEY *pub),
|
||||
int (*pub_encode) (X509_PUBKEY *pub,
|
||||
const EVP_PKEY *pk),
|
||||
int (*pub_cmp) (const EVP_PKEY *a,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -635,7 +635,11 @@ fmtfp(char **sbuffer,
|
||||
fvalue = tmpvalue;
|
||||
}
|
||||
ufvalue = abs_val(fvalue);
|
||||
if (ufvalue > ULONG_MAX) {
|
||||
/*
|
||||
* By subtracting 65535 (2^16-1) we cancel the low order 15 bits
|
||||
* of ULONG_MAX to avoid using imprecise floating point values.
|
||||
*/
|
||||
if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) {
|
||||
/* Number too big */
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-34
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "bio_local.h"
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
# define SOCKET_PROTOCOL IPPROTO_TCP
|
||||
@@ -23,13 +24,6 @@
|
||||
static int wsa_init_done = 0;
|
||||
# endif
|
||||
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# include <sys/select.h>
|
||||
# else
|
||||
# include <winsock.h> /* for type fd_set */
|
||||
# endif
|
||||
|
||||
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
int BIO_get_host_ip(const char *str, unsigned char *ip)
|
||||
{
|
||||
@@ -375,30 +369,4 @@ int BIO_sock_info(int sock,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO simplify by BIO_socket_wait() further other uses of select() in apps/ */
|
||||
/*
|
||||
* Wait on fd at most until max_time; succeed immediately if max_time == 0.
|
||||
* If for_read == 0 then assume to wait for writing, else wait for reading.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_socket_wait(int fd, int for_read, time_t max_time)
|
||||
{
|
||||
fd_set confds;
|
||||
struct timeval tv;
|
||||
time_t now;
|
||||
|
||||
if (max_time == 0)
|
||||
return 1;
|
||||
|
||||
now = time(NULL);
|
||||
if (max_time <= now)
|
||||
return 0;
|
||||
|
||||
FD_ZERO(&confds);
|
||||
openssl_fdset(fd, &confds);
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = (long)(max_time - now); /* might overflow */
|
||||
return select(fd + 1, for_read ? &confds : NULL,
|
||||
for_read ? NULL : &confds, NULL, &tv);
|
||||
}
|
||||
#endif /* !defined(OPENSSL_NO_SOCK) */
|
||||
#endif
|
||||
@@ -22,7 +22,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
|
||||
"gethostbyname addr is not af inet"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
|
||||
@@ -46,8 +45,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
|
||||
"unable to bind socket"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET),
|
||||
|
||||
@@ -784,102 +784,3 @@ void bio_cleanup(void)
|
||||
CRYPTO_THREAD_lock_free(bio_type_lock);
|
||||
bio_type_lock = NULL;
|
||||
}
|
||||
|
||||
/* Internal variant of the below BIO_wait() not calling BIOerr() */
|
||||
static int bio_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
if (max_time == 0)
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if (BIO_get_fd(bio, &fd) > 0)
|
||||
return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
|
||||
#endif
|
||||
if (milliseconds > 1000) {
|
||||
long sec_diff = (long)(max_time - time(NULL)); /* might overflow */
|
||||
|
||||
if (sec_diff <= 0)
|
||||
return 0; /* timeout */
|
||||
if ((unsigned long)sec_diff < milliseconds / 1000)
|
||||
milliseconds = (unsigned long)sec_diff * 1000;
|
||||
}
|
||||
ossl_sleep(milliseconds);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on (typically socket-based) BIO at most until max_time.
|
||||
* Succeed immediately if max_time == 0. If sockets are not available succeed
|
||||
* after waiting at most given milliseconds in order to avoid a tight busy loop.
|
||||
* Call BIOerr(...) unless success.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
int rv = bio_wait(bio, max_time, milliseconds);
|
||||
|
||||
if (rv <= 0)
|
||||
BIOerr(0, rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect via given BIO using BIO_do_handshake() until success/timeout/error.
|
||||
* Parameter timeout == 0 means infinite, < 0 leads to immediate timeout error.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_connect_retry(BIO *bio, int timeout)
|
||||
{
|
||||
int blocking = timeout == 0;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
int rv;
|
||||
|
||||
if (bio == NULL) {
|
||||
BIOerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout < 0) {
|
||||
BIOerr(0, BIO_R_CONNECT_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!blocking)
|
||||
BIO_set_nbio(bio, 1);
|
||||
|
||||
retry: /* it does not help here to set SSL_MODE_AUTO_RETRY */
|
||||
rv = BIO_do_handshake(bio); /* This indirectly calls ERR_clear_error(); */
|
||||
|
||||
if (rv <= 0) {
|
||||
if (get_last_sys_error() == ETIMEDOUT) {
|
||||
/*
|
||||
* if blocking, despite blocking BIO, BIO_do_handshake() timed out
|
||||
* when non-blocking, BIO_do_handshake() timed out early
|
||||
* with rv == -1 and get_last_sys_error() == 0
|
||||
*/
|
||||
ERR_clear_error();
|
||||
(void)BIO_reset(bio);
|
||||
/*
|
||||
* unless using BIO_reset(), blocking next connect() may crash and
|
||||
* non-blocking next BIO_do_handshake() will fail
|
||||
*/
|
||||
goto retry;
|
||||
} else if (BIO_should_retry(bio)) {
|
||||
/* will not actually wait if timeout == 0 (i.e., blocking BIO) */
|
||||
rv = bio_wait(bio, max_time, 100 /* milliseconds */);
|
||||
if (rv > 0)
|
||||
goto retry;
|
||||
BIOerr(0, rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
|
||||
} else {
|
||||
rv = -1;
|
||||
if (ERR_peek_error() == 0) /* missing error queue entry */
|
||||
BIOerr(0, BIO_R_CONNECT_ERROR); /* workaround: general error */
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
+10
-1
@@ -188,8 +188,17 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
|
||||
|
||||
case BIO_CONN_S_BLOCKED_CONNECT:
|
||||
i = BIO_sock_error(b->num);
|
||||
if (i) {
|
||||
if (i != 0) {
|
||||
BIO_clear_retry_flags(b);
|
||||
if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
|
||||
/*
|
||||
* if there are more addresses to try, do that first
|
||||
*/
|
||||
BIO_closesocket(b->num);
|
||||
c->state = BIO_CONN_S_CREATE_SOCKET;
|
||||
ERR_clear_error();
|
||||
break;
|
||||
}
|
||||
ERR_raise_data(ERR_LIB_SYS, i,
|
||||
"calling connect(%s, %s)",
|
||||
c->param_hostname, c->param_service);
|
||||
|
||||
@@ -154,10 +154,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
long ret = 1;
|
||||
int *ip;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
size_t crypto_info_len;
|
||||
# ifdef __FreeBSD__
|
||||
struct tls_enable *crypto_info;
|
||||
# else
|
||||
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||
struct tls_crypto_info_all *crypto_info;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -191,10 +192,12 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_SET_KTLS:
|
||||
# ifdef __FreeBSD__
|
||||
crypto_info = (struct tls_enable *)ptr;
|
||||
crypto_info_len = sizeof(*crypto_info);
|
||||
# else
|
||||
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
|
||||
crypto_info = (struct tls_crypto_info_all *)ptr;
|
||||
crypto_info_len = crypto_info->tls_crypto_info_len;
|
||||
# endif
|
||||
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
|
||||
ret = ktls_start(b->num, crypto_info, crypto_info_len, num);
|
||||
if (ret)
|
||||
BIO_set_ktls_flag(b, num);
|
||||
break;
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
* The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
* RFC2312 specifies a generator of 22.
|
||||
* RFC2412 specifies a generator of 22.
|
||||
*/
|
||||
static const BN_ULONG modp_1536_p[] = {
|
||||
BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCA237327, 0xF1746C08),
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -45,7 +45,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
|
||||
int neg = 0;
|
||||
BIGNUM *a = NULL;
|
||||
|
||||
if (n < 4) {
|
||||
if (n < 4 || (d[0] & 0x80) != 0) {
|
||||
BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \
|
||||
md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \
|
||||
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
||||
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
||||
err comp http ocsp cms ts srp cmac ct async ess crmf cmp serializer \
|
||||
err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer \
|
||||
ffc
|
||||
|
||||
LIBS=../libcrypto
|
||||
|
||||
@@ -2,7 +2,7 @@ LIBS=../../libcrypto
|
||||
|
||||
$CASTASM=c_enc.c
|
||||
# CAST assembly source is not PIC
|
||||
IF[{- !$disabled{asm} && !$disabled{pic} -}]
|
||||
IF[{- !$disabled{asm} && $disabled{pic} -}]
|
||||
$CASTASM_x86=cast-586.s
|
||||
|
||||
# Now that we have defined all the arch specific variables, use the
|
||||
|
||||
@@ -31,9 +31,9 @@ static int cmac_size(const EVP_PKEY *pkey)
|
||||
static void cmac_key_free(EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
|
||||
EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx);
|
||||
EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_get_ctx_mac(cmctx);
|
||||
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
EVP_MAC_free_ctx(cmctx);
|
||||
EVP_MAC_free(mac);
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -125,12 +125,18 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
|
||||
return 1;
|
||||
}
|
||||
/* Initialise context */
|
||||
if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
|
||||
if (cipher != NULL) {
|
||||
/* Ensure we can't use this ctx until we also have a key */
|
||||
ctx->nlast_block = -1;
|
||||
if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
|
||||
return 0;
|
||||
}
|
||||
/* Non-NULL key means initialisation complete */
|
||||
if (key) {
|
||||
if (key != NULL) {
|
||||
int bl;
|
||||
|
||||
/* If anything fails then ensure we can't use this ctx */
|
||||
ctx->nlast_block = -1;
|
||||
if (!EVP_CIPHER_CTX_cipher(ctx->cctx))
|
||||
return 0;
|
||||
if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen))
|
||||
@@ -139,7 +145,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
|
||||
return 0;
|
||||
if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0)
|
||||
return 0;
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl) <= 0)
|
||||
return 0;
|
||||
make_kn(ctx->k1, ctx->tbl, bl);
|
||||
make_kn(ctx->k2, ctx->k1, bl);
|
||||
@@ -180,12 +186,12 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
|
||||
return 1;
|
||||
data += nleft;
|
||||
/* Else not final block so encrypt it */
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl) <= 0)
|
||||
return 0;
|
||||
}
|
||||
/* Encrypt all but one of the complete blocks left */
|
||||
while (dlen > (size_t)bl) {
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
|
||||
return 0;
|
||||
dlen -= bl;
|
||||
data += bl;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
|
||||
cmp_server.c cmp_client.c cmp_http.c
|
||||
cmp_server.c cmp_client.c
|
||||
@@ -146,7 +146,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb;
|
||||
|
||||
if (transfer_cb == NULL)
|
||||
transfer_cb = OSSL_CMP_MSG_http_perform;
|
||||
transfer_cb = NULL; /* TODO: will be OSSL_CMP_MSG_http_perform of chunk 10 */
|
||||
|
||||
*rep = NULL;
|
||||
msg_timeout = ctx->msg_timeout; /* backup original value */
|
||||
@@ -189,8 +189,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
*/
|
||||
ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt));
|
||||
|
||||
if ((bt = ossl_cmp_msg_check_received(ctx, *rep, unprotected_exception,
|
||||
expected_type)) < 0)
|
||||
if (!ossl_cmp_msg_check_update(ctx, *rep, unprotected_exception,
|
||||
expected_type))
|
||||
return 0;
|
||||
|
||||
if (bt == expected_type
|
||||
|
||||
+148
-39
@@ -43,6 +43,7 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
* Set certificate store containing trusted (root) CA certs and possibly CRLs
|
||||
* and a cert verification callback function used for CMP server authentication.
|
||||
* Any already existing store entry is freed. Given NULL, the entry is reset.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
{
|
||||
@@ -55,7 +56,9 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get current list of non-trusted intermediate certs */
|
||||
/*
|
||||
* Get current list of non-trusted intermediate certs
|
||||
*/
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -68,6 +71,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set untrusted certificates for path construction in authentication of
|
||||
* the CMP server and potentially others (TLS server, newly enrolled cert).
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
|
||||
{
|
||||
@@ -104,6 +108,8 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
ctx->status = -1;
|
||||
ctx->failInfoCode = -1;
|
||||
|
||||
ctx->serverPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->proxyPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->msg_timeout = 2 * 60;
|
||||
|
||||
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
|
||||
@@ -126,7 +132,9 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
|
||||
/*
|
||||
* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX
|
||||
*/
|
||||
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -147,16 +155,17 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
&& ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
|
||||
}
|
||||
|
||||
/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
|
||||
/*
|
||||
* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new()
|
||||
*/
|
||||
void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_free(ctx->serverPath);
|
||||
OPENSSL_free(ctx->server);
|
||||
OPENSSL_free(ctx->proxy);
|
||||
OPENSSL_free(ctx->no_proxy);
|
||||
OPENSSL_free(ctx->serverName);
|
||||
OPENSSL_free(ctx->proxyName);
|
||||
|
||||
X509_free(ctx->srvCert);
|
||||
X509_free(ctx->validatedSrvCert);
|
||||
@@ -250,7 +259,11 @@ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set callback function for checking if the cert is ok or should be rejected */
|
||||
/*
|
||||
* Set callback function for checking if the cert is ok or should
|
||||
* it be rejected.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -264,6 +277,7 @@ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
/*
|
||||
* Set argument, respectively a pointer to a structure containing arguments,
|
||||
* optionally to be used by the certConf callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
@@ -373,7 +387,10 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Set a callback function for error reporting and logging messages */
|
||||
/*
|
||||
* Set a callback function for error reporting and logging messages.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -393,7 +410,7 @@ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
}
|
||||
|
||||
/* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */
|
||||
void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb);
|
||||
}
|
||||
@@ -401,6 +418,7 @@ void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set or clear the reference value to be used for identification
|
||||
* (i.e., the user name) when using PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
const unsigned char *ref, int len)
|
||||
@@ -413,7 +431,10 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
len);
|
||||
}
|
||||
|
||||
/* Set or clear the password to be used for protecting messages with PBMAC */
|
||||
/*
|
||||
* Set or clear the password to be used for protecting messages with PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
|
||||
const int len)
|
||||
{
|
||||
@@ -451,6 +472,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Copies any given stack of inbound X509 certificates to extraCertsIn
|
||||
* of the OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsIn)
|
||||
@@ -468,6 +490,7 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Duplicate and set the given stack as the new stack of X509
|
||||
* certificates to send out in the extraCerts field.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsOut)
|
||||
@@ -487,6 +510,7 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Add the given policy info object
|
||||
* to the X509_EXTENSIONS of the requested certificate template.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
{
|
||||
@@ -502,7 +526,9 @@ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
return sk_POLICYINFO_push(ctx->policies, pinfo);
|
||||
}
|
||||
|
||||
/* Add an ITAV for geninfo of the PKI message header */
|
||||
/*
|
||||
* Add an ITAV for geninfo of the PKI message header
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -512,7 +538,9 @@ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
|
||||
}
|
||||
|
||||
/* Add an itav for the body of outgoing general messages */
|
||||
/*
|
||||
* Add an itav for the body of outgoing general messages
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -541,6 +569,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Duplicate and copy the given stack of certificates to the given
|
||||
* OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs)
|
||||
{
|
||||
@@ -592,25 +621,39 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
|
||||
* Pins the server certificate to be directly trusted (even if it is expired)
|
||||
* for verifying response messages.
|
||||
* Cert pointer is not consumed. It may be NULL to clear the entry.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509)
|
||||
|
||||
/* Set the X509 name of the recipient. Set in the PKIHeader */
|
||||
/*
|
||||
* Set the X509 name of the recipient. Set in the PKIHeader.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
|
||||
|
||||
/* Store the X509 name of the expected sender in the PKIHeader of responses */
|
||||
/*
|
||||
* Store the X509 name of the expected sender in the PKIHeader of responses.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
|
||||
|
||||
/* Set the X509 name of the issuer. Set in the PKIHeader */
|
||||
/*
|
||||
* Set the X509 name of the issuer. Set in the PKIHeader.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the subject name that will be placed in the certificate
|
||||
* request. This will be the subject name on the received certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
|
||||
|
||||
/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
|
||||
/*
|
||||
* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -644,6 +687,7 @@ int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Add a GENERAL_NAME structure that will be added to the CRMF
|
||||
* request's extensions field to request subject alternative names.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name)
|
||||
@@ -675,6 +719,7 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Set our own client certificate, used for example in KUR and when
|
||||
* doing the IR with existing certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509)
|
||||
|
||||
@@ -683,14 +728,19 @@ DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509)
|
||||
* or the certificate to be revoked in RR, respectively.
|
||||
* Also used as reference cert (defaulting to cert) for deriving subject DN
|
||||
* and SANs. Its issuer is used as default recipient in the CMP message header.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509)
|
||||
|
||||
/* Set the PKCS#10 CSR to be sent in P10CR */
|
||||
/*
|
||||
* Set the PKCS#10 CSR to be sent in P10CR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
|
||||
|
||||
/*
|
||||
* Set the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Sets the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
* TODO: this only permits for one cert to be enrolled at a time.
|
||||
*/
|
||||
int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
@@ -716,10 +766,16 @@ X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->newCert;
|
||||
}
|
||||
|
||||
/* Set the client's current private key */
|
||||
/*
|
||||
* Set the client's current private key.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY)
|
||||
|
||||
/* Set new key pair. Used e.g. when doing Key Update */
|
||||
/*
|
||||
* Set new key pair. Used e.g. when doing Key Update.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -733,7 +789,9 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the private/public key to use for cert enrollment, or NULL on error */
|
||||
/*
|
||||
* gets the private/public key to use for certificate enrollment, NULL on error
|
||||
*/
|
||||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -748,7 +806,10 @@ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
return ctx->pkey; /* may be NULL */
|
||||
}
|
||||
|
||||
/* Set the given transactionID to the context */
|
||||
/*
|
||||
* Sets the given transactionID to the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *id)
|
||||
{
|
||||
@@ -759,7 +820,11 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id);
|
||||
}
|
||||
|
||||
/* Set the nonce to be used for the recipNonce in the message created next */
|
||||
/*
|
||||
* sets the given nonce to be used for the recipNonce in the next message to be
|
||||
* created.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -768,7 +833,10 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce);
|
||||
}
|
||||
|
||||
/* Stores the given nonce as the last senderNonce sent out */
|
||||
/*
|
||||
* Stores the given nonce as the last senderNonce sent out.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -779,17 +847,37 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce);
|
||||
}
|
||||
|
||||
/* Set the proxy server to use for HTTP(S) connections */
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxy, char)
|
||||
/*
|
||||
* Set the host name of the (HTTP) proxy server to use for all connections
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxyName, char)
|
||||
|
||||
/* Set the (HTTP) host name of the CMP server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(server, char)
|
||||
/*
|
||||
* Set the (HTTP) host name of the CA server.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverName, char)
|
||||
|
||||
/* Set the server exclusion list of the HTTP proxy server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
|
||||
/*
|
||||
* Sets the (HTTP) proxy port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->proxyPort = port;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the http connect/disconnect callback function to be used for HTTP(S) */
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
/*
|
||||
* sets the http connect/disconnect callback function to be used for HTTP(S)
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_http_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -799,7 +887,10 @@ int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set argument optionally to be used by the http connect/disconnect callback */
|
||||
/*
|
||||
* Set argument optionally to be used by the http connect/disconnect callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -823,7 +914,10 @@ void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->http_cb_arg;
|
||||
}
|
||||
|
||||
/* Set callback function for sending CMP request and receiving response */
|
||||
/*
|
||||
* Set callback function for sending CMP request and receiving response.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -834,7 +928,10 @@ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set argument optionally to be used by the transfer callback */
|
||||
/*
|
||||
* Set argument optionally to be used by the transfer callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -858,7 +955,10 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->transfer_cb_arg;
|
||||
}
|
||||
|
||||
/** Set the HTTP server port to be used */
|
||||
/*
|
||||
* Sets the (HTTP) server port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -869,10 +969,16 @@ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the HTTP path to be used on the server (e.g "pkix/") */
|
||||
/*
|
||||
* Sets the HTTP path to be used on the server (e.g "pkix/").
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
|
||||
|
||||
/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
|
||||
/*
|
||||
* Set the failInfo error code as bit encoding in OSSL_CMP_CTX.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
@@ -894,7 +1000,10 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->failInfoCode;
|
||||
}
|
||||
|
||||
/* Set a Boolean or integer option of the context to the "val" arg */
|
||||
/*
|
||||
* Sets a Boolean or integer option of the context to the "val" arg.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
{
|
||||
int min_val;
|
||||
|
||||
@@ -76,6 +76,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"error unexpected certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
|
||||
"error validating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE),
|
||||
"error validating signature"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
"failed extracting pubkey"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
|
||||
|
||||
+19
-15
@@ -41,6 +41,14 @@ int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr)
|
||||
return (int)pvno;
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
if (!ossl_assert(hdr != NULL)
|
||||
|| hdr->protectionAlg == NULL)
|
||||
return NID_undef;
|
||||
return OBJ_obj2nid(hdr->protectionAlg->algorithm);
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
|
||||
OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
@@ -300,30 +308,26 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The sender name is copied from the subject of the client cert, if any,
|
||||
* or else from the subject name provided for certification requests.
|
||||
* If neither protection cert nor oldCert nor subject are given,
|
||||
* sender name is not known to the client and thus set to NULL-DN
|
||||
*/
|
||||
sender = ctx->cert != NULL ?
|
||||
X509_get_subject_name(ctx->cert) : ctx->subjectName;
|
||||
sender = ctx->cert != NULL ? X509_get_subject_name(ctx->cert) :
|
||||
ctx->oldCert != NULL ? X509_get_subject_name(ctx->oldCert) :
|
||||
ctx->subjectName;
|
||||
if (!ossl_cmp_hdr_set1_sender(hdr, sender))
|
||||
return 0;
|
||||
|
||||
/* determine recipient entry in PKIHeader */
|
||||
if (ctx->srvCert != NULL) {
|
||||
rcp = X509_get_subject_name(ctx->srvCert);
|
||||
/* set also as expected_sender of responses unless set explicitly */
|
||||
if (ctx->expected_sender == NULL && rcp != NULL
|
||||
&& !OSSL_CMP_CTX_set1_expected_sender(ctx, rcp))
|
||||
return 0;
|
||||
} else if (ctx->recipient != NULL) {
|
||||
if (ctx->recipient != NULL)
|
||||
rcp = ctx->recipient;
|
||||
} else if (ctx->issuer != NULL) {
|
||||
else if (ctx->srvCert != NULL)
|
||||
rcp = X509_get_subject_name(ctx->srvCert);
|
||||
else if (ctx->issuer != NULL)
|
||||
rcp = ctx->issuer;
|
||||
} else if (ctx->oldCert != NULL) {
|
||||
else if (ctx->oldCert != NULL)
|
||||
rcp = X509_get_issuer_name(ctx->oldCert);
|
||||
} else if (ctx->cert != NULL) {
|
||||
else if (ctx->cert != NULL)
|
||||
rcp = X509_get_issuer_name(ctx->cert);
|
||||
}
|
||||
if (!ossl_cmp_hdr_set1_recipient(hdr, rcp))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
|
||||
#include "openssl/cmp.h"
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
DEFINE_STACK_OF(CONF_VALUE)
|
||||
|
||||
/*
|
||||
* Send the PKIMessage req and on success return the response, else NULL.
|
||||
* Any previous error queue entries will likely be removed by ERR_clear_error().
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
char server_port[32] = { '\0' };
|
||||
STACK_OF(CONF_VALUE) *headers = NULL;
|
||||
const char *const content_type_pkix = "application/pkixcmp";
|
||||
OSSL_CMP_MSG *res;
|
||||
|
||||
if (ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value("Pragma", "no-cache", &headers))
|
||||
return NULL;
|
||||
|
||||
if (ctx->serverPort != 0)
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
|
||||
res = (OSSL_CMP_MSG *)
|
||||
OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath,
|
||||
OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL,
|
||||
ctx->proxy, ctx->no_proxy, NULL, NULL,
|
||||
ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx),
|
||||
headers, content_type_pkix, (const ASN1_VALUE *)req,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
0, 0, ctx->msg_timeout, content_type_pkix,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG));
|
||||
|
||||
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
|
||||
return res;
|
||||
}
|
||||
@@ -36,15 +36,15 @@ struct ossl_cmp_ctx_st {
|
||||
void *transfer_cb_arg; /* allows to store optional argument to cb */
|
||||
/* HTTP-based transfer */
|
||||
char *serverPath;
|
||||
char *server;
|
||||
char *serverName;
|
||||
int serverPort;
|
||||
char *proxy;
|
||||
char *no_proxy;
|
||||
char *proxyName;
|
||||
int proxyPort;
|
||||
int msg_timeout; /* max seconds to wait for each CMP message round trip */
|
||||
int total_timeout; /* max number of seconds an enrollment may take, incl. */
|
||||
/* attempts polling for a response if a 'waiting' PKIStatus is received */
|
||||
time_t end_time; /* session start time + totaltimeout */
|
||||
OSSL_HTTP_bio_cb_t http_cb;
|
||||
OSSL_CMP_http_cb_t http_cb;
|
||||
void *http_cb_arg; /* allows to store optional argument to cb */
|
||||
|
||||
/* server authentication */
|
||||
@@ -283,7 +283,6 @@ struct ossl_cmp_pkisi_st {
|
||||
OSSL_CMP_PKIFREETEXT *statusString;
|
||||
OSSL_CMP_PKIFAILUREINFO *failInfo;
|
||||
} /* OSSL_CMP_PKISI */;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
* RevReqContent ::= SEQUENCE OF RevDetails
|
||||
@@ -797,6 +796,7 @@ int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
|
||||
/* from cmp_hdr.c */
|
||||
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
|
||||
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name);
|
||||
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
@@ -909,7 +909,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg,
|
||||
int invalid_protection, int arg);
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)
|
||||
DEFINE_STACK_OF(OSSL_CMP_ITAV)
|
||||
DEFINE_STACK_OF(GENERAL_NAME)
|
||||
DEFINE_STACK_OF(X509)
|
||||
DEFINE_STACK_OF(X509_EXTENSION)
|
||||
DEFINE_STACK_OF(OSSL_CMP_PKISI)
|
||||
DEFINE_STACK_OF(OSSL_CRMF_MSG)
|
||||
@@ -228,7 +229,7 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
|
||||
X509_EXTENSIONS *exts = NULL;
|
||||
|
||||
if (rkey == NULL)
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldCert */
|
||||
if (rkey == NULL) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -426,9 +427,12 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL
|
||||
&& (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL)
|
||||
goto err;
|
||||
if (chain != NULL
|
||||
&& !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0))
|
||||
if (sk_X509_num(chain) > 0) {
|
||||
msg->extraCerts = sk_X509_new_reserve(NULL, sk_X509_num(chain));
|
||||
if (msg->extraCerts == NULL
|
||||
|| !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!unprotectedErrors
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|
||||
@@ -26,8 +26,8 @@ DEFINE_STACK_OF(X509)
|
||||
* Calculate protection for given PKImessage utilizing the given credentials
|
||||
* and the algorithm parameters set inside the message header's protectionAlg.
|
||||
*
|
||||
* Either secret or pkey must be set, the other must be NULL. Attempts doing
|
||||
* PBMAC in case 'secret' is set and signature if 'pkey' is set - but will only
|
||||
* secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set
|
||||
* and else signature if 'pkey' is set - but will only
|
||||
* do the protection already marked in msg->header->protectionAlg.
|
||||
*
|
||||
* returns ptr to ASN1_BIT_STRING containing protection on success, else NULL
|
||||
@@ -73,7 +73,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
}
|
||||
X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);
|
||||
|
||||
if (secret != NULL && pkey == NULL) {
|
||||
if (secret != NULL) {
|
||||
if (ppval == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
|
||||
goto end;
|
||||
@@ -94,7 +94,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
secret->data, secret->length,
|
||||
&protection, &sig_len))
|
||||
goto end;
|
||||
} else if (secret == NULL && pkey != NULL) {
|
||||
} else if (pkey != NULL) {
|
||||
/* TODO combine this with large parts of CRMF_poposigningkey_init() */
|
||||
/* EVP_DigestSignInit() checks that pkey type is correct for the alg */
|
||||
|
||||
@@ -259,10 +259,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (msg->header->protectionAlg == NULL)
|
||||
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
|
||||
EVP_PKEY_id(ctx->pkey))) {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
|
||||
|
||||
+23
-7
@@ -452,8 +452,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
ASN1_OCTET_STRING *backup_secret;
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
int req_type, rsp_type;
|
||||
int res;
|
||||
OSSL_CMP_MSG *rsp = NULL;
|
||||
|
||||
if (srv_ctx == NULL || srv_ctx->ctx == NULL
|
||||
@@ -463,7 +465,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
return 0;
|
||||
}
|
||||
ctx = srv_ctx->ctx;
|
||||
backup_secret = ctx->secretValue;
|
||||
|
||||
/*
|
||||
* Some things need to be done already before validating the message in
|
||||
* order to be able to send an error message as far as needed and possible.
|
||||
*/
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
goto err;
|
||||
@@ -485,6 +492,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
|
||||
tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
|
||||
ctx->transactionID->length);
|
||||
if (tid != NULL)
|
||||
ossl_cmp_log1(WARN, ctx,
|
||||
"Assuming that last transaction with ID=%s got aborted",
|
||||
tid);
|
||||
@@ -500,16 +508,17 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
if (ctx->transactionID == NULL) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected) < 0)
|
||||
res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected);
|
||||
if (ctx->secretValue != NULL && ctx->pkey != NULL
|
||||
&& ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC)
|
||||
ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */
|
||||
if (!res)
|
||||
goto err;
|
||||
|
||||
switch (req_type) {
|
||||
@@ -568,9 +577,14 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
/* TODO fail_info could be more specific */
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
|
||||
if (ctx->transactionID == NULL) {
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
}
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
fail_info, NULL)) == NULL)
|
||||
return 0;
|
||||
fail_info, NULL)) != NULL) {
|
||||
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
|
||||
data = ERR_reason_error_string(err);
|
||||
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
|
||||
@@ -578,6 +592,8 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
data, srv_ctx->sendUnprotectedErrors);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
}
|
||||
}
|
||||
ctx->secretValue = backup_secret;
|
||||
|
||||
/* possibly close the transaction */
|
||||
rsp_type =
|
||||
|
||||
+242
-225
@@ -24,7 +24,7 @@
|
||||
|
||||
DEFINE_STACK_OF(X509)
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Verify a message protected by signature according to section 5.1.3.3
|
||||
* (sha1+RSA/DSA or any other algorithm supported by OpenSSL).
|
||||
*
|
||||
@@ -70,7 +70,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
|
||||
prot_part_der_len = (size_t) len;
|
||||
|
||||
/* verify signature of protected part */
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(msg->header->protectionAlg->algorithm),
|
||||
if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header),
|
||||
&digest_nid, &pk_nid)
|
||||
|| digest_nid == NID_undef || pk_nid == NID_undef
|
||||
|| (digest = EVP_get_digestbynid(digest_nid)) == NULL) {
|
||||
@@ -95,7 +95,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
|
||||
|
||||
sig_err:
|
||||
res = x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_SIGNATURE);
|
||||
if (res)
|
||||
ERR_add_error_mem_bio("\n", bio);
|
||||
res = 0;
|
||||
@@ -132,15 +132,15 @@ static int verify_PBMAC(const OSSL_CMP_MSG *msg,
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Attempt to validate certificate and path using any given store with trusted
|
||||
* certs (possibly including CRLs and a cert verification callback function)
|
||||
* and non-trusted intermediate certs from the given ctx.
|
||||
*
|
||||
* Returns 1 on successful validation and 0 otherwise.
|
||||
*/
|
||||
int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
X509 *cert)
|
||||
int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
|
||||
X509_STORE *trusted_store, X509 *cert)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE_CTX *csc = NULL;
|
||||
@@ -176,7 +176,7 @@ int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
}
|
||||
|
||||
/* Return 0 if expect_name != NULL and there is no matching actual_name */
|
||||
static int check_name(OSSL_CMP_CTX *ctx,
|
||||
static int check_name(const OSSL_CMP_CTX *ctx, int log_success,
|
||||
const char *actual_desc, const X509_NAME *actual_name,
|
||||
const char *expect_desc, const X509_NAME *expect_name)
|
||||
{
|
||||
@@ -190,10 +190,16 @@ static int check_name(OSSL_CMP_CTX *ctx,
|
||||
ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc);
|
||||
return 0;
|
||||
}
|
||||
if (X509_NAME_cmp(actual_name, expect_name) == 0)
|
||||
str = X509_NAME_oneline(actual_name, NULL, 0);
|
||||
if (X509_NAME_cmp(actual_name, expect_name) == 0) {
|
||||
if (log_success && str != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc,
|
||||
str);
|
||||
OPENSSL_free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((str = X509_NAME_oneline(actual_name, NULL, 0)) != NULL)
|
||||
if (str != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str);
|
||||
OPENSSL_free(str);
|
||||
if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL)
|
||||
@@ -203,11 +209,11 @@ static int check_name(OSSL_CMP_CTX *ctx,
|
||||
}
|
||||
|
||||
/* Return 0 if skid != NULL and there is no matching subject key ID in cert */
|
||||
static int check_kid(OSSL_CMP_CTX *ctx,
|
||||
X509 *cert, const ASN1_OCTET_STRING *skid)
|
||||
static int check_kid(const OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *ckid,
|
||||
const ASN1_OCTET_STRING *skid)
|
||||
{
|
||||
char *actual, *expect;
|
||||
const ASN1_OCTET_STRING *ckid = X509_get0_subject_key_id(cert);
|
||||
char *str;
|
||||
|
||||
if (skid == NULL)
|
||||
return 1; /* no expectation, thus trivially fulfilled */
|
||||
@@ -217,19 +223,25 @@ static int check_kid(OSSL_CMP_CTX *ctx,
|
||||
ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate");
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0)
|
||||
str = OPENSSL_buf2hexstr(ckid->data, ckid->length);
|
||||
if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) {
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str);
|
||||
OPENSSL_free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((actual = OPENSSL_buf2hexstr(ckid->data, ckid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", actual);
|
||||
if ((expect = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", expect);
|
||||
OPENSSL_free(expect);
|
||||
OPENSSL_free(actual);
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str);
|
||||
OPENSSL_free(str);
|
||||
if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", str);
|
||||
OPENSSL_free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
static int already_checked(const X509 *cert,
|
||||
const STACK_OF(X509) *already_checked)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -239,7 +251,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Check if the given cert is acceptable as sender cert of the given message.
|
||||
* The subject DN must match, the subject key ID as well if present in the msg,
|
||||
* and the cert must be current (checked if ctx->trusted is not NULL).
|
||||
@@ -247,7 +259,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
*
|
||||
* Returns 0 on error or not acceptable, else 1.
|
||||
*/
|
||||
static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
static int cert_acceptable(const OSSL_CMP_CTX *ctx,
|
||||
const char *desc1, const char *desc2, X509 *cert,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
@@ -285,19 +297,19 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!check_name(ctx,
|
||||
if (!check_name(ctx, 1,
|
||||
"cert subject", X509_get_subject_name(cert),
|
||||
"sender field", msg->header->sender->d.directoryName))
|
||||
return 0;
|
||||
|
||||
if (!check_kid(ctx, cert, msg->header->senderKID))
|
||||
if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID))
|
||||
return 0;
|
||||
/* acceptable also if there is no senderKID in msg header */
|
||||
ossl_cmp_info(ctx, " cert seems acceptable");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
X509 *scrt, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
if (!verify_signature(ctx, msg, scrt)) {
|
||||
@@ -319,7 +331,7 @@ static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
* from extraCerts as trust anchor to validate sender cert and msg -
|
||||
* provided it also can validate the newly enrolled certificate
|
||||
*/
|
||||
static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
int valid = 0;
|
||||
@@ -361,11 +373,21 @@ static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
return cert_acceptable(ctx, "previously validated", "sender cert",
|
||||
cert, NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, cert, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, cert, msg));
|
||||
}
|
||||
|
||||
/*-
|
||||
* Try all certs in given list for verifying msg, normally or in 3GPP mode.
|
||||
* If already_checked1 == NULL then certs are assumed to be the msg->extraCerts.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
|
||||
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
|
||||
const char *desc,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
@@ -406,9 +428,10 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Verify msg trying first ctx->untrusted_certs, which should include extraCerts
|
||||
* at its front, then trying the trusted certs in truststore (if any) of ctx.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
int mode_3gpp)
|
||||
@@ -451,7 +474,10 @@ static int no_log_cb(const char *func, const char *file, int line,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify message signature with any acceptable and valid candidate cert */
|
||||
/*-
|
||||
* Verify message signature with any acceptable and valid candidate cert.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */
|
||||
@@ -472,29 +498,28 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
/* dump any hitherto errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
|
||||
/*
|
||||
* try first cached scrt, used successfully earlier in same transaction,
|
||||
* for validating this and any further msgs where extraCerts may be left out
|
||||
*/
|
||||
if (scrt != NULL) {
|
||||
(void)ERR_set_mark();
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
if (cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, scrt, msg))) {
|
||||
if (check_msg_given_cert(ctx, scrt, msg)) {
|
||||
ctx->log_cb = backup_log_cb;
|
||||
(void)ERR_pop_to_mark();
|
||||
return 1;
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
/* cached sender cert has shown to be no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
/* re-do the above check (just) for adding diagnostic information */
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
(void)check_msg_given_cert(ctx, scrt, msg);
|
||||
}
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
ctx->log_cb = backup_log_cb;
|
||||
@@ -518,8 +543,8 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
else
|
||||
ossl_cmp_info(ctx, "while msg header does not contain senderKID");
|
||||
/* re-do the above checks (just) for adding diagnostic information */
|
||||
check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
|
||||
check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
(void)check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
|
||||
(void)check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
}
|
||||
|
||||
CMPerr(0, CMP_R_NO_SUITABLE_SENDER_CERT);
|
||||
@@ -538,12 +563,13 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Validate the protection of the given PKIMessage using either password-
|
||||
* based mac (PBM) or a signature algorithm. In the case of signature algorithm,
|
||||
* the sender certificate can have been pinned by providing it in ctx->srvCert,
|
||||
* else it is searched in msg->extraCerts, ctx->untrusted_certs, in ctx->trusted
|
||||
* (in this order) and is path is validated against ctx->trusted.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*
|
||||
* If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg,
|
||||
* the trust anchor for validating the IP msg may be taken from msg->extraCerts
|
||||
@@ -555,9 +581,6 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
*/
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_ALGOR *alg;
|
||||
int nid = NID_undef, pk_nid = NID_undef;
|
||||
const ASN1_OBJECT *algorOID = NULL;
|
||||
X509 *scrt;
|
||||
|
||||
if (ctx == NULL || msg == NULL
|
||||
@@ -566,17 +589,13 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((alg = msg->header->protectionAlg) == NULL /* unprotected message */
|
||||
if (msg->header->protectionAlg == NULL /* unprotected message */
|
||||
|| msg->protection == NULL || msg->protection->data == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* determine the nid for the used protection algorithm */
|
||||
X509_ALGOR_get0(&algorOID, NULL, NULL, alg);
|
||||
nid = OBJ_obj2nid(algorOID);
|
||||
|
||||
switch (nid) {
|
||||
switch (ossl_cmp_hdr_get_protection_nid(msg->header)) {
|
||||
/* 5.1.3.1. Shared Secret Information */
|
||||
case NID_id_PasswordBasedMAC:
|
||||
if (ctx->secretValue == 0) {
|
||||
@@ -584,7 +603,174 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
break;
|
||||
}
|
||||
|
||||
if (verify_PBMAC(msg, ctx->secretValue)) {
|
||||
if (verify_PBMAC(msg, ctx->secretValue))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.2 DH Key Pairs
|
||||
* Not yet supported
|
||||
*/
|
||||
case NID_id_DHBasedMac:
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC);
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.3. Signature
|
||||
*/
|
||||
default:
|
||||
scrt = ctx->srvCert;
|
||||
if (scrt == NULL) {
|
||||
if (check_msg_find_cert(ctx, msg))
|
||||
return 1;
|
||||
} else { /* use pinned sender cert */
|
||||
/* use ctx->srvCert for signature check even if not acceptable */
|
||||
if (verify_signature(ctx, msg, scrt))
|
||||
return 1;
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* Check received message (i.e., response by server or request from client)
|
||||
* Any msg->extraCerts are prepended to ctx->untrusted_certs.
|
||||
*
|
||||
* Ensures that:
|
||||
* its sender is of appropriate type (curently only X509_NAME) and
|
||||
* matches any expected sender or srvCert subject given in the ctx
|
||||
* it has a valid body type
|
||||
* its protection is valid (or invalid/absent, but only if a callback function
|
||||
* is present and yields a positive result using also the supplied argument)
|
||||
* its transaction ID matches the previous transaction ID stored in ctx (if any)
|
||||
* its recipNonce matches the previous senderNonce stored in the ctx (if any)
|
||||
*
|
||||
* If everything is fine:
|
||||
* learns the senderNonce from the received message,
|
||||
* learns the transaction ID if it is not yet in ctx,
|
||||
* and makes any certs in caPubs directly trusted.
|
||||
*
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
|
||||
{
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
const X509_NAME *expected_sender;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL))
|
||||
return 0;
|
||||
hdr = OSSL_CMP_MSG_get0_header(msg);
|
||||
|
||||
/* validate sender name of received msg */
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
return 0; /* TODO FR#42: support for more than X509_NAME */
|
||||
}
|
||||
/*
|
||||
* Compare actual sender name of response with expected sender name.
|
||||
* Mitigates risk to accept misused PBM secret
|
||||
* or misused certificate of an unauthorized entity of a trusted hierarchy.
|
||||
*/
|
||||
expected_sender = ctx->expected_sender;
|
||||
if (expected_sender == NULL && ctx->srvCert != NULL)
|
||||
expected_sender = X509_get_subject_name(ctx->srvCert);
|
||||
if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName,
|
||||
"expected sender", expected_sender))
|
||||
return 0;
|
||||
/* Note: if recipient was NULL-DN it could be learned here if needed */
|
||||
|
||||
if (sk_X509_num(msg->extraCerts) > 10)
|
||||
ossl_cmp_warn(ctx,
|
||||
"received CMP message contains more than 10 extraCerts");
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg()
|
||||
* and for future use, such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* Note that it does not help validating the message before storing the
|
||||
* extraCerts because they do not belong to the protected msg part anyway.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return 0;
|
||||
|
||||
/* validate message protection */
|
||||
if (hdr->protectionAlg != NULL) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* detect explicitly permitted exceptions for missing protection */
|
||||
if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_get_bodytype(msg) < 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (hdr->transactionID == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->transactionID,
|
||||
hdr->transactionID) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare received nonce with the one we sent */
|
||||
if (ctx->senderNonce != NULL
|
||||
&& (msg->header->recipNonce == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->senderNonce,
|
||||
hdr->recipNonce) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 4210 section 5.1.1 states: the recipNonce is copied from
|
||||
* the senderNonce of the previous message in the transaction.
|
||||
* --> Store for setting in next message
|
||||
*/
|
||||
if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
|
||||
return 0;
|
||||
|
||||
/* if not yet present, learn transactionID */
|
||||
if (ctx->transactionID == NULL
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID))
|
||||
return 0;
|
||||
|
||||
if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
* "shared secret information", then any certificate transported in
|
||||
@@ -592,8 +778,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
* certificate by the initiator.'
|
||||
*/
|
||||
switch (ossl_cmp_msg_get_bodytype(msg)) {
|
||||
case -1:
|
||||
return 0;
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
@@ -610,175 +794,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.2 DH Key Pairs
|
||||
* Not yet supported
|
||||
*/
|
||||
case NID_id_DHBasedMac:
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC);
|
||||
break;
|
||||
|
||||
/*
|
||||
* 5.1.3.3. Signature
|
||||
*/
|
||||
default:
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), NULL, &pk_nid)
|
||||
|| pk_nid == NID_undef) {
|
||||
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
|
||||
break;
|
||||
}
|
||||
/* validate sender name of received msg */
|
||||
if (msg->header->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
break; /* FR#42: support for more than X509_NAME */
|
||||
}
|
||||
/*
|
||||
* Compare actual sender name of response with expected sender name.
|
||||
* Expected name can be set explicitly or the subject of ctx->srvCert.
|
||||
* Mitigates risk to accept misused certificate of an unauthorized
|
||||
* entity of a trusted hierarchy.
|
||||
*/
|
||||
if (!check_name(ctx, "sender DN field",
|
||||
msg->header->sender->d.directoryName,
|
||||
"expected sender", ctx->expected_sender))
|
||||
break;
|
||||
/* Note: if recipient was NULL-DN it could be learned here if needed */
|
||||
|
||||
scrt = ctx->srvCert;
|
||||
if (scrt == NULL) {
|
||||
if (check_msg_find_cert(ctx, msg))
|
||||
return 1;
|
||||
} else { /* use pinned sender cert */
|
||||
/* use ctx->srvCert for signature check even if not acceptable */
|
||||
if (verify_signature(ctx, msg, scrt))
|
||||
return 1;
|
||||
/* call cert_acceptable() for adding diagnostic information */
|
||||
(void)cert_acceptable(ctx, "explicitly set", "sender cert", scrt,
|
||||
NULL, NULL, msg);
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* Check received message (i.e., response by server or request from client)
|
||||
* Any msg->extraCerts are prepended to ctx->untrusted_certs
|
||||
*
|
||||
* Ensures that:
|
||||
* it has a valid body type
|
||||
* its protection is valid (or invalid/absent, but only if a callback function
|
||||
* is present and yields a positive result using also the supplied argument)
|
||||
* its transaction ID matches the previous transaction ID stored in ctx (if any)
|
||||
* its recipNonce matches the previous senderNonce stored in the ctx (if any)
|
||||
*
|
||||
* If everything is fine:
|
||||
* learns the senderNonce from the received message,
|
||||
* learns the transaction ID if it is not yet in ctx.
|
||||
*
|
||||
* returns body type (which is >= 0) of the message on success, -1 on error
|
||||
*/
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
|
||||
{
|
||||
int rcvd_type;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && msg != NULL))
|
||||
return -1;
|
||||
|
||||
if (sk_X509_num(msg->extraCerts) > 10)
|
||||
ossl_cmp_warn(ctx,
|
||||
"received CMP message contains more than 10 extraCerts");
|
||||
|
||||
/* validate message protection */
|
||||
if (msg->header->protectionAlg != 0) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* detect explicitly permitted exceptions for missing protection */
|
||||
if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (msg->header->transactionID == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->transactionID,
|
||||
msg->header->transactionID) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare received nonce with the one we sent */
|
||||
if (ctx->senderNonce != NULL
|
||||
&& (msg->header->recipNonce == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->senderNonce,
|
||||
msg->header->recipNonce) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 4210 section 5.1.1 states: the recipNonce is copied from
|
||||
* the senderNonce of the previous message in the transaction.
|
||||
* --> Store for setting in next message
|
||||
*/
|
||||
if (!ossl_cmp_ctx_set1_recipNonce(ctx, msg->header->senderNonce))
|
||||
return -1;
|
||||
|
||||
/* if not yet present, learn transactionID */
|
||||
if (ctx->transactionID == NULL
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
|
||||
return rcvd_type;
|
||||
}
|
||||
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
|
||||
|
||||
@@ -52,6 +52,10 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO),
|
||||
"error setting recipientinfo"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE),
|
||||
"ess no signing certid attribute"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR),
|
||||
"ess signing certid mismatch error"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
|
||||
"invalid encrypted key length"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
|
||||
|
||||
+82
-10
@@ -21,6 +21,9 @@
|
||||
|
||||
DEFINE_STACK_OF(GENERAL_NAMES)
|
||||
DEFINE_STACK_OF(CMS_SignerInfo)
|
||||
DEFINE_STACK_OF(ESS_CERT_ID)
|
||||
DEFINE_STACK_OF(ESS_CERT_ID_V2)
|
||||
DEFINE_STACK_OF(X509)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
|
||||
@@ -29,33 +32,100 @@ IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
|
||||
{
|
||||
ASN1_STRING *str;
|
||||
CMS_ReceiptRequest *rr = NULL;
|
||||
if (prr)
|
||||
CMS_ReceiptRequest *rr;
|
||||
ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest);
|
||||
|
||||
if (prr != NULL)
|
||||
*prr = NULL;
|
||||
str = CMS_signed_get0_data_by_OBJ(si,
|
||||
OBJ_nid2obj
|
||||
(NID_id_smime_aa_receiptRequest), -3,
|
||||
V_ASN1_SEQUENCE);
|
||||
if (!str)
|
||||
str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
|
||||
if (!rr)
|
||||
if (rr == NULL)
|
||||
return -1;
|
||||
if (prr)
|
||||
if (prr != NULL)
|
||||
*prr = rr;
|
||||
else
|
||||
CMS_ReceiptRequest_free(rr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
First, get the ESS_SIGNING_CERT(V2) signed attribute from |si|.
|
||||
Then check matching of each cert of trust |chain| with one of
|
||||
the |cert_ids|(Hash+IssuerID) list from this ESS_SIGNING_CERT.
|
||||
Derived from ts_check_signing_certs()
|
||||
*/
|
||||
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain)
|
||||
{
|
||||
ESS_SIGNING_CERT *ss = NULL;
|
||||
ESS_SIGNING_CERT_V2 *ssv2 = NULL;
|
||||
X509 *cert;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
if (cms_signerinfo_get_signing_cert(si, &ss) > 0 && ss->cert_ids != NULL) {
|
||||
STACK_OF(ESS_CERT_ID) *cert_ids = ss->cert_ids;
|
||||
|
||||
cert = sk_X509_value(chain, 0);
|
||||
if (ess_find_cert(cert_ids, cert) != 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check the other certificates of the chain.
|
||||
* Fail if no signing certificate ids found for each certificate.
|
||||
*/
|
||||
if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
|
||||
/* for each chain cert, try to find its cert id */
|
||||
for (i = 1; i < sk_X509_num(chain); ++i) {
|
||||
cert = sk_X509_value(chain, i);
|
||||
if (ess_find_cert(cert_ids, cert) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else if (cms_signerinfo_get_signing_cert_v2(si, &ssv2) > 0
|
||||
&& ssv2->cert_ids!= NULL) {
|
||||
STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = ssv2->cert_ids;
|
||||
|
||||
cert = sk_X509_value(chain, 0);
|
||||
if (ess_find_cert_v2(cert_ids_v2, cert) != 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check the other certificates of the chain.
|
||||
* Fail if no signing certificate ids found for each certificate.
|
||||
*/
|
||||
if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
|
||||
/* for each chain cert, try to find its cert id */
|
||||
for (i = 1; i < sk_X509_num(chain); ++i) {
|
||||
cert = sk_X509_value(chain, i);
|
||||
if (ess_find_cert_v2(cert_ids_v2, cert) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS,
|
||||
CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE);
|
||||
return 0;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS,
|
||||
CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR);
|
||||
|
||||
ESS_SIGNING_CERT_free(ss);
|
||||
ESS_SIGNING_CERT_V2_free(ssv2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES)
|
||||
*receiptList, STACK_OF(GENERAL_NAMES)
|
||||
*receiptsTo)
|
||||
{
|
||||
CMS_ReceiptRequest *rr = NULL;
|
||||
CMS_ReceiptRequest *rr;
|
||||
|
||||
rr = CMS_ReceiptRequest_new();
|
||||
if (rr == NULL)
|
||||
@@ -145,6 +215,7 @@ static int cms_msgSigDigest(CMS_SignerInfo *si,
|
||||
unsigned char *dig, unsigned int *diglen)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
|
||||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
@@ -160,6 +231,7 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
|
||||
{
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
|
||||
if (!cms_msgSigDigest(src, dig, &diglen)) {
|
||||
CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
|
||||
return 0;
|
||||
|
||||
@@ -421,6 +421,9 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
/* SignerInfo routines */
|
||||
int CMS_si_check_attributes(const CMS_SignerInfo *si);
|
||||
|
||||
/* ESS routines */
|
||||
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
|
||||
|
||||
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
|
||||
DECLARE_ASN1_ITEM(CMS_DigestedData)
|
||||
DECLARE_ASN1_ITEM(CMS_EncryptedData)
|
||||
|
||||
+35
-6
@@ -233,7 +233,8 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
X509_STORE *store,
|
||||
STACK_OF(X509) *certs,
|
||||
STACK_OF(X509_CRL) *crls)
|
||||
STACK_OF(X509_CRL) *crls,
|
||||
STACK_OF(X509) **chain)
|
||||
{
|
||||
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
|
||||
X509 *signer;
|
||||
@@ -262,6 +263,10 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
goto err;
|
||||
}
|
||||
r = 1;
|
||||
|
||||
/* also send back the trust chain when required */
|
||||
if (chain != NULL)
|
||||
*chain = X509_STORE_CTX_get1_chain(ctx);
|
||||
err:
|
||||
X509_STORE_CTX_free(ctx);
|
||||
return r;
|
||||
@@ -275,9 +280,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||
STACK_OF(X509) *cms_certs = NULL;
|
||||
STACK_OF(X509_CRL) *crls = NULL;
|
||||
STACK_OF(X509) **si_chains = NULL;
|
||||
X509 *signer;
|
||||
int i, scount = 0, ret = 0;
|
||||
BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
|
||||
int cadesVerify = (flags & CMS_CADES) != 0;
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
return 0;
|
||||
@@ -312,27 +319,44 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
}
|
||||
|
||||
/* Attempt to verify all signers certs */
|
||||
/* at this point scount == sk_CMS_SignerInfo_num(sinfos) */
|
||||
|
||||
if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
|
||||
if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) {
|
||||
if (cadesVerify) {
|
||||
/* Certificate trust chain is required to check CAdES signature */
|
||||
si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0]));
|
||||
if (si_chains == NULL) {
|
||||
CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
cms_certs = CMS_get1_certs(cms);
|
||||
if (!(flags & CMS_NOCRL))
|
||||
crls = CMS_get1_crls(cms);
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
for (i = 0; i < scount; i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
|
||||
|
||||
if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls,
|
||||
si_chains ? &si_chains[i] : NULL))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt to verify all SignerInfo signed attribute signatures */
|
||||
|
||||
if (!(flags & CMS_NO_ATTR_VERIFY)) {
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) {
|
||||
for (i = 0; i < scount; i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (CMS_signed_get_attr_count(si) < 0)
|
||||
continue;
|
||||
if (CMS_SignerInfo_verify(si) <= 0)
|
||||
goto err;
|
||||
if (cadesVerify) {
|
||||
STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL;
|
||||
|
||||
if (ess_check_signing_certs(si, si_chain) <= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,6 +444,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
BIO_free_all(tmpout);
|
||||
|
||||
err2:
|
||||
if (si_chains != NULL) {
|
||||
for (i = 0; i < scount; ++i)
|
||||
sk_X509_pop_free(si_chains[i], X509_free);
|
||||
OPENSSL_free(si_chains);
|
||||
}
|
||||
sk_X509_pop_free(cms_certs, X509_free);
|
||||
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||
|
||||
|
||||
@@ -516,25 +516,23 @@ void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
|
||||
|
||||
char *CONF_get1_default_config_file(void)
|
||||
{
|
||||
const char *t;
|
||||
char *file, *sep = "";
|
||||
int len;
|
||||
size_t size;
|
||||
|
||||
if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL)
|
||||
return OPENSSL_strdup(file);
|
||||
|
||||
len = strlen(X509_get_default_cert_area());
|
||||
t = X509_get_default_cert_area();
|
||||
#ifndef OPENSSL_SYS_VMS
|
||||
len++;
|
||||
sep = "/";
|
||||
#endif
|
||||
len += strlen(OPENSSL_CONF);
|
||||
|
||||
file = OPENSSL_malloc(len + 1);
|
||||
size = strlen(t) + strlen(sep) + strlen(OPENSSL_CONF) + 1;
|
||||
file = OPENSSL_malloc(size);
|
||||
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
BIO_snprintf(file, len + 1, "%s%s%s", X509_get_default_cert_area(),
|
||||
sep, OPENSSL_CONF);
|
||||
BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
+44
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -16,8 +16,11 @@
|
||||
struct algorithm_data_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
int operation_id; /* May be zero for finding them all */
|
||||
int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result);
|
||||
void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store,
|
||||
void *data);
|
||||
int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data,
|
||||
int *result);
|
||||
void *data;
|
||||
};
|
||||
|
||||
@@ -36,19 +39,48 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
for (cur_operation = first_operation;
|
||||
cur_operation <= last_operation;
|
||||
cur_operation++) {
|
||||
const OSSL_ALGORITHM *map =
|
||||
ossl_provider_query_operation(provider, cur_operation,
|
||||
&no_store);
|
||||
const OSSL_ALGORITHM *map = NULL;
|
||||
int ret;
|
||||
|
||||
/* Do we fulfill pre-conditions? */
|
||||
if (data->pre == NULL) {
|
||||
/* If there is no pre-condition function, assume "yes" */
|
||||
ret = 1;
|
||||
} else {
|
||||
if (!data->pre(provider, cur_operation, data->data, &ret))
|
||||
/* Error, bail out! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If pre-condition not fulfilled, go to the next operation */
|
||||
if (!ret)
|
||||
continue;
|
||||
|
||||
map = ossl_provider_query_operation(provider, cur_operation,
|
||||
&no_store);
|
||||
if (map == NULL)
|
||||
continue;
|
||||
|
||||
ok = 1; /* As long as we've found *something* */
|
||||
while (map->algorithm_names != NULL) {
|
||||
const OSSL_ALGORITHM *thismap = map++;
|
||||
|
||||
data->fn(provider, thismap, no_store, data->data);
|
||||
}
|
||||
|
||||
/* Do we fulfill post-conditions? */
|
||||
if (data->post == NULL) {
|
||||
/* If there is no post-condition function, assume "yes" */
|
||||
ret = 1;
|
||||
} else {
|
||||
if (!data->post(provider, cur_operation, no_store, data->data,
|
||||
&ret))
|
||||
/* Error, bail out! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If post-condition fulfilled, set general success */
|
||||
if (ret)
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
return ok;
|
||||
@@ -56,16 +88,22 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
|
||||
void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
OSSL_PROVIDER *provider,
|
||||
int (*pre)(OSSL_PROVIDER *, int operation_id,
|
||||
void *data, int *result),
|
||||
void (*fn)(OSSL_PROVIDER *provider,
|
||||
const OSSL_ALGORITHM *algo,
|
||||
int no_store, void *data),
|
||||
int (*post)(OSSL_PROVIDER *, int operation_id,
|
||||
int no_store, void *data, int *result),
|
||||
void *data)
|
||||
{
|
||||
struct algorithm_data_st cbdata;
|
||||
struct algorithm_data_st cbdata = { 0, };
|
||||
|
||||
cbdata.libctx = libctx;
|
||||
cbdata.operation_id = operation_id;
|
||||
cbdata.pre = pre;
|
||||
cbdata.fn = fn;
|
||||
cbdata.post = post;
|
||||
cbdata.data = data;
|
||||
|
||||
if (provider == NULL)
|
||||
|
||||
+41
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -24,6 +24,42 @@ struct construct_data_st {
|
||||
void *mcm_data;
|
||||
};
|
||||
|
||||
static int ossl_method_construct_precondition(OSSL_PROVIDER *provider,
|
||||
int operation_id, void *cbdata,
|
||||
int *result)
|
||||
{
|
||||
if (!ossl_assert(result != NULL)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ossl_provider_test_operation_bit(provider, operation_id, result))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The result we get tells if methods have already been constructed.
|
||||
* However, we want to tell whether construction should happen (true)
|
||||
* or not (false), which is the opposite of what we got.
|
||||
*/
|
||||
*result = !*result;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider,
|
||||
int operation_id, int no_store,
|
||||
void *cbdata, int *result)
|
||||
{
|
||||
if (!ossl_assert(result != NULL)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = 1;
|
||||
return no_store != 0
|
||||
|| ossl_provider_set_operation_bit(provider, operation_id);
|
||||
}
|
||||
|
||||
static void ossl_method_construct_this(OSSL_PROVIDER *provider,
|
||||
const OSSL_ALGORITHM *algo,
|
||||
int no_store, void *cbdata)
|
||||
@@ -86,7 +122,10 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
|
||||
cbdata.mcm = mcm;
|
||||
cbdata.mcm_data = mcm_data;
|
||||
ossl_algorithm_do_all(libctx, operation_id, NULL,
|
||||
ossl_method_construct_this, &cbdata);
|
||||
ossl_method_construct_precondition,
|
||||
ossl_method_construct_this,
|
||||
ossl_method_construct_postcondition,
|
||||
&cbdata);
|
||||
|
||||
method = mcm->get(libctx, cbdata.store, mcm_data);
|
||||
mcm->dealloc_tmp_store(cbdata.store);
|
||||
|
||||
+1
-20
@@ -461,25 +461,6 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 0 for equal, -1 for a < b or error on a, 1 for a > b or error on b */
|
||||
static int X509_PUBKEY_cmp(X509_PUBKEY *a, X509_PUBKEY *b)
|
||||
{
|
||||
X509_ALGOR *algA = NULL, *algB = NULL;
|
||||
int res = 0;
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (a == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a)
|
||||
|| algA == NULL)
|
||||
return -1;
|
||||
if (b == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b)
|
||||
|| algB == NULL)
|
||||
return 1;
|
||||
if ((res = X509_ALGOR_cmp(algA, algB)) != 0)
|
||||
return res;
|
||||
return EVP_PKEY_cmp(X509_PUBKEY_get0(a), X509_PUBKEY_get0(b));
|
||||
}
|
||||
|
||||
/* verifies the Proof-of-Possession of the request with the given rid in reqs */
|
||||
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
int rid, int acceptRAVerified)
|
||||
@@ -522,7 +503,7 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) {
|
||||
if (X509_PUBKEY_eq(pubkey, sig->poposkInput->publicKey) != 1) {
|
||||
CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ struct ossl_crmf_certid_st {
|
||||
GENERAL_NAME *issuer;
|
||||
ASN1_INTEGER *serialNumber;
|
||||
} /* OSSL_CRMF_CERTID */;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
* SinglePubInfo ::= SEQUENCE {
|
||||
|
||||
@@ -202,8 +202,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||
macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
basekey, bklen);
|
||||
if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
|
||||
|| (mctx = EVP_MAC_CTX_new(mac)) == NULL
|
||||
|| !EVP_MAC_CTX_set_params(mctx, macparams)
|
||||
|| (mctx = EVP_MAC_new_ctx(mac)) == NULL
|
||||
|| !EVP_MAC_set_ctx_params(mctx, macparams)
|
||||
|| !EVP_MAC_init(mctx)
|
||||
|| !EVP_MAC_update(mctx, msg, msglen)
|
||||
|| !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
|
||||
@@ -214,7 +214,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||
err:
|
||||
/* cleanup */
|
||||
OPENSSL_cleanse(basekey, bklen);
|
||||
EVP_MAC_CTX_free(mctx);
|
||||
EVP_MAC_free_ctx(mctx);
|
||||
EVP_MAC_free(mac);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ static void int_dh_free(EVP_PKEY *pkey)
|
||||
DH_free(pkey->pkey.dh);
|
||||
}
|
||||
|
||||
static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p, *pm;
|
||||
int pklen, pmlen;
|
||||
@@ -438,7 +438,7 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1);
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2);
|
||||
return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1);
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA DH_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_FFC_PARAMETERS), "bad ffc parameters"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error"},
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ int dh_get_named_group_uid_from_size(int pbits)
|
||||
* Just choose an approved safe prime group.
|
||||
* The alternative to this is to generate FIPS186-4 domain parameters i.e.
|
||||
* return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb);
|
||||
* As the FIPS186-4 generated params are for backwards compatability,
|
||||
* As the FIPS186-4 generated params are for backwards compatibility,
|
||||
* the safe prime group should be used as the default.
|
||||
*/
|
||||
int nid;
|
||||
|
||||
+3
-3
@@ -46,7 +46,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
|
||||
return 0;
|
||||
|
||||
kdf = EVP_KDF_fetch(provctx, OSSL_KDF_NAME_X942KDF, NULL);
|
||||
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL)
|
||||
if ((kctx = EVP_KDF_new_ctx(kdf)) == NULL)
|
||||
goto err;
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, 0);
|
||||
@@ -58,10 +58,10 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
|
||||
(char *)oid_sn, 0);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) > 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) > 0
|
||||
&& EVP_KDF_derive(kctx, out, outlen) > 0;
|
||||
err:
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
EVP_KDF_free(kdf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+13
-3
@@ -351,10 +351,10 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, int alloc)
|
||||
{
|
||||
const BIGNUM *pubkey;
|
||||
unsigned char *pbuf;
|
||||
unsigned char *pbuf = NULL;
|
||||
const BIGNUM *p;
|
||||
int p_size;
|
||||
|
||||
@@ -366,7 +366,15 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
|
||||
DHerr(DH_F_DH_KEY2BUF, DH_R_INVALID_PUBKEY);
|
||||
return 0;
|
||||
}
|
||||
if ((pbuf = OPENSSL_malloc(p_size)) == NULL) {
|
||||
if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) {
|
||||
if (!alloc) {
|
||||
if (size >= (size_t)p_size)
|
||||
pbuf = *pbuf_out;
|
||||
} else {
|
||||
pbuf = OPENSSL_malloc(p_size);
|
||||
}
|
||||
|
||||
if (pbuf == NULL) {
|
||||
DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@@ -375,10 +383,12 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
|
||||
* key with zeros to the size of p
|
||||
*/
|
||||
if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
|
||||
if (alloc)
|
||||
OPENSSL_free(pbuf);
|
||||
DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
|
||||
return 0;
|
||||
}
|
||||
*pbuf_out = pbuf;
|
||||
}
|
||||
return p_size;
|
||||
}
|
||||
+3
-3
@@ -475,7 +475,7 @@ int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
|
||||
EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL);
|
||||
#endif
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GENERATOR, &gen);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
@@ -500,7 +500,7 @@ int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP,
|
||||
(void *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
@@ -531,7 +531,7 @@ int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP,
|
||||
(void *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
|
||||
@@ -58,6 +58,3 @@ struct dh_method {
|
||||
int (*generate_params) (DH *dh, int prime_len, int generator,
|
||||
BN_GENCB *cb);
|
||||
};
|
||||
|
||||
int dh_buf2key(DH *key, const unsigned char *buf, size_t len);
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf);
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "internal/ffc.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p, *pm;
|
||||
int pklen, pmlen;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA DSA_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_FFC_PARAMETERS), "bad ffc parameters"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_ERROR), "bn error"},
|
||||
|
||||
@@ -221,7 +221,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
dctx->nbits, dctx->qbits, dctx->pmd,
|
||||
&res, pcb);
|
||||
BN_GENCB_free(pcb);
|
||||
if (ret)
|
||||
if (ret > 0)
|
||||
EVP_PKEY_assign_DSA(pkey, dsa);
|
||||
else
|
||||
DSA_free(dsa);
|
||||
|
||||
@@ -1,2082 +0,0 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright (c) 2014, Intel Corporation. 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
|
||||
#
|
||||
# Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
|
||||
# (1) Intel Corporation, Israel Development Center, Haifa, Israel
|
||||
# (2) University of Haifa, Israel
|
||||
#
|
||||
# Reference:
|
||||
# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
|
||||
# 256 Bit Primes"
|
||||
|
||||
# $output is the last argument if it looks like a file (it has an extension)
|
||||
# $flavour is the first argument if it doesn't look like a file
|
||||
$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
|
||||
$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
|
||||
|
||||
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour \"$output\""
|
||||
or die "can't call $xlate: $!";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
|
||||
$avx = ($1>=2.19) + ($1>=2.22);
|
||||
$addx = ($1>=2.23);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
|
||||
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
|
||||
$avx = ($1>=2.09) + ($1>=2.10);
|
||||
$addx = ($1>=2.10);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
|
||||
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
|
||||
$avx = ($1>=10) + ($1>=11);
|
||||
$addx = ($1>=12);
|
||||
}
|
||||
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) {
|
||||
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
|
||||
$avx = ($ver>=3.0) + ($ver>=3.01);
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
||||
if ($avx>=2) {{
|
||||
$digit_size = "\$29";
|
||||
$n_digits = "\$9";
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.align 64
|
||||
.LAVX2_AND_MASK:
|
||||
.LAVX2_POLY:
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00040000, 0x00040000, 0x00040000, 0x00040000
|
||||
.quad 0x1fe00000, 0x1fe00000, 0x1fe00000, 0x1fe00000
|
||||
.quad 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff
|
||||
|
||||
.LAVX2_POLY_x2:
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x400007FC, 0x400007FC, 0x400007FC, 0x400007FC
|
||||
.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
|
||||
.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
|
||||
.quad 0x400FFFFE, 0x400FFFFE, 0x400FFFFE, 0x400FFFFE
|
||||
.quad 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE
|
||||
.quad 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC
|
||||
|
||||
.LAVX2_POLY_x8:
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0x80000FF8, 0x80000FF8, 0x80000FF8, 0x80000FF8
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x801FFFFC, 0x801FFFFC, 0x801FFFFC, 0x801FFFFC
|
||||
.quad 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC
|
||||
.quad 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8
|
||||
|
||||
.LONE:
|
||||
.quad 0x00000020, 0x00000020, 0x00000020, 0x00000020
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1fffc000, 0x1fffc000, 0x1fffc000, 0x1fffc000
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1f7fffff, 0x1f7fffff, 0x1f7fffff, 0x1f7fffff
|
||||
.quad 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
# RR = 2^266 mod p in AVX2 format, to transform from the native OpenSSL
|
||||
# Montgomery form (*2^256) to our format (*2^261)
|
||||
|
||||
.LTO_MONT_AVX2:
|
||||
.quad 0x00000400, 0x00000400, 0x00000400, 0x00000400
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1ff80000, 0x1ff80000, 0x1ff80000, 0x1ff80000
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x00000003, 0x00000003, 0x00000003, 0x00000003
|
||||
|
||||
.LFROM_MONT_AVX2:
|
||||
.quad 0x00000001, 0x00000001, 0x00000001, 0x00000001
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1ffffe00, 0x1ffffe00, 0x1ffffe00, 0x1ffffe00
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1ffbffff, 0x1ffbffff, 0x1ffbffff, 0x1ffbffff
|
||||
.quad 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
.LIntOne:
|
||||
.long 1,1,1,1,1,1,1,1
|
||||
___
|
||||
|
||||
{
|
||||
# This function receives a pointer to an array of four affine points
|
||||
# (X, Y, <1>) and rearranges the data for AVX2 execution, while
|
||||
# converting it to 2^29 radix redundant form
|
||||
|
||||
my ($X0,$X1,$X2,$X3, $Y0,$Y1,$Y2,$Y3,
|
||||
$T0,$T1,$T2,$T3, $T4,$T5,$T6,$T7)=map("%ymm$_",(0..15));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_transpose_convert
|
||||
.type ecp_nistz256_avx2_transpose_convert,\@function,2
|
||||
.align 64
|
||||
ecp_nistz256_avx2_transpose_convert:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
# Load the data
|
||||
vmovdqa 32*0(%rsi), $X0
|
||||
lea 112(%rsi), %rax # size optimization
|
||||
vmovdqa 32*1(%rsi), $Y0
|
||||
lea .LAVX2_AND_MASK(%rip), %rdx
|
||||
vmovdqa 32*2(%rsi), $X1
|
||||
vmovdqa 32*3(%rsi), $Y1
|
||||
vmovdqa 32*4-112(%rax), $X2
|
||||
vmovdqa 32*5-112(%rax), $Y2
|
||||
vmovdqa 32*6-112(%rax), $X3
|
||||
vmovdqa 32*7-112(%rax), $Y3
|
||||
|
||||
# Transpose X and Y independently
|
||||
vpunpcklqdq $X1, $X0, $T0 # T0 = [B2 A2 B0 A0]
|
||||
vpunpcklqdq $X3, $X2, $T1 # T1 = [D2 C2 D0 C0]
|
||||
vpunpckhqdq $X1, $X0, $T2 # T2 = [B3 A3 B1 A1]
|
||||
vpunpckhqdq $X3, $X2, $T3 # T3 = [D3 C3 D1 C1]
|
||||
|
||||
vpunpcklqdq $Y1, $Y0, $T4
|
||||
vpunpcklqdq $Y3, $Y2, $T5
|
||||
vpunpckhqdq $Y1, $Y0, $T6
|
||||
vpunpckhqdq $Y3, $Y2, $T7
|
||||
|
||||
vperm2i128 \$0x20, $T1, $T0, $X0 # X0 = [D0 C0 B0 A0]
|
||||
vperm2i128 \$0x20, $T3, $T2, $X1 # X1 = [D1 C1 B1 A1]
|
||||
vperm2i128 \$0x31, $T1, $T0, $X2 # X2 = [D2 C2 B2 A2]
|
||||
vperm2i128 \$0x31, $T3, $T2, $X3 # X3 = [D3 C3 B3 A3]
|
||||
|
||||
vperm2i128 \$0x20, $T5, $T4, $Y0
|
||||
vperm2i128 \$0x20, $T7, $T6, $Y1
|
||||
vperm2i128 \$0x31, $T5, $T4, $Y2
|
||||
vperm2i128 \$0x31, $T7, $T6, $Y3
|
||||
vmovdqa (%rdx), $T7
|
||||
|
||||
vpand (%rdx), $X0, $T0 # out[0] = in[0] & mask;
|
||||
vpsrlq \$29, $X0, $X0
|
||||
vpand $T7, $X0, $T1 # out[1] = (in[0] >> shift) & mask;
|
||||
vpsrlq \$29, $X0, $X0
|
||||
vpsllq \$6, $X1, $T2
|
||||
vpxor $X0, $T2, $T2
|
||||
vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
|
||||
vpsrlq \$23, $X1, $X1
|
||||
vpand $T7, $X1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask;
|
||||
vpsrlq \$29, $X1, $X1
|
||||
vpsllq \$12, $X2, $T4
|
||||
vpxor $X1, $T4, $T4
|
||||
vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
|
||||
vpsrlq \$17, $X2, $X2
|
||||
vpand $T7, $X2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask;
|
||||
vpsrlq \$29, $X2, $X2
|
||||
vpsllq \$18, $X3, $T6
|
||||
vpxor $X2, $T6, $T6
|
||||
vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
|
||||
vpsrlq \$11, $X3, $X3
|
||||
vmovdqa $T0, 32*0(%rdi)
|
||||
lea 112(%rdi), %rax # size optimization
|
||||
vpand $T7, $X3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask;
|
||||
vpsrlq \$29, $X3, $X3 # out[8] = (in[3] >> ((shift*8)%64)) & mask;
|
||||
|
||||
vmovdqa $T1, 32*1(%rdi)
|
||||
vmovdqa $T2, 32*2(%rdi)
|
||||
vmovdqa $T3, 32*3(%rdi)
|
||||
vmovdqa $T4, 32*4-112(%rax)
|
||||
vmovdqa $T5, 32*5-112(%rax)
|
||||
vmovdqa $T6, 32*6-112(%rax)
|
||||
vmovdqa $T0, 32*7-112(%rax)
|
||||
vmovdqa $X3, 32*8-112(%rax)
|
||||
lea 448(%rdi), %rax # size optimization
|
||||
|
||||
vpand $T7, $Y0, $T0 # out[0] = in[0] & mask;
|
||||
vpsrlq \$29, $Y0, $Y0
|
||||
vpand $T7, $Y0, $T1 # out[1] = (in[0] >> shift) & mask;
|
||||
vpsrlq \$29, $Y0, $Y0
|
||||
vpsllq \$6, $Y1, $T2
|
||||
vpxor $Y0, $T2, $T2
|
||||
vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
|
||||
vpsrlq \$23, $Y1, $Y1
|
||||
vpand $T7, $Y1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask;
|
||||
vpsrlq \$29, $Y1, $Y1
|
||||
vpsllq \$12, $Y2, $T4
|
||||
vpxor $Y1, $T4, $T4
|
||||
vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
|
||||
vpsrlq \$17, $Y2, $Y2
|
||||
vpand $T7, $Y2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask;
|
||||
vpsrlq \$29, $Y2, $Y2
|
||||
vpsllq \$18, $Y3, $T6
|
||||
vpxor $Y2, $T6, $T6
|
||||
vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
|
||||
vpsrlq \$11, $Y3, $Y3
|
||||
vmovdqa $T0, 32*9-448(%rax)
|
||||
vpand $T7, $Y3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask;
|
||||
vpsrlq \$29, $Y3, $Y3 # out[8] = (in[3] >> ((shift*8)%64)) & mask;
|
||||
|
||||
vmovdqa $T1, 32*10-448(%rax)
|
||||
vmovdqa $T2, 32*11-448(%rax)
|
||||
vmovdqa $T3, 32*12-448(%rax)
|
||||
vmovdqa $T4, 32*13-448(%rax)
|
||||
vmovdqa $T5, 32*14-448(%rax)
|
||||
vmovdqa $T6, 32*15-448(%rax)
|
||||
vmovdqa $T0, 32*16-448(%rax)
|
||||
vmovdqa $Y3, 32*17-448(%rax)
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_transpose_convert,.-ecp_nistz256_avx2_transpose_convert
|
||||
___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# This function receives a pointer to an array of four AVX2 formatted points
|
||||
# (X, Y, Z) convert the data to normal representation, and rearranges the data
|
||||
|
||||
my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8));
|
||||
my ($T0,$T1,$T2,$T3, $T4,$T5,$T6)=map("%ymm$_",(9..15));
|
||||
|
||||
$code.=<<___;
|
||||
|
||||
.globl ecp_nistz256_avx2_convert_transpose_back
|
||||
.type ecp_nistz256_avx2_convert_transpose_back,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_convert_transpose_back:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov \$3, %ecx
|
||||
|
||||
.Lconv_loop:
|
||||
vmovdqa 32*0(%rsi), $D0
|
||||
lea 160(%rsi), %rax # size optimization
|
||||
vmovdqa 32*1(%rsi), $D1
|
||||
vmovdqa 32*2(%rsi), $D2
|
||||
vmovdqa 32*3(%rsi), $D3
|
||||
vmovdqa 32*4-160(%rax), $D4
|
||||
vmovdqa 32*5-160(%rax), $D5
|
||||
vmovdqa 32*6-160(%rax), $D6
|
||||
vmovdqa 32*7-160(%rax), $D7
|
||||
vmovdqa 32*8-160(%rax), $D8
|
||||
|
||||
vpsllq \$29, $D1, $D1
|
||||
vpsllq \$58, $D2, $T0
|
||||
vpaddq $D1, $D0, $D0
|
||||
vpaddq $T0, $D0, $D0 # out[0] = (in[0]) ^ (in[1] << shift*1) ^ (in[2] << shift*2);
|
||||
|
||||
vpsrlq \$6, $D2, $D2
|
||||
vpsllq \$23, $D3, $D3
|
||||
vpsllq \$52, $D4, $T1
|
||||
vpaddq $D2, $D3, $D3
|
||||
vpaddq $D3, $T1, $D1 # out[1] = (in[2] >> (64*1-shift*2)) ^ (in[3] << shift*3%64) ^ (in[4] << shift*4%64);
|
||||
|
||||
vpsrlq \$12, $D4, $D4
|
||||
vpsllq \$17, $D5, $D5
|
||||
vpsllq \$46, $D6, $T2
|
||||
vpaddq $D4, $D5, $D5
|
||||
vpaddq $D5, $T2, $D2 # out[2] = (in[4] >> (64*2-shift*4)) ^ (in[5] << shift*5%64) ^ (in[6] << shift*6%64);
|
||||
|
||||
vpsrlq \$18, $D6, $D6
|
||||
vpsllq \$11, $D7, $D7
|
||||
vpsllq \$40, $D8, $T3
|
||||
vpaddq $D6, $D7, $D7
|
||||
vpaddq $D7, $T3, $D3 # out[3] = (in[6] >> (64*3-shift*6)) ^ (in[7] << shift*7%64) ^ (in[8] << shift*8%64);
|
||||
|
||||
vpunpcklqdq $D1, $D0, $T0 # T0 = [B2 A2 B0 A0]
|
||||
vpunpcklqdq $D3, $D2, $T1 # T1 = [D2 C2 D0 C0]
|
||||
vpunpckhqdq $D1, $D0, $T2 # T2 = [B3 A3 B1 A1]
|
||||
vpunpckhqdq $D3, $D2, $T3 # T3 = [D3 C3 D1 C1]
|
||||
|
||||
vperm2i128 \$0x20, $T1, $T0, $D0 # X0 = [D0 C0 B0 A0]
|
||||
vperm2i128 \$0x20, $T3, $T2, $D1 # X1 = [D1 C1 B1 A1]
|
||||
vperm2i128 \$0x31, $T1, $T0, $D2 # X2 = [D2 C2 B2 A2]
|
||||
vperm2i128 \$0x31, $T3, $T2, $D3 # X3 = [D3 C3 B3 A3]
|
||||
|
||||
vmovdqa $D0, 32*0(%rdi)
|
||||
vmovdqa $D1, 32*3(%rdi)
|
||||
vmovdqa $D2, 32*6(%rdi)
|
||||
vmovdqa $D3, 32*9(%rdi)
|
||||
|
||||
lea 32*9(%rsi), %rsi
|
||||
lea 32*1(%rdi), %rdi
|
||||
|
||||
dec %ecx
|
||||
jnz .Lconv_loop
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_convert_transpose_back,.-ecp_nistz256_avx2_convert_transpose_back
|
||||
___
|
||||
}
|
||||
{
|
||||
my ($r_ptr,$a_ptr,$b_ptr,$itr)=("%rdi","%rsi","%rdx","%ecx");
|
||||
my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4,$ACC5,$ACC6,$ACC7,$ACC8)=map("%ymm$_",(0..8));
|
||||
my ($B,$Y,$T0,$AND_MASK,$OVERFLOW)=map("%ymm$_",(9..13));
|
||||
|
||||
sub NORMALIZE {
|
||||
my $ret=<<___;
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
___
|
||||
$ret;
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my $ret=<<___;
|
||||
vmovdqa $ACC0, 32*0(%rdi)
|
||||
lea 160(%rdi), %rax # size optimization
|
||||
vmovdqa $ACC1, 32*1(%rdi)
|
||||
vmovdqa $ACC2, 32*2(%rdi)
|
||||
vmovdqa $ACC3, 32*3(%rdi)
|
||||
vmovdqa $ACC4, 32*4-160(%rax)
|
||||
vmovdqa $ACC5, 32*5-160(%rax)
|
||||
vmovdqa $ACC6, 32*6-160(%rax)
|
||||
vmovdqa $ACC7, 32*7-160(%rax)
|
||||
vmovdqa $ACC8, 32*8-160(%rax)
|
||||
___
|
||||
$ret;
|
||||
}
|
||||
|
||||
$code.=<<___;
|
||||
.type avx2_normalize,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_normalize:
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_normalize,.-avx2_normalize
|
||||
|
||||
.type avx2_normalize_n_store,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_normalize_n_store:
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vmovdqa $ACC0, 32*0(%rdi)
|
||||
lea 160(%rdi), %rax # size optimization
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vmovdqa $ACC1, 32*1(%rdi)
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vmovdqa $ACC2, 32*2(%rdi)
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vmovdqa $ACC3, 32*3(%rdi)
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vmovdqa $ACC4, 32*4-160(%rax)
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vmovdqa $ACC5, 32*5-160(%rax)
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vmovdqa $ACC6, 32*6-160(%rax)
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
vmovdqa $ACC7, 32*7-160(%rax)
|
||||
vmovdqa $ACC8, 32*8-160(%rax)
|
||||
|
||||
ret
|
||||
.size avx2_normalize_n_store,.-avx2_normalize_n_store
|
||||
|
||||
################################################################################
|
||||
# void avx2_mul_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_mul_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vpxor $ACC0, $ACC0, $ACC0
|
||||
vpxor $ACC1, $ACC1, $ACC1
|
||||
vpxor $ACC2, $ACC2, $ACC2
|
||||
vpxor $ACC3, $ACC3, $ACC3
|
||||
vpxor $ACC4, $ACC4, $ACC4
|
||||
vpxor $ACC5, $ACC5, $ACC5
|
||||
vpxor $ACC6, $ACC6, $ACC6
|
||||
vpxor $ACC7, $ACC7, $ACC7
|
||||
|
||||
vmovdqa 32*7(%rax), %ymm14
|
||||
vmovdqa 32*8(%rax), %ymm15
|
||||
|
||||
mov $n_digits, $itr
|
||||
lea -512($a_ptr), $a_ptr # strategic bias to control u-op density
|
||||
jmp .Lavx2_mul_x4_loop
|
||||
|
||||
.align 32
|
||||
.Lavx2_mul_x4_loop:
|
||||
vmovdqa 32*0($b_ptr), $B
|
||||
lea 32*1($b_ptr), $b_ptr
|
||||
|
||||
vpmuludq 32*0+512($a_ptr), $B, $T0
|
||||
vpmuludq 32*1+512($a_ptr), $B, $OVERFLOW # borrow $OVERFLOW
|
||||
vpaddq $T0, $ACC0, $ACC0
|
||||
vpmuludq 32*2+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC1, $ACC1
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*3+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*4+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*5+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*6+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*7+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
# Skip some multiplications, optimizing for the constant poly
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*8+512($a_ptr), $B, $ACC8
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
.byte 0x67
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $OVERFLOW
|
||||
.byte 0x67
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC7, $ACC6
|
||||
vpaddq $OVERFLOW, $ACC8, $ACC7
|
||||
|
||||
dec $itr
|
||||
jnz .Lavx2_mul_x4_loop
|
||||
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_mul_x4,.-avx2_mul_x4
|
||||
|
||||
# Function optimized for the constant 1
|
||||
################################################################################
|
||||
# void avx2_mul_by1_x4(void* RESULTx4, void *Ax4);
|
||||
.type avx2_mul_by1_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_by1_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vpxor $ACC0, $ACC0, $ACC0
|
||||
vpxor $ACC1, $ACC1, $ACC1
|
||||
vpxor $ACC2, $ACC2, $ACC2
|
||||
vpxor $ACC3, $ACC3, $ACC3
|
||||
vpxor $ACC4, $ACC4, $ACC4
|
||||
vpxor $ACC5, $ACC5, $ACC5
|
||||
vpxor $ACC6, $ACC6, $ACC6
|
||||
vpxor $ACC7, $ACC7, $ACC7
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
vmovdqa 32*3+.LONE(%rip), %ymm14
|
||||
vmovdqa 32*7+.LONE(%rip), %ymm15
|
||||
|
||||
mov $n_digits, $itr
|
||||
jmp .Lavx2_mul_by1_x4_loop
|
||||
|
||||
.align 32
|
||||
.Lavx2_mul_by1_x4_loop:
|
||||
vmovdqa 32*0($a_ptr), $B
|
||||
.byte 0x48,0x8d,0xb6,0x20,0,0,0 # lea 32*1($a_ptr), $a_ptr
|
||||
|
||||
vpsllq \$5, $B, $OVERFLOW
|
||||
vpmuludq %ymm14, $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
.byte 0x67
|
||||
vpmuludq $AND_MASK, $B, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
vpsllq \$23, $B, $T0
|
||||
|
||||
.byte 0x67,0x67
|
||||
vpmuludq %ymm15, $B, $OVERFLOW
|
||||
vpsubq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
.byte 0x67,0x67
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $OVERFLOW
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq 32*7(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC6, $ACC5
|
||||
vpaddq $T0, $ACC7, $ACC6
|
||||
vpmuludq 32*8(%rax), $Y, $ACC7
|
||||
|
||||
dec $itr
|
||||
jnz .Lavx2_mul_by1_x4_loop
|
||||
|
||||
ret
|
||||
.size avx2_mul_by1_x4,.-avx2_mul_by1_x4
|
||||
|
||||
################################################################################
|
||||
# void avx2_sqr_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_sqr_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_sqr_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vmovdqa 32*7(%rax), %ymm14
|
||||
vmovdqa 32*8(%rax), %ymm15
|
||||
|
||||
vmovdqa 32*0($a_ptr), $B
|
||||
vmovdqa 32*1($a_ptr), $ACC1
|
||||
vmovdqa 32*2($a_ptr), $ACC2
|
||||
vmovdqa 32*3($a_ptr), $ACC3
|
||||
vmovdqa 32*4($a_ptr), $ACC4
|
||||
vmovdqa 32*5($a_ptr), $ACC5
|
||||
vmovdqa 32*6($a_ptr), $ACC6
|
||||
vmovdqa 32*7($a_ptr), $ACC7
|
||||
vpaddq $ACC1, $ACC1, $ACC1 # 2*$ACC0..7
|
||||
vmovdqa 32*8($a_ptr), $ACC8
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vmovdqa $ACC1, 32*0(%rcx)
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vmovdqa $ACC2, 32*1(%rcx)
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vmovdqa $ACC3, 32*2(%rcx)
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vmovdqa $ACC4, 32*3(%rcx)
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vmovdqa $ACC5, 32*4(%rcx)
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vmovdqa $ACC6, 32*5(%rcx)
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
vmovdqa $ACC7, 32*6(%rcx)
|
||||
vmovdqa $ACC8, 32*7(%rcx)
|
||||
|
||||
#itr 1
|
||||
vpmuludq $B, $B, $ACC0
|
||||
vpmuludq $B, $ACC1, $ACC1
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq $B, $ACC2, $ACC2
|
||||
vpmuludq $B, $ACC3, $ACC3
|
||||
vpmuludq $B, $ACC4, $ACC4
|
||||
vpmuludq $B, $ACC5, $ACC5
|
||||
vpmuludq $B, $ACC6, $ACC6
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpmuludq $B, $ACC7, $ACC7
|
||||
vpmuludq $B, $ACC8, $ACC8
|
||||
vmovdqa 32*1($a_ptr), $B
|
||||
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 2
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*1(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC1, $ACC1
|
||||
vpmuludq 32*2(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*2($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 3
|
||||
vpmuludq $B, $B, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*2(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*3($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 4
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*4($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 5
|
||||
vpmuludq $B, $B, $T0
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*5($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3+.LAVX2_POLY(%rip), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 6
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*6($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 7
|
||||
vpmuludq $B, $B, $T0
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*7($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 8
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*8($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 9
|
||||
vpmuludq $B, $B, $ACC8
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_sqr_x4,.-avx2_sqr_x4
|
||||
|
||||
################################################################################
|
||||
# void avx2_sub_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_sub_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_sub_x4:
|
||||
vmovdqa 32*0($a_ptr), $ACC0
|
||||
lea 160($a_ptr), $a_ptr
|
||||
lea .LAVX2_POLY_x8+128(%rip), %rax
|
||||
lea 128($b_ptr), $b_ptr
|
||||
vmovdqa 32*1-160($a_ptr), $ACC1
|
||||
vmovdqa 32*2-160($a_ptr), $ACC2
|
||||
vmovdqa 32*3-160($a_ptr), $ACC3
|
||||
vmovdqa 32*4-160($a_ptr), $ACC4
|
||||
vmovdqa 32*5-160($a_ptr), $ACC5
|
||||
vmovdqa 32*6-160($a_ptr), $ACC6
|
||||
vmovdqa 32*7-160($a_ptr), $ACC7
|
||||
vmovdqa 32*8-160($a_ptr), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128($b_ptr), $ACC0, $ACC0
|
||||
vpsubq 32*1-128($b_ptr), $ACC1, $ACC1
|
||||
vpsubq 32*2-128($b_ptr), $ACC2, $ACC2
|
||||
vpsubq 32*3-128($b_ptr), $ACC3, $ACC3
|
||||
vpsubq 32*4-128($b_ptr), $ACC4, $ACC4
|
||||
vpsubq 32*5-128($b_ptr), $ACC5, $ACC5
|
||||
vpsubq 32*6-128($b_ptr), $ACC6, $ACC6
|
||||
vpsubq 32*7-128($b_ptr), $ACC7, $ACC7
|
||||
vpsubq 32*8-128($b_ptr), $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_sub_x4,.-avx2_sub_x4
|
||||
|
||||
.type avx2_select_n_store,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_select_n_store:
|
||||
vmovdqa `8+32*9*8`(%rsp), $Y
|
||||
vpor `8+32*9*8+32`(%rsp), $Y, $Y
|
||||
|
||||
vpandn $ACC0, $Y, $ACC0
|
||||
vpandn $ACC1, $Y, $ACC1
|
||||
vpandn $ACC2, $Y, $ACC2
|
||||
vpandn $ACC3, $Y, $ACC3
|
||||
vpandn $ACC4, $Y, $ACC4
|
||||
vpandn $ACC5, $Y, $ACC5
|
||||
vpandn $ACC6, $Y, $ACC6
|
||||
vmovdqa `8+32*9*8+32`(%rsp), $B
|
||||
vpandn $ACC7, $Y, $ACC7
|
||||
vpandn `8+32*9*8`(%rsp), $B, $B
|
||||
vpandn $ACC8, $Y, $ACC8
|
||||
|
||||
vpand 32*0(%rsi), $B, $T0
|
||||
lea 160(%rsi), %rax
|
||||
vpand 32*1(%rsi), $B, $Y
|
||||
vpxor $T0, $ACC0, $ACC0
|
||||
vpand 32*2(%rsi), $B, $T0
|
||||
vpxor $Y, $ACC1, $ACC1
|
||||
vpand 32*3(%rsi), $B, $Y
|
||||
vpxor $T0, $ACC2, $ACC2
|
||||
vpand 32*4-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC3, $ACC3
|
||||
vpand 32*5-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC4, $ACC4
|
||||
vpand 32*6-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC5, $ACC5
|
||||
vpand 32*7-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC6, $ACC6
|
||||
vpand 32*8-160(%rax), $B, $T0
|
||||
vmovdqa `8+32*9*8+32`(%rsp), $B
|
||||
vpxor $Y, $ACC7, $ACC7
|
||||
|
||||
vpand 32*0(%rdx), $B, $Y
|
||||
lea 160(%rdx), %rax
|
||||
vpxor $T0, $ACC8, $ACC8
|
||||
vpand 32*1(%rdx), $B, $T0
|
||||
vpxor $Y, $ACC0, $ACC0
|
||||
vpand 32*2(%rdx), $B, $Y
|
||||
vpxor $T0, $ACC1, $ACC1
|
||||
vpand 32*3(%rdx), $B, $T0
|
||||
vpxor $Y, $ACC2, $ACC2
|
||||
vpand 32*4-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC3, $ACC3
|
||||
vpand 32*5-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC4, $ACC4
|
||||
vpand 32*6-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC5, $ACC5
|
||||
vpand 32*7-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC6, $ACC6
|
||||
vpand 32*8-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC7, $ACC7
|
||||
vpxor $Y, $ACC8, $ACC8
|
||||
`&STORE`
|
||||
|
||||
ret
|
||||
.size avx2_select_n_store,.-avx2_select_n_store
|
||||
___
|
||||
$code.=<<___ if (0); # inlined
|
||||
################################################################################
|
||||
# void avx2_mul_by2_x4(void* RESULTx4, void *Ax4);
|
||||
.type avx2_mul_by2_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_by2_x4:
|
||||
vmovdqa 32*0($a_ptr), $ACC0
|
||||
lea 160($a_ptr), %rax
|
||||
vmovdqa 32*1($a_ptr), $ACC1
|
||||
vmovdqa 32*2($a_ptr), $ACC2
|
||||
vmovdqa 32*3($a_ptr), $ACC3
|
||||
vmovdqa 32*4-160(%rax), $ACC4
|
||||
vmovdqa 32*5-160(%rax), $ACC5
|
||||
vmovdqa 32*6-160(%rax), $ACC6
|
||||
vmovdqa 32*7-160(%rax), $ACC7
|
||||
vmovdqa 32*8-160(%rax), $ACC8
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_mul_by2_x4,.-avx2_mul_by2_x4
|
||||
___
|
||||
my ($r_ptr_in,$a_ptr_in,$b_ptr_in)=("%rdi","%rsi","%rdx");
|
||||
my ($r_ptr,$a_ptr,$b_ptr)=("%r8","%r9","%r10");
|
||||
|
||||
$code.=<<___;
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_point_add_affine_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.globl ecp_nistz256_avx2_point_add_affine_x4
|
||||
.type ecp_nistz256_avx2_point_add_affine_x4,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_point_add_affine_x4:
|
||||
mov %rsp, %rax
|
||||
push %rbp
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea -8(%rax), %rbp
|
||||
|
||||
# Result + 32*0 = Result.X
|
||||
# Result + 32*9 = Result.Y
|
||||
# Result + 32*18 = Result.Z
|
||||
|
||||
# A + 32*0 = A.X
|
||||
# A + 32*9 = A.Y
|
||||
# A + 32*18 = A.Z
|
||||
|
||||
# B + 32*0 = B.X
|
||||
# B + 32*9 = B.Y
|
||||
|
||||
sub \$`32*9*8+32*2+32*8`, %rsp
|
||||
and \$-64, %rsp
|
||||
|
||||
mov $r_ptr_in, $r_ptr
|
||||
mov $a_ptr_in, $a_ptr
|
||||
mov $b_ptr_in, $b_ptr
|
||||
|
||||
vmovdqa 32*0($a_ptr_in), %ymm0
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
lea 256($a_ptr_in), %rax # size optimization
|
||||
vpor 32*1($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*2($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*3($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8`(%rsp)
|
||||
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
vmovdqa 32*0($b_ptr), %ymm0
|
||||
lea 256($b_ptr), %rax # size optimization
|
||||
vpor 32*1($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*2($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*3($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8+32`(%rsp)
|
||||
|
||||
# Z1^2 = Z1*Z1
|
||||
lea `32*9*2`($a_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = X2*Z1^2
|
||||
lea `32*9*0`($b_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# S2 = Z1*Z1^2 = Z1^3
|
||||
lea `32*9*2`($a_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# S2 = S2*Y2 = Y2*Z1^3
|
||||
lea `32*9*1`($b_ptr), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H = U2 - U1 = U2 - X1
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($a_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# R = S2 - S1 = S2 - Y1
|
||||
lea `32*9*1`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*4`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# Z3 = H*Z1*Z2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*2`($a_ptr), %rdx
|
||||
lea `32*9*2`($r_ptr), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea .LONE(%rip), %rsi
|
||||
lea `32*9*2`($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# R^2 = R^2
|
||||
lea `32*9*4`(%rsp), %rsi
|
||||
lea `32*9*6`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^2 = H^2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^3 = H^2*H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*7`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = U1*H^2
|
||||
lea `32*9*0`($a_ptr), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# Hsqr = U2*2
|
||||
#lea 32*9*0(%rsp), %rsi
|
||||
#lea 32*9*5(%rsp), %rdi
|
||||
#call avx2_mul_by2_x4
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# X3 = R^2 - H^3
|
||||
#lea 32*9*6(%rsp), %rsi
|
||||
#lea 32*9*7(%rsp), %rdx
|
||||
#lea 32*9*5(%rsp), %rcx
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
# X3 = X3 - U2*2
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*6+128`(%rsp), %rsi
|
||||
lea .LAVX2_POLY_x2+128(%rip), %rax
|
||||
lea `32*9*7+128`(%rsp), %rdx
|
||||
lea `32*9*5+128`(%rsp), %rcx
|
||||
lea `32*9*0`($r_ptr), %rdi
|
||||
|
||||
vmovdqa 32*0-128(%rsi), $ACC0
|
||||
vmovdqa 32*1-128(%rsi), $ACC1
|
||||
vmovdqa 32*2-128(%rsi), $ACC2
|
||||
vmovdqa 32*3-128(%rsi), $ACC3
|
||||
vmovdqa 32*4-128(%rsi), $ACC4
|
||||
vmovdqa 32*5-128(%rsi), $ACC5
|
||||
vmovdqa 32*6-128(%rsi), $ACC6
|
||||
vmovdqa 32*7-128(%rsi), $ACC7
|
||||
vmovdqa 32*8-128(%rsi), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rdx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rdx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rdx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rdx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rdx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rdx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rdx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rdx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rdx), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rcx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rcx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rcx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rcx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rcx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rcx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rcx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rcx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rcx), $ACC8, $ACC8
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*0($b_ptr), %rsi
|
||||
lea 32*0($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# H = U2 - X3
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($r_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*4`(%rsp), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*7`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*9($b_ptr), %rsi
|
||||
lea 32*9($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_mul_by1_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*1`($r_ptr), %rsi
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps %xmm6, -16*10(%rbp)
|
||||
movaps %xmm7, -16*9(%rbp)
|
||||
movaps %xmm8, -16*8(%rbp)
|
||||
movaps %xmm9, -16*7(%rbp)
|
||||
movaps %xmm10, -16*6(%rbp)
|
||||
movaps %xmm11, -16*5(%rbp)
|
||||
movaps %xmm12, -16*4(%rbp)
|
||||
movaps %xmm13, -16*3(%rbp)
|
||||
movaps %xmm14, -16*2(%rbp)
|
||||
movaps %xmm15, -16*1(%rbp)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
.size ecp_nistz256_avx2_point_add_affine_x4,.-ecp_nistz256_avx2_point_add_affine_x4
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_point_add_affines_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.globl ecp_nistz256_avx2_point_add_affines_x4
|
||||
.type ecp_nistz256_avx2_point_add_affines_x4,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_point_add_affines_x4:
|
||||
mov %rsp, %rax
|
||||
push %rbp
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea -8(%rax), %rbp
|
||||
|
||||
# Result + 32*0 = Result.X
|
||||
# Result + 32*9 = Result.Y
|
||||
# Result + 32*18 = Result.Z
|
||||
|
||||
# A + 32*0 = A.X
|
||||
# A + 32*9 = A.Y
|
||||
|
||||
# B + 32*0 = B.X
|
||||
# B + 32*9 = B.Y
|
||||
|
||||
sub \$`32*9*8+32*2+32*8`, %rsp
|
||||
and \$-64, %rsp
|
||||
|
||||
mov $r_ptr_in, $r_ptr
|
||||
mov $a_ptr_in, $a_ptr
|
||||
mov $b_ptr_in, $b_ptr
|
||||
|
||||
vmovdqa 32*0($a_ptr_in), %ymm0
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
lea 256($a_ptr_in), %rax # size optimization
|
||||
vpor 32*1($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*2($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*3($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8`(%rsp)
|
||||
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
vmovdqa 32*0($b_ptr), %ymm0
|
||||
lea 256($b_ptr), %rax # size optimization
|
||||
vpor 32*1($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*2($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*3($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8+32`(%rsp)
|
||||
|
||||
# H = U2 - U1 = X2 - X1
|
||||
lea `32*9*0`($b_ptr), %rsi
|
||||
lea `32*9*0`($a_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# R = S2 - S1 = Y2 - Y1
|
||||
lea `32*9*1`($b_ptr), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*4`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# Z3 = H*Z1*Z2 = H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*2`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize
|
||||
|
||||
vmovdqa `32*9*8`(%rsp), $B
|
||||
vpor `32*9*8+32`(%rsp), $B, $B
|
||||
|
||||
vpandn $ACC0, $B, $ACC0
|
||||
lea .LONE+128(%rip), %rax
|
||||
vpandn $ACC1, $B, $ACC1
|
||||
vpandn $ACC2, $B, $ACC2
|
||||
vpandn $ACC3, $B, $ACC3
|
||||
vpandn $ACC4, $B, $ACC4
|
||||
vpandn $ACC5, $B, $ACC5
|
||||
vpandn $ACC6, $B, $ACC6
|
||||
vpandn $ACC7, $B, $ACC7
|
||||
|
||||
vpand 32*0-128(%rax), $B, $T0
|
||||
vpandn $ACC8, $B, $ACC8
|
||||
vpand 32*1-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC0, $ACC0
|
||||
vpand 32*2-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC1, $ACC1
|
||||
vpand 32*3-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC2, $ACC2
|
||||
vpand 32*4-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC3, $ACC3
|
||||
vpand 32*5-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC4, $ACC4
|
||||
vpand 32*6-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC5, $ACC5
|
||||
vpand 32*7-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC6, $ACC6
|
||||
vpand 32*8-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC7, $ACC7
|
||||
vpxor $T0, $ACC8, $ACC8
|
||||
`&STORE`
|
||||
|
||||
# R^2 = R^2
|
||||
lea `32*9*4`(%rsp), %rsi
|
||||
lea `32*9*6`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^2 = H^2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^3 = H^2*H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*7`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = U1*H^2
|
||||
lea `32*9*0`($a_ptr), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# Hsqr = U2*2
|
||||
#lea 32*9*0(%rsp), %rsi
|
||||
#lea 32*9*5(%rsp), %rdi
|
||||
#call avx2_mul_by2_x4
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# X3 = R^2 - H^3
|
||||
#lea 32*9*6(%rsp), %rsi
|
||||
#lea 32*9*7(%rsp), %rdx
|
||||
#lea 32*9*5(%rsp), %rcx
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
# X3 = X3 - U2*2
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*6+128`(%rsp), %rsi
|
||||
lea .LAVX2_POLY_x2+128(%rip), %rax
|
||||
lea `32*9*7+128`(%rsp), %rdx
|
||||
lea `32*9*5+128`(%rsp), %rcx
|
||||
lea `32*9*0`($r_ptr), %rdi
|
||||
|
||||
vmovdqa 32*0-128(%rsi), $ACC0
|
||||
vmovdqa 32*1-128(%rsi), $ACC1
|
||||
vmovdqa 32*2-128(%rsi), $ACC2
|
||||
vmovdqa 32*3-128(%rsi), $ACC3
|
||||
vmovdqa 32*4-128(%rsi), $ACC4
|
||||
vmovdqa 32*5-128(%rsi), $ACC5
|
||||
vmovdqa 32*6-128(%rsi), $ACC6
|
||||
vmovdqa 32*7-128(%rsi), $ACC7
|
||||
vmovdqa 32*8-128(%rsi), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rdx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rdx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rdx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rdx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rdx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rdx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rdx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rdx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rdx), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rcx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rcx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rcx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rcx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rcx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rcx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rcx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rcx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rcx), $ACC8, $ACC8
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*0($b_ptr), %rsi
|
||||
lea 32*0($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# H = U2 - X3
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($r_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H = H*R
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*4`(%rsp), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# S2 = S1 * H^3
|
||||
lea `32*9*7`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*9($b_ptr), %rsi
|
||||
lea 32*9($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_mul_by1_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*1`($r_ptr), %rsi
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps %xmm6, -16*10(%rbp)
|
||||
movaps %xmm7, -16*9(%rbp)
|
||||
movaps %xmm8, -16*8(%rbp)
|
||||
movaps %xmm9, -16*7(%rbp)
|
||||
movaps %xmm10, -16*6(%rbp)
|
||||
movaps %xmm11, -16*5(%rbp)
|
||||
movaps %xmm12, -16*4(%rbp)
|
||||
movaps %xmm13, -16*3(%rbp)
|
||||
movaps %xmm14, -16*2(%rbp)
|
||||
movaps %xmm15, -16*1(%rbp)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
.size ecp_nistz256_avx2_point_add_affines_x4,.-ecp_nistz256_avx2_point_add_affines_x4
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_to_mont(void* RESULTx4, void *Ax4);
|
||||
.globl ecp_nistz256_avx2_to_mont
|
||||
.type ecp_nistz256_avx2_to_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_to_mont:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
lea .LTO_MONT_AVX2(%rip), %rdx
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_to_mont,.-ecp_nistz256_avx2_to_mont
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_from_mont(void* RESULTx4, void *Ax4);
|
||||
.globl ecp_nistz256_avx2_from_mont
|
||||
.type ecp_nistz256_avx2_from_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_from_mont:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
lea .LFROM_MONT_AVX2(%rip), %rdx
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_from_mont,.-ecp_nistz256_avx2_from_mont
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_set1(void* RESULTx4);
|
||||
.globl ecp_nistz256_avx2_set1
|
||||
.type ecp_nistz256_avx2_set1,\@function,1
|
||||
.align 32
|
||||
ecp_nistz256_avx2_set1:
|
||||
lea .LONE+128(%rip), %rax
|
||||
lea 128(%rdi), %rdi
|
||||
vzeroupper
|
||||
vmovdqa 32*0-128(%rax), %ymm0
|
||||
vmovdqa 32*1-128(%rax), %ymm1
|
||||
vmovdqa 32*2-128(%rax), %ymm2
|
||||
vmovdqa 32*3-128(%rax), %ymm3
|
||||
vmovdqa 32*4-128(%rax), %ymm4
|
||||
vmovdqa 32*5-128(%rax), %ymm5
|
||||
vmovdqa %ymm0, 32*0-128(%rdi)
|
||||
vmovdqa 32*6-128(%rax), %ymm0
|
||||
vmovdqa %ymm1, 32*1-128(%rdi)
|
||||
vmovdqa 32*7-128(%rax), %ymm1
|
||||
vmovdqa %ymm2, 32*2-128(%rdi)
|
||||
vmovdqa 32*8-128(%rax), %ymm2
|
||||
vmovdqa %ymm3, 32*3-128(%rdi)
|
||||
vmovdqa %ymm4, 32*4-128(%rdi)
|
||||
vmovdqa %ymm5, 32*5-128(%rdi)
|
||||
vmovdqa %ymm0, 32*6-128(%rdi)
|
||||
vmovdqa %ymm1, 32*7-128(%rdi)
|
||||
vmovdqa %ymm2, 32*8-128(%rdi)
|
||||
|
||||
vzeroupper
|
||||
ret
|
||||
.size ecp_nistz256_avx2_set1,.-ecp_nistz256_avx2_set1
|
||||
___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_multi_gather_w7(void* RESULT, void *in,
|
||||
# int index0, int index1, int index2, int index3);
|
||||
################################################################################
|
||||
|
||||
my ($val,$in_t,$index0,$index1,$index2,$index3)=("%rdi","%rsi","%edx","%ecx","%r8d","%r9d");
|
||||
my ($INDEX0,$INDEX1,$INDEX2,$INDEX3)=map("%ymm$_",(0..3));
|
||||
my ($R0a,$R0b,$R1a,$R1b,$R2a,$R2b,$R3a,$R3b)=map("%ymm$_",(4..11));
|
||||
my ($M0,$T0,$T1,$TMP0)=map("%ymm$_",(12..15));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@function,6
|
||||
.align 32
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea .LIntOne(%rip), %rax
|
||||
|
||||
vmovd $index0, %xmm0
|
||||
vmovd $index1, %xmm1
|
||||
vmovd $index2, %xmm2
|
||||
vmovd $index3, %xmm3
|
||||
|
||||
vpxor $R0a, $R0a, $R0a
|
||||
vpxor $R0b, $R0b, $R0b
|
||||
vpxor $R1a, $R1a, $R1a
|
||||
vpxor $R1b, $R1b, $R1b
|
||||
vpxor $R2a, $R2a, $R2a
|
||||
vpxor $R2b, $R2b, $R2b
|
||||
vpxor $R3a, $R3a, $R3a
|
||||
vpxor $R3b, $R3b, $R3b
|
||||
vmovdqa (%rax), $M0
|
||||
|
||||
vpermd $INDEX0, $R0a, $INDEX0
|
||||
vpermd $INDEX1, $R0a, $INDEX1
|
||||
vpermd $INDEX2, $R0a, $INDEX2
|
||||
vpermd $INDEX3, $R0a, $INDEX3
|
||||
|
||||
mov \$64, %ecx
|
||||
lea 112($val), $val # size optimization
|
||||
jmp .Lmulti_select_loop_avx2
|
||||
|
||||
# INDEX=0, corresponds to the point at infty (0,0)
|
||||
.align 32
|
||||
.Lmulti_select_loop_avx2:
|
||||
vpcmpeqd $INDEX0, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*0`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*0`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R0a, $R0a
|
||||
vpxor $T1, $R0b, $R0b
|
||||
|
||||
vpcmpeqd $INDEX1, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*1`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*1`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R1a, $R1a
|
||||
vpxor $T1, $R1b, $R1b
|
||||
|
||||
vpcmpeqd $INDEX2, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*2`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*2`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R2a, $R2a
|
||||
vpxor $T1, $R2b, $R2b
|
||||
|
||||
vpcmpeqd $INDEX3, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*3`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*3`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R3a, $R3a
|
||||
vpxor $T1, $R3b, $R3b
|
||||
|
||||
vpaddd (%rax), $M0, $M0 # increment
|
||||
lea 32*2($in_t), $in_t
|
||||
|
||||
dec %ecx
|
||||
jnz .Lmulti_select_loop_avx2
|
||||
|
||||
vmovdqu $R0a, 32*0-112($val)
|
||||
vmovdqu $R0b, 32*1-112($val)
|
||||
vmovdqu $R1a, 32*2-112($val)
|
||||
vmovdqu $R1b, 32*3-112($val)
|
||||
vmovdqu $R2a, 32*4-112($val)
|
||||
vmovdqu $R2b, 32*5-112($val)
|
||||
vmovdqu $R3a, 32*6-112($val)
|
||||
vmovdqu $R3b, 32*7-112($val)
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.extern OPENSSL_ia32cap_P
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
.type ecp_nistz_avx2_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz_avx2_eligible:
|
||||
mov OPENSSL_ia32cap_P+8(%rip),%eax
|
||||
shr \$5,%eax
|
||||
and \$1,%eax
|
||||
ret
|
||||
.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
|
||||
___
|
||||
}
|
||||
}} else {{ # assembler is too old
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.globl ecp_nistz256_avx2_transpose_convert
|
||||
.globl ecp_nistz256_avx2_convert_transpose_back
|
||||
.globl ecp_nistz256_avx2_point_add_affine_x4
|
||||
.globl ecp_nistz256_avx2_point_add_affines_x4
|
||||
.globl ecp_nistz256_avx2_to_mont
|
||||
.globl ecp_nistz256_avx2_from_mont
|
||||
.globl ecp_nistz256_avx2_set1
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@abi-omnipotent
|
||||
ecp_nistz256_avx2_transpose_convert:
|
||||
ecp_nistz256_avx2_convert_transpose_back:
|
||||
ecp_nistz256_avx2_point_add_affine_x4:
|
||||
ecp_nistz256_avx2_point_add_affines_x4:
|
||||
ecp_nistz256_avx2_to_mont:
|
||||
ecp_nistz256_avx2_from_mont:
|
||||
ecp_nistz256_avx2_set1:
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
.type ecp_nistz_avx2_eligible,\@abi-omnipotent
|
||||
ecp_nistz_avx2_eligible:
|
||||
xor %eax,%eax
|
||||
ret
|
||||
.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
|
||||
___
|
||||
}}
|
||||
|
||||
foreach (split("\n",$code)) {
|
||||
s/\`([^\`]*)\`/eval($1)/geo;
|
||||
|
||||
print $_,"\n";
|
||||
}
|
||||
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
@@ -489,7 +489,8 @@ int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
/* point is its own inverse */
|
||||
return 1;
|
||||
|
||||
if (!EC_POINT_make_affine(group, point, ctx))
|
||||
if (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, point, ctx))
|
||||
return 0;
|
||||
return BN_GF2m_add(point->Y, point->X, point->Y);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
const void *pval;
|
||||
|
||||
+4
-7
@@ -27,8 +27,7 @@ int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field)
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field)
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
|
||||
@@ -53,8 +52,7 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
|
||||
@@ -74,8 +72,7 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] != 0) && (group->poly[3] != 0)
|
||||
&& (group->poly[4] == 0))) {
|
||||
@@ -262,7 +259,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
|
||||
ASN1_OBJECT_free(field->fieldType);
|
||||
ASN1_TYPE_free(field->p.other);
|
||||
|
||||
nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
|
||||
nid = EC_GROUP_get_field_type(group);
|
||||
/* set OID for the field */
|
||||
if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
|
||||
ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
|
||||
|
||||
@@ -19,15 +19,10 @@
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ec_set_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p)
|
||||
int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode)
|
||||
{
|
||||
const EC_GROUP *ecg = EC_KEY_get0_group(ec);
|
||||
const BIGNUM *cofactor;
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* mode can be only 0 for disable, or 1 for enable here.
|
||||
*
|
||||
@@ -224,8 +219,12 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
return 0;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
|
||||
if (p != NULL && !ec_set_param_ecdh_cofactor_mode(ec, p))
|
||||
return 0;
|
||||
if (p != NULL) {
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode)
|
||||
|| !ec_set_ecdh_cofactor_mode(ec, mode))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -3195,7 +3195,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
/* If no curve data curve method must handle everything */
|
||||
if (curve.data == NULL)
|
||||
return EC_GROUP_new_ex(libctx,
|
||||
return ec_group_new_ex(libctx,
|
||||
curve.meth != NULL ? curve.meth() : NULL);
|
||||
|
||||
if ((ctx = BN_CTX_new_ex(libctx)) == NULL) {
|
||||
@@ -3218,7 +3218,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
if (curve.meth != 0) {
|
||||
meth = curve.meth();
|
||||
if (((group = EC_GROUP_new_ex(libctx, meth)) == NULL) ||
|
||||
if (((group = ec_group_new_ex(libctx, meth)) == NULL) ||
|
||||
(!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
@@ -3388,17 +3388,13 @@ int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
|
||||
unsigned char *param_bytes = NULL;
|
||||
const EC_CURVE_DATA *data;
|
||||
const EC_POINT *generator = NULL;
|
||||
const EC_METHOD *meth;
|
||||
const BIGNUM *cofactor = NULL;
|
||||
/* An array of BIGNUMs for (p, a, b, x, y, order) */
|
||||
BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
meth = EC_GROUP_method_of(group);
|
||||
if (meth == NULL)
|
||||
return -1;
|
||||
/* Use the optional named curve nid as a search field */
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
field_type = EC_METHOD_get_field_type(meth);
|
||||
field_type = EC_GROUP_get_field_type(group);
|
||||
seed_len = EC_GROUP_get_seed_len(group);
|
||||
seed = EC_GROUP_get0_seed(group);
|
||||
cofactor = EC_GROUP_get0_cofactor(group);
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
meth = EC_GFp_mont_method();
|
||||
#endif
|
||||
|
||||
ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
|
||||
|
||||
meth = EC_GF2m_simple_method();
|
||||
|
||||
ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
+4
-3
@@ -117,10 +117,9 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
dest->libctx = src->libctx;
|
||||
/* copy the parameters */
|
||||
if (src->group != NULL) {
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
|
||||
/* clear the old group */
|
||||
EC_GROUP_free(dest->group);
|
||||
dest->group = EC_GROUP_new_ex(src->libctx, meth);
|
||||
dest->group = ec_group_new_ex(src->libctx, src->group->meth);
|
||||
if (dest->group == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(dest->group, src->group))
|
||||
@@ -398,7 +397,7 @@ static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key)
|
||||
if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
if (EC_METHOD_get_field_type(key->group->meth) == NID_X9_62_prime_field) {
|
||||
if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) {
|
||||
if (BN_is_negative(x)
|
||||
|| BN_cmp(x, key->group->field) >= 0
|
||||
|| BN_is_negative(y)
|
||||
@@ -781,12 +780,14 @@ void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
|
||||
EC_GROUP_set_asn1_flag(key->group, flag);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
|
||||
{
|
||||
if (key->group == NULL)
|
||||
return 0;
|
||||
return EC_GROUP_precompute_mult(key->group, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_KEY_get_flags(const EC_KEY *key)
|
||||
{
|
||||
|
||||
+24
-10
@@ -23,7 +23,7 @@
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
{
|
||||
EC_GROUP *ret;
|
||||
|
||||
@@ -65,11 +65,13 @@ EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
# ifndef FIPS_MODULE
|
||||
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
{
|
||||
return EC_GROUP_new_ex(NULL, meth);
|
||||
return ec_group_new_ex(NULL, meth);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group)
|
||||
@@ -255,7 +257,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((t = EC_GROUP_new_ex(a->libctx, a->meth)) == NULL)
|
||||
if ((t = ec_group_new_ex(a->libctx, a->meth)) == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(t, a))
|
||||
goto err;
|
||||
@@ -270,6 +272,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
|
||||
{
|
||||
return group->meth;
|
||||
@@ -279,6 +282,7 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
|
||||
{
|
||||
return meth->field_type;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ec_precompute_mont_data(EC_GROUP *);
|
||||
|
||||
@@ -475,6 +479,11 @@ const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group)
|
||||
return group->field;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_field_type(const EC_GROUP *group)
|
||||
{
|
||||
return group->meth->field_type;
|
||||
}
|
||||
|
||||
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
|
||||
{
|
||||
group->asn1_flag = flag;
|
||||
@@ -602,8 +611,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
#endif
|
||||
|
||||
/* compare the field types */
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
|
||||
EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
|
||||
if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b))
|
||||
return 1;
|
||||
/* compare the curve name (if present in both) */
|
||||
if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
|
||||
@@ -777,10 +785,12 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
|
||||
{
|
||||
return point->meth;
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
|
||||
{
|
||||
@@ -1004,6 +1014,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
|
||||
return group->meth->point_cmp(group, a, b, ctx);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->make_affine == 0) {
|
||||
@@ -1034,6 +1045,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
|
||||
}
|
||||
return group->meth->points_make_affine(group, num, points, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions for point multiplication. If group->meth->mul is 0, we use the
|
||||
@@ -1093,6 +1105,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t num;
|
||||
#ifndef FIPS_MODULE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
@@ -1115,13 +1128,12 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
return 0;
|
||||
}
|
||||
|
||||
num = (point != NULL && p_scalar != NULL) ? 1 : 0;
|
||||
if (group->meth->mul != NULL)
|
||||
ret = group->meth->mul(group, r, g_scalar, point != NULL
|
||||
&& p_scalar != NULL, &point, &p_scalar, ctx);
|
||||
ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
|
||||
else
|
||||
/* use default */
|
||||
ret = ec_wNAF_mul(group, r, g_scalar, point != NULL
|
||||
&& p_scalar != NULL, &point, &p_scalar, ctx);
|
||||
ret = ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
BN_CTX_free(new_ctx);
|
||||
@@ -1129,6 +1141,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->mul == 0)
|
||||
@@ -1153,6 +1166,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
|
||||
return 0; /* cannot tell whether precomputation has
|
||||
* been performed */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
/* Curve does not support signing operations */
|
||||
#define EC_FLAGS_NO_SIGN 0x4
|
||||
|
||||
#ifdef OPENSSL_NO_DEPRECATED_3_0
|
||||
typedef struct ec_method_st EC_METHOD;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure details are not part of the exported interface, so all this may
|
||||
* change in future versions.
|
||||
@@ -585,6 +589,15 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
#endif
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
|
||||
/**
|
||||
* Creates a new EC_GROUP object
|
||||
* \param libctx The associated library context or NULL for the default
|
||||
* library context
|
||||
* \param meth EC_METHOD to use
|
||||
* \return newly created EC_GROUP object or NULL in case of an error.
|
||||
*/
|
||||
EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth);
|
||||
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
|
||||
* P256. See http://eprint.iacr.org/2013/816.
|
||||
|
||||
+6
-3
@@ -267,7 +267,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
}
|
||||
|
||||
/* ensure input point is in affine coords for ladder step efficiency */
|
||||
if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) {
|
||||
if (!p->Z_is_one && (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, p, ctx))) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -711,7 +712,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num_val, val, ctx))
|
||||
if (group->meth->points_make_affine == NULL
|
||||
|| !group->meth->points_make_affine(group, num_val, val, ctx))
|
||||
goto err;
|
||||
|
||||
r_is_at_infinity = 1;
|
||||
@@ -949,7 +951,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num, points, ctx))
|
||||
if (group->meth->points_make_affine == NULL
|
||||
|| !group->meth->points_make_affine(group, num, points, ctx))
|
||||
goto err;
|
||||
|
||||
pre_comp->group = group;
|
||||
|
||||
@@ -32,7 +32,7 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
const char *mdname = EVP_MD_name(md);
|
||||
EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL);
|
||||
|
||||
if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) {
|
||||
if ((kctx = EVP_KDF_new_ctx(kdf)) != NULL) {
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, 0);
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
@@ -41,9 +41,9 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
(void *)sinfo, sinfolen);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) > 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) > 0
|
||||
&& EVP_KDF_derive(kctx, out, outlen) > 0;
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
}
|
||||
EVP_KDF_free(kdf);
|
||||
return ret;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
@@ -115,7 +115,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
/* explicit parameters */
|
||||
int is_char_two = 0;
|
||||
point_conversion_form_t form;
|
||||
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
|
||||
int tmp_nid = EC_GROUP_get_field_type(x);
|
||||
|
||||
if (tmp_nid == NID_X9_62_characteristic_two_field)
|
||||
is_char_two = 1;
|
||||
|
||||
@@ -75,6 +75,7 @@ typedef uint64_t u64;
|
||||
*/
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef uint64_t limb_aX __attribute((__aligned__(1)));
|
||||
typedef uint128_t widelimb;
|
||||
|
||||
typedef limb felem[4];
|
||||
@@ -311,10 +312,10 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
|
||||
*/
|
||||
static void bin28_to_felem(felem out, const u8 in[28])
|
||||
{
|
||||
out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const uint64_t *)(in+20))) >> 8;
|
||||
out[0] = *((const limb *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const limb_aX *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const limb_aX *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const limb_aX *)(in + 20))) >> 8;
|
||||
}
|
||||
|
||||
static void felem_to_bin28(u8 out[28], const felem in)
|
||||
|
||||
+17
-16
@@ -131,6 +131,7 @@ static const felem_bytearray nistp521_curve_params[5] = {
|
||||
#define NLIMBS 9
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef limb limb_aX __attribute((__aligned__(1)));
|
||||
typedef limb felem[NLIMBS];
|
||||
typedef uint128_t largefelem[NLIMBS];
|
||||
|
||||
@@ -144,14 +145,14 @@ static const limb bottom58bits = 0x3ffffffffffffff;
|
||||
static void bin66_to_felem(felem out, const u8 in[66])
|
||||
{
|
||||
out[0] = (*((limb *) & in[0])) & bottom58bits;
|
||||
out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb *) & in[58])) & bottom57bits;
|
||||
out[1] = (*((limb_aX *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb_aX *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb_aX *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb_aX *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb_aX *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb_aX *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb_aX *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb_aX *) & in[58])) & bottom57bits;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -162,14 +163,14 @@ static void felem_to_bin66(u8 out[66], const felem in)
|
||||
{
|
||||
memset(out, 0, 66);
|
||||
(*((limb *) & out[0])) = in[0];
|
||||
(*((limb *) & out[7])) |= in[1] << 2;
|
||||
(*((limb *) & out[14])) |= in[2] << 4;
|
||||
(*((limb *) & out[21])) |= in[3] << 6;
|
||||
(*((limb *) & out[29])) = in[4];
|
||||
(*((limb *) & out[36])) |= in[5] << 2;
|
||||
(*((limb *) & out[43])) |= in[6] << 4;
|
||||
(*((limb *) & out[50])) |= in[7] << 6;
|
||||
(*((limb *) & out[58])) = in[8];
|
||||
(*((limb_aX *) & out[7])) |= in[1] << 2;
|
||||
(*((limb_aX *) & out[14])) |= in[2] << 4;
|
||||
(*((limb_aX *) & out[21])) |= in[3] << 6;
|
||||
(*((limb_aX *) & out[29])) = in[4];
|
||||
(*((limb_aX *) & out[36])) |= in[5] << 2;
|
||||
(*((limb_aX *) & out[43])) |= in[6] << 4;
|
||||
(*((limb_aX *) & out[50])) |= in[7] << 6;
|
||||
(*((limb_aX *) & out[58])) = in[8];
|
||||
}
|
||||
|
||||
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
|
||||
|
||||
+5
-212
@@ -897,7 +897,8 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
||||
* It would be faster to use EC_POINTs_make_affine and
|
||||
* make multiple points affine at the same time.
|
||||
*/
|
||||
if (!EC_POINT_make_affine(group, P, ctx))
|
||||
if (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, P, ctx))
|
||||
goto err;
|
||||
if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) {
|
||||
@@ -935,207 +936,6 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great
|
||||
* code processing 4 points in parallel, corresponding serial operation
|
||||
* is several times slower, because it uses 29x29=58-bit multiplication
|
||||
* as opposite to 64x64=128-bit in integer-only scalar case. As result
|
||||
* it doesn't provide *significant* performance improvement. Note that
|
||||
* just defining ECP_NISTZ256_AVX2 is not sufficient to make it work,
|
||||
* you'd need to compile even asm/ecp_nistz256-avx.pl module.
|
||||
*/
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
# if !(defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64)) || \
|
||||
!(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */
|
||||
# undef ECP_NISTZ256_AVX2
|
||||
# else
|
||||
/* Constant time access, loading four values, from four consecutive tables */
|
||||
void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in,
|
||||
int index0, int index1, int index2,
|
||||
int index3);
|
||||
void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in);
|
||||
void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4);
|
||||
void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_set1(void *RESULTx4);
|
||||
int ecp_nistz_avx2_eligible(void);
|
||||
|
||||
static void booth_recode_w7(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in)
|
||||
{
|
||||
unsigned char s, d;
|
||||
|
||||
s = ~((in >> 7) - 1);
|
||||
d = (1 << 8) - in - 1;
|
||||
d = (d & s) | (in & ~s);
|
||||
d = (d >> 1) + (d & 1);
|
||||
|
||||
*sign = s & 1;
|
||||
*digit = d;
|
||||
}
|
||||
|
||||
/*
|
||||
* ecp_nistz256_avx2_mul_g performs multiplication by G, using only the
|
||||
* precomputed table. It does 4 affine point additions in parallel,
|
||||
* significantly speeding up point multiplication for a fixed value.
|
||||
*/
|
||||
static void ecp_nistz256_avx2_mul_g(P256_POINT *r,
|
||||
unsigned char p_str[33],
|
||||
const P256_POINT_AFFINE(*preComputedTable)[64])
|
||||
{
|
||||
const unsigned int window_size = 7;
|
||||
const unsigned int mask = (1 << (window_size + 1)) - 1;
|
||||
unsigned int wvalue;
|
||||
/* Using 4 windows at a time */
|
||||
unsigned char sign0, digit0;
|
||||
unsigned char sign1, digit1;
|
||||
unsigned char sign2, digit2;
|
||||
unsigned char sign3, digit3;
|
||||
unsigned int idx = 0;
|
||||
BN_ULONG tmp[P256_LIMBS];
|
||||
int i;
|
||||
|
||||
ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 };
|
||||
ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 };
|
||||
ALIGN32 P256_POINT_AFFINE point_arr[4];
|
||||
ALIGN32 P256_POINT res_point_arr[4];
|
||||
|
||||
/* Initial four windows */
|
||||
wvalue = *((u16 *) & p_str[0]);
|
||||
wvalue = (wvalue << 1) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(aX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(aX4, aX4);
|
||||
ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]);
|
||||
ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]);
|
||||
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
/* Optimized when both inputs are affine */
|
||||
ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4);
|
||||
|
||||
for (i = 2; i < 9; i++) {
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr,
|
||||
preComputedTable[4 * i],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
|
||||
ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4);
|
||||
}
|
||||
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]);
|
||||
|
||||
ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4);
|
||||
/* Last window is performed serially */
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r,
|
||||
preComputedTable[36], digit0);
|
||||
ecp_nistz256_neg(tmp, r->Y);
|
||||
copy_conditional(r->Y, tmp, sign0);
|
||||
memcpy(r->Z, ONE, sizeof(ONE));
|
||||
/* Sum the four windows */
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[0]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[1]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[2]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[3]);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
__owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group,
|
||||
const P256_POINT_AFFINE *in,
|
||||
BN_CTX *ctx)
|
||||
@@ -1225,6 +1025,8 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
if (preComputedTable) {
|
||||
BN_ULONG infty;
|
||||
|
||||
if ((BN_num_bits(scalar) > 256)
|
||||
|| BN_is_negative(scalar)) {
|
||||
if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)
|
||||
@@ -1256,14 +1058,6 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
for (; i < 33; i++)
|
||||
p_str[i] = 0;
|
||||
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
if (ecp_nistz_avx2_eligible()) {
|
||||
ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
BN_ULONG infty;
|
||||
|
||||
/* First window */
|
||||
wvalue = (p_str[0] << 1) & mask;
|
||||
idx += window_size;
|
||||
@@ -1278,7 +1072,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
|
||||
/*
|
||||
* Since affine infinity is encoded as (0,0) and
|
||||
* Jacobian ias (,,0), we need to harmonize them
|
||||
* Jacobian is (,,0), we need to harmonize them
|
||||
* by assigning "one" or zero to Z.
|
||||
*/
|
||||
infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
|
||||
@@ -1317,7 +1111,6 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p_is_infinity = 1;
|
||||
no_precomp_for_generator = 1;
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* EC_METHOD low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -126,7 +126,7 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int pklen;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -171,6 +171,7 @@ void engine_cleanup_int(void)
|
||||
cleanup_stack = NULL;
|
||||
}
|
||||
CRYPTO_THREAD_lock_free(global_engine_lock);
|
||||
global_engine_lock = NULL;
|
||||
}
|
||||
|
||||
/* Now the "ex_data" support */
|
||||
|
||||
@@ -76,7 +76,6 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
|
||||
{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "internal/dso.h"
|
||||
#include <openssl/engineerr.h>
|
||||
#include <openssl/uierr.h>
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/ocsperr.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/tserr.h>
|
||||
@@ -86,7 +85,6 @@ int err_load_crypto_strings_int(void)
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
ERR_load_ENGINE_strings() == 0 ||
|
||||
# endif
|
||||
ERR_load_HTTP_strings() == 0 ||
|
||||
# ifndef OPENSSL_NO_OCSP
|
||||
ERR_load_OCSP_strings() == 0 ||
|
||||
# endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user