Latest update (add quic)

This commit is contained in:
2020-07-12 19:52:18 +09:00
parent 3a6d64bb68
commit e85ee33eee
501 changed files with 19166 additions and 10232 deletions
+78 -11
View File
@@ -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.
-1
View File
@@ -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",
},
-6
View File
@@ -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)',
+5
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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
--------------------
+114 -75
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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, &params) <= 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
View File
@@ -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
View File
@@ -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;
+40 -58
View File
@@ -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");
goto end;
}
hexe = BN_bn2hex(e);
dece = BN_bn2dec(e);
if (hexe && dece) {
BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
}
OPENSSL_free(hexe);
OPENSSL_free(dece);
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 && verbose) {
BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
}
if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout))
OPENSSL_free(hexe);
OPENSSL_free(dece);
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
View File
@@ -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
+23 -7
View File
@@ -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,
const char *prog, int accept_get, int timeout);
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
View File
@@ -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;
+25 -198
View File
@@ -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",
opt_getprog(), sz, what);
ERR_print_errors(bio_err);
exit(1);
}
if (vp == NULL)
app_bail_out("%s: Could not allocate %d bytes for %s\n",
opt_getprog(), sz, what);
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,12 +1640,12 @@ 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,
"%s: Hit end of string before finding the '='\n",
opt_getprog());
"%s: Hit end of string before finding the '='\n",
opt_getprog());
goto err;
}
*bp++ = '\0';
@@ -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;
}
+77 -24
View File
@@ -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')
if (strlen(meth) == 3 && url[0] == '\0') {
(void)http_server_send_status(cbio, 200, "OK");
goto out;
}
len = urldecode(url);
if (len <= 0) {
if (len < 0) {
log_message(prog, LOG_INFO,
"Invalid GET request -- bad URL encoding: %s", url);
"Invalid %s request -- bad URL encoding: %s",
meth, url);
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
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;
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);
goto fatal;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
getbio = BIO_push(b64, getbio);
}
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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+124 -15
View File
@@ -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,
NULL);
send_ocsp_response(cbio, resp);
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;
}
-53
View File
@@ -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
View File
@@ -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]);
-53
View File
@@ -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
View File
@@ -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}
};
+174 -38
View File
@@ -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))
goto shut;
{
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
+17 -8
View File
@@ -534,8 +534,8 @@ 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),
&host, &port, &path, &use_ssl)) {
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,9 +1406,10 @@ 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,
&tlscstatp.path, &tlscstatp.use_ssl)) {
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",
@@ -3617,7 +3626,7 @@ static int generate_session_id(SSL *ssl, unsigned char *id,
{
unsigned int count = 0;
unsigned int session_id_prefix_len = strlen(session_id_prefix);
do {
if (RAND_bytes(id, *id_len) <= 0)
return 0;
+347 -10
View File
@@ -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
View File
@@ -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"
}
+9 -5
View File
@@ -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)
+1 -1
View File
@@ -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,
+6 -2
View File
@@ -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
View File
@@ -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
-3
View File
@@ -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),
-99
View File
@@ -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
View File
@@ -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);
+6 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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);
}
+12 -6
View File
@@ -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))
return 0;
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 -1
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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;
+2
View File
@@ -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
View File
@@ -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;
-68
View File
@@ -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;
}
+7 -7
View File
@@ -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,8 +909,8 @@ 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,
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
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);
/* from cmp_client.c */
+7 -3
View File
@@ -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)
+6 -8
View File
@@ -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 ((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);
+32 -16
View File
@@ -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,9 +492,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
ctx->transactionID->length);
ossl_cmp_log1(WARN, ctx,
"Assuming that last transaction with ID=%s got aborted",
tid);
if (tid != NULL)
ossl_cmp_log1(WARN, ctx,
"Assuming that last transaction with ID=%s got aborted",
tid);
OPENSSL_free(tid);
}
/* start of a new transaction, reset transactionID and senderNonce */
@@ -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,16 +577,23 @@ 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;
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
data = ERR_reason_error_string(err);
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
err != 0 ? ERR_GET_REASON(err) : -1,
data, srv_ctx->sendUnprotectedErrors);
OSSL_CMP_PKISI_free(si);
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,
err != 0 ? ERR_GET_REASON(err) : -1,
data, srv_ctx->sendUnprotectedErrors);
OSSL_CMP_PKISI_free(si);
}
}
ctx->secretValue = backup_secret;
/* possibly close the transaction */
rsp_type =
+158 -141
View File
@@ -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,34 +603,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
break;
}
if (verify_PBMAC(msg, ctx->secretValue)) {
/*
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
* "shared secret information", then any certificate transported in
* the caPubs field may be directly trusted as a root CA
* 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:
case OSSL_CMP_PKIBODY_CCP:
if (ctx->trusted != NULL) {
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
/* value.ip is same for cp, kup, and ccp */
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
/* adds both self-issued and not self-issued certs */
return 0;
}
break;
default:
break;
}
if (verify_PBMAC(msg, ctx->secretValue))
return 1;
}
break;
/*
@@ -626,28 +619,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
* 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))
@@ -656,9 +627,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
/* 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);
}
@@ -670,9 +638,11 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
/*-
* Check received message (i.e., response by server or request from client)
* Any msg->extraCerts are prepended to ctx->untrusted_certs
* 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)
@@ -681,30 +651,63 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
*
* If everything is fine:
* learns the senderNonce from the received message,
* learns the transaction ID if it is not yet in ctx.
* learns the transaction ID if it is not yet in ctx,
* and makes any certs in caPubs directly trusted.
*
* returns body type (which is >= 0) of the message on success, -1 on error
* Returns 1 on success, 0 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 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 rcvd_type;
OSSL_CMP_PKIHEADER *hdr;
const X509_NAME *expected_sender;
if (!ossl_assert(ctx != NULL && msg != NULL))
return -1;
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 (msg->header->protectionAlg != 0) {
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 -1;
return 0;
#endif
}
} else {
@@ -712,34 +715,34 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
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;
return 0;
#endif
}
}
/* check CMP version number in header */
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
return -1;
return 0;
#endif
}
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
if (ossl_cmp_msg_get_bodytype(msg) < 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
CMPerr(0, CMP_R_PKIBODY_ERROR);
return -1;
return 0;
#endif
}
/* compare received transactionID with the expected one in previous msg */
if (ctx->transactionID != NULL
&& (msg->header->transactionID == NULL
&& (hdr->transactionID == NULL
|| ASN1_OCTET_STRING_cmp(ctx->transactionID,
msg->header->transactionID) != 0)) {
hdr->transactionID) != 0)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED);
return -1;
return 0;
#endif
}
@@ -747,10 +750,10 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
if (ctx->senderNonce != NULL
&& (msg->header->recipNonce == NULL
|| ASN1_OCTET_STRING_cmp(ctx->senderNonce,
msg->header->recipNonce) != 0)) {
hdr->recipNonce) != 0)) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED);
return -1;
return 0;
#endif
}
@@ -759,26 +762,40 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
* 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 (!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, msg->header->transactionID))
return -1;
&& !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID))
return 0;
/*
* 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;
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
* the caPubs field may be directly trusted as a root CA
* certificate by the initiator.'
*/
switch (ossl_cmp_msg_get_bodytype(msg)) {
case OSSL_CMP_PKIBODY_IP:
case OSSL_CMP_PKIBODY_CP:
case OSSL_CMP_PKIBODY_KUP:
case OSSL_CMP_PKIBODY_CCP:
if (ctx->trusted != NULL) {
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
/* value.ip is same for cp, kup, and ccp */
return rcvd_type;
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
/* adds both self-issued and not self-issued certs */
return 0;
}
break;
default:
break;
}
}
return 1;
}
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
+4
View File
@@ -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
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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);
+6 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
-1
View File
@@ -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 {
+3 -3
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+25 -15
View File
@@ -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,19 +366,29 @@ 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) {
DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
return 0;
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;
}
/*
* As per Section 4.2.8.1 of RFC 8446 left pad public
* 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;
}
/*
* As per Section 4.2.8.1 of RFC 8446 left pad public
* key with zeros to the size of p
*/
if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
OPENSSL_free(pbuf);
DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
return 0;
}
*pbuf_out = pbuf;
return p_size;
}
+3 -3
View File
@@ -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);
-3
View File
@@ -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);
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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"},
+1 -1
View File
@@ -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);
-2082
View File
@@ -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: $!";
+2 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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
View File
@@ -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);
+7 -8
View File
@@ -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;
}
+3 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+13
View File
@@ -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
View File
@@ -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;
+3 -3
View File
@@ -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
View File
@@ -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;
+5 -4
View File
@@ -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
View File
@@ -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 */
+49 -256
View File
@@ -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,67 +1058,58 @@ __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;
/* First window */
wvalue = (p_str[0] << 1) & mask;
wvalue = _booth_recode_w7(wvalue);
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
wvalue >> 1);
ecp_nistz256_neg(p.p.Z, p.p.Y);
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
/*
* Since affine infinity is encoded as (0,0) and
* 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] |
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
if (P256_LIMBS == 8)
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
infty = 0 - is_zero(infty);
infty = ~infty;
p.p.Z[0] = ONE[0] & infty;
p.p.Z[1] = ONE[1] & infty;
p.p.Z[2] = ONE[2] & infty;
p.p.Z[3] = ONE[3] & infty;
if (P256_LIMBS == 8) {
p.p.Z[4] = ONE[4] & infty;
p.p.Z[5] = ONE[5] & infty;
p.p.Z[6] = ONE[6] & infty;
p.p.Z[7] = ONE[7] & infty;
}
for (i = 1; i < 37; i++) {
unsigned int off = (idx - 1) / 8;
wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
idx += window_size;
wvalue = _booth_recode_w7(wvalue);
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
wvalue >> 1);
ecp_nistz256_gather_w7(&t.a,
preComputedTable[i], wvalue >> 1);
ecp_nistz256_neg(p.p.Z, p.p.Y);
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
ecp_nistz256_neg(t.p.Z, t.a.Y);
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
/*
* Since affine infinity is encoded as (0,0) and
* Jacobian ias (,,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] |
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
if (P256_LIMBS == 8)
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
infty = 0 - is_zero(infty);
infty = ~infty;
p.p.Z[0] = ONE[0] & infty;
p.p.Z[1] = ONE[1] & infty;
p.p.Z[2] = ONE[2] & infty;
p.p.Z[3] = ONE[3] & infty;
if (P256_LIMBS == 8) {
p.p.Z[4] = ONE[4] & infty;
p.p.Z[5] = ONE[5] & infty;
p.p.Z[6] = ONE[6] & infty;
p.p.Z[7] = ONE[7] & infty;
}
for (i = 1; i < 37; i++) {
unsigned int off = (idx - 1) / 8;
wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
idx += window_size;
wvalue = _booth_recode_w7(wvalue);
ecp_nistz256_gather_w7(&t.a,
preComputedTable[i], wvalue >> 1);
ecp_nistz256_neg(t.p.Z, t.a.Y);
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
}
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
}
} else {
p_is_infinity = 1;
+6
View File
@@ -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>
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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 */
-1
View File
@@ -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},
};
-2
View File
@@ -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